diff --git a/src/com/android/settings/bluetooth/BluetoothDetailsProfilesController.java b/src/com/android/settings/bluetooth/BluetoothDetailsProfilesController.java index 3fa811a5499..2e5daeb3c93 100644 --- a/src/com/android/settings/bluetooth/BluetoothDetailsProfilesController.java +++ b/src/com/android/settings/bluetooth/BluetoothDetailsProfilesController.java @@ -43,7 +43,6 @@ import com.android.settingslib.bluetooth.A2dpProfile; import com.android.settingslib.bluetooth.BluetoothUtils; import com.android.settingslib.bluetooth.CachedBluetoothDevice; import com.android.settingslib.bluetooth.HeadsetProfile; -import com.android.settingslib.bluetooth.HearingAidProfile; import com.android.settingslib.bluetooth.LeAudioProfile; import com.android.settingslib.bluetooth.LocalBluetoothManager; import com.android.settingslib.bluetooth.LocalBluetoothProfile; @@ -95,6 +94,7 @@ public class BluetoothDetailsProfilesController extends BluetoothDetailsControll new HashMap>(); private boolean mIsLeContactSharingEnabled = false; private boolean mIsLeAudioToggleEnabled = false; + private boolean mIsLeAudioOnlyDevice = false; @VisibleForTesting PreferenceCategory mProfilesContainer; @@ -345,6 +345,11 @@ public class BluetoothDetailsProfilesController extends BluetoothDetailsControll result.remove(mManager.getProfileManager().getA2dpProfile()); result.remove(mManager.getProfileManager().getHeadsetProfile()); } + boolean hearingAidSupported = result.contains( + mManager.getProfileManager().getHearingAidProfile()); + if (leAudioSupported && !classicAudioSupported && !hearingAidSupported) { + mIsLeAudioOnlyDevice = true; + } Log.d(TAG, "getProfiles:Map:" + mProfileDeviceMap); return result; } @@ -513,19 +518,6 @@ public class BluetoothDetailsProfilesController extends BluetoothDetailsControll refresh(); } - private boolean isLeAudioOnlyDevice() { - if (mCachedDevice.getProfiles().stream() - .noneMatch(profile -> profile instanceof LeAudioProfile)) { - return false; - } - return mCachedDevice.getProfiles().stream() - .noneMatch( - profile -> - profile instanceof HearingAidProfile - || profile instanceof A2dpProfile - || profile instanceof HeadsetProfile); - } - private void updateLeAudioConfig() { mIsLeContactSharingEnabled = DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_SETTINGS_UI, SettingsUIDeviceConfig.BT_LE_AUDIO_CONTACT_SHARING_ENABLED, true); @@ -534,7 +526,7 @@ public class BluetoothDetailsProfilesController extends BluetoothDetailsControll boolean isLeEnabledByDefault = SystemProperties.getBoolean(LE_AUDIO_CONNECTION_BY_DEFAULT_PROPERTY, true); mIsLeAudioToggleEnabled = isLeAudioToggleVisible || isLeEnabledByDefault; - if (Flags.hideLeAudioToggleForLeAudioOnlyDevice() && isLeAudioOnlyDevice()) { + if (Flags.hideLeAudioToggleForLeAudioOnlyDevice() && mIsLeAudioOnlyDevice) { mIsLeAudioToggleEnabled = false; Log.d( TAG, diff --git a/tests/robotests/src/com/android/settings/bluetooth/BluetoothDetailsProfilesControllerTest.java b/tests/robotests/src/com/android/settings/bluetooth/BluetoothDetailsProfilesControllerTest.java index 9b922349d6b..2d1f4c0e907 100644 --- a/tests/robotests/src/com/android/settings/bluetooth/BluetoothDetailsProfilesControllerTest.java +++ b/tests/robotests/src/com/android/settings/bluetooth/BluetoothDetailsProfilesControllerTest.java @@ -90,6 +90,9 @@ public class BluetoothDetailsProfilesControllerTest extends BluetoothDetailsCont @Mock private CachedBluetoothDeviceManager mCachedBluetoothDeviceManager; + private @Mock A2dpProfile mA2dpProfile; + private @Mock LeAudioProfile mLeAudioProfile; + @Override public void setUp() { super.setUp(); @@ -103,11 +106,13 @@ public class BluetoothDetailsProfilesControllerTest extends BluetoothDetailsCont mConnectableProfiles = new ArrayList<>(); when(mLocalManager.getProfileManager()).thenReturn(mProfileManager); when(mLocalManager.getCachedDeviceManager()).thenReturn(mCachedBluetoothDeviceManager); + setUpMockProfiles(); when(mCachedBluetoothDeviceManager.getCachedDevicesCopy()) .thenReturn(ImmutableList.of(mCachedDevice)); - when(mCachedDevice.getConnectableProfiles()).thenAnswer(invocation -> - new ArrayList<>(mConnectableProfiles) - ); + when(mCachedDevice.getConnectableProfiles()) + .thenAnswer(invocation -> new ArrayList<>(mConnectableProfiles)); + when(mCachedDevice.getProfiles()) + .thenAnswer(invocation -> ImmutableList.of(mConnectableProfiles)); setupDevice(mDeviceConfig); mController = new BluetoothDetailsProfilesController(mContext, mFragment, mLocalManager, @@ -389,21 +394,36 @@ public class BluetoothDetailsProfilesControllerTest extends BluetoothDetailsCont assertThat(mDevice.getMessageAccessPermission()).isEqualTo(BluetoothDevice.ACCESS_ALLOWED); } - private A2dpProfile addMockA2dpProfile(boolean preferred, boolean supportsHighQualityAudio, - boolean highQualityAudioEnabled) { - A2dpProfile profile = mock(A2dpProfile.class); - when(mProfileManager.getProfileByName(eq(profile.toString()))).thenReturn(profile); - when(profile.getNameResource(mDevice)) + private void setUpMockProfiles() { + when(mA2dpProfile.toString()).thenReturn("A2DP"); + when(mProfileManager.getProfileByName(eq(mA2dpProfile.toString()))) + .thenReturn(mA2dpProfile); + when(mA2dpProfile.getNameResource(any())) .thenReturn(com.android.settingslib.R.string.bluetooth_profile_a2dp); - when(profile.getHighQualityAudioOptionLabel(mDevice)).thenReturn( + when(mA2dpProfile.getHighQualityAudioOptionLabel(any())).thenReturn( mContext.getString(com.android.settingslib.R .string.bluetooth_profile_a2dp_high_quality_unknown_codec)); - when(profile.supportsHighQualityAudio(mDevice)).thenReturn(supportsHighQualityAudio); - when(profile.isHighQualityAudioEnabled(mDevice)).thenReturn(highQualityAudioEnabled); - when(profile.isEnabled(mDevice)).thenReturn(preferred); - when(profile.isProfileReady()).thenReturn(true); - mConnectableProfiles.add(profile); - return profile; + when(mA2dpProfile.isProfileReady()).thenReturn(true); + when(mProfileManager.getA2dpProfile()).thenReturn(mA2dpProfile); + + when(mLeAudioProfile.toString()).thenReturn("LE_AUDIO"); + when(mLeAudioProfile.getNameResource(any())) + .thenReturn(com.android.settingslib.R.string.bluetooth_profile_le_audio); + when(mLeAudioProfile.isProfileReady()).thenReturn(true); + when(mProfileManager.getLeAudioProfile()).thenReturn(mLeAudioProfile); + } + + private void addA2dpProfileToDevice(boolean preferred, boolean supportsHighQualityAudio, + boolean highQualityAudioEnabled) { + when(mA2dpProfile.supportsHighQualityAudio(any())).thenReturn(supportsHighQualityAudio); + when(mA2dpProfile.isHighQualityAudioEnabled(any())).thenReturn(highQualityAudioEnabled); + when(mA2dpProfile.isEnabled(any())).thenReturn(preferred); + mConnectableProfiles.add(mA2dpProfile); + } + + private void addLeAudioProfileToDevice(boolean enabled) { + when(mLeAudioProfile.isEnabled(any())).thenReturn(enabled); + mConnectableProfiles.add(mLeAudioProfile); } private SwitchPreferenceCompat getHighQualityAudioPref() { @@ -414,7 +434,7 @@ public class BluetoothDetailsProfilesControllerTest extends BluetoothDetailsCont @Test public void highQualityAudio_prefIsPresentWhenSupported() { setupDevice(makeDefaultDeviceConfig()); - addMockA2dpProfile(true, true, true); + addA2dpProfileToDevice(true, true, true); showScreen(mController); SwitchPreferenceCompat pref = getHighQualityAudioPref(); assertThat(pref.getKey()).isEqualTo( @@ -431,7 +451,7 @@ public class BluetoothDetailsProfilesControllerTest extends BluetoothDetailsCont @Test public void highQualityAudio_prefIsAbsentWhenNotSupported() { setupDevice(makeDefaultDeviceConfig()); - addMockA2dpProfile(true, false, false); + addA2dpProfileToDevice(true, false, false); showScreen(mController); assertThat(mProfiles.getPreferenceCount()).isEqualTo(2); SwitchPreferenceCompat pref = (SwitchPreferenceCompat) mProfiles.getPreference(0); @@ -444,7 +464,7 @@ public class BluetoothDetailsProfilesControllerTest extends BluetoothDetailsCont @Test public void highQualityAudio_busyDeviceDisablesSwitch() { setupDevice(makeDefaultDeviceConfig()); - addMockA2dpProfile(true, true, true); + addA2dpProfileToDevice(true, true, true); when(mCachedDevice.isBusy()).thenReturn(true); showScreen(mController); SwitchPreferenceCompat pref = getHighQualityAudioPref(); @@ -454,17 +474,17 @@ public class BluetoothDetailsProfilesControllerTest extends BluetoothDetailsCont @Test public void highQualityAudio_mediaAudioDisabledAndReEnabled() { setupDevice(makeDefaultDeviceConfig()); - A2dpProfile audioProfile = addMockA2dpProfile(true, true, true); + addA2dpProfileToDevice(true, true, true); showScreen(mController); assertThat(mProfiles.getPreferenceCount()).isEqualTo(3); // Disabling media audio should cause the high quality audio switch to disappear, but not // the regular audio one. SwitchPreferenceCompat audioPref = - (SwitchPreferenceCompat) mScreen.findPreference(audioProfile.toString()); + (SwitchPreferenceCompat) mScreen.findPreference(mA2dpProfile.toString()); audioPref.performClick(); - verify(audioProfile).setEnabled(mDevice, false); - when(audioProfile.isEnabled(mDevice)).thenReturn(false); + verify(mA2dpProfile).setEnabled(mDevice, false); + when(mA2dpProfile.isEnabled(mDevice)).thenReturn(false); mController.onDeviceAttributesChanged(); assertThat(audioPref.isVisible()).isTrue(); SwitchPreferenceCompat highQualityAudioPref = getHighQualityAudioPref(); @@ -472,8 +492,8 @@ public class BluetoothDetailsProfilesControllerTest extends BluetoothDetailsCont // And re-enabling media audio should make high quality switch to reappear. audioPref.performClick(); - verify(audioProfile).setEnabled(mDevice, true); - when(audioProfile.isEnabled(mDevice)).thenReturn(true); + verify(mA2dpProfile).setEnabled(mDevice, true); + when(mA2dpProfile.isEnabled(mDevice)).thenReturn(true); mController.onDeviceAttributesChanged(); highQualityAudioPref = getHighQualityAudioPref(); assertThat(highQualityAudioPref.isVisible()).isTrue(); @@ -482,9 +502,9 @@ public class BluetoothDetailsProfilesControllerTest extends BluetoothDetailsCont @Test public void highQualityAudio_mediaAudioStartsDisabled() { setupDevice(makeDefaultDeviceConfig()); - A2dpProfile audioProfile = addMockA2dpProfile(false, true, true); + addA2dpProfileToDevice(false, true, true); showScreen(mController); - SwitchPreferenceCompat audioPref = mScreen.findPreference(audioProfile.toString()); + SwitchPreferenceCompat audioPref = mScreen.findPreference(mA2dpProfile.toString()); SwitchPreferenceCompat highQualityAudioPref = getHighQualityAudioPref(); assertThat(audioPref).isNotNull(); assertThat(audioPref.isChecked()).isFalse(); @@ -522,15 +542,9 @@ public class BluetoothDetailsProfilesControllerTest extends BluetoothDetailsCont mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_BLUETOOTH_PROFILE_TOGGLE_VISIBILITY_CHECKER); setupDevice(makeDefaultDeviceConfig()); - LeAudioProfile leAudioProfile = mock(LeAudioProfile.class); - when(leAudioProfile.getNameResource(mDevice)) - .thenReturn(com.android.settingslib.R.string.bluetooth_profile_le_audio); - when(leAudioProfile.isProfileReady()).thenReturn(true); - when(leAudioProfile.toString()).thenReturn("LE_AUDIO"); - when(mProfileManager.getLeAudioProfile()).thenReturn(leAudioProfile); + addA2dpProfileToDevice(true, true, true); when(mFeatureProvider.getInvisibleProfilePreferenceKeys(any(), any())) - .thenReturn(ImmutableSet.of("LE_AUDIO")); - mConnectableProfiles.add(leAudioProfile); + .thenReturn(ImmutableSet.of("A2DP")); showScreen(mController); @@ -543,15 +557,9 @@ public class BluetoothDetailsProfilesControllerTest extends BluetoothDetailsCont mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_BLUETOOTH_PROFILE_TOGGLE_VISIBILITY_CHECKER); setupDevice(makeDefaultDeviceConfig()); - LeAudioProfile leAudioProfile = mock(LeAudioProfile.class); - when(leAudioProfile.getNameResource(mDevice)) - .thenReturn(com.android.settingslib.R.string.bluetooth_profile_le_audio); - when(leAudioProfile.isProfileReady()).thenReturn(true); - when(leAudioProfile.toString()).thenReturn("LE_AUDIO"); - when(mProfileManager.getLeAudioProfile()).thenReturn(leAudioProfile); + addA2dpProfileToDevice(true, true, true); when(mFeatureProvider.getInvisibleProfilePreferenceKeys(any(), any())) - .thenReturn(ImmutableSet.of("A2DP")); - mConnectableProfiles.add(leAudioProfile); + .thenReturn(ImmutableSet.of("LE_AUDIO")); showScreen(mController); @@ -563,19 +571,8 @@ public class BluetoothDetailsProfilesControllerTest extends BluetoothDetailsCont public void classicAudioDeviceWithLeAudio_showLeAudioToggle() { mSetFlagsRule.enableFlags(Flags.FLAG_HIDE_LE_AUDIO_TOGGLE_FOR_LE_AUDIO_ONLY_DEVICE); setupDevice(makeDefaultDeviceConfig()); - - LeAudioProfile leAudioProfile = mock(LeAudioProfile.class); - when(leAudioProfile.getNameResource(mDevice)) - .thenReturn(com.android.settingslib.R.string.bluetooth_profile_le_audio); - when(leAudioProfile.isProfileReady()).thenReturn(true); - when(leAudioProfile.toString()).thenReturn("LE_AUDIO"); - when(mProfileManager.getLeAudioProfile()).thenReturn(leAudioProfile); - mConnectableProfiles.add(leAudioProfile); - when(mCachedDevice.getProfiles()) - .thenAnswer( - invocation -> - ImmutableList.of( - leAudioProfile, addMockA2dpProfile(false, false, false))); + addLeAudioProfileToDevice(false); + addA2dpProfileToDevice(false, false, false); showScreen(mController); @@ -587,16 +584,7 @@ public class BluetoothDetailsProfilesControllerTest extends BluetoothDetailsCont public void leAudioOnlyDevice_hideLeAudioToggle() { mSetFlagsRule.enableFlags(Flags.FLAG_HIDE_LE_AUDIO_TOGGLE_FOR_LE_AUDIO_ONLY_DEVICE); setupDevice(makeDefaultDeviceConfig()); - - LeAudioProfile leAudioProfile = mock(LeAudioProfile.class); - when(leAudioProfile.getNameResource(mDevice)) - .thenReturn(com.android.settingslib.R.string.bluetooth_profile_le_audio); - when(leAudioProfile.isProfileReady()).thenReturn(true); - when(leAudioProfile.toString()).thenReturn("LE_AUDIO"); - when(mProfileManager.getLeAudioProfile()).thenReturn(leAudioProfile); - mConnectableProfiles.add(leAudioProfile); - when(mCachedDevice.getProfiles()) - .thenAnswer(invocation -> ImmutableList.of(leAudioProfile)); + addLeAudioProfileToDevice(false); showScreen(mController);