aboutsummaryrefslogtreecommitdiff
path: root/framework/java/android/bluetooth/BluetoothDevice.java
diff options
context:
space:
mode:
Diffstat (limited to 'framework/java/android/bluetooth/BluetoothDevice.java')
-rw-r--r--framework/java/android/bluetooth/BluetoothDevice.java147
1 files changed, 89 insertions, 58 deletions
diff --git a/framework/java/android/bluetooth/BluetoothDevice.java b/framework/java/android/bluetooth/BluetoothDevice.java
index 3040b51ce0..4d416f2052 100644
--- a/framework/java/android/bluetooth/BluetoothDevice.java
+++ b/framework/java/android/bluetooth/BluetoothDevice.java
@@ -26,7 +26,7 @@ import android.annotation.RequiresPermission;
import android.annotation.SdkConstant;
import android.annotation.SdkConstant.SdkConstantType;
import android.annotation.SuppressLint;
-import android.annotation.SystemApi; //import android.app.PropertyInvalidatedCache;
+import android.annotation.SystemApi;
import android.bluetooth.annotations.RequiresBluetoothConnectPermission;
import android.bluetooth.annotations.RequiresBluetoothLocationPermission;
import android.bluetooth.annotations.RequiresBluetoothScanPermission;
@@ -38,6 +38,7 @@ import android.content.AttributionSource;
import android.content.Context;
import android.os.Build;
import android.os.Handler;
+import android.os.IpcDataCache;
import android.os.Parcel;
import android.os.ParcelUuid;
import android.os.Parcelable;
@@ -216,7 +217,7 @@ public final class BluetoothDevice implements Parcelable, Attributable {
* #EXTRA_BOND_STATE} and {@link #EXTRA_PREVIOUS_BOND_STATE}.
*/
// Note: When EXTRA_BOND_STATE is BOND_NONE then this will also
- // contain a hidden extra field EXTRA_REASON with the result code.
+ // contain a hidden extra field EXTRA_UNBOND_REASON with the result code.
@RequiresLegacyBluetoothPermission
@RequiresBluetoothConnectPermission
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
@@ -379,8 +380,7 @@ public final class BluetoothDevice implements Parcelable, Attributable {
public static final int BOND_BONDED = 12;
/**
- * Used as an int extra field in {@link #ACTION_PAIRING_REQUEST}
- * intents for unbond reason.
+ * Used as an int extra field in {@link #ACTION_PAIRING_REQUEST} intents for unbond reason.
* Possible value are :
* - {@link #UNBOND_REASON_AUTH_FAILED}
* - {@link #UNBOND_REASON_AUTH_REJECTED}
@@ -392,11 +392,22 @@ public final class BluetoothDevice implements Parcelable, Attributable {
* - {@link #UNBOND_REASON_REMOTE_AUTH_CANCELED}
* - {@link #UNBOND_REASON_REMOVED}
*
- * {@hide}
+ * Note: Can be added as a hidden extra field for {@link #ACTION_BOND_STATE_CHANGED} when the
+ * {@link #EXTRA_BOND_STATE} is {@link #BOND_NONE}
+ *
+ * @hide
*/
@SystemApi
@SuppressLint("ActionValue")
- public static final String EXTRA_REASON = "android.bluetooth.device.extra.REASON";
+ public static final String EXTRA_UNBOND_REASON = "android.bluetooth.device.extra.REASON";
+
+ /**
+ * Use {@link EXTRA_UNBOND_REASON} instead
+ * @hide
+ */
+ @UnsupportedAppUsage
+ public static final String EXTRA_REASON = EXTRA_UNBOND_REASON;
+
/**
* Used as an int extra field in {@link #ACTION_PAIRING_REQUEST}
@@ -1476,17 +1487,21 @@ public final class BluetoothDevice implements Parcelable, Attributable {
android.Manifest.permission.BLUETOOTH_PRIVILEGED,
})
public @Nullable String getIdentityAddress() {
+ if (DBG) log("getIdentityAddress()");
final IBluetooth service = sService;
+ final String defaultValue = null;
if (service == null) {
Log.e(TAG, "BT not enabled. Cannot get identity address");
- return null;
- }
- try {
- return service.getIdentityAddress(mAddress);
- } catch (RemoteException e) {
- Log.e(TAG, "", e);
+ } else {
+ try {
+ final SynchronousResultReceiver<String> recv = new SynchronousResultReceiver();
+ service.getIdentityAddress(mAddress, recv);
+ return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(null);
+ } catch (RemoteException | TimeoutException e) {
+ Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
+ }
}
- return null;
+ return defaultValue;
}
/**
@@ -1870,41 +1885,71 @@ public final class BluetoothDevice implements Parcelable, Attributable {
return defaultValue;
}
- /*
- private static final String BLUETOOTH_BONDING_CACHE_PROPERTY =
- "cache_key.bluetooth.get_bond_state";
- private final PropertyInvalidatedCache<BluetoothDevice, Integer> mBluetoothBondCache =
- new PropertyInvalidatedCache<BluetoothDevice, Integer>(
- 8, BLUETOOTH_BONDING_CACHE_PROPERTY) {
+ /**
+ * There are several instances of IpcDataCache used in this class.
+ * BluetoothCache wraps up the common code. All caches are created with a maximum of
+ * eight entries, and the key is in the bluetooth module. The name is set to the api.
+ */
+ private static class BluetoothCache<Q, R> extends IpcDataCache<Q, R> {
+ BluetoothCache(String api, IpcDataCache.QueryHandler query) {
+ super(8, IpcDataCache.MODULE_BLUETOOTH, api, api, query);
+ }};
+
+ /**
+ * Invalidate a bluetooth cache. This method is just a short-hand wrapper that
+ * enforces the bluetooth module.
+ */
+ private static void invalidateCache(@NonNull String api) {
+ IpcDataCache.invalidateCache(IpcDataCache.MODULE_BLUETOOTH, api);
+ }
+
+ private final
+ IpcDataCache.QueryHandler<BluetoothDevice, Integer> mBluetoothBondQuery =
+ new IpcDataCache.QueryHandler<>() {
+ @RequiresLegacyBluetoothPermission
+ @RequiresBluetoothConnectPermission
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
@Override
- @SuppressLint("AndroidFrameworkRequiresPermission")
- protected Integer recompute(BluetoothDevice query) {
- try {
- final SynchronousResultReceiver<Integer> recv =
- new SynchronousResultReceiver();
- sService.getBondState(query, mAttributionSource, recv);
- return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
- } catch (TimeoutException e) {
- Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
- } catch (RemoteException e) {
- throw e.rethrowAsRuntimeException();
+ public Integer apply(BluetoothDevice query) {
+ if (DBG) log("getBondState() uncached");
+ final IBluetooth service = sService;
+ final int defaultValue = BOND_NONE;
+ if (service == null) {
+ Log.e(TAG, "BT not enabled. Cannot get bond state");
+ if (DBG) log(Log.getStackTraceString(new Throwable()));
+ } else {
+ try {
+ final SynchronousResultReceiver<Integer> recv =
+ new SynchronousResultReceiver();
+ service.getBondState(BluetoothDevice.this, mAttributionSource, recv);
+ return recv.awaitResultNoInterrupt(getSyncTimeout())
+ .getValue(defaultValue);
+ } catch (TimeoutException e) {
+ Log.e(TAG, e.toString() + "\n"
+ + Log.getStackTraceString(new Throwable()));
+ } catch (RemoteException e) {
+ Log.e(TAG, "failed to ", e);
+ e.rethrowFromSystemServer();
+ }
}
return defaultValue;
}
};
- */
+
+ private static final String GET_BOND_STATE_API = "getBondState";
+
+ private final BluetoothCache<BluetoothDevice, Integer> mBluetoothBondCache =
+ new BluetoothCache<BluetoothDevice, Integer>(GET_BOND_STATE_API, mBluetoothBondQuery);
/** @hide */
- /* public void disableBluetoothGetBondStateCache() {
- mBluetoothBondCache.disableLocal();
- } */
+ public void disableBluetoothGetBondStateCache() {
+ mBluetoothBondCache.disableForCurrentProcess();
+ }
/** @hide */
- /*
public static void invalidateBluetoothGetBondStateCache() {
- PropertyInvalidatedCache.invalidateCache(BLUETOOTH_BONDING_CACHE_PROPERTY);
+ invalidateCache(GET_BOND_STATE_API);
}
- */
/**
* Get the bond state of the remote device.
@@ -1921,25 +1966,7 @@ public final class BluetoothDevice implements Parcelable, Attributable {
@SuppressLint("AndroidFrameworkRequiresPermission")
public int getBondState() {
if (DBG) log("getBondState()");
- final IBluetooth service = sService;
- final int defaultValue = BOND_NONE;
- if (service == null) {
- Log.e(TAG, "BT not enabled. Cannot get bond state");
- if (DBG) log(Log.getStackTraceString(new Throwable()));
- } else {
- try {
- final SynchronousResultReceiver<Integer> recv = new SynchronousResultReceiver();
- //return mBluetoothBondCache.query(this);
- service.getBondState(this, mAttributionSource, recv);
- return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
- } catch (TimeoutException e) {
- Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
- } catch (RemoteException e) {
- Log.e(TAG, "failed to ", e);
- e.rethrowFromSystemServer();
- }
- }
- return defaultValue;
+ return mBluetoothBondCache.query(null);
}
/**
@@ -2033,10 +2060,14 @@ public final class BluetoothDevice implements Parcelable, Attributable {
/**
* Disconnects all connected bluetooth profiles between the local and remote device.
- * Disconnection is asynchronous and you should listen to each profile's broadcast intent
+ * Disconnection is asynchronous, so you should listen to each profile's broadcast intent
* ACTION_CONNECTION_STATE_CHANGED to verify whether disconnection was successful. For example,
* to verify a2dp is disconnected, you would listen for
- * {@link BluetoothA2dp#ACTION_CONNECTION_STATE_CHANGED}
+ * {@link BluetoothA2dp#ACTION_CONNECTION_STATE_CHANGED}. Once all profiles have disconnected,
+ * the ACL link should come down and {@link #ACTION_ACL_DISCONNECTED} should be broadcast.
+ * <p>
+ * In the rare event that one or more profiles fail to disconnect, call this method again to
+ * send another request to disconnect each connected profile.
*
* @return whether the messages were successfully sent to try to disconnect all profiles
* @throws IllegalArgumentException if the device address is invalid