Merge "Revert "Revert "Require user pass in a non-null BluetoothDevice ..."" into rvc-dev

This commit is contained in:
TreeHugger Robot
2020-03-05 19:15:30 +00:00
committed by Android (Google) Code Review
4 changed files with 68 additions and 36 deletions

View File

@@ -1469,16 +1469,16 @@ package android.app.usage {
package android.bluetooth {
public final class BluetoothA2dp implements android.bluetooth.BluetoothProfile {
method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public void disableOptionalCodecs(@Nullable android.bluetooth.BluetoothDevice);
method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public void enableOptionalCodecs(@Nullable android.bluetooth.BluetoothDevice);
method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public void disableOptionalCodecs(@NonNull android.bluetooth.BluetoothDevice);
method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public void enableOptionalCodecs(@NonNull android.bluetooth.BluetoothDevice);
method @Nullable @RequiresPermission(android.Manifest.permission.BLUETOOTH) public android.bluetooth.BluetoothDevice getActiveDevice();
method @Nullable @RequiresPermission(android.Manifest.permission.BLUETOOTH) public android.bluetooth.BluetoothCodecStatus getCodecStatus(@Nullable android.bluetooth.BluetoothDevice);
method @Nullable @RequiresPermission(android.Manifest.permission.BLUETOOTH) public android.bluetooth.BluetoothCodecStatus getCodecStatus(@NonNull android.bluetooth.BluetoothDevice);
method @RequiresPermission(android.Manifest.permission.BLUETOOTH) public int getConnectionPolicy(@NonNull android.bluetooth.BluetoothDevice);
method @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADMIN) public int getOptionalCodecsEnabled(@Nullable android.bluetooth.BluetoothDevice);
method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public void setCodecConfigPreference(@Nullable android.bluetooth.BluetoothDevice, @Nullable android.bluetooth.BluetoothCodecConfig);
method @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADMIN) public int isOptionalCodecsEnabled(@NonNull android.bluetooth.BluetoothDevice);
method @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADMIN) public int isOptionalCodecsSupported(@NonNull android.bluetooth.BluetoothDevice);
method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public void setCodecConfigPreference(@NonNull android.bluetooth.BluetoothDevice, @NonNull android.bluetooth.BluetoothCodecConfig);
method @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADMIN) public boolean setConnectionPolicy(@NonNull android.bluetooth.BluetoothDevice, int);
method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public void setOptionalCodecsEnabled(@Nullable android.bluetooth.BluetoothDevice, int);
method @RequiresPermission(android.Manifest.permission.BLUETOOTH_ADMIN) public int supportsOptionalCodecs(@Nullable android.bluetooth.BluetoothDevice);
method @RequiresPermission(android.Manifest.permission.BLUETOOTH_PRIVILEGED) public void setOptionalCodecsEnabled(@NonNull android.bluetooth.BluetoothDevice, int);
field public static final int OPTIONAL_CODECS_NOT_SUPPORTED = 0; // 0x0
field public static final int OPTIONAL_CODECS_PREF_DISABLED = 0; // 0x0
field public static final int OPTIONAL_CODECS_PREF_ENABLED = 1; // 0x1

View File

@@ -643,8 +643,9 @@ public final class BluetoothA2dp implements BluetoothProfile {
@SystemApi
@Nullable
@RequiresPermission(Manifest.permission.BLUETOOTH)
public BluetoothCodecStatus getCodecStatus(@Nullable BluetoothDevice device) {
public BluetoothCodecStatus getCodecStatus(@NonNull BluetoothDevice device) {
if (DBG) Log.d(TAG, "getCodecStatus(" + device + ")");
verifyDeviceNotNull(device, "getCodecStatus");
try {
final IBluetoothA2dp service = getService();
if (service != null && isEnabled()) {
@@ -670,9 +671,14 @@ public final class BluetoothA2dp implements BluetoothProfile {
*/
@SystemApi
@RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
public void setCodecConfigPreference(@Nullable BluetoothDevice device,
@Nullable BluetoothCodecConfig codecConfig) {
public void setCodecConfigPreference(@NonNull BluetoothDevice device,
@NonNull BluetoothCodecConfig codecConfig) {
if (DBG) Log.d(TAG, "setCodecConfigPreference(" + device + ")");
verifyDeviceNotNull(device, "setCodecConfigPreference");
if (codecConfig == null) {
Log.e(TAG, "setCodecConfigPreference: Codec config can't be null");
throw new IllegalArgumentException("codecConfig cannot be null");
}
try {
final IBluetoothA2dp service = getService();
if (service != null && isEnabled()) {
@@ -695,8 +701,9 @@ public final class BluetoothA2dp implements BluetoothProfile {
*/
@SystemApi
@RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
public void enableOptionalCodecs(@Nullable BluetoothDevice device) {
public void enableOptionalCodecs(@NonNull BluetoothDevice device) {
if (DBG) Log.d(TAG, "enableOptionalCodecs(" + device + ")");
verifyDeviceNotNull(device, "enableOptionalCodecs");
enableDisableOptionalCodecs(device, true);
}
@@ -709,8 +716,9 @@ public final class BluetoothA2dp implements BluetoothProfile {
*/
@SystemApi
@RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
public void disableOptionalCodecs(@Nullable BluetoothDevice device) {
public void disableOptionalCodecs(@NonNull BluetoothDevice device) {
if (DBG) Log.d(TAG, "disableOptionalCodecs(" + device + ")");
verifyDeviceNotNull(device, "disableOptionalCodecs");
enableDisableOptionalCodecs(device, false);
}
@@ -750,7 +758,8 @@ public final class BluetoothA2dp implements BluetoothProfile {
@SystemApi
@RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN)
@OptionalCodecsSupportStatus
public int supportsOptionalCodecs(@Nullable BluetoothDevice device) {
public int isOptionalCodecsSupported(@NonNull BluetoothDevice device) {
verifyDeviceNotNull(device, "isOptionalCodecsSupported");
try {
final IBluetoothA2dp service = getService();
if (service != null && isEnabled() && isValidDevice(device)) {
@@ -775,7 +784,8 @@ public final class BluetoothA2dp implements BluetoothProfile {
@SystemApi
@RequiresPermission(Manifest.permission.BLUETOOTH_ADMIN)
@OptionalCodecsPreferenceStatus
public int getOptionalCodecsEnabled(@Nullable BluetoothDevice device) {
public int isOptionalCodecsEnabled(@NonNull BluetoothDevice device) {
verifyDeviceNotNull(device, "isOptionalCodecsEnabled");
try {
final IBluetoothA2dp service = getService();
if (service != null && isEnabled() && isValidDevice(device)) {
@@ -800,8 +810,9 @@ public final class BluetoothA2dp implements BluetoothProfile {
*/
@SystemApi
@RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
public void setOptionalCodecsEnabled(@Nullable BluetoothDevice device,
public void setOptionalCodecsEnabled(@NonNull BluetoothDevice device,
@OptionalCodecsPreferenceStatus int value) {
verifyDeviceNotNull(device, "setOptionalCodecsEnabled");
try {
if (value != BluetoothA2dp.OPTIONAL_CODECS_PREF_UNKNOWN
&& value != BluetoothA2dp.OPTIONAL_CODECS_PREF_DISABLED
@@ -854,6 +865,13 @@ public final class BluetoothA2dp implements BluetoothProfile {
return false;
}
private void verifyDeviceNotNull(BluetoothDevice device, String methodName) {
if (device == null) {
Log.e(TAG, methodName + ": device param is null");
throw new IllegalArgumentException("Device cannot be null");
}
}
private boolean isValidDevice(BluetoothDevice device) {
if (device == null) return false;

View File

@@ -218,24 +218,32 @@ public class A2dpProfile implements LocalBluetoothProfile {
}
public boolean supportsHighQualityAudio(BluetoothDevice device) {
int support = mService.supportsOptionalCodecs(device);
BluetoothDevice bluetoothDevice = (device == null) ? device : mService.getActiveDevice();
if (bluetoothDevice == null) {
return false;
}
int support = mService.isOptionalCodecsSupported(bluetoothDevice);
return support == BluetoothA2dp.OPTIONAL_CODECS_SUPPORTED;
}
public boolean isHighQualityAudioEnabled(BluetoothDevice device) {
int enabled = mService.getOptionalCodecsEnabled(device);
BluetoothDevice bluetoothDevice = (device == null) ? device : mService.getActiveDevice();
if (bluetoothDevice == null) {
return false;
}
int enabled = mService.isOptionalCodecsEnabled(bluetoothDevice);
if (enabled != BluetoothA2dp.OPTIONAL_CODECS_PREF_UNKNOWN) {
return enabled == BluetoothA2dp.OPTIONAL_CODECS_PREF_ENABLED;
} else if (getConnectionStatus(device) != BluetoothProfile.STATE_CONNECTED &&
supportsHighQualityAudio(device)) {
} else if (getConnectionStatus(bluetoothDevice) != BluetoothProfile.STATE_CONNECTED
&& supportsHighQualityAudio(bluetoothDevice)) {
// Since we don't have a stored preference and the device isn't connected, just return
// true since the default behavior when the device gets connected in the future would be
// to have optional codecs enabled.
return true;
}
BluetoothCodecConfig codecConfig = null;
if (mService.getCodecStatus(device) != null) {
codecConfig = mService.getCodecStatus(device).getCodecConfig();
if (mService.getCodecStatus(bluetoothDevice) != null) {
codecConfig = mService.getCodecStatus(bluetoothDevice).getCodecConfig();
}
if (codecConfig != null) {
return !codecConfig.isMandatoryCodec();
@@ -245,23 +253,28 @@ public class A2dpProfile implements LocalBluetoothProfile {
}
public void setHighQualityAudioEnabled(BluetoothDevice device, boolean enabled) {
BluetoothDevice bluetoothDevice = (device == null) ? device : mService.getActiveDevice();
if (bluetoothDevice == null) {
return;
}
int prefValue = enabled
? BluetoothA2dp.OPTIONAL_CODECS_PREF_ENABLED
: BluetoothA2dp.OPTIONAL_CODECS_PREF_DISABLED;
mService.setOptionalCodecsEnabled(device, prefValue);
if (getConnectionStatus(device) != BluetoothProfile.STATE_CONNECTED) {
mService.setOptionalCodecsEnabled(bluetoothDevice, prefValue);
if (getConnectionStatus(bluetoothDevice) != BluetoothProfile.STATE_CONNECTED) {
return;
}
if (enabled) {
mService.enableOptionalCodecs(device);
mService.enableOptionalCodecs(bluetoothDevice);
} else {
mService.disableOptionalCodecs(device);
mService.disableOptionalCodecs(bluetoothDevice);
}
}
public String getHighQualityAudioOptionLabel(BluetoothDevice device) {
BluetoothDevice bluetoothDevice = (device == null) ? device : mService.getActiveDevice();
int unknownCodecId = R.string.bluetooth_profile_a2dp_high_quality_unknown_codec;
if (!supportsHighQualityAudio(device)
if (bluetoothDevice == null || !supportsHighQualityAudio(device)
|| getConnectionStatus(device) != BluetoothProfile.STATE_CONNECTED) {
return mContext.getString(unknownCodecId);
}

View File

@@ -69,30 +69,31 @@ public class A2dpProfileTest {
mProfile = new A2dpProfile(mContext, mDeviceManager, mProfileManager);
mServiceListener = mShadowBluetoothAdapter.getServiceListener();
mServiceListener.onServiceConnected(BluetoothProfile.A2DP, mBluetoothA2dp);
when(mBluetoothA2dp.getActiveDevice()).thenReturn(mDevice);
}
@Test
public void supportsHighQualityAudio() {
when(mBluetoothA2dp.supportsOptionalCodecs(any())).thenReturn(
when(mBluetoothA2dp.isOptionalCodecsSupported(mDevice)).thenReturn(
BluetoothA2dp.OPTIONAL_CODECS_SUPPORTED);
assertThat(mProfile.supportsHighQualityAudio(mDevice)).isTrue();
when(mBluetoothA2dp.supportsOptionalCodecs(any())).thenReturn(
when(mBluetoothA2dp.isOptionalCodecsSupported(mDevice)).thenReturn(
BluetoothA2dp.OPTIONAL_CODECS_NOT_SUPPORTED);
assertThat(mProfile.supportsHighQualityAudio(mDevice)).isFalse();
when(mBluetoothA2dp.supportsOptionalCodecs(any())).thenReturn(
when(mBluetoothA2dp.isOptionalCodecsSupported(mDevice)).thenReturn(
BluetoothA2dp.OPTIONAL_CODECS_SUPPORT_UNKNOWN);
assertThat(mProfile.supportsHighQualityAudio(mDevice)).isFalse();
}
@Test
public void isHighQualityAudioEnabled() {
when(mBluetoothA2dp.getOptionalCodecsEnabled(any())).thenReturn(
when(mBluetoothA2dp.isOptionalCodecsEnabled(mDevice)).thenReturn(
BluetoothA2dp.OPTIONAL_CODECS_PREF_ENABLED);
assertThat(mProfile.isHighQualityAudioEnabled(mDevice)).isTrue();
when(mBluetoothA2dp.getOptionalCodecsEnabled(any())).thenReturn(
when(mBluetoothA2dp.isOptionalCodecsEnabled(mDevice)).thenReturn(
BluetoothA2dp.OPTIONAL_CODECS_PREF_DISABLED);
assertThat(mProfile.isHighQualityAudioEnabled(mDevice)).isFalse();
@@ -100,16 +101,16 @@ public class A2dpProfileTest {
// then isHighQualityAudioEnabled() should return true or false based on whether optional
// codecs are supported. If the device is connected then we should ask it directly, but if
// the device isn't connected then rely on the stored pref about such support.
when(mBluetoothA2dp.getOptionalCodecsEnabled(any())).thenReturn(
when(mBluetoothA2dp.isOptionalCodecsEnabled(mDevice)).thenReturn(
BluetoothA2dp.OPTIONAL_CODECS_PREF_UNKNOWN);
when(mBluetoothA2dp.getConnectionState(any())).thenReturn(
BluetoothProfile.STATE_DISCONNECTED);
when(mBluetoothA2dp.supportsOptionalCodecs(any())).thenReturn(
when(mBluetoothA2dp.isOptionalCodecsSupported(mDevice)).thenReturn(
BluetoothA2dp.OPTIONAL_CODECS_NOT_SUPPORTED);
assertThat(mProfile.isHighQualityAudioEnabled(mDevice)).isFalse();
when(mBluetoothA2dp.supportsOptionalCodecs(any())).thenReturn(
when(mBluetoothA2dp.isOptionalCodecsSupported(mDevice)).thenReturn(
BluetoothA2dp.OPTIONAL_CODECS_SUPPORTED);
assertThat(mProfile.isHighQualityAudioEnabled(mDevice)).isTrue();
@@ -151,14 +152,14 @@ public class A2dpProfileTest {
// Most tests want to simulate optional codecs being supported by the device, so do that
// by default here.
when(mBluetoothA2dp.supportsOptionalCodecs(any())).thenReturn(
when(mBluetoothA2dp.isOptionalCodecsSupported(any())).thenReturn(
BluetoothA2dp.OPTIONAL_CODECS_SUPPORTED);
}
@Test
public void getLableCodecsNotSupported() {
setupLabelTest();
when(mBluetoothA2dp.supportsOptionalCodecs(any())).thenReturn(
when(mBluetoothA2dp.isOptionalCodecsSupported(any())).thenReturn(
BluetoothA2dp.OPTIONAL_CODECS_NOT_SUPPORTED);
assertThat(mProfile.getHighQualityAudioOptionLabel(mDevice)).isEqualTo(UNKNOWN_CODEC_LABEL);
}