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