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

Commit 4c51f97a authored by Michal Belusiak's avatar Michal Belusiak
Browse files

ActiveDeviceManager: Fix handling of LEA group devices

Bug: 316958532
Bug: 324364321
Test: atest ActiveDeviceManagerTest
Change-Id: I942e867f154e84e295928d55a8e9aa769c18707b
parent 06af2f0e
Loading
Loading
Loading
Loading
+16 −1
Original line number Diff line number Diff line
@@ -987,6 +987,16 @@ public class ActiveDeviceManager implements AdapterService.BluetoothStateCallbac
            if (device == null) {
                success = leAudioService.removeActiveDevice(hasFallbackDevice);
            } else {
                if (mFeatureFlags.leaudioActiveDeviceManagerGroupHandlingFix()) {
                    if ((mLeAudioActiveDevice != null)
                            && (Objects.equals(
                                    mLeAudioActiveDevice, leAudioService.getLeadDevice(device)))) {
                        if (DBG) {
                            Log.d(TAG, "New LeAudioDevice is a part of an active group");
                        }
                        return true;
                    }
                }
                success = leAudioService.setActiveDevice(device);
            }

@@ -994,7 +1004,12 @@ public class ActiveDeviceManager implements AdapterService.BluetoothStateCallbac
                return false;
            }

            if (mFeatureFlags.leaudioActiveDeviceManagerGroupHandlingFix()) {
                mLeAudioActiveDevice = leAudioService.getLeadDevice(device);
            } else {
                mLeAudioActiveDevice = device;
            }

            if (device == null) {
                mLeHearingAidActiveDevice = null;
                mPendingLeHearingAidActiveDevice.remove(device);
+48 −4
Original line number Diff line number Diff line
@@ -122,6 +122,7 @@ public class ActiveDeviceManagerTest {

        mFakeFlagsImpl = new FakeFeatureFlagsImpl();
        mFakeFlagsImpl.setFlag(Flags.FLAG_LEAUDIO_BROADCAST_AUDIO_HANDOVER_POLICIES, false);
        mFakeFlagsImpl.setFlag(Flags.FLAG_LEAUDIO_ACTIVE_DEVICE_MANAGER_GROUP_HANDLING_FIX, false);
        mDatabaseManager = new TestDatabaseManager(mAdapterService, mFakeFlagsImpl);

        when(mAdapterService.getSystemService(Context.AUDIO_SERVICE)).thenReturn(mAudioManager);
@@ -160,6 +161,11 @@ public class ActiveDeviceManagerTest {
        when(mLeAudioService.setActiveDevice(any())).thenReturn(true);
        when(mLeAudioService.removeActiveDevice(anyBoolean())).thenReturn(true);

        when(mLeAudioService.getLeadDevice(mLeAudioDevice)).thenReturn(mLeAudioDevice);
        when(mLeAudioService.getLeadDevice(mLeAudioDevice2)).thenReturn(mLeAudioDevice2);
        when(mLeAudioService.getLeadDevice(mDualModeAudioDevice)).thenReturn(mDualModeAudioDevice);
        when(mLeAudioService.getLeadDevice(mLeHearingAidDevice)).thenReturn(mLeHearingAidDevice);

        List<BluetoothDevice> connectedHearingAidDevices = new ArrayList<>();
        connectedHearingAidDevices.add(mHearingAidDevice);
        when(mHearingAidService.getHiSyncId(mHearingAidDevice)).thenReturn(mHearingAidHiSyncId);
@@ -742,11 +748,11 @@ public class ActiveDeviceManagerTest {
        leAudioConnected(mLeAudioDevice);
        verify(mLeAudioService, timeout(TIMEOUT_MS)).setActiveDevice(mLeAudioDevice);

        leAudioConnected(mSecondaryAudioDevice);
        verify(mLeAudioService, timeout(TIMEOUT_MS)).setActiveDevice(mSecondaryAudioDevice);
        leAudioConnected(mLeAudioDevice2);
        verify(mLeAudioService, timeout(TIMEOUT_MS)).setActiveDevice(mLeAudioDevice2);

        Mockito.clearInvocations(mLeAudioService);
        leAudioDisconnected(mSecondaryAudioDevice);
        leAudioDisconnected(mLeAudioDevice2);
        verify(mLeAudioService, timeout(TIMEOUT_MS)).setActiveDevice(mLeAudioDevice);
    }

@@ -905,6 +911,35 @@ public class ActiveDeviceManagerTest {
        verify(mLeAudioService, timeout(TIMEOUT_MS)).deviceDisconnected(mLeAudioDevice2, true);
    }

    @Test
    public void leAudioSetConnectedGroupThenDisconnected_noFallback() {
        mFakeFlagsImpl.setFlag(Flags.FLAG_LEAUDIO_ACTIVE_DEVICE_MANAGER_GROUP_HANDLING_FIX, true);
        when(mAudioManager.getMode()).thenReturn(AudioManager.MODE_NORMAL);

        leAudioConnected(mLeAudioDevice);
        TestUtils.waitForLooperToFinishScheduledTask(mActiveDeviceManager.getHandlerLooper());
        verify(mLeAudioService, timeout(TIMEOUT_MS)).setActiveDevice(mLeAudioDevice);

        Mockito.clearInvocations(mLeAudioService);

        when(mLeAudioService.getLeadDevice(mLeAudioDevice2)).thenReturn(mLeAudioDevice);
        leAudioConnected(mLeAudioDevice2);
        TestUtils.waitForLooperToFinishScheduledTask(mActiveDeviceManager.getHandlerLooper());
        verify(mLeAudioService, never()).setActiveDevice(any());

        Mockito.clearInvocations(mLeAudioService);

        leAudioDisconnected(mLeAudioDevice2);
        TestUtils.waitForLooperToFinishScheduledTask(mActiveDeviceManager.getHandlerLooper());
        verify(mLeAudioService, never()).setActiveDevice(any());
        verify(mLeAudioService, never()).removeActiveDevice(anyBoolean());

        leAudioDisconnected(mLeAudioDevice);
        TestUtils.waitForLooperToFinishScheduledTask(mActiveDeviceManager.getHandlerLooper());
        verify(mLeAudioService, timeout(TIMEOUT_MS)).removeActiveDevice(false);
        verify(mLeAudioService, timeout(TIMEOUT_MS)).deviceDisconnected(mLeAudioDevice2, false);
    }

    /**
     * An A2DP connected. An LE Audio connected. The LE Audio disconnected.
     * Then the A2DP should be the active one.
@@ -1089,15 +1124,24 @@ public class ActiveDeviceManagerTest {

        when(mLeAudioService.setActiveDevice(any())).thenReturn(true);
        when(mLeAudioService.removeActiveDevice(anyBoolean())).thenReturn(true);
        when(mLeAudioService.getLeadDevice(mDualModeAudioDevice)).thenReturn(mDualModeAudioDevice);

        Mockito.clearInvocations(mLeAudioService);

        // Ensure we make LEA active after all supported classic profiles are active
        a2dpActiveDeviceChanged(mDualModeAudioDevice);
        TestUtils.waitForLooperToFinishScheduledTask(mActiveDeviceManager.getHandlerLooper());

        when(mAdapterService.isAllSupportedClassicAudioProfilesActive(mDualModeAudioDevice))
                .thenReturn(true);
        headsetActiveDeviceChanged(mDualModeAudioDevice);
        TestUtils.waitForLooperToFinishScheduledTask(mActiveDeviceManager.getHandlerLooper());
        verify(mLeAudioService, times(2)).setActiveDevice(mDualModeAudioDevice);

        // When A2DP device is getting active, first LeAudio device is removed from active devices
        // and later added
        verify(mLeAudioService, times(1)).removeActiveDevice(anyBoolean());
        verify(mLeAudioService, times(1)).setActiveDevice(mDualModeAudioDevice);

        Assert.assertEquals(mDualModeAudioDevice, mActiveDeviceManager.getA2dpActiveDevice());
        Assert.assertEquals(mDualModeAudioDevice, mActiveDeviceManager.getHfpActiveDevice());
        Assert.assertEquals(mDualModeAudioDevice, mActiveDeviceManager.getLeAudioActiveDevice());
+2 −0
Original line number Diff line number Diff line
@@ -51,6 +51,7 @@ import com.android.bluetooth.a2dp.A2dpService;
import com.android.bluetooth.btservice.storage.DatabaseManager;
import com.android.bluetooth.flags.FakeFeatureFlagsImpl;
import com.android.bluetooth.flags.FeatureFlags;
import com.android.bluetooth.flags.Flags;
import com.android.bluetooth.hearingaid.HearingAidService;
import com.android.bluetooth.hfp.HeadsetService;
import com.android.bluetooth.le_audio.LeAudioService;
@@ -117,6 +118,7 @@ public class AudioRoutingManagerTest {
        TestUtils.setAdapterService(mAdapterService);

        mFakeFlagsImpl = new FakeFeatureFlagsImpl();
        mFakeFlagsImpl.setFlag(Flags.FLAG_LEAUDIO_ACTIVE_DEVICE_MANAGER_GROUP_HANDLING_FIX, false);
        mDatabaseManager = new TestDatabaseManager(mAdapterService, mFakeFlagsImpl);

        when(mAdapterService.getSystemService(Context.AUDIO_SERVICE)).thenReturn(mAudioManager);