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