blob: e08d405324ea896a0efc1c340ce112589d8aebb1 [file] [log] [blame]
Matthew Xieddf7e472013-03-01 18:41:02 -08001/*
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
Tor Norbye2d497522015-04-23 17:10:21 -070019import android.Manifest;
Jeff Sharkey98af2e42018-02-16 10:14:57 -070020import android.annotation.RequiresFeature;
Tor Norbye2d497522015-04-23 17:10:21 -070021import android.annotation.RequiresPermission;
Jeff Sharkeyd86b8fe2017-06-02 17:36:26 -060022import android.annotation.SystemService;
Matthew Xieddf7e472013-03-01 18:41:02 -080023import android.content.Context;
Jeff Sharkey98af2e42018-02-16 10:14:57 -070024import android.content.pm.PackageManager;
Matthew Xieddf7e472013-03-01 18:41:02 -080025import android.os.RemoteException;
26import android.util.Log;
27
28import java.util.ArrayList;
29import 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}.
Marie Janssen553c8c72017-01-12 16:00:30 -080038 * </p>
Matthew Xieddf7e472013-03-01 18:41:02 -080039 * <div class="special reference">
40 * <h3>Developer Guides</h3>
Hemal Patel65813df2016-08-17 13:18:14 -070041 * <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>
Matthew Xieddf7e472013-03-01 18:41:02 -080046 * </div>
47 *
48 * @see Context#getSystemService
49 * @see BluetoothAdapter#getDefaultAdapter()
50 */
Jeff Sharkeyd86b8fe2017-06-02 17:36:26 -060051@SystemService(Context.BLUETOOTH_SERVICE)
Jeff Sharkey98af2e42018-02-16 10:14:57 -070052@RequiresFeature(PackageManager.FEATURE_BLUETOOTH)
Matthew Xieddf7e472013-03-01 18:41:02 -080053public final class BluetoothManager {
54 private static final String TAG = "BluetoothManager";
Myles Watson3ee31a72018-11-14 14:40:14 -080055 private static final boolean DBG = false;
Matthew Xieddf7e472013-03-01 18:41:02 -080056
57 private final BluetoothAdapter mAdapter;
58
59 /**
60 * @hide
61 */
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();
Zach Johnson57e6e902018-12-12 17:11:25 -080070 mAdapter.setContext(context);
Matthew Xieddf7e472013-03-01 18:41:02 -080071 }
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 *
Matthew Xieddf7e472013-03-01 18:41:02 -080090 * @param device Remote bluetooth device.
91 * @param profile GATT or GATT_SERVER
Jack Hea355e5e2017-08-22 16:06:54 -070092 * @return State of the profile connection. One of {@link BluetoothProfile#STATE_CONNECTED},
93 * {@link BluetoothProfile#STATE_CONNECTING}, {@link BluetoothProfile#STATE_DISCONNECTED},
94 * {@link BluetoothProfile#STATE_DISCONNECTING}
Matthew Xieddf7e472013-03-01 18:41:02 -080095 */
Tor Norbye2d497522015-04-23 17:10:21 -070096 @RequiresPermission(Manifest.permission.BLUETOOTH)
Matthew Xieddf7e472013-03-01 18:41:02 -080097 public int getConnectionState(BluetoothDevice device, int profile) {
Jack Hea355e5e2017-08-22 16:06:54 -070098 if (DBG) Log.d(TAG, "getConnectionState()");
Matthew Xieddf7e472013-03-01 18:41:02 -080099
100 List<BluetoothDevice> connectedDevices = getConnectedDevices(profile);
Jack Hea355e5e2017-08-22 16:06:54 -0700101 for (BluetoothDevice connectedDevice : connectedDevices) {
Matthew Xieddf7e472013-03-01 18:41:02 -0800102 if (device.equals(connectedDevice)) {
103 return BluetoothProfile.STATE_CONNECTED;
104 }
105 }
106
107 return BluetoothProfile.STATE_DISCONNECTED;
108 }
109
110 /**
111 * Get connected devices for the specified profile.
112 *
113 * <p> Return the set of devices which are in state {@link BluetoothProfile#STATE_CONNECTED}
114 *
115 * <p>This is not specific to any application configuration but represents
116 * the connection state of Bluetooth for this profile.
117 * This can be used by applications like status bar which would just like
118 * to know the state of Bluetooth.
119 *
Matthew Xieddf7e472013-03-01 18:41:02 -0800120 * @param profile GATT or GATT_SERVER
121 * @return List of devices. The list will be empty on error.
122 */
Tor Norbye2d497522015-04-23 17:10:21 -0700123 @RequiresPermission(Manifest.permission.BLUETOOTH)
Matthew Xieddf7e472013-03-01 18:41:02 -0800124 public List<BluetoothDevice> getConnectedDevices(int profile) {
Jack Hea355e5e2017-08-22 16:06:54 -0700125 if (DBG) Log.d(TAG, "getConnectedDevices");
Matthew Xieddf7e472013-03-01 18:41:02 -0800126 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();
Matthew Xiecdd94e32013-04-11 16:36:26 -0700134 IBluetoothGatt iGatt = managerService.getBluetoothGatt();
Matthew Xieddf7e472013-03-01 18:41:02 -0800135 if (iGatt == null) return connectedDevices;
136
137 connectedDevices = iGatt.getDevicesMatchingConnectionStates(
Jack Hea355e5e2017-08-22 16:06:54 -0700138 new int[]{BluetoothProfile.STATE_CONNECTED});
Matthew Xieddf7e472013-03-01 18:41:02 -0800139 } catch (RemoteException e) {
Jack Hea355e5e2017-08-22 16:06:54 -0700140 Log.e(TAG, "", e);
Matthew Xieddf7e472013-03-01 18:41:02 -0800141 }
142
143 return connectedDevices;
144 }
145
146 /**
Matthew Xieddf7e472013-03-01 18:41:02 -0800147 * Get a list of devices that match any of the given connection
148 * states.
149 *
150 * <p> If none of the devices match any of the given states,
151 * an empty list will be returned.
152 *
153 * <p>This is not specific to any application configuration but represents
154 * the connection state of the local Bluetooth adapter for this profile.
155 * This can be used by applications like status bar which would just like
156 * to know the state of the local adapter.
157 *
Matthew Xieddf7e472013-03-01 18:41:02 -0800158 * @param profile GATT or GATT_SERVER
Jack Hea355e5e2017-08-22 16:06:54 -0700159 * @param states Array of states. States can be one of {@link BluetoothProfile#STATE_CONNECTED},
160 * {@link BluetoothProfile#STATE_CONNECTING}, {@link BluetoothProfile#STATE_DISCONNECTED},
161 * {@link BluetoothProfile#STATE_DISCONNECTING},
Matthew Xieddf7e472013-03-01 18:41:02 -0800162 * @return List of devices. The list will be empty on error.
163 */
Tor Norbye2d497522015-04-23 17:10:21 -0700164 @RequiresPermission(Manifest.permission.BLUETOOTH)
Matthew Xieddf7e472013-03-01 18:41:02 -0800165 public List<BluetoothDevice> getDevicesMatchingConnectionStates(int profile, int[] states) {
Jack Hea355e5e2017-08-22 16:06:54 -0700166 if (DBG) Log.d(TAG, "getDevicesMatchingConnectionStates");
Matthew Xieddf7e472013-03-01 18:41:02 -0800167
168 if (profile != BluetoothProfile.GATT && profile != BluetoothProfile.GATT_SERVER) {
169 throw new IllegalArgumentException("Profile not supported: " + profile);
170 }
171
172 List<BluetoothDevice> devices = new ArrayList<BluetoothDevice>();
173
174 try {
175 IBluetoothManager managerService = mAdapter.getBluetoothManager();
Matthew Xiecdd94e32013-04-11 16:36:26 -0700176 IBluetoothGatt iGatt = managerService.getBluetoothGatt();
Matthew Xieddf7e472013-03-01 18:41:02 -0800177 if (iGatt == null) return devices;
178 devices = iGatt.getDevicesMatchingConnectionStates(states);
179 } catch (RemoteException e) {
Jack Hea355e5e2017-08-22 16:06:54 -0700180 Log.e(TAG, "", e);
Matthew Xieddf7e472013-03-01 18:41:02 -0800181 }
182
183 return devices;
184 }
185
186 /**
187 * Open a GATT Server
188 * The callback is used to deliver results to Caller, such as connection status as well
189 * as the results of any other GATT server operations.
190 * The method returns a BluetoothGattServer instance. You can use BluetoothGattServer
191 * to conduct GATT server operations.
Jack Hea355e5e2017-08-22 16:06:54 -0700192 *
Matthew Xieddf7e472013-03-01 18:41:02 -0800193 * @param context App context
194 * @param callback GATT server callback handler that will receive asynchronous callbacks.
195 * @return BluetoothGattServer instance
196 */
197 public BluetoothGattServer openGattServer(Context context,
Jack Hea355e5e2017-08-22 16:06:54 -0700198 BluetoothGattServerCallback callback) {
Ganesh Ganapathi Battab88fa822014-04-18 10:00:40 -0700199
Jack Hea355e5e2017-08-22 16:06:54 -0700200 return (openGattServer(context, callback, BluetoothDevice.TRANSPORT_AUTO));
Ganesh Ganapathi Battab88fa822014-04-18 10:00:40 -0700201 }
202
203 /**
204 * Open a GATT Server
205 * The callback is used to deliver results to Caller, such as connection status as well
206 * as the results of any other GATT server operations.
207 * The method returns a BluetoothGattServer instance. You can use BluetoothGattServer
208 * to conduct GATT server operations.
Jack Hea355e5e2017-08-22 16:06:54 -0700209 *
Ganesh Ganapathi Battab88fa822014-04-18 10:00:40 -0700210 * @param context App context
211 * @param callback GATT server callback handler that will receive asynchronous callbacks.
Jack Hea355e5e2017-08-22 16:06:54 -0700212 * @param transport preferred transport for GATT connections to remote dual-mode devices {@link
213 * BluetoothDevice#TRANSPORT_AUTO} or {@link BluetoothDevice#TRANSPORT_BREDR} or {@link
214 * BluetoothDevice#TRANSPORT_LE}
Ganesh Ganapathi Battab88fa822014-04-18 10:00:40 -0700215 * @return BluetoothGattServer instance
216 * @hide
217 */
218 public BluetoothGattServer openGattServer(Context context,
Jack Hea355e5e2017-08-22 16:06:54 -0700219 BluetoothGattServerCallback callback, int transport) {
Matthew Xieddf7e472013-03-01 18:41:02 -0800220 if (context == null || callback == null) {
221 throw new IllegalArgumentException("null parameter: " + context + " " + callback);
222 }
223
224 // TODO(Bluetooth) check whether platform support BLE
225 // Do the check here or in GattServer?
226
227 try {
228 IBluetoothManager managerService = mAdapter.getBluetoothManager();
Matthew Xiecdd94e32013-04-11 16:36:26 -0700229 IBluetoothGatt iGatt = managerService.getBluetoothGatt();
Matthew Xieddf7e472013-03-01 18:41:02 -0800230 if (iGatt == null) {
231 Log.e(TAG, "Fail to get GATT Server connection");
232 return null;
233 }
Jack Hea355e5e2017-08-22 16:06:54 -0700234 BluetoothGattServer mGattServer = new BluetoothGattServer(iGatt, transport);
Matthew Xieddf7e472013-03-01 18:41:02 -0800235 Boolean regStatus = mGattServer.registerCallback(callback);
Jack Hea355e5e2017-08-22 16:06:54 -0700236 return regStatus ? mGattServer : null;
Matthew Xieddf7e472013-03-01 18:41:02 -0800237 } catch (RemoteException e) {
Jack Hea355e5e2017-08-22 16:06:54 -0700238 Log.e(TAG, "", e);
Matthew Xieddf7e472013-03-01 18:41:02 -0800239 return null;
240 }
241 }
242}