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