Disable the spatializer options for device categories
If the BT device cannot be of category headphones do not show the
spatializer options.
Test: manual & atest BluetoothDetailsSpatialAudioControllerTest
Bug: 297265575
Change-Id: I7f044d40afadec6ccf659ae4969c0d6e2dc8c79e
diff --git a/src/com/android/settings/bluetooth/BluetoothDetailsAudioDeviceTypeController.java b/src/com/android/settings/bluetooth/BluetoothDetailsAudioDeviceTypeController.java
index fe0d141..9571767 100644
--- a/src/com/android/settings/bluetooth/BluetoothDetailsAudioDeviceTypeController.java
+++ b/src/com/android/settings/bluetooth/BluetoothDetailsAudioDeviceTypeController.java
@@ -109,6 +109,7 @@
mAudioManager.setBluetoothAudioDeviceCategory(mCachedDevice.getAddress(),
mCachedDevice.getDevice().getType() == DEVICE_TYPE_LE,
Integer.parseInt(value));
+ mCachedDevice.onAudioDeviceCategoryChanged();
}
}
return true;
diff --git a/src/com/android/settings/bluetooth/BluetoothDetailsSpatialAudioController.java b/src/com/android/settings/bluetooth/BluetoothDetailsSpatialAudioController.java
index bec6b03..c431cee 100644
--- a/src/com/android/settings/bluetooth/BluetoothDetailsSpatialAudioController.java
+++ b/src/com/android/settings/bluetooth/BluetoothDetailsSpatialAudioController.java
@@ -53,9 +53,7 @@
@VisibleForTesting
PreferenceCategory mProfilesContainer;
@VisibleForTesting
- AudioDeviceAttributes mAudioDevice;
-
- private boolean mIsAvailable;
+ AudioDeviceAttributes mAudioDevice = null;
public BluetoothDetailsSpatialAudioController(
Context context,
@@ -65,13 +63,11 @@
super(context, fragment, device, lifecycle);
AudioManager audioManager = context.getSystemService(AudioManager.class);
mSpatializer = audioManager.getSpatializer();
- getAvailableDevice();
-
}
@Override
public boolean isAvailable() {
- return mIsAvailable;
+ return mSpatializer.getImmersiveAudioLevel() != SPATIALIZER_IMMERSIVE_LEVEL_NONE;
}
@Override
@@ -79,15 +75,11 @@
SwitchPreference switchPreference = (SwitchPreference) preference;
String key = switchPreference.getKey();
if (TextUtils.equals(key, KEY_SPATIAL_AUDIO)) {
- if (switchPreference.isChecked()) {
- mSpatializer.addCompatibleAudioDevice(mAudioDevice);
- } else {
- mSpatializer.removeCompatibleAudioDevice(mAudioDevice);
- }
- refresh();
+ updateSpatializerEnabled(switchPreference.isChecked());
+ refreshSpatialAudioEnabled(switchPreference);
return true;
} else if (TextUtils.equals(key, KEY_HEAD_TRACKING)) {
- mSpatializer.setHeadTrackerEnabled(switchPreference.isChecked(), mAudioDevice);
+ updateSpatializerHeadTracking(switchPreference.isChecked());
return true;
} else {
Log.w(TAG, "invalid key name.");
@@ -95,6 +87,26 @@
}
}
+ private void updateSpatializerEnabled(boolean enabled) {
+ if (mAudioDevice == null) {
+ Log.w(TAG, "cannot update spatializer enabled for null audio device.");
+ return;
+ }
+ if (enabled) {
+ mSpatializer.addCompatibleAudioDevice(mAudioDevice);
+ } else {
+ mSpatializer.removeCompatibleAudioDevice(mAudioDevice);
+ }
+ }
+
+ private void updateSpatializerHeadTracking(boolean enabled) {
+ if (mAudioDevice == null) {
+ Log.w(TAG, "cannot update spatializer head tracking for null audio device.");
+ return;
+ }
+ mSpatializer.setHeadTrackerEnabled(enabled, mAudioDevice);
+ }
+
@Override
public String getPreferenceKey() {
return KEY_SPATIAL_AUDIO_GROUP;
@@ -109,15 +121,30 @@
@Override
protected void refresh() {
if (mAudioDevice == null) {
- return;
+ getAvailableDevice();
}
SwitchPreference spatialAudioPref = mProfilesContainer.findPreference(KEY_SPATIAL_AUDIO);
- if (spatialAudioPref == null) {
+ if (spatialAudioPref == null && mAudioDevice != null) {
spatialAudioPref = createSpatialAudioPreference(mProfilesContainer.getContext());
mProfilesContainer.addPreference(spatialAudioPref);
+ } else if (mAudioDevice == null || !mSpatializer.isAvailableForDevice(mAudioDevice)) {
+ if (spatialAudioPref != null) {
+ mProfilesContainer.removePreference(spatialAudioPref);
+ }
+ final SwitchPreference headTrackingPref =
+ mProfilesContainer.findPreference(KEY_HEAD_TRACKING);
+ if (headTrackingPref != null) {
+ mProfilesContainer.removePreference(headTrackingPref);
+ }
+ mAudioDevice = null;
+ return;
}
+ refreshSpatialAudioEnabled(spatialAudioPref);
+ }
+
+ private void refreshSpatialAudioEnabled(SwitchPreference spatialAudioPref) {
boolean isSpatialAudioOn = mSpatializer.getCompatibleAudioDevices().contains(mAudioDevice);
Log.d(TAG, "refresh() isSpatialAudioOn : " + isSpatialAudioOn);
spatialAudioPref.setChecked(isSpatialAudioOn);
@@ -127,9 +154,13 @@
headTrackingPref = createHeadTrackingPreference(mProfilesContainer.getContext());
mProfilesContainer.addPreference(headTrackingPref);
}
+ refreshHeadTracking(spatialAudioPref, headTrackingPref);
+ }
+ private void refreshHeadTracking(SwitchPreference spatialAudioPref,
+ SwitchPreference headTrackingPref) {
boolean isHeadTrackingAvailable =
- isSpatialAudioOn && mSpatializer.hasHeadTracker(mAudioDevice);
+ spatialAudioPref.isChecked() && mSpatializer.hasHeadTracker(mAudioDevice);
Log.d(TAG, "refresh() has head tracker : " + mSpatializer.hasHeadTracker(mAudioDevice));
headTrackingPref.setVisible(isHeadTrackingAvailable);
if (isHeadTrackingAvailable) {
@@ -158,14 +189,6 @@
}
private void getAvailableDevice() {
- if (mSpatializer.getImmersiveAudioLevel() == SPATIALIZER_IMMERSIVE_LEVEL_NONE) {
- mIsAvailable = false;
- mAudioDevice = null;
- Log.d(TAG, "getAvailableDevice() ignored: spatializer not supported");
-
- return;
- }
-
AudioDeviceAttributes a2dpDevice = new AudioDeviceAttributes(
AudioDeviceAttributes.ROLE_OUTPUT,
AudioDeviceInfo.TYPE_BLUETOOTH_A2DP,
@@ -187,7 +210,6 @@
AudioDeviceInfo.TYPE_HEARING_AID,
mCachedDevice.getAddress());
- mIsAvailable = true;
if (mSpatializer.isAvailableForDevice(bleHeadsetDevice)) {
mAudioDevice = bleHeadsetDevice;
} else if (mSpatializer.isAvailableForDevice(bleSpeakerDevice)) {
@@ -196,20 +218,20 @@
mAudioDevice = bleBroadcastDevice;
} else if (mSpatializer.isAvailableForDevice(a2dpDevice)) {
mAudioDevice = a2dpDevice;
- } else {
- mIsAvailable = mSpatializer.isAvailableForDevice(hearingAidDevice);
+ } else if (mSpatializer.isAvailableForDevice(hearingAidDevice)) {
mAudioDevice = hearingAidDevice;
+ } else {
+ mAudioDevice = null;
}
Log.d(TAG, "getAvailableDevice() device : "
+ mCachedDevice.getDevice().getAnonymizedAddress()
- + ", type : " + mAudioDevice.getType()
- + ", is available : " + mIsAvailable);
+ + ", is available : " + (mAudioDevice != null)
+ + ", type : " + (mAudioDevice == null ? "no type" : mAudioDevice.getType()));
}
@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 1f0adcf..ce5631f 100644
--- a/tests/robotests/src/com/android/settings/bluetooth/BluetoothDetailsSpatialAudioControllerTest.java
+++ b/tests/robotests/src/com/android/settings/bluetooth/BluetoothDetailsSpatialAudioControllerTest.java
@@ -16,6 +16,9 @@
package com.android.settings.bluetooth;
+import static android.media.Spatializer.SPATIALIZER_IMMERSIVE_LEVEL_MULTICHANNEL;
+import static android.media.Spatializer.SPATIALIZER_IMMERSIVE_LEVEL_NONE;
+
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.spy;
@@ -62,6 +65,8 @@
@Mock
private BluetoothDevice mBluetoothDevice;
+ private AudioDeviceAttributes mAvailableDevice;
+
private BluetoothDetailsSpatialAudioController mController;
private SwitchPreference mSpatialAudioPref;
private SwitchPreference mHeadTrackingPref;
@@ -86,94 +91,32 @@
when(mProfilesContainer.findPreference(KEY_SPATIAL_AUDIO)).thenReturn(mSpatialAudioPref);
when(mProfilesContainer.findPreference(KEY_HEAD_TRACKING)).thenReturn(mHeadTrackingPref);
- }
- @Test
- public void isAvailable_spatialAudioSupportA2dpDevice_returnsTrue() {
- AudioDeviceAttributes a2dpDevice = new AudioDeviceAttributes(
+ mAvailableDevice = 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_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() {
+ public void isAvailable_forSpatializerWithLevelNone_returnsFalse() {
+ when(mSpatializer.getImmersiveAudioLevel()).thenReturn(SPATIALIZER_IMMERSIVE_LEVEL_NONE);
assertThat(mController.isAvailable()).isFalse();
- assertThat(mController.mAudioDevice.getType())
- .isEqualTo(AudioDeviceInfo.TYPE_HEARING_AID);
+ }
+
+ @Test
+ public void isAvailable_forSpatializerWithLevelNotNone_returnsTrue() {
+ when(mSpatializer.getImmersiveAudioLevel()).thenReturn(
+ SPATIALIZER_IMMERSIVE_LEVEL_MULTICHANNEL);
+ assertThat(mController.isAvailable()).isTrue();
}
@Test
public void refresh_spatialAudioIsTurnedOn_checksSpatialAudioPreference() {
List<AudioDeviceAttributes> compatibleAudioDevices = new ArrayList<>();
+ mController.setAvailableDevice(mAvailableDevice);
compatibleAudioDevices.add(mController.mAudioDevice);
+ when(mSpatializer.isAvailableForDevice(mController.mAudioDevice)).thenReturn(true);
when(mSpatializer.getCompatibleAudioDevices()).thenReturn(compatibleAudioDevices);
mController.refresh();
@@ -207,13 +150,14 @@
public void
refresh_spatialAudioOnAndHeadTrackingIsNotAvailable_hidesHeadTrackingPreference() {
List<AudioDeviceAttributes> compatibleAudioDevices = new ArrayList<>();
+ mController.setAvailableDevice(mAvailableDevice);
compatibleAudioDevices.add(mController.mAudioDevice);
when(mSpatializer.getCompatibleAudioDevices()).thenReturn(compatibleAudioDevices);
when(mSpatializer.hasHeadTracker(mController.mAudioDevice)).thenReturn(false);
mController.refresh();
- assertThat(mHeadTrackingPref.isVisible()).isFalse();
+ verify(mProfilesContainer).removePreference(mHeadTrackingPref);
}
@Test
@@ -223,14 +167,16 @@
mController.refresh();
- assertThat(mHeadTrackingPref.isVisible()).isFalse();
+ verify(mProfilesContainer).removePreference(mHeadTrackingPref);
}
@Test
public void refresh_headTrackingIsTurnedOn_checksHeadTrackingPreference() {
List<AudioDeviceAttributes> compatibleAudioDevices = new ArrayList<>();
+ mController.setAvailableDevice(mAvailableDevice);
compatibleAudioDevices.add(mController.mAudioDevice);
when(mSpatializer.getCompatibleAudioDevices()).thenReturn(compatibleAudioDevices);
+ when(mSpatializer.isAvailableForDevice(mController.mAudioDevice)).thenReturn(true);
when(mSpatializer.hasHeadTracker(mController.mAudioDevice)).thenReturn(true);
when(mSpatializer.isHeadTrackerEnabled(mController.mAudioDevice)).thenReturn(true);
@@ -242,8 +188,10 @@
@Test
public void refresh_headTrackingIsTurnedOff_unchecksHeadTrackingPreference() {
List<AudioDeviceAttributes> compatibleAudioDevices = new ArrayList<>();
+ mController.setAvailableDevice(mAvailableDevice);
compatibleAudioDevices.add(mController.mAudioDevice);
when(mSpatializer.getCompatibleAudioDevices()).thenReturn(compatibleAudioDevices);
+ when(mSpatializer.isAvailableForDevice(mController.mAudioDevice)).thenReturn(true);
when(mSpatializer.hasHeadTracker(mController.mAudioDevice)).thenReturn(true);
when(mSpatializer.isHeadTrackerEnabled(mController.mAudioDevice)).thenReturn(false);
@@ -254,6 +202,7 @@
@Test
public void turnedOnSpatialAudio_invokesAddCompatibleAudioDevice() {
+ mController.setAvailableDevice(mAvailableDevice);
mSpatialAudioPref.setChecked(true);
mController.onPreferenceClick(mSpatialAudioPref);
verify(mSpatializer).addCompatibleAudioDevice(mController.mAudioDevice);
@@ -261,6 +210,7 @@
@Test
public void turnedOffSpatialAudio_invokesRemoveCompatibleAudioDevice() {
+ mController.setAvailableDevice(mAvailableDevice);
mSpatialAudioPref.setChecked(false);
mController.onPreferenceClick(mSpatialAudioPref);
verify(mSpatializer).removeCompatibleAudioDevice(mController.mAudioDevice);
@@ -268,6 +218,7 @@
@Test
public void turnedOnHeadTracking_invokesSetHeadTrackerEnabled_setsTrue() {
+ mController.setAvailableDevice(mAvailableDevice);
mHeadTrackingPref.setChecked(true);
mController.onPreferenceClick(mHeadTrackingPref);
verify(mSpatializer).setHeadTrackerEnabled(true, mController.mAudioDevice);
@@ -275,6 +226,7 @@
@Test
public void turnedOffHeadTracking_invokesSetHeadTrackerEnabled_setsFalse() {
+ mController.setAvailableDevice(mAvailableDevice);
mHeadTrackingPref.setChecked(false);
mController.onPreferenceClick(mHeadTrackingPref);
verify(mSpatializer).setHeadTrackerEnabled(false, mController.mAudioDevice);