blob: b2b02850e2e2452d3a7ea5c502df7b1b70a7df30 [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
Nick Pellybd022f42009-08-14 18:33:38 -07002 * Copyright (C) 2009 The Android Open Source Project
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003 *
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;
20import android.annotation.RequiresPermission;
Nick Pelly005b2282009-09-10 10:21:56 -070021import android.annotation.SdkConstant;
22import android.annotation.SdkConstant.SdkConstantType;
Andre Eisenbach2b8696e2015-02-05 20:06:33 -080023import android.annotation.SystemApi;
Mathew Inwood4dc66d32018-08-01 15:07:20 +010024import android.annotation.UnsupportedAppUsage;
Matthew Xieddf7e472013-03-01 18:41:02 -080025import android.content.Context;
Jakub Pawlowskib0f64742017-04-21 03:49:00 -070026import android.os.Handler;
Nick Pellybd022f42009-08-14 18:33:38 -070027import android.os.Parcel;
Nick Pellyaef439e2009-09-28 12:33:17 -070028import android.os.ParcelUuid;
Jack Hea355e5e2017-08-22 16:06:54 -070029import android.os.Parcelable;
Christine Hallstrom044b8f32015-11-17 12:24:07 -080030import android.os.Process;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080031import android.os.RemoteException;
32import android.util.Log;
33
Nick Pellybd022f42009-08-14 18:33:38 -070034import java.io.IOException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080035import java.io.UnsupportedEncodingException;
Jaikumar Ganesh1caa6d12009-09-18 11:32:54 -070036import java.util.UUID;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080037
38/**
Scott Main9fab0ae2009-11-03 18:17:59 -080039 * Represents a remote Bluetooth device. A {@link BluetoothDevice} lets you
Jake Hambyf51eada2010-09-21 13:39:53 -070040 * create a connection with the respective device or query information about
Scott Main9fab0ae2009-11-03 18:17:59 -080041 * it, such as the name, address, class, and bonding state.
Nick Pelly45e27042009-08-19 11:00:00 -070042 *
43 * <p>This class is really just a thin wrapper for a Bluetooth hardware
44 * address. Objects of this class are immutable. Operations on this class
45 * are performed on the remote Bluetooth hardware address, using the
46 * {@link BluetoothAdapter} that was used to create this {@link
47 * BluetoothDevice}.
Scott Main9fab0ae2009-11-03 18:17:59 -080048 *
49 * <p>To get a {@link BluetoothDevice}, use
50 * {@link BluetoothAdapter#getRemoteDevice(String)
51 * BluetoothAdapter.getRemoteDevice(String)} to create one representing a device
52 * of a known MAC address (which you can get through device discovery with
53 * {@link BluetoothAdapter}) or get one from the set of bonded devices
54 * returned by {@link BluetoothAdapter#getBondedDevices()
55 * BluetoothAdapter.getBondedDevices()}. You can then open a
Jake Hambyf51eada2010-09-21 13:39:53 -070056 * {@link BluetoothSocket} for communication with the remote device, using
Scott Main9fab0ae2009-11-03 18:17:59 -080057 * {@link #createRfcommSocketToServiceRecord(UUID)}.
58 *
59 * <p class="note"><strong>Note:</strong>
60 * Requires the {@link android.Manifest.permission#BLUETOOTH} permission.
61 *
Joe Fernandez3aef8e1d2011-12-20 10:38:34 -080062 * <div class="special reference">
63 * <h3>Developer Guides</h3>
Hemal Patel65813df2016-08-17 13:18:14 -070064 * <p>
65 * For more information about using Bluetooth, read the <a href=
66 * "{@docRoot}guide/topics/connectivity/bluetooth.html">Bluetooth</a> developer
67 * guide.
68 * </p>
Joe Fernandez3aef8e1d2011-12-20 10:38:34 -080069 * </div>
70 *
Scott Main9fab0ae2009-11-03 18:17:59 -080071 * {@see BluetoothAdapter}
72 * {@see BluetoothSocket}
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080073 */
Nick Pellybd022f42009-08-14 18:33:38 -070074public final class BluetoothDevice implements Parcelable {
75 private static final String TAG = "BluetoothDevice";
Ravi Nagarajan70772722012-04-23 04:06:49 -070076 private static final boolean DBG = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080077
Nick Pellyb24e11b2009-09-08 17:40:43 -070078 /**
Andre Eisenbach2b8696e2015-02-05 20:06:33 -080079 * Connection state bitmask as returned by getConnectionState.
80 */
81 private static final int CONNECTION_STATE_DISCONNECTED = 0;
82 private static final int CONNECTION_STATE_CONNECTED = 1;
83 private static final int CONNECTION_STATE_ENCRYPTED_BREDR = 2;
84 private static final int CONNECTION_STATE_ENCRYPTED_LE = 4;
85
86 /**
Nick Pellyb24e11b2009-09-08 17:40:43 -070087 * Sentinel error value for this class. Guaranteed to not equal any other
88 * integer constant in this class. Provided as a convenience for functions
89 * that require a sentinel error value, for example:
Nick Pelly005b2282009-09-10 10:21:56 -070090 * <p><code>Intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE,
91 * BluetoothDevice.ERROR)</code>
Nick Pellyb24e11b2009-09-08 17:40:43 -070092 */
Nick Pelly005b2282009-09-10 10:21:56 -070093 public static final int ERROR = Integer.MIN_VALUE;
Nick Pellyb24e11b2009-09-08 17:40:43 -070094
Nick Pelly005b2282009-09-10 10:21:56 -070095 /**
96 * Broadcast Action: Remote device discovered.
97 * <p>Sent when a remote device is found during discovery.
98 * <p>Always contains the extra fields {@link #EXTRA_DEVICE} and {@link
99 * #EXTRA_CLASS}. Can contain the extra fields {@link #EXTRA_NAME} and/or
100 * {@link #EXTRA_RSSI} if they are available.
Fyodor Kupolov72f491d2015-07-14 11:38:58 -0700101 * <p>Requires {@link android.Manifest.permission#BLUETOOTH} and
102 * {@link android.Manifest.permission#ACCESS_COARSE_LOCATION} to receive.
Nick Pelly005b2282009-09-10 10:21:56 -0700103 */
Jack Hea355e5e2017-08-22 16:06:54 -0700104 // TODO: Change API to not broadcast RSSI if not available (incoming connection)
Nick Pelly005b2282009-09-10 10:21:56 -0700105 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
106 public static final String ACTION_FOUND =
107 "android.bluetooth.device.action.FOUND";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800108
Nick Pelly005b2282009-09-10 10:21:56 -0700109 /**
Nick Pelly005b2282009-09-10 10:21:56 -0700110 * Broadcast Action: Bluetooth class of a remote device has changed.
111 * <p>Always contains the extra fields {@link #EXTRA_DEVICE} and {@link
112 * #EXTRA_CLASS}.
113 * <p>Requires {@link android.Manifest.permission#BLUETOOTH} to receive.
Matthew Xieb30f91e2013-05-29 10:19:06 -0700114 * {@see BluetoothClass}
Nick Pelly005b2282009-09-10 10:21:56 -0700115 */
116 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
117 public static final String ACTION_CLASS_CHANGED =
118 "android.bluetooth.device.action.CLASS_CHANGED";
119
120 /**
121 * Broadcast Action: Indicates a low level (ACL) connection has been
122 * established with a remote device.
123 * <p>Always contains the extra field {@link #EXTRA_DEVICE}.
124 * <p>ACL connections are managed automatically by the Android Bluetooth
125 * stack.
126 * <p>Requires {@link android.Manifest.permission#BLUETOOTH} to receive.
127 */
128 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
129 public static final String ACTION_ACL_CONNECTED =
130 "android.bluetooth.device.action.ACL_CONNECTED";
131
132 /**
133 * Broadcast Action: Indicates that a low level (ACL) disconnection has
134 * been requested for a remote device, and it will soon be disconnected.
135 * <p>This is useful for graceful disconnection. Applications should use
136 * this intent as a hint to immediately terminate higher level connections
137 * (RFCOMM, L2CAP, or profile connections) to the remote device.
138 * <p>Always contains the extra field {@link #EXTRA_DEVICE}.
139 * <p>Requires {@link android.Manifest.permission#BLUETOOTH} to receive.
140 */
141 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
142 public static final String ACTION_ACL_DISCONNECT_REQUESTED =
143 "android.bluetooth.device.action.ACL_DISCONNECT_REQUESTED";
144
145 /**
146 * Broadcast Action: Indicates a low level (ACL) disconnection from a
147 * remote device.
148 * <p>Always contains the extra field {@link #EXTRA_DEVICE}.
149 * <p>ACL connections are managed automatically by the Android Bluetooth
150 * stack.
151 * <p>Requires {@link android.Manifest.permission#BLUETOOTH} to receive.
152 */
153 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
154 public static final String ACTION_ACL_DISCONNECTED =
155 "android.bluetooth.device.action.ACL_DISCONNECTED";
156
157 /**
158 * Broadcast Action: Indicates the friendly name of a remote device has
159 * been retrieved for the first time, or changed since the last retrieval.
160 * <p>Always contains the extra fields {@link #EXTRA_DEVICE} and {@link
161 * #EXTRA_NAME}.
162 * <p>Requires {@link android.Manifest.permission#BLUETOOTH} to receive.
163 */
164 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
165 public static final String ACTION_NAME_CHANGED =
166 "android.bluetooth.device.action.NAME_CHANGED";
167
168 /**
Jeff Brown5bbd4b42012-04-20 19:28:00 -0700169 * Broadcast Action: Indicates the alias of a remote device has been
170 * changed.
171 * <p>Always contains the extra field {@link #EXTRA_DEVICE}.
172 * <p>Requires {@link android.Manifest.permission#BLUETOOTH} to receive.
173 *
174 * @hide
175 */
176 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
Mathew Inwood4dc66d32018-08-01 15:07:20 +0100177 @UnsupportedAppUsage
Jeff Brown5bbd4b42012-04-20 19:28:00 -0700178 public static final String ACTION_ALIAS_CHANGED =
179 "android.bluetooth.device.action.ALIAS_CHANGED";
180
181 /**
Nick Pelly005b2282009-09-10 10:21:56 -0700182 * Broadcast Action: Indicates a change in the bond state of a remote
183 * device. For example, if a device is bonded (paired).
184 * <p>Always contains the extra fields {@link #EXTRA_DEVICE}, {@link
185 * #EXTRA_BOND_STATE} and {@link #EXTRA_PREVIOUS_BOND_STATE}.
186 * <p>Requires {@link android.Manifest.permission#BLUETOOTH} to receive.
187 */
188 // Note: When EXTRA_BOND_STATE is BOND_NONE then this will also
189 // contain a hidden extra field EXTRA_REASON with the result code.
190 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
191 public static final String ACTION_BOND_STATE_CHANGED =
192 "android.bluetooth.device.action.BOND_STATE_CHANGED";
193
194 /**
Jack He1d312bf2017-06-16 19:43:58 -0700195 * Broadcast Action: Indicates the battery level of a remote device has
196 * been retrieved for the first time, or changed since the last retrieval
197 * <p>Always contains the extra fields {@link #EXTRA_DEVICE} and {@link
198 * #EXTRA_BATTERY_LEVEL}.
199 * <p>Requires {@link android.Manifest.permission#BLUETOOTH} to receive.
Jack Hea355e5e2017-08-22 16:06:54 -0700200 *
Jack He1d312bf2017-06-16 19:43:58 -0700201 * @hide
202 */
203 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
204 public static final String ACTION_BATTERY_LEVEL_CHANGED =
205 "android.bluetooth.device.action.BATTERY_LEVEL_CHANGED";
206
207 /**
208 * Used as an Integer extra field in {@link #ACTION_BATTERY_LEVEL_CHANGED}
209 * intent. It contains the most recently retrieved battery level information
210 * ranging from 0% to 100% for a remote device, {@link #BATTERY_LEVEL_UNKNOWN}
211 * when the valid is unknown or there is an error
Jack Hea355e5e2017-08-22 16:06:54 -0700212 *
Jack He1d312bf2017-06-16 19:43:58 -0700213 * @hide
214 */
215 public static final String EXTRA_BATTERY_LEVEL =
216 "android.bluetooth.device.extra.BATTERY_LEVEL";
217
218 /**
219 * Used as the unknown value for {@link #EXTRA_BATTERY_LEVEL} and {@link #getBatteryLevel()}
Jack Hea355e5e2017-08-22 16:06:54 -0700220 *
Jack He1d312bf2017-06-16 19:43:58 -0700221 * @hide
222 */
223 public static final int BATTERY_LEVEL_UNKNOWN = -1;
224
225 /**
Nick Pelly005b2282009-09-10 10:21:56 -0700226 * Used as a Parcelable {@link BluetoothDevice} extra field in every intent
227 * broadcast by this class. It contains the {@link BluetoothDevice} that
228 * the intent applies to.
229 */
230 public static final String EXTRA_DEVICE = "android.bluetooth.device.extra.DEVICE";
231
232 /**
233 * Used as a String extra field in {@link #ACTION_NAME_CHANGED} and {@link
234 * #ACTION_FOUND} intents. It contains the friendly Bluetooth name.
235 */
236 public static final String EXTRA_NAME = "android.bluetooth.device.extra.NAME";
237
238 /**
239 * Used as an optional short extra field in {@link #ACTION_FOUND} intents.
240 * Contains the RSSI value of the remote device as reported by the
241 * Bluetooth hardware.
242 */
243 public static final String EXTRA_RSSI = "android.bluetooth.device.extra.RSSI";
244
245 /**
Ken Wakasaf76a50c2012-03-09 19:56:35 +0900246 * Used as a Parcelable {@link BluetoothClass} extra field in {@link
Nick Pelly005b2282009-09-10 10:21:56 -0700247 * #ACTION_FOUND} and {@link #ACTION_CLASS_CHANGED} intents.
248 */
249 public static final String EXTRA_CLASS = "android.bluetooth.device.extra.CLASS";
250
251 /**
252 * Used as an int extra field in {@link #ACTION_BOND_STATE_CHANGED} intents.
253 * Contains the bond state of the remote device.
254 * <p>Possible values are:
255 * {@link #BOND_NONE},
256 * {@link #BOND_BONDING},
257 * {@link #BOND_BONDED}.
Matthew Xie091fc2b2013-09-23 23:23:13 -0700258 */
Nick Pelly005b2282009-09-10 10:21:56 -0700259 public static final String EXTRA_BOND_STATE = "android.bluetooth.device.extra.BOND_STATE";
260 /**
261 * Used as an int extra field in {@link #ACTION_BOND_STATE_CHANGED} intents.
262 * Contains the previous bond state of the remote device.
263 * <p>Possible values are:
264 * {@link #BOND_NONE},
265 * {@link #BOND_BONDING},
266 * {@link #BOND_BONDED}.
Matthew Xie091fc2b2013-09-23 23:23:13 -0700267 */
Nick Pelly005b2282009-09-10 10:21:56 -0700268 public static final String EXTRA_PREVIOUS_BOND_STATE =
269 "android.bluetooth.device.extra.PREVIOUS_BOND_STATE";
270 /**
271 * Indicates the remote device is not bonded (paired).
272 * <p>There is no shared link key with the remote device, so communication
273 * (if it is allowed at all) will be unauthenticated and unencrypted.
274 */
275 public static final int BOND_NONE = 10;
276 /**
277 * Indicates bonding (pairing) is in progress with the remote device.
278 */
279 public static final int BOND_BONDING = 11;
280 /**
281 * Indicates the remote device is bonded (paired).
282 * <p>A shared link keys exists locally for the remote device, so
283 * communication can be authenticated and encrypted.
284 * <p><i>Being bonded (paired) with a remote device does not necessarily
Jake Hambyf51eada2010-09-21 13:39:53 -0700285 * mean the device is currently connected. It just means that the pending
286 * procedure was completed at some earlier time, and the link key is still
Nick Pelly005b2282009-09-10 10:21:56 -0700287 * stored locally, ready to use on the next connection.
288 * </i>
289 */
290 public static final int BOND_BONDED = 12;
291
Matthew Xie091fc2b2013-09-23 23:23:13 -0700292 /**
293 * Used as an int extra field in {@link #ACTION_PAIRING_REQUEST}
294 * intents for unbond reason.
Jack Hea355e5e2017-08-22 16:06:54 -0700295 *
Matthew Xie091fc2b2013-09-23 23:23:13 -0700296 * @hide
297 */
Mathew Inwood4dc66d32018-08-01 15:07:20 +0100298 @UnsupportedAppUsage
Nick Pelly005b2282009-09-10 10:21:56 -0700299 public static final String EXTRA_REASON = "android.bluetooth.device.extra.REASON";
Matthew Xie091fc2b2013-09-23 23:23:13 -0700300
301 /**
302 * Used as an int extra field in {@link #ACTION_PAIRING_REQUEST}
303 * intents to indicate pairing method used. Possible values are:
304 * {@link #PAIRING_VARIANT_PIN},
305 * {@link #PAIRING_VARIANT_PASSKEY_CONFIRMATION},
306 */
Nick Pelly005b2282009-09-10 10:21:56 -0700307 public static final String EXTRA_PAIRING_VARIANT =
308 "android.bluetooth.device.extra.PAIRING_VARIANT";
Matthew Xie091fc2b2013-09-23 23:23:13 -0700309
310 /**
311 * Used as an int extra field in {@link #ACTION_PAIRING_REQUEST}
312 * intents as the value of passkey.
313 */
Jaikumar Ganeshc88b0c62011-01-05 13:49:00 -0800314 public static final String EXTRA_PAIRING_KEY = "android.bluetooth.device.extra.PAIRING_KEY";
Nick Pelly005b2282009-09-10 10:21:56 -0700315
316 /**
Matthew Xie33ec9842013-04-03 00:29:27 -0700317 * Bluetooth device type, Unknown
318 */
319 public static final int DEVICE_TYPE_UNKNOWN = 0;
320
321 /**
322 * Bluetooth device type, Classic - BR/EDR devices
323 */
324 public static final int DEVICE_TYPE_CLASSIC = 1;
325
326 /**
327 * Bluetooth device type, Low Energy - LE-only
328 */
329 public static final int DEVICE_TYPE_LE = 2;
330
331 /**
332 * Bluetooth device type, Dual Mode - BR/EDR/LE
333 */
334 public static final int DEVICE_TYPE_DUAL = 3;
335
Casper Bonde238e0f92015-04-09 09:24:48 +0200336
337 /** @hide */
338 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
Mathew Inwood4dc66d32018-08-01 15:07:20 +0100339 @UnsupportedAppUsage
Casper Bonde238e0f92015-04-09 09:24:48 +0200340 public static final String ACTION_SDP_RECORD =
341 "android.bluetooth.device.action.SDP_RECORD";
342
Matthew Xie33ec9842013-04-03 00:29:27 -0700343 /**
Jaikumar Ganesh1caa6d12009-09-18 11:32:54 -0700344 * Broadcast Action: This intent is used to broadcast the {@link UUID}
Nick Pellyaef439e2009-09-28 12:33:17 -0700345 * wrapped as a {@link android.os.ParcelUuid} of the remote device after it
346 * has been fetched. This intent is sent only when the UUIDs of the remote
347 * device are requested to be fetched using Service Discovery Protocol
Jaikumar Ganesh1caa6d12009-09-18 11:32:54 -0700348 * <p> Always contains the extra field {@link #EXTRA_DEVICE}
Matthew Xiead232102011-11-08 10:58:12 -0800349 * <p> Always contains the extra field {@link #EXTRA_UUID}
Hansong Zhangff1c21c2018-11-12 14:32:03 -0800350 * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN} to receive.
Jaikumar Ganesh1caa6d12009-09-18 11:32:54 -0700351 */
352 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
353 public static final String ACTION_UUID =
Matthew Xiead232102011-11-08 10:58:12 -0800354 "android.bluetooth.device.action.UUID";
Jaikumar Ganesh1caa6d12009-09-18 11:32:54 -0700355
Hemant Gupta8949bfb2013-08-16 14:57:55 +0530356 /** @hide */
357 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
358 public static final String ACTION_MAS_INSTANCE =
359 "android.bluetooth.device.action.MAS_INSTANCE";
360
Jaikumar Ganesh1caa6d12009-09-18 11:32:54 -0700361 /**
Nick Pelly005b2282009-09-10 10:21:56 -0700362 * Broadcast Action: Indicates a failure to retrieve the name of a remote
363 * device.
364 * <p>Always contains the extra field {@link #EXTRA_DEVICE}.
365 * <p>Requires {@link android.Manifest.permission#BLUETOOTH} to receive.
Jack Hea355e5e2017-08-22 16:06:54 -0700366 *
Nick Pelly005b2282009-09-10 10:21:56 -0700367 * @hide
368 */
369 //TODO: is this actually useful?
370 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
371 public static final String ACTION_NAME_FAILED =
372 "android.bluetooth.device.action.NAME_FAILED";
373
Matthew Xie091fc2b2013-09-23 23:23:13 -0700374 /**
375 * Broadcast Action: This intent is used to broadcast PAIRING REQUEST
Matthew Xieac2c6c32013-10-21 14:56:33 -0700376 * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN} to
Edward Jee430e3612013-10-07 18:12:15 -0700377 * receive.
Matthew Xie091fc2b2013-09-23 23:23:13 -0700378 */
Nick Pelly005b2282009-09-10 10:21:56 -0700379 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
380 public static final String ACTION_PAIRING_REQUEST =
381 "android.bluetooth.device.action.PAIRING_REQUEST";
382 /** @hide */
383 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
Mathew Inwood4dc66d32018-08-01 15:07:20 +0100384 @UnsupportedAppUsage
Nick Pelly005b2282009-09-10 10:21:56 -0700385 public static final String ACTION_PAIRING_CANCEL =
386 "android.bluetooth.device.action.PAIRING_CANCEL";
Yue Lixina4433af2009-07-09 16:56:43 +0800387
Matthew Xiea0c68032011-06-25 21:47:07 -0700388 /** @hide */
389 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
390 public static final String ACTION_CONNECTION_ACCESS_REQUEST =
391 "android.bluetooth.device.action.CONNECTION_ACCESS_REQUEST";
392
393 /** @hide */
394 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
395 public static final String ACTION_CONNECTION_ACCESS_REPLY =
396 "android.bluetooth.device.action.CONNECTION_ACCESS_REPLY";
397
398 /** @hide */
399 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
400 public static final String ACTION_CONNECTION_ACCESS_CANCEL =
401 "android.bluetooth.device.action.CONNECTION_ACCESS_CANCEL";
402
403 /**
404 * Used as an extra field in {@link #ACTION_CONNECTION_ACCESS_REQUEST} intent.
Jack Hea355e5e2017-08-22 16:06:54 -0700405 *
Matthew Xiea0c68032011-06-25 21:47:07 -0700406 * @hide
407 */
408 public static final String EXTRA_ACCESS_REQUEST_TYPE =
Jack Hea355e5e2017-08-22 16:06:54 -0700409 "android.bluetooth.device.extra.ACCESS_REQUEST_TYPE";
Matthew Xiea0c68032011-06-25 21:47:07 -0700410
Jack Hea355e5e2017-08-22 16:06:54 -0700411 /** @hide */
Matthew Xiea0c68032011-06-25 21:47:07 -0700412 public static final int REQUEST_TYPE_PROFILE_CONNECTION = 1;
413
Jack Hea355e5e2017-08-22 16:06:54 -0700414 /** @hide */
Matthew Xiea0c68032011-06-25 21:47:07 -0700415 public static final int REQUEST_TYPE_PHONEBOOK_ACCESS = 2;
416
Jack Hea355e5e2017-08-22 16:06:54 -0700417 /** @hide */
Matthew Xiefe3807a2013-07-18 17:31:50 -0700418 public static final int REQUEST_TYPE_MESSAGE_ACCESS = 3;
419
Jack Hea355e5e2017-08-22 16:06:54 -0700420 /** @hide */
Casper Bonde2a5f6082015-03-19 10:36:45 +0100421 public static final int REQUEST_TYPE_SIM_ACCESS = 4;
422
Matthew Xiea0c68032011-06-25 21:47:07 -0700423 /**
424 * Used as an extra field in {@link #ACTION_CONNECTION_ACCESS_REQUEST} intents,
425 * Contains package name to return reply intent to.
Jack Hea355e5e2017-08-22 16:06:54 -0700426 *
Matthew Xiea0c68032011-06-25 21:47:07 -0700427 * @hide
428 */
429 public static final String EXTRA_PACKAGE_NAME = "android.bluetooth.device.extra.PACKAGE_NAME";
430
431 /**
432 * Used as an extra field in {@link #ACTION_CONNECTION_ACCESS_REQUEST} intents,
433 * Contains class name to return reply intent to.
Jack Hea355e5e2017-08-22 16:06:54 -0700434 *
Matthew Xiea0c68032011-06-25 21:47:07 -0700435 * @hide
436 */
437 public static final String EXTRA_CLASS_NAME = "android.bluetooth.device.extra.CLASS_NAME";
438
439 /**
440 * Used as an extra field in {@link #ACTION_CONNECTION_ACCESS_REPLY} intent.
Jack Hea355e5e2017-08-22 16:06:54 -0700441 *
Matthew Xiea0c68032011-06-25 21:47:07 -0700442 * @hide
443 */
444 public static final String EXTRA_CONNECTION_ACCESS_RESULT =
Jack Hea355e5e2017-08-22 16:06:54 -0700445 "android.bluetooth.device.extra.CONNECTION_ACCESS_RESULT";
Matthew Xiea0c68032011-06-25 21:47:07 -0700446
Jack Hea355e5e2017-08-22 16:06:54 -0700447 /** @hide */
Matthew Xiea0c68032011-06-25 21:47:07 -0700448 public static final int CONNECTION_ACCESS_YES = 1;
449
Jack Hea355e5e2017-08-22 16:06:54 -0700450 /** @hide */
Matthew Xiea0c68032011-06-25 21:47:07 -0700451 public static final int CONNECTION_ACCESS_NO = 2;
452
453 /**
454 * Used as an extra field in {@link #ACTION_CONNECTION_ACCESS_REPLY} intents,
455 * Contains boolean to indicate if the allowed response is once-for-all so that
456 * next request will be granted without asking user again.
Jack Hea355e5e2017-08-22 16:06:54 -0700457 *
Matthew Xiea0c68032011-06-25 21:47:07 -0700458 * @hide
459 */
460 public static final String EXTRA_ALWAYS_ALLOWED =
Jack Hea355e5e2017-08-22 16:06:54 -0700461 "android.bluetooth.device.extra.ALWAYS_ALLOWED";
Matthew Xiea0c68032011-06-25 21:47:07 -0700462
Jaikumar Ganeshc88b0c62011-01-05 13:49:00 -0800463 /**
464 * A bond attempt succeeded
Jack Hea355e5e2017-08-22 16:06:54 -0700465 *
Jaikumar Ganeshc88b0c62011-01-05 13:49:00 -0800466 * @hide
467 */
Nick Pellyb24e11b2009-09-08 17:40:43 -0700468 public static final int BOND_SUCCESS = 0;
Jaikumar Ganeshc88b0c62011-01-05 13:49:00 -0800469
470 /**
471 * A bond attempt failed because pins did not match, or remote device did
Jaikumar Ganesh32d85712009-09-10 22:00:05 -0700472 * not respond to pin request in time
Jack Hea355e5e2017-08-22 16:06:54 -0700473 *
Jaikumar Ganeshc88b0c62011-01-05 13:49:00 -0800474 * @hide
475 */
Mathew Inwood4dc66d32018-08-01 15:07:20 +0100476 @UnsupportedAppUsage
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800477 public static final int UNBOND_REASON_AUTH_FAILED = 1;
Jaikumar Ganeshc88b0c62011-01-05 13:49:00 -0800478
479 /**
480 * A bond attempt failed because the other side explicitly rejected
Nick Pelly45e27042009-08-19 11:00:00 -0700481 * bonding
Jack Hea355e5e2017-08-22 16:06:54 -0700482 *
Jaikumar Ganeshc88b0c62011-01-05 13:49:00 -0800483 * @hide
484 */
Mathew Inwood4dc66d32018-08-01 15:07:20 +0100485 @UnsupportedAppUsage
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800486 public static final int UNBOND_REASON_AUTH_REJECTED = 2;
Jaikumar Ganeshc88b0c62011-01-05 13:49:00 -0800487
488 /**
489 * A bond attempt failed because we canceled the bonding process
Jack Hea355e5e2017-08-22 16:06:54 -0700490 *
Jaikumar Ganeshc88b0c62011-01-05 13:49:00 -0800491 * @hide
492 */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800493 public static final int UNBOND_REASON_AUTH_CANCELED = 3;
Jaikumar Ganeshc88b0c62011-01-05 13:49:00 -0800494
495 /**
496 * A bond attempt failed because we could not contact the remote device
Jack Hea355e5e2017-08-22 16:06:54 -0700497 *
Jaikumar Ganeshc88b0c62011-01-05 13:49:00 -0800498 * @hide
499 */
Mathew Inwood4dc66d32018-08-01 15:07:20 +0100500 @UnsupportedAppUsage
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800501 public static final int UNBOND_REASON_REMOTE_DEVICE_DOWN = 4;
Jaikumar Ganeshc88b0c62011-01-05 13:49:00 -0800502
503 /**
504 * A bond attempt failed because a discovery is in progress
Jack Hea355e5e2017-08-22 16:06:54 -0700505 *
Jaikumar Ganeshc88b0c62011-01-05 13:49:00 -0800506 * @hide
507 */
Mathew Inwood4dc66d32018-08-01 15:07:20 +0100508 @UnsupportedAppUsage
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800509 public static final int UNBOND_REASON_DISCOVERY_IN_PROGRESS = 5;
Jaikumar Ganeshc88b0c62011-01-05 13:49:00 -0800510
511 /**
512 * A bond attempt failed because of authentication timeout
Jack Hea355e5e2017-08-22 16:06:54 -0700513 *
Jaikumar Ganeshc88b0c62011-01-05 13:49:00 -0800514 * @hide
515 */
Mathew Inwood4dc66d32018-08-01 15:07:20 +0100516 @UnsupportedAppUsage
Jaikumar Ganesh32d85712009-09-10 22:00:05 -0700517 public static final int UNBOND_REASON_AUTH_TIMEOUT = 6;
Jaikumar Ganeshc88b0c62011-01-05 13:49:00 -0800518
519 /**
520 * A bond attempt failed because of repeated attempts
Jack Hea355e5e2017-08-22 16:06:54 -0700521 *
Jaikumar Ganeshc88b0c62011-01-05 13:49:00 -0800522 * @hide
523 */
Mathew Inwood4dc66d32018-08-01 15:07:20 +0100524 @UnsupportedAppUsage
Jaikumar Ganesh32d85712009-09-10 22:00:05 -0700525 public static final int UNBOND_REASON_REPEATED_ATTEMPTS = 7;
Jaikumar Ganeshc88b0c62011-01-05 13:49:00 -0800526
527 /**
528 * A bond attempt failed because we received an Authentication Cancel
529 * by remote end
Jack Hea355e5e2017-08-22 16:06:54 -0700530 *
Jaikumar Ganeshc88b0c62011-01-05 13:49:00 -0800531 * @hide
532 */
Mathew Inwood4dc66d32018-08-01 15:07:20 +0100533 @UnsupportedAppUsage
Jaikumar Ganeshe5d93b72009-10-08 02:27:52 -0700534 public static final int UNBOND_REASON_REMOTE_AUTH_CANCELED = 8;
Jaikumar Ganeshc88b0c62011-01-05 13:49:00 -0800535
536 /**
537 * An existing bond was explicitly revoked
Jack Hea355e5e2017-08-22 16:06:54 -0700538 *
Jaikumar Ganeshc88b0c62011-01-05 13:49:00 -0800539 * @hide
540 */
Jaikumar Ganeshe5d93b72009-10-08 02:27:52 -0700541 public static final int UNBOND_REASON_REMOVED = 9;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800542
Jaikumar Ganeshc88b0c62011-01-05 13:49:00 -0800543 /**
Matthew Xie091fc2b2013-09-23 23:23:13 -0700544 * The user will be prompted to enter a pin or
Matthew Xieac2c6c32013-10-21 14:56:33 -0700545 * an app will enter a pin for user.
Jaikumar Ganeshc88b0c62011-01-05 13:49:00 -0800546 */
Jaikumar Ganeshb0eca412009-07-16 18:26:28 -0700547 public static final int PAIRING_VARIANT_PIN = 0;
Jaikumar Ganeshc88b0c62011-01-05 13:49:00 -0800548
549 /**
550 * The user will be prompted to enter a passkey
Jack Hea355e5e2017-08-22 16:06:54 -0700551 *
Jaikumar Ganeshc88b0c62011-01-05 13:49:00 -0800552 * @hide
553 */
Jaikumar Ganeshb0eca412009-07-16 18:26:28 -0700554 public static final int PAIRING_VARIANT_PASSKEY = 1;
Jaikumar Ganeshc88b0c62011-01-05 13:49:00 -0800555
556 /**
Matthew Xie091fc2b2013-09-23 23:23:13 -0700557 * The user will be prompted to confirm the passkey displayed on the screen or
Matthew Xieac2c6c32013-10-21 14:56:33 -0700558 * an app will confirm the passkey for the user.
Jaikumar Ganeshc88b0c62011-01-05 13:49:00 -0800559 */
Jaikumar Ganesh32d85712009-09-10 22:00:05 -0700560 public static final int PAIRING_VARIANT_PASSKEY_CONFIRMATION = 2;
Jaikumar Ganeshc88b0c62011-01-05 13:49:00 -0800561
562 /**
563 * The user will be prompted to accept or deny the incoming pairing request
Jack Hea355e5e2017-08-22 16:06:54 -0700564 *
Jaikumar Ganeshc88b0c62011-01-05 13:49:00 -0800565 * @hide
566 */
Jaikumar Ganesh32d85712009-09-10 22:00:05 -0700567 public static final int PAIRING_VARIANT_CONSENT = 3;
Jaikumar Ganeshc88b0c62011-01-05 13:49:00 -0800568
569 /**
570 * The user will be prompted to enter the passkey displayed on remote device
571 * This is used for Bluetooth 2.1 pairing.
Jack Hea355e5e2017-08-22 16:06:54 -0700572 *
Jaikumar Ganeshc88b0c62011-01-05 13:49:00 -0800573 * @hide
574 */
Jaikumar Ganesh32d85712009-09-10 22:00:05 -0700575 public static final int PAIRING_VARIANT_DISPLAY_PASSKEY = 4;
Jaikumar Ganeshc88b0c62011-01-05 13:49:00 -0800576
577 /**
578 * The user will be prompted to enter the PIN displayed on remote device.
579 * This is used for Bluetooth 2.0 pairing.
Jack Hea355e5e2017-08-22 16:06:54 -0700580 *
Jaikumar Ganeshc88b0c62011-01-05 13:49:00 -0800581 * @hide
582 */
583 public static final int PAIRING_VARIANT_DISPLAY_PIN = 5;
584
585 /**
586 * The user will be prompted to accept or deny the OOB pairing request
Jack Hea355e5e2017-08-22 16:06:54 -0700587 *
Jaikumar Ganeshc88b0c62011-01-05 13:49:00 -0800588 * @hide
589 */
590 public static final int PAIRING_VARIANT_OOB_CONSENT = 6;
591
Jaikumar Ganesh1caa6d12009-09-18 11:32:54 -0700592 /**
Casper Bonde3b3d1fe2015-05-08 14:32:24 +0200593 * The user will be prompted to enter a 16 digit pin or
594 * an app will enter a 16 digit pin for user.
Jack Hea355e5e2017-08-22 16:06:54 -0700595 *
Casper Bonde3b3d1fe2015-05-08 14:32:24 +0200596 * @hide
597 */
598 public static final int PAIRING_VARIANT_PIN_16_DIGITS = 7;
599
600 /**
Jaikumar Ganesh1caa6d12009-09-18 11:32:54 -0700601 * Used as an extra field in {@link #ACTION_UUID} intents,
Nick Pellyaef439e2009-09-28 12:33:17 -0700602 * Contains the {@link android.os.ParcelUuid}s of the remote device which
603 * is a parcelable version of {@link UUID}.
Jaikumar Ganesh1caa6d12009-09-18 11:32:54 -0700604 */
605 public static final String EXTRA_UUID = "android.bluetooth.device.extra.UUID";
606
Casper Bonde238e0f92015-04-09 09:24:48 +0200607 /** @hide */
608 public static final String EXTRA_SDP_RECORD =
Jack Hea355e5e2017-08-22 16:06:54 -0700609 "android.bluetooth.device.extra.SDP_RECORD";
Casper Bonde238e0f92015-04-09 09:24:48 +0200610
611 /** @hide */
Mathew Inwood4dc66d32018-08-01 15:07:20 +0100612 @UnsupportedAppUsage
Casper Bonde238e0f92015-04-09 09:24:48 +0200613 public static final String EXTRA_SDP_SEARCH_STATUS =
614 "android.bluetooth.device.extra.SDP_SEARCH_STATUS";
Edward Jee8dd30aa2014-09-05 00:29:14 -0700615 /**
616 * For {@link #getPhonebookAccessPermission}, {@link #setPhonebookAccessPermission},
617 * {@link #getMessageAccessPermission} and {@link #setMessageAccessPermission}.
Jack Hea355e5e2017-08-22 16:06:54 -0700618 *
Edward Jee8dd30aa2014-09-05 00:29:14 -0700619 * @hide
620 */
Selim Gurun17a26c72018-01-09 14:35:19 -0800621 @SystemApi
Edward Jee8dd30aa2014-09-05 00:29:14 -0700622 public static final int ACCESS_UNKNOWN = 0;
623
624 /**
625 * For {@link #getPhonebookAccessPermission}, {@link #setPhonebookAccessPermission},
626 * {@link #getMessageAccessPermission} and {@link #setMessageAccessPermission}.
Jack Hea355e5e2017-08-22 16:06:54 -0700627 *
Edward Jee8dd30aa2014-09-05 00:29:14 -0700628 * @hide
629 */
Selim Gurun17a26c72018-01-09 14:35:19 -0800630 @SystemApi
Edward Jee8dd30aa2014-09-05 00:29:14 -0700631 public static final int ACCESS_ALLOWED = 1;
632
633 /**
634 * For {@link #getPhonebookAccessPermission}, {@link #setPhonebookAccessPermission},
635 * {@link #getMessageAccessPermission} and {@link #setMessageAccessPermission}.
Jack Hea355e5e2017-08-22 16:06:54 -0700636 *
Edward Jee8dd30aa2014-09-05 00:29:14 -0700637 * @hide
638 */
Selim Gurun17a26c72018-01-09 14:35:19 -0800639 @SystemApi
Edward Jee8dd30aa2014-09-05 00:29:14 -0700640 public static final int ACCESS_REJECTED = 2;
641
Jack Hea355e5e2017-08-22 16:06:54 -0700642 /**
643 * No preferrence of physical transport for GATT connections to remote dual-mode devices
644 */
Ganesh Ganapathi Battab88fa822014-04-18 10:00:40 -0700645 public static final int TRANSPORT_AUTO = 0;
646
647 /**
648 * Prefer BR/EDR transport for GATT connections to remote dual-mode devices
Ganesh Ganapathi Battab88fa822014-04-18 10:00:40 -0700649 */
Hemant Gupta8949bfb2013-08-16 14:57:55 +0530650 public static final int TRANSPORT_BREDR = 1;
Ganesh Ganapathi Battab88fa822014-04-18 10:00:40 -0700651
652 /**
653 * Prefer LE transport for GATT connections to remote dual-mode devices
Ganesh Ganapathi Battab88fa822014-04-18 10:00:40 -0700654 */
Hemant Gupta8949bfb2013-08-16 14:57:55 +0530655 public static final int TRANSPORT_LE = 2;
Ganesh Ganapathi Battab88fa822014-04-18 10:00:40 -0700656
Jakub Pawlowski409cee62017-02-02 08:07:12 -0800657 /**
Jakub Pawlowski91fe3082017-04-21 04:26:12 -0700658 * Bluetooth LE 1M PHY. Used to refer to LE 1M Physical Channel for advertising, scanning or
659 * connection.
Jakub Pawlowski409cee62017-02-02 08:07:12 -0800660 */
661 public static final int PHY_LE_1M = 1;
662
663 /**
Jakub Pawlowski91fe3082017-04-21 04:26:12 -0700664 * Bluetooth LE 2M PHY. Used to refer to LE 2M Physical Channel for advertising, scanning or
665 * connection.
Jakub Pawlowski409cee62017-02-02 08:07:12 -0800666 */
667 public static final int PHY_LE_2M = 2;
668
669 /**
Jakub Pawlowski91fe3082017-04-21 04:26:12 -0700670 * Bluetooth LE Coded PHY. Used to refer to LE Coded Physical Channel for advertising, scanning
671 * or connection.
Jakub Pawlowski409cee62017-02-02 08:07:12 -0800672 */
Jakub Pawlowskia5151372017-04-12 08:51:22 -0700673 public static final int PHY_LE_CODED = 3;
Jakub Pawlowski409cee62017-02-02 08:07:12 -0800674
675 /**
Jakub Pawlowski91fe3082017-04-21 04:26:12 -0700676 * Bluetooth LE 1M PHY mask. Used to specify LE 1M Physical Channel as one of many available
677 * options in a bitmask.
Jakub Pawlowski409cee62017-02-02 08:07:12 -0800678 */
Jakub Pawlowskia5151372017-04-12 08:51:22 -0700679 public static final int PHY_LE_1M_MASK = 1;
680
681 /**
Jakub Pawlowski91fe3082017-04-21 04:26:12 -0700682 * Bluetooth LE 2M PHY mask. Used to specify LE 2M Physical Channel as one of many available
683 * options in a bitmask.
Jakub Pawlowskia5151372017-04-12 08:51:22 -0700684 */
685 public static final int PHY_LE_2M_MASK = 2;
686
687 /**
Jakub Pawlowski91fe3082017-04-21 04:26:12 -0700688 * Bluetooth LE Coded PHY mask. Used to specify LE Coded Physical Channel as one of many
689 * available options in a bitmask.
Jakub Pawlowskia5151372017-04-12 08:51:22 -0700690 */
691 public static final int PHY_LE_CODED_MASK = 4;
Jakub Pawlowski409cee62017-02-02 08:07:12 -0800692
693 /**
694 * No preferred coding when transmitting on the LE Coded PHY.
695 */
696 public static final int PHY_OPTION_NO_PREFERRED = 0;
697
698 /**
699 * Prefer the S=2 coding to be used when transmitting on the LE Coded PHY.
700 */
701 public static final int PHY_OPTION_S2 = 1;
702
703 /**
704 * Prefer the S=8 coding to be used when transmitting on the LE Coded PHY.
705 */
706 public static final int PHY_OPTION_S8 = 2;
707
708
Hemant Gupta8949bfb2013-08-16 14:57:55 +0530709 /** @hide */
710 public static final String EXTRA_MAS_INSTANCE =
Jack Hea355e5e2017-08-22 16:06:54 -0700711 "android.bluetooth.device.extra.MAS_INSTANCE";
Ganesh Ganapathi Battab88fa822014-04-18 10:00:40 -0700712
Nick Pelly16fb88a2009-10-07 07:44:03 +0200713 /**
714 * Lazy initialization. Guaranteed final after first object constructed, or
715 * getService() called.
716 * TODO: Unify implementation of sService amongst BluetoothFoo API's
717 */
Jack He16eeac32017-08-17 12:11:18 -0700718 private static volatile IBluetooth sService;
Jaikumar Ganeshd5ac1ae2009-05-05 22:26:12 -0700719
Nick Pellybd022f42009-08-14 18:33:38 -0700720 private final String mAddress;
721
Jack Hea355e5e2017-08-22 16:06:54 -0700722 /*package*/
Mathew Inwood4dc66d32018-08-01 15:07:20 +0100723 @UnsupportedAppUsage
Jack Hea355e5e2017-08-22 16:06:54 -0700724 static IBluetooth getService() {
Nick Pelly16fb88a2009-10-07 07:44:03 +0200725 synchronized (BluetoothDevice.class) {
726 if (sService == null) {
fredc0f420372012-04-12 00:02:00 -0700727 BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
Jack He2992cd02017-08-22 21:21:23 -0700728 sService = adapter.getBluetoothService(sStateChangeCallback);
Nick Pelly16fb88a2009-10-07 07:44:03 +0200729 }
730 }
731 return sService;
732 }
733
Jack He2992cd02017-08-22 21:21:23 -0700734 static IBluetoothManagerCallback sStateChangeCallback = new IBluetoothManagerCallback.Stub() {
fredc903ac6f2012-04-24 03:59:57 -0700735
736 public void onBluetoothServiceUp(IBluetooth bluetoothService)
737 throws RemoteException {
738 synchronized (BluetoothDevice.class) {
Nitin Arorad055adb2015-03-02 15:03:51 -0800739 if (sService == null) {
740 sService = bluetoothService;
741 }
fredc903ac6f2012-04-24 03:59:57 -0700742 }
743 }
744
745 public void onBluetoothServiceDown()
Jack Hea355e5e2017-08-22 16:06:54 -0700746 throws RemoteException {
fredc903ac6f2012-04-24 03:59:57 -0700747 synchronized (BluetoothDevice.class) {
748 sService = null;
749 }
750 }
Nitin Arorad055adb2015-03-02 15:03:51 -0800751
Jack Hea355e5e2017-08-22 16:06:54 -0700752 public void onBrEdrDown() {
Nitin Arorad055adb2015-03-02 15:03:51 -0800753 if (DBG) Log.d(TAG, "onBrEdrDown: reached BLE ON state");
754 }
fredc903ac6f2012-04-24 03:59:57 -0700755 };
Jack Hea355e5e2017-08-22 16:06:54 -0700756
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800757 /**
Nick Pellybd022f42009-08-14 18:33:38 -0700758 * Create a new BluetoothDevice
759 * Bluetooth MAC address must be upper case, such as "00:11:22:33:AA:BB",
760 * and is validated in this constructor.
Jack Hea355e5e2017-08-22 16:06:54 -0700761 *
Nick Pellybd022f42009-08-14 18:33:38 -0700762 * @param address valid Bluetooth MAC address
763 * @throws RuntimeException Bluetooth is not available on this platform
764 * @throws IllegalArgumentException address is invalid
765 * @hide
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800766 */
Mathew Inwood4dc66d32018-08-01 15:07:20 +0100767 @UnsupportedAppUsage
Nick Pellybd022f42009-08-14 18:33:38 -0700768 /*package*/ BluetoothDevice(String address) {
Nick Pelly16fb88a2009-10-07 07:44:03 +0200769 getService(); // ensures sService is initialized
Nick Pelly005b2282009-09-10 10:21:56 -0700770 if (!BluetoothAdapter.checkBluetoothAddress(address)) {
Nick Pellybd022f42009-08-14 18:33:38 -0700771 throw new IllegalArgumentException(address + " is not a valid Bluetooth address");
772 }
773
774 mAddress = address;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800775 }
776
Nick Pellybd022f42009-08-14 18:33:38 -0700777 @Override
778 public boolean equals(Object o) {
779 if (o instanceof BluetoothDevice) {
Jack Hea355e5e2017-08-22 16:06:54 -0700780 return mAddress.equals(((BluetoothDevice) o).getAddress());
Nick Pellybd022f42009-08-14 18:33:38 -0700781 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800782 return false;
783 }
784
Nick Pellybd022f42009-08-14 18:33:38 -0700785 @Override
786 public int hashCode() {
787 return mAddress.hashCode();
The Android Open Source Project10592532009-03-18 17:39:46 -0700788 }
789
Nick Pelly45e27042009-08-19 11:00:00 -0700790 /**
791 * Returns a string representation of this BluetoothDevice.
792 * <p>Currently this is the Bluetooth hardware address, for example
793 * "00:11:22:AA:BB:CC". However, you should always use {@link #getAddress}
794 * if you explicitly require the Bluetooth hardware address in case the
795 * {@link #toString} representation changes in the future.
Jack Hea355e5e2017-08-22 16:06:54 -0700796 *
Nick Pelly45e27042009-08-19 11:00:00 -0700797 * @return string representation of this BluetoothDevice
798 */
Nick Pellybd022f42009-08-14 18:33:38 -0700799 @Override
800 public String toString() {
801 return mAddress;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800802 }
803
Jack He2992cd02017-08-22 21:21:23 -0700804 @Override
Nick Pellybd022f42009-08-14 18:33:38 -0700805 public int describeContents() {
806 return 0;
807 }
808
809 public static final Parcelable.Creator<BluetoothDevice> CREATOR =
810 new Parcelable.Creator<BluetoothDevice>() {
Jack Hea355e5e2017-08-22 16:06:54 -0700811 public BluetoothDevice createFromParcel(Parcel in) {
812 return new BluetoothDevice(in.readString());
813 }
814
815 public BluetoothDevice[] newArray(int size) {
816 return new BluetoothDevice[size];
817 }
818 };
Nick Pellybd022f42009-08-14 18:33:38 -0700819
Jack He2992cd02017-08-22 21:21:23 -0700820 @Override
Nick Pellybd022f42009-08-14 18:33:38 -0700821 public void writeToParcel(Parcel out, int flags) {
822 out.writeString(mAddress);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800823 }
824
Nick Pelly45e27042009-08-19 11:00:00 -0700825 /**
826 * Returns the hardware address of this BluetoothDevice.
827 * <p> For example, "00:11:22:AA:BB:CC".
Jack Hea355e5e2017-08-22 16:06:54 -0700828 *
Nick Pelly45e27042009-08-19 11:00:00 -0700829 * @return Bluetooth hardware address as string
830 */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800831 public String getAddress() {
fredc0f420372012-04-12 00:02:00 -0700832 if (DBG) Log.d(TAG, "mAddress: " + mAddress);
Nick Pellybd022f42009-08-14 18:33:38 -0700833 return mAddress;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800834 }
835
836 /**
Nick Pelly45e27042009-08-19 11:00:00 -0700837 * Get the friendly Bluetooth name of the remote device.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800838 *
Nick Pelly45e27042009-08-19 11:00:00 -0700839 * <p>The local adapter will automatically retrieve remote names when
840 * performing a device scan, and will cache them. This method just returns
841 * the name for this device from the cache.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800842 *
843 * @return the Bluetooth name, or null if there was a problem.
844 */
Tor Norbye2d497522015-04-23 17:10:21 -0700845 @RequiresPermission(Manifest.permission.BLUETOOTH)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800846 public String getName() {
Jack He16eeac32017-08-17 12:11:18 -0700847 final IBluetooth service = sService;
848 if (service == null) {
fredc0f420372012-04-12 00:02:00 -0700849 Log.e(TAG, "BT not enabled. Cannot get Remote Device name");
850 return null;
851 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800852 try {
Hansong Zhang2e3bf462018-04-26 14:22:39 -0700853 String name = service.getRemoteName(this);
854 if (name != null) {
855 return name.replaceAll("[\\t\\n\\r]+", " ");
856 }
857 return null;
Jack Hea355e5e2017-08-22 16:06:54 -0700858 } catch (RemoteException e) {
859 Log.e(TAG, "", e);
860 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800861 return null;
862 }
863
864 /**
Matthew Xie33ec9842013-04-03 00:29:27 -0700865 * Get the Bluetooth device type of the remote device.
866 *
Jack Hea355e5e2017-08-22 16:06:54 -0700867 * @return the device type {@link #DEVICE_TYPE_CLASSIC}, {@link #DEVICE_TYPE_LE} {@link
868 * #DEVICE_TYPE_DUAL}. {@link #DEVICE_TYPE_UNKNOWN} if it's not available
Matthew Xie33ec9842013-04-03 00:29:27 -0700869 */
Tor Norbye2d497522015-04-23 17:10:21 -0700870 @RequiresPermission(Manifest.permission.BLUETOOTH)
Matthew Xie33ec9842013-04-03 00:29:27 -0700871 public int getType() {
Jack He16eeac32017-08-17 12:11:18 -0700872 final IBluetooth service = sService;
873 if (service == null) {
Matthew Xie33ec9842013-04-03 00:29:27 -0700874 Log.e(TAG, "BT not enabled. Cannot get Remote Device type");
875 return DEVICE_TYPE_UNKNOWN;
876 }
877 try {
Jack He16eeac32017-08-17 12:11:18 -0700878 return service.getRemoteType(this);
Jack Hea355e5e2017-08-22 16:06:54 -0700879 } catch (RemoteException e) {
880 Log.e(TAG, "", e);
881 }
Matthew Xie33ec9842013-04-03 00:29:27 -0700882 return DEVICE_TYPE_UNKNOWN;
883 }
884
885 /**
Matthew Xie269e81a2011-07-26 18:36:49 -0700886 * Get the Bluetooth alias of the remote device.
887 * <p>Alias is the locally modified name of a remote device.
888 *
889 * @return the Bluetooth alias, or null if no alias or there was a problem
890 * @hide
891 */
Mathew Inwood4dc66d32018-08-01 15:07:20 +0100892 @UnsupportedAppUsage
Matthew Xie269e81a2011-07-26 18:36:49 -0700893 public String getAlias() {
Jack He16eeac32017-08-17 12:11:18 -0700894 final IBluetooth service = sService;
895 if (service == null) {
fredc0f420372012-04-12 00:02:00 -0700896 Log.e(TAG, "BT not enabled. Cannot get Remote Device Alias");
897 return null;
898 }
Matthew Xie269e81a2011-07-26 18:36:49 -0700899 try {
Jack He16eeac32017-08-17 12:11:18 -0700900 return service.getRemoteAlias(this);
Jack Hea355e5e2017-08-22 16:06:54 -0700901 } catch (RemoteException e) {
902 Log.e(TAG, "", e);
903 }
Matthew Xie269e81a2011-07-26 18:36:49 -0700904 return null;
905 }
906
907 /**
908 * Set the Bluetooth alias of the remote device.
909 * <p>Alias is the locally modified name of a remote device.
910 * <p>This methoid overwrites the alias. The changed
911 * alias is saved in the local storage so that the change
912 * is preserved over power cycle.
913 *
914 * @return true on success, false on error
915 * @hide
916 */
Mathew Inwood4dc66d32018-08-01 15:07:20 +0100917 @UnsupportedAppUsage
Matthew Xie269e81a2011-07-26 18:36:49 -0700918 public boolean setAlias(String alias) {
Jack He16eeac32017-08-17 12:11:18 -0700919 final IBluetooth service = sService;
920 if (service == null) {
fredc0f420372012-04-12 00:02:00 -0700921 Log.e(TAG, "BT not enabled. Cannot set Remote Device name");
922 return false;
923 }
Matthew Xie269e81a2011-07-26 18:36:49 -0700924 try {
Jack He16eeac32017-08-17 12:11:18 -0700925 return service.setRemoteAlias(this, alias);
Jack Hea355e5e2017-08-22 16:06:54 -0700926 } catch (RemoteException e) {
927 Log.e(TAG, "", e);
928 }
Matthew Xie269e81a2011-07-26 18:36:49 -0700929 return false;
930 }
931
932 /**
933 * Get the Bluetooth alias of the remote device.
934 * If Alias is null, get the Bluetooth name instead.
Matthew Xie269e81a2011-07-26 18:36:49 -0700935 *
936 * @return the Bluetooth alias, or null if no alias or there was a problem
937 * @hide
Jack Hea355e5e2017-08-22 16:06:54 -0700938 * @see #getAlias()
939 * @see #getName()
Matthew Xie269e81a2011-07-26 18:36:49 -0700940 */
Mathew Inwood4dc66d32018-08-01 15:07:20 +0100941 @UnsupportedAppUsage
Matthew Xie269e81a2011-07-26 18:36:49 -0700942 public String getAliasName() {
943 String name = getAlias();
944 if (name == null) {
945 name = getName();
946 }
947 return name;
948 }
949
950 /**
Jack He1d312bf2017-06-16 19:43:58 -0700951 * Get the most recent identified battery level of this Bluetooth device
952 * <p>Requires {@link android.Manifest.permission#BLUETOOTH}
953 *
954 * @return Battery level in percents from 0 to 100, or {@link #BATTERY_LEVEL_UNKNOWN} if
Jack Hea355e5e2017-08-22 16:06:54 -0700955 * Bluetooth is disabled, or device is disconnected, or does not have any battery reporting
956 * service, or return value is invalid
Jack He1d312bf2017-06-16 19:43:58 -0700957 * @hide
958 */
959 @RequiresPermission(Manifest.permission.BLUETOOTH)
Mathew Inwood4dc66d32018-08-01 15:07:20 +0100960 @UnsupportedAppUsage
Jack He1d312bf2017-06-16 19:43:58 -0700961 public int getBatteryLevel() {
Jack He16eeac32017-08-17 12:11:18 -0700962 final IBluetooth service = sService;
963 if (service == null) {
Jack He1d312bf2017-06-16 19:43:58 -0700964 Log.e(TAG, "Bluetooth disabled. Cannot get remote device battery level");
965 return BATTERY_LEVEL_UNKNOWN;
966 }
967 try {
Jack He16eeac32017-08-17 12:11:18 -0700968 return service.getBatteryLevel(this);
Jack Hea355e5e2017-08-22 16:06:54 -0700969 } catch (RemoteException e) {
970 Log.e(TAG, "", e);
971 }
Jack He1d312bf2017-06-16 19:43:58 -0700972 return BATTERY_LEVEL_UNKNOWN;
973 }
974
975 /**
Nick Pelly005b2282009-09-10 10:21:56 -0700976 * Start the bonding (pairing) process with the remote device.
977 * <p>This is an asynchronous call, it will return immediately. Register
978 * for {@link #ACTION_BOND_STATE_CHANGED} intents to be notified when
979 * the bonding process completes, and its result.
980 * <p>Android system services will handle the necessary user interactions
981 * to confirm and complete the bonding process.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800982 *
Nick Pelly005b2282009-09-10 10:21:56 -0700983 * @return false on immediate error, true if bonding will begin
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800984 */
Tor Norbye2d497522015-04-23 17:10:21 -0700985 @RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN)
Nick Pellybd022f42009-08-14 18:33:38 -0700986 public boolean createBond() {
Jack He16eeac32017-08-17 12:11:18 -0700987 final IBluetooth service = sService;
988 if (service == null) {
fredc0f420372012-04-12 00:02:00 -0700989 Log.e(TAG, "BT not enabled. Cannot create bond to Remote Device");
990 return false;
991 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800992 try {
Jack He2992cd02017-08-22 21:21:23 -0700993 Log.i(TAG, "createBond() for device " + getAddress()
994 + " called by pid: " + Process.myPid()
995 + " tid: " + Process.myTid());
Jack He16eeac32017-08-17 12:11:18 -0700996 return service.createBond(this, TRANSPORT_AUTO);
Jack Hea355e5e2017-08-22 16:06:54 -0700997 } catch (RemoteException e) {
998 Log.e(TAG, "", e);
999 }
Andre Eisenbach57210c72014-08-04 17:51:43 -07001000 return false;
1001 }
1002
1003 /**
1004 * Start the bonding (pairing) process with the remote device using the
1005 * specified transport.
1006 *
1007 * <p>This is an asynchronous call, it will return immediately. Register
1008 * for {@link #ACTION_BOND_STATE_CHANGED} intents to be notified when
1009 * the bonding process completes, and its result.
1010 * <p>Android system services will handle the necessary user interactions
1011 * to confirm and complete the bonding process.
1012 * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}.
1013 *
1014 * @param transport The transport to use for the pairing procedure.
1015 * @return false on immediate error, true if bonding will begin
1016 * @throws IllegalArgumentException if an invalid transport was specified
1017 * @hide
1018 */
Mathew Inwood4dc66d32018-08-01 15:07:20 +01001019 @UnsupportedAppUsage
Andre Eisenbach57210c72014-08-04 17:51:43 -07001020 public boolean createBond(int transport) {
Jack He16eeac32017-08-17 12:11:18 -07001021 final IBluetooth service = sService;
1022 if (service == null) {
Andre Eisenbach57210c72014-08-04 17:51:43 -07001023 Log.e(TAG, "BT not enabled. Cannot create bond to Remote Device");
1024 return false;
1025 }
Jack Hea355e5e2017-08-22 16:06:54 -07001026 if (TRANSPORT_AUTO > transport || transport > TRANSPORT_LE) {
Andre Eisenbach57210c72014-08-04 17:51:43 -07001027 throw new IllegalArgumentException(transport + " is not a valid Bluetooth transport");
1028 }
1029 try {
Jack He2992cd02017-08-22 21:21:23 -07001030 Log.i(TAG, "createBond() for device " + getAddress()
1031 + " called by pid: " + Process.myPid()
1032 + " tid: " + Process.myTid());
Jack He16eeac32017-08-17 12:11:18 -07001033 return service.createBond(this, transport);
Jack Hea355e5e2017-08-22 16:06:54 -07001034 } catch (RemoteException e) {
1035 Log.e(TAG, "", e);
1036 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001037 return false;
1038 }
1039
1040 /**
Jaikumar Ganeshcc5494c2010-09-09 15:37:57 -07001041 * Start the bonding (pairing) process with the remote device using the
1042 * Out Of Band mechanism.
1043 *
1044 * <p>This is an asynchronous call, it will return immediately. Register
1045 * for {@link #ACTION_BOND_STATE_CHANGED} intents to be notified when
1046 * the bonding process completes, and its result.
1047 *
1048 * <p>Android system services will handle the necessary user interactions
1049 * to confirm and complete the bonding process.
1050 *
1051 * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}.
1052 *
Jakub Pawlowski2fc6e6b2015-12-29 13:19:21 -08001053 * @param transport - Transport to use
1054 * @param oobData - Out Of Band data
Jaikumar Ganeshcc5494c2010-09-09 15:37:57 -07001055 * @return false on immediate error, true if bonding will begin
Jaikumar Ganeshcc5494c2010-09-09 15:37:57 -07001056 * @hide
1057 */
Jakub Pawlowski2fc6e6b2015-12-29 13:19:21 -08001058 public boolean createBondOutOfBand(int transport, OobData oobData) {
Jack He16eeac32017-08-17 12:11:18 -07001059 final IBluetooth service = sService;
1060 if (service == null) {
1061 Log.w(TAG, "BT not enabled, createBondOutOfBand failed");
1062 return false;
1063 }
Jaikumar Ganeshcc5494c2010-09-09 15:37:57 -07001064 try {
Jack He16eeac32017-08-17 12:11:18 -07001065 return service.createBondOutOfBand(this, transport, oobData);
Jack Hea355e5e2017-08-22 16:06:54 -07001066 } catch (RemoteException e) {
1067 Log.e(TAG, "", e);
1068 }
Jaikumar Ganeshcc5494c2010-09-09 15:37:57 -07001069 return false;
1070 }
1071
Jakub Pawlowski0278ab92016-07-20 11:55:48 -07001072 /** @hide */
Mathew Inwood4dc66d32018-08-01 15:07:20 +01001073 @UnsupportedAppUsage
Jakub Pawlowski0278ab92016-07-20 11:55:48 -07001074 public boolean isBondingInitiatedLocally() {
Jack He16eeac32017-08-17 12:11:18 -07001075 final IBluetooth service = sService;
1076 if (service == null) {
1077 Log.w(TAG, "BT not enabled, isBondingInitiatedLocally failed");
1078 return false;
1079 }
Jakub Pawlowski0278ab92016-07-20 11:55:48 -07001080 try {
Jack He16eeac32017-08-17 12:11:18 -07001081 return service.isBondingInitiatedLocally(this);
Jack Hea355e5e2017-08-22 16:06:54 -07001082 } catch (RemoteException e) {
1083 Log.e(TAG, "", e);
1084 }
Jakub Pawlowski0278ab92016-07-20 11:55:48 -07001085 return false;
1086 }
1087
Jaikumar Ganeshcc5494c2010-09-09 15:37:57 -07001088 /**
1089 * Set the Out Of Band data for a remote device to be used later
1090 * in the pairing mechanism. Users can obtain this data through other
1091 * trusted channels
1092 *
1093 * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}.
1094 *
1095 * @param hash Simple Secure pairing hash
1096 * @param randomizer The random key obtained using OOB
1097 * @return false on error; true otherwise
Jaikumar Ganeshcc5494c2010-09-09 15:37:57 -07001098 * @hide
1099 */
1100 public boolean setDeviceOutOfBandData(byte[] hash, byte[] randomizer) {
Jack Hea355e5e2017-08-22 16:06:54 -07001101 //TODO(BT)
Jaikumar Ganeshe4caddb2012-01-25 16:16:48 -08001102 /*
Jaikumar Ganeshcc5494c2010-09-09 15:37:57 -07001103 try {
Jaikumar Ganeshe4caddb2012-01-25 16:16:48 -08001104 return sService.setDeviceOutOfBandData(this, hash, randomizer);
1105 } catch (RemoteException e) {Log.e(TAG, "", e);} */
Jack Hea355e5e2017-08-22 16:06:54 -07001106 return false;
Jaikumar Ganeshcc5494c2010-09-09 15:37:57 -07001107 }
1108
1109 /**
Nick Pelly005b2282009-09-10 10:21:56 -07001110 * Cancel an in-progress bonding request started with {@link #createBond}.
1111 * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}.
1112 *
Jake Hambyf51eada2010-09-21 13:39:53 -07001113 * @return true on success, false on error
Nick Pelly18b1e792009-09-24 11:14:15 -07001114 * @hide
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001115 */
Selim Gurun4029fa62017-10-17 17:01:38 -07001116 @SystemApi
1117 @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADMIN)
Nick Pellybd022f42009-08-14 18:33:38 -07001118 public boolean cancelBondProcess() {
Jack He16eeac32017-08-17 12:11:18 -07001119 final IBluetooth service = sService;
1120 if (service == null) {
fredc0f420372012-04-12 00:02:00 -07001121 Log.e(TAG, "BT not enabled. Cannot cancel Remote Device bond");
1122 return false;
1123 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001124 try {
Jack He2992cd02017-08-22 21:21:23 -07001125 Log.i(TAG, "cancelBondProcess() for device " + getAddress()
1126 + " called by pid: " + Process.myPid()
1127 + " tid: " + Process.myTid());
Jack He16eeac32017-08-17 12:11:18 -07001128 return service.cancelBondProcess(this);
Jack Hea355e5e2017-08-22 16:06:54 -07001129 } catch (RemoteException e) {
1130 Log.e(TAG, "", e);
1131 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001132 return false;
1133 }
1134
1135 /**
Nick Pelly005b2282009-09-10 10:21:56 -07001136 * Remove bond (pairing) with the remote device.
1137 * <p>Delete the link key associated with the remote device, and
1138 * immediately terminate connections to that device that require
1139 * authentication and encryption.
1140 * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001141 *
Jake Hambyf51eada2010-09-21 13:39:53 -07001142 * @return true on success, false on error
Nick Pelly18b1e792009-09-24 11:14:15 -07001143 * @hide
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001144 */
Selim Gurun4029fa62017-10-17 17:01:38 -07001145 @SystemApi
1146 @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADMIN)
Nick Pellybd022f42009-08-14 18:33:38 -07001147 public boolean removeBond() {
Jack He16eeac32017-08-17 12:11:18 -07001148 final IBluetooth service = sService;
1149 if (service == null) {
fredc0f420372012-04-12 00:02:00 -07001150 Log.e(TAG, "BT not enabled. Cannot remove Remote Device bond");
1151 return false;
1152 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001153 try {
Jack He2992cd02017-08-22 21:21:23 -07001154 Log.i(TAG, "removeBond() for device " + getAddress()
1155 + " called by pid: " + Process.myPid()
1156 + " tid: " + Process.myTid());
Jack He16eeac32017-08-17 12:11:18 -07001157 return service.removeBond(this);
Jack Hea355e5e2017-08-22 16:06:54 -07001158 } catch (RemoteException e) {
1159 Log.e(TAG, "", e);
1160 }
Nick Pellybd022f42009-08-14 18:33:38 -07001161 return false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001162 }
1163
1164 /**
Nick Pelly005b2282009-09-10 10:21:56 -07001165 * Get the bond state of the remote device.
1166 * <p>Possible values for the bond state are:
1167 * {@link #BOND_NONE},
1168 * {@link #BOND_BONDING},
1169 * {@link #BOND_BONDED}.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001170 *
Nick Pelly005b2282009-09-10 10:21:56 -07001171 * @return the bond state
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001172 */
Tor Norbye2d497522015-04-23 17:10:21 -07001173 @RequiresPermission(Manifest.permission.BLUETOOTH)
Nick Pellybd022f42009-08-14 18:33:38 -07001174 public int getBondState() {
Jack He16eeac32017-08-17 12:11:18 -07001175 final IBluetooth service = sService;
1176 if (service == null) {
fredc0f420372012-04-12 00:02:00 -07001177 Log.e(TAG, "BT not enabled. Cannot get bond state");
1178 return BOND_NONE;
1179 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001180 try {
Jack He16eeac32017-08-17 12:11:18 -07001181 return service.getBondState(this);
Jack Hea355e5e2017-08-22 16:06:54 -07001182 } catch (RemoteException e) {
1183 Log.e(TAG, "", e);
Syed Ibrahim M305f2402012-06-19 10:14:25 -07001184 }
Nick Pelly005b2282009-09-10 10:21:56 -07001185 return BOND_NONE;
1186 }
1187
1188 /**
Jay Civelli174928c2014-05-08 09:24:08 -07001189 * Returns whether there is an open connection to this device.
1190 * <p>Requires {@link android.Manifest.permission#BLUETOOTH}.
1191 *
1192 * @return True if there is at least one open connection to this device.
1193 * @hide
1194 */
Andre Eisenbach2b8696e2015-02-05 20:06:33 -08001195 @SystemApi
Selim Gurun4029fa62017-10-17 17:01:38 -07001196 @RequiresPermission(android.Manifest.permission.BLUETOOTH)
Jay Civelli174928c2014-05-08 09:24:08 -07001197 public boolean isConnected() {
Jack He16eeac32017-08-17 12:11:18 -07001198 final IBluetooth service = sService;
1199 if (service == null) {
Jay Civelli174928c2014-05-08 09:24:08 -07001200 // BT is not enabled, we cannot be connected.
1201 return false;
1202 }
1203 try {
Jack He16eeac32017-08-17 12:11:18 -07001204 return service.getConnectionState(this) != CONNECTION_STATE_DISCONNECTED;
Andre Eisenbach2b8696e2015-02-05 20:06:33 -08001205 } catch (RemoteException e) {
1206 Log.e(TAG, "", e);
1207 return false;
1208 }
1209 }
1210
1211 /**
1212 * Returns whether there is an open connection to this device
1213 * that has been encrypted.
1214 * <p>Requires {@link android.Manifest.permission#BLUETOOTH}.
1215 *
1216 * @return True if there is at least one encrypted connection to this device.
1217 * @hide
1218 */
1219 @SystemApi
Selim Gurun4029fa62017-10-17 17:01:38 -07001220 @RequiresPermission(android.Manifest.permission.BLUETOOTH)
Andre Eisenbach2b8696e2015-02-05 20:06:33 -08001221 public boolean isEncrypted() {
Jack He16eeac32017-08-17 12:11:18 -07001222 final IBluetooth service = sService;
1223 if (service == null) {
Andre Eisenbach2b8696e2015-02-05 20:06:33 -08001224 // BT is not enabled, we cannot be connected.
1225 return false;
1226 }
1227 try {
Jack He16eeac32017-08-17 12:11:18 -07001228 return service.getConnectionState(this) > CONNECTION_STATE_CONNECTED;
Jay Civelli174928c2014-05-08 09:24:08 -07001229 } catch (RemoteException e) {
1230 Log.e(TAG, "", e);
1231 return false;
1232 }
1233 }
1234
1235 /**
Nick Pelly005b2282009-09-10 10:21:56 -07001236 * Get the Bluetooth class of the remote device.
Nick Pelly005b2282009-09-10 10:21:56 -07001237 *
1238 * @return Bluetooth class object, or null on error
1239 */
Tor Norbye2d497522015-04-23 17:10:21 -07001240 @RequiresPermission(Manifest.permission.BLUETOOTH)
Nick Pelly005b2282009-09-10 10:21:56 -07001241 public BluetoothClass getBluetoothClass() {
Jack He16eeac32017-08-17 12:11:18 -07001242 final IBluetooth service = sService;
1243 if (service == null) {
fredc0f420372012-04-12 00:02:00 -07001244 Log.e(TAG, "BT not enabled. Cannot get Bluetooth Class");
1245 return null;
1246 }
Nick Pelly005b2282009-09-10 10:21:56 -07001247 try {
Jack He16eeac32017-08-17 12:11:18 -07001248 int classInt = service.getRemoteClass(this);
Nick Pelly005b2282009-09-10 10:21:56 -07001249 if (classInt == BluetoothClass.ERROR) return null;
1250 return new BluetoothClass(classInt);
Jack Hea355e5e2017-08-22 16:06:54 -07001251 } catch (RemoteException e) {
1252 Log.e(TAG, "", e);
1253 }
Nick Pelly005b2282009-09-10 10:21:56 -07001254 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001255 }
1256
Lixin Yueefa1dd72009-08-31 15:55:13 +08001257 /**
Matthew Xiead232102011-11-08 10:58:12 -08001258 * Returns the supported features (UUIDs) of the remote device.
1259 *
1260 * <p>This method does not start a service discovery procedure to retrieve the UUIDs
1261 * from the remote device. Instead, the local cached copy of the service
1262 * UUIDs are returned.
1263 * <p>Use {@link #fetchUuidsWithSdp} if fresh UUIDs are desired.
Matthew Xiead232102011-11-08 10:58:12 -08001264 *
Jack Hea355e5e2017-08-22 16:06:54 -07001265 * @return the supported features (UUIDs) of the remote device, or null on error
Matthew Xiead232102011-11-08 10:58:12 -08001266 */
Tor Norbye2d497522015-04-23 17:10:21 -07001267 @RequiresPermission(Manifest.permission.BLUETOOTH)
Jack Hea355e5e2017-08-22 16:06:54 -07001268 public ParcelUuid[] getUuids() {
Jack He16eeac32017-08-17 12:11:18 -07001269 final IBluetooth service = sService;
1270 if (service == null || !isBluetoothEnabled()) {
fredc0f420372012-04-12 00:02:00 -07001271 Log.e(TAG, "BT not enabled. Cannot get remote device Uuids");
Jack Hea355e5e2017-08-22 16:06:54 -07001272 return null;
1273 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001274 try {
Jack He16eeac32017-08-17 12:11:18 -07001275 return service.getRemoteUuids(this);
Jack Hea355e5e2017-08-22 16:06:54 -07001276 } catch (RemoteException e) {
1277 Log.e(TAG, "", e);
1278 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001279 return null;
1280 }
Jaikumar Ganeshd5ac1ae2009-05-05 22:26:12 -07001281
Jack Hea355e5e2017-08-22 16:06:54 -07001282 /**
1283 * Perform a service discovery on the remote device to get the UUIDs supported.
1284 *
1285 * <p>This API is asynchronous and {@link #ACTION_UUID} intent is sent,
1286 * with the UUIDs supported by the remote end. If there is an error
1287 * in getting the SDP records or if the process takes a long time,
1288 * {@link #ACTION_UUID} intent is sent with the UUIDs that is currently
1289 * present in the cache. Clients should use the {@link #getUuids} to get UUIDs
1290 * if service discovery is not to be performed.
1291 *
1292 * @return False if the sanity check fails, True if the process of initiating an ACL connection
1293 * to the remote device was started.
1294 */
1295 @RequiresPermission(Manifest.permission.BLUETOOTH)
1296 public boolean fetchUuidsWithSdp() {
Jack He16eeac32017-08-17 12:11:18 -07001297 final IBluetooth service = sService;
Jack He2992cd02017-08-22 21:21:23 -07001298 if (service == null || !isBluetoothEnabled()) {
Zhihai Xu5d04f1c2014-01-13 16:54:38 -08001299 Log.e(TAG, "BT not enabled. Cannot fetchUuidsWithSdp");
1300 return false;
1301 }
Jaikumar Ganesh1caa6d12009-09-18 11:32:54 -07001302 try {
Zhihai Xu5d04f1c2014-01-13 16:54:38 -08001303 return service.fetchRemoteUuids(this);
Jack Hea355e5e2017-08-22 16:06:54 -07001304 } catch (RemoteException e) {
1305 Log.e(TAG, "", e);
1306 }
1307 return false;
Jaikumar Ganesh1caa6d12009-09-18 11:32:54 -07001308 }
1309
Jack Hea355e5e2017-08-22 16:06:54 -07001310 /**
1311 * Perform a service discovery on the remote device to get the SDP records associated
1312 * with the specified UUID.
1313 *
1314 * <p>This API is asynchronous and {@link #ACTION_SDP_RECORD} intent is sent,
1315 * with the SDP records found on the remote end. If there is an error
1316 * in getting the SDP records or if the process takes a long time,
1317 * {@link #ACTION_SDP_RECORD} intent is sent with an status value in
1318 * {@link #EXTRA_SDP_SEARCH_STATUS} different from 0.
1319 * Detailed status error codes can be found by members of the Bluetooth package in
1320 * the AbstractionLayer class.
1321 * <p>Requires {@link android.Manifest.permission#BLUETOOTH}.
1322 * The SDP record data will be stored in the intent as {@link #EXTRA_SDP_RECORD}.
1323 * The object type will match one of the SdpXxxRecord types, depending on the UUID searched
1324 * for.
1325 *
1326 * @return False if the sanity check fails, True if the process
1327 * of initiating an ACL connection to the remote device
1328 * was started.
1329 */
1330 /** @hide */
1331 public boolean sdpSearch(ParcelUuid uuid) {
Jack He16eeac32017-08-17 12:11:18 -07001332 final IBluetooth service = sService;
1333 if (service == null) {
Jack Hea355e5e2017-08-22 16:06:54 -07001334 Log.e(TAG, "BT not enabled. Cannot query remote device sdp records");
1335 return false;
1336 }
1337 try {
Jack He16eeac32017-08-17 12:11:18 -07001338 return service.sdpSearch(this, uuid);
Jack Hea355e5e2017-08-22 16:06:54 -07001339 } catch (RemoteException e) {
1340 Log.e(TAG, "", e);
1341 }
1342 return false;
1343 }
Hemant Gupta8949bfb2013-08-16 14:57:55 +05301344
Matthew Xie091fc2b2013-09-23 23:23:13 -07001345 /**
1346 * Set the pin during pairing when the pairing method is {@link #PAIRING_VARIANT_PIN}
Matthew Xieac2c6c32013-10-21 14:56:33 -07001347 * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}.
Matthew Xie091fc2b2013-09-23 23:23:13 -07001348 *
Jack Hea355e5e2017-08-22 16:06:54 -07001349 * @return true pin has been set false for error
Matthew Xie091fc2b2013-09-23 23:23:13 -07001350 */
Nick Pellybd022f42009-08-14 18:33:38 -07001351 public boolean setPin(byte[] pin) {
Jack He16eeac32017-08-17 12:11:18 -07001352 final IBluetooth service = sService;
1353 if (service == null) {
fredc0f420372012-04-12 00:02:00 -07001354 Log.e(TAG, "BT not enabled. Cannot set Remote Device pin");
1355 return false;
1356 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001357 try {
Jack He16eeac32017-08-17 12:11:18 -07001358 return service.setPin(this, true, pin.length, pin);
Jack Hea355e5e2017-08-22 16:06:54 -07001359 } catch (RemoteException e) {
1360 Log.e(TAG, "", e);
1361 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001362 return false;
1363 }
Jaikumar Ganeshb0eca412009-07-16 18:26:28 -07001364
Nick Pelly45e27042009-08-19 11:00:00 -07001365 /** @hide */
Mathew Inwood4dc66d32018-08-01 15:07:20 +01001366 @UnsupportedAppUsage
Nick Pellybd022f42009-08-14 18:33:38 -07001367 public boolean setPasskey(int passkey) {
Jaikumar Ganeshe4caddb2012-01-25 16:16:48 -08001368 //TODO(BT)
1369 /*
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001370 try {
Jaikumar Ganeshe4caddb2012-01-25 16:16:48 -08001371 return sService.setPasskey(this, true, 4, passkey);
1372 } catch (RemoteException e) {Log.e(TAG, "", e);}*/
Jaikumar Ganeshb0eca412009-07-16 18:26:28 -07001373 return false;
1374 }
1375
Matthew Xie091fc2b2013-09-23 23:23:13 -07001376 /**
1377 * Confirm passkey for {@link #PAIRING_VARIANT_PASSKEY_CONFIRMATION} pairing.
Matthew Xie091fc2b2013-09-23 23:23:13 -07001378 *
Jack Hea355e5e2017-08-22 16:06:54 -07001379 * @return true confirmation has been sent out false for error
Matthew Xie091fc2b2013-09-23 23:23:13 -07001380 */
Marie Janssen93326cf2016-08-09 13:23:39 -07001381 @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
Nick Pellybd022f42009-08-14 18:33:38 -07001382 public boolean setPairingConfirmation(boolean confirm) {
Jack He16eeac32017-08-17 12:11:18 -07001383 final IBluetooth service = sService;
1384 if (service == null) {
fredc0f420372012-04-12 00:02:00 -07001385 Log.e(TAG, "BT not enabled. Cannot set pairing confirmation");
1386 return false;
1387 }
Jaikumar Ganeshb0eca412009-07-16 18:26:28 -07001388 try {
Jack He16eeac32017-08-17 12:11:18 -07001389 return service.setPairingConfirmation(this, confirm);
Jack Hea355e5e2017-08-22 16:06:54 -07001390 } catch (RemoteException e) {
1391 Log.e(TAG, "", e);
1392 }
Jaikumar Ganeshb0eca412009-07-16 18:26:28 -07001393 return false;
1394 }
1395
Nick Pelly45e27042009-08-19 11:00:00 -07001396 /** @hide */
Jaikumar Ganeshcc5494c2010-09-09 15:37:57 -07001397 public boolean setRemoteOutOfBandData() {
Jaikumar Ganeshe4caddb2012-01-25 16:16:48 -08001398 // TODO(BT)
1399 /*
Jaikumar Ganeshcc5494c2010-09-09 15:37:57 -07001400 try {
Jaikumar Ganeshe4caddb2012-01-25 16:16:48 -08001401 return sService.setRemoteOutOfBandData(this);
1402 } catch (RemoteException e) {Log.e(TAG, "", e);}*/
Jack Hea355e5e2017-08-22 16:06:54 -07001403 return false;
Jaikumar Ganeshcc5494c2010-09-09 15:37:57 -07001404 }
1405
1406 /** @hide */
Mathew Inwood4dc66d32018-08-01 15:07:20 +01001407 @UnsupportedAppUsage
Nick Pellybd022f42009-08-14 18:33:38 -07001408 public boolean cancelPairingUserInput() {
Jack He16eeac32017-08-17 12:11:18 -07001409 final IBluetooth service = sService;
1410 if (service == null) {
fredc0f420372012-04-12 00:02:00 -07001411 Log.e(TAG, "BT not enabled. Cannot create pairing user input");
1412 return false;
1413 }
Jaikumar Ganeshb0eca412009-07-16 18:26:28 -07001414 try {
Jack He16eeac32017-08-17 12:11:18 -07001415 return service.cancelBondProcess(this);
Jack Hea355e5e2017-08-22 16:06:54 -07001416 } catch (RemoteException e) {
1417 Log.e(TAG, "", e);
1418 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001419 return false;
1420 }
1421
Jaikumar Ganesh3fbf7b62009-12-02 17:28:38 -08001422 /** @hide */
Mathew Inwood4dc66d32018-08-01 15:07:20 +01001423 @UnsupportedAppUsage
Jaikumar Ganesh3fbf7b62009-12-02 17:28:38 -08001424 public boolean isBluetoothDock() {
Jaikumar Ganeshe4caddb2012-01-25 16:16:48 -08001425 // TODO(BT)
1426 /*
Jaikumar Ganesh3fbf7b62009-12-02 17:28:38 -08001427 try {
Jaikumar Ganeshe4caddb2012-01-25 16:16:48 -08001428 return sService.isBluetoothDock(this);
1429 } catch (RemoteException e) {Log.e(TAG, "", e);}*/
Jaikumar Ganesh3fbf7b62009-12-02 17:28:38 -08001430 return false;
1431 }
1432
Jack Hea355e5e2017-08-22 16:06:54 -07001433 boolean isBluetoothEnabled() {
1434 boolean ret = false;
1435 BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
Jack He2992cd02017-08-22 21:21:23 -07001436 if (adapter != null && adapter.isEnabled()) {
Jack Hea355e5e2017-08-22 16:06:54 -07001437 ret = true;
1438 }
1439 return ret;
1440 }
Nitin Arorad055adb2015-03-02 15:03:51 -08001441
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001442 /**
Edward Jee8dd30aa2014-09-05 00:29:14 -07001443 * Requires {@link android.Manifest.permission#BLUETOOTH}.
Jack Hea355e5e2017-08-22 16:06:54 -07001444 *
1445 * @return Whether the phonebook access is allowed to this device. Can be {@link
1446 * #ACCESS_UNKNOWN}, {@link #ACCESS_ALLOWED} or {@link #ACCESS_REJECTED}.
Edward Jee8dd30aa2014-09-05 00:29:14 -07001447 * @hide
1448 */
Mathew Inwood4dc66d32018-08-01 15:07:20 +01001449 @UnsupportedAppUsage
Edward Jee8dd30aa2014-09-05 00:29:14 -07001450 public int getPhonebookAccessPermission() {
Jack He16eeac32017-08-17 12:11:18 -07001451 final IBluetooth service = sService;
1452 if (service == null) {
Edward Jee8dd30aa2014-09-05 00:29:14 -07001453 return ACCESS_UNKNOWN;
1454 }
1455 try {
Jack He16eeac32017-08-17 12:11:18 -07001456 return service.getPhonebookAccessPermission(this);
Edward Jee8dd30aa2014-09-05 00:29:14 -07001457 } catch (RemoteException e) {
1458 Log.e(TAG, "", e);
1459 }
1460 return ACCESS_UNKNOWN;
1461 }
1462
1463 /**
1464 * Sets whether the phonebook access is allowed to this device.
1465 * <p>Requires {@link android.Manifest.permission#BLUETOOTH_PRIVILEGED}.
Jack Hea355e5e2017-08-22 16:06:54 -07001466 *
1467 * @param value Can be {@link #ACCESS_UNKNOWN}, {@link #ACCESS_ALLOWED} or {@link
1468 * #ACCESS_REJECTED}.
Edward Jee8dd30aa2014-09-05 00:29:14 -07001469 * @return Whether the value has been successfully set.
1470 * @hide
1471 */
Selim Gurun4029fa62017-10-17 17:01:38 -07001472 @SystemApi
1473 @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED)
Edward Jee8dd30aa2014-09-05 00:29:14 -07001474 public boolean setPhonebookAccessPermission(int value) {
Jack He16eeac32017-08-17 12:11:18 -07001475 final IBluetooth service = sService;
1476 if (service == null) {
Edward Jee8dd30aa2014-09-05 00:29:14 -07001477 return false;
1478 }
1479 try {
Jack He16eeac32017-08-17 12:11:18 -07001480 return service.setPhonebookAccessPermission(this, value);
Edward Jee8dd30aa2014-09-05 00:29:14 -07001481 } catch (RemoteException e) {
1482 Log.e(TAG, "", e);
1483 }
1484 return false;
1485 }
1486
1487 /**
1488 * Requires {@link android.Manifest.permission#BLUETOOTH}.
Jack Hea355e5e2017-08-22 16:06:54 -07001489 *
1490 * @return Whether the message access is allowed to this device. Can be {@link #ACCESS_UNKNOWN},
1491 * {@link #ACCESS_ALLOWED} or {@link #ACCESS_REJECTED}.
Edward Jee8dd30aa2014-09-05 00:29:14 -07001492 * @hide
1493 */
Mathew Inwood4dc66d32018-08-01 15:07:20 +01001494 @UnsupportedAppUsage
Edward Jee8dd30aa2014-09-05 00:29:14 -07001495 public int getMessageAccessPermission() {
Jack He16eeac32017-08-17 12:11:18 -07001496 final IBluetooth service = sService;
1497 if (service == null) {
Edward Jee8dd30aa2014-09-05 00:29:14 -07001498 return ACCESS_UNKNOWN;
1499 }
1500 try {
Jack He16eeac32017-08-17 12:11:18 -07001501 return service.getMessageAccessPermission(this);
Edward Jee8dd30aa2014-09-05 00:29:14 -07001502 } catch (RemoteException e) {
1503 Log.e(TAG, "", e);
1504 }
1505 return ACCESS_UNKNOWN;
1506 }
1507
1508 /**
1509 * Sets whether the message access is allowed to this device.
1510 * <p>Requires {@link android.Manifest.permission#BLUETOOTH_PRIVILEGED}.
Jack Hea355e5e2017-08-22 16:06:54 -07001511 *
1512 * @param value Can be {@link #ACCESS_UNKNOWN}, {@link #ACCESS_ALLOWED} or {@link
1513 * #ACCESS_REJECTED}.
Edward Jee8dd30aa2014-09-05 00:29:14 -07001514 * @return Whether the value has been successfully set.
1515 * @hide
1516 */
Mathew Inwood4dc66d32018-08-01 15:07:20 +01001517 @UnsupportedAppUsage
Edward Jee8dd30aa2014-09-05 00:29:14 -07001518 public boolean setMessageAccessPermission(int value) {
Jack He16eeac32017-08-17 12:11:18 -07001519 final IBluetooth service = sService;
1520 if (service == null) {
Edward Jee8dd30aa2014-09-05 00:29:14 -07001521 return false;
1522 }
1523 try {
Jack He16eeac32017-08-17 12:11:18 -07001524 return service.setMessageAccessPermission(this, value);
Edward Jee8dd30aa2014-09-05 00:29:14 -07001525 } catch (RemoteException e) {
1526 Log.e(TAG, "", e);
1527 }
1528 return false;
1529 }
1530
1531 /**
Casper Bonde2a5f6082015-03-19 10:36:45 +01001532 * Requires {@link android.Manifest.permission#BLUETOOTH}.
Jack Hea355e5e2017-08-22 16:06:54 -07001533 *
1534 * @return Whether the Sim access is allowed to this device. Can be {@link #ACCESS_UNKNOWN},
1535 * {@link #ACCESS_ALLOWED} or {@link #ACCESS_REJECTED}.
Casper Bonde2a5f6082015-03-19 10:36:45 +01001536 * @hide
1537 */
1538 public int getSimAccessPermission() {
Jack He16eeac32017-08-17 12:11:18 -07001539 final IBluetooth service = sService;
1540 if (service == null) {
Casper Bonde2a5f6082015-03-19 10:36:45 +01001541 return ACCESS_UNKNOWN;
1542 }
1543 try {
Jack He16eeac32017-08-17 12:11:18 -07001544 return service.getSimAccessPermission(this);
Casper Bonde2a5f6082015-03-19 10:36:45 +01001545 } catch (RemoteException e) {
1546 Log.e(TAG, "", e);
1547 }
1548 return ACCESS_UNKNOWN;
1549 }
1550
1551 /**
1552 * Sets whether the Sim access is allowed to this device.
1553 * <p>Requires {@link android.Manifest.permission#BLUETOOTH_PRIVILEGED}.
Jack Hea355e5e2017-08-22 16:06:54 -07001554 *
1555 * @param value Can be {@link #ACCESS_UNKNOWN}, {@link #ACCESS_ALLOWED} or {@link
1556 * #ACCESS_REJECTED}.
Casper Bonde2a5f6082015-03-19 10:36:45 +01001557 * @return Whether the value has been successfully set.
1558 * @hide
1559 */
Mathew Inwood4dc66d32018-08-01 15:07:20 +01001560 @UnsupportedAppUsage
Casper Bonde2a5f6082015-03-19 10:36:45 +01001561 public boolean setSimAccessPermission(int value) {
Jack He16eeac32017-08-17 12:11:18 -07001562 final IBluetooth service = sService;
1563 if (service == null) {
Casper Bonde2a5f6082015-03-19 10:36:45 +01001564 return false;
1565 }
1566 try {
Jack He16eeac32017-08-17 12:11:18 -07001567 return service.setSimAccessPermission(this, value);
Casper Bonde2a5f6082015-03-19 10:36:45 +01001568 } catch (RemoteException e) {
1569 Log.e(TAG, "", e);
1570 }
1571 return false;
Casper Bonde3b3d1fe2015-05-08 14:32:24 +02001572 }
1573
Casper Bonde2a5f6082015-03-19 10:36:45 +01001574 /**
Nick Pelly45e27042009-08-19 11:00:00 -07001575 * Create an RFCOMM {@link BluetoothSocket} ready to start a secure
Nick Pelly16fb88a2009-10-07 07:44:03 +02001576 * outgoing connection to this remote device on given channel.
Nick Pelly45e27042009-08-19 11:00:00 -07001577 * <p>The remote device will be authenticated and communication on this
1578 * socket will be encrypted.
Jaikumar Ganeshc8fa4ff2011-01-25 16:03:13 -08001579 * <p> Use this socket only if an authenticated socket link is possible.
1580 * Authentication refers to the authentication of the link key to
1581 * prevent man-in-the-middle type of attacks.
1582 * For example, for Bluetooth 2.1 devices, if any of the devices does not
1583 * have an input and output capability or just has the ability to
1584 * display a numeric key, a secure socket connection is not possible.
1585 * In such a case, use {#link createInsecureRfcommSocket}.
1586 * For more details, refer to the Security Model section 5.2 (vol 3) of
1587 * Bluetooth Core Specification version 2.1 + EDR.
Jake Hambyf51eada2010-09-21 13:39:53 -07001588 * <p>Use {@link BluetoothSocket#connect} to initiate the outgoing
Nick Pelly45e27042009-08-19 11:00:00 -07001589 * connection.
1590 * <p>Valid RFCOMM channels are in range 1 to 30.
Nick Pellycf440592009-09-08 10:12:06 -07001591 * <p>Requires {@link android.Manifest.permission#BLUETOOTH}
Nick Pellyde893f52009-09-08 13:15:33 -07001592 *
Nick Pelly45e27042009-08-19 11:00:00 -07001593 * @param channel RFCOMM channel to connect to
1594 * @return a RFCOMM BluetoothServerSocket ready for an outgoing connection
Jack Hea355e5e2017-08-22 16:06:54 -07001595 * @throws IOException on error, for example Bluetooth not available, or insufficient
1596 * permissions
Nick Pelly16fb88a2009-10-07 07:44:03 +02001597 * @hide
Nick Pellybd022f42009-08-14 18:33:38 -07001598 */
Mathew Inwood4dc66d32018-08-01 15:07:20 +01001599 @UnsupportedAppUsage
Nick Pelly45e27042009-08-19 11:00:00 -07001600 public BluetoothSocket createRfcommSocket(int channel) throws IOException {
Jack He2992cd02017-08-22 21:21:23 -07001601 if (!isBluetoothEnabled()) {
Nitin Arorad055adb2015-03-02 15:03:51 -08001602 Log.e(TAG, "Bluetooth is not enabled");
1603 throw new IOException();
1604 }
Nick Pelly16fb88a2009-10-07 07:44:03 +02001605 return new BluetoothSocket(BluetoothSocket.TYPE_RFCOMM, -1, true, true, this, channel,
1606 null);
1607 }
1608
1609 /**
Casper Bonde238e0f92015-04-09 09:24:48 +02001610 * Create an L2cap {@link BluetoothSocket} ready to start a secure
1611 * outgoing connection to this remote device on given channel.
1612 * <p>The remote device will be authenticated and communication on this
1613 * socket will be encrypted.
1614 * <p> Use this socket only if an authenticated socket link is possible.
1615 * Authentication refers to the authentication of the link key to
1616 * prevent man-in-the-middle type of attacks.
1617 * For example, for Bluetooth 2.1 devices, if any of the devices does not
1618 * have an input and output capability or just has the ability to
1619 * display a numeric key, a secure socket connection is not possible.
1620 * In such a case, use {#link createInsecureRfcommSocket}.
1621 * For more details, refer to the Security Model section 5.2 (vol 3) of
1622 * Bluetooth Core Specification version 2.1 + EDR.
1623 * <p>Use {@link BluetoothSocket#connect} to initiate the outgoing
1624 * connection.
1625 * <p>Valid L2CAP PSM channels are in range 1 to 2^16.
1626 * <p>Requires {@link android.Manifest.permission#BLUETOOTH}
1627 *
1628 * @param channel L2cap PSM/channel to connect to
1629 * @return a RFCOMM BluetoothServerSocket ready for an outgoing connection
Jack Hea355e5e2017-08-22 16:06:54 -07001630 * @throws IOException on error, for example Bluetooth not available, or insufficient
1631 * permissions
Casper Bonde238e0f92015-04-09 09:24:48 +02001632 * @hide
1633 */
1634 public BluetoothSocket createL2capSocket(int channel) throws IOException {
1635 return new BluetoothSocket(BluetoothSocket.TYPE_L2CAP, -1, true, true, this, channel,
1636 null);
1637 }
1638
1639 /**
Hemant Guptaef3e0db2017-02-03 16:38:59 +05301640 * Create an L2cap {@link BluetoothSocket} ready to start an insecure
1641 * outgoing connection to this remote device on given channel.
1642 * <p>The remote device will be not authenticated and communication on this
1643 * socket will not be encrypted.
1644 * <p>Use {@link BluetoothSocket#connect} to initiate the outgoing
1645 * connection.
1646 * <p>Valid L2CAP PSM channels are in range 1 to 2^16.
1647 * <p>Requires {@link android.Manifest.permission#BLUETOOTH}
1648 *
1649 * @param channel L2cap PSM/channel to connect to
1650 * @return a RFCOMM BluetoothServerSocket ready for an outgoing connection
Jack Hea355e5e2017-08-22 16:06:54 -07001651 * @throws IOException on error, for example Bluetooth not available, or insufficient
1652 * permissions
Hemant Guptaef3e0db2017-02-03 16:38:59 +05301653 * @hide
1654 */
1655 public BluetoothSocket createInsecureL2capSocket(int channel) throws IOException {
1656 return new BluetoothSocket(BluetoothSocket.TYPE_L2CAP, -1, false, false, this, channel,
1657 null);
1658 }
1659
1660 /**
Nick Pelly16fb88a2009-10-07 07:44:03 +02001661 * Create an RFCOMM {@link BluetoothSocket} ready to start a secure
1662 * outgoing connection to this remote device using SDP lookup of uuid.
1663 * <p>This is designed to be used with {@link
1664 * BluetoothAdapter#listenUsingRfcommWithServiceRecord} for peer-peer
1665 * Bluetooth applications.
Jake Hambyf51eada2010-09-21 13:39:53 -07001666 * <p>Use {@link BluetoothSocket#connect} to initiate the outgoing
Nick Pelly16fb88a2009-10-07 07:44:03 +02001667 * connection. This will also perform an SDP lookup of the given uuid to
1668 * determine which channel to connect to.
1669 * <p>The remote device will be authenticated and communication on this
1670 * socket will be encrypted.
Jaikumar Ganeshc8fa4ff2011-01-25 16:03:13 -08001671 * <p> Use this socket only if an authenticated socket link is possible.
1672 * Authentication refers to the authentication of the link key to
1673 * prevent man-in-the-middle type of attacks.
1674 * For example, for Bluetooth 2.1 devices, if any of the devices does not
1675 * have an input and output capability or just has the ability to
1676 * display a numeric key, a secure socket connection is not possible.
1677 * In such a case, use {#link createInsecureRfcommSocketToServiceRecord}.
1678 * For more details, refer to the Security Model section 5.2 (vol 3) of
1679 * Bluetooth Core Specification version 2.1 + EDR.
Nick Pellyea5056e2010-02-24 11:19:10 -08001680 * <p>Hint: If you are connecting to a Bluetooth serial board then try
1681 * using the well-known SPP UUID 00001101-0000-1000-8000-00805F9B34FB.
1682 * However if you are connecting to an Android peer then please generate
1683 * your own unique UUID.
Nick Pelly16fb88a2009-10-07 07:44:03 +02001684 *
1685 * @param uuid service record uuid to lookup RFCOMM channel
1686 * @return a RFCOMM BluetoothServerSocket ready for an outgoing connection
Jack Hea355e5e2017-08-22 16:06:54 -07001687 * @throws IOException on error, for example Bluetooth not available, or insufficient
1688 * permissions
Nick Pelly16fb88a2009-10-07 07:44:03 +02001689 */
Tor Norbye2d497522015-04-23 17:10:21 -07001690 @RequiresPermission(Manifest.permission.BLUETOOTH)
Nick Pelly16fb88a2009-10-07 07:44:03 +02001691 public BluetoothSocket createRfcommSocketToServiceRecord(UUID uuid) throws IOException {
Jack He2992cd02017-08-22 21:21:23 -07001692 if (!isBluetoothEnabled()) {
Nitin Arorad055adb2015-03-02 15:03:51 -08001693 Log.e(TAG, "Bluetooth is not enabled");
1694 throw new IOException();
1695 }
1696
Nick Pelly16fb88a2009-10-07 07:44:03 +02001697 return new BluetoothSocket(BluetoothSocket.TYPE_RFCOMM, -1, true, true, this, -1,
1698 new ParcelUuid(uuid));
Nick Pellybd022f42009-08-14 18:33:38 -07001699 }
1700
1701 /**
Jaikumar Ganesh6eef14a2010-12-23 12:57:02 -08001702 * Create an RFCOMM {@link BluetoothSocket} socket ready to start an insecure
1703 * outgoing connection to this remote device using SDP lookup of uuid.
1704 * <p> The communication channel will not have an authenticated link key
1705 * i.e it will be subject to man-in-the-middle attacks. For Bluetooth 2.1
1706 * devices, the link key will be encrypted, as encryption is mandatory.
1707 * For legacy devices (pre Bluetooth 2.1 devices) the link key will
1708 * be not be encrypted. Use {@link #createRfcommSocketToServiceRecord} if an
1709 * encrypted and authenticated communication channel is desired.
1710 * <p>This is designed to be used with {@link
1711 * BluetoothAdapter#listenUsingInsecureRfcommWithServiceRecord} for peer-peer
1712 * Bluetooth applications.
1713 * <p>Use {@link BluetoothSocket#connect} to initiate the outgoing
1714 * connection. This will also perform an SDP lookup of the given uuid to
1715 * determine which channel to connect to.
1716 * <p>The remote device will be authenticated and communication on this
1717 * socket will be encrypted.
1718 * <p>Hint: If you are connecting to a Bluetooth serial board then try
1719 * using the well-known SPP UUID 00001101-0000-1000-8000-00805F9B34FB.
1720 * However if you are connecting to an Android peer then please generate
1721 * your own unique UUID.
Jaikumar Ganesh6eef14a2010-12-23 12:57:02 -08001722 *
1723 * @param uuid service record uuid to lookup RFCOMM channel
1724 * @return a RFCOMM BluetoothServerSocket ready for an outgoing connection
Jack Hea355e5e2017-08-22 16:06:54 -07001725 * @throws IOException on error, for example Bluetooth not available, or insufficient
1726 * permissions
Jaikumar Ganesh6eef14a2010-12-23 12:57:02 -08001727 */
Tor Norbye2d497522015-04-23 17:10:21 -07001728 @RequiresPermission(Manifest.permission.BLUETOOTH)
Jaikumar Ganesh6eef14a2010-12-23 12:57:02 -08001729 public BluetoothSocket createInsecureRfcommSocketToServiceRecord(UUID uuid) throws IOException {
Jack He2992cd02017-08-22 21:21:23 -07001730 if (!isBluetoothEnabled()) {
Nitin Arorad055adb2015-03-02 15:03:51 -08001731 Log.e(TAG, "Bluetooth is not enabled");
1732 throw new IOException();
1733 }
Jaikumar Ganesh6eef14a2010-12-23 12:57:02 -08001734 return new BluetoothSocket(BluetoothSocket.TYPE_RFCOMM, -1, false, false, this, -1,
1735 new ParcelUuid(uuid));
1736 }
1737
1738 /**
Nick Pellybd022f42009-08-14 18:33:38 -07001739 * Construct an insecure RFCOMM socket ready to start an outgoing
1740 * connection.
1741 * Call #connect on the returned #BluetoothSocket to begin the connection.
1742 * The remote device will not be authenticated and communication on this
1743 * socket will not be encrypted.
Nick Pellye6ee3be2009-10-08 23:27:28 +02001744 * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}
1745 *
Jack Hea355e5e2017-08-22 16:06:54 -07001746 * @param port remote port
Nick Pellybd022f42009-08-14 18:33:38 -07001747 * @return An RFCOMM BluetoothSocket
Jack Hea355e5e2017-08-22 16:06:54 -07001748 * @throws IOException On error, for example Bluetooth not available, or insufficient
1749 * permissions.
Nick Pelly45e27042009-08-19 11:00:00 -07001750 * @hide
Nick Pellybd022f42009-08-14 18:33:38 -07001751 */
Mathew Inwood4dc66d32018-08-01 15:07:20 +01001752 @UnsupportedAppUsage
Nick Pellybd022f42009-08-14 18:33:38 -07001753 public BluetoothSocket createInsecureRfcommSocket(int port) throws IOException {
Jack He2992cd02017-08-22 21:21:23 -07001754 if (!isBluetoothEnabled()) {
Nitin Arorad055adb2015-03-02 15:03:51 -08001755 Log.e(TAG, "Bluetooth is not enabled");
1756 throw new IOException();
1757 }
Nick Pelly16fb88a2009-10-07 07:44:03 +02001758 return new BluetoothSocket(BluetoothSocket.TYPE_RFCOMM, -1, false, false, this, port,
1759 null);
Nick Pellybd022f42009-08-14 18:33:38 -07001760 }
1761
1762 /**
1763 * Construct a SCO socket ready to start an outgoing connection.
1764 * Call #connect on the returned #BluetoothSocket to begin the connection.
Nick Pellye6ee3be2009-10-08 23:27:28 +02001765 * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}
1766 *
Nick Pellybd022f42009-08-14 18:33:38 -07001767 * @return a SCO BluetoothSocket
Jack Hea355e5e2017-08-22 16:06:54 -07001768 * @throws IOException on error, for example Bluetooth not available, or insufficient
1769 * permissions.
Nick Pelly45e27042009-08-19 11:00:00 -07001770 * @hide
Nick Pellybd022f42009-08-14 18:33:38 -07001771 */
Mathew Inwood4dc66d32018-08-01 15:07:20 +01001772 @UnsupportedAppUsage
Nick Pellybd022f42009-08-14 18:33:38 -07001773 public BluetoothSocket createScoSocket() throws IOException {
Jack He2992cd02017-08-22 21:21:23 -07001774 if (!isBluetoothEnabled()) {
Nitin Arorad055adb2015-03-02 15:03:51 -08001775 Log.e(TAG, "Bluetooth is not enabled");
1776 throw new IOException();
1777 }
Nick Pelly16fb88a2009-10-07 07:44:03 +02001778 return new BluetoothSocket(BluetoothSocket.TYPE_SCO, -1, true, true, this, -1, null);
Nick Pellybd022f42009-08-14 18:33:38 -07001779 }
1780
1781 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001782 * Check that a pin is valid and convert to byte array.
1783 *
Jake Hambyf51eada2010-09-21 13:39:53 -07001784 * Bluetooth pin's are 1 to 16 bytes of UTF-8 characters.
Jack Hea355e5e2017-08-22 16:06:54 -07001785 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001786 * @param pin pin as java String
Jack Hea355e5e2017-08-22 16:06:54 -07001787 * @return the pin code as a UTF-8 byte array, or null if it is an invalid Bluetooth pin.
Nick Pelly45e27042009-08-19 11:00:00 -07001788 * @hide
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001789 */
Mathew Inwood4dc66d32018-08-01 15:07:20 +01001790 @UnsupportedAppUsage
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001791 public static byte[] convertPinToBytes(String pin) {
1792 if (pin == null) {
1793 return null;
1794 }
1795 byte[] pinBytes;
1796 try {
Jake Hambyf51eada2010-09-21 13:39:53 -07001797 pinBytes = pin.getBytes("UTF-8");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001798 } catch (UnsupportedEncodingException uee) {
Jake Hambyf51eada2010-09-21 13:39:53 -07001799 Log.e(TAG, "UTF-8 not supported?!?"); // this should not happen
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001800 return null;
1801 }
1802 if (pinBytes.length <= 0 || pinBytes.length > 16) {
1803 return null;
1804 }
1805 return pinBytes;
1806 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001807
Matthew Xieddf7e472013-03-01 18:41:02 -08001808 /**
1809 * Connect to GATT Server hosted by this device. Caller acts as GATT client.
1810 * The callback is used to deliver results to Caller, such as connection status as well
1811 * as any further GATT client operations.
1812 * The method returns a BluetoothGatt instance. You can use BluetoothGatt to conduct
1813 * GATT client operations.
Jack Hea355e5e2017-08-22 16:06:54 -07001814 *
Matthew Xieddf7e472013-03-01 18:41:02 -08001815 * @param callback GATT callback handler that will receive asynchronous callbacks.
Jack Hea355e5e2017-08-22 16:06:54 -07001816 * @param autoConnect Whether to directly connect to the remote device (false) or to
1817 * automatically connect as soon as the remote device becomes available (true).
Matthew Xieddf7e472013-03-01 18:41:02 -08001818 * @throws IllegalArgumentException if callback is null
1819 */
Matthew Xie33ec9842013-04-03 00:29:27 -07001820 public BluetoothGatt connectGatt(Context context, boolean autoConnect,
Jack Hea355e5e2017-08-22 16:06:54 -07001821 BluetoothGattCallback callback) {
1822 return (connectGatt(context, autoConnect, callback, TRANSPORT_AUTO));
Ganesh Ganapathi Battab88fa822014-04-18 10:00:40 -07001823 }
1824
1825 /**
1826 * Connect to GATT Server hosted by this device. Caller acts as GATT client.
1827 * The callback is used to deliver results to Caller, such as connection status as well
1828 * as any further GATT client operations.
1829 * The method returns a BluetoothGatt instance. You can use BluetoothGatt to conduct
1830 * GATT client operations.
Jack Hea355e5e2017-08-22 16:06:54 -07001831 *
Ganesh Ganapathi Battab88fa822014-04-18 10:00:40 -07001832 * @param callback GATT callback handler that will receive asynchronous callbacks.
Jack Hea355e5e2017-08-22 16:06:54 -07001833 * @param autoConnect Whether to directly connect to the remote device (false) or to
1834 * automatically connect as soon as the remote device becomes available (true).
1835 * @param transport preferred transport for GATT connections to remote dual-mode devices {@link
1836 * BluetoothDevice#TRANSPORT_AUTO} or {@link BluetoothDevice#TRANSPORT_BREDR} or {@link
1837 * BluetoothDevice#TRANSPORT_LE}
Ganesh Ganapathi Battab88fa822014-04-18 10:00:40 -07001838 * @throws IllegalArgumentException if callback is null
Ganesh Ganapathi Battab88fa822014-04-18 10:00:40 -07001839 */
1840 public BluetoothGatt connectGatt(Context context, boolean autoConnect,
Jack Hea355e5e2017-08-22 16:06:54 -07001841 BluetoothGattCallback callback, int transport) {
1842 return (connectGatt(context, autoConnect, callback, transport, PHY_LE_1M_MASK));
Jakub Pawlowski409cee62017-02-02 08:07:12 -08001843 }
1844
1845 /**
1846 * Connect to GATT Server hosted by this device. Caller acts as GATT client.
1847 * The callback is used to deliver results to Caller, such as connection status as well
1848 * as any further GATT client operations.
1849 * The method returns a BluetoothGatt instance. You can use BluetoothGatt to conduct
1850 * GATT client operations.
Jack Hea355e5e2017-08-22 16:06:54 -07001851 *
Jakub Pawlowski409cee62017-02-02 08:07:12 -08001852 * @param callback GATT callback handler that will receive asynchronous callbacks.
Jack Hea355e5e2017-08-22 16:06:54 -07001853 * @param autoConnect Whether to directly connect to the remote device (false) or to
1854 * automatically connect as soon as the remote device becomes available (true).
1855 * @param transport preferred transport for GATT connections to remote dual-mode devices {@link
1856 * BluetoothDevice#TRANSPORT_AUTO} or {@link BluetoothDevice#TRANSPORT_BREDR} or {@link
1857 * BluetoothDevice#TRANSPORT_LE}
1858 * @param phy preferred PHY for connections to remote LE device. Bitwise OR of any of {@link
1859 * BluetoothDevice#PHY_LE_1M_MASK}, {@link BluetoothDevice#PHY_LE_2M_MASK}, and {@link
1860 * BluetoothDevice#PHY_LE_CODED_MASK}. This option does not take effect if {@code autoConnect}
1861 * is set to true.
Jakub Pawlowskib0f64742017-04-21 03:49:00 -07001862 * @throws NullPointerException if callback is null
Jakub Pawlowski409cee62017-02-02 08:07:12 -08001863 */
1864 public BluetoothGatt connectGatt(Context context, boolean autoConnect,
Jack Hea355e5e2017-08-22 16:06:54 -07001865 BluetoothGattCallback callback, int transport, int phy) {
1866 return connectGatt(context, autoConnect, callback, transport, phy, null);
Jakub Pawlowskib0f64742017-04-21 03:49:00 -07001867 }
1868
1869 /**
1870 * Connect to GATT Server hosted by this device. Caller acts as GATT client.
1871 * The callback is used to deliver results to Caller, such as connection status as well
1872 * as any further GATT client operations.
1873 * The method returns a BluetoothGatt instance. You can use BluetoothGatt to conduct
1874 * GATT client operations.
Jack Hea355e5e2017-08-22 16:06:54 -07001875 *
Jakub Pawlowskib0f64742017-04-21 03:49:00 -07001876 * @param callback GATT callback handler that will receive asynchronous callbacks.
Jack Hea355e5e2017-08-22 16:06:54 -07001877 * @param autoConnect Whether to directly connect to the remote device (false) or to
1878 * automatically connect as soon as the remote device becomes available (true).
1879 * @param transport preferred transport for GATT connections to remote dual-mode devices {@link
1880 * BluetoothDevice#TRANSPORT_AUTO} or {@link BluetoothDevice#TRANSPORT_BREDR} or {@link
1881 * BluetoothDevice#TRANSPORT_LE}
1882 * @param phy preferred PHY for connections to remote LE device. Bitwise OR of any of {@link
1883 * BluetoothDevice#PHY_LE_1M_MASK}, {@link BluetoothDevice#PHY_LE_2M_MASK}, an d{@link
1884 * BluetoothDevice#PHY_LE_CODED_MASK}. This option does not take effect if {@code autoConnect}
1885 * is set to true.
1886 * @param handler The handler to use for the callback. If {@code null}, callbacks will happen on
1887 * an un-specified background thread.
Jakub Pawlowskib0f64742017-04-21 03:49:00 -07001888 * @throws NullPointerException if callback is null
1889 */
1890 public BluetoothGatt connectGatt(Context context, boolean autoConnect,
Jack Hea355e5e2017-08-22 16:06:54 -07001891 BluetoothGattCallback callback, int transport, int phy,
1892 Handler handler) {
Jack He13f52c82017-07-05 14:55:35 -07001893 return connectGatt(context, autoConnect, callback, transport, false, phy, handler);
1894 }
1895
1896 /**
1897 * Connect to GATT Server hosted by this device. Caller acts as GATT client.
1898 * The callback is used to deliver results to Caller, such as connection status as well
1899 * as any further GATT client operations.
1900 * The method returns a BluetoothGatt instance. You can use BluetoothGatt to conduct
1901 * GATT client operations.
Jack Hea355e5e2017-08-22 16:06:54 -07001902 *
Jack He13f52c82017-07-05 14:55:35 -07001903 * @param callback GATT callback handler that will receive asynchronous callbacks.
Jack Hea355e5e2017-08-22 16:06:54 -07001904 * @param autoConnect Whether to directly connect to the remote device (false) or to
1905 * automatically connect as soon as the remote device becomes available (true).
1906 * @param transport preferred transport for GATT connections to remote dual-mode devices {@link
1907 * BluetoothDevice#TRANSPORT_AUTO} or {@link BluetoothDevice#TRANSPORT_BREDR} or {@link
1908 * BluetoothDevice#TRANSPORT_LE}
Jack He13f52c82017-07-05 14:55:35 -07001909 * @param opportunistic Whether this GATT client is opportunistic. An opportunistic GATT client
Jack Hea355e5e2017-08-22 16:06:54 -07001910 * does not hold a GATT connection. It automatically disconnects when no other GATT connections
1911 * are active for the remote device.
1912 * @param phy preferred PHY for connections to remote LE device. Bitwise OR of any of {@link
1913 * BluetoothDevice#PHY_LE_1M_MASK}, {@link BluetoothDevice#PHY_LE_2M_MASK}, an d{@link
1914 * BluetoothDevice#PHY_LE_CODED_MASK}. This option does not take effect if {@code autoConnect}
1915 * is set to true.
1916 * @param handler The handler to use for the callback. If {@code null}, callbacks will happen on
1917 * an un-specified background thread.
Jack He13f52c82017-07-05 14:55:35 -07001918 * @return A BluetoothGatt instance. You can use BluetoothGatt to conduct GATT client
Jack Hea355e5e2017-08-22 16:06:54 -07001919 * operations.
Jack He13f52c82017-07-05 14:55:35 -07001920 * @hide
1921 */
Mathew Inwood4dc66d32018-08-01 15:07:20 +01001922 @UnsupportedAppUsage
Jack He13f52c82017-07-05 14:55:35 -07001923 public BluetoothGatt connectGatt(Context context, boolean autoConnect,
Jack Hea355e5e2017-08-22 16:06:54 -07001924 BluetoothGattCallback callback, int transport,
1925 boolean opportunistic, int phy, Handler handler) {
1926 if (callback == null) {
Jakub Pawlowskib0f64742017-04-21 03:49:00 -07001927 throw new NullPointerException("callback is null");
Jack Hea355e5e2017-08-22 16:06:54 -07001928 }
Jakub Pawlowskib0f64742017-04-21 03:49:00 -07001929
Matthew Xieddf7e472013-03-01 18:41:02 -08001930 // TODO(Bluetooth) check whether platform support BLE
1931 // Do the check here or in GattServer?
1932 BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
1933 IBluetoothManager managerService = adapter.getBluetoothManager();
1934 try {
1935 IBluetoothGatt iGatt = managerService.getBluetoothGatt();
Matthew Xie32ab77b2013-05-08 19:26:57 -07001936 if (iGatt == null) {
1937 // BLE is not supported
1938 return null;
1939 }
Jack He13f52c82017-07-05 14:55:35 -07001940 BluetoothGatt gatt = new BluetoothGatt(iGatt, this, transport, opportunistic, phy);
Jakub Pawlowskib0f64742017-04-21 03:49:00 -07001941 gatt.connect(autoConnect, callback, handler);
Matthew Xieddf7e472013-03-01 18:41:02 -08001942 return gatt;
Jack Hea355e5e2017-08-22 16:06:54 -07001943 } catch (RemoteException e) {
1944 Log.e(TAG, "", e);
1945 }
Matthew Xieddf7e472013-03-01 18:41:02 -08001946 return null;
1947 }
Stanley Tnge48468d2017-11-22 16:04:40 -08001948
1949 /**
1950 * Create a Bluetooth L2CAP Connection-oriented Channel (CoC) {@link BluetoothSocket} that can
1951 * be used to start a secure outgoing connection to the remote device with the same dynamic
Stanley Tng1bff4ba2018-06-29 14:05:04 -07001952 * protocol/service multiplexer (PSM) value. The supported Bluetooth transport is LE only.
1953 * <p>This is designed to be used with {@link BluetoothAdapter#listenUsingL2capChannel()} for
Stanley Tnge48468d2017-11-22 16:04:40 -08001954 * peer-peer Bluetooth applications.
1955 * <p>Use {@link BluetoothSocket#connect} to initiate the outgoing connection.
1956 * <p>Application using this API is responsible for obtaining PSM value from remote device.
1957 * <p>The remote device will be authenticated and communication on this socket will be
1958 * encrypted.
1959 * <p> Use this socket if an authenticated socket link is possible. Authentication refers
1960 * to the authentication of the link key to prevent man-in-the-middle type of attacks. When a
1961 * secure socket connection is not possible, use {#link createInsecureLeL2capCocSocket(int,
1962 * int)}.
1963 *
Stanley Tnge48468d2017-11-22 16:04:40 -08001964 * @param psm dynamic PSM value from remote device
1965 * @return a CoC #BluetoothSocket ready for an outgoing connection
1966 * @throws IOException on error, for example Bluetooth not available, or insufficient
1967 * permissions
Stanley Tnge48468d2017-11-22 16:04:40 -08001968 */
1969 @RequiresPermission(Manifest.permission.BLUETOOTH)
Stanley Tng1bff4ba2018-06-29 14:05:04 -07001970 public BluetoothSocket createL2capChannel(int psm) throws IOException {
Stanley Tnge48468d2017-11-22 16:04:40 -08001971 if (!isBluetoothEnabled()) {
Stanley Tng1bff4ba2018-06-29 14:05:04 -07001972 Log.e(TAG, "createL2capChannel: Bluetooth is not enabled");
Stanley Tnge48468d2017-11-22 16:04:40 -08001973 throw new IOException();
1974 }
Stanley Tng1bff4ba2018-06-29 14:05:04 -07001975 if (DBG) Log.d(TAG, "createL2capChannel: psm=" + psm);
Stanley Tnge48468d2017-11-22 16:04:40 -08001976 return new BluetoothSocket(BluetoothSocket.TYPE_L2CAP_LE, -1, true, true, this, psm,
1977 null);
1978 }
1979
1980 /**
Stanley Tng1bff4ba2018-06-29 14:05:04 -07001981 * TODO: Remove this hidden method once all the SL4A and other tests are updated to use the new
1982 * API name, createL2capChannel.
1983 * @hide
1984 */
1985 @RequiresPermission(Manifest.permission.BLUETOOTH)
1986 public BluetoothSocket createL2capCocSocket(int transport, int psm) throws IOException {
1987 Log.e(TAG, "createL2capCocSocket: PLEASE USE THE OFFICIAL API, createL2capChannel");
1988 return createL2capChannel(psm);
1989 }
1990
1991 /**
Stanley Tnge48468d2017-11-22 16:04:40 -08001992 * Create a Bluetooth L2CAP Connection-oriented Channel (CoC) {@link BluetoothSocket} that can
1993 * be used to start a secure outgoing connection to the remote device with the same dynamic
Stanley Tng1bff4ba2018-06-29 14:05:04 -07001994 * protocol/service multiplexer (PSM) value. The supported Bluetooth transport is LE only.
1995 * <p>This is designed to be used with {@link
1996 * BluetoothAdapter#listenUsingInsecureL2capChannel()} for peer-peer Bluetooth applications.
Stanley Tnge48468d2017-11-22 16:04:40 -08001997 * <p>Use {@link BluetoothSocket#connect} to initiate the outgoing connection.
1998 * <p>Application using this API is responsible for obtaining PSM value from remote device.
1999 * <p> The communication channel may not have an authenticated link key, i.e. it may be subject
Stanley Tng1bff4ba2018-06-29 14:05:04 -07002000 * to man-in-the-middle attacks. Use {@link #createL2capChannel(int)} if an encrypted and
Stanley Tnge48468d2017-11-22 16:04:40 -08002001 * authenticated communication channel is possible.
2002 *
Stanley Tnge48468d2017-11-22 16:04:40 -08002003 * @param psm dynamic PSM value from remote device
2004 * @return a CoC #BluetoothSocket ready for an outgoing connection
2005 * @throws IOException on error, for example Bluetooth not available, or insufficient
2006 * permissions
Stanley Tng1bff4ba2018-06-29 14:05:04 -07002007 */
2008 @RequiresPermission(Manifest.permission.BLUETOOTH)
2009 public BluetoothSocket createInsecureL2capChannel(int psm) throws IOException {
2010 if (!isBluetoothEnabled()) {
2011 Log.e(TAG, "createInsecureL2capChannel: Bluetooth is not enabled");
2012 throw new IOException();
2013 }
2014 if (DBG) {
2015 Log.d(TAG, "createInsecureL2capChannel: psm=" + psm);
2016 }
2017 return new BluetoothSocket(BluetoothSocket.TYPE_L2CAP_LE, -1, false, false, this, psm,
2018 null);
2019 }
2020
2021 /**
2022 * TODO: Remove this hidden method once all the SL4A and other tests are updated to use the new
2023 * API name, createInsecureL2capChannel.
Stanley Tnge48468d2017-11-22 16:04:40 -08002024 * @hide
2025 */
2026 @RequiresPermission(Manifest.permission.BLUETOOTH)
2027 public BluetoothSocket createInsecureL2capCocSocket(int transport, int psm) throws IOException {
Stanley Tng1bff4ba2018-06-29 14:05:04 -07002028 Log.e(TAG, "createL2capCocSocket: PLEASE USE THE OFFICIAL API, createInsecureL2capChannel");
2029 return createInsecureL2capChannel(psm);
Stanley Tnge48468d2017-11-22 16:04:40 -08002030 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002031}