blob: 4d8dc35d71480e1777ffbc38db00242057215566 [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 /**
Ugo Yu4a33b882019-01-08 09:00:09 +0800344 * Maximum length of a metadata entry, this is to avoid exploding Bluetooth
345 * disk usage
346 * @hide
347 */
348 @SystemApi
349 public static final int METADATA_MAX_LENGTH = 2048;
350
351 /**
352 * Manufacturer name of this Bluetooth device
353 * @hide
354 */
355 @SystemApi
356 public static final int METADATA_MANUFACTURER_NAME = 0;
357
358 /**
359 * Model name of this Bluetooth device
360 * @hide
361 */
362 @SystemApi
363 public static final int METADATA_MODEL_NAME = 1;
364
365 /**
366 * Software version of this Bluetooth device
367 * @hide
368 */
369 @SystemApi
370 public static final int METADATA_SOFTWARE_VERSION = 2;
371
372 /**
373 * Hardware version of this Bluetooth device
374 * @hide
375 */
376 @SystemApi
377 public static final int METADATA_HARDWARE_VERSION = 3;
378
379 /**
380 * Package name of the companion app, if any
381 * @hide
382 */
383 @SystemApi
384 public static final int METADATA_COMPANION_APP = 4;
385
386 /**
387 * URI to the main icon shown on the settings UI
388 * @hide
389 */
390 @SystemApi
391 public static final int METADATA_MAIN_ICON = 5;
392
393 /**
394 * Whether this device is an untethered headset with left, right and case
395 * @hide
396 */
397 @SystemApi
398 public static final int METADATA_IS_UNTHETHERED_HEADSET = 6;
399
400 /**
401 * URI to icon of the left headset
402 * @hide
403 */
404 @SystemApi
405 public static final int METADATA_UNTHETHERED_LEFT_ICON = 7;
406
407 /**
408 * URI to icon of the right headset
409 * @hide
410 */
411 @SystemApi
412 public static final int METADATA_UNTHETHERED_RIGHT_ICON = 8;
413
414 /**
415 * URI to icon of the headset charging case
416 * @hide
417 */
418 @SystemApi
419 public static final int METADATA_UNTHETHERED_CASE_ICON = 9;
420
421 /**
422 * Battery level (0-100), {@link BluetoothDevice#BATTERY_LEVEL_UNKNOWN}
423 * is invalid, of the left headset
424 * @hide
425 */
426 @SystemApi
427 public static final int METADATA_UNTHETHERED_LEFT_BATTERY = 10;
428
429 /**
430 * Battery level (0-100), {@link BluetoothDevice#BATTERY_LEVEL_UNKNOWN}
431 * is invalid, of the right headset
432 * @hide
433 */
434 @SystemApi
435 public static final int METADATA_UNTHETHERED_RIGHT_BATTERY = 11;
436
437 /**
438 * Battery level (0-100), {@link BluetoothDevice#BATTERY_LEVEL_UNKNOWN}
439 * is invalid, of the headset charging case
440 * @hide
441 */
442 @SystemApi
443 public static final int METADATA_UNTHETHERED_CASE_BATTERY = 12;
444
445 /**
446 * Whether the left headset is charging
447 * @hide
448 */
449 @SystemApi
450 public static final int METADATA_UNTHETHERED_LEFT_CHARGING = 13;
451
452 /**
453 * Whether the right headset is charging
454 * @hide
455 */
456 @SystemApi
457 public static final int METADATA_UNTHETHERED_RIGHT_CHARGING = 14;
458
459 /**
460 * Whether the headset charging case is charging
461 * @hide
462 */
463 @SystemApi
464 public static final int METADATA_UNTHETHERED_CASE_CHARGING = 15;
465
466 /**
467 * URI to the enhanced settings UI slice, null or empty String means
468 * the UI does not exist
469 * @hide
470 */
471 @SystemApi
472 public static final int METADATA_ENHANCED_SETTINGS_UI_URI = 16;
473
474 /**
Jaikumar Ganesh1caa6d12009-09-18 11:32:54 -0700475 * Broadcast Action: This intent is used to broadcast the {@link UUID}
Nick Pellyaef439e2009-09-28 12:33:17 -0700476 * wrapped as a {@link android.os.ParcelUuid} of the remote device after it
477 * has been fetched. This intent is sent only when the UUIDs of the remote
478 * device are requested to be fetched using Service Discovery Protocol
Jaikumar Ganesh1caa6d12009-09-18 11:32:54 -0700479 * <p> Always contains the extra field {@link #EXTRA_DEVICE}
Matthew Xiead232102011-11-08 10:58:12 -0800480 * <p> Always contains the extra field {@link #EXTRA_UUID}
Hansong Zhangff1c21c2018-11-12 14:32:03 -0800481 * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN} to receive.
Jaikumar Ganesh1caa6d12009-09-18 11:32:54 -0700482 */
483 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
484 public static final String ACTION_UUID =
Matthew Xiead232102011-11-08 10:58:12 -0800485 "android.bluetooth.device.action.UUID";
Jaikumar Ganesh1caa6d12009-09-18 11:32:54 -0700486
Hemant Gupta8949bfb2013-08-16 14:57:55 +0530487 /** @hide */
488 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
489 public static final String ACTION_MAS_INSTANCE =
490 "android.bluetooth.device.action.MAS_INSTANCE";
491
Jaikumar Ganesh1caa6d12009-09-18 11:32:54 -0700492 /**
Nick Pelly005b2282009-09-10 10:21:56 -0700493 * Broadcast Action: Indicates a failure to retrieve the name of a remote
494 * device.
495 * <p>Always contains the extra field {@link #EXTRA_DEVICE}.
496 * <p>Requires {@link android.Manifest.permission#BLUETOOTH} to receive.
Jack Hea355e5e2017-08-22 16:06:54 -0700497 *
Nick Pelly005b2282009-09-10 10:21:56 -0700498 * @hide
499 */
500 //TODO: is this actually useful?
501 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
502 public static final String ACTION_NAME_FAILED =
503 "android.bluetooth.device.action.NAME_FAILED";
504
Matthew Xie091fc2b2013-09-23 23:23:13 -0700505 /**
506 * Broadcast Action: This intent is used to broadcast PAIRING REQUEST
Matthew Xieac2c6c32013-10-21 14:56:33 -0700507 * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN} to
Edward Jee430e3612013-10-07 18:12:15 -0700508 * receive.
Matthew Xie091fc2b2013-09-23 23:23:13 -0700509 */
Nick Pelly005b2282009-09-10 10:21:56 -0700510 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
511 public static final String ACTION_PAIRING_REQUEST =
512 "android.bluetooth.device.action.PAIRING_REQUEST";
513 /** @hide */
514 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
Mathew Inwood4dc66d32018-08-01 15:07:20 +0100515 @UnsupportedAppUsage
Nick Pelly005b2282009-09-10 10:21:56 -0700516 public static final String ACTION_PAIRING_CANCEL =
517 "android.bluetooth.device.action.PAIRING_CANCEL";
Yue Lixina4433af2009-07-09 16:56:43 +0800518
Matthew Xiea0c68032011-06-25 21:47:07 -0700519 /** @hide */
520 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
521 public static final String ACTION_CONNECTION_ACCESS_REQUEST =
522 "android.bluetooth.device.action.CONNECTION_ACCESS_REQUEST";
523
524 /** @hide */
525 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
526 public static final String ACTION_CONNECTION_ACCESS_REPLY =
527 "android.bluetooth.device.action.CONNECTION_ACCESS_REPLY";
528
529 /** @hide */
530 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
531 public static final String ACTION_CONNECTION_ACCESS_CANCEL =
532 "android.bluetooth.device.action.CONNECTION_ACCESS_CANCEL";
533
534 /**
Ugo Yubfbe0ee2019-01-13 02:50:07 +0800535 * Intent to broadcast silence mode changed.
536 * Alway contains the extra field {@link #EXTRA_DEVICE}
537 * Alway contains the extra field {@link #EXTRA_SILENCE_ENABLED}
538 *
539 * @hide
540 */
541 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
542 @SystemApi
543 public static final String ACTION_SILENCE_MODE_CHANGED =
544 "android.bluetooth.device.action.SILENCE_MODE_CHANGED";
545
546 /**
547 * Used as an extra field in {@link #ACTION_SILENCE_MODE_CHANGED} intent,
548 * contains whether device is in silence mode as boolean.
549 *
550 * @hide
551 */
552 @SystemApi
553 public static final String EXTRA_SILENCE_ENABLED =
554 "android.bluetooth.device.extra.SILENCE_ENABLED";
555
556 /**
Matthew Xiea0c68032011-06-25 21:47:07 -0700557 * Used as an extra field in {@link #ACTION_CONNECTION_ACCESS_REQUEST} intent.
Jack Hea355e5e2017-08-22 16:06:54 -0700558 *
Matthew Xiea0c68032011-06-25 21:47:07 -0700559 * @hide
560 */
561 public static final String EXTRA_ACCESS_REQUEST_TYPE =
Jack Hea355e5e2017-08-22 16:06:54 -0700562 "android.bluetooth.device.extra.ACCESS_REQUEST_TYPE";
Matthew Xiea0c68032011-06-25 21:47:07 -0700563
Jack Hea355e5e2017-08-22 16:06:54 -0700564 /** @hide */
Matthew Xiea0c68032011-06-25 21:47:07 -0700565 public static final int REQUEST_TYPE_PROFILE_CONNECTION = 1;
566
Jack Hea355e5e2017-08-22 16:06:54 -0700567 /** @hide */
Matthew Xiea0c68032011-06-25 21:47:07 -0700568 public static final int REQUEST_TYPE_PHONEBOOK_ACCESS = 2;
569
Jack Hea355e5e2017-08-22 16:06:54 -0700570 /** @hide */
Matthew Xiefe3807a2013-07-18 17:31:50 -0700571 public static final int REQUEST_TYPE_MESSAGE_ACCESS = 3;
572
Jack Hea355e5e2017-08-22 16:06:54 -0700573 /** @hide */
Casper Bonde2a5f6082015-03-19 10:36:45 +0100574 public static final int REQUEST_TYPE_SIM_ACCESS = 4;
575
Matthew Xiea0c68032011-06-25 21:47:07 -0700576 /**
577 * Used as an extra field in {@link #ACTION_CONNECTION_ACCESS_REQUEST} intents,
578 * Contains package name to return reply intent to.
Jack Hea355e5e2017-08-22 16:06:54 -0700579 *
Matthew Xiea0c68032011-06-25 21:47:07 -0700580 * @hide
581 */
582 public static final String EXTRA_PACKAGE_NAME = "android.bluetooth.device.extra.PACKAGE_NAME";
583
584 /**
585 * Used as an extra field in {@link #ACTION_CONNECTION_ACCESS_REQUEST} intents,
586 * Contains class name to return reply intent to.
Jack Hea355e5e2017-08-22 16:06:54 -0700587 *
Matthew Xiea0c68032011-06-25 21:47:07 -0700588 * @hide
589 */
590 public static final String EXTRA_CLASS_NAME = "android.bluetooth.device.extra.CLASS_NAME";
591
592 /**
593 * Used as an extra field in {@link #ACTION_CONNECTION_ACCESS_REPLY} intent.
Jack Hea355e5e2017-08-22 16:06:54 -0700594 *
Matthew Xiea0c68032011-06-25 21:47:07 -0700595 * @hide
596 */
597 public static final String EXTRA_CONNECTION_ACCESS_RESULT =
Jack Hea355e5e2017-08-22 16:06:54 -0700598 "android.bluetooth.device.extra.CONNECTION_ACCESS_RESULT";
Matthew Xiea0c68032011-06-25 21:47:07 -0700599
Jack Hea355e5e2017-08-22 16:06:54 -0700600 /** @hide */
Matthew Xiea0c68032011-06-25 21:47:07 -0700601 public static final int CONNECTION_ACCESS_YES = 1;
602
Jack Hea355e5e2017-08-22 16:06:54 -0700603 /** @hide */
Matthew Xiea0c68032011-06-25 21:47:07 -0700604 public static final int CONNECTION_ACCESS_NO = 2;
605
606 /**
607 * Used as an extra field in {@link #ACTION_CONNECTION_ACCESS_REPLY} intents,
608 * Contains boolean to indicate if the allowed response is once-for-all so that
609 * next request will be granted without asking user again.
Jack Hea355e5e2017-08-22 16:06:54 -0700610 *
Matthew Xiea0c68032011-06-25 21:47:07 -0700611 * @hide
612 */
613 public static final String EXTRA_ALWAYS_ALLOWED =
Jack Hea355e5e2017-08-22 16:06:54 -0700614 "android.bluetooth.device.extra.ALWAYS_ALLOWED";
Matthew Xiea0c68032011-06-25 21:47:07 -0700615
Jaikumar Ganeshc88b0c62011-01-05 13:49:00 -0800616 /**
617 * A bond attempt succeeded
Jack Hea355e5e2017-08-22 16:06:54 -0700618 *
Jaikumar Ganeshc88b0c62011-01-05 13:49:00 -0800619 * @hide
620 */
Nick Pellyb24e11b2009-09-08 17:40:43 -0700621 public static final int BOND_SUCCESS = 0;
Jaikumar Ganeshc88b0c62011-01-05 13:49:00 -0800622
623 /**
624 * A bond attempt failed because pins did not match, or remote device did
Jaikumar Ganesh32d85712009-09-10 22:00:05 -0700625 * not respond to pin request in time
Jack Hea355e5e2017-08-22 16:06:54 -0700626 *
Jaikumar Ganeshc88b0c62011-01-05 13:49:00 -0800627 * @hide
628 */
Mathew Inwood4dc66d32018-08-01 15:07:20 +0100629 @UnsupportedAppUsage
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800630 public static final int UNBOND_REASON_AUTH_FAILED = 1;
Jaikumar Ganeshc88b0c62011-01-05 13:49:00 -0800631
632 /**
633 * A bond attempt failed because the other side explicitly rejected
Nick Pelly45e27042009-08-19 11:00:00 -0700634 * bonding
Jack Hea355e5e2017-08-22 16:06:54 -0700635 *
Jaikumar Ganeshc88b0c62011-01-05 13:49:00 -0800636 * @hide
637 */
Mathew Inwood4dc66d32018-08-01 15:07:20 +0100638 @UnsupportedAppUsage
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800639 public static final int UNBOND_REASON_AUTH_REJECTED = 2;
Jaikumar Ganeshc88b0c62011-01-05 13:49:00 -0800640
641 /**
642 * A bond attempt failed because we canceled the bonding process
Jack Hea355e5e2017-08-22 16:06:54 -0700643 *
Jaikumar Ganeshc88b0c62011-01-05 13:49:00 -0800644 * @hide
645 */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800646 public static final int UNBOND_REASON_AUTH_CANCELED = 3;
Jaikumar Ganeshc88b0c62011-01-05 13:49:00 -0800647
648 /**
649 * A bond attempt failed because we could not contact the remote device
Jack Hea355e5e2017-08-22 16:06:54 -0700650 *
Jaikumar Ganeshc88b0c62011-01-05 13:49:00 -0800651 * @hide
652 */
Mathew Inwood4dc66d32018-08-01 15:07:20 +0100653 @UnsupportedAppUsage
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800654 public static final int UNBOND_REASON_REMOTE_DEVICE_DOWN = 4;
Jaikumar Ganeshc88b0c62011-01-05 13:49:00 -0800655
656 /**
657 * A bond attempt failed because a discovery is in progress
Jack Hea355e5e2017-08-22 16:06:54 -0700658 *
Jaikumar Ganeshc88b0c62011-01-05 13:49:00 -0800659 * @hide
660 */
Mathew Inwood4dc66d32018-08-01 15:07:20 +0100661 @UnsupportedAppUsage
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800662 public static final int UNBOND_REASON_DISCOVERY_IN_PROGRESS = 5;
Jaikumar Ganeshc88b0c62011-01-05 13:49:00 -0800663
664 /**
665 * A bond attempt failed because of authentication timeout
Jack Hea355e5e2017-08-22 16:06:54 -0700666 *
Jaikumar Ganeshc88b0c62011-01-05 13:49:00 -0800667 * @hide
668 */
Mathew Inwood4dc66d32018-08-01 15:07:20 +0100669 @UnsupportedAppUsage
Jaikumar Ganesh32d85712009-09-10 22:00:05 -0700670 public static final int UNBOND_REASON_AUTH_TIMEOUT = 6;
Jaikumar Ganeshc88b0c62011-01-05 13:49:00 -0800671
672 /**
673 * A bond attempt failed because of repeated attempts
Jack Hea355e5e2017-08-22 16:06:54 -0700674 *
Jaikumar Ganeshc88b0c62011-01-05 13:49:00 -0800675 * @hide
676 */
Mathew Inwood4dc66d32018-08-01 15:07:20 +0100677 @UnsupportedAppUsage
Jaikumar Ganesh32d85712009-09-10 22:00:05 -0700678 public static final int UNBOND_REASON_REPEATED_ATTEMPTS = 7;
Jaikumar Ganeshc88b0c62011-01-05 13:49:00 -0800679
680 /**
681 * A bond attempt failed because we received an Authentication Cancel
682 * by remote end
Jack Hea355e5e2017-08-22 16:06:54 -0700683 *
Jaikumar Ganeshc88b0c62011-01-05 13:49:00 -0800684 * @hide
685 */
Mathew Inwood4dc66d32018-08-01 15:07:20 +0100686 @UnsupportedAppUsage
Jaikumar Ganeshe5d93b72009-10-08 02:27:52 -0700687 public static final int UNBOND_REASON_REMOTE_AUTH_CANCELED = 8;
Jaikumar Ganeshc88b0c62011-01-05 13:49:00 -0800688
689 /**
690 * An existing bond was explicitly revoked
Jack Hea355e5e2017-08-22 16:06:54 -0700691 *
Jaikumar Ganeshc88b0c62011-01-05 13:49:00 -0800692 * @hide
693 */
Jaikumar Ganeshe5d93b72009-10-08 02:27:52 -0700694 public static final int UNBOND_REASON_REMOVED = 9;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800695
Jaikumar Ganeshc88b0c62011-01-05 13:49:00 -0800696 /**
Matthew Xie091fc2b2013-09-23 23:23:13 -0700697 * The user will be prompted to enter a pin or
Matthew Xieac2c6c32013-10-21 14:56:33 -0700698 * an app will enter a pin for user.
Jaikumar Ganeshc88b0c62011-01-05 13:49:00 -0800699 */
Jaikumar Ganeshb0eca412009-07-16 18:26:28 -0700700 public static final int PAIRING_VARIANT_PIN = 0;
Jaikumar Ganeshc88b0c62011-01-05 13:49:00 -0800701
702 /**
703 * The user will be prompted to enter a passkey
Jack Hea355e5e2017-08-22 16:06:54 -0700704 *
Jaikumar Ganeshc88b0c62011-01-05 13:49:00 -0800705 * @hide
706 */
Jaikumar Ganeshb0eca412009-07-16 18:26:28 -0700707 public static final int PAIRING_VARIANT_PASSKEY = 1;
Jaikumar Ganeshc88b0c62011-01-05 13:49:00 -0800708
709 /**
Matthew Xie091fc2b2013-09-23 23:23:13 -0700710 * The user will be prompted to confirm the passkey displayed on the screen or
Matthew Xieac2c6c32013-10-21 14:56:33 -0700711 * an app will confirm the passkey for the user.
Jaikumar Ganeshc88b0c62011-01-05 13:49:00 -0800712 */
Jaikumar Ganesh32d85712009-09-10 22:00:05 -0700713 public static final int PAIRING_VARIANT_PASSKEY_CONFIRMATION = 2;
Jaikumar Ganeshc88b0c62011-01-05 13:49:00 -0800714
715 /**
716 * The user will be prompted to accept or deny the incoming pairing request
Jack Hea355e5e2017-08-22 16:06:54 -0700717 *
Jaikumar Ganeshc88b0c62011-01-05 13:49:00 -0800718 * @hide
719 */
Jaikumar Ganesh32d85712009-09-10 22:00:05 -0700720 public static final int PAIRING_VARIANT_CONSENT = 3;
Jaikumar Ganeshc88b0c62011-01-05 13:49:00 -0800721
722 /**
723 * The user will be prompted to enter the passkey displayed on remote device
724 * This is used for Bluetooth 2.1 pairing.
Jack Hea355e5e2017-08-22 16:06:54 -0700725 *
Jaikumar Ganeshc88b0c62011-01-05 13:49:00 -0800726 * @hide
727 */
Jaikumar Ganesh32d85712009-09-10 22:00:05 -0700728 public static final int PAIRING_VARIANT_DISPLAY_PASSKEY = 4;
Jaikumar Ganeshc88b0c62011-01-05 13:49:00 -0800729
730 /**
731 * The user will be prompted to enter the PIN displayed on remote device.
732 * This is used for Bluetooth 2.0 pairing.
Jack Hea355e5e2017-08-22 16:06:54 -0700733 *
Jaikumar Ganeshc88b0c62011-01-05 13:49:00 -0800734 * @hide
735 */
736 public static final int PAIRING_VARIANT_DISPLAY_PIN = 5;
737
738 /**
739 * The user will be prompted to accept or deny the OOB pairing request
Jack Hea355e5e2017-08-22 16:06:54 -0700740 *
Jaikumar Ganeshc88b0c62011-01-05 13:49:00 -0800741 * @hide
742 */
743 public static final int PAIRING_VARIANT_OOB_CONSENT = 6;
744
Jaikumar Ganesh1caa6d12009-09-18 11:32:54 -0700745 /**
Casper Bonde3b3d1fe2015-05-08 14:32:24 +0200746 * The user will be prompted to enter a 16 digit pin or
747 * an app will enter a 16 digit pin for user.
Jack Hea355e5e2017-08-22 16:06:54 -0700748 *
Casper Bonde3b3d1fe2015-05-08 14:32:24 +0200749 * @hide
750 */
751 public static final int PAIRING_VARIANT_PIN_16_DIGITS = 7;
752
753 /**
Jaikumar Ganesh1caa6d12009-09-18 11:32:54 -0700754 * Used as an extra field in {@link #ACTION_UUID} intents,
Nick Pellyaef439e2009-09-28 12:33:17 -0700755 * Contains the {@link android.os.ParcelUuid}s of the remote device which
756 * is a parcelable version of {@link UUID}.
Jaikumar Ganesh1caa6d12009-09-18 11:32:54 -0700757 */
758 public static final String EXTRA_UUID = "android.bluetooth.device.extra.UUID";
759
Casper Bonde238e0f92015-04-09 09:24:48 +0200760 /** @hide */
761 public static final String EXTRA_SDP_RECORD =
Jack Hea355e5e2017-08-22 16:06:54 -0700762 "android.bluetooth.device.extra.SDP_RECORD";
Casper Bonde238e0f92015-04-09 09:24:48 +0200763
764 /** @hide */
Mathew Inwood4dc66d32018-08-01 15:07:20 +0100765 @UnsupportedAppUsage
Casper Bonde238e0f92015-04-09 09:24:48 +0200766 public static final String EXTRA_SDP_SEARCH_STATUS =
767 "android.bluetooth.device.extra.SDP_SEARCH_STATUS";
Edward Jee8dd30aa2014-09-05 00:29:14 -0700768 /**
769 * For {@link #getPhonebookAccessPermission}, {@link #setPhonebookAccessPermission},
770 * {@link #getMessageAccessPermission} and {@link #setMessageAccessPermission}.
Jack Hea355e5e2017-08-22 16:06:54 -0700771 *
Edward Jee8dd30aa2014-09-05 00:29:14 -0700772 * @hide
773 */
Selim Gurun17a26c72018-01-09 14:35:19 -0800774 @SystemApi
Edward Jee8dd30aa2014-09-05 00:29:14 -0700775 public static final int ACCESS_UNKNOWN = 0;
776
777 /**
778 * For {@link #getPhonebookAccessPermission}, {@link #setPhonebookAccessPermission},
779 * {@link #getMessageAccessPermission} and {@link #setMessageAccessPermission}.
Jack Hea355e5e2017-08-22 16:06:54 -0700780 *
Edward Jee8dd30aa2014-09-05 00:29:14 -0700781 * @hide
782 */
Selim Gurun17a26c72018-01-09 14:35:19 -0800783 @SystemApi
Edward Jee8dd30aa2014-09-05 00:29:14 -0700784 public static final int ACCESS_ALLOWED = 1;
785
786 /**
787 * For {@link #getPhonebookAccessPermission}, {@link #setPhonebookAccessPermission},
788 * {@link #getMessageAccessPermission} and {@link #setMessageAccessPermission}.
Jack Hea355e5e2017-08-22 16:06:54 -0700789 *
Edward Jee8dd30aa2014-09-05 00:29:14 -0700790 * @hide
791 */
Selim Gurun17a26c72018-01-09 14:35:19 -0800792 @SystemApi
Edward Jee8dd30aa2014-09-05 00:29:14 -0700793 public static final int ACCESS_REJECTED = 2;
794
Jack Hea355e5e2017-08-22 16:06:54 -0700795 /**
kopriva219f7dc2018-10-09 13:42:28 -0700796 * No preference of physical transport for GATT connections to remote dual-mode devices
Jack Hea355e5e2017-08-22 16:06:54 -0700797 */
Ganesh Ganapathi Battab88fa822014-04-18 10:00:40 -0700798 public static final int TRANSPORT_AUTO = 0;
799
800 /**
801 * Prefer BR/EDR transport for GATT connections to remote dual-mode devices
Ganesh Ganapathi Battab88fa822014-04-18 10:00:40 -0700802 */
Hemant Gupta8949bfb2013-08-16 14:57:55 +0530803 public static final int TRANSPORT_BREDR = 1;
Ganesh Ganapathi Battab88fa822014-04-18 10:00:40 -0700804
805 /**
806 * Prefer LE transport for GATT connections to remote dual-mode devices
Ganesh Ganapathi Battab88fa822014-04-18 10:00:40 -0700807 */
Hemant Gupta8949bfb2013-08-16 14:57:55 +0530808 public static final int TRANSPORT_LE = 2;
Ganesh Ganapathi Battab88fa822014-04-18 10:00:40 -0700809
Jakub Pawlowski409cee62017-02-02 08:07:12 -0800810 /**
Jakub Pawlowski91fe3082017-04-21 04:26:12 -0700811 * Bluetooth LE 1M PHY. Used to refer to LE 1M Physical Channel for advertising, scanning or
812 * connection.
Jakub Pawlowski409cee62017-02-02 08:07:12 -0800813 */
814 public static final int PHY_LE_1M = 1;
815
816 /**
Jakub Pawlowski91fe3082017-04-21 04:26:12 -0700817 * Bluetooth LE 2M PHY. Used to refer to LE 2M Physical Channel for advertising, scanning or
818 * connection.
Jakub Pawlowski409cee62017-02-02 08:07:12 -0800819 */
820 public static final int PHY_LE_2M = 2;
821
822 /**
Jakub Pawlowski91fe3082017-04-21 04:26:12 -0700823 * Bluetooth LE Coded PHY. Used to refer to LE Coded Physical Channel for advertising, scanning
824 * or connection.
Jakub Pawlowski409cee62017-02-02 08:07:12 -0800825 */
Jakub Pawlowskia5151372017-04-12 08:51:22 -0700826 public static final int PHY_LE_CODED = 3;
Jakub Pawlowski409cee62017-02-02 08:07:12 -0800827
828 /**
Jakub Pawlowski91fe3082017-04-21 04:26:12 -0700829 * Bluetooth LE 1M PHY mask. Used to specify LE 1M Physical Channel as one of many available
830 * options in a bitmask.
Jakub Pawlowski409cee62017-02-02 08:07:12 -0800831 */
Jakub Pawlowskia5151372017-04-12 08:51:22 -0700832 public static final int PHY_LE_1M_MASK = 1;
833
834 /**
Jakub Pawlowski91fe3082017-04-21 04:26:12 -0700835 * Bluetooth LE 2M PHY mask. Used to specify LE 2M Physical Channel as one of many available
836 * options in a bitmask.
Jakub Pawlowskia5151372017-04-12 08:51:22 -0700837 */
838 public static final int PHY_LE_2M_MASK = 2;
839
840 /**
Jakub Pawlowski91fe3082017-04-21 04:26:12 -0700841 * Bluetooth LE Coded PHY mask. Used to specify LE Coded Physical Channel as one of many
842 * available options in a bitmask.
Jakub Pawlowskia5151372017-04-12 08:51:22 -0700843 */
844 public static final int PHY_LE_CODED_MASK = 4;
Jakub Pawlowski409cee62017-02-02 08:07:12 -0800845
846 /**
847 * No preferred coding when transmitting on the LE Coded PHY.
848 */
849 public static final int PHY_OPTION_NO_PREFERRED = 0;
850
851 /**
852 * Prefer the S=2 coding to be used when transmitting on the LE Coded PHY.
853 */
854 public static final int PHY_OPTION_S2 = 1;
855
856 /**
857 * Prefer the S=8 coding to be used when transmitting on the LE Coded PHY.
858 */
859 public static final int PHY_OPTION_S8 = 2;
860
861
Hemant Gupta8949bfb2013-08-16 14:57:55 +0530862 /** @hide */
863 public static final String EXTRA_MAS_INSTANCE =
Jack Hea355e5e2017-08-22 16:06:54 -0700864 "android.bluetooth.device.extra.MAS_INSTANCE";
Ganesh Ganapathi Battab88fa822014-04-18 10:00:40 -0700865
Nick Pelly16fb88a2009-10-07 07:44:03 +0200866 /**
867 * Lazy initialization. Guaranteed final after first object constructed, or
868 * getService() called.
869 * TODO: Unify implementation of sService amongst BluetoothFoo API's
870 */
Jack He16eeac32017-08-17 12:11:18 -0700871 private static volatile IBluetooth sService;
Jaikumar Ganeshd5ac1ae2009-05-05 22:26:12 -0700872
Nick Pellybd022f42009-08-14 18:33:38 -0700873 private final String mAddress;
874
Jack Hea355e5e2017-08-22 16:06:54 -0700875 /*package*/
Mathew Inwood4dc66d32018-08-01 15:07:20 +0100876 @UnsupportedAppUsage
Jack Hea355e5e2017-08-22 16:06:54 -0700877 static IBluetooth getService() {
Nick Pelly16fb88a2009-10-07 07:44:03 +0200878 synchronized (BluetoothDevice.class) {
879 if (sService == null) {
fredc0f420372012-04-12 00:02:00 -0700880 BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
Jack He2992cd02017-08-22 21:21:23 -0700881 sService = adapter.getBluetoothService(sStateChangeCallback);
Nick Pelly16fb88a2009-10-07 07:44:03 +0200882 }
883 }
884 return sService;
885 }
886
Jack He2992cd02017-08-22 21:21:23 -0700887 static IBluetoothManagerCallback sStateChangeCallback = new IBluetoothManagerCallback.Stub() {
fredc903ac6f2012-04-24 03:59:57 -0700888
889 public void onBluetoothServiceUp(IBluetooth bluetoothService)
890 throws RemoteException {
891 synchronized (BluetoothDevice.class) {
Nitin Arorad055adb2015-03-02 15:03:51 -0800892 if (sService == null) {
893 sService = bluetoothService;
894 }
fredc903ac6f2012-04-24 03:59:57 -0700895 }
896 }
897
898 public void onBluetoothServiceDown()
Jack Hea355e5e2017-08-22 16:06:54 -0700899 throws RemoteException {
fredc903ac6f2012-04-24 03:59:57 -0700900 synchronized (BluetoothDevice.class) {
901 sService = null;
902 }
903 }
Nitin Arorad055adb2015-03-02 15:03:51 -0800904
Jack Hea355e5e2017-08-22 16:06:54 -0700905 public void onBrEdrDown() {
Nitin Arorad055adb2015-03-02 15:03:51 -0800906 if (DBG) Log.d(TAG, "onBrEdrDown: reached BLE ON state");
907 }
fredc903ac6f2012-04-24 03:59:57 -0700908 };
Jack Hea355e5e2017-08-22 16:06:54 -0700909
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800910 /**
Nick Pellybd022f42009-08-14 18:33:38 -0700911 * Create a new BluetoothDevice
912 * Bluetooth MAC address must be upper case, such as "00:11:22:33:AA:BB",
913 * and is validated in this constructor.
Jack Hea355e5e2017-08-22 16:06:54 -0700914 *
Nick Pellybd022f42009-08-14 18:33:38 -0700915 * @param address valid Bluetooth MAC address
916 * @throws RuntimeException Bluetooth is not available on this platform
917 * @throws IllegalArgumentException address is invalid
918 * @hide
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800919 */
Mathew Inwood4dc66d32018-08-01 15:07:20 +0100920 @UnsupportedAppUsage
Nick Pellybd022f42009-08-14 18:33:38 -0700921 /*package*/ BluetoothDevice(String address) {
Nick Pelly16fb88a2009-10-07 07:44:03 +0200922 getService(); // ensures sService is initialized
Nick Pelly005b2282009-09-10 10:21:56 -0700923 if (!BluetoothAdapter.checkBluetoothAddress(address)) {
Nick Pellybd022f42009-08-14 18:33:38 -0700924 throw new IllegalArgumentException(address + " is not a valid Bluetooth address");
925 }
926
927 mAddress = address;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800928 }
929
Nick Pellybd022f42009-08-14 18:33:38 -0700930 @Override
931 public boolean equals(Object o) {
932 if (o instanceof BluetoothDevice) {
Jack Hea355e5e2017-08-22 16:06:54 -0700933 return mAddress.equals(((BluetoothDevice) o).getAddress());
Nick Pellybd022f42009-08-14 18:33:38 -0700934 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800935 return false;
936 }
937
Nick Pellybd022f42009-08-14 18:33:38 -0700938 @Override
939 public int hashCode() {
940 return mAddress.hashCode();
The Android Open Source Project10592532009-03-18 17:39:46 -0700941 }
942
Nick Pelly45e27042009-08-19 11:00:00 -0700943 /**
944 * Returns a string representation of this BluetoothDevice.
945 * <p>Currently this is the Bluetooth hardware address, for example
946 * "00:11:22:AA:BB:CC". However, you should always use {@link #getAddress}
947 * if you explicitly require the Bluetooth hardware address in case the
948 * {@link #toString} representation changes in the future.
Jack Hea355e5e2017-08-22 16:06:54 -0700949 *
Nick Pelly45e27042009-08-19 11:00:00 -0700950 * @return string representation of this BluetoothDevice
951 */
Nick Pellybd022f42009-08-14 18:33:38 -0700952 @Override
953 public String toString() {
954 return mAddress;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800955 }
956
Jack He2992cd02017-08-22 21:21:23 -0700957 @Override
Nick Pellybd022f42009-08-14 18:33:38 -0700958 public int describeContents() {
959 return 0;
960 }
961
962 public static final Parcelable.Creator<BluetoothDevice> CREATOR =
963 new Parcelable.Creator<BluetoothDevice>() {
Jack Hea355e5e2017-08-22 16:06:54 -0700964 public BluetoothDevice createFromParcel(Parcel in) {
965 return new BluetoothDevice(in.readString());
966 }
967
968 public BluetoothDevice[] newArray(int size) {
969 return new BluetoothDevice[size];
970 }
971 };
Nick Pellybd022f42009-08-14 18:33:38 -0700972
Jack He2992cd02017-08-22 21:21:23 -0700973 @Override
Nick Pellybd022f42009-08-14 18:33:38 -0700974 public void writeToParcel(Parcel out, int flags) {
975 out.writeString(mAddress);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800976 }
977
Nick Pelly45e27042009-08-19 11:00:00 -0700978 /**
979 * Returns the hardware address of this BluetoothDevice.
980 * <p> For example, "00:11:22:AA:BB:CC".
Jack Hea355e5e2017-08-22 16:06:54 -0700981 *
Nick Pelly45e27042009-08-19 11:00:00 -0700982 * @return Bluetooth hardware address as string
983 */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800984 public String getAddress() {
fredc0f420372012-04-12 00:02:00 -0700985 if (DBG) Log.d(TAG, "mAddress: " + mAddress);
Nick Pellybd022f42009-08-14 18:33:38 -0700986 return mAddress;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800987 }
988
989 /**
Nick Pelly45e27042009-08-19 11:00:00 -0700990 * Get the friendly Bluetooth name of the remote device.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800991 *
Nick Pelly45e27042009-08-19 11:00:00 -0700992 * <p>The local adapter will automatically retrieve remote names when
993 * performing a device scan, and will cache them. This method just returns
994 * the name for this device from the cache.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800995 *
996 * @return the Bluetooth name, or null if there was a problem.
997 */
Tor Norbye2d497522015-04-23 17:10:21 -0700998 @RequiresPermission(Manifest.permission.BLUETOOTH)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800999 public String getName() {
Jack He16eeac32017-08-17 12:11:18 -07001000 final IBluetooth service = sService;
1001 if (service == null) {
fredc0f420372012-04-12 00:02:00 -07001002 Log.e(TAG, "BT not enabled. Cannot get Remote Device name");
1003 return null;
1004 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001005 try {
Hansong Zhang2e3bf462018-04-26 14:22:39 -07001006 String name = service.getRemoteName(this);
1007 if (name != null) {
1008 return name.replaceAll("[\\t\\n\\r]+", " ");
1009 }
1010 return null;
Jack Hea355e5e2017-08-22 16:06:54 -07001011 } catch (RemoteException e) {
1012 Log.e(TAG, "", e);
1013 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001014 return null;
1015 }
1016
1017 /**
Matthew Xie33ec9842013-04-03 00:29:27 -07001018 * Get the Bluetooth device type of the remote device.
1019 *
Jack Hea355e5e2017-08-22 16:06:54 -07001020 * @return the device type {@link #DEVICE_TYPE_CLASSIC}, {@link #DEVICE_TYPE_LE} {@link
1021 * #DEVICE_TYPE_DUAL}. {@link #DEVICE_TYPE_UNKNOWN} if it's not available
Matthew Xie33ec9842013-04-03 00:29:27 -07001022 */
Tor Norbye2d497522015-04-23 17:10:21 -07001023 @RequiresPermission(Manifest.permission.BLUETOOTH)
Matthew Xie33ec9842013-04-03 00:29:27 -07001024 public int getType() {
Jack He16eeac32017-08-17 12:11:18 -07001025 final IBluetooth service = sService;
1026 if (service == null) {
Matthew Xie33ec9842013-04-03 00:29:27 -07001027 Log.e(TAG, "BT not enabled. Cannot get Remote Device type");
1028 return DEVICE_TYPE_UNKNOWN;
1029 }
1030 try {
Jack He16eeac32017-08-17 12:11:18 -07001031 return service.getRemoteType(this);
Jack Hea355e5e2017-08-22 16:06:54 -07001032 } catch (RemoteException e) {
1033 Log.e(TAG, "", e);
1034 }
Matthew Xie33ec9842013-04-03 00:29:27 -07001035 return DEVICE_TYPE_UNKNOWN;
1036 }
1037
1038 /**
Matthew Xie269e81a2011-07-26 18:36:49 -07001039 * Get the Bluetooth alias of the remote device.
1040 * <p>Alias is the locally modified name of a remote device.
1041 *
1042 * @return the Bluetooth alias, or null if no alias or there was a problem
1043 * @hide
1044 */
Mathew Inwood4dc66d32018-08-01 15:07:20 +01001045 @UnsupportedAppUsage
Matthew Xie269e81a2011-07-26 18:36:49 -07001046 public String getAlias() {
Jack He16eeac32017-08-17 12:11:18 -07001047 final IBluetooth service = sService;
1048 if (service == null) {
fredc0f420372012-04-12 00:02:00 -07001049 Log.e(TAG, "BT not enabled. Cannot get Remote Device Alias");
1050 return null;
1051 }
Matthew Xie269e81a2011-07-26 18:36:49 -07001052 try {
Jack He16eeac32017-08-17 12:11:18 -07001053 return service.getRemoteAlias(this);
Jack Hea355e5e2017-08-22 16:06:54 -07001054 } catch (RemoteException e) {
1055 Log.e(TAG, "", e);
1056 }
Matthew Xie269e81a2011-07-26 18:36:49 -07001057 return null;
1058 }
1059
1060 /**
1061 * Set the Bluetooth alias of the remote device.
1062 * <p>Alias is the locally modified name of a remote device.
1063 * <p>This methoid overwrites the alias. The changed
1064 * alias is saved in the local storage so that the change
1065 * is preserved over power cycle.
1066 *
1067 * @return true on success, false on error
1068 * @hide
1069 */
Mathew Inwood4dc66d32018-08-01 15:07:20 +01001070 @UnsupportedAppUsage
Matthew Xie269e81a2011-07-26 18:36:49 -07001071 public boolean setAlias(String alias) {
Jack He16eeac32017-08-17 12:11:18 -07001072 final IBluetooth service = sService;
1073 if (service == null) {
fredc0f420372012-04-12 00:02:00 -07001074 Log.e(TAG, "BT not enabled. Cannot set Remote Device name");
1075 return false;
1076 }
Matthew Xie269e81a2011-07-26 18:36:49 -07001077 try {
Jack He16eeac32017-08-17 12:11:18 -07001078 return service.setRemoteAlias(this, alias);
Jack Hea355e5e2017-08-22 16:06:54 -07001079 } catch (RemoteException e) {
1080 Log.e(TAG, "", e);
1081 }
Matthew Xie269e81a2011-07-26 18:36:49 -07001082 return false;
1083 }
1084
1085 /**
1086 * Get the Bluetooth alias of the remote device.
1087 * If Alias is null, get the Bluetooth name instead.
Matthew Xie269e81a2011-07-26 18:36:49 -07001088 *
1089 * @return the Bluetooth alias, or null if no alias or there was a problem
1090 * @hide
Jack Hea355e5e2017-08-22 16:06:54 -07001091 * @see #getAlias()
1092 * @see #getName()
Matthew Xie269e81a2011-07-26 18:36:49 -07001093 */
Mathew Inwood4dc66d32018-08-01 15:07:20 +01001094 @UnsupportedAppUsage
Matthew Xie269e81a2011-07-26 18:36:49 -07001095 public String getAliasName() {
1096 String name = getAlias();
1097 if (name == null) {
1098 name = getName();
1099 }
1100 return name;
1101 }
1102
1103 /**
Jack He1d312bf2017-06-16 19:43:58 -07001104 * Get the most recent identified battery level of this Bluetooth device
1105 * <p>Requires {@link android.Manifest.permission#BLUETOOTH}
1106 *
1107 * @return Battery level in percents from 0 to 100, or {@link #BATTERY_LEVEL_UNKNOWN} if
Jack Hea355e5e2017-08-22 16:06:54 -07001108 * Bluetooth is disabled, or device is disconnected, or does not have any battery reporting
1109 * service, or return value is invalid
Jack He1d312bf2017-06-16 19:43:58 -07001110 * @hide
1111 */
1112 @RequiresPermission(Manifest.permission.BLUETOOTH)
Mathew Inwood4dc66d32018-08-01 15:07:20 +01001113 @UnsupportedAppUsage
Jack He1d312bf2017-06-16 19:43:58 -07001114 public int getBatteryLevel() {
Jack He16eeac32017-08-17 12:11:18 -07001115 final IBluetooth service = sService;
1116 if (service == null) {
Jack He1d312bf2017-06-16 19:43:58 -07001117 Log.e(TAG, "Bluetooth disabled. Cannot get remote device battery level");
1118 return BATTERY_LEVEL_UNKNOWN;
1119 }
1120 try {
Jack He16eeac32017-08-17 12:11:18 -07001121 return service.getBatteryLevel(this);
Jack Hea355e5e2017-08-22 16:06:54 -07001122 } catch (RemoteException e) {
1123 Log.e(TAG, "", e);
1124 }
Jack He1d312bf2017-06-16 19:43:58 -07001125 return BATTERY_LEVEL_UNKNOWN;
1126 }
1127
1128 /**
Nick Pelly005b2282009-09-10 10:21:56 -07001129 * Start the bonding (pairing) process with the remote device.
1130 * <p>This is an asynchronous call, it will return immediately. Register
1131 * for {@link #ACTION_BOND_STATE_CHANGED} intents to be notified when
1132 * the bonding process completes, and its result.
1133 * <p>Android system services will handle the necessary user interactions
1134 * to confirm and complete the bonding process.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001135 *
Nick Pelly005b2282009-09-10 10:21:56 -07001136 * @return false on immediate error, true if bonding will begin
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001137 */
Tor Norbye2d497522015-04-23 17:10:21 -07001138 @RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN)
Nick Pellybd022f42009-08-14 18:33:38 -07001139 public boolean createBond() {
Jack He16eeac32017-08-17 12:11:18 -07001140 final IBluetooth service = sService;
1141 if (service == null) {
fredc0f420372012-04-12 00:02:00 -07001142 Log.e(TAG, "BT not enabled. Cannot create bond to Remote Device");
1143 return false;
1144 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001145 try {
Jack He2992cd02017-08-22 21:21:23 -07001146 Log.i(TAG, "createBond() for device " + getAddress()
1147 + " called by pid: " + Process.myPid()
1148 + " tid: " + Process.myTid());
Jack He16eeac32017-08-17 12:11:18 -07001149 return service.createBond(this, TRANSPORT_AUTO);
Jack Hea355e5e2017-08-22 16:06:54 -07001150 } catch (RemoteException e) {
1151 Log.e(TAG, "", e);
1152 }
Andre Eisenbach57210c72014-08-04 17:51:43 -07001153 return false;
1154 }
1155
1156 /**
1157 * Start the bonding (pairing) process with the remote device using the
1158 * specified transport.
1159 *
1160 * <p>This is an asynchronous call, it will return immediately. Register
1161 * for {@link #ACTION_BOND_STATE_CHANGED} intents to be notified when
1162 * the bonding process completes, and its result.
1163 * <p>Android system services will handle the necessary user interactions
1164 * to confirm and complete the bonding process.
1165 * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}.
1166 *
1167 * @param transport The transport to use for the pairing procedure.
1168 * @return false on immediate error, true if bonding will begin
1169 * @throws IllegalArgumentException if an invalid transport was specified
1170 * @hide
1171 */
Mathew Inwood4dc66d32018-08-01 15:07:20 +01001172 @UnsupportedAppUsage
Andre Eisenbach57210c72014-08-04 17:51:43 -07001173 public boolean createBond(int transport) {
Jack He16eeac32017-08-17 12:11:18 -07001174 final IBluetooth service = sService;
1175 if (service == null) {
Andre Eisenbach57210c72014-08-04 17:51:43 -07001176 Log.e(TAG, "BT not enabled. Cannot create bond to Remote Device");
1177 return false;
1178 }
Jack Hea355e5e2017-08-22 16:06:54 -07001179 if (TRANSPORT_AUTO > transport || transport > TRANSPORT_LE) {
Andre Eisenbach57210c72014-08-04 17:51:43 -07001180 throw new IllegalArgumentException(transport + " is not a valid Bluetooth transport");
1181 }
1182 try {
Jack He2992cd02017-08-22 21:21:23 -07001183 Log.i(TAG, "createBond() for device " + getAddress()
1184 + " called by pid: " + Process.myPid()
1185 + " tid: " + Process.myTid());
Jack He16eeac32017-08-17 12:11:18 -07001186 return service.createBond(this, transport);
Jack Hea355e5e2017-08-22 16:06:54 -07001187 } catch (RemoteException e) {
1188 Log.e(TAG, "", e);
1189 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001190 return false;
1191 }
1192
1193 /**
Jaikumar Ganeshcc5494c2010-09-09 15:37:57 -07001194 * Start the bonding (pairing) process with the remote device using the
1195 * Out Of Band mechanism.
1196 *
1197 * <p>This is an asynchronous call, it will return immediately. Register
1198 * for {@link #ACTION_BOND_STATE_CHANGED} intents to be notified when
1199 * the bonding process completes, and its result.
1200 *
1201 * <p>Android system services will handle the necessary user interactions
1202 * to confirm and complete the bonding process.
1203 *
1204 * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}.
1205 *
Jakub Pawlowski2fc6e6b2015-12-29 13:19:21 -08001206 * @param transport - Transport to use
1207 * @param oobData - Out Of Band data
Jaikumar Ganeshcc5494c2010-09-09 15:37:57 -07001208 * @return false on immediate error, true if bonding will begin
Jaikumar Ganeshcc5494c2010-09-09 15:37:57 -07001209 * @hide
1210 */
Jakub Pawlowski2fc6e6b2015-12-29 13:19:21 -08001211 public boolean createBondOutOfBand(int transport, OobData oobData) {
Jack He16eeac32017-08-17 12:11:18 -07001212 final IBluetooth service = sService;
1213 if (service == null) {
1214 Log.w(TAG, "BT not enabled, createBondOutOfBand failed");
1215 return false;
1216 }
Jaikumar Ganeshcc5494c2010-09-09 15:37:57 -07001217 try {
Jack He16eeac32017-08-17 12:11:18 -07001218 return service.createBondOutOfBand(this, transport, oobData);
Jack Hea355e5e2017-08-22 16:06:54 -07001219 } catch (RemoteException e) {
1220 Log.e(TAG, "", e);
1221 }
Jaikumar Ganeshcc5494c2010-09-09 15:37:57 -07001222 return false;
1223 }
1224
Jakub Pawlowski0278ab92016-07-20 11:55:48 -07001225 /** @hide */
Mathew Inwood4dc66d32018-08-01 15:07:20 +01001226 @UnsupportedAppUsage
Jakub Pawlowski0278ab92016-07-20 11:55:48 -07001227 public boolean isBondingInitiatedLocally() {
Jack He16eeac32017-08-17 12:11:18 -07001228 final IBluetooth service = sService;
1229 if (service == null) {
1230 Log.w(TAG, "BT not enabled, isBondingInitiatedLocally failed");
1231 return false;
1232 }
Jakub Pawlowski0278ab92016-07-20 11:55:48 -07001233 try {
Jack He16eeac32017-08-17 12:11:18 -07001234 return service.isBondingInitiatedLocally(this);
Jack Hea355e5e2017-08-22 16:06:54 -07001235 } catch (RemoteException e) {
1236 Log.e(TAG, "", e);
1237 }
Jakub Pawlowski0278ab92016-07-20 11:55:48 -07001238 return false;
1239 }
1240
Jaikumar Ganeshcc5494c2010-09-09 15:37:57 -07001241 /**
1242 * Set the Out Of Band data for a remote device to be used later
1243 * in the pairing mechanism. Users can obtain this data through other
1244 * trusted channels
1245 *
1246 * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}.
1247 *
1248 * @param hash Simple Secure pairing hash
1249 * @param randomizer The random key obtained using OOB
1250 * @return false on error; true otherwise
Jaikumar Ganeshcc5494c2010-09-09 15:37:57 -07001251 * @hide
1252 */
1253 public boolean setDeviceOutOfBandData(byte[] hash, byte[] randomizer) {
Jack Hea355e5e2017-08-22 16:06:54 -07001254 //TODO(BT)
Jaikumar Ganeshe4caddb2012-01-25 16:16:48 -08001255 /*
Jaikumar Ganeshcc5494c2010-09-09 15:37:57 -07001256 try {
Jaikumar Ganeshe4caddb2012-01-25 16:16:48 -08001257 return sService.setDeviceOutOfBandData(this, hash, randomizer);
1258 } catch (RemoteException e) {Log.e(TAG, "", e);} */
Jack Hea355e5e2017-08-22 16:06:54 -07001259 return false;
Jaikumar Ganeshcc5494c2010-09-09 15:37:57 -07001260 }
1261
1262 /**
Nick Pelly005b2282009-09-10 10:21:56 -07001263 * Cancel an in-progress bonding request started with {@link #createBond}.
1264 * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}.
1265 *
Jake Hambyf51eada2010-09-21 13:39:53 -07001266 * @return true on success, false on error
Nick Pelly18b1e792009-09-24 11:14:15 -07001267 * @hide
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001268 */
Selim Gurun4029fa62017-10-17 17:01:38 -07001269 @SystemApi
1270 @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADMIN)
Nick Pellybd022f42009-08-14 18:33:38 -07001271 public boolean cancelBondProcess() {
Jack He16eeac32017-08-17 12:11:18 -07001272 final IBluetooth service = sService;
1273 if (service == null) {
fredc0f420372012-04-12 00:02:00 -07001274 Log.e(TAG, "BT not enabled. Cannot cancel Remote Device bond");
1275 return false;
1276 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001277 try {
Jack He2992cd02017-08-22 21:21:23 -07001278 Log.i(TAG, "cancelBondProcess() for device " + getAddress()
1279 + " called by pid: " + Process.myPid()
1280 + " tid: " + Process.myTid());
Jack He16eeac32017-08-17 12:11:18 -07001281 return service.cancelBondProcess(this);
Jack Hea355e5e2017-08-22 16:06:54 -07001282 } catch (RemoteException e) {
1283 Log.e(TAG, "", e);
1284 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001285 return false;
1286 }
1287
1288 /**
Nick Pelly005b2282009-09-10 10:21:56 -07001289 * Remove bond (pairing) with the remote device.
1290 * <p>Delete the link key associated with the remote device, and
1291 * immediately terminate connections to that device that require
1292 * authentication and encryption.
1293 * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001294 *
Jake Hambyf51eada2010-09-21 13:39:53 -07001295 * @return true on success, false on error
Nick Pelly18b1e792009-09-24 11:14:15 -07001296 * @hide
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001297 */
Selim Gurun4029fa62017-10-17 17:01:38 -07001298 @SystemApi
1299 @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADMIN)
Nick Pellybd022f42009-08-14 18:33:38 -07001300 public boolean removeBond() {
Jack He16eeac32017-08-17 12:11:18 -07001301 final IBluetooth service = sService;
1302 if (service == null) {
fredc0f420372012-04-12 00:02:00 -07001303 Log.e(TAG, "BT not enabled. Cannot remove Remote Device bond");
1304 return false;
1305 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001306 try {
Jack He2992cd02017-08-22 21:21:23 -07001307 Log.i(TAG, "removeBond() for device " + getAddress()
1308 + " called by pid: " + Process.myPid()
1309 + " tid: " + Process.myTid());
Jack He16eeac32017-08-17 12:11:18 -07001310 return service.removeBond(this);
Jack Hea355e5e2017-08-22 16:06:54 -07001311 } catch (RemoteException e) {
1312 Log.e(TAG, "", e);
1313 }
Nick Pellybd022f42009-08-14 18:33:38 -07001314 return false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001315 }
1316
1317 /**
Nick Pelly005b2282009-09-10 10:21:56 -07001318 * Get the bond state of the remote device.
1319 * <p>Possible values for the bond state are:
1320 * {@link #BOND_NONE},
1321 * {@link #BOND_BONDING},
1322 * {@link #BOND_BONDED}.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001323 *
Nick Pelly005b2282009-09-10 10:21:56 -07001324 * @return the bond state
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001325 */
Tor Norbye2d497522015-04-23 17:10:21 -07001326 @RequiresPermission(Manifest.permission.BLUETOOTH)
Nick Pellybd022f42009-08-14 18:33:38 -07001327 public int getBondState() {
Jack He16eeac32017-08-17 12:11:18 -07001328 final IBluetooth service = sService;
1329 if (service == null) {
fredc0f420372012-04-12 00:02:00 -07001330 Log.e(TAG, "BT not enabled. Cannot get bond state");
1331 return BOND_NONE;
1332 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001333 try {
Jack He16eeac32017-08-17 12:11:18 -07001334 return service.getBondState(this);
Jack Hea355e5e2017-08-22 16:06:54 -07001335 } catch (RemoteException e) {
1336 Log.e(TAG, "", e);
Syed Ibrahim M305f2402012-06-19 10:14:25 -07001337 }
Nick Pelly005b2282009-09-10 10:21:56 -07001338 return BOND_NONE;
1339 }
1340
1341 /**
Jay Civelli174928c2014-05-08 09:24:08 -07001342 * Returns whether there is an open connection to this device.
1343 * <p>Requires {@link android.Manifest.permission#BLUETOOTH}.
1344 *
1345 * @return True if there is at least one open connection to this device.
1346 * @hide
1347 */
Andre Eisenbach2b8696e2015-02-05 20:06:33 -08001348 @SystemApi
Selim Gurun4029fa62017-10-17 17:01:38 -07001349 @RequiresPermission(android.Manifest.permission.BLUETOOTH)
Jay Civelli174928c2014-05-08 09:24:08 -07001350 public boolean isConnected() {
Jack He16eeac32017-08-17 12:11:18 -07001351 final IBluetooth service = sService;
1352 if (service == null) {
Jay Civelli174928c2014-05-08 09:24:08 -07001353 // BT is not enabled, we cannot be connected.
1354 return false;
1355 }
1356 try {
Jack He16eeac32017-08-17 12:11:18 -07001357 return service.getConnectionState(this) != CONNECTION_STATE_DISCONNECTED;
Andre Eisenbach2b8696e2015-02-05 20:06:33 -08001358 } catch (RemoteException e) {
1359 Log.e(TAG, "", e);
1360 return false;
1361 }
1362 }
1363
1364 /**
1365 * Returns whether there is an open connection to this device
1366 * that has been encrypted.
1367 * <p>Requires {@link android.Manifest.permission#BLUETOOTH}.
1368 *
1369 * @return True if there is at least one encrypted connection to this device.
1370 * @hide
1371 */
1372 @SystemApi
Selim Gurun4029fa62017-10-17 17:01:38 -07001373 @RequiresPermission(android.Manifest.permission.BLUETOOTH)
Andre Eisenbach2b8696e2015-02-05 20:06:33 -08001374 public boolean isEncrypted() {
Jack He16eeac32017-08-17 12:11:18 -07001375 final IBluetooth service = sService;
1376 if (service == null) {
Andre Eisenbach2b8696e2015-02-05 20:06:33 -08001377 // BT is not enabled, we cannot be connected.
1378 return false;
1379 }
1380 try {
Jack He16eeac32017-08-17 12:11:18 -07001381 return service.getConnectionState(this) > CONNECTION_STATE_CONNECTED;
Jay Civelli174928c2014-05-08 09:24:08 -07001382 } catch (RemoteException e) {
1383 Log.e(TAG, "", e);
1384 return false;
1385 }
1386 }
1387
1388 /**
Nick Pelly005b2282009-09-10 10:21:56 -07001389 * Get the Bluetooth class of the remote device.
Nick Pelly005b2282009-09-10 10:21:56 -07001390 *
1391 * @return Bluetooth class object, or null on error
1392 */
Tor Norbye2d497522015-04-23 17:10:21 -07001393 @RequiresPermission(Manifest.permission.BLUETOOTH)
Nick Pelly005b2282009-09-10 10:21:56 -07001394 public BluetoothClass getBluetoothClass() {
Jack He16eeac32017-08-17 12:11:18 -07001395 final IBluetooth service = sService;
1396 if (service == null) {
fredc0f420372012-04-12 00:02:00 -07001397 Log.e(TAG, "BT not enabled. Cannot get Bluetooth Class");
1398 return null;
1399 }
Nick Pelly005b2282009-09-10 10:21:56 -07001400 try {
Jack He16eeac32017-08-17 12:11:18 -07001401 int classInt = service.getRemoteClass(this);
Nick Pelly005b2282009-09-10 10:21:56 -07001402 if (classInt == BluetoothClass.ERROR) return null;
1403 return new BluetoothClass(classInt);
Jack Hea355e5e2017-08-22 16:06:54 -07001404 } catch (RemoteException e) {
1405 Log.e(TAG, "", e);
1406 }
Nick Pelly005b2282009-09-10 10:21:56 -07001407 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001408 }
1409
Lixin Yueefa1dd72009-08-31 15:55:13 +08001410 /**
Matthew Xiead232102011-11-08 10:58:12 -08001411 * Returns the supported features (UUIDs) of the remote device.
1412 *
1413 * <p>This method does not start a service discovery procedure to retrieve the UUIDs
1414 * from the remote device. Instead, the local cached copy of the service
1415 * UUIDs are returned.
1416 * <p>Use {@link #fetchUuidsWithSdp} if fresh UUIDs are desired.
Matthew Xiead232102011-11-08 10:58:12 -08001417 *
Jack Hea355e5e2017-08-22 16:06:54 -07001418 * @return the supported features (UUIDs) of the remote device, or null on error
Matthew Xiead232102011-11-08 10:58:12 -08001419 */
Tor Norbye2d497522015-04-23 17:10:21 -07001420 @RequiresPermission(Manifest.permission.BLUETOOTH)
Jack Hea355e5e2017-08-22 16:06:54 -07001421 public ParcelUuid[] getUuids() {
Jack He16eeac32017-08-17 12:11:18 -07001422 final IBluetooth service = sService;
1423 if (service == null || !isBluetoothEnabled()) {
fredc0f420372012-04-12 00:02:00 -07001424 Log.e(TAG, "BT not enabled. Cannot get remote device Uuids");
Jack Hea355e5e2017-08-22 16:06:54 -07001425 return null;
1426 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001427 try {
Jack He16eeac32017-08-17 12:11:18 -07001428 return service.getRemoteUuids(this);
Jack Hea355e5e2017-08-22 16:06:54 -07001429 } catch (RemoteException e) {
1430 Log.e(TAG, "", e);
1431 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001432 return null;
1433 }
Jaikumar Ganeshd5ac1ae2009-05-05 22:26:12 -07001434
Jack Hea355e5e2017-08-22 16:06:54 -07001435 /**
1436 * Perform a service discovery on the remote device to get the UUIDs supported.
1437 *
1438 * <p>This API is asynchronous and {@link #ACTION_UUID} intent is sent,
1439 * with the UUIDs supported by the remote end. If there is an error
1440 * in getting the SDP records or if the process takes a long time,
1441 * {@link #ACTION_UUID} intent is sent with the UUIDs that is currently
1442 * present in the cache. Clients should use the {@link #getUuids} to get UUIDs
1443 * if service discovery is not to be performed.
1444 *
1445 * @return False if the sanity check fails, True if the process of initiating an ACL connection
1446 * to the remote device was started.
1447 */
1448 @RequiresPermission(Manifest.permission.BLUETOOTH)
1449 public boolean fetchUuidsWithSdp() {
Jack He16eeac32017-08-17 12:11:18 -07001450 final IBluetooth service = sService;
Jack He2992cd02017-08-22 21:21:23 -07001451 if (service == null || !isBluetoothEnabled()) {
Zhihai Xu5d04f1c2014-01-13 16:54:38 -08001452 Log.e(TAG, "BT not enabled. Cannot fetchUuidsWithSdp");
1453 return false;
1454 }
Jaikumar Ganesh1caa6d12009-09-18 11:32:54 -07001455 try {
Zhihai Xu5d04f1c2014-01-13 16:54:38 -08001456 return service.fetchRemoteUuids(this);
Jack Hea355e5e2017-08-22 16:06:54 -07001457 } catch (RemoteException e) {
1458 Log.e(TAG, "", e);
1459 }
1460 return false;
Jaikumar Ganesh1caa6d12009-09-18 11:32:54 -07001461 }
1462
Jack Hea355e5e2017-08-22 16:06:54 -07001463 /**
1464 * Perform a service discovery on the remote device to get the SDP records associated
1465 * with the specified UUID.
1466 *
1467 * <p>This API is asynchronous and {@link #ACTION_SDP_RECORD} intent is sent,
1468 * with the SDP records found on the remote end. If there is an error
1469 * in getting the SDP records or if the process takes a long time,
1470 * {@link #ACTION_SDP_RECORD} intent is sent with an status value in
1471 * {@link #EXTRA_SDP_SEARCH_STATUS} different from 0.
1472 * Detailed status error codes can be found by members of the Bluetooth package in
1473 * the AbstractionLayer class.
1474 * <p>Requires {@link android.Manifest.permission#BLUETOOTH}.
1475 * The SDP record data will be stored in the intent as {@link #EXTRA_SDP_RECORD}.
1476 * The object type will match one of the SdpXxxRecord types, depending on the UUID searched
1477 * for.
1478 *
1479 * @return False if the sanity check fails, True if the process
1480 * of initiating an ACL connection to the remote device
1481 * was started.
1482 */
1483 /** @hide */
1484 public boolean sdpSearch(ParcelUuid uuid) {
Jack He16eeac32017-08-17 12:11:18 -07001485 final IBluetooth service = sService;
1486 if (service == null) {
Jack Hea355e5e2017-08-22 16:06:54 -07001487 Log.e(TAG, "BT not enabled. Cannot query remote device sdp records");
1488 return false;
1489 }
1490 try {
Jack He16eeac32017-08-17 12:11:18 -07001491 return service.sdpSearch(this, uuid);
Jack Hea355e5e2017-08-22 16:06:54 -07001492 } catch (RemoteException e) {
1493 Log.e(TAG, "", e);
1494 }
1495 return false;
1496 }
Hemant Gupta8949bfb2013-08-16 14:57:55 +05301497
Matthew Xie091fc2b2013-09-23 23:23:13 -07001498 /**
1499 * Set the pin during pairing when the pairing method is {@link #PAIRING_VARIANT_PIN}
Matthew Xieac2c6c32013-10-21 14:56:33 -07001500 * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}.
Matthew Xie091fc2b2013-09-23 23:23:13 -07001501 *
Jack Hea355e5e2017-08-22 16:06:54 -07001502 * @return true pin has been set false for error
Matthew Xie091fc2b2013-09-23 23:23:13 -07001503 */
Nick Pellybd022f42009-08-14 18:33:38 -07001504 public boolean setPin(byte[] pin) {
Jack He16eeac32017-08-17 12:11:18 -07001505 final IBluetooth service = sService;
1506 if (service == null) {
fredc0f420372012-04-12 00:02:00 -07001507 Log.e(TAG, "BT not enabled. Cannot set Remote Device pin");
1508 return false;
1509 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001510 try {
Jack He16eeac32017-08-17 12:11:18 -07001511 return service.setPin(this, true, pin.length, pin);
Jack Hea355e5e2017-08-22 16:06:54 -07001512 } catch (RemoteException e) {
1513 Log.e(TAG, "", e);
1514 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001515 return false;
1516 }
Jaikumar Ganeshb0eca412009-07-16 18:26:28 -07001517
Nick Pelly45e27042009-08-19 11:00:00 -07001518 /** @hide */
Mathew Inwood4dc66d32018-08-01 15:07:20 +01001519 @UnsupportedAppUsage
Nick Pellybd022f42009-08-14 18:33:38 -07001520 public boolean setPasskey(int passkey) {
Jaikumar Ganeshe4caddb2012-01-25 16:16:48 -08001521 //TODO(BT)
1522 /*
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001523 try {
Jaikumar Ganeshe4caddb2012-01-25 16:16:48 -08001524 return sService.setPasskey(this, true, 4, passkey);
1525 } catch (RemoteException e) {Log.e(TAG, "", e);}*/
Jaikumar Ganeshb0eca412009-07-16 18:26:28 -07001526 return false;
1527 }
1528
Matthew Xie091fc2b2013-09-23 23:23:13 -07001529 /**
1530 * Confirm passkey for {@link #PAIRING_VARIANT_PASSKEY_CONFIRMATION} pairing.
Matthew Xie091fc2b2013-09-23 23:23:13 -07001531 *
Jack Hea355e5e2017-08-22 16:06:54 -07001532 * @return true confirmation has been sent out false for error
Matthew Xie091fc2b2013-09-23 23:23:13 -07001533 */
Marie Janssen93326cf2016-08-09 13:23:39 -07001534 @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
Nick Pellybd022f42009-08-14 18:33:38 -07001535 public boolean setPairingConfirmation(boolean confirm) {
Jack He16eeac32017-08-17 12:11:18 -07001536 final IBluetooth service = sService;
1537 if (service == null) {
fredc0f420372012-04-12 00:02:00 -07001538 Log.e(TAG, "BT not enabled. Cannot set pairing confirmation");
1539 return false;
1540 }
Jaikumar Ganeshb0eca412009-07-16 18:26:28 -07001541 try {
Jack He16eeac32017-08-17 12:11:18 -07001542 return service.setPairingConfirmation(this, confirm);
Jack Hea355e5e2017-08-22 16:06:54 -07001543 } catch (RemoteException e) {
1544 Log.e(TAG, "", e);
1545 }
Jaikumar Ganeshb0eca412009-07-16 18:26:28 -07001546 return false;
1547 }
1548
Nick Pelly45e27042009-08-19 11:00:00 -07001549 /** @hide */
Jaikumar Ganeshcc5494c2010-09-09 15:37:57 -07001550 public boolean setRemoteOutOfBandData() {
Jaikumar Ganeshe4caddb2012-01-25 16:16:48 -08001551 // TODO(BT)
1552 /*
Jaikumar Ganeshcc5494c2010-09-09 15:37:57 -07001553 try {
Jaikumar Ganeshe4caddb2012-01-25 16:16:48 -08001554 return sService.setRemoteOutOfBandData(this);
1555 } catch (RemoteException e) {Log.e(TAG, "", e);}*/
Jack Hea355e5e2017-08-22 16:06:54 -07001556 return false;
Jaikumar Ganeshcc5494c2010-09-09 15:37:57 -07001557 }
1558
1559 /** @hide */
Mathew Inwood4dc66d32018-08-01 15:07:20 +01001560 @UnsupportedAppUsage
Nick Pellybd022f42009-08-14 18:33:38 -07001561 public boolean cancelPairingUserInput() {
Jack He16eeac32017-08-17 12:11:18 -07001562 final IBluetooth service = sService;
1563 if (service == null) {
fredc0f420372012-04-12 00:02:00 -07001564 Log.e(TAG, "BT not enabled. Cannot create pairing user input");
1565 return false;
1566 }
Jaikumar Ganeshb0eca412009-07-16 18:26:28 -07001567 try {
Jack He16eeac32017-08-17 12:11:18 -07001568 return service.cancelBondProcess(this);
Jack Hea355e5e2017-08-22 16:06:54 -07001569 } catch (RemoteException e) {
1570 Log.e(TAG, "", e);
1571 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001572 return false;
1573 }
1574
Jaikumar Ganesh3fbf7b62009-12-02 17:28:38 -08001575 /** @hide */
Mathew Inwood4dc66d32018-08-01 15:07:20 +01001576 @UnsupportedAppUsage
Jaikumar Ganesh3fbf7b62009-12-02 17:28:38 -08001577 public boolean isBluetoothDock() {
Jaikumar Ganeshe4caddb2012-01-25 16:16:48 -08001578 // TODO(BT)
1579 /*
Jaikumar Ganesh3fbf7b62009-12-02 17:28:38 -08001580 try {
Jaikumar Ganeshe4caddb2012-01-25 16:16:48 -08001581 return sService.isBluetoothDock(this);
1582 } catch (RemoteException e) {Log.e(TAG, "", e);}*/
Jaikumar Ganesh3fbf7b62009-12-02 17:28:38 -08001583 return false;
1584 }
1585
Jack Hea355e5e2017-08-22 16:06:54 -07001586 boolean isBluetoothEnabled() {
1587 boolean ret = false;
1588 BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
Jack He2992cd02017-08-22 21:21:23 -07001589 if (adapter != null && adapter.isEnabled()) {
Jack Hea355e5e2017-08-22 16:06:54 -07001590 ret = true;
1591 }
1592 return ret;
1593 }
Nitin Arorad055adb2015-03-02 15:03:51 -08001594
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001595 /**
Edward Jee8dd30aa2014-09-05 00:29:14 -07001596 * Requires {@link android.Manifest.permission#BLUETOOTH}.
Jack Hea355e5e2017-08-22 16:06:54 -07001597 *
1598 * @return Whether the phonebook access is allowed to this device. Can be {@link
1599 * #ACCESS_UNKNOWN}, {@link #ACCESS_ALLOWED} or {@link #ACCESS_REJECTED}.
Edward Jee8dd30aa2014-09-05 00:29:14 -07001600 * @hide
1601 */
Mathew Inwood4dc66d32018-08-01 15:07:20 +01001602 @UnsupportedAppUsage
Edward Jee8dd30aa2014-09-05 00:29:14 -07001603 public int getPhonebookAccessPermission() {
Jack He16eeac32017-08-17 12:11:18 -07001604 final IBluetooth service = sService;
1605 if (service == null) {
Edward Jee8dd30aa2014-09-05 00:29:14 -07001606 return ACCESS_UNKNOWN;
1607 }
1608 try {
Jack He16eeac32017-08-17 12:11:18 -07001609 return service.getPhonebookAccessPermission(this);
Edward Jee8dd30aa2014-09-05 00:29:14 -07001610 } catch (RemoteException e) {
1611 Log.e(TAG, "", e);
1612 }
1613 return ACCESS_UNKNOWN;
1614 }
1615
1616 /**
Ugo Yubfbe0ee2019-01-13 02:50:07 +08001617 * Set the Bluetooth device silence mode.
1618 *
1619 * When the {@link BluetoothDevice} enters silence mode, and the {@link BluetoothDevice}
1620 * is an active device (for A2DP or HFP), the active device for that profile
1621 * will be set to null.
1622 * If the {@link BluetoothDevice} exits silence mode while the A2DP or HFP
1623 * active device is null, the {@link BluetoothDevice} will be set as the
1624 * active device for that profile.
1625 * If the {@link BluetoothDevice} is disconnected, it exits silence mode.
1626 * If the {@link BluetoothDevice} is set as the active device for A2DP or
1627 * HFP, while silence mode is enabled, then the device will exit silence mode.
1628 * If the {@link BluetoothDevice} is in silence mode, AVRCP position change
1629 * event and HFP AG indicators will be disabled.
1630 * If the {@link BluetoothDevice} is not connected with A2DP or HFP, it cannot
1631 * enter silence mode.
1632 *
1633 * <p> Requires {@link android.Manifest.permission#BLUETOOTH_PRIVILEGED}.
1634 *
1635 * @param silence true to enter silence mode, false to exit
1636 * @return true on success, false on error.
1637 * @hide
1638 */
1639 @SystemApi
1640 @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED)
1641 public boolean setSilenceMode(boolean silence) {
1642 final IBluetooth service = sService;
1643 if (service == null) {
1644 return false;
1645 }
1646 try {
1647 if (getSilenceMode() == silence) {
1648 return true;
1649 }
1650 return service.setSilenceMode(this, silence);
1651 } catch (RemoteException e) {
1652 Log.e(TAG, "setSilenceMode fail", e);
1653 return false;
1654 }
1655 }
1656
1657 /**
1658 * Get the device silence mode status
1659 *
1660 * <p> Requires {@link android.Manifest.permission#BLUETOOTH_PRIVILEGED}.
1661 *
1662 * @return true on device in silence mode, otherwise false.
1663 * @hide
1664 */
1665 @SystemApi
1666 @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED)
1667 public boolean getSilenceMode() {
1668 final IBluetooth service = sService;
1669 if (service == null) {
1670 return false;
1671 }
1672 try {
1673 return service.getSilenceMode(this);
1674 } catch (RemoteException e) {
1675 Log.e(TAG, "getSilenceMode fail", e);
1676 return false;
1677 }
1678 }
1679
1680 /**
Edward Jee8dd30aa2014-09-05 00:29:14 -07001681 * Sets whether the phonebook access is allowed to this device.
1682 * <p>Requires {@link android.Manifest.permission#BLUETOOTH_PRIVILEGED}.
Jack Hea355e5e2017-08-22 16:06:54 -07001683 *
1684 * @param value Can be {@link #ACCESS_UNKNOWN}, {@link #ACCESS_ALLOWED} or {@link
1685 * #ACCESS_REJECTED}.
Edward Jee8dd30aa2014-09-05 00:29:14 -07001686 * @return Whether the value has been successfully set.
1687 * @hide
1688 */
Selim Gurun4029fa62017-10-17 17:01:38 -07001689 @SystemApi
1690 @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED)
Edward Jee8dd30aa2014-09-05 00:29:14 -07001691 public boolean setPhonebookAccessPermission(int value) {
Jack He16eeac32017-08-17 12:11:18 -07001692 final IBluetooth service = sService;
1693 if (service == null) {
Edward Jee8dd30aa2014-09-05 00:29:14 -07001694 return false;
1695 }
1696 try {
Jack He16eeac32017-08-17 12:11:18 -07001697 return service.setPhonebookAccessPermission(this, value);
Edward Jee8dd30aa2014-09-05 00:29:14 -07001698 } catch (RemoteException e) {
1699 Log.e(TAG, "", e);
1700 }
1701 return false;
1702 }
1703
1704 /**
1705 * Requires {@link android.Manifest.permission#BLUETOOTH}.
Jack Hea355e5e2017-08-22 16:06:54 -07001706 *
1707 * @return Whether the message access is allowed to this device. Can be {@link #ACCESS_UNKNOWN},
1708 * {@link #ACCESS_ALLOWED} or {@link #ACCESS_REJECTED}.
Edward Jee8dd30aa2014-09-05 00:29:14 -07001709 * @hide
1710 */
Mathew Inwood4dc66d32018-08-01 15:07:20 +01001711 @UnsupportedAppUsage
Edward Jee8dd30aa2014-09-05 00:29:14 -07001712 public int getMessageAccessPermission() {
Jack He16eeac32017-08-17 12:11:18 -07001713 final IBluetooth service = sService;
1714 if (service == null) {
Edward Jee8dd30aa2014-09-05 00:29:14 -07001715 return ACCESS_UNKNOWN;
1716 }
1717 try {
Jack He16eeac32017-08-17 12:11:18 -07001718 return service.getMessageAccessPermission(this);
Edward Jee8dd30aa2014-09-05 00:29:14 -07001719 } catch (RemoteException e) {
1720 Log.e(TAG, "", e);
1721 }
1722 return ACCESS_UNKNOWN;
1723 }
1724
1725 /**
1726 * Sets whether the message access is allowed to this device.
1727 * <p>Requires {@link android.Manifest.permission#BLUETOOTH_PRIVILEGED}.
Jack Hea355e5e2017-08-22 16:06:54 -07001728 *
1729 * @param value Can be {@link #ACCESS_UNKNOWN}, {@link #ACCESS_ALLOWED} or {@link
1730 * #ACCESS_REJECTED}.
Edward Jee8dd30aa2014-09-05 00:29:14 -07001731 * @return Whether the value has been successfully set.
1732 * @hide
1733 */
Mathew Inwood4dc66d32018-08-01 15:07:20 +01001734 @UnsupportedAppUsage
Edward Jee8dd30aa2014-09-05 00:29:14 -07001735 public boolean setMessageAccessPermission(int value) {
Jack He16eeac32017-08-17 12:11:18 -07001736 final IBluetooth service = sService;
1737 if (service == null) {
Edward Jee8dd30aa2014-09-05 00:29:14 -07001738 return false;
1739 }
1740 try {
Jack He16eeac32017-08-17 12:11:18 -07001741 return service.setMessageAccessPermission(this, value);
Edward Jee8dd30aa2014-09-05 00:29:14 -07001742 } catch (RemoteException e) {
1743 Log.e(TAG, "", e);
1744 }
1745 return false;
1746 }
1747
1748 /**
Casper Bonde2a5f6082015-03-19 10:36:45 +01001749 * Requires {@link android.Manifest.permission#BLUETOOTH}.
Jack Hea355e5e2017-08-22 16:06:54 -07001750 *
1751 * @return Whether the Sim access is allowed to this device. Can be {@link #ACCESS_UNKNOWN},
1752 * {@link #ACCESS_ALLOWED} or {@link #ACCESS_REJECTED}.
Casper Bonde2a5f6082015-03-19 10:36:45 +01001753 * @hide
1754 */
1755 public int getSimAccessPermission() {
Jack He16eeac32017-08-17 12:11:18 -07001756 final IBluetooth service = sService;
1757 if (service == null) {
Casper Bonde2a5f6082015-03-19 10:36:45 +01001758 return ACCESS_UNKNOWN;
1759 }
1760 try {
Jack He16eeac32017-08-17 12:11:18 -07001761 return service.getSimAccessPermission(this);
Casper Bonde2a5f6082015-03-19 10:36:45 +01001762 } catch (RemoteException e) {
1763 Log.e(TAG, "", e);
1764 }
1765 return ACCESS_UNKNOWN;
1766 }
1767
1768 /**
1769 * Sets whether the Sim access is allowed to this device.
1770 * <p>Requires {@link android.Manifest.permission#BLUETOOTH_PRIVILEGED}.
Jack Hea355e5e2017-08-22 16:06:54 -07001771 *
1772 * @param value Can be {@link #ACCESS_UNKNOWN}, {@link #ACCESS_ALLOWED} or {@link
1773 * #ACCESS_REJECTED}.
Casper Bonde2a5f6082015-03-19 10:36:45 +01001774 * @return Whether the value has been successfully set.
1775 * @hide
1776 */
Mathew Inwood4dc66d32018-08-01 15:07:20 +01001777 @UnsupportedAppUsage
Casper Bonde2a5f6082015-03-19 10:36:45 +01001778 public boolean setSimAccessPermission(int value) {
Jack He16eeac32017-08-17 12:11:18 -07001779 final IBluetooth service = sService;
1780 if (service == null) {
Casper Bonde2a5f6082015-03-19 10:36:45 +01001781 return false;
1782 }
1783 try {
Jack He16eeac32017-08-17 12:11:18 -07001784 return service.setSimAccessPermission(this, value);
Casper Bonde2a5f6082015-03-19 10:36:45 +01001785 } catch (RemoteException e) {
1786 Log.e(TAG, "", e);
1787 }
1788 return false;
Casper Bonde3b3d1fe2015-05-08 14:32:24 +02001789 }
1790
Casper Bonde2a5f6082015-03-19 10:36:45 +01001791 /**
Nick Pelly45e27042009-08-19 11:00:00 -07001792 * Create an RFCOMM {@link BluetoothSocket} ready to start a secure
Nick Pelly16fb88a2009-10-07 07:44:03 +02001793 * outgoing connection to this remote device on given channel.
Nick Pelly45e27042009-08-19 11:00:00 -07001794 * <p>The remote device will be authenticated and communication on this
1795 * socket will be encrypted.
Jaikumar Ganeshc8fa4ff2011-01-25 16:03:13 -08001796 * <p> Use this socket only if an authenticated socket link is possible.
1797 * Authentication refers to the authentication of the link key to
1798 * prevent man-in-the-middle type of attacks.
1799 * For example, for Bluetooth 2.1 devices, if any of the devices does not
1800 * have an input and output capability or just has the ability to
1801 * display a numeric key, a secure socket connection is not possible.
Andrew Solovaya44f2c072018-10-02 14:14:42 -07001802 * In such a case, use {@link createInsecureRfcommSocket}.
Jaikumar Ganeshc8fa4ff2011-01-25 16:03:13 -08001803 * For more details, refer to the Security Model section 5.2 (vol 3) of
1804 * Bluetooth Core Specification version 2.1 + EDR.
Jake Hambyf51eada2010-09-21 13:39:53 -07001805 * <p>Use {@link BluetoothSocket#connect} to initiate the outgoing
Nick Pelly45e27042009-08-19 11:00:00 -07001806 * connection.
1807 * <p>Valid RFCOMM channels are in range 1 to 30.
Nick Pellycf440592009-09-08 10:12:06 -07001808 * <p>Requires {@link android.Manifest.permission#BLUETOOTH}
Nick Pellyde893f52009-09-08 13:15:33 -07001809 *
Nick Pelly45e27042009-08-19 11:00:00 -07001810 * @param channel RFCOMM channel to connect to
1811 * @return a RFCOMM BluetoothServerSocket ready for an outgoing connection
Jack Hea355e5e2017-08-22 16:06:54 -07001812 * @throws IOException on error, for example Bluetooth not available, or insufficient
1813 * permissions
Nick Pelly16fb88a2009-10-07 07:44:03 +02001814 * @hide
Nick Pellybd022f42009-08-14 18:33:38 -07001815 */
Mathew Inwood4dc66d32018-08-01 15:07:20 +01001816 @UnsupportedAppUsage
Nick Pelly45e27042009-08-19 11:00:00 -07001817 public BluetoothSocket createRfcommSocket(int channel) throws IOException {
Jack He2992cd02017-08-22 21:21:23 -07001818 if (!isBluetoothEnabled()) {
Nitin Arorad055adb2015-03-02 15:03:51 -08001819 Log.e(TAG, "Bluetooth is not enabled");
1820 throw new IOException();
1821 }
Nick Pelly16fb88a2009-10-07 07:44:03 +02001822 return new BluetoothSocket(BluetoothSocket.TYPE_RFCOMM, -1, true, true, this, channel,
1823 null);
1824 }
1825
1826 /**
Casper Bonde238e0f92015-04-09 09:24:48 +02001827 * Create an L2cap {@link BluetoothSocket} ready to start a secure
1828 * outgoing connection to this remote device on given channel.
1829 * <p>The remote device will be authenticated and communication on this
1830 * socket will be encrypted.
1831 * <p> Use this socket only if an authenticated socket link is possible.
1832 * Authentication refers to the authentication of the link key to
1833 * prevent man-in-the-middle type of attacks.
1834 * For example, for Bluetooth 2.1 devices, if any of the devices does not
1835 * have an input and output capability or just has the ability to
1836 * display a numeric key, a secure socket connection is not possible.
Andrew Solovaya44f2c072018-10-02 14:14:42 -07001837 * In such a case, use {@link createInsecureRfcommSocket}.
Casper Bonde238e0f92015-04-09 09:24:48 +02001838 * For more details, refer to the Security Model section 5.2 (vol 3) of
1839 * Bluetooth Core Specification version 2.1 + EDR.
1840 * <p>Use {@link BluetoothSocket#connect} to initiate the outgoing
1841 * connection.
1842 * <p>Valid L2CAP PSM channels are in range 1 to 2^16.
1843 * <p>Requires {@link android.Manifest.permission#BLUETOOTH}
1844 *
1845 * @param channel L2cap PSM/channel to connect to
1846 * @return a RFCOMM BluetoothServerSocket ready for an outgoing connection
Jack Hea355e5e2017-08-22 16:06:54 -07001847 * @throws IOException on error, for example Bluetooth not available, or insufficient
1848 * permissions
Casper Bonde238e0f92015-04-09 09:24:48 +02001849 * @hide
1850 */
1851 public BluetoothSocket createL2capSocket(int channel) throws IOException {
1852 return new BluetoothSocket(BluetoothSocket.TYPE_L2CAP, -1, true, true, this, channel,
1853 null);
1854 }
1855
1856 /**
Hemant Guptaef3e0db2017-02-03 16:38:59 +05301857 * Create an L2cap {@link BluetoothSocket} ready to start an insecure
1858 * outgoing connection to this remote device on given channel.
1859 * <p>The remote device will be not authenticated and communication on this
1860 * socket will not be encrypted.
1861 * <p>Use {@link BluetoothSocket#connect} to initiate the outgoing
1862 * connection.
1863 * <p>Valid L2CAP PSM channels are in range 1 to 2^16.
1864 * <p>Requires {@link android.Manifest.permission#BLUETOOTH}
1865 *
1866 * @param channel L2cap PSM/channel to connect to
1867 * @return a RFCOMM BluetoothServerSocket ready for an outgoing connection
Jack Hea355e5e2017-08-22 16:06:54 -07001868 * @throws IOException on error, for example Bluetooth not available, or insufficient
1869 * permissions
Hemant Guptaef3e0db2017-02-03 16:38:59 +05301870 * @hide
1871 */
1872 public BluetoothSocket createInsecureL2capSocket(int channel) throws IOException {
1873 return new BluetoothSocket(BluetoothSocket.TYPE_L2CAP, -1, false, false, this, channel,
1874 null);
1875 }
1876
1877 /**
Nick Pelly16fb88a2009-10-07 07:44:03 +02001878 * Create an RFCOMM {@link BluetoothSocket} ready to start a secure
1879 * outgoing connection to this remote device using SDP lookup of uuid.
1880 * <p>This is designed to be used with {@link
1881 * BluetoothAdapter#listenUsingRfcommWithServiceRecord} for peer-peer
1882 * Bluetooth applications.
Jake Hambyf51eada2010-09-21 13:39:53 -07001883 * <p>Use {@link BluetoothSocket#connect} to initiate the outgoing
Nick Pelly16fb88a2009-10-07 07:44:03 +02001884 * connection. This will also perform an SDP lookup of the given uuid to
1885 * determine which channel to connect to.
1886 * <p>The remote device will be authenticated and communication on this
1887 * socket will be encrypted.
Jaikumar Ganeshc8fa4ff2011-01-25 16:03:13 -08001888 * <p> Use this socket only if an authenticated socket link is possible.
1889 * Authentication refers to the authentication of the link key to
1890 * prevent man-in-the-middle type of attacks.
1891 * For example, for Bluetooth 2.1 devices, if any of the devices does not
1892 * have an input and output capability or just has the ability to
1893 * display a numeric key, a secure socket connection is not possible.
Andrew Solovaya44f2c072018-10-02 14:14:42 -07001894 * In such a case, use {@link #createInsecureRfcommSocketToServiceRecord}.
Jaikumar Ganeshc8fa4ff2011-01-25 16:03:13 -08001895 * For more details, refer to the Security Model section 5.2 (vol 3) of
1896 * Bluetooth Core Specification version 2.1 + EDR.
Nick Pellyea5056e2010-02-24 11:19:10 -08001897 * <p>Hint: If you are connecting to a Bluetooth serial board then try
1898 * using the well-known SPP UUID 00001101-0000-1000-8000-00805F9B34FB.
1899 * However if you are connecting to an Android peer then please generate
1900 * your own unique UUID.
Nick Pelly16fb88a2009-10-07 07:44:03 +02001901 *
1902 * @param uuid service record uuid to lookup RFCOMM channel
1903 * @return a RFCOMM BluetoothServerSocket ready for an outgoing connection
Jack Hea355e5e2017-08-22 16:06:54 -07001904 * @throws IOException on error, for example Bluetooth not available, or insufficient
1905 * permissions
Nick Pelly16fb88a2009-10-07 07:44:03 +02001906 */
Tor Norbye2d497522015-04-23 17:10:21 -07001907 @RequiresPermission(Manifest.permission.BLUETOOTH)
Nick Pelly16fb88a2009-10-07 07:44:03 +02001908 public BluetoothSocket createRfcommSocketToServiceRecord(UUID uuid) throws IOException {
Jack He2992cd02017-08-22 21:21:23 -07001909 if (!isBluetoothEnabled()) {
Nitin Arorad055adb2015-03-02 15:03:51 -08001910 Log.e(TAG, "Bluetooth is not enabled");
1911 throw new IOException();
1912 }
1913
Nick Pelly16fb88a2009-10-07 07:44:03 +02001914 return new BluetoothSocket(BluetoothSocket.TYPE_RFCOMM, -1, true, true, this, -1,
1915 new ParcelUuid(uuid));
Nick Pellybd022f42009-08-14 18:33:38 -07001916 }
1917
1918 /**
Jaikumar Ganesh6eef14a2010-12-23 12:57:02 -08001919 * Create an RFCOMM {@link BluetoothSocket} socket ready to start an insecure
1920 * outgoing connection to this remote device using SDP lookup of uuid.
1921 * <p> The communication channel will not have an authenticated link key
1922 * i.e it will be subject to man-in-the-middle attacks. For Bluetooth 2.1
1923 * devices, the link key will be encrypted, as encryption is mandatory.
1924 * For legacy devices (pre Bluetooth 2.1 devices) the link key will
1925 * be not be encrypted. Use {@link #createRfcommSocketToServiceRecord} if an
1926 * encrypted and authenticated communication channel is desired.
1927 * <p>This is designed to be used with {@link
1928 * BluetoothAdapter#listenUsingInsecureRfcommWithServiceRecord} for peer-peer
1929 * Bluetooth applications.
1930 * <p>Use {@link BluetoothSocket#connect} to initiate the outgoing
1931 * connection. This will also perform an SDP lookup of the given uuid to
1932 * determine which channel to connect to.
1933 * <p>The remote device will be authenticated and communication on this
1934 * socket will be encrypted.
1935 * <p>Hint: If you are connecting to a Bluetooth serial board then try
1936 * using the well-known SPP UUID 00001101-0000-1000-8000-00805F9B34FB.
1937 * However if you are connecting to an Android peer then please generate
1938 * your own unique UUID.
Jaikumar Ganesh6eef14a2010-12-23 12:57:02 -08001939 *
1940 * @param uuid service record uuid to lookup RFCOMM channel
1941 * @return a RFCOMM BluetoothServerSocket ready for an outgoing connection
Jack Hea355e5e2017-08-22 16:06:54 -07001942 * @throws IOException on error, for example Bluetooth not available, or insufficient
1943 * permissions
Jaikumar Ganesh6eef14a2010-12-23 12:57:02 -08001944 */
Tor Norbye2d497522015-04-23 17:10:21 -07001945 @RequiresPermission(Manifest.permission.BLUETOOTH)
Jaikumar Ganesh6eef14a2010-12-23 12:57:02 -08001946 public BluetoothSocket createInsecureRfcommSocketToServiceRecord(UUID uuid) throws IOException {
Jack He2992cd02017-08-22 21:21:23 -07001947 if (!isBluetoothEnabled()) {
Nitin Arorad055adb2015-03-02 15:03:51 -08001948 Log.e(TAG, "Bluetooth is not enabled");
1949 throw new IOException();
1950 }
Jaikumar Ganesh6eef14a2010-12-23 12:57:02 -08001951 return new BluetoothSocket(BluetoothSocket.TYPE_RFCOMM, -1, false, false, this, -1,
1952 new ParcelUuid(uuid));
1953 }
1954
1955 /**
Nick Pellybd022f42009-08-14 18:33:38 -07001956 * Construct an insecure RFCOMM socket ready to start an outgoing
1957 * connection.
1958 * Call #connect on the returned #BluetoothSocket to begin the connection.
1959 * The remote device will not be authenticated and communication on this
1960 * socket will not be encrypted.
Nick Pellye6ee3be2009-10-08 23:27:28 +02001961 * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}
1962 *
Jack Hea355e5e2017-08-22 16:06:54 -07001963 * @param port remote port
Nick Pellybd022f42009-08-14 18:33:38 -07001964 * @return An RFCOMM BluetoothSocket
Jack Hea355e5e2017-08-22 16:06:54 -07001965 * @throws IOException On error, for example Bluetooth not available, or insufficient
1966 * permissions.
Nick Pelly45e27042009-08-19 11:00:00 -07001967 * @hide
Nick Pellybd022f42009-08-14 18:33:38 -07001968 */
Mathew Inwood4dc66d32018-08-01 15:07:20 +01001969 @UnsupportedAppUsage
Nick Pellybd022f42009-08-14 18:33:38 -07001970 public BluetoothSocket createInsecureRfcommSocket(int port) throws IOException {
Jack He2992cd02017-08-22 21:21:23 -07001971 if (!isBluetoothEnabled()) {
Nitin Arorad055adb2015-03-02 15:03:51 -08001972 Log.e(TAG, "Bluetooth is not enabled");
1973 throw new IOException();
1974 }
Nick Pelly16fb88a2009-10-07 07:44:03 +02001975 return new BluetoothSocket(BluetoothSocket.TYPE_RFCOMM, -1, false, false, this, port,
1976 null);
Nick Pellybd022f42009-08-14 18:33:38 -07001977 }
1978
1979 /**
1980 * Construct a SCO socket ready to start an outgoing connection.
1981 * Call #connect on the returned #BluetoothSocket to begin the connection.
Nick Pellye6ee3be2009-10-08 23:27:28 +02001982 * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}
1983 *
Nick Pellybd022f42009-08-14 18:33:38 -07001984 * @return a SCO BluetoothSocket
Jack Hea355e5e2017-08-22 16:06:54 -07001985 * @throws IOException on error, for example Bluetooth not available, or insufficient
1986 * permissions.
Nick Pelly45e27042009-08-19 11:00:00 -07001987 * @hide
Nick Pellybd022f42009-08-14 18:33:38 -07001988 */
Mathew Inwood4dc66d32018-08-01 15:07:20 +01001989 @UnsupportedAppUsage
Nick Pellybd022f42009-08-14 18:33:38 -07001990 public BluetoothSocket createScoSocket() throws IOException {
Jack He2992cd02017-08-22 21:21:23 -07001991 if (!isBluetoothEnabled()) {
Nitin Arorad055adb2015-03-02 15:03:51 -08001992 Log.e(TAG, "Bluetooth is not enabled");
1993 throw new IOException();
1994 }
Nick Pelly16fb88a2009-10-07 07:44:03 +02001995 return new BluetoothSocket(BluetoothSocket.TYPE_SCO, -1, true, true, this, -1, null);
Nick Pellybd022f42009-08-14 18:33:38 -07001996 }
1997
1998 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001999 * Check that a pin is valid and convert to byte array.
2000 *
Jake Hambyf51eada2010-09-21 13:39:53 -07002001 * Bluetooth pin's are 1 to 16 bytes of UTF-8 characters.
Jack Hea355e5e2017-08-22 16:06:54 -07002002 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002003 * @param pin pin as java String
Jack Hea355e5e2017-08-22 16:06:54 -07002004 * @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 -07002005 * @hide
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002006 */
Mathew Inwood4dc66d32018-08-01 15:07:20 +01002007 @UnsupportedAppUsage
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002008 public static byte[] convertPinToBytes(String pin) {
2009 if (pin == null) {
2010 return null;
2011 }
2012 byte[] pinBytes;
2013 try {
Jake Hambyf51eada2010-09-21 13:39:53 -07002014 pinBytes = pin.getBytes("UTF-8");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002015 } catch (UnsupportedEncodingException uee) {
Jake Hambyf51eada2010-09-21 13:39:53 -07002016 Log.e(TAG, "UTF-8 not supported?!?"); // this should not happen
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002017 return null;
2018 }
2019 if (pinBytes.length <= 0 || pinBytes.length > 16) {
2020 return null;
2021 }
2022 return pinBytes;
2023 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002024
Matthew Xieddf7e472013-03-01 18:41:02 -08002025 /**
2026 * Connect to GATT Server hosted by this device. Caller acts as GATT client.
2027 * The callback is used to deliver results to Caller, such as connection status as well
2028 * as any further GATT client operations.
2029 * The method returns a BluetoothGatt instance. You can use BluetoothGatt to conduct
2030 * GATT client operations.
Jack Hea355e5e2017-08-22 16:06:54 -07002031 *
Matthew Xieddf7e472013-03-01 18:41:02 -08002032 * @param callback GATT callback handler that will receive asynchronous callbacks.
Jack Hea355e5e2017-08-22 16:06:54 -07002033 * @param autoConnect Whether to directly connect to the remote device (false) or to
2034 * automatically connect as soon as the remote device becomes available (true).
Matthew Xieddf7e472013-03-01 18:41:02 -08002035 * @throws IllegalArgumentException if callback is null
2036 */
Matthew Xie33ec9842013-04-03 00:29:27 -07002037 public BluetoothGatt connectGatt(Context context, boolean autoConnect,
Jack Hea355e5e2017-08-22 16:06:54 -07002038 BluetoothGattCallback callback) {
2039 return (connectGatt(context, autoConnect, callback, TRANSPORT_AUTO));
Ganesh Ganapathi Battab88fa822014-04-18 10:00:40 -07002040 }
2041
2042 /**
2043 * Connect to GATT Server hosted by this device. Caller acts as GATT client.
2044 * The callback is used to deliver results to Caller, such as connection status as well
2045 * as any further GATT client operations.
2046 * The method returns a BluetoothGatt instance. You can use BluetoothGatt to conduct
2047 * GATT client operations.
Jack Hea355e5e2017-08-22 16:06:54 -07002048 *
Ganesh Ganapathi Battab88fa822014-04-18 10:00:40 -07002049 * @param callback GATT callback handler that will receive asynchronous callbacks.
Jack Hea355e5e2017-08-22 16:06:54 -07002050 * @param autoConnect Whether to directly connect to the remote device (false) or to
2051 * automatically connect as soon as the remote device becomes available (true).
2052 * @param transport preferred transport for GATT connections to remote dual-mode devices {@link
2053 * BluetoothDevice#TRANSPORT_AUTO} or {@link BluetoothDevice#TRANSPORT_BREDR} or {@link
2054 * BluetoothDevice#TRANSPORT_LE}
Ganesh Ganapathi Battab88fa822014-04-18 10:00:40 -07002055 * @throws IllegalArgumentException if callback is null
Ganesh Ganapathi Battab88fa822014-04-18 10:00:40 -07002056 */
2057 public BluetoothGatt connectGatt(Context context, boolean autoConnect,
Jack Hea355e5e2017-08-22 16:06:54 -07002058 BluetoothGattCallback callback, int transport) {
2059 return (connectGatt(context, autoConnect, callback, transport, PHY_LE_1M_MASK));
Jakub Pawlowski409cee62017-02-02 08:07:12 -08002060 }
2061
2062 /**
2063 * Connect to GATT Server hosted by this device. Caller acts as GATT client.
2064 * The callback is used to deliver results to Caller, such as connection status as well
2065 * as any further GATT client operations.
2066 * The method returns a BluetoothGatt instance. You can use BluetoothGatt to conduct
2067 * GATT client operations.
Jack Hea355e5e2017-08-22 16:06:54 -07002068 *
Jakub Pawlowski409cee62017-02-02 08:07:12 -08002069 * @param callback GATT callback handler that will receive asynchronous callbacks.
Jack Hea355e5e2017-08-22 16:06:54 -07002070 * @param autoConnect Whether to directly connect to the remote device (false) or to
2071 * automatically connect as soon as the remote device becomes available (true).
2072 * @param transport preferred transport for GATT connections to remote dual-mode devices {@link
2073 * BluetoothDevice#TRANSPORT_AUTO} or {@link BluetoothDevice#TRANSPORT_BREDR} or {@link
2074 * BluetoothDevice#TRANSPORT_LE}
2075 * @param phy preferred PHY for connections to remote LE device. Bitwise OR of any of {@link
2076 * BluetoothDevice#PHY_LE_1M_MASK}, {@link BluetoothDevice#PHY_LE_2M_MASK}, and {@link
2077 * BluetoothDevice#PHY_LE_CODED_MASK}. This option does not take effect if {@code autoConnect}
2078 * is set to true.
Jakub Pawlowskib0f64742017-04-21 03:49:00 -07002079 * @throws NullPointerException if callback is null
Jakub Pawlowski409cee62017-02-02 08:07:12 -08002080 */
2081 public BluetoothGatt connectGatt(Context context, boolean autoConnect,
Jack Hea355e5e2017-08-22 16:06:54 -07002082 BluetoothGattCallback callback, int transport, int phy) {
2083 return connectGatt(context, autoConnect, callback, transport, phy, null);
Jakub Pawlowskib0f64742017-04-21 03:49:00 -07002084 }
2085
2086 /**
2087 * Connect to GATT Server hosted by this device. Caller acts as GATT client.
2088 * The callback is used to deliver results to Caller, such as connection status as well
2089 * as any further GATT client operations.
2090 * The method returns a BluetoothGatt instance. You can use BluetoothGatt to conduct
2091 * GATT client operations.
Jack Hea355e5e2017-08-22 16:06:54 -07002092 *
Jakub Pawlowskib0f64742017-04-21 03:49:00 -07002093 * @param callback GATT callback handler that will receive asynchronous callbacks.
Jack Hea355e5e2017-08-22 16:06:54 -07002094 * @param autoConnect Whether to directly connect to the remote device (false) or to
2095 * automatically connect as soon as the remote device becomes available (true).
2096 * @param transport preferred transport for GATT connections to remote dual-mode devices {@link
2097 * BluetoothDevice#TRANSPORT_AUTO} or {@link BluetoothDevice#TRANSPORT_BREDR} or {@link
2098 * BluetoothDevice#TRANSPORT_LE}
2099 * @param phy preferred PHY for connections to remote LE device. Bitwise OR of any of {@link
2100 * BluetoothDevice#PHY_LE_1M_MASK}, {@link BluetoothDevice#PHY_LE_2M_MASK}, an d{@link
2101 * BluetoothDevice#PHY_LE_CODED_MASK}. This option does not take effect if {@code autoConnect}
2102 * is set to true.
2103 * @param handler The handler to use for the callback. If {@code null}, callbacks will happen on
2104 * an un-specified background thread.
Jakub Pawlowskib0f64742017-04-21 03:49:00 -07002105 * @throws NullPointerException if callback is null
2106 */
2107 public BluetoothGatt connectGatt(Context context, boolean autoConnect,
Jack Hea355e5e2017-08-22 16:06:54 -07002108 BluetoothGattCallback callback, int transport, int phy,
2109 Handler handler) {
Jack He13f52c82017-07-05 14:55:35 -07002110 return connectGatt(context, autoConnect, callback, transport, false, phy, handler);
2111 }
2112
2113 /**
2114 * Connect to GATT Server hosted by this device. Caller acts as GATT client.
2115 * The callback is used to deliver results to Caller, such as connection status as well
2116 * as any further GATT client operations.
2117 * The method returns a BluetoothGatt instance. You can use BluetoothGatt to conduct
2118 * GATT client operations.
Jack Hea355e5e2017-08-22 16:06:54 -07002119 *
Jack He13f52c82017-07-05 14:55:35 -07002120 * @param callback GATT callback handler that will receive asynchronous callbacks.
Jack Hea355e5e2017-08-22 16:06:54 -07002121 * @param autoConnect Whether to directly connect to the remote device (false) or to
2122 * automatically connect as soon as the remote device becomes available (true).
2123 * @param transport preferred transport for GATT connections to remote dual-mode devices {@link
2124 * BluetoothDevice#TRANSPORT_AUTO} or {@link BluetoothDevice#TRANSPORT_BREDR} or {@link
2125 * BluetoothDevice#TRANSPORT_LE}
Jack He13f52c82017-07-05 14:55:35 -07002126 * @param opportunistic Whether this GATT client is opportunistic. An opportunistic GATT client
Jack Hea355e5e2017-08-22 16:06:54 -07002127 * does not hold a GATT connection. It automatically disconnects when no other GATT connections
2128 * are active for the remote device.
2129 * @param phy preferred PHY for connections to remote LE device. Bitwise OR of any of {@link
2130 * BluetoothDevice#PHY_LE_1M_MASK}, {@link BluetoothDevice#PHY_LE_2M_MASK}, an d{@link
2131 * BluetoothDevice#PHY_LE_CODED_MASK}. This option does not take effect if {@code autoConnect}
2132 * is set to true.
2133 * @param handler The handler to use for the callback. If {@code null}, callbacks will happen on
2134 * an un-specified background thread.
Jack He13f52c82017-07-05 14:55:35 -07002135 * @return A BluetoothGatt instance. You can use BluetoothGatt to conduct GATT client
Jack Hea355e5e2017-08-22 16:06:54 -07002136 * operations.
Jack He13f52c82017-07-05 14:55:35 -07002137 * @hide
2138 */
Mathew Inwood4dc66d32018-08-01 15:07:20 +01002139 @UnsupportedAppUsage
Jack He13f52c82017-07-05 14:55:35 -07002140 public BluetoothGatt connectGatt(Context context, boolean autoConnect,
Jack Hea355e5e2017-08-22 16:06:54 -07002141 BluetoothGattCallback callback, int transport,
2142 boolean opportunistic, int phy, Handler handler) {
2143 if (callback == null) {
Jakub Pawlowskib0f64742017-04-21 03:49:00 -07002144 throw new NullPointerException("callback is null");
Jack Hea355e5e2017-08-22 16:06:54 -07002145 }
Jakub Pawlowskib0f64742017-04-21 03:49:00 -07002146
Matthew Xieddf7e472013-03-01 18:41:02 -08002147 // TODO(Bluetooth) check whether platform support BLE
2148 // Do the check here or in GattServer?
2149 BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
2150 IBluetoothManager managerService = adapter.getBluetoothManager();
2151 try {
2152 IBluetoothGatt iGatt = managerService.getBluetoothGatt();
Matthew Xie32ab77b2013-05-08 19:26:57 -07002153 if (iGatt == null) {
2154 // BLE is not supported
2155 return null;
2156 }
Jack He13f52c82017-07-05 14:55:35 -07002157 BluetoothGatt gatt = new BluetoothGatt(iGatt, this, transport, opportunistic, phy);
Jakub Pawlowskib0f64742017-04-21 03:49:00 -07002158 gatt.connect(autoConnect, callback, handler);
Matthew Xieddf7e472013-03-01 18:41:02 -08002159 return gatt;
Jack Hea355e5e2017-08-22 16:06:54 -07002160 } catch (RemoteException e) {
2161 Log.e(TAG, "", e);
2162 }
Matthew Xieddf7e472013-03-01 18:41:02 -08002163 return null;
2164 }
Stanley Tnge48468d2017-11-22 16:04:40 -08002165
2166 /**
2167 * Create a Bluetooth L2CAP Connection-oriented Channel (CoC) {@link BluetoothSocket} that can
2168 * be used to start a secure outgoing connection to the remote device with the same dynamic
Stanley Tng1bff4ba2018-06-29 14:05:04 -07002169 * protocol/service multiplexer (PSM) value. The supported Bluetooth transport is LE only.
2170 * <p>This is designed to be used with {@link BluetoothAdapter#listenUsingL2capChannel()} for
Stanley Tnge48468d2017-11-22 16:04:40 -08002171 * peer-peer Bluetooth applications.
2172 * <p>Use {@link BluetoothSocket#connect} to initiate the outgoing connection.
2173 * <p>Application using this API is responsible for obtaining PSM value from remote device.
2174 * <p>The remote device will be authenticated and communication on this socket will be
2175 * encrypted.
2176 * <p> Use this socket if an authenticated socket link is possible. Authentication refers
Nan Zhang55581d92018-10-11 17:54:36 -07002177 * to the authentication of the link key to prevent man-in-the-middle type of attacks.
Stanley Tnge48468d2017-11-22 16:04:40 -08002178 *
Stanley Tnge48468d2017-11-22 16:04:40 -08002179 * @param psm dynamic PSM value from remote device
2180 * @return a CoC #BluetoothSocket ready for an outgoing connection
2181 * @throws IOException on error, for example Bluetooth not available, or insufficient
2182 * permissions
Stanley Tnge48468d2017-11-22 16:04:40 -08002183 */
2184 @RequiresPermission(Manifest.permission.BLUETOOTH)
Stanley Tng1bff4ba2018-06-29 14:05:04 -07002185 public BluetoothSocket createL2capChannel(int psm) throws IOException {
Stanley Tnge48468d2017-11-22 16:04:40 -08002186 if (!isBluetoothEnabled()) {
Stanley Tng1bff4ba2018-06-29 14:05:04 -07002187 Log.e(TAG, "createL2capChannel: Bluetooth is not enabled");
Stanley Tnge48468d2017-11-22 16:04:40 -08002188 throw new IOException();
2189 }
Stanley Tng1bff4ba2018-06-29 14:05:04 -07002190 if (DBG) Log.d(TAG, "createL2capChannel: psm=" + psm);
Stanley Tnge48468d2017-11-22 16:04:40 -08002191 return new BluetoothSocket(BluetoothSocket.TYPE_L2CAP_LE, -1, true, true, this, psm,
2192 null);
2193 }
2194
2195 /**
Stanley Tng1bff4ba2018-06-29 14:05:04 -07002196 * TODO: Remove this hidden method once all the SL4A and other tests are updated to use the new
2197 * API name, createL2capChannel.
2198 * @hide
2199 */
2200 @RequiresPermission(Manifest.permission.BLUETOOTH)
2201 public BluetoothSocket createL2capCocSocket(int transport, int psm) throws IOException {
2202 Log.e(TAG, "createL2capCocSocket: PLEASE USE THE OFFICIAL API, createL2capChannel");
2203 return createL2capChannel(psm);
2204 }
2205
2206 /**
Stanley Tnge48468d2017-11-22 16:04:40 -08002207 * Create a Bluetooth L2CAP Connection-oriented Channel (CoC) {@link BluetoothSocket} that can
2208 * be used to start a secure outgoing connection to the remote device with the same dynamic
Stanley Tng1bff4ba2018-06-29 14:05:04 -07002209 * protocol/service multiplexer (PSM) value. The supported Bluetooth transport is LE only.
2210 * <p>This is designed to be used with {@link
2211 * BluetoothAdapter#listenUsingInsecureL2capChannel()} for peer-peer Bluetooth applications.
Stanley Tnge48468d2017-11-22 16:04:40 -08002212 * <p>Use {@link BluetoothSocket#connect} to initiate the outgoing connection.
2213 * <p>Application using this API is responsible for obtaining PSM value from remote device.
2214 * <p> The communication channel may not have an authenticated link key, i.e. it may be subject
Stanley Tng1bff4ba2018-06-29 14:05:04 -07002215 * to man-in-the-middle attacks. Use {@link #createL2capChannel(int)} if an encrypted and
Stanley Tnge48468d2017-11-22 16:04:40 -08002216 * authenticated communication channel is possible.
2217 *
Stanley Tnge48468d2017-11-22 16:04:40 -08002218 * @param psm dynamic PSM value from remote device
2219 * @return a CoC #BluetoothSocket ready for an outgoing connection
2220 * @throws IOException on error, for example Bluetooth not available, or insufficient
2221 * permissions
Stanley Tng1bff4ba2018-06-29 14:05:04 -07002222 */
2223 @RequiresPermission(Manifest.permission.BLUETOOTH)
2224 public BluetoothSocket createInsecureL2capChannel(int psm) throws IOException {
2225 if (!isBluetoothEnabled()) {
2226 Log.e(TAG, "createInsecureL2capChannel: Bluetooth is not enabled");
2227 throw new IOException();
2228 }
2229 if (DBG) {
2230 Log.d(TAG, "createInsecureL2capChannel: psm=" + psm);
2231 }
2232 return new BluetoothSocket(BluetoothSocket.TYPE_L2CAP_LE, -1, false, false, this, psm,
2233 null);
2234 }
2235
2236 /**
2237 * TODO: Remove this hidden method once all the SL4A and other tests are updated to use the new
2238 * API name, createInsecureL2capChannel.
Stanley Tnge48468d2017-11-22 16:04:40 -08002239 * @hide
2240 */
2241 @RequiresPermission(Manifest.permission.BLUETOOTH)
2242 public BluetoothSocket createInsecureL2capCocSocket(int transport, int psm) throws IOException {
Stanley Tng1bff4ba2018-06-29 14:05:04 -07002243 Log.e(TAG, "createL2capCocSocket: PLEASE USE THE OFFICIAL API, createInsecureL2capChannel");
2244 return createInsecureL2capChannel(psm);
Stanley Tnge48468d2017-11-22 16:04:40 -08002245 }
Ugo Yu4a33b882019-01-08 09:00:09 +08002246
2247 /**
2248 * Set a keyed metadata of this {@link BluetoothDevice} to a
2249 * {@link String} value.
2250 * Only bonded devices's metadata will be persisted across Bluetooth
2251 * restart.
2252 * Metadata will be removed when the device's bond state is moved to
2253 * {@link #BOND_NONE}.
2254 *
2255 * @param key must be within the list of BluetoothDevice.METADATA_*
2256 * @param value the string data to set for key. Must be less than
2257 * {@link BluetoothAdapter#METADATA_MAX_LENGTH} characters in length
2258 * @return true on success, false on error
2259 * @hide
2260 */
2261 @SystemApi
2262 @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
2263 public boolean setMetadata(int key, String value) {
2264 final IBluetooth service = sService;
2265 if (service == null) {
2266 Log.e(TAG, "Bluetooth is not enabled. Cannot set metadata");
2267 return false;
2268 }
2269 if (value.length() > METADATA_MAX_LENGTH) {
2270 throw new IllegalArgumentException("value length is " + value.length()
2271 + ", should not over " + METADATA_MAX_LENGTH);
2272 }
2273 try {
2274 return service.setMetadata(this, key, value);
2275 } catch (RemoteException e) {
2276 Log.e(TAG, "setMetadata fail", e);
2277 return false;
2278 }
2279 }
2280
2281 /**
2282 * Get a keyed metadata for this {@link BluetoothDevice} as {@link String}
2283 *
2284 * @param key must be within the list of BluetoothDevice.METADATA_*
2285 * @return Metadata of the key as string, null on error or not found
2286 * @hide
2287 */
2288 @SystemApi
2289 @RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
2290 public String getMetadata(int key) {
2291 final IBluetooth service = sService;
2292 if (service == null) {
2293 Log.e(TAG, "Bluetooth is not enabled. Cannot get metadata");
2294 return null;
2295 }
2296 try {
2297 return service.getMetadata(this, key);
2298 } catch (RemoteException e) {
2299 Log.e(TAG, "getMetadata fail", e);
2300 return null;
2301 }
2302 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002303}