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.RequiresFeature; 21 import android.annotation.RequiresPermission; 22 import android.annotation.SystemService; 23 import android.content.Context; 24 import android.content.pm.PackageManager; 25 import android.os.RemoteException; 26 import android.util.Log; 27 28 import java.util.ArrayList; 29 import java.util.List; 30 31 /** 32 * High level manager used to obtain an instance of an {@link BluetoothAdapter} 33 * and to conduct overall Bluetooth Management. 34 * <p> 35 * Use {@link android.content.Context#getSystemService(java.lang.String)} 36 * with {@link Context#BLUETOOTH_SERVICE} to create an {@link BluetoothManager}, 37 * then call {@link #getAdapter} to obtain the {@link BluetoothAdapter}. 38 * </p> 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 @SystemService(Context.BLUETOOTH_SERVICE) 52 @RequiresFeature(PackageManager.FEATURE_BLUETOOTH) 53 public final class BluetoothManager { 54 private static final String TAG = "BluetoothManager"; 55 private static final boolean DBG = false; 56 57 private final BluetoothAdapter mAdapter; 58 59 /** 60 * @hide 61 */ BluetoothManager(Context context)62 public BluetoothManager(Context context) { 63 context = context.getApplicationContext(); 64 if (context == null) { 65 throw new IllegalArgumentException( 66 "context not associated with any application (using a mock context?)"); 67 } 68 // Legacy api - getDefaultAdapter does not take in the context 69 mAdapter = BluetoothAdapter.getDefaultAdapter(); 70 if (mAdapter != null) { 71 mAdapter.setContext(context); 72 } 73 } 74 75 /** 76 * Get the default BLUETOOTH Adapter for this device. 77 * 78 * @return the default BLUETOOTH Adapter 79 */ getAdapter()80 public BluetoothAdapter getAdapter() { 81 return mAdapter; 82 } 83 84 /** 85 * Get the current connection state of the profile to the remote device. 86 * 87 * <p>This is not specific to any application configuration but represents 88 * the connection state of the local Bluetooth adapter for certain profile. 89 * This can be used by applications like status bar which would just like 90 * to know the state of Bluetooth. 91 * 92 * @param device Remote bluetooth device. 93 * @param profile GATT or GATT_SERVER 94 * @return State of the profile connection. One of {@link BluetoothProfile#STATE_CONNECTED}, 95 * {@link BluetoothProfile#STATE_CONNECTING}, {@link BluetoothProfile#STATE_DISCONNECTED}, 96 * {@link BluetoothProfile#STATE_DISCONNECTING} 97 */ 98 @RequiresPermission(Manifest.permission.BLUETOOTH) getConnectionState(BluetoothDevice device, int profile)99 public int getConnectionState(BluetoothDevice device, int profile) { 100 if (DBG) Log.d(TAG, "getConnectionState()"); 101 102 List<BluetoothDevice> connectedDevices = getConnectedDevices(profile); 103 for (BluetoothDevice connectedDevice : connectedDevices) { 104 if (device.equals(connectedDevice)) { 105 return BluetoothProfile.STATE_CONNECTED; 106 } 107 } 108 109 return BluetoothProfile.STATE_DISCONNECTED; 110 } 111 112 /** 113 * Get connected devices for the specified profile. 114 * 115 * <p> Return the set of devices which are in state {@link BluetoothProfile#STATE_CONNECTED} 116 * 117 * <p>This is not specific to any application configuration but represents 118 * the connection state of Bluetooth for this profile. 119 * This can be used by applications like status bar which would just like 120 * to know the state of Bluetooth. 121 * 122 * @param profile GATT or GATT_SERVER 123 * @return List of devices. The list will be empty on error. 124 */ 125 @RequiresPermission(Manifest.permission.BLUETOOTH) getConnectedDevices(int profile)126 public List<BluetoothDevice> getConnectedDevices(int profile) { 127 if (DBG) Log.d(TAG, "getConnectedDevices"); 128 if (profile != BluetoothProfile.GATT && profile != BluetoothProfile.GATT_SERVER) { 129 throw new IllegalArgumentException("Profile not supported: " + profile); 130 } 131 132 List<BluetoothDevice> connectedDevices = new ArrayList<BluetoothDevice>(); 133 134 try { 135 IBluetoothManager managerService = mAdapter.getBluetoothManager(); 136 IBluetoothGatt iGatt = managerService.getBluetoothGatt(); 137 if (iGatt == null) return connectedDevices; 138 139 connectedDevices = iGatt.getDevicesMatchingConnectionStates( 140 new int[]{BluetoothProfile.STATE_CONNECTED}); 141 } catch (RemoteException e) { 142 Log.e(TAG, "", e); 143 } 144 145 return connectedDevices; 146 } 147 148 /** 149 * Get a list of devices that match any of the given connection 150 * states. 151 * 152 * <p> If none of the devices match any of the given states, 153 * an empty list will be returned. 154 * 155 * <p>This is not specific to any application configuration but represents 156 * the connection state of the local Bluetooth adapter for this profile. 157 * This can be used by applications like status bar which would just like 158 * to know the state of the local adapter. 159 * 160 * @param profile GATT or GATT_SERVER 161 * @param states Array of states. States can be one of {@link BluetoothProfile#STATE_CONNECTED}, 162 * {@link BluetoothProfile#STATE_CONNECTING}, {@link BluetoothProfile#STATE_DISCONNECTED}, 163 * {@link BluetoothProfile#STATE_DISCONNECTING}, 164 * @return List of devices. The list will be empty on error. 165 */ 166 @RequiresPermission(Manifest.permission.BLUETOOTH) getDevicesMatchingConnectionStates(int profile, int[] states)167 public List<BluetoothDevice> getDevicesMatchingConnectionStates(int profile, int[] states) { 168 if (DBG) Log.d(TAG, "getDevicesMatchingConnectionStates"); 169 170 if (profile != BluetoothProfile.GATT && profile != BluetoothProfile.GATT_SERVER) { 171 throw new IllegalArgumentException("Profile not supported: " + profile); 172 } 173 174 List<BluetoothDevice> devices = new ArrayList<BluetoothDevice>(); 175 176 try { 177 IBluetoothManager managerService = mAdapter.getBluetoothManager(); 178 IBluetoothGatt iGatt = managerService.getBluetoothGatt(); 179 if (iGatt == null) return devices; 180 devices = iGatt.getDevicesMatchingConnectionStates(states); 181 } catch (RemoteException e) { 182 Log.e(TAG, "", e); 183 } 184 185 return devices; 186 } 187 188 /** 189 * Open a GATT Server 190 * The callback is used to deliver results to Caller, such as connection status as well 191 * as the results of any other GATT server operations. 192 * The method returns a BluetoothGattServer instance. You can use BluetoothGattServer 193 * to conduct GATT server operations. 194 * 195 * @param context App context 196 * @param callback GATT server callback handler that will receive asynchronous callbacks. 197 * @return BluetoothGattServer instance 198 */ openGattServer(Context context, BluetoothGattServerCallback callback)199 public BluetoothGattServer openGattServer(Context context, 200 BluetoothGattServerCallback callback) { 201 202 return (openGattServer(context, callback, BluetoothDevice.TRANSPORT_AUTO)); 203 } 204 205 /** 206 * Open a GATT Server 207 * The callback is used to deliver results to Caller, such as connection status as well 208 * as the results of any other GATT server operations. 209 * The method returns a BluetoothGattServer instance. You can use BluetoothGattServer 210 * to conduct GATT server operations. 211 * 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 {@link 215 * BluetoothDevice#TRANSPORT_AUTO} or {@link BluetoothDevice#TRANSPORT_BREDR} or {@link 216 * 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(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