1 /* 2 * Copyright (C) 2013 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 android.bluetooth; 18 19 import android.Manifest; 20 import android.annotation.RequiresPermission; 21 import android.content.Context; 22 import android.os.RemoteException; 23 import android.util.Log; 24 25 import java.util.ArrayList; 26 import java.util.List; 27 28 /** 29 * High level manager used to obtain an instance of an {@link BluetoothAdapter} 30 * and to conduct overall Bluetooth Management. 31 * <p> 32 * Use {@link android.content.Context#getSystemService(java.lang.String)} 33 * with {@link Context#BLUETOOTH_SERVICE} to create an {@link BluetoothManager}, 34 * then call {@link #getAdapter} to obtain the {@link BluetoothAdapter}. 35 * <p> 36 * Alternately, you can just call the static helper 37 * {@link BluetoothAdapter#getDefaultAdapter()}. 38 * 39 * <div class="special reference"> 40 * <h3>Developer Guides</h3> 41 * <p>For more information about using BLUETOOTH, read the 42 * <a href="{@docRoot}guide/topics/connectivity/bluetooth.html">Bluetooth</a> developer guide.</p> 43 * </div> 44 * 45 * @see Context#getSystemService 46 * @see BluetoothAdapter#getDefaultAdapter() 47 */ 48 public final class BluetoothManager { 49 private static final String TAG = "BluetoothManager"; 50 private static final boolean DBG = true; 51 private static final boolean VDBG = true; 52 53 private final BluetoothAdapter mAdapter; 54 55 /** 56 * @hide 57 */ BluetoothManager(Context context)58 public BluetoothManager(Context context) { 59 context = context.getApplicationContext(); 60 if (context == null) { 61 throw new IllegalArgumentException( 62 "context not associated with any application (using a mock context?)"); 63 } 64 // Legacy api - getDefaultAdapter does not take in the context 65 mAdapter = BluetoothAdapter.getDefaultAdapter(); 66 } 67 68 /** 69 * Get the default BLUETOOTH Adapter for this device. 70 * 71 * @return the default BLUETOOTH Adapter 72 */ getAdapter()73 public BluetoothAdapter getAdapter() { 74 return mAdapter; 75 } 76 77 /** 78 * Get the current connection state of the profile to the remote device. 79 * 80 * <p>This is not specific to any application configuration but represents 81 * the connection state of the local Bluetooth adapter for certain profile. 82 * This can be used by applications like status bar which would just like 83 * to know the state of Bluetooth. 84 * 85 * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. 86 * 87 * @param device Remote bluetooth device. 88 * @param profile GATT or GATT_SERVER 89 * @return State of the profile connection. One of 90 * {@link BluetoothProfile#STATE_CONNECTED}, {@link BluetoothProfile#STATE_CONNECTING}, 91 * {@link BluetoothProfile#STATE_DISCONNECTED}, 92 * {@link BluetoothProfile#STATE_DISCONNECTING} 93 */ 94 @RequiresPermission(Manifest.permission.BLUETOOTH) getConnectionState(BluetoothDevice device, int profile)95 public int getConnectionState(BluetoothDevice device, int profile) { 96 if (DBG) Log.d(TAG,"getConnectionState()"); 97 98 List<BluetoothDevice> connectedDevices = getConnectedDevices(profile); 99 for(BluetoothDevice connectedDevice : connectedDevices) { 100 if (device.equals(connectedDevice)) { 101 return BluetoothProfile.STATE_CONNECTED; 102 } 103 } 104 105 return BluetoothProfile.STATE_DISCONNECTED; 106 } 107 108 /** 109 * Get connected devices for the specified profile. 110 * 111 * <p> Return the set of devices which are in state {@link BluetoothProfile#STATE_CONNECTED} 112 * 113 * <p>This is not specific to any application configuration but represents 114 * the connection state of Bluetooth for this profile. 115 * This can be used by applications like status bar which would just like 116 * to know the state of Bluetooth. 117 * 118 * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. 119 * 120 * @param profile GATT or GATT_SERVER 121 * @return List of devices. The list will be empty on error. 122 */ 123 @RequiresPermission(Manifest.permission.BLUETOOTH) getConnectedDevices(int profile)124 public List<BluetoothDevice> getConnectedDevices(int profile) { 125 if (DBG) Log.d(TAG,"getConnectedDevices"); 126 if (profile != BluetoothProfile.GATT && profile != BluetoothProfile.GATT_SERVER) { 127 throw new IllegalArgumentException("Profile not supported: " + profile); 128 } 129 130 List<BluetoothDevice> connectedDevices = new ArrayList<BluetoothDevice>(); 131 132 try { 133 IBluetoothManager managerService = mAdapter.getBluetoothManager(); 134 IBluetoothGatt iGatt = managerService.getBluetoothGatt(); 135 if (iGatt == null) return connectedDevices; 136 137 connectedDevices = iGatt.getDevicesMatchingConnectionStates( 138 new int[] { BluetoothProfile.STATE_CONNECTED }); 139 } catch (RemoteException e) { 140 Log.e(TAG,"",e); 141 } 142 143 return connectedDevices; 144 } 145 146 /** 147 * 148 * Get a list of devices that match any of the given connection 149 * states. 150 * 151 * <p> If none of the devices match any of the given states, 152 * an empty list will be returned. 153 * 154 * <p>This is not specific to any application configuration but represents 155 * the connection state of the local Bluetooth adapter for this profile. 156 * This can be used by applications like status bar which would just like 157 * to know the state of the local adapter. 158 * 159 * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. 160 * 161 * @param profile GATT or GATT_SERVER 162 * @param states Array of states. States can be one of 163 * {@link BluetoothProfile#STATE_CONNECTED}, {@link BluetoothProfile#STATE_CONNECTING}, 164 * {@link BluetoothProfile#STATE_DISCONNECTED}, 165 * {@link BluetoothProfile#STATE_DISCONNECTING}, 166 * @return List of devices. The list will be empty on error. 167 */ 168 @RequiresPermission(Manifest.permission.BLUETOOTH) getDevicesMatchingConnectionStates(int profile, int[] states)169 public List<BluetoothDevice> getDevicesMatchingConnectionStates(int profile, int[] states) { 170 if (DBG) Log.d(TAG,"getDevicesMatchingConnectionStates"); 171 172 if (profile != BluetoothProfile.GATT && profile != BluetoothProfile.GATT_SERVER) { 173 throw new IllegalArgumentException("Profile not supported: " + profile); 174 } 175 176 List<BluetoothDevice> devices = new ArrayList<BluetoothDevice>(); 177 178 try { 179 IBluetoothManager managerService = mAdapter.getBluetoothManager(); 180 IBluetoothGatt iGatt = managerService.getBluetoothGatt(); 181 if (iGatt == null) return devices; 182 devices = iGatt.getDevicesMatchingConnectionStates(states); 183 } catch (RemoteException e) { 184 Log.e(TAG,"",e); 185 } 186 187 return devices; 188 } 189 190 /** 191 * Open a GATT Server 192 * The callback is used to deliver results to Caller, such as connection status as well 193 * as the results of any other GATT server operations. 194 * The method returns a BluetoothGattServer instance. You can use BluetoothGattServer 195 * to conduct GATT server operations. 196 * @param context App context 197 * @param callback GATT server callback handler that will receive asynchronous callbacks. 198 * @return BluetoothGattServer instance 199 */ openGattServer(Context context, BluetoothGattServerCallback callback)200 public BluetoothGattServer openGattServer(Context context, 201 BluetoothGattServerCallback callback) { 202 203 return (openGattServer (context, callback, BluetoothDevice.TRANSPORT_AUTO)); 204 } 205 206 /** 207 * Open a GATT Server 208 * The callback is used to deliver results to Caller, such as connection status as well 209 * as the results of any other GATT server operations. 210 * The method returns a BluetoothGattServer instance. You can use BluetoothGattServer 211 * to conduct GATT server operations. 212 * @param context App context 213 * @param callback GATT server callback handler that will receive asynchronous callbacks. 214 * @param transport preferred transport for GATT connections to remote dual-mode devices 215 * {@link BluetoothDevice#TRANSPORT_AUTO} or 216 * {@link BluetoothDevice#TRANSPORT_BREDR} or {@link BluetoothDevice#TRANSPORT_LE} 217 * @return BluetoothGattServer instance 218 * @hide 219 */ openGattServer(Context context, BluetoothGattServerCallback callback,int transport)220 public BluetoothGattServer openGattServer(Context context, 221 BluetoothGattServerCallback callback,int transport) { 222 if (context == null || callback == null) { 223 throw new IllegalArgumentException("null parameter: " + context + " " + callback); 224 } 225 226 // TODO(Bluetooth) check whether platform support BLE 227 // Do the check here or in GattServer? 228 229 try { 230 IBluetoothManager managerService = mAdapter.getBluetoothManager(); 231 IBluetoothGatt iGatt = managerService.getBluetoothGatt(); 232 if (iGatt == null) { 233 Log.e(TAG, "Fail to get GATT Server connection"); 234 return null; 235 } 236 BluetoothGattServer mGattServer = new BluetoothGattServer(context, iGatt,transport); 237 Boolean regStatus = mGattServer.registerCallback(callback); 238 return regStatus? mGattServer : null; 239 } catch (RemoteException e) { 240 Log.e(TAG,"",e); 241 return null; 242 } 243 } 244 } 245