diff options
author | Jeff Sharkey <jsharkey@android.com> | 2021-04-29 07:12:20 -0600 |
---|---|---|
committer | Jeff Sharkey <jsharkey@android.com> | 2021-04-29 13:55:07 -0600 |
commit | a2d365484c43a19ab6f67152651d61f3b0667b47 (patch) | |
tree | b1e0d4963d4e9156f3662c1be494a4f332db0ae1 /framework/java/android/bluetooth/BluetoothAdapter.java | |
parent | 19a8d096ae4e76490be422c7033f69896199421c (diff) |
Ensure privileged APIs require runtime permission.
When users revoke a runtime permission, they expect all interactions
to be blocked, including those protected by the BLUETOOTH_PRIVILEGED
permission.
This change finishes applying that policy to any remaining Bluetooth
APIs which didn't already implement it. To keep the implementation
straightforward, this change does "data delivery" checks when
registering for callbacks; the ideal behavior would be to wait
until data is actually delivered through the callbacks, but
RemoteCallbackList doesn't have support for AttributionSource yet.
Bug: 186405452
Test: atest BluetoothInstrumentationTests
Change-Id: Idd7be143eb8baff020a0718065293baae708041b
Diffstat (limited to 'framework/java/android/bluetooth/BluetoothAdapter.java')
-rw-r--r-- | framework/java/android/bluetooth/BluetoothAdapter.java | 104 |
1 files changed, 79 insertions, 25 deletions
diff --git a/framework/java/android/bluetooth/BluetoothAdapter.java b/framework/java/android/bluetooth/BluetoothAdapter.java index 8afc557ef8..67179c7d3e 100644 --- a/framework/java/android/bluetooth/BluetoothAdapter.java +++ b/framework/java/android/bluetooth/BluetoothAdapter.java @@ -1311,11 +1311,15 @@ public final class BluetoothAdapter { * @hide */ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) - @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) + @RequiresBluetoothConnectPermission + @RequiresPermission(allOf = { + android.Manifest.permission.BLUETOOTH_CONNECT, + android.Manifest.permission.BLUETOOTH_PRIVILEGED, + }) public boolean factoryReset() { try { mServiceLock.readLock().lock(); - if (mService != null && mService.factoryReset() + if (mService != null && mService.factoryReset(mAttributionSource) && mManagerService != null && mManagerService.onFactoryReset(mAttributionSource)) { return true; @@ -1430,7 +1434,11 @@ public final class BluetoothAdapter { * * @hide */ - @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) + @RequiresBluetoothConnectPermission + @RequiresPermission(allOf = { + android.Manifest.permission.BLUETOOTH_CONNECT, + android.Manifest.permission.BLUETOOTH_PRIVILEGED, + }) public boolean setBluetoothClass(BluetoothClass bluetoothClass) { if (getState() != STATE_ON) { return false; @@ -1438,7 +1446,7 @@ public final class BluetoothAdapter { try { mServiceLock.readLock().lock(); if (mService != null) { - return mService.setBluetoothClass(bluetoothClass); + return mService.setBluetoothClass(bluetoothClass, mAttributionSource); } } catch (RemoteException e) { Log.e(TAG, "", e); @@ -1487,12 +1495,16 @@ public final class BluetoothAdapter { * * @hide */ - @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) + @RequiresBluetoothConnectPermission + @RequiresPermission(allOf = { + android.Manifest.permission.BLUETOOTH_CONNECT, + android.Manifest.permission.BLUETOOTH_PRIVILEGED, + }) public boolean setIoCapability(@IoCapability int capability) { if (getState() != STATE_ON) return false; try { mServiceLock.readLock().lock(); - if (mService != null) return mService.setIoCapability(capability); + if (mService != null) return mService.setIoCapability(capability, mAttributionSource); } catch (RemoteException e) { Log.e(TAG, e.getMessage(), e); } finally { @@ -1540,12 +1552,16 @@ public final class BluetoothAdapter { * * @hide */ - @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) + @RequiresBluetoothConnectPermission + @RequiresPermission(allOf = { + android.Manifest.permission.BLUETOOTH_CONNECT, + android.Manifest.permission.BLUETOOTH_PRIVILEGED, + }) public boolean setLeIoCapability(@IoCapability int capability) { if (getState() != STATE_ON) return false; try { mServiceLock.readLock().lock(); - if (mService != null) return mService.setLeIoCapability(capability); + if (mService != null) return mService.setLeIoCapability(capability, mAttributionSource); } catch (RemoteException e) { Log.e(TAG, e.getMessage(), e); } finally { @@ -1739,12 +1755,16 @@ public final class BluetoothAdapter { * @hide */ @SystemApi - @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) + @RequiresBluetoothConnectPermission + @RequiresPermission(allOf = { + android.Manifest.permission.BLUETOOTH_CONNECT, + android.Manifest.permission.BLUETOOTH_PRIVILEGED, + }) public long getDiscoveryEndMillis() { try { mServiceLock.readLock().lock(); if (mService != null) { - return mService.getDiscoveryEndMillis(); + return mService.getDiscoveryEndMillis(mAttributionSource); } } catch (RemoteException e) { Log.e(TAG, "", e); @@ -2353,7 +2373,11 @@ public final class BluetoothAdapter { * instead. */ @Deprecated - @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) + @RequiresBluetoothConnectPermission + @RequiresPermission(allOf = { + android.Manifest.permission.BLUETOOTH_CONNECT, + android.Manifest.permission.BLUETOOTH_PRIVILEGED, + }) public BluetoothActivityEnergyInfo getControllerActivityEnergyInfo(int updateType) { SynchronousResultReceiver receiver = new SynchronousResultReceiver(); requestControllerActivityEnergyInfo(receiver); @@ -2379,12 +2403,16 @@ public final class BluetoothAdapter { * @param result The callback to which to send the activity info. * @hide */ - @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) + @RequiresBluetoothConnectPermission + @RequiresPermission(allOf = { + android.Manifest.permission.BLUETOOTH_CONNECT, + android.Manifest.permission.BLUETOOTH_PRIVILEGED, + }) public void requestControllerActivityEnergyInfo(ResultReceiver result) { try { mServiceLock.readLock().lock(); if (mService != null) { - mService.requestActivityInfo(result); + mService.requestActivityInfo(result, mAttributionSource); result = null; } } catch (RemoteException e) { @@ -3141,7 +3169,7 @@ public final class BluetoothAdapter { sMetadataListeners.forEach((device, pair) -> { try { mService.registerMetadataListener(sBluetoothMetadataListener, - device); + device, mAttributionSource); } catch (RemoteException e) { Log.e(TAG, "Failed to register metadata listener", e); } @@ -3150,7 +3178,8 @@ public final class BluetoothAdapter { synchronized (mBluetoothConnectionCallbackExecutorMap) { if (!mBluetoothConnectionCallbackExecutorMap.isEmpty()) { try { - mService.registerBluetoothConnectionCallback(mConnectionCallback); + mService.registerBluetoothConnectionCallback(mConnectionCallback, + mAttributionSource); } catch (RemoteException e) { Log.e(TAG, "onBluetoothServiceUp: Failed to register bluetooth" + "connection callback", e); @@ -3364,7 +3393,11 @@ public final class BluetoothAdapter { * @hide */ @SystemApi - @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) + @RequiresBluetoothConnectPermission + @RequiresPermission(allOf = { + android.Manifest.permission.BLUETOOTH_CONNECT, + android.Manifest.permission.BLUETOOTH_PRIVILEGED, + }) public void generateLocalOobData(@Transport int transport, @NonNull @CallbackExecutor Executor executor, @NonNull OobDataCallback callback) { if (transport != BluetoothDevice.TRANSPORT_BREDR && transport @@ -3378,7 +3411,7 @@ public final class BluetoothAdapter { } else { try { mService.generateLocalOobData(transport, new WrappedOobDataCallback(callback, - executor)); + executor), mAttributionSource); } catch (RemoteException e) { Log.e(TAG, "", e); } @@ -3515,11 +3548,13 @@ public final class BluetoothAdapter { /** {@hide} */ @UnsupportedAppUsage + @RequiresNoPermission public IBluetoothManager getBluetoothManager() { return mManagerService; } /** {@hide} */ + @RequiresNoPermission public AttributionSource getAttributionSource() { return mAttributionSource; } @@ -3892,7 +3927,11 @@ public final class BluetoothAdapter { * @hide */ @SystemApi - @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) + @RequiresBluetoothConnectPermission + @RequiresPermission(allOf = { + android.Manifest.permission.BLUETOOTH_CONNECT, + android.Manifest.permission.BLUETOOTH_PRIVILEGED, + }) public boolean addOnMetadataChangedListener(@NonNull BluetoothDevice device, @NonNull Executor executor, @NonNull OnMetadataChangedListener listener) { if (DBG) Log.d(TAG, "addOnMetadataChangedListener()"); @@ -3932,7 +3971,8 @@ public final class BluetoothAdapter { boolean ret = false; try { - ret = service.registerMetadataListener(sBluetoothMetadataListener, device); + ret = service.registerMetadataListener(sBluetoothMetadataListener, device, + mAttributionSource); } catch (RemoteException e) { Log.e(TAG, "registerMetadataListener fail", e); } finally { @@ -3965,7 +4005,11 @@ public final class BluetoothAdapter { * @hide */ @SystemApi - @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) + @RequiresBluetoothConnectPermission + @RequiresPermission(allOf = { + android.Manifest.permission.BLUETOOTH_CONNECT, + android.Manifest.permission.BLUETOOTH_PRIVILEGED, + }) public boolean removeOnMetadataChangedListener(@NonNull BluetoothDevice device, @NonNull OnMetadataChangedListener listener) { if (DBG) Log.d(TAG, "removeOnMetadataChangedListener()"); @@ -3993,7 +4037,7 @@ public final class BluetoothAdapter { return true; } try { - return service.unregisterMetadataListener(device); + return service.unregisterMetadataListener(device, mAttributionSource); } catch (RemoteException e) { Log.e(TAG, "unregisterMetadataListener fail", e); return false; @@ -4055,7 +4099,11 @@ public final class BluetoothAdapter { * @throws IllegalArgumentException if the callback is already registered * @hide */ - @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) + @RequiresBluetoothConnectPermission + @RequiresPermission(allOf = { + android.Manifest.permission.BLUETOOTH_CONNECT, + android.Manifest.permission.BLUETOOTH_PRIVILEGED, + }) public boolean registerBluetoothConnectionCallback(@NonNull @CallbackExecutor Executor executor, @NonNull BluetoothConnectionCallback callback) { if (DBG) Log.d(TAG, "registerBluetoothConnectionCallback()"); @@ -4069,7 +4117,8 @@ public final class BluetoothAdapter { try { mServiceLock.readLock().lock(); if (mService != null) { - if (!mService.registerBluetoothConnectionCallback(mConnectionCallback)) { + if (!mService.registerBluetoothConnectionCallback(mConnectionCallback, + mAttributionSource)) { return false; } } @@ -4098,7 +4147,11 @@ public final class BluetoothAdapter { * @return true if the callback was unregistered successfully, false otherwise * @hide */ - @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) + @RequiresBluetoothConnectPermission + @RequiresPermission(allOf = { + android.Manifest.permission.BLUETOOTH_CONNECT, + android.Manifest.permission.BLUETOOTH_PRIVILEGED, + }) public boolean unregisterBluetoothConnectionCallback( @NonNull BluetoothConnectionCallback callback) { if (DBG) Log.d(TAG, "unregisterBluetoothConnectionCallback()"); @@ -4120,7 +4173,8 @@ public final class BluetoothAdapter { try { mServiceLock.readLock().lock(); if (mService != null) { - return mService.unregisterBluetoothConnectionCallback(mConnectionCallback); + return mService.unregisterBluetoothConnectionCallback(mConnectionCallback, + mAttributionSource); } } catch (RemoteException e) { Log.e(TAG, "", e); |