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

Commit 705f9a84 authored by chelseahao's avatar chelseahao Committed by Chelsea Hao
Browse files

When adding member devices, sync profiles.

Test: atest CachedBluetoothDeviceTest
Bug: 308116836
Change-Id: I49cd677c111872c639e856809854c376e44c759f
parent 647dbb62
Loading
Loading
Loading
Loading
+36 −0
Original line number Diff line number Diff line
@@ -1788,4 +1788,40 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice>
    boolean getUnpairing() {
        return mUnpairing;
    }

    ListenableFuture<Void> syncProfileForMemberDevice() {
        return ThreadUtils.getBackgroundExecutor()
            .submit(
                () -> {
                    List<Pair<LocalBluetoothProfile, Boolean>> toSync =
                        Stream.of(
                            mProfileManager.getA2dpProfile(),
                            mProfileManager.getHeadsetProfile(),
                            mProfileManager.getHearingAidProfile(),
                            mProfileManager.getLeAudioProfile(),
                            mProfileManager.getLeAudioBroadcastAssistantProfile())
                        .filter(Objects::nonNull)
                        .map(profile -> new Pair<>(profile, profile.isEnabled(mDevice)))
                        .toList();

                    for (var t : toSync) {
                        LocalBluetoothProfile profile = t.first;
                        boolean enabledForMain = t.second;

                        for (var member : mMemberDevices) {
                            BluetoothDevice btDevice = member.getDevice();

                            if (enabledForMain != profile.isEnabled(btDevice)) {
                                Log.d(TAG, "Syncing profile " + profile + " to "
                                        + enabledForMain + " for member device "
                                        + btDevice.getAnonymizedAddress() + " of main device "
                                        + mDevice.getAnonymizedAddress());
                                profile.setEnabled(btDevice, enabledForMain);
                            }
                        }
                    }
                    return null;
                }
            );
    }
}
+1 −0
Original line number Diff line number Diff line
@@ -349,6 +349,7 @@ public class CachedBluetoothDeviceManager {
        if (profileId == BluetoothProfile.HEADSET
                || profileId == BluetoothProfile.A2DP
                || profileId == BluetoothProfile.LE_AUDIO
                || profileId == BluetoothProfile.LE_AUDIO_BROADCAST_ASSISTANT
                || profileId == BluetoothProfile.CSIP_SET_COORDINATOR) {
            return mCsipDeviceManager.onProfileConnectionStateChangedIfProcessed(cachedDevice,
                state);
+1 −0
Original line number Diff line number Diff line
@@ -379,6 +379,7 @@ public class CsipDeviceManager {
        if (hasChanged) {
            log("addMemberDevicesIntoMainDevice: After changed, CachedBluetoothDevice list: "
                    + mCachedDevices);
            preferredMainDevice.syncProfileForMemberDevice();
        }
        return hasChanged;
    }
+50 −0
Original line number Diff line number Diff line
@@ -18,7 +18,9 @@ package com.android.settingslib.bluetooth;
import static com.google.common.truth.Truth.assertThat;

import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
@@ -56,6 +58,8 @@ import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
import org.robolectric.shadow.api.Shadow;

import java.util.concurrent.ExecutionException;

@RunWith(RobolectricTestRunner.class)
@Config(shadows = {ShadowBluetoothAdapter.class})
public class CachedBluetoothDeviceTest {
@@ -1815,6 +1819,52 @@ public class CachedBluetoothDeviceTest {
        assertThat(mCachedDevice.isConnectedHearingAidDevice()).isFalse();
    }

    @Test
    public void syncProfileForMemberDevice_hasDiff_shouldSync()
            throws ExecutionException, InterruptedException {
        mCachedDevice.addMemberDevice(mSubCachedDevice);
        when(mProfileManager.getA2dpProfile()).thenReturn(mA2dpProfile);
        when(mProfileManager.getHearingAidProfile()).thenReturn(mHearingAidProfile);
        when(mProfileManager.getLeAudioProfile()).thenReturn(mLeAudioProfile);

        when(mA2dpProfile.isEnabled(mDevice)).thenReturn(true);
        when(mHearingAidProfile.isEnabled(mDevice)).thenReturn(true);
        when(mLeAudioProfile.isEnabled(mDevice)).thenReturn(true);

        when(mA2dpProfile.isEnabled(mSubDevice)).thenReturn(true);
        when(mHearingAidProfile.isEnabled(mSubDevice)).thenReturn(false);
        when(mLeAudioProfile.isEnabled(mSubDevice)).thenReturn(false);

        mCachedDevice.syncProfileForMemberDevice().get();

        verify(mA2dpProfile, never()).setEnabled(any(BluetoothDevice.class), anyBoolean());
        verify(mHearingAidProfile).setEnabled(any(BluetoothDevice.class), eq(true));
        verify(mLeAudioProfile).setEnabled(any(BluetoothDevice.class), eq(true));
    }

    @Test
    public void syncProfileForMemberDevice_noDiff_shouldNotSync()
            throws ExecutionException, InterruptedException {
        mCachedDevice.addMemberDevice(mSubCachedDevice);
        when(mProfileManager.getA2dpProfile()).thenReturn(mA2dpProfile);
        when(mProfileManager.getHearingAidProfile()).thenReturn(mHearingAidProfile);
        when(mProfileManager.getLeAudioProfile()).thenReturn(mLeAudioProfile);

        when(mA2dpProfile.isEnabled(mDevice)).thenReturn(false);
        when(mHearingAidProfile.isEnabled(mDevice)).thenReturn(false);
        when(mLeAudioProfile.isEnabled(mDevice)).thenReturn(true);

        when(mA2dpProfile.isEnabled(mSubDevice)).thenReturn(false);
        when(mHearingAidProfile.isEnabled(mSubDevice)).thenReturn(false);
        when(mLeAudioProfile.isEnabled(mSubDevice)).thenReturn(true);

        mCachedDevice.syncProfileForMemberDevice().get();

        verify(mA2dpProfile, never()).setEnabled(any(BluetoothDevice.class), anyBoolean());
        verify(mHearingAidProfile, never()).setEnabled(any(BluetoothDevice.class), anyBoolean());
        verify(mLeAudioProfile, never()).setEnabled(any(BluetoothDevice.class), anyBoolean());
    }

    private HearingAidInfo getLeftAshaHearingAidInfo() {
        return new HearingAidInfo.Builder()
                .setAshaDeviceSide(HearingAidProfile.DeviceSide.SIDE_LEFT)