blob: d789a944f5f2641eec630fe6c887b3b4b4d2558a [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
Nick Pelly005b2282009-09-10 10:21:56 -070019import android.annotation.SdkConstant;
20import android.annotation.SdkConstant.SdkConstantType;
Matthew Xieddf7e472013-03-01 18:41:02 -080021import android.content.Context;
Nick Pellybd022f42009-08-14 18:33:38 -070022import android.os.IBinder;
23import android.os.Parcel;
24import android.os.Parcelable;
Nick Pellyaef439e2009-09-28 12:33:17 -070025import android.os.ParcelUuid;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080026import android.os.RemoteException;
Nick Pellybd022f42009-08-14 18:33:38 -070027import android.os.ServiceManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080028import android.util.Log;
29
Nick Pellybd022f42009-08-14 18:33:38 -070030import java.io.IOException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080031import java.io.UnsupportedEncodingException;
Jaikumar Ganesh1caa6d12009-09-18 11:32:54 -070032import java.util.UUID;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080033
34/**
Scott Main9fab0ae2009-11-03 18:17:59 -080035 * Represents a remote Bluetooth device. A {@link BluetoothDevice} lets you
Jake Hambyf51eada2010-09-21 13:39:53 -070036 * create a connection with the respective device or query information about
Scott Main9fab0ae2009-11-03 18:17:59 -080037 * it, such as the name, address, class, and bonding state.
Nick Pelly45e27042009-08-19 11:00:00 -070038 *
39 * <p>This class is really just a thin wrapper for a Bluetooth hardware
40 * address. Objects of this class are immutable. Operations on this class
41 * are performed on the remote Bluetooth hardware address, using the
42 * {@link BluetoothAdapter} that was used to create this {@link
43 * BluetoothDevice}.
Scott Main9fab0ae2009-11-03 18:17:59 -080044 *
45 * <p>To get a {@link BluetoothDevice}, use
46 * {@link BluetoothAdapter#getRemoteDevice(String)
47 * BluetoothAdapter.getRemoteDevice(String)} to create one representing a device
48 * of a known MAC address (which you can get through device discovery with
49 * {@link BluetoothAdapter}) or get one from the set of bonded devices
50 * returned by {@link BluetoothAdapter#getBondedDevices()
51 * BluetoothAdapter.getBondedDevices()}. You can then open a
Jake Hambyf51eada2010-09-21 13:39:53 -070052 * {@link BluetoothSocket} for communication with the remote device, using
Scott Main9fab0ae2009-11-03 18:17:59 -080053 * {@link #createRfcommSocketToServiceRecord(UUID)}.
54 *
55 * <p class="note"><strong>Note:</strong>
56 * Requires the {@link android.Manifest.permission#BLUETOOTH} permission.
57 *
Joe Fernandez3aef8e1d2011-12-20 10:38:34 -080058 * <div class="special reference">
59 * <h3>Developer Guides</h3>
60 * <p>For more information about using Bluetooth, read the
61 * <a href="{@docRoot}guide/topics/wireless/bluetooth.html">Bluetooth</a> developer guide.</p>
62 * </div>
63 *
Scott Main9fab0ae2009-11-03 18:17:59 -080064 * {@see BluetoothAdapter}
65 * {@see BluetoothSocket}
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080066 */
Nick Pellybd022f42009-08-14 18:33:38 -070067public final class BluetoothDevice implements Parcelable {
68 private static final String TAG = "BluetoothDevice";
Ravi Nagarajan70772722012-04-23 04:06:49 -070069 private static final boolean DBG = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080070
Nick Pellyb24e11b2009-09-08 17:40:43 -070071 /**
72 * Sentinel error value for this class. Guaranteed to not equal any other
73 * integer constant in this class. Provided as a convenience for functions
74 * that require a sentinel error value, for example:
Nick Pelly005b2282009-09-10 10:21:56 -070075 * <p><code>Intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE,
76 * BluetoothDevice.ERROR)</code>
Nick Pellyb24e11b2009-09-08 17:40:43 -070077 */
Nick Pelly005b2282009-09-10 10:21:56 -070078 public static final int ERROR = Integer.MIN_VALUE;
Nick Pellyb24e11b2009-09-08 17:40:43 -070079
Nick Pelly005b2282009-09-10 10:21:56 -070080 /**
81 * Broadcast Action: Remote device discovered.
82 * <p>Sent when a remote device is found during discovery.
83 * <p>Always contains the extra fields {@link #EXTRA_DEVICE} and {@link
84 * #EXTRA_CLASS}. Can contain the extra fields {@link #EXTRA_NAME} and/or
85 * {@link #EXTRA_RSSI} if they are available.
86 * <p>Requires {@link android.Manifest.permission#BLUETOOTH} to receive.
87 */
88 // TODO: Change API to not broadcast RSSI if not available (incoming connection)
89 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
90 public static final String ACTION_FOUND =
91 "android.bluetooth.device.action.FOUND";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080092
Nick Pelly005b2282009-09-10 10:21:56 -070093 /**
94 * Broadcast Action: Remote device disappeared.
95 * <p>Sent when a remote device that was found in the last discovery is not
96 * found in the current discovery.
97 * <p>Always contains the extra field {@link #EXTRA_DEVICE}.
98 * <p>Requires {@link android.Manifest.permission#BLUETOOTH} to receive.
99 * @hide
100 */
101 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
102 public static final String ACTION_DISAPPEARED =
103 "android.bluetooth.device.action.DISAPPEARED";
104
105 /**
106 * Broadcast Action: Bluetooth class of a remote device has changed.
107 * <p>Always contains the extra fields {@link #EXTRA_DEVICE} and {@link
108 * #EXTRA_CLASS}.
109 * <p>Requires {@link android.Manifest.permission#BLUETOOTH} to receive.
Matthew Xieb30f91e2013-05-29 10:19:06 -0700110 * {@see BluetoothClass}
Nick Pelly005b2282009-09-10 10:21:56 -0700111 */
112 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
113 public static final String ACTION_CLASS_CHANGED =
114 "android.bluetooth.device.action.CLASS_CHANGED";
115
116 /**
117 * Broadcast Action: Indicates a low level (ACL) connection has been
118 * established with a remote device.
119 * <p>Always contains the extra field {@link #EXTRA_DEVICE}.
120 * <p>ACL connections are managed automatically by the Android Bluetooth
121 * stack.
122 * <p>Requires {@link android.Manifest.permission#BLUETOOTH} to receive.
123 */
124 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
125 public static final String ACTION_ACL_CONNECTED =
126 "android.bluetooth.device.action.ACL_CONNECTED";
127
128 /**
129 * Broadcast Action: Indicates that a low level (ACL) disconnection has
130 * been requested for a remote device, and it will soon be disconnected.
131 * <p>This is useful for graceful disconnection. Applications should use
132 * this intent as a hint to immediately terminate higher level connections
133 * (RFCOMM, L2CAP, or profile connections) to the remote device.
134 * <p>Always contains the extra field {@link #EXTRA_DEVICE}.
135 * <p>Requires {@link android.Manifest.permission#BLUETOOTH} to receive.
136 */
137 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
138 public static final String ACTION_ACL_DISCONNECT_REQUESTED =
139 "android.bluetooth.device.action.ACL_DISCONNECT_REQUESTED";
140
141 /**
142 * Broadcast Action: Indicates a low level (ACL) disconnection from a
143 * remote device.
144 * <p>Always contains the extra field {@link #EXTRA_DEVICE}.
145 * <p>ACL connections are managed automatically by the Android Bluetooth
146 * stack.
147 * <p>Requires {@link android.Manifest.permission#BLUETOOTH} to receive.
148 */
149 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
150 public static final String ACTION_ACL_DISCONNECTED =
151 "android.bluetooth.device.action.ACL_DISCONNECTED";
152
153 /**
154 * Broadcast Action: Indicates the friendly name of a remote device has
155 * been retrieved for the first time, or changed since the last retrieval.
156 * <p>Always contains the extra fields {@link #EXTRA_DEVICE} and {@link
157 * #EXTRA_NAME}.
158 * <p>Requires {@link android.Manifest.permission#BLUETOOTH} to receive.
159 */
160 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
161 public static final String ACTION_NAME_CHANGED =
162 "android.bluetooth.device.action.NAME_CHANGED";
163
164 /**
Jeff Brown5bbd4b42012-04-20 19:28:00 -0700165 * Broadcast Action: Indicates the alias of a remote device has been
166 * changed.
167 * <p>Always contains the extra field {@link #EXTRA_DEVICE}.
168 * <p>Requires {@link android.Manifest.permission#BLUETOOTH} to receive.
169 *
170 * @hide
171 */
172 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
173 public static final String ACTION_ALIAS_CHANGED =
174 "android.bluetooth.device.action.ALIAS_CHANGED";
175
176 /**
Nick Pelly005b2282009-09-10 10:21:56 -0700177 * Broadcast Action: Indicates a change in the bond state of a remote
178 * device. For example, if a device is bonded (paired).
179 * <p>Always contains the extra fields {@link #EXTRA_DEVICE}, {@link
180 * #EXTRA_BOND_STATE} and {@link #EXTRA_PREVIOUS_BOND_STATE}.
181 * <p>Requires {@link android.Manifest.permission#BLUETOOTH} to receive.
182 */
183 // Note: When EXTRA_BOND_STATE is BOND_NONE then this will also
184 // contain a hidden extra field EXTRA_REASON with the result code.
185 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
186 public static final String ACTION_BOND_STATE_CHANGED =
187 "android.bluetooth.device.action.BOND_STATE_CHANGED";
188
189 /**
190 * Used as a Parcelable {@link BluetoothDevice} extra field in every intent
191 * broadcast by this class. It contains the {@link BluetoothDevice} that
192 * the intent applies to.
193 */
194 public static final String EXTRA_DEVICE = "android.bluetooth.device.extra.DEVICE";
195
196 /**
197 * Used as a String extra field in {@link #ACTION_NAME_CHANGED} and {@link
198 * #ACTION_FOUND} intents. It contains the friendly Bluetooth name.
199 */
200 public static final String EXTRA_NAME = "android.bluetooth.device.extra.NAME";
201
202 /**
203 * Used as an optional short extra field in {@link #ACTION_FOUND} intents.
204 * Contains the RSSI value of the remote device as reported by the
205 * Bluetooth hardware.
206 */
207 public static final String EXTRA_RSSI = "android.bluetooth.device.extra.RSSI";
208
209 /**
Ken Wakasaf76a50c2012-03-09 19:56:35 +0900210 * Used as a Parcelable {@link BluetoothClass} extra field in {@link
Nick Pelly005b2282009-09-10 10:21:56 -0700211 * #ACTION_FOUND} and {@link #ACTION_CLASS_CHANGED} intents.
212 */
213 public static final String EXTRA_CLASS = "android.bluetooth.device.extra.CLASS";
214
215 /**
216 * Used as an int extra field in {@link #ACTION_BOND_STATE_CHANGED} intents.
217 * Contains the bond state of the remote device.
218 * <p>Possible values are:
219 * {@link #BOND_NONE},
220 * {@link #BOND_BONDING},
221 * {@link #BOND_BONDED}.
Matthew Xie091fc2b2013-09-23 23:23:13 -0700222 */
Nick Pelly005b2282009-09-10 10:21:56 -0700223 public static final String EXTRA_BOND_STATE = "android.bluetooth.device.extra.BOND_STATE";
224 /**
225 * Used as an int extra field in {@link #ACTION_BOND_STATE_CHANGED} intents.
226 * Contains the previous bond state of the remote device.
227 * <p>Possible values are:
228 * {@link #BOND_NONE},
229 * {@link #BOND_BONDING},
230 * {@link #BOND_BONDED}.
Matthew Xie091fc2b2013-09-23 23:23:13 -0700231 */
Nick Pelly005b2282009-09-10 10:21:56 -0700232 public static final String EXTRA_PREVIOUS_BOND_STATE =
233 "android.bluetooth.device.extra.PREVIOUS_BOND_STATE";
234 /**
235 * Indicates the remote device is not bonded (paired).
236 * <p>There is no shared link key with the remote device, so communication
237 * (if it is allowed at all) will be unauthenticated and unencrypted.
238 */
239 public static final int BOND_NONE = 10;
240 /**
241 * Indicates bonding (pairing) is in progress with the remote device.
242 */
243 public static final int BOND_BONDING = 11;
244 /**
245 * Indicates the remote device is bonded (paired).
246 * <p>A shared link keys exists locally for the remote device, so
247 * communication can be authenticated and encrypted.
248 * <p><i>Being bonded (paired) with a remote device does not necessarily
Jake Hambyf51eada2010-09-21 13:39:53 -0700249 * mean the device is currently connected. It just means that the pending
250 * procedure was completed at some earlier time, and the link key is still
Nick Pelly005b2282009-09-10 10:21:56 -0700251 * stored locally, ready to use on the next connection.
252 * </i>
253 */
254 public static final int BOND_BONDED = 12;
255
Matthew Xie091fc2b2013-09-23 23:23:13 -0700256 /**
257 * Used as an int extra field in {@link #ACTION_PAIRING_REQUEST}
258 * intents for unbond reason.
259 * @hide
260 */
Nick Pelly005b2282009-09-10 10:21:56 -0700261 public static final String EXTRA_REASON = "android.bluetooth.device.extra.REASON";
Matthew Xie091fc2b2013-09-23 23:23:13 -0700262
263 /**
264 * Used as an int extra field in {@link #ACTION_PAIRING_REQUEST}
265 * intents to indicate pairing method used. Possible values are:
266 * {@link #PAIRING_VARIANT_PIN},
267 * {@link #PAIRING_VARIANT_PASSKEY_CONFIRMATION},
268 */
Nick Pelly005b2282009-09-10 10:21:56 -0700269 public static final String EXTRA_PAIRING_VARIANT =
270 "android.bluetooth.device.extra.PAIRING_VARIANT";
Matthew Xie091fc2b2013-09-23 23:23:13 -0700271
272 /**
273 * Used as an int extra field in {@link #ACTION_PAIRING_REQUEST}
274 * intents as the value of passkey.
275 */
Jaikumar Ganeshc88b0c62011-01-05 13:49:00 -0800276 public static final String EXTRA_PAIRING_KEY = "android.bluetooth.device.extra.PAIRING_KEY";
Nick Pelly005b2282009-09-10 10:21:56 -0700277
278 /**
Matthew Xie33ec9842013-04-03 00:29:27 -0700279 * Bluetooth device type, Unknown
280 */
281 public static final int DEVICE_TYPE_UNKNOWN = 0;
282
283 /**
284 * Bluetooth device type, Classic - BR/EDR devices
285 */
286 public static final int DEVICE_TYPE_CLASSIC = 1;
287
288 /**
289 * Bluetooth device type, Low Energy - LE-only
290 */
291 public static final int DEVICE_TYPE_LE = 2;
292
293 /**
294 * Bluetooth device type, Dual Mode - BR/EDR/LE
295 */
296 public static final int DEVICE_TYPE_DUAL = 3;
297
298 /**
Jaikumar Ganesh1caa6d12009-09-18 11:32:54 -0700299 * Broadcast Action: This intent is used to broadcast the {@link UUID}
Nick Pellyaef439e2009-09-28 12:33:17 -0700300 * wrapped as a {@link android.os.ParcelUuid} of the remote device after it
301 * has been fetched. This intent is sent only when the UUIDs of the remote
302 * device are requested to be fetched using Service Discovery Protocol
Jaikumar Ganesh1caa6d12009-09-18 11:32:54 -0700303 * <p> Always contains the extra field {@link #EXTRA_DEVICE}
Matthew Xiead232102011-11-08 10:58:12 -0800304 * <p> Always contains the extra field {@link #EXTRA_UUID}
Jaikumar Ganesh1caa6d12009-09-18 11:32:54 -0700305 * <p>Requires {@link android.Manifest.permission#BLUETOOTH} to receive.
Jaikumar Ganesh1caa6d12009-09-18 11:32:54 -0700306 */
307 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
308 public static final String ACTION_UUID =
Matthew Xiead232102011-11-08 10:58:12 -0800309 "android.bluetooth.device.action.UUID";
Jaikumar Ganesh1caa6d12009-09-18 11:32:54 -0700310
311 /**
Nick Pelly005b2282009-09-10 10:21:56 -0700312 * Broadcast Action: Indicates a failure to retrieve the name of a remote
313 * device.
314 * <p>Always contains the extra field {@link #EXTRA_DEVICE}.
315 * <p>Requires {@link android.Manifest.permission#BLUETOOTH} to receive.
316 * @hide
317 */
318 //TODO: is this actually useful?
319 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
320 public static final String ACTION_NAME_FAILED =
321 "android.bluetooth.device.action.NAME_FAILED";
322
Matthew Xie091fc2b2013-09-23 23:23:13 -0700323 /**
324 * Broadcast Action: This intent is used to broadcast PAIRING REQUEST
Matthew Xieac2c6c32013-10-21 14:56:33 -0700325 * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN} to
Edward Jee430e3612013-10-07 18:12:15 -0700326 * receive.
Matthew Xie091fc2b2013-09-23 23:23:13 -0700327 */
Nick Pelly005b2282009-09-10 10:21:56 -0700328 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
329 public static final String ACTION_PAIRING_REQUEST =
330 "android.bluetooth.device.action.PAIRING_REQUEST";
331 /** @hide */
332 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
333 public static final String ACTION_PAIRING_CANCEL =
334 "android.bluetooth.device.action.PAIRING_CANCEL";
Yue Lixina4433af2009-07-09 16:56:43 +0800335
Matthew Xiea0c68032011-06-25 21:47:07 -0700336 /** @hide */
337 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
338 public static final String ACTION_CONNECTION_ACCESS_REQUEST =
339 "android.bluetooth.device.action.CONNECTION_ACCESS_REQUEST";
340
341 /** @hide */
342 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
343 public static final String ACTION_CONNECTION_ACCESS_REPLY =
344 "android.bluetooth.device.action.CONNECTION_ACCESS_REPLY";
345
346 /** @hide */
347 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
348 public static final String ACTION_CONNECTION_ACCESS_CANCEL =
349 "android.bluetooth.device.action.CONNECTION_ACCESS_CANCEL";
350
351 /**
352 * Used as an extra field in {@link #ACTION_CONNECTION_ACCESS_REQUEST} intent.
353 * @hide
354 */
355 public static final String EXTRA_ACCESS_REQUEST_TYPE =
356 "android.bluetooth.device.extra.ACCESS_REQUEST_TYPE";
357
358 /**@hide*/
359 public static final int REQUEST_TYPE_PROFILE_CONNECTION = 1;
360
361 /**@hide*/
362 public static final int REQUEST_TYPE_PHONEBOOK_ACCESS = 2;
363
Matthew Xiefe3807a2013-07-18 17:31:50 -0700364 /**@hide*/
365 public static final int REQUEST_TYPE_MESSAGE_ACCESS = 3;
366
Matthew Xiea0c68032011-06-25 21:47:07 -0700367 /**
368 * Used as an extra field in {@link #ACTION_CONNECTION_ACCESS_REQUEST} intents,
369 * Contains package name to return reply intent to.
370 * @hide
371 */
372 public static final String EXTRA_PACKAGE_NAME = "android.bluetooth.device.extra.PACKAGE_NAME";
373
374 /**
375 * Used as an extra field in {@link #ACTION_CONNECTION_ACCESS_REQUEST} intents,
376 * Contains class name to return reply intent to.
377 * @hide
378 */
379 public static final String EXTRA_CLASS_NAME = "android.bluetooth.device.extra.CLASS_NAME";
380
381 /**
382 * Used as an extra field in {@link #ACTION_CONNECTION_ACCESS_REPLY} intent.
383 * @hide
384 */
385 public static final String EXTRA_CONNECTION_ACCESS_RESULT =
386 "android.bluetooth.device.extra.CONNECTION_ACCESS_RESULT";
387
388 /**@hide*/
389 public static final int CONNECTION_ACCESS_YES = 1;
390
391 /**@hide*/
392 public static final int CONNECTION_ACCESS_NO = 2;
393
394 /**
395 * Used as an extra field in {@link #ACTION_CONNECTION_ACCESS_REPLY} intents,
396 * Contains boolean to indicate if the allowed response is once-for-all so that
397 * next request will be granted without asking user again.
398 * @hide
399 */
400 public static final String EXTRA_ALWAYS_ALLOWED =
401 "android.bluetooth.device.extra.ALWAYS_ALLOWED";
402
Jaikumar Ganeshc88b0c62011-01-05 13:49:00 -0800403 /**
404 * A bond attempt succeeded
405 * @hide
406 */
Nick Pellyb24e11b2009-09-08 17:40:43 -0700407 public static final int BOND_SUCCESS = 0;
Jaikumar Ganeshc88b0c62011-01-05 13:49:00 -0800408
409 /**
410 * A bond attempt failed because pins did not match, or remote device did
Jaikumar Ganesh32d85712009-09-10 22:00:05 -0700411 * not respond to pin request in time
Jaikumar Ganeshc88b0c62011-01-05 13:49:00 -0800412 * @hide
413 */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800414 public static final int UNBOND_REASON_AUTH_FAILED = 1;
Jaikumar Ganeshc88b0c62011-01-05 13:49:00 -0800415
416 /**
417 * A bond attempt failed because the other side explicitly rejected
Nick Pelly45e27042009-08-19 11:00:00 -0700418 * bonding
Jaikumar Ganeshc88b0c62011-01-05 13:49:00 -0800419 * @hide
420 */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800421 public static final int UNBOND_REASON_AUTH_REJECTED = 2;
Jaikumar Ganeshc88b0c62011-01-05 13:49:00 -0800422
423 /**
424 * A bond attempt failed because we canceled the bonding process
425 * @hide
426 */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800427 public static final int UNBOND_REASON_AUTH_CANCELED = 3;
Jaikumar Ganeshc88b0c62011-01-05 13:49:00 -0800428
429 /**
430 * A bond attempt failed because we could not contact the remote device
431 * @hide
432 */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800433 public static final int UNBOND_REASON_REMOTE_DEVICE_DOWN = 4;
Jaikumar Ganeshc88b0c62011-01-05 13:49:00 -0800434
435 /**
436 * A bond attempt failed because a discovery is in progress
437 * @hide
438 */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800439 public static final int UNBOND_REASON_DISCOVERY_IN_PROGRESS = 5;
Jaikumar Ganeshc88b0c62011-01-05 13:49:00 -0800440
441 /**
442 * A bond attempt failed because of authentication timeout
443 * @hide
444 */
Jaikumar Ganesh32d85712009-09-10 22:00:05 -0700445 public static final int UNBOND_REASON_AUTH_TIMEOUT = 6;
Jaikumar Ganeshc88b0c62011-01-05 13:49:00 -0800446
447 /**
448 * A bond attempt failed because of repeated attempts
449 * @hide
450 */
Jaikumar Ganesh32d85712009-09-10 22:00:05 -0700451 public static final int UNBOND_REASON_REPEATED_ATTEMPTS = 7;
Jaikumar Ganeshc88b0c62011-01-05 13:49:00 -0800452
453 /**
454 * A bond attempt failed because we received an Authentication Cancel
455 * by remote end
456 * @hide
457 */
Jaikumar Ganeshe5d93b72009-10-08 02:27:52 -0700458 public static final int UNBOND_REASON_REMOTE_AUTH_CANCELED = 8;
Jaikumar Ganeshc88b0c62011-01-05 13:49:00 -0800459
460 /**
461 * An existing bond was explicitly revoked
462 * @hide
463 */
Jaikumar Ganeshe5d93b72009-10-08 02:27:52 -0700464 public static final int UNBOND_REASON_REMOVED = 9;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800465
Jaikumar Ganeshc88b0c62011-01-05 13:49:00 -0800466 /**
Matthew Xie091fc2b2013-09-23 23:23:13 -0700467 * The user will be prompted to enter a pin or
Matthew Xieac2c6c32013-10-21 14:56:33 -0700468 * an app will enter a pin for user.
Jaikumar Ganeshc88b0c62011-01-05 13:49:00 -0800469 */
Jaikumar Ganeshb0eca412009-07-16 18:26:28 -0700470 public static final int PAIRING_VARIANT_PIN = 0;
Jaikumar Ganeshc88b0c62011-01-05 13:49:00 -0800471
472 /**
473 * The user will be prompted to enter a passkey
474 * @hide
475 */
Jaikumar Ganeshb0eca412009-07-16 18:26:28 -0700476 public static final int PAIRING_VARIANT_PASSKEY = 1;
Jaikumar Ganeshc88b0c62011-01-05 13:49:00 -0800477
478 /**
Matthew Xie091fc2b2013-09-23 23:23:13 -0700479 * The user will be prompted to confirm the passkey displayed on the screen or
Matthew Xieac2c6c32013-10-21 14:56:33 -0700480 * an app will confirm the passkey for the user.
Jaikumar Ganeshc88b0c62011-01-05 13:49:00 -0800481 */
Jaikumar Ganesh32d85712009-09-10 22:00:05 -0700482 public static final int PAIRING_VARIANT_PASSKEY_CONFIRMATION = 2;
Jaikumar Ganeshc88b0c62011-01-05 13:49:00 -0800483
484 /**
485 * The user will be prompted to accept or deny the incoming pairing request
486 * @hide
487 */
Jaikumar Ganesh32d85712009-09-10 22:00:05 -0700488 public static final int PAIRING_VARIANT_CONSENT = 3;
Jaikumar Ganeshc88b0c62011-01-05 13:49:00 -0800489
490 /**
491 * The user will be prompted to enter the passkey displayed on remote device
492 * This is used for Bluetooth 2.1 pairing.
493 * @hide
494 */
Jaikumar Ganesh32d85712009-09-10 22:00:05 -0700495 public static final int PAIRING_VARIANT_DISPLAY_PASSKEY = 4;
Jaikumar Ganeshc88b0c62011-01-05 13:49:00 -0800496
497 /**
498 * The user will be prompted to enter the PIN displayed on remote device.
499 * This is used for Bluetooth 2.0 pairing.
500 * @hide
501 */
502 public static final int PAIRING_VARIANT_DISPLAY_PIN = 5;
503
504 /**
505 * The user will be prompted to accept or deny the OOB pairing request
506 * @hide
507 */
508 public static final int PAIRING_VARIANT_OOB_CONSENT = 6;
509
Jaikumar Ganesh1caa6d12009-09-18 11:32:54 -0700510 /**
511 * Used as an extra field in {@link #ACTION_UUID} intents,
Nick Pellyaef439e2009-09-28 12:33:17 -0700512 * Contains the {@link android.os.ParcelUuid}s of the remote device which
513 * is a parcelable version of {@link UUID}.
Jaikumar Ganesh1caa6d12009-09-18 11:32:54 -0700514 */
515 public static final String EXTRA_UUID = "android.bluetooth.device.extra.UUID";
516
Nick Pelly16fb88a2009-10-07 07:44:03 +0200517 /**
518 * Lazy initialization. Guaranteed final after first object constructed, or
519 * getService() called.
520 * TODO: Unify implementation of sService amongst BluetoothFoo API's
521 */
522 private static IBluetooth sService;
Jaikumar Ganeshd5ac1ae2009-05-05 22:26:12 -0700523
Nick Pellybd022f42009-08-14 18:33:38 -0700524 private final String mAddress;
525
Nick Pelly16fb88a2009-10-07 07:44:03 +0200526 /*package*/ static IBluetooth getService() {
527 synchronized (BluetoothDevice.class) {
528 if (sService == null) {
fredc0f420372012-04-12 00:02:00 -0700529 BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
fredc903ac6f2012-04-24 03:59:57 -0700530 sService = adapter.getBluetoothService(mStateChangeCallback);
Nick Pelly16fb88a2009-10-07 07:44:03 +0200531 }
532 }
533 return sService;
534 }
535
fredc903ac6f2012-04-24 03:59:57 -0700536 static IBluetoothManagerCallback mStateChangeCallback = new IBluetoothManagerCallback.Stub() {
537
538 public void onBluetoothServiceUp(IBluetooth bluetoothService)
539 throws RemoteException {
540 synchronized (BluetoothDevice.class) {
541 sService = bluetoothService;
542 }
543 }
544
545 public void onBluetoothServiceDown()
546 throws RemoteException {
547 synchronized (BluetoothDevice.class) {
548 sService = null;
549 }
550 }
551 };
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800552 /**
Nick Pellybd022f42009-08-14 18:33:38 -0700553 * Create a new BluetoothDevice
554 * Bluetooth MAC address must be upper case, such as "00:11:22:33:AA:BB",
555 * and is validated in this constructor.
556 * @param address valid Bluetooth MAC address
557 * @throws RuntimeException Bluetooth is not available on this platform
558 * @throws IllegalArgumentException address is invalid
559 * @hide
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800560 */
Nick Pellybd022f42009-08-14 18:33:38 -0700561 /*package*/ BluetoothDevice(String address) {
Nick Pelly16fb88a2009-10-07 07:44:03 +0200562 getService(); // ensures sService is initialized
Nick Pelly005b2282009-09-10 10:21:56 -0700563 if (!BluetoothAdapter.checkBluetoothAddress(address)) {
Nick Pellybd022f42009-08-14 18:33:38 -0700564 throw new IllegalArgumentException(address + " is not a valid Bluetooth address");
565 }
566
567 mAddress = address;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800568 }
569
Nick Pellybd022f42009-08-14 18:33:38 -0700570 @Override
571 public boolean equals(Object o) {
572 if (o instanceof BluetoothDevice) {
573 return mAddress.equals(((BluetoothDevice)o).getAddress());
574 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800575 return false;
576 }
577
Nick Pellybd022f42009-08-14 18:33:38 -0700578 @Override
579 public int hashCode() {
580 return mAddress.hashCode();
The Android Open Source Project10592532009-03-18 17:39:46 -0700581 }
582
Nick Pelly45e27042009-08-19 11:00:00 -0700583 /**
584 * Returns a string representation of this BluetoothDevice.
585 * <p>Currently this is the Bluetooth hardware address, for example
586 * "00:11:22:AA:BB:CC". However, you should always use {@link #getAddress}
587 * if you explicitly require the Bluetooth hardware address in case the
588 * {@link #toString} representation changes in the future.
589 * @return string representation of this BluetoothDevice
590 */
Nick Pellybd022f42009-08-14 18:33:38 -0700591 @Override
592 public String toString() {
593 return mAddress;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800594 }
595
Nick Pellybd022f42009-08-14 18:33:38 -0700596 public int describeContents() {
597 return 0;
598 }
599
600 public static final Parcelable.Creator<BluetoothDevice> CREATOR =
601 new Parcelable.Creator<BluetoothDevice>() {
602 public BluetoothDevice createFromParcel(Parcel in) {
603 return new BluetoothDevice(in.readString());
604 }
605 public BluetoothDevice[] newArray(int size) {
606 return new BluetoothDevice[size];
607 }
608 };
609
610 public void writeToParcel(Parcel out, int flags) {
611 out.writeString(mAddress);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800612 }
613
Nick Pelly45e27042009-08-19 11:00:00 -0700614 /**
615 * Returns the hardware address of this BluetoothDevice.
616 * <p> For example, "00:11:22:AA:BB:CC".
617 * @return Bluetooth hardware address as string
618 */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800619 public String getAddress() {
fredc0f420372012-04-12 00:02:00 -0700620 if (DBG) Log.d(TAG, "mAddress: " + mAddress);
Nick Pellybd022f42009-08-14 18:33:38 -0700621 return mAddress;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800622 }
623
624 /**
Nick Pelly45e27042009-08-19 11:00:00 -0700625 * Get the friendly Bluetooth name of the remote device.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800626 *
Nick Pelly45e27042009-08-19 11:00:00 -0700627 * <p>The local adapter will automatically retrieve remote names when
628 * performing a device scan, and will cache them. This method just returns
629 * the name for this device from the cache.
Nick Pellyde893f52009-09-08 13:15:33 -0700630 * <p>Requires {@link android.Manifest.permission#BLUETOOTH}
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800631 *
632 * @return the Bluetooth name, or null if there was a problem.
633 */
634 public String getName() {
fredc0f420372012-04-12 00:02:00 -0700635 if (sService == null) {
636 Log.e(TAG, "BT not enabled. Cannot get Remote Device name");
637 return null;
638 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800639 try {
Jaikumar Ganeshe4caddb2012-01-25 16:16:48 -0800640 return sService.getRemoteName(this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800641 } catch (RemoteException e) {Log.e(TAG, "", e);}
642 return null;
643 }
644
645 /**
Matthew Xie33ec9842013-04-03 00:29:27 -0700646 * Get the Bluetooth device type of the remote device.
647 *
648 * <p>Requires {@link android.Manifest.permission#BLUETOOTH}
649 *
650 * @return the device type {@link #DEVICE_TYPE_CLASSIC}, {@link #DEVICE_TYPE_LE}
651 * {@link #DEVICE_TYPE_DUAL}.
652 * {@link #DEVICE_TYPE_UNKNOWN} if it's not available
653 */
654 public int getType() {
655 if (sService == null) {
656 Log.e(TAG, "BT not enabled. Cannot get Remote Device type");
657 return DEVICE_TYPE_UNKNOWN;
658 }
659 try {
660 return sService.getRemoteType(this);
661 } catch (RemoteException e) {Log.e(TAG, "", e);}
662 return DEVICE_TYPE_UNKNOWN;
663 }
664
665 /**
Matthew Xie269e81a2011-07-26 18:36:49 -0700666 * Get the Bluetooth alias of the remote device.
667 * <p>Alias is the locally modified name of a remote device.
668 *
669 * @return the Bluetooth alias, or null if no alias or there was a problem
670 * @hide
671 */
672 public String getAlias() {
fredc0f420372012-04-12 00:02:00 -0700673 if (sService == null) {
674 Log.e(TAG, "BT not enabled. Cannot get Remote Device Alias");
675 return null;
676 }
Matthew Xie269e81a2011-07-26 18:36:49 -0700677 try {
Jaikumar Ganeshe4caddb2012-01-25 16:16:48 -0800678 return sService.getRemoteAlias(this);
Matthew Xie269e81a2011-07-26 18:36:49 -0700679 } catch (RemoteException e) {Log.e(TAG, "", e);}
680 return null;
681 }
682
683 /**
684 * Set the Bluetooth alias of the remote device.
685 * <p>Alias is the locally modified name of a remote device.
686 * <p>This methoid overwrites the alias. The changed
687 * alias is saved in the local storage so that the change
688 * is preserved over power cycle.
689 *
690 * @return true on success, false on error
691 * @hide
692 */
693 public boolean setAlias(String alias) {
fredc0f420372012-04-12 00:02:00 -0700694 if (sService == null) {
695 Log.e(TAG, "BT not enabled. Cannot set Remote Device name");
696 return false;
697 }
Matthew Xie269e81a2011-07-26 18:36:49 -0700698 try {
Jaikumar Ganeshe4caddb2012-01-25 16:16:48 -0800699 return sService.setRemoteAlias(this, alias);
Matthew Xie269e81a2011-07-26 18:36:49 -0700700 } catch (RemoteException e) {Log.e(TAG, "", e);}
701 return false;
702 }
703
704 /**
705 * Get the Bluetooth alias of the remote device.
706 * If Alias is null, get the Bluetooth name instead.
707 * @see #getAlias()
708 * @see #getName()
709 *
710 * @return the Bluetooth alias, or null if no alias or there was a problem
711 * @hide
712 */
713 public String getAliasName() {
714 String name = getAlias();
715 if (name == null) {
716 name = getName();
717 }
718 return name;
719 }
720
721 /**
Nick Pelly005b2282009-09-10 10:21:56 -0700722 * Start the bonding (pairing) process with the remote device.
723 * <p>This is an asynchronous call, it will return immediately. Register
724 * for {@link #ACTION_BOND_STATE_CHANGED} intents to be notified when
725 * the bonding process completes, and its result.
726 * <p>Android system services will handle the necessary user interactions
727 * to confirm and complete the bonding process.
Matthew Xieac2c6c32013-10-21 14:56:33 -0700728 * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800729 *
Nick Pelly005b2282009-09-10 10:21:56 -0700730 * @return false on immediate error, true if bonding will begin
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800731 */
Nick Pellybd022f42009-08-14 18:33:38 -0700732 public boolean createBond() {
fredc0f420372012-04-12 00:02:00 -0700733 if (sService == null) {
734 Log.e(TAG, "BT not enabled. Cannot create bond to Remote Device");
735 return false;
736 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800737 try {
Jaikumar Ganeshe4caddb2012-01-25 16:16:48 -0800738 return sService.createBond(this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800739 } catch (RemoteException e) {Log.e(TAG, "", e);}
740 return false;
741 }
742
743 /**
Jaikumar Ganeshcc5494c2010-09-09 15:37:57 -0700744 * Start the bonding (pairing) process with the remote device using the
745 * Out Of Band mechanism.
746 *
747 * <p>This is an asynchronous call, it will return immediately. Register
748 * for {@link #ACTION_BOND_STATE_CHANGED} intents to be notified when
749 * the bonding process completes, and its result.
750 *
751 * <p>Android system services will handle the necessary user interactions
752 * to confirm and complete the bonding process.
753 *
754 * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}.
755 *
756 * @param hash - Simple Secure pairing hash
757 * @param randomizer - The random key obtained using OOB
758 * @return false on immediate error, true if bonding will begin
759 *
760 * @hide
761 */
762 public boolean createBondOutOfBand(byte[] hash, byte[] randomizer) {
Jaikumar Ganeshe4caddb2012-01-25 16:16:48 -0800763 //TODO(BT)
764 /*
Jaikumar Ganeshcc5494c2010-09-09 15:37:57 -0700765 try {
Jaikumar Ganeshe4caddb2012-01-25 16:16:48 -0800766 return sService.createBondOutOfBand(this, hash, randomizer);
767 } catch (RemoteException e) {Log.e(TAG, "", e);}*/
Jaikumar Ganeshcc5494c2010-09-09 15:37:57 -0700768 return false;
769 }
770
771 /**
772 * Set the Out Of Band data for a remote device to be used later
773 * in the pairing mechanism. Users can obtain this data through other
774 * trusted channels
775 *
776 * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}.
777 *
778 * @param hash Simple Secure pairing hash
779 * @param randomizer The random key obtained using OOB
780 * @return false on error; true otherwise
781 *
782 * @hide
783 */
784 public boolean setDeviceOutOfBandData(byte[] hash, byte[] randomizer) {
Jaikumar Ganeshe4caddb2012-01-25 16:16:48 -0800785 //TODO(BT)
786 /*
Jaikumar Ganeshcc5494c2010-09-09 15:37:57 -0700787 try {
Jaikumar Ganeshe4caddb2012-01-25 16:16:48 -0800788 return sService.setDeviceOutOfBandData(this, hash, randomizer);
789 } catch (RemoteException e) {Log.e(TAG, "", e);} */
Jaikumar Ganeshcc5494c2010-09-09 15:37:57 -0700790 return false;
791 }
792
793 /**
Nick Pelly005b2282009-09-10 10:21:56 -0700794 * Cancel an in-progress bonding request started with {@link #createBond}.
795 * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}.
796 *
Jake Hambyf51eada2010-09-21 13:39:53 -0700797 * @return true on success, false on error
Nick Pelly18b1e792009-09-24 11:14:15 -0700798 * @hide
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800799 */
Nick Pellybd022f42009-08-14 18:33:38 -0700800 public boolean cancelBondProcess() {
fredc0f420372012-04-12 00:02:00 -0700801 if (sService == null) {
802 Log.e(TAG, "BT not enabled. Cannot cancel Remote Device bond");
803 return false;
804 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800805 try {
Jaikumar Ganeshe4caddb2012-01-25 16:16:48 -0800806 return sService.cancelBondProcess(this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800807 } catch (RemoteException e) {Log.e(TAG, "", e);}
808 return false;
809 }
810
811 /**
Nick Pelly005b2282009-09-10 10:21:56 -0700812 * Remove bond (pairing) with the remote device.
813 * <p>Delete the link key associated with the remote device, and
814 * immediately terminate connections to that device that require
815 * authentication and encryption.
816 * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800817 *
Jake Hambyf51eada2010-09-21 13:39:53 -0700818 * @return true on success, false on error
Nick Pelly18b1e792009-09-24 11:14:15 -0700819 * @hide
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800820 */
Nick Pellybd022f42009-08-14 18:33:38 -0700821 public boolean removeBond() {
fredc0f420372012-04-12 00:02:00 -0700822 if (sService == null) {
823 Log.e(TAG, "BT not enabled. Cannot remove Remote Device bond");
824 return false;
825 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800826 try {
Jaikumar Ganeshe4caddb2012-01-25 16:16:48 -0800827 return sService.removeBond(this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800828 } catch (RemoteException e) {Log.e(TAG, "", e);}
Nick Pellybd022f42009-08-14 18:33:38 -0700829 return false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800830 }
831
832 /**
Nick Pelly005b2282009-09-10 10:21:56 -0700833 * Get the bond state of the remote device.
834 * <p>Possible values for the bond state are:
835 * {@link #BOND_NONE},
836 * {@link #BOND_BONDING},
837 * {@link #BOND_BONDED}.
838 * <p>Requires {@link android.Manifest.permission#BLUETOOTH}.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800839 *
Nick Pelly005b2282009-09-10 10:21:56 -0700840 * @return the bond state
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800841 */
Nick Pellybd022f42009-08-14 18:33:38 -0700842 public int getBondState() {
fredc0f420372012-04-12 00:02:00 -0700843 if (sService == null) {
844 Log.e(TAG, "BT not enabled. Cannot get bond state");
845 return BOND_NONE;
846 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800847 try {
Jaikumar Ganeshe4caddb2012-01-25 16:16:48 -0800848 return sService.getBondState(this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800849 } catch (RemoteException e) {Log.e(TAG, "", e);}
Syed Ibrahim M305f2402012-06-19 10:14:25 -0700850 catch (NullPointerException npe) {
851 // Handle case where bluetooth service proxy
852 // is already null.
853 Log.e(TAG, "NullPointerException for getBondState() of device ("+
854 getAddress()+")", npe);
855 }
Nick Pelly005b2282009-09-10 10:21:56 -0700856 return BOND_NONE;
857 }
858
859 /**
860 * Get the Bluetooth class of the remote device.
861 * <p>Requires {@link android.Manifest.permission#BLUETOOTH}.
862 *
863 * @return Bluetooth class object, or null on error
864 */
865 public BluetoothClass getBluetoothClass() {
fredc0f420372012-04-12 00:02:00 -0700866 if (sService == null) {
867 Log.e(TAG, "BT not enabled. Cannot get Bluetooth Class");
868 return null;
869 }
Nick Pelly005b2282009-09-10 10:21:56 -0700870 try {
Jaikumar Ganeshe4caddb2012-01-25 16:16:48 -0800871 int classInt = sService.getRemoteClass(this);
Nick Pelly005b2282009-09-10 10:21:56 -0700872 if (classInt == BluetoothClass.ERROR) return null;
873 return new BluetoothClass(classInt);
874 } catch (RemoteException e) {Log.e(TAG, "", e);}
875 return null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800876 }
877
Lixin Yueefa1dd72009-08-31 15:55:13 +0800878 /**
879 * Get trust state of a remote device.
Nick Pellye6ee3be2009-10-08 23:27:28 +0200880 * <p>Requires {@link android.Manifest.permission#BLUETOOTH}.
Lixin Yueefa1dd72009-08-31 15:55:13 +0800881 * @hide
882 */
883 public boolean getTrustState() {
Jaikumar Ganeshe4caddb2012-01-25 16:16:48 -0800884 //TODO(BT)
885 /*
Lixin Yueefa1dd72009-08-31 15:55:13 +0800886 try {
Jaikumar Ganeshe4caddb2012-01-25 16:16:48 -0800887 return sService.getTrustState(this);
Lixin Yueefa1dd72009-08-31 15:55:13 +0800888 } catch (RemoteException e) {
889 Log.e(TAG, "", e);
Jaikumar Ganeshe4caddb2012-01-25 16:16:48 -0800890 }*/
Lixin Yueefa1dd72009-08-31 15:55:13 +0800891 return false;
892 }
893
894 /**
895 * Set trust state for a remote device.
Nick Pellye6ee3be2009-10-08 23:27:28 +0200896 * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}.
Lixin Yueefa1dd72009-08-31 15:55:13 +0800897 * @param value the trust state value (true or false)
898 * @hide
899 */
900 public boolean setTrust(boolean value) {
Jaikumar Ganeshe4caddb2012-01-25 16:16:48 -0800901 //TODO(BT)
902 /*
Lixin Yueefa1dd72009-08-31 15:55:13 +0800903 try {
Jaikumar Ganeshe4caddb2012-01-25 16:16:48 -0800904 return sService.setTrust(this, value);
Lixin Yueefa1dd72009-08-31 15:55:13 +0800905 } catch (RemoteException e) {
906 Log.e(TAG, "", e);
Jaikumar Ganeshe4caddb2012-01-25 16:16:48 -0800907 }*/
Lixin Yueefa1dd72009-08-31 15:55:13 +0800908 return false;
909 }
910
Matthew Xiead232102011-11-08 10:58:12 -0800911 /**
912 * Returns the supported features (UUIDs) of the remote device.
913 *
914 * <p>This method does not start a service discovery procedure to retrieve the UUIDs
915 * from the remote device. Instead, the local cached copy of the service
916 * UUIDs are returned.
917 * <p>Use {@link #fetchUuidsWithSdp} if fresh UUIDs are desired.
918 * <p>Requires {@link android.Manifest.permission#BLUETOOTH}.
919 *
920 * @return the supported features (UUIDs) of the remote device,
921 * or null on error
922 */
Jaikumar Ganeshdd0463a2009-09-16 12:30:02 -0700923 public ParcelUuid[] getUuids() {
fredc0f420372012-04-12 00:02:00 -0700924 if (sService == null) {
925 Log.e(TAG, "BT not enabled. Cannot get remote device Uuids");
926 return null;
927 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800928 try {
Jaikumar Ganeshe4caddb2012-01-25 16:16:48 -0800929 return sService.getRemoteUuids(this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800930 } catch (RemoteException e) {Log.e(TAG, "", e);}
931 return null;
932 }
Jaikumar Ganeshd5ac1ae2009-05-05 22:26:12 -0700933
Jaikumar Ganesh1caa6d12009-09-18 11:32:54 -0700934 /**
Matthew Xiead232102011-11-08 10:58:12 -0800935 * Perform a service discovery on the remote device to get the UUIDs supported.
Jaikumar Ganesh1caa6d12009-09-18 11:32:54 -0700936 *
Matthew Xiead232102011-11-08 10:58:12 -0800937 * <p>This API is asynchronous and {@link #ACTION_UUID} intent is sent,
938 * with the UUIDs supported by the remote end. If there is an error
939 * in getting the SDP records or if the process takes a long time,
940 * {@link #ACTION_UUID} intent is sent with the UUIDs that is currently
941 * present in the cache. Clients should use the {@link #getUuids} to get UUIDs
942 * if service discovery is not to be performed.
943 * <p>Requires {@link android.Manifest.permission#BLUETOOTH}.
944 *
945 * @return False if the sanity check fails, True if the process
Jaikumar Ganesh1caa6d12009-09-18 11:32:54 -0700946 * of initiating an ACL connection to the remote device
947 * was started.
Jaikumar Ganesh1caa6d12009-09-18 11:32:54 -0700948 */
949 public boolean fetchUuidsWithSdp() {
950 try {
fredc4c9caca2012-04-06 02:08:46 -0700951 return sService.fetchRemoteUuids(this);
952 } catch (RemoteException e) {Log.e(TAG, "", e);}
953 return false;
Jaikumar Ganesh1caa6d12009-09-18 11:32:54 -0700954 }
955
Nick Pelly45e27042009-08-19 11:00:00 -0700956 /** @hide */
Jaikumar Ganeshdd0463a2009-09-16 12:30:02 -0700957 public int getServiceChannel(ParcelUuid uuid) {
Jaikumar Ganeshe4caddb2012-01-25 16:16:48 -0800958 //TODO(BT)
959 /*
Jaikumar Ganeshd5ac1ae2009-05-05 22:26:12 -0700960 try {
Jaikumar Ganeshe4caddb2012-01-25 16:16:48 -0800961 return sService.getRemoteServiceChannel(this, uuid);
962 } catch (RemoteException e) {Log.e(TAG, "", e);}*/
Nick Pellyb24e11b2009-09-08 17:40:43 -0700963 return BluetoothDevice.ERROR;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800964 }
965
Matthew Xie091fc2b2013-09-23 23:23:13 -0700966 /**
967 * Set the pin during pairing when the pairing method is {@link #PAIRING_VARIANT_PIN}
Matthew Xieac2c6c32013-10-21 14:56:33 -0700968 * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}.
Matthew Xie091fc2b2013-09-23 23:23:13 -0700969 *
970 * @return true pin has been set
971 * false for error
972 */
Nick Pellybd022f42009-08-14 18:33:38 -0700973 public boolean setPin(byte[] pin) {
fredc0f420372012-04-12 00:02:00 -0700974 if (sService == null) {
975 Log.e(TAG, "BT not enabled. Cannot set Remote Device pin");
976 return false;
977 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800978 try {
Jaikumar Ganeshe4caddb2012-01-25 16:16:48 -0800979 return sService.setPin(this, true, pin.length, pin);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800980 } catch (RemoteException e) {Log.e(TAG, "", e);}
981 return false;
982 }
Jaikumar Ganeshb0eca412009-07-16 18:26:28 -0700983
Nick Pelly45e27042009-08-19 11:00:00 -0700984 /** @hide */
Nick Pellybd022f42009-08-14 18:33:38 -0700985 public boolean setPasskey(int passkey) {
Jaikumar Ganeshe4caddb2012-01-25 16:16:48 -0800986 //TODO(BT)
987 /*
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800988 try {
Jaikumar Ganeshe4caddb2012-01-25 16:16:48 -0800989 return sService.setPasskey(this, true, 4, passkey);
990 } catch (RemoteException e) {Log.e(TAG, "", e);}*/
Jaikumar Ganeshb0eca412009-07-16 18:26:28 -0700991 return false;
992 }
993
Matthew Xie091fc2b2013-09-23 23:23:13 -0700994 /**
995 * Confirm passkey for {@link #PAIRING_VARIANT_PASSKEY_CONFIRMATION} pairing.
Matthew Xieac2c6c32013-10-21 14:56:33 -0700996 * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}.
Matthew Xie091fc2b2013-09-23 23:23:13 -0700997 *
998 * @return true confirmation has been sent out
999 * false for error
1000 */
Nick Pellybd022f42009-08-14 18:33:38 -07001001 public boolean setPairingConfirmation(boolean confirm) {
fredc0f420372012-04-12 00:02:00 -07001002 if (sService == null) {
1003 Log.e(TAG, "BT not enabled. Cannot set pairing confirmation");
1004 return false;
1005 }
Jaikumar Ganeshb0eca412009-07-16 18:26:28 -07001006 try {
Jaikumar Ganeshe4caddb2012-01-25 16:16:48 -08001007 return sService.setPairingConfirmation(this, confirm);
Jaikumar Ganeshb0eca412009-07-16 18:26:28 -07001008 } catch (RemoteException e) {Log.e(TAG, "", e);}
1009 return false;
1010 }
1011
Nick Pelly45e27042009-08-19 11:00:00 -07001012 /** @hide */
Jaikumar Ganeshcc5494c2010-09-09 15:37:57 -07001013 public boolean setRemoteOutOfBandData() {
Jaikumar Ganeshe4caddb2012-01-25 16:16:48 -08001014 // TODO(BT)
1015 /*
Jaikumar Ganeshcc5494c2010-09-09 15:37:57 -07001016 try {
Jaikumar Ganeshe4caddb2012-01-25 16:16:48 -08001017 return sService.setRemoteOutOfBandData(this);
1018 } catch (RemoteException e) {Log.e(TAG, "", e);}*/
Jaikumar Ganeshcc5494c2010-09-09 15:37:57 -07001019 return false;
1020 }
1021
1022 /** @hide */
Nick Pellybd022f42009-08-14 18:33:38 -07001023 public boolean cancelPairingUserInput() {
fredc0f420372012-04-12 00:02:00 -07001024 if (sService == null) {
1025 Log.e(TAG, "BT not enabled. Cannot create pairing user input");
1026 return false;
1027 }
Jaikumar Ganeshb0eca412009-07-16 18:26:28 -07001028 try {
Ravi Nagarajan919a4c62012-04-13 21:18:16 +05301029 return sService.cancelBondProcess(this);
Priti Agheradb44b202012-03-13 10:41:41 -07001030 } catch (RemoteException e) {Log.e(TAG, "", e);}
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001031 return false;
1032 }
1033
Jaikumar Ganesh3fbf7b62009-12-02 17:28:38 -08001034 /** @hide */
1035 public boolean isBluetoothDock() {
Jaikumar Ganeshe4caddb2012-01-25 16:16:48 -08001036 // TODO(BT)
1037 /*
Jaikumar Ganesh3fbf7b62009-12-02 17:28:38 -08001038 try {
Jaikumar Ganeshe4caddb2012-01-25 16:16:48 -08001039 return sService.isBluetoothDock(this);
1040 } catch (RemoteException e) {Log.e(TAG, "", e);}*/
Jaikumar Ganesh3fbf7b62009-12-02 17:28:38 -08001041 return false;
1042 }
1043
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001044 /**
Nick Pelly45e27042009-08-19 11:00:00 -07001045 * Create an RFCOMM {@link BluetoothSocket} ready to start a secure
Nick Pelly16fb88a2009-10-07 07:44:03 +02001046 * outgoing connection to this remote device on given channel.
Nick Pelly45e27042009-08-19 11:00:00 -07001047 * <p>The remote device will be authenticated and communication on this
1048 * socket will be encrypted.
Jaikumar Ganeshc8fa4ff2011-01-25 16:03:13 -08001049 * <p> Use this socket only if an authenticated socket link is possible.
1050 * Authentication refers to the authentication of the link key to
1051 * prevent man-in-the-middle type of attacks.
1052 * For example, for Bluetooth 2.1 devices, if any of the devices does not
1053 * have an input and output capability or just has the ability to
1054 * display a numeric key, a secure socket connection is not possible.
1055 * In such a case, use {#link createInsecureRfcommSocket}.
1056 * For more details, refer to the Security Model section 5.2 (vol 3) of
1057 * Bluetooth Core Specification version 2.1 + EDR.
Jake Hambyf51eada2010-09-21 13:39:53 -07001058 * <p>Use {@link BluetoothSocket#connect} to initiate the outgoing
Nick Pelly45e27042009-08-19 11:00:00 -07001059 * connection.
1060 * <p>Valid RFCOMM channels are in range 1 to 30.
Nick Pellycf440592009-09-08 10:12:06 -07001061 * <p>Requires {@link android.Manifest.permission#BLUETOOTH}
Nick Pellyde893f52009-09-08 13:15:33 -07001062 *
Nick Pelly45e27042009-08-19 11:00:00 -07001063 * @param channel RFCOMM channel to connect to
1064 * @return a RFCOMM BluetoothServerSocket ready for an outgoing connection
Nick Pellybd022f42009-08-14 18:33:38 -07001065 * @throws IOException on error, for example Bluetooth not available, or
Nick Pelly45e27042009-08-19 11:00:00 -07001066 * insufficient permissions
Nick Pelly16fb88a2009-10-07 07:44:03 +02001067 * @hide
Nick Pellybd022f42009-08-14 18:33:38 -07001068 */
Nick Pelly45e27042009-08-19 11:00:00 -07001069 public BluetoothSocket createRfcommSocket(int channel) throws IOException {
Nick Pelly16fb88a2009-10-07 07:44:03 +02001070 return new BluetoothSocket(BluetoothSocket.TYPE_RFCOMM, -1, true, true, this, channel,
1071 null);
1072 }
1073
1074 /**
1075 * Create an RFCOMM {@link BluetoothSocket} ready to start a secure
1076 * outgoing connection to this remote device using SDP lookup of uuid.
1077 * <p>This is designed to be used with {@link
1078 * BluetoothAdapter#listenUsingRfcommWithServiceRecord} for peer-peer
1079 * Bluetooth applications.
Jake Hambyf51eada2010-09-21 13:39:53 -07001080 * <p>Use {@link BluetoothSocket#connect} to initiate the outgoing
Nick Pelly16fb88a2009-10-07 07:44:03 +02001081 * connection. This will also perform an SDP lookup of the given uuid to
1082 * determine which channel to connect to.
1083 * <p>The remote device will be authenticated and communication on this
1084 * socket will be encrypted.
Jaikumar Ganeshc8fa4ff2011-01-25 16:03:13 -08001085 * <p> Use this socket only if an authenticated socket link is possible.
1086 * Authentication refers to the authentication of the link key to
1087 * prevent man-in-the-middle type of attacks.
1088 * For example, for Bluetooth 2.1 devices, if any of the devices does not
1089 * have an input and output capability or just has the ability to
1090 * display a numeric key, a secure socket connection is not possible.
1091 * In such a case, use {#link createInsecureRfcommSocketToServiceRecord}.
1092 * For more details, refer to the Security Model section 5.2 (vol 3) of
1093 * Bluetooth Core Specification version 2.1 + EDR.
Nick Pellyea5056e2010-02-24 11:19:10 -08001094 * <p>Hint: If you are connecting to a Bluetooth serial board then try
1095 * using the well-known SPP UUID 00001101-0000-1000-8000-00805F9B34FB.
1096 * However if you are connecting to an Android peer then please generate
1097 * your own unique UUID.
Nick Pelly16fb88a2009-10-07 07:44:03 +02001098 * <p>Requires {@link android.Manifest.permission#BLUETOOTH}
1099 *
1100 * @param uuid service record uuid to lookup RFCOMM channel
1101 * @return a RFCOMM BluetoothServerSocket ready for an outgoing connection
1102 * @throws IOException on error, for example Bluetooth not available, or
1103 * insufficient permissions
1104 */
1105 public BluetoothSocket createRfcommSocketToServiceRecord(UUID uuid) throws IOException {
1106 return new BluetoothSocket(BluetoothSocket.TYPE_RFCOMM, -1, true, true, this, -1,
1107 new ParcelUuid(uuid));
Nick Pellybd022f42009-08-14 18:33:38 -07001108 }
1109
1110 /**
Jaikumar Ganesh6eef14a2010-12-23 12:57:02 -08001111 * Create an RFCOMM {@link BluetoothSocket} socket ready to start an insecure
1112 * outgoing connection to this remote device using SDP lookup of uuid.
1113 * <p> The communication channel will not have an authenticated link key
1114 * i.e it will be subject to man-in-the-middle attacks. For Bluetooth 2.1
1115 * devices, the link key will be encrypted, as encryption is mandatory.
1116 * For legacy devices (pre Bluetooth 2.1 devices) the link key will
1117 * be not be encrypted. Use {@link #createRfcommSocketToServiceRecord} if an
1118 * encrypted and authenticated communication channel is desired.
1119 * <p>This is designed to be used with {@link
1120 * BluetoothAdapter#listenUsingInsecureRfcommWithServiceRecord} for peer-peer
1121 * Bluetooth applications.
1122 * <p>Use {@link BluetoothSocket#connect} to initiate the outgoing
1123 * connection. This will also perform an SDP lookup of the given uuid to
1124 * determine which channel to connect to.
1125 * <p>The remote device will be authenticated and communication on this
1126 * socket will be encrypted.
1127 * <p>Hint: If you are connecting to a Bluetooth serial board then try
1128 * using the well-known SPP UUID 00001101-0000-1000-8000-00805F9B34FB.
1129 * However if you are connecting to an Android peer then please generate
1130 * your own unique UUID.
1131 * <p>Requires {@link android.Manifest.permission#BLUETOOTH}
1132 *
1133 * @param uuid service record uuid to lookup RFCOMM channel
1134 * @return a RFCOMM BluetoothServerSocket ready for an outgoing connection
1135 * @throws IOException on error, for example Bluetooth not available, or
1136 * insufficient permissions
1137 */
1138 public BluetoothSocket createInsecureRfcommSocketToServiceRecord(UUID uuid) throws IOException {
1139 return new BluetoothSocket(BluetoothSocket.TYPE_RFCOMM, -1, false, false, this, -1,
1140 new ParcelUuid(uuid));
1141 }
1142
1143 /**
Nick Pellybd022f42009-08-14 18:33:38 -07001144 * Construct an insecure RFCOMM socket ready to start an outgoing
1145 * connection.
1146 * Call #connect on the returned #BluetoothSocket to begin the connection.
1147 * The remote device will not be authenticated and communication on this
1148 * socket will not be encrypted.
Nick Pellye6ee3be2009-10-08 23:27:28 +02001149 * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}
1150 *
Nick Pellybd022f42009-08-14 18:33:38 -07001151 * @param port remote port
1152 * @return An RFCOMM BluetoothSocket
1153 * @throws IOException On error, for example Bluetooth not available, or
1154 * insufficient permissions.
Nick Pelly45e27042009-08-19 11:00:00 -07001155 * @hide
Nick Pellybd022f42009-08-14 18:33:38 -07001156 */
1157 public BluetoothSocket createInsecureRfcommSocket(int port) throws IOException {
Nick Pelly16fb88a2009-10-07 07:44:03 +02001158 return new BluetoothSocket(BluetoothSocket.TYPE_RFCOMM, -1, false, false, this, port,
1159 null);
Nick Pellybd022f42009-08-14 18:33:38 -07001160 }
1161
1162 /**
1163 * Construct a SCO socket ready to start an outgoing connection.
1164 * Call #connect on the returned #BluetoothSocket to begin the connection.
Nick Pellye6ee3be2009-10-08 23:27:28 +02001165 * <p>Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}
1166 *
Nick Pellybd022f42009-08-14 18:33:38 -07001167 * @return a SCO BluetoothSocket
1168 * @throws IOException on error, for example Bluetooth not available, or
1169 * insufficient permissions.
Nick Pelly45e27042009-08-19 11:00:00 -07001170 * @hide
Nick Pellybd022f42009-08-14 18:33:38 -07001171 */
1172 public BluetoothSocket createScoSocket() throws IOException {
Nick Pelly16fb88a2009-10-07 07:44:03 +02001173 return new BluetoothSocket(BluetoothSocket.TYPE_SCO, -1, true, true, this, -1, null);
Nick Pellybd022f42009-08-14 18:33:38 -07001174 }
1175
1176 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001177 * Check that a pin is valid and convert to byte array.
1178 *
Jake Hambyf51eada2010-09-21 13:39:53 -07001179 * Bluetooth pin's are 1 to 16 bytes of UTF-8 characters.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001180 * @param pin pin as java String
Jake Hambyf51eada2010-09-21 13:39:53 -07001181 * @return the pin code as a UTF-8 byte array, or null if it is an invalid
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001182 * Bluetooth pin.
Nick Pelly45e27042009-08-19 11:00:00 -07001183 * @hide
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001184 */
1185 public static byte[] convertPinToBytes(String pin) {
1186 if (pin == null) {
1187 return null;
1188 }
1189 byte[] pinBytes;
1190 try {
Jake Hambyf51eada2010-09-21 13:39:53 -07001191 pinBytes = pin.getBytes("UTF-8");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001192 } catch (UnsupportedEncodingException uee) {
Jake Hambyf51eada2010-09-21 13:39:53 -07001193 Log.e(TAG, "UTF-8 not supported?!?"); // this should not happen
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001194 return null;
1195 }
1196 if (pinBytes.length <= 0 || pinBytes.length > 16) {
1197 return null;
1198 }
1199 return pinBytes;
1200 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001201
Matthew Xieddf7e472013-03-01 18:41:02 -08001202 /**
1203 * Connect to GATT Server hosted by this device. Caller acts as GATT client.
1204 * The callback is used to deliver results to Caller, such as connection status as well
1205 * as any further GATT client operations.
1206 * The method returns a BluetoothGatt instance. You can use BluetoothGatt to conduct
1207 * GATT client operations.
1208 * @param callback GATT callback handler that will receive asynchronous callbacks.
1209 * @param autoConnect Whether to directly connect to the remote device (false)
1210 * or to automatically connect as soon as the remote
1211 * device becomes available (true).
1212 * @throws IllegalArgumentException if callback is null
1213 */
Matthew Xie33ec9842013-04-03 00:29:27 -07001214 public BluetoothGatt connectGatt(Context context, boolean autoConnect,
1215 BluetoothGattCallback callback) {
Matthew Xieddf7e472013-03-01 18:41:02 -08001216 // TODO(Bluetooth) check whether platform support BLE
1217 // Do the check here or in GattServer?
1218 BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
1219 IBluetoothManager managerService = adapter.getBluetoothManager();
1220 try {
1221 IBluetoothGatt iGatt = managerService.getBluetoothGatt();
Matthew Xie32ab77b2013-05-08 19:26:57 -07001222 if (iGatt == null) {
1223 // BLE is not supported
1224 return null;
1225 }
Matthew Xieddf7e472013-03-01 18:41:02 -08001226 BluetoothGatt gatt = new BluetoothGatt(context, iGatt, this);
1227 gatt.connect(autoConnect, callback);
1228 return gatt;
1229 } catch (RemoteException e) {Log.e(TAG, "", e);}
1230 return null;
1231 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001232}