diff options
Diffstat (limited to 'framework/java/android/bluetooth/BluetoothDevice.java')
| -rw-r--r-- | framework/java/android/bluetooth/BluetoothDevice.java | 147 |
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 |
