diff options
Diffstat (limited to 'framework/java/android/bluetooth/BluetoothDevice.java')
| -rw-r--r-- | framework/java/android/bluetooth/BluetoothDevice.java | 207 |
1 files changed, 119 insertions, 88 deletions
diff --git a/framework/java/android/bluetooth/BluetoothDevice.java b/framework/java/android/bluetooth/BluetoothDevice.java index 3040b51ce0..222df3286a 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; - if (service == null) { + final String defaultValue = null; + if (service == null || !isBluetoothEnabled()) { 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; } /** @@ -1505,7 +1520,7 @@ public final class BluetoothDevice implements Parcelable, Attributable { if (DBG) log("getName()"); final IBluetooth service = sService; final String defaultValue = null; - if (service == null) { + if (service == null || !isBluetoothEnabled()) { Log.e(TAG, "BT not enabled. Cannot get Remote Device name"); if (DBG) log(Log.getStackTraceString(new Throwable())); } else { @@ -1540,7 +1555,7 @@ public final class BluetoothDevice implements Parcelable, Attributable { if (DBG) log("getType()"); final IBluetooth service = sService; final int defaultValue = DEVICE_TYPE_UNKNOWN; - if (service == null) { + if (service == null || !isBluetoothEnabled()) { Log.e(TAG, "BT not enabled. Cannot get Remote Device type"); if (DBG) log(Log.getStackTraceString(new Throwable())); } else { @@ -1569,7 +1584,7 @@ public final class BluetoothDevice implements Parcelable, Attributable { if (DBG) log("getAlias()"); final IBluetooth service = sService; final String defaultValue = null; - if (service == null) { + if (service == null || !isBluetoothEnabled()) { Log.e(TAG, "BT not enabled. Cannot get Remote Device Alias"); if (DBG) log(Log.getStackTraceString(new Throwable())); } else { @@ -1630,7 +1645,7 @@ public final class BluetoothDevice implements Parcelable, Attributable { if (DBG) log("setAlias(" + alias + ")"); final IBluetooth service = sService; final int defaultValue = BluetoothStatusCodes.ERROR_BLUETOOTH_NOT_ENABLED; - if (service == null) { + if (service == null || !isBluetoothEnabled()) { Log.e(TAG, "BT not enabled. Cannot set Remote Device name"); if (DBG) log(Log.getStackTraceString(new Throwable())); } else { @@ -1664,7 +1679,7 @@ public final class BluetoothDevice implements Parcelable, Attributable { if (DBG) log("getBatteryLevel()"); final IBluetooth service = sService; final int defaultValue = BATTERY_LEVEL_BLUETOOTH_OFF; - if (service == null) { + if (service == null || !isBluetoothEnabled()) { Log.e(TAG, "Bluetooth disabled. Cannot get remote device battery level"); if (DBG) log(Log.getStackTraceString(new Throwable())); } else { @@ -1759,7 +1774,7 @@ public final class BluetoothDevice implements Parcelable, Attributable { if (DBG) log("createBondOutOfBand()"); final IBluetooth service = sService; final boolean defaultValue = false; - if (service == null) { + if (service == null || !isBluetoothEnabled()) { Log.w(TAG, "BT not enabled, createBondOutOfBand failed"); if (DBG) log(Log.getStackTraceString(new Throwable())); } else if (NULL_MAC_ADDRESS.equals(mAddress)) { @@ -1792,7 +1807,7 @@ public final class BluetoothDevice implements Parcelable, Attributable { if (DBG) log("isBondingInitiatedLocally()"); final IBluetooth service = sService; final boolean defaultValue = false; - if (service == null) { + if (service == null || !isBluetoothEnabled()) { Log.w(TAG, "BT not enabled, isBondingInitiatedLocally failed"); if (DBG) log(Log.getStackTraceString(new Throwable())); } else { @@ -1819,7 +1834,7 @@ public final class BluetoothDevice implements Parcelable, Attributable { if (DBG) log("cancelBondProcess()"); final IBluetooth service = sService; final boolean defaultValue = false; - if (service == null) { + if (service == null || !isBluetoothEnabled()) { Log.e(TAG, "BT not enabled. Cannot cancel Remote Device bond"); if (DBG) log(Log.getStackTraceString(new Throwable())); } else { @@ -1852,7 +1867,7 @@ public final class BluetoothDevice implements Parcelable, Attributable { if (DBG) log("removeBond()"); final IBluetooth service = sService; final boolean defaultValue = false; - if (service == null) { + if (service == null || !isBluetoothEnabled()) { Log.e(TAG, "BT not enabled. Cannot remove Remote Device bond"); if (DBG) log(Log.getStackTraceString(new Throwable())); } else { @@ -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 || !isBluetoothEnabled()) { + 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); } /** @@ -1959,7 +1986,7 @@ public final class BluetoothDevice implements Parcelable, Attributable { if (DBG) log("canBondWithoutDialog, device: " + this); final IBluetooth service = sService; final boolean defaultValue = false; - if (service == null) { + if (service == null || !isBluetoothEnabled()) { Log.e(TAG, "BT not enabled. Cannot check if we can skip pairing dialog"); if (DBG) log(Log.getStackTraceString(new Throwable())); } else { @@ -2013,7 +2040,7 @@ public final class BluetoothDevice implements Parcelable, Attributable { } final IBluetooth service = sService; final int defaultValue = BluetoothStatusCodes.ERROR_BLUETOOTH_NOT_ENABLED; - if (service == null) { + if (service == null || !isBluetoothEnabled()) { Log.e(TAG, "BT not enabled. Cannot connect to remote device."); if (DBG) log(Log.getStackTraceString(new Throwable())); } else { @@ -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 @@ -2056,7 +2087,7 @@ public final class BluetoothDevice implements Parcelable, Attributable { } final IBluetooth service = sService; final int defaultValue = BluetoothStatusCodes.ERROR_BLUETOOTH_NOT_ENABLED; - if (service == null) { + if (service == null || !isBluetoothEnabled()) { Log.e(TAG, "BT not enabled. Cannot disconnect to remote device."); if (DBG) log(Log.getStackTraceString(new Throwable())); } else { @@ -2088,7 +2119,7 @@ public final class BluetoothDevice implements Parcelable, Attributable { if (DBG) log("isConnected()"); final IBluetooth service = sService; final int defaultValue = CONNECTION_STATE_DISCONNECTED; - if (service == null) { + if (service == null || !isBluetoothEnabled()) { Log.w(TAG, "Proxy not attached to service"); if (DBG) log(Log.getStackTraceString(new Throwable())); } else { @@ -2120,7 +2151,7 @@ public final class BluetoothDevice implements Parcelable, Attributable { if (DBG) log("isEncrypted()"); final IBluetooth service = sService; final int defaultValue = CONNECTION_STATE_DISCONNECTED; - if (service == null) { + if (service == null || !isBluetoothEnabled()) { Log.w(TAG, "Proxy not attached to service"); if (DBG) log(Log.getStackTraceString(new Throwable())); } else { @@ -2149,7 +2180,7 @@ public final class BluetoothDevice implements Parcelable, Attributable { if (DBG) log("getBluetoothClass()"); final IBluetooth service = sService; final int defaultValue = 0; - if (service == null) { + if (service == null || !isBluetoothEnabled()) { Log.e(TAG, "BT not enabled. Cannot get Bluetooth Class"); if (DBG) log(Log.getStackTraceString(new Throwable())); } else { @@ -2292,7 +2323,7 @@ public final class BluetoothDevice implements Parcelable, Attributable { if (DBG) log("sdpSearch()"); final IBluetooth service = sService; final boolean defaultValue = false; - if (service == null) { + if (service == null || !isBluetoothEnabled()) { Log.e(TAG, "BT not enabled. Cannot query remote device sdp records"); if (DBG) log(Log.getStackTraceString(new Throwable())); } else { @@ -2319,7 +2350,7 @@ public final class BluetoothDevice implements Parcelable, Attributable { if (DBG) log("setPin()"); final IBluetooth service = sService; final boolean defaultValue = false; - if (service == null) { + if (service == null || !isBluetoothEnabled()) { Log.e(TAG, "BT not enabled. Cannot set Remote Device pin"); if (DBG) log(Log.getStackTraceString(new Throwable())); } else { @@ -2365,7 +2396,7 @@ public final class BluetoothDevice implements Parcelable, Attributable { if (DBG) log("setPairingConfirmation()"); final IBluetooth service = sService; final boolean defaultValue = false; - if (service == null) { + if (service == null || !isBluetoothEnabled()) { Log.e(TAG, "BT not enabled. Cannot set pairing confirmation"); if (DBG) log(Log.getStackTraceString(new Throwable())); } else { @@ -2404,7 +2435,7 @@ public final class BluetoothDevice implements Parcelable, Attributable { if (DBG) log("getPhonebookAccessPermission()"); final IBluetooth service = sService; final int defaultValue = ACCESS_UNKNOWN; - if (service == null) { + if (service == null || !isBluetoothEnabled()) { Log.w(TAG, "Proxy not attached to service"); if (DBG) log(Log.getStackTraceString(new Throwable())); } else { @@ -2451,7 +2482,7 @@ public final class BluetoothDevice implements Parcelable, Attributable { if (DBG) log("setSilenceMode()"); final IBluetooth service = sService; final boolean defaultValue = false; - if (service == null) { + if (service == null || !isBluetoothEnabled()) { throw new IllegalStateException("Bluetooth is not turned ON"); } else { try { @@ -2481,7 +2512,7 @@ public final class BluetoothDevice implements Parcelable, Attributable { if (DBG) log("isInSilenceMode()"); final IBluetooth service = sService; final boolean defaultValue = false; - if (service == null) { + if (service == null || !isBluetoothEnabled()) { throw new IllegalStateException("Bluetooth is not turned ON"); } else { try { @@ -2512,7 +2543,7 @@ public final class BluetoothDevice implements Parcelable, Attributable { if (DBG) log("setPhonebookAccessPermission()"); final IBluetooth service = sService; final boolean defaultValue = false; - if (service == null) { + if (service == null || !isBluetoothEnabled()) { Log.w(TAG, "Proxy not attached to service"); if (DBG) log(Log.getStackTraceString(new Throwable())); } else { @@ -2541,7 +2572,7 @@ public final class BluetoothDevice implements Parcelable, Attributable { if (DBG) log("getMessageAccessPermission()"); final IBluetooth service = sService; final int defaultValue = ACCESS_UNKNOWN; - if (service == null) { + if (service == null || !isBluetoothEnabled()) { Log.w(TAG, "Proxy not attached to service"); if (DBG) log(Log.getStackTraceString(new Throwable())); } else { @@ -2578,7 +2609,7 @@ public final class BluetoothDevice implements Parcelable, Attributable { if (DBG) log("setMessageAccessPermission()"); final IBluetooth service = sService; final boolean defaultValue = false; - if (service == null) { + if (service == null || !isBluetoothEnabled()) { Log.w(TAG, "Proxy not attached to service"); if (DBG) log(Log.getStackTraceString(new Throwable())); } else { @@ -2607,7 +2638,7 @@ public final class BluetoothDevice implements Parcelable, Attributable { if (DBG) log("getSimAccessPermission()"); final IBluetooth service = sService; final int defaultValue = ACCESS_UNKNOWN; - if (service == null) { + if (service == null || !isBluetoothEnabled()) { Log.w(TAG, "Proxy not attached to service"); if (DBG) log(Log.getStackTraceString(new Throwable())); } else { @@ -2640,7 +2671,7 @@ public final class BluetoothDevice implements Parcelable, Attributable { if (DBG) log("setSimAccessPermission()"); final IBluetooth service = sService; final boolean defaultValue = false; - if (service == null) { + if (service == null || !isBluetoothEnabled()) { Log.w(TAG, "Proxy not attached to service"); if (DBG) log(Log.getStackTraceString(new Throwable())); } else { @@ -3151,7 +3182,7 @@ public final class BluetoothDevice implements Parcelable, Attributable { if (DBG) log("setMetadata()"); final IBluetooth service = sService; final boolean defaultValue = false; - if (service == null) { + if (service == null || !isBluetoothEnabled()) { Log.e(TAG, "Bluetooth is not enabled. Cannot set metadata"); if (DBG) log(Log.getStackTraceString(new Throwable())); } else if (value.length > METADATA_MAX_LENGTH) { @@ -3186,7 +3217,7 @@ public final class BluetoothDevice implements Parcelable, Attributable { if (DBG) log("getMetadata()"); final IBluetooth service = sService; final byte[] defaultValue = null; - if (service == null) { + if (service == null || !isBluetoothEnabled()) { Log.e(TAG, "Bluetooth is not enabled. Cannot get metadata"); if (DBG) log(Log.getStackTraceString(new Throwable())); } else { @@ -3229,7 +3260,7 @@ public final class BluetoothDevice implements Parcelable, Attributable { if (DBG) log("setLowLatencyAudioAllowed(" + allowed + ")"); final IBluetooth service = sService; final boolean defaultValue = false; - if (service == null) { + if (service == null || !isBluetoothEnabled()) { Log.e(TAG, "Bluetooth is not enabled. Cannot allow low latency"); if (DBG) log(Log.getStackTraceString(new Throwable())); } else { |
