From 655d691d65c6b55a28a9a751fa2515f502f9d585 Mon Sep 17 00:00:00 2001
From: Jeff Sharkey
Date: Fri, 16 Apr 2021 15:34:54 -0600
Subject: [PATCH] Add missing Bluetooth API permission enforcement.
Recent work has been using Error Prone rules and annotations to
reflect the current state of permission enforcement across the
Bluetooth stack, and we're now in a position were we can add new
permission enforcement that had been missing.
We've currently standardized on saying that APIs that return device
or Bluetooth state information (without sharing details about any
particular remote Bluetooth device) do not need to be permission
protected.
Bug: 183626724
Test: ./build/soong/soong_ui.bash --make-mode Bluetooth RUN_ERROR_PRONE=true
Change-Id: I37a9e03ecdca6f7a6eb9d7f094e2f95a97036612
---
core/java/android/bluetooth/BluetoothA2dpSink.java | 8 ++++++++
.../android/bluetooth/BluetoothAvrcpController.java | 12 ++++++++++++
.../android/bluetooth/BluetoothHeadsetClient.java | 8 ++++++++
core/java/android/bluetooth/BluetoothHearingAid.java | 6 ++++++
core/java/android/bluetooth/BluetoothLeAudio.java | 4 ++++
.../android/bluetooth/le/BluetoothLeScanner.java | 3 +++
.../com/android/server/BluetoothManagerService.java | 3 ---
7 files changed, 41 insertions(+), 3 deletions(-)
diff --git a/core/java/android/bluetooth/BluetoothA2dpSink.java b/core/java/android/bluetooth/BluetoothA2dpSink.java
index 6aba483b15158..280e8bc8402b4 100755
--- a/core/java/android/bluetooth/BluetoothA2dpSink.java
+++ b/core/java/android/bluetooth/BluetoothA2dpSink.java
@@ -187,6 +187,8 @@ public final class BluetoothA2dpSink implements BluetoothProfile {
* @hide
*/
@Override
+ @RequiresBluetoothConnectPermission
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public List getConnectedDevices() {
if (VDBG) log("getConnectedDevices()");
final IBluetoothA2dpSink service = getService();
@@ -208,6 +210,8 @@ public final class BluetoothA2dpSink implements BluetoothProfile {
* @hide
*/
@Override
+ @RequiresBluetoothConnectPermission
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public List getDevicesMatchingConnectionStates(int[] states) {
if (VDBG) log("getDevicesMatchingStates()");
final IBluetoothA2dpSink service = getService();
@@ -229,6 +233,8 @@ public final class BluetoothA2dpSink implements BluetoothProfile {
* @hide
*/
@Override
+ @RequiresBluetoothConnectPermission
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public int getConnectionState(BluetoothDevice device) {
if (VDBG) log("getState(" + device + ")");
final IBluetoothA2dpSink service = getService();
@@ -256,6 +262,8 @@ public final class BluetoothA2dpSink implements BluetoothProfile {
* @hide
*/
@RequiresLegacyBluetoothPermission
+ @RequiresBluetoothConnectPermission
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public BluetoothAudioConfig getAudioConfig(BluetoothDevice device) {
if (VDBG) log("getAudioConfig(" + device + ")");
final IBluetoothA2dpSink service = getService();
diff --git a/core/java/android/bluetooth/BluetoothAvrcpController.java b/core/java/android/bluetooth/BluetoothAvrcpController.java
index 887cf3f08b9d0..5148d5b431d76 100644
--- a/core/java/android/bluetooth/BluetoothAvrcpController.java
+++ b/core/java/android/bluetooth/BluetoothAvrcpController.java
@@ -117,6 +117,8 @@ public final class BluetoothAvrcpController implements BluetoothProfile {
* {@inheritDoc}
*/
@Override
+ @RequiresBluetoothConnectPermission
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public List getConnectedDevices() {
if (VDBG) log("getConnectedDevices()");
final IBluetoothAvrcpController service =
@@ -137,6 +139,8 @@ public final class BluetoothAvrcpController implements BluetoothProfile {
* {@inheritDoc}
*/
@Override
+ @RequiresBluetoothConnectPermission
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public List getDevicesMatchingConnectionStates(int[] states) {
if (VDBG) log("getDevicesMatchingStates()");
final IBluetoothAvrcpController service =
@@ -157,6 +161,8 @@ public final class BluetoothAvrcpController implements BluetoothProfile {
* {@inheritDoc}
*/
@Override
+ @RequiresBluetoothConnectPermission
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public int getConnectionState(BluetoothDevice device) {
if (VDBG) log("getState(" + device + ")");
final IBluetoothAvrcpController service =
@@ -178,6 +184,8 @@ public final class BluetoothAvrcpController implements BluetoothProfile {
*
* @return the {@link BluetoothAvrcpPlayerSettings} or {@link null} if there is an error.
*/
+ @RequiresBluetoothConnectPermission
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public BluetoothAvrcpPlayerSettings getPlayerSettings(BluetoothDevice device) {
if (DBG) Log.d(TAG, "getPlayerSettings");
BluetoothAvrcpPlayerSettings settings = null;
@@ -198,6 +206,8 @@ public final class BluetoothAvrcpController implements BluetoothProfile {
* Sets the player app setting for current player.
* returns true in case setting is supported by remote, false otherwise
*/
+ @RequiresBluetoothConnectPermission
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public boolean setPlayerApplicationSetting(BluetoothAvrcpPlayerSettings plAppSetting) {
if (DBG) Log.d(TAG, "setPlayerApplicationSetting");
final IBluetoothAvrcpController service =
@@ -218,6 +228,8 @@ public final class BluetoothAvrcpController implements BluetoothProfile {
* Send Group Navigation Command to Remote.
* possible keycode values: next_grp, previous_grp defined above
*/
+ @RequiresBluetoothConnectPermission
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public void sendGroupNavigationCmd(BluetoothDevice device, int keyCode, int keyState) {
Log.d(TAG, "sendGroupNavigationCmd dev = " + device + " key " + keyCode + " State = "
+ keyState);
diff --git a/core/java/android/bluetooth/BluetoothHeadsetClient.java b/core/java/android/bluetooth/BluetoothHeadsetClient.java
index 5816500d2c37d..eef42d1b2f341 100644
--- a/core/java/android/bluetooth/BluetoothHeadsetClient.java
+++ b/core/java/android/bluetooth/BluetoothHeadsetClient.java
@@ -1038,6 +1038,8 @@ public final class BluetoothHeadsetClient implements BluetoothProfile {
* #EXTRA_AG_FEATURE_ATTACH_NUMBER_TO_VT}. This method invocation will fail silently when
* feature is not supported.
*/
+ @RequiresBluetoothConnectPermission
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public boolean getLastVoiceTagNumber(BluetoothDevice device) {
if (DBG) log("getLastVoiceTagNumber()");
final IBluetoothHeadsetClient service =
@@ -1059,6 +1061,8 @@ public final class BluetoothHeadsetClient implements BluetoothProfile {
* Note: This is an internal function and shouldn't be exposed
*/
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+ @RequiresBluetoothConnectPermission
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public int getAudioState(BluetoothDevice device) {
if (VDBG) log("getAudioState");
final IBluetoothHeadsetClient service =
@@ -1083,6 +1087,8 @@ public final class BluetoothHeadsetClient implements BluetoothProfile {
* @param allowed if routing is allowed to the device Note: This is an internal function and
* shouldn't be exposed
*/
+ @RequiresBluetoothConnectPermission
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public void setAudioRouteAllowed(BluetoothDevice device, boolean allowed) {
if (VDBG) log("setAudioRouteAllowed");
final IBluetoothHeadsetClient service =
@@ -1106,6 +1112,8 @@ public final class BluetoothHeadsetClient implements BluetoothProfile {
* @return whether the command succeeded Note: This is an internal function and shouldn't be
* exposed
*/
+ @RequiresBluetoothConnectPermission
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public boolean getAudioRouteAllowed(BluetoothDevice device) {
if (VDBG) log("getAudioRouteAllowed");
final IBluetoothHeadsetClient service =
diff --git a/core/java/android/bluetooth/BluetoothHearingAid.java b/core/java/android/bluetooth/BluetoothHearingAid.java
index 1fd779a17dbd7..fa52eda8ea61c 100644
--- a/core/java/android/bluetooth/BluetoothHearingAid.java
+++ b/core/java/android/bluetooth/BluetoothHearingAid.java
@@ -497,6 +497,8 @@ public final class BluetoothHearingAid implements BluetoothProfile {
* @param volume Absolute volume to be set on remote
* @hide
*/
+ @RequiresBluetoothConnectPermission
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public void setVolume(int volume) {
if (DBG) Log.d(TAG, "setVolume(" + volume + ")");
@@ -556,6 +558,8 @@ public final class BluetoothHearingAid implements BluetoothProfile {
* @hide
*/
@RequiresLegacyBluetoothPermission
+ @RequiresBluetoothConnectPermission
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public int getDeviceSide(BluetoothDevice device) {
if (VDBG) {
log("getDeviceSide(" + device + ")");
@@ -582,6 +586,8 @@ public final class BluetoothHearingAid implements BluetoothProfile {
* @hide
*/
@RequiresLegacyBluetoothPermission
+ @RequiresBluetoothConnectPermission
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public int getDeviceMode(BluetoothDevice device) {
if (VDBG) {
log("getDeviceMode(" + device + ")");
diff --git a/core/java/android/bluetooth/BluetoothLeAudio.java b/core/java/android/bluetooth/BluetoothLeAudio.java
index c12b1f77fb9e6..462c7b7ede664 100644
--- a/core/java/android/bluetooth/BluetoothLeAudio.java
+++ b/core/java/android/bluetooth/BluetoothLeAudio.java
@@ -325,6 +325,8 @@ public final class BluetoothLeAudio implements BluetoothProfile, AutoCloseable {
*/
@NonNull
@RequiresLegacyBluetoothPermission
+ @RequiresBluetoothConnectPermission
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public List getActiveDevices() {
if (VDBG) log("getActiveDevices()");
try {
@@ -348,6 +350,8 @@ public final class BluetoothLeAudio implements BluetoothProfile, AutoCloseable {
* @hide
*/
@RequiresLegacyBluetoothPermission
+ @RequiresBluetoothConnectPermission
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
public int getGroupId(@NonNull BluetoothDevice device) {
if (VDBG) log("getGroupId()");
try {
diff --git a/core/java/android/bluetooth/le/BluetoothLeScanner.java b/core/java/android/bluetooth/le/BluetoothLeScanner.java
index 09cd11d075906..f27f22b9af5cc 100644
--- a/core/java/android/bluetooth/le/BluetoothLeScanner.java
+++ b/core/java/android/bluetooth/le/BluetoothLeScanner.java
@@ -442,6 +442,7 @@ public final class BluetoothLeScanner {
}
}
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN)
public void stopLeScan() {
synchronized (this) {
if (mScannerId <= 0) {
@@ -458,6 +459,7 @@ public final class BluetoothLeScanner {
}
}
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_SCAN)
void flushPendingBatchResults() {
synchronized (this) {
if (mScannerId <= 0) {
@@ -588,6 +590,7 @@ public final class BluetoothLeScanner {
}
}
+ @SuppressLint("AndroidFrameworkBluetoothPermission")
private void postCallbackError(final ScanCallback callback, final int errorCode) {
mHandler.post(new Runnable() {
@Override
diff --git a/services/core/java/com/android/server/BluetoothManagerService.java b/services/core/java/com/android/server/BluetoothManagerService.java
index feed2205dc419..c3a5d1f871bbb 100644
--- a/services/core/java/com/android/server/BluetoothManagerService.java
+++ b/services/core/java/com/android/server/BluetoothManagerService.java
@@ -714,9 +714,6 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
Slog.w(TAG, "Callback is null in unregisterAdapter");
return;
}
- if (!checkConnectPermissionForPreflight(mContext)) {
- return;
- }
synchronized (mCallbacks) {
mCallbacks.unregister(callback);
}