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

Commit d3a67dc4 authored by Haijie Hong's avatar Haijie Hong Committed by Android (Google) Code Review
Browse files

Merge "Check all member devices to determine whether it's LeAudio-only device" into main

parents e2c83cae bfcd25ed
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);