API Review: Update api for S+: Throw / Privileged
> Please throw the exception for apps targeting S+.
> You don't seem to be using any privileged permission:
> please either make the API a public API or enforce the permission for
> apps targeting S+ (check go/android-api-types)
Bug: 222434921
Tag: #refactor
Test: build
Change-Id: I002b972b3a1fd5cd0b1af8aae81a49124fc9273d
diff --git a/android/app/src/com/android/bluetooth/a2dp/A2dpService.java b/android/app/src/com/android/bluetooth/a2dp/A2dpService.java
index 9cefc03..27cd1ba 100644
--- a/android/app/src/com/android/bluetooth/a2dp/A2dpService.java
+++ b/android/app/src/com/android/bluetooth/a2dp/A2dpService.java
@@ -18,6 +18,7 @@
import static android.Manifest.permission.BLUETOOTH_CONNECT;
+import static com.android.bluetooth.Utils.checkCallerTargetSdk;
import static com.android.bluetooth.Utils.enforceBluetoothPrivilegedPermission;
import android.annotation.RequiresPermission;
@@ -38,6 +39,7 @@
import android.content.IntentFilter;
import android.media.AudioManager;
import android.media.BluetoothProfileConnectionInfo;
+import android.os.Build;
import android.os.HandlerThread;
import android.util.Log;
@@ -1428,6 +1430,7 @@
if (service == null) {
return;
}
+ enforceBluetoothPrivilegedPermission(service);
service.setAvrcpAbsoluteVolume(volume);
}
@@ -1453,6 +1456,10 @@
A2dpService service = getService(source);
BluetoothCodecStatus codecStatus = null;
if (service != null) {
+ if (checkCallerTargetSdk(mService, source.getPackageName(),
+ Build.VERSION_CODES.TIRAMISU)) {
+ enforceBluetoothPrivilegedPermission(service);
+ }
codecStatus = service.getCodecStatus(device);
}
receiver.send(codecStatus);
@@ -1468,6 +1475,10 @@
if (service == null) {
return;
}
+ if (checkCallerTargetSdk(mService, source.getPackageName(),
+ Build.VERSION_CODES.TIRAMISU)) {
+ enforceBluetoothPrivilegedPermission(service);
+ }
service.setCodecConfigPreference(device, codecConfig);
}
@@ -1477,6 +1488,10 @@
if (service == null) {
return;
}
+ if (checkCallerTargetSdk(mService, source.getPackageName(),
+ Build.VERSION_CODES.TIRAMISU)) {
+ enforceBluetoothPrivilegedPermission(service);
+ }
service.enableOptionalCodecs(device);
}
@@ -1486,16 +1501,24 @@
if (service == null) {
return;
}
+ if (checkCallerTargetSdk(mService, source.getPackageName(),
+ Build.VERSION_CODES.TIRAMISU)) {
+ enforceBluetoothPrivilegedPermission(service);
+ }
service.disableOptionalCodecs(device);
}
@Override
- public void supportsOptionalCodecs(BluetoothDevice device, AttributionSource source,
+ public void isOptionalCodecsSupported(BluetoothDevice device, AttributionSource source,
SynchronousResultReceiver receiver) {
try {
A2dpService service = getService(source);
int codecSupport = BluetoothA2dp.OPTIONAL_CODECS_SUPPORT_UNKNOWN;
if (service != null) {
+ if (checkCallerTargetSdk(mService, source.getPackageName(),
+ Build.VERSION_CODES.TIRAMISU)) {
+ enforceBluetoothPrivilegedPermission(service);
+ }
codecSupport = service.getSupportsOptionalCodecs(device);
}
receiver.send(codecSupport);
@@ -1505,12 +1528,16 @@
}
@Override
- public void getOptionalCodecsEnabled(BluetoothDevice device, AttributionSource source,
+ public void isOptionalCodecsEnabled(BluetoothDevice device, AttributionSource source,
SynchronousResultReceiver receiver) {
try {
A2dpService service = getService(source);
int optionalCodecEnabled = BluetoothA2dp.OPTIONAL_CODECS_PREF_UNKNOWN;
if (service != null) {
+ if (checkCallerTargetSdk(mService, source.getPackageName(),
+ Build.VERSION_CODES.TIRAMISU)) {
+ enforceBluetoothPrivilegedPermission(service);
+ }
optionalCodecEnabled = service.getOptionalCodecsEnabled(device);
}
receiver.send(optionalCodecEnabled);
@@ -1526,6 +1553,10 @@
if (service == null) {
return;
}
+ if (checkCallerTargetSdk(mService, source.getPackageName(),
+ Build.VERSION_CODES.TIRAMISU)) {
+ enforceBluetoothPrivilegedPermission(service);
+ }
service.setOptionalCodecsEnabled(device, value);
}
diff --git a/framework/api/system-current.txt b/framework/api/system-current.txt
index 282b7ee..af44fc6 100644
--- a/framework/api/system-current.txt
+++ b/framework/api/system-current.txt
@@ -2,19 +2,19 @@
package android.bluetooth {
public final class BluetoothA2dp implements android.bluetooth.BluetoothProfile {
- method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public void disableOptionalCodecs(@NonNull android.bluetooth.BluetoothDevice);
- method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public void enableOptionalCodecs(@NonNull android.bluetooth.BluetoothDevice);
+ method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public void disableOptionalCodecs(@NonNull android.bluetooth.BluetoothDevice);
+ method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public void enableOptionalCodecs(@NonNull android.bluetooth.BluetoothDevice);
method @Nullable @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public android.bluetooth.BufferConstraints getBufferConstraints();
- method @Nullable @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public android.bluetooth.BluetoothCodecStatus getCodecStatus(@NonNull android.bluetooth.BluetoothDevice);
+ method @Nullable @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public android.bluetooth.BluetoothCodecStatus getCodecStatus(@NonNull android.bluetooth.BluetoothDevice);
method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public int getConnectionPolicy(@NonNull android.bluetooth.BluetoothDevice);
method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public int getDynamicBufferSupport();
- method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public int isOptionalCodecsEnabled(@NonNull android.bluetooth.BluetoothDevice);
- method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public int isOptionalCodecsSupported(@NonNull android.bluetooth.BluetoothDevice);
+ method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public int isOptionalCodecsEnabled(@NonNull android.bluetooth.BluetoothDevice);
+ method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public int isOptionalCodecsSupported(@NonNull android.bluetooth.BluetoothDevice);
method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public void setAvrcpAbsoluteVolume(int);
method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public boolean setBufferLengthMillis(int, int);
- method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public void setCodecConfigPreference(@NonNull android.bluetooth.BluetoothDevice, @NonNull android.bluetooth.BluetoothCodecConfig);
+ method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public void setCodecConfigPreference(@NonNull android.bluetooth.BluetoothDevice, @NonNull android.bluetooth.BluetoothCodecConfig);
method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public boolean setConnectionPolicy(@NonNull android.bluetooth.BluetoothDevice, int);
- method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public void setOptionalCodecsEnabled(@NonNull android.bluetooth.BluetoothDevice, int);
+ method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public void setOptionalCodecsEnabled(@NonNull android.bluetooth.BluetoothDevice, int);
field @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public static final String ACTION_ACTIVE_DEVICE_CHANGED = "android.bluetooth.a2dp.profile.action.ACTIVE_DEVICE_CHANGED";
field @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public static final String ACTION_CODEC_CONFIG_CHANGED = "android.bluetooth.a2dp.profile.action.CODEC_CONFIG_CHANGED";
field public static final int DYNAMIC_BUFFER_SUPPORT_A2DP_OFFLOAD = 1; // 0x1
diff --git a/framework/java/android/bluetooth/BluetoothA2dp.java b/framework/java/android/bluetooth/BluetoothA2dp.java
index 6c15925..6022058 100644
--- a/framework/java/android/bluetooth/BluetoothA2dp.java
+++ b/framework/java/android/bluetooth/BluetoothA2dp.java
@@ -780,7 +780,10 @@
@Nullable
@RequiresLegacyBluetoothPermission
@RequiresBluetoothConnectPermission
- @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
+ @RequiresPermission(allOf = {
+ android.Manifest.permission.BLUETOOTH_CONNECT,
+ android.Manifest.permission.BLUETOOTH_PRIVILEGED,
+ })
public BluetoothCodecStatus getCodecStatus(@NonNull BluetoothDevice device) {
if (DBG) Log.d(TAG, "getCodecStatus(" + device + ")");
verifyDeviceNotNull(device, "getCodecStatus");
@@ -812,7 +815,10 @@
@SystemApi
@RequiresLegacyBluetoothPermission
@RequiresBluetoothConnectPermission
- @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
+ @RequiresPermission(allOf = {
+ android.Manifest.permission.BLUETOOTH_CONNECT,
+ android.Manifest.permission.BLUETOOTH_PRIVILEGED,
+ })
public void setCodecConfigPreference(@NonNull BluetoothDevice device,
@NonNull BluetoothCodecConfig codecConfig) {
if (DBG) Log.d(TAG, "setCodecConfigPreference(" + device + ")");
@@ -848,7 +854,10 @@
@SystemApi
@RequiresLegacyBluetoothPermission
@RequiresBluetoothConnectPermission
- @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
+ @RequiresPermission(allOf = {
+ android.Manifest.permission.BLUETOOTH_CONNECT,
+ android.Manifest.permission.BLUETOOTH_PRIVILEGED,
+ })
public void enableOptionalCodecs(@NonNull BluetoothDevice device) {
if (DBG) Log.d(TAG, "enableOptionalCodecs(" + device + ")");
verifyDeviceNotNull(device, "enableOptionalCodecs");
@@ -870,7 +879,10 @@
@SystemApi
@RequiresLegacyBluetoothPermission
@RequiresBluetoothConnectPermission
- @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
+ @RequiresPermission(allOf = {
+ android.Manifest.permission.BLUETOOTH_CONNECT,
+ android.Manifest.permission.BLUETOOTH_PRIVILEGED,
+ })
public void disableOptionalCodecs(@NonNull BluetoothDevice device) {
if (DBG) Log.d(TAG, "disableOptionalCodecs(" + device + ")");
verifyDeviceNotNull(device, "disableOptionalCodecs");
@@ -883,7 +895,10 @@
* @param device the remote Bluetooth device.
* @param enable if true, enable the optional codecs, otherwise disable them
*/
- @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
+ @RequiresPermission(allOf = {
+ android.Manifest.permission.BLUETOOTH_CONNECT,
+ android.Manifest.permission.BLUETOOTH_PRIVILEGED,
+ })
private void enableDisableOptionalCodecs(BluetoothDevice device, boolean enable) {
final IBluetoothA2dp service = getService();
if (service == null) {
@@ -914,7 +929,10 @@
@SystemApi
@RequiresLegacyBluetoothAdminPermission
@RequiresBluetoothConnectPermission
- @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
+ @RequiresPermission(allOf = {
+ android.Manifest.permission.BLUETOOTH_CONNECT,
+ android.Manifest.permission.BLUETOOTH_PRIVILEGED,
+ })
public @OptionalCodecsSupportStatus int isOptionalCodecsSupported(
@NonNull BluetoothDevice device) {
if (DBG) log("isOptionalCodecsSupported(" + device + ")");
@@ -927,7 +945,7 @@
} else if (isEnabled() && isValidDevice(device)) {
try {
final SynchronousResultReceiver<Integer> recv = new SynchronousResultReceiver();
- service.supportsOptionalCodecs(device, mAttributionSource, recv);
+ service.isOptionalCodecsSupported(device, mAttributionSource, recv);
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
} catch (RemoteException | TimeoutException e) {
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
@@ -948,7 +966,10 @@
@SystemApi
@RequiresLegacyBluetoothAdminPermission
@RequiresBluetoothConnectPermission
- @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
+ @RequiresPermission(allOf = {
+ android.Manifest.permission.BLUETOOTH_CONNECT,
+ android.Manifest.permission.BLUETOOTH_PRIVILEGED,
+ })
public @OptionalCodecsPreferenceStatus int isOptionalCodecsEnabled(
@NonNull BluetoothDevice device) {
if (DBG) log("isOptionalCodecsEnabled(" + device + ")");
@@ -961,7 +982,7 @@
} else if (isEnabled() && isValidDevice(device)) {
try {
final SynchronousResultReceiver<Integer> recv = new SynchronousResultReceiver();
- service.getOptionalCodecsEnabled(device, mAttributionSource, recv);
+ service.isOptionalCodecsEnabled(device, mAttributionSource, recv);
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
} catch (RemoteException | TimeoutException e) {
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
@@ -983,7 +1004,10 @@
@SystemApi
@RequiresLegacyBluetoothAdminPermission
@RequiresBluetoothConnectPermission
- @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
+ @RequiresPermission(allOf = {
+ android.Manifest.permission.BLUETOOTH_CONNECT,
+ android.Manifest.permission.BLUETOOTH_PRIVILEGED,
+ })
public void setOptionalCodecsEnabled(@NonNull BluetoothDevice device,
@OptionalCodecsPreferenceStatus int value) {
if (DBG) log("setOptionalCodecsEnabled(" + device + ")");
@@ -992,6 +1016,9 @@
&& value != BluetoothA2dp.OPTIONAL_CODECS_PREF_DISABLED
&& value != BluetoothA2dp.OPTIONAL_CODECS_PREF_ENABLED) {
Log.e(TAG, "Invalid value passed to setOptionalCodecsEnabled: " + value);
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
+ throw new IllegalArgumentException("Invalid codec preference");
+ }
return;
}
final IBluetoothA2dp service = getService();
diff --git a/system/binder/android/bluetooth/IBluetoothA2dp.aidl b/system/binder/android/bluetooth/IBluetoothA2dp.aidl
index 8745407..3e38a29 100644
--- a/system/binder/android/bluetooth/IBluetoothA2dp.aidl
+++ b/system/binder/android/bluetooth/IBluetoothA2dp.aidl
@@ -66,23 +66,23 @@
void getConnectionPolicy(in BluetoothDevice device, in AttributionSource attributionSource, in SynchronousResultReceiver receiver);
@JavaPassthrough(annotation="@android.annotation.RequiresNoPermission")
void isAvrcpAbsoluteVolumeSupported(in SynchronousResultReceiver receiver);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
+ @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})")
oneway void setAvrcpAbsoluteVolume(int volume, in AttributionSource attributionSource);
@JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
void isA2dpPlaying(in BluetoothDevice device, in AttributionSource attributionSource, in SynchronousResultReceiver receiver);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
+ @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})")
void getCodecStatus(in BluetoothDevice device, in AttributionSource attributionSource, in SynchronousResultReceiver receiver);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
+ @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})")
oneway void setCodecConfigPreference(in BluetoothDevice device, in BluetoothCodecConfig codecConfig, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
+ @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})")
oneway void enableOptionalCodecs(in BluetoothDevice device, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
+ @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})")
oneway void disableOptionalCodecs(in BluetoothDevice device, in AttributionSource attributionSource);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- void supportsOptionalCodecs(in BluetoothDevice device, in AttributionSource attributionSource, in SynchronousResultReceiver receiver);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
- void getOptionalCodecsEnabled(in BluetoothDevice device, in AttributionSource attributionSource, in SynchronousResultReceiver receiver);
- @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
+ @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})")
+ void isOptionalCodecsSupported(in BluetoothDevice device, in AttributionSource attributionSource, in SynchronousResultReceiver receiver);
+ @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})")
+ void isOptionalCodecsEnabled(in BluetoothDevice device, in AttributionSource attributionSource, in SynchronousResultReceiver receiver);
+ @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})")
oneway void setOptionalCodecsEnabled(in BluetoothDevice device, int value, in AttributionSource attributionSource);
@JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})")
void getDynamicBufferSupport(in AttributionSource attributionSource, in SynchronousResultReceiver receiver);