1 /*
2  * Copyright (C) 2017 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.googlecode.android_scripting.facade.bluetooth;
18 
19 import android.app.Service;
20 import android.bluetooth.BluetoothAdapter;
21 import android.bluetooth.BluetoothDevice;
22 import android.bluetooth.BluetoothPbapClient;
23 import android.bluetooth.BluetoothProfile;
24 import android.bluetooth.BluetoothUuid;
25 import android.os.ParcelUuid;
26 
27 import com.googlecode.android_scripting.Log;
28 import com.googlecode.android_scripting.facade.FacadeManager;
29 import com.googlecode.android_scripting.jsonrpc.RpcReceiver;
30 import com.googlecode.android_scripting.rpc.Rpc;
31 import com.googlecode.android_scripting.rpc.RpcParameter;
32 
33 import java.util.ArrayList;
34 import java.util.List;
35 
36 /**
37  * BluetoothPbapClientFacade
38  */
39 public class BluetoothPbapClientFacade extends RpcReceiver {
40     static final ParcelUuid[] UUIDS = {
41         BluetoothUuid.PBAP_PSE,
42     };
43 
44     private final Service mService;
45     private final BluetoothAdapter mBluetoothAdapter;
46 
47     private static boolean sIsPbapClientReady = false;
48     private static BluetoothPbapClient sPbapClientProfile = null;
49 
BluetoothPbapClientFacade(FacadeManager manager)50     public BluetoothPbapClientFacade(FacadeManager manager) {
51         super(manager);
52         mService = manager.getService();
53         mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
54         mBluetoothAdapter.getProfileProxy(mService,
55                 new PbapClientServiceListener(), BluetoothProfile.PBAP_CLIENT);
56     }
57 
58     class PbapClientServiceListener implements
59             BluetoothProfile.ServiceListener {
60         @Override
onServiceConnected(int profile, BluetoothProfile proxy)61         public void onServiceConnected(int profile, BluetoothProfile proxy) {
62             sPbapClientProfile = (BluetoothPbapClient) proxy;
63             sIsPbapClientReady = true;
64         }
65 
66         @Override
onServiceDisconnected(int profile)67         public void onServiceDisconnected(int profile) {
68             sIsPbapClientReady = false;
69         }
70     }
71 
72     /**
73      * Connect PbapClient profile.
74      * @param device - the BluetoothDevice object to connect to.
75      * @return if the connection was successfull or not.
76      */
pbapClientConnect(BluetoothDevice device)77     public Boolean pbapClientConnect(BluetoothDevice device) {
78         if (sPbapClientProfile == null) return false;
79         return sPbapClientProfile.connect(device);
80     }
81 
82     /**
83      * Disconnect PbapClient profile.
84      * @param device - the Bluetooth Device object to disconnect from.
85      * @return if the disconnection was successfull or not.
86      */
pbapClientDisconnect(BluetoothDevice device)87     public Boolean pbapClientDisconnect(BluetoothDevice device) {
88         if (sPbapClientProfile == null) return false;
89         return sPbapClientProfile.disconnect(device);
90     }
91 
92     /**
93      * Is PbapClient profile ready.
94      * @return if PbapClient profile is ready or not.
95      */
96     @Rpc(description = "Is PbapClient profile ready.")
bluetoothPbapClientIsReady()97     public Boolean bluetoothPbapClientIsReady() {
98         return sIsPbapClientReady;
99     }
100 
101     /**
102      * Set priority of the profile.
103      * @param deviceStr - name or MAC address of a Bluetooth device.
104      * @param priority - Priority that needs to be set.
105      */
106     @Rpc(description = "Set priority of the profile")
bluetoothPbapClientSetPriority(@pcParametername = "device", description = "Mac address of a BT device.") String deviceStr, @RpcParameter(name = "priority", description = "Priority that needs to be set.") Integer priority)107     public void bluetoothPbapClientSetPriority(@RpcParameter(name = "device",
108                 description = "Mac address of a BT device.") String deviceStr,
109             @RpcParameter(name = "priority",
110                 description = "Priority that needs to be set.")
111                 Integer priority) throws Exception {
112         if (sPbapClientProfile == null) return;
113         BluetoothDevice device =
114                 BluetoothFacade.getDevice(mBluetoothAdapter.getBondedDevices(),
115                 deviceStr);
116         Log.d("Changing priority of device " + device.getAliasName()
117                 + " p: " + priority);
118         sPbapClientProfile.setPriority(device, priority);
119     }
120 
121     /**
122      * Get priority of the profile.
123      * @return Priority of the device.
124      */
125     @Rpc(description = "Get priority of the profile")
bluetoothPbapClientGetPriority( @pcParametername = "device", description = "Mac address of a BT device.") String deviceStr)126     public Integer bluetoothPbapClientGetPriority(
127             @RpcParameter(name = "device",
128                 description = "Mac address of a BT device.") String deviceStr)
129                 throws Exception {
130         if (sPbapClientProfile == null) {
131             return BluetoothProfile.PRIORITY_UNDEFINED;
132         }
133         BluetoothDevice device =
134                 BluetoothFacade.getDevice(mBluetoothAdapter.getBondedDevices(),
135                     deviceStr);
136         return sPbapClientProfile.getPriority(device);
137     }
138 
139     /**
140      * Connect to an PBAP Client device.
141      * @param deviceStr - Name or MAC address of a bluetooth device.
142      * @return True if the connection was successful; otherwise False.
143      */
144     @Rpc(description = "Connect to an PBAP Client device.")
bluetoothPbapClientConnect( @pcParametername = "device", description = "Name or MAC address of a bluetooth device.") String deviceStr)145     public Boolean bluetoothPbapClientConnect(
146                 @RpcParameter(name = "device",
147                     description = "Name or MAC address of a bluetooth device.")
148                     String deviceStr) throws Exception {
149         if (sPbapClientProfile == null) return false;
150         try {
151             BluetoothDevice device =
152                     BluetoothFacade.getDevice(
153                             mBluetoothAdapter.getBondedDevices(), deviceStr);
154             Log.d("Connecting to device " + device.getAliasName());
155             return pbapClientConnect(device);
156         } catch (Exception e) {
157             Log.e("bluetoothPbapClientConnect failed on getDevice "
158                     + deviceStr + " with " + e);
159             return false;
160         }
161     }
162 
163     /**
164      * Disconnect an PBAP Client device.
165      * @param deviceStr - Name or MAC address of a bluetooth device.
166      * @return True if the disconnection was successful; otherwise False.
167      */
168     @Rpc(description = "Disconnect an PBAP Client device.")
bluetoothPbapClientDisconnect( @pcParametername = "device", description = "Name or MAC address of a device.") String deviceStr)169     public Boolean bluetoothPbapClientDisconnect(
170             @RpcParameter(name = "device",
171                 description = "Name or MAC address of a device.")
172                 String deviceStr) {
173         if (sPbapClientProfile == null) return false;
174         Log.d("Connected devices: " + sPbapClientProfile.getConnectedDevices());
175         try {
176             BluetoothDevice device =
177                     BluetoothFacade.getDevice(
178                         sPbapClientProfile.getConnectedDevices(), deviceStr);
179             return pbapClientDisconnect(device);
180         } catch (Exception e) {
181             // Do nothing since it is disconnect and the above call
182             // should force disconnect.
183             Log.e("bluetoothPbapClientConnect getDevice failed " + e);
184         }
185         return false;
186     }
187 
188     /**
189      * Get all the devices connected through PBAP Client.
190      * @return List of all the devices connected through PBAP client.
191      */
192     @Rpc(description = "Get all the devices connected through PBAP Client.")
bluetoothPbapClientGetConnectedDevices()193     public List<BluetoothDevice> bluetoothPbapClientGetConnectedDevices() {
194         if (sPbapClientProfile == null) return new ArrayList<BluetoothDevice>();
195         return sPbapClientProfile.getConnectedDevices();
196     }
197 
198      /**
199      * Get the connection status of a device.
200      * @return connection status of the device.
201      */
202     @Rpc(description = "Get the connection status of a device.")
bluetoothPbapClientGetConnectionStatus( @pcParametername = "deviceID", description = "Name or MAC address of a bluetooth device.") String deviceID)203     public Integer bluetoothPbapClientGetConnectionStatus(
204             @RpcParameter(name = "deviceID",
205             description = "Name or MAC address of a bluetooth device.")
206             String deviceID) {
207         if (sPbapClientProfile == null) {
208             return BluetoothProfile.STATE_DISCONNECTED;
209         }
210         List<BluetoothDevice> deviceList =
211                 sPbapClientProfile.getConnectedDevices();
212         BluetoothDevice device;
213         try {
214             device = BluetoothFacade.getDevice(deviceList, deviceID);
215         } catch (Exception e) {
216             Log.e(e);
217             return BluetoothProfile.STATE_DISCONNECTED;
218         }
219         return sPbapClientProfile.getConnectionState(device);
220     }
221 
222     @Override
shutdown()223     public void shutdown() {
224     }
225 }
226