Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit bfcd25ed authored by Haijie Hong's avatar Haijie Hong
Browse files

Check all member devices to determine whether it's LeAudio-only device

Bug: 352431349
Test: atest BluetoothDetailsProfilesControllerTest
Flag: com.android.settings.flags.hide_le_audio_toggle_for_le_audio_only_device
Change-Id: I3697b4f3abf5f789100b63f0b7a01c3b78d70a7f
parent 62db4b3a
Loading
Loading
Loading
Loading
+7 −15
Original line number Diff line number Diff line
@@ -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<String, List<CachedBluetoothDevice>>();
    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,
+53 −65
Original line number Diff line number Diff line
@@ -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);