From f8704add5108872fc68307eb6349008f98b228c6 Mon Sep 17 00:00:00 2001 From: Hugh Chen Date: Tue, 13 Sep 2022 12:56:53 +0000 Subject: [PATCH] Add Spatial audio settings for LE Audio devices - Adds TYPE_BLE_HEADSE, TYPE_BLE_SPEAKER and TYPE_BLE_BROADCAST for display Le audio devices. - Adds TYPE_HEARING_AID for display hearing aid devices. Bug: 244528781 Test: make -j64 RunSettingsRoboTests Change-Id: I1278a5e0c93fdc5a4873df68032128ffedfe72d6 --- ...luetoothDetailsSpatialAudioController.java | 57 +++++++++++-- ...oothDetailsSpatialAudioControllerTest.java | 84 ++++++++++++++++++- 2 files changed, 132 insertions(+), 9 deletions(-) diff --git a/src/com/android/settings/bluetooth/BluetoothDetailsSpatialAudioController.java b/src/com/android/settings/bluetooth/BluetoothDetailsSpatialAudioController.java index 89d923d616a..29066b8822d 100644 --- a/src/com/android/settings/bluetooth/BluetoothDetailsSpatialAudioController.java +++ b/src/com/android/settings/bluetooth/BluetoothDetailsSpatialAudioController.java @@ -53,6 +53,8 @@ public class BluetoothDetailsSpatialAudioController extends BluetoothDetailsCont @VisibleForTesting AudioDeviceAttributes mAudioDevice; + private boolean mIsAvailable; + public BluetoothDetailsSpatialAudioController( Context context, PreferenceFragmentCompat fragment, @@ -61,16 +63,13 @@ public class BluetoothDetailsSpatialAudioController extends BluetoothDetailsCont super(context, fragment, device, lifecycle); AudioManager audioManager = context.getSystemService(AudioManager.class); mSpatializer = audioManager.getSpatializer(); - mAudioDevice = new AudioDeviceAttributes( - AudioDeviceAttributes.ROLE_OUTPUT, - AudioDeviceInfo.TYPE_BLUETOOTH_A2DP, - mCachedDevice.getAddress()); + getAvailableDevice(); } @Override public boolean isAvailable() { - return mSpatializer.isAvailableForDevice(mAudioDevice) ? true : false; + return mIsAvailable; } @Override @@ -152,4 +151,52 @@ public class BluetoothDetailsSpatialAudioController extends BluetoothDetailsCont pref.setOnPreferenceClickListener(this); return pref; } + + private void getAvailableDevice() { + AudioDeviceAttributes a2dpDevice = new AudioDeviceAttributes( + AudioDeviceAttributes.ROLE_OUTPUT, + AudioDeviceInfo.TYPE_BLUETOOTH_A2DP, + mCachedDevice.getAddress()); + AudioDeviceAttributes bleHeadsetDevice = new AudioDeviceAttributes( + AudioDeviceAttributes.ROLE_OUTPUT, + AudioDeviceInfo.TYPE_BLE_HEADSET, + mCachedDevice.getAddress()); + AudioDeviceAttributes bleSpeakerDevice = new AudioDeviceAttributes( + AudioDeviceAttributes.ROLE_OUTPUT, + AudioDeviceInfo.TYPE_BLE_SPEAKER, + mCachedDevice.getAddress()); + AudioDeviceAttributes bleBroadcastDevice = new AudioDeviceAttributes( + AudioDeviceAttributes.ROLE_OUTPUT, + AudioDeviceInfo.TYPE_BLE_BROADCAST, + mCachedDevice.getAddress()); + AudioDeviceAttributes hearingAidDevice = new AudioDeviceAttributes( + AudioDeviceAttributes.ROLE_OUTPUT, + AudioDeviceInfo.TYPE_HEARING_AID, + mCachedDevice.getAddress()); + + mIsAvailable = true; + if (mSpatializer.isAvailableForDevice(bleHeadsetDevice)) { + mAudioDevice = bleHeadsetDevice; + } else if (mSpatializer.isAvailableForDevice(bleSpeakerDevice)) { + mAudioDevice = bleSpeakerDevice; + } else if (mSpatializer.isAvailableForDevice(bleBroadcastDevice)) { + mAudioDevice = bleBroadcastDevice; + } else if (mSpatializer.isAvailableForDevice(a2dpDevice)) { + mAudioDevice = a2dpDevice; + } else { + mIsAvailable = mSpatializer.isAvailableForDevice(hearingAidDevice); + mAudioDevice = hearingAidDevice; + } + + Log.d(TAG, "getAvailableDevice() device : " + + mCachedDevice.getDevice().getAnonymizedAddress() + + ", type : " + mAudioDevice.getType() + + ", is available : " + mIsAvailable); + } + + @VisibleForTesting + void setAvailableDevice(AudioDeviceAttributes audioDevice) { + mAudioDevice = audioDevice; + mIsAvailable = mSpatializer.isAvailableForDevice(audioDevice); + } } diff --git a/tests/robotests/src/com/android/settings/bluetooth/BluetoothDetailsSpatialAudioControllerTest.java b/tests/robotests/src/com/android/settings/bluetooth/BluetoothDetailsSpatialAudioControllerTest.java index ef812473565..1f0adcfca80 100644 --- a/tests/robotests/src/com/android/settings/bluetooth/BluetoothDetailsSpatialAudioControllerTest.java +++ b/tests/robotests/src/com/android/settings/bluetooth/BluetoothDetailsSpatialAudioControllerTest.java @@ -22,7 +22,9 @@ import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import android.bluetooth.BluetoothDevice; import android.media.AudioDeviceAttributes; +import android.media.AudioDeviceInfo; import android.media.AudioManager; import android.media.Spatializer; @@ -57,6 +59,8 @@ public class BluetoothDetailsSpatialAudioControllerTest extends BluetoothDetails private Lifecycle mSpatialAudioLifecycle; @Mock private PreferenceCategory mProfilesContainer; + @Mock + private BluetoothDevice mBluetoothDevice; private BluetoothDetailsSpatialAudioController mController; private SwitchPreference mSpatialAudioPref; @@ -70,6 +74,8 @@ public class BluetoothDetailsSpatialAudioControllerTest extends BluetoothDetails when(mContext.getSystemService(AudioManager.class)).thenReturn(mAudioManager); when(mAudioManager.getSpatializer()).thenReturn(mSpatializer); when(mCachedDevice.getAddress()).thenReturn(MAC_ADDRESS); + when(mCachedDevice.getDevice()).thenReturn(mBluetoothDevice); + when(mBluetoothDevice.getAnonymizedAddress()).thenReturn(MAC_ADDRESS); mController = new BluetoothDetailsSpatialAudioController(mContext, mFragment, mCachedDevice, mSpatialAudioLifecycle); @@ -83,15 +89,85 @@ public class BluetoothDetailsSpatialAudioControllerTest extends BluetoothDetails } @Test - public void isAvailable_spatialAudioIsAvailable_returnsTrue() { - when(mSpatializer.isAvailableForDevice(mController.mAudioDevice)).thenReturn(true); + public void isAvailable_spatialAudioSupportA2dpDevice_returnsTrue() { + AudioDeviceAttributes a2dpDevice = new AudioDeviceAttributes( + AudioDeviceAttributes.ROLE_OUTPUT, + AudioDeviceInfo.TYPE_BLUETOOTH_A2DP, + MAC_ADDRESS); + when(mSpatializer.isAvailableForDevice(a2dpDevice)).thenReturn(true); + + mController.setAvailableDevice(a2dpDevice); + assertThat(mController.isAvailable()).isTrue(); + assertThat(mController.mAudioDevice.getType()) + .isEqualTo(AudioDeviceInfo.TYPE_BLUETOOTH_A2DP); } @Test - public void isAvailable_spatialAudioIsNotAvailable_returnsFalse() { - when(mSpatializer.isAvailableForDevice(mController.mAudioDevice)).thenReturn(false); + public void isAvailable_spatialAudioSupportBleHeadsetDevice_returnsTrue() { + AudioDeviceAttributes bleHeadsetDevice = new AudioDeviceAttributes( + AudioDeviceAttributes.ROLE_OUTPUT, + AudioDeviceInfo.TYPE_BLE_HEADSET, + MAC_ADDRESS); + when(mSpatializer.isAvailableForDevice(bleHeadsetDevice)).thenReturn(true); + + mController.setAvailableDevice(bleHeadsetDevice); + + assertThat(mController.isAvailable()).isTrue(); + assertThat(mController.mAudioDevice.getType()) + .isEqualTo(AudioDeviceInfo.TYPE_BLE_HEADSET); + } + + @Test + public void isAvailable_spatialAudioSupportBleSpeakerDevice_returnsTrue() { + AudioDeviceAttributes bleSpeakerDevice = new AudioDeviceAttributes( + AudioDeviceAttributes.ROLE_OUTPUT, + AudioDeviceInfo.TYPE_BLE_SPEAKER, + MAC_ADDRESS); + when(mSpatializer.isAvailableForDevice(bleSpeakerDevice)).thenReturn(true); + + mController.setAvailableDevice(bleSpeakerDevice); + + assertThat(mController.isAvailable()).isTrue(); + assertThat(mController.mAudioDevice.getType()) + .isEqualTo(AudioDeviceInfo.TYPE_BLE_SPEAKER); + } + + @Test + public void isAvailable_spatialAudioSupportBleBroadcastDevice_returnsTrue() { + AudioDeviceAttributes bleBroadcastDevice = new AudioDeviceAttributes( + AudioDeviceAttributes.ROLE_OUTPUT, + AudioDeviceInfo.TYPE_BLE_BROADCAST, + MAC_ADDRESS); + when(mSpatializer.isAvailableForDevice(bleBroadcastDevice)).thenReturn(true); + + mController.setAvailableDevice(bleBroadcastDevice); + + assertThat(mController.isAvailable()).isTrue(); + assertThat(mController.mAudioDevice.getType()) + .isEqualTo(AudioDeviceInfo.TYPE_BLE_BROADCAST); + } + + @Test + public void isAvailable_spatialAudioSupportHearingAidDevice_returnsTrue() { + AudioDeviceAttributes hearingAidDevice = new AudioDeviceAttributes( + AudioDeviceAttributes.ROLE_OUTPUT, + AudioDeviceInfo.TYPE_HEARING_AID, + MAC_ADDRESS); + when(mSpatializer.isAvailableForDevice(hearingAidDevice)).thenReturn(true); + + mController.setAvailableDevice(hearingAidDevice); + + assertThat(mController.isAvailable()).isTrue(); + assertThat(mController.mAudioDevice.getType()) + .isEqualTo(AudioDeviceInfo.TYPE_HEARING_AID); + } + + @Test + public void isAvailable_spatialAudioNotSupported_returnsFalse() { assertThat(mController.isAvailable()).isFalse(); + assertThat(mController.mAudioDevice.getType()) + .isEqualTo(AudioDeviceInfo.TYPE_HEARING_AID); } @Test