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

Commit 0456d4ea authored by Sungsoo Lim's avatar Sungsoo Lim
Browse files

Refactoring: Audio Routing Handler (Step 1)

This CL refactors connection and activation events to be handled in
the AudioRoutingHandler. This will remove the mLock and migrate the
variables guarded by the mLock into the handler.

It will also remove the priority of hearing aid devices so that they
are activated at the same level as other BT devices.

This CL refactors the connection events of A2DP and HFP, and more CLs
will follow.

Bug: 299023147
Test: atest BluetoothInstrumentationTests
Change-Id: I2c6ac3cafb1ee2f68c9b33b624b0769762e08fcd
parent 2fa9276a
Loading
Loading
Loading
Loading
+343 −193

File changed.

Preview size limit exceeded, changes collapsed.

+31 −68
Original line number Diff line number Diff line
@@ -580,31 +580,30 @@ public class AudioRoutingManagerTest {

    /** A Hearing Aid is connected. Then a combo (A2DP + Headset) device is connected. */
    @Test
    public void hearingAidActive_dontSetA2dpAndHeadsetActive() {
    public void hearingAidAndA2dpHeadsetConnected_setA2dpHeadsetActive() {
        hearingAidActiveDeviceChanged(mHearingAidDevice);
        a2dpConnected(mA2dpHeadsetDevice, true);
        headsetConnected(mA2dpHeadsetDevice, true);

        TestUtils.waitForLooperToFinishScheduledTask(mAudioRoutingManager.getHandlerLooper());
        verify(mA2dpService, never()).setActiveDevice(mA2dpHeadsetDevice);
        verify(mHeadsetService, never()).setActiveDevice(mA2dpHeadsetDevice);
        verify(mHearingAidService).removeActiveDevice(false);
        verify(mA2dpService).setActiveDevice(mA2dpHeadsetDevice);
        verify(mHeadsetService).setActiveDevice(mA2dpHeadsetDevice);
    }

    /** A Hearing Aid is connected. Then an A2DP active device is explicitly set. */
    /** A Hearing Aid is connected. Then an A2DP connected. */
    @Test
    public void hearingAidActive_setA2dpActiveExplicitly() {
        when(mHearingAidService.removeActiveDevice(anyBoolean())).thenReturn(true);

        hearingAidActiveDeviceChanged(mHearingAidDevice);
        a2dpConnected(mA2dpDevice, false);
        a2dpActiveDeviceChanged(mA2dpDevice);

        TestUtils.waitForLooperToFinishScheduledTask(mAudioRoutingManager.getHandlerLooper());
        verify(mHearingAidService).removeActiveDevice(false);
        // Don't call mA2dpService.setActiveDevice()
        verify(mA2dpService, never()).setActiveDevice(mA2dpDevice);

        assertThat(mAudioRoutingManager.getA2dpActiveDevice()).isEqualTo(mA2dpDevice);
        assertThat(mAudioRoutingManager.getHearingAidActiveDevices().isEmpty()).isTrue();
        assertThat(mAudioRoutingManager.getHearingAidActiveDevices()).isEmpty();
    }

    /** A Hearing Aid is connected. Then a Headset active device is explicitly set. */
@@ -614,14 +613,11 @@ public class AudioRoutingManagerTest {

        hearingAidActiveDeviceChanged(mHearingAidDevice);
        headsetConnected(mHeadsetDevice, false);
        headsetActiveDeviceChanged(mHeadsetDevice);

        TestUtils.waitForLooperToFinishScheduledTask(mAudioRoutingManager.getHandlerLooper());
        verify(mHearingAidService).removeActiveDevice(false);
        // Don't call mHeadsetService.setActiveDevice()
        verify(mHeadsetService, never()).setActiveDevice(mHeadsetDevice);
        assertThat(mAudioRoutingManager.getHfpActiveDevice()).isEqualTo(mHeadsetDevice);
        assertThat(mAudioRoutingManager.getHearingAidActiveDevices().isEmpty()).isTrue();
        assertThat(mAudioRoutingManager.getHearingAidActiveDevices()).isEmpty();
    }

    @Test
@@ -883,36 +879,6 @@ public class AudioRoutingManagerTest {
        verify(mHearingAidService, timeout(TIMEOUT_MS)).setActiveDevice(mHearingAidDevice);
    }

    /**
     * Hearing aid is connected, but active device is different BT. When the active device is
     * disconnected, the hearing aid should be the active one.
     */
    @Test
    public void activeDeviceDisconnected_fallbackToHearingAid() {
        when(mAudioManager.getMode()).thenReturn(AudioManager.MODE_NORMAL);
        when(mA2dpService.setActiveDevice(any())).thenReturn(true);
        when(mLeAudioService.setActiveDevice(any())).thenReturn(true);
        when(mHearingAidService.setActiveDevice(any())).thenReturn(true);
        when(mHearingAidService.removeActiveDevice(anyBoolean())).thenReturn(true);

        hearingAidConnected(mHearingAidDevice);
        verify(mHearingAidService, timeout(TIMEOUT_MS)).setActiveDevice(mHearingAidDevice);

        leAudioConnected(mLeAudioDevice);
        a2dpConnected(mA2dpDevice, false);

        a2dpActiveDeviceChanged(mA2dpDevice);
        TestUtils.waitForLooperToFinishScheduledTask(mAudioRoutingManager.getHandlerLooper());

        verify(mHearingAidService).removeActiveDevice(false);
        verify(mLeAudioService, never()).setActiveDevice(mLeAudioDevice);
        verify(mA2dpService, never()).setActiveDevice(mA2dpDevice);

        a2dpDisconnected(mA2dpDevice);
        verify(mA2dpService, timeout(TIMEOUT_MS).atLeast(1)).removeActiveDevice(false);
        verify(mHearingAidService, timeout(TIMEOUT_MS).times(2)).setActiveDevice(mHearingAidDevice);
    }

    /** One LE Hearing Aid is connected. */
    @Test
    public void onlyLeHearingAidConnected_setLeAudioActive() {
@@ -937,7 +903,7 @@ public class AudioRoutingManagerTest {
    }

    /**
     * Test connect/disconnect of devices. Hearing Aid, LE Hearing Aid, A2DP connected, then LE
     * Test connect/disconnect of devices. Hearing Aid, A2DP connected, LE Hearing Aid, then LE
     * hearing Aid and hearing aid disconnected.
     */
    @Test
@@ -948,22 +914,21 @@ public class AudioRoutingManagerTest {
        hearingAidConnected(mHearingAidDevice);
        verify(mHearingAidService, timeout(TIMEOUT_MS)).setActiveDevice(mHearingAidDevice);

        a2dpConnected(mA2dpDevice, false);
        verify(mA2dpService, timeout(TIMEOUT_MS)).setActiveDevice(mA2dpDevice);
        verify(mHearingAidService, timeout(TIMEOUT_MS)).removeActiveDevice(false);

        Mockito.clearInvocations(mHearingAidService, mA2dpService, mLeAudioService);
        leHearingAidConnected(mLeHearingAidDevice);
        leAudioConnected(mLeHearingAidDevice);
        verify(mLeAudioService, timeout(TIMEOUT_MS)).setActiveDevice(mLeHearingAidDevice);
        verify(mA2dpService, timeout(TIMEOUT_MS)).removeActiveDevice(false);

        a2dpConnected(mA2dpDevice, false);
        TestUtils.waitForLooperToFinishScheduledTask(mAudioRoutingManager.getHandlerLooper());
        verify(mA2dpService, never()).setActiveDevice(mA2dpDevice);

        Mockito.clearInvocations(mHearingAidService, mA2dpService);
        Mockito.clearInvocations(mHearingAidService, mA2dpService, mLeAudioService);
        leHearingAidDisconnected(mLeHearingAidDevice);
        leAudioDisconnected(mLeHearingAidDevice);
        verify(mHearingAidService, timeout(TIMEOUT_MS)).setActiveDevice(mHearingAidDevice);
        verify(mA2dpService, timeout(TIMEOUT_MS)).removeActiveDevice(false);

        hearingAidDisconnected(mHearingAidDevice);
        verify(mA2dpService, timeout(TIMEOUT_MS)).setActiveDevice(mA2dpDevice);
        verify(mLeAudioService, timeout(TIMEOUT_MS)).removeActiveDevice(true);
    }

    /**
@@ -982,7 +947,6 @@ public class AudioRoutingManagerTest {
                .setActiveDevice(mDualModeAudioDevice);
        verify(mHeadsetService, timeout(TIMEOUT_MS).atLeastOnce())
                .setActiveDevice(mDualModeAudioDevice);
        verify(mLeAudioService, timeout(TIMEOUT_MS).atLeastOnce()).removeActiveDevice(true);
        assertThat(mAudioRoutingManager.getA2dpActiveDevice()).isEqualTo(mDualModeAudioDevice);
        assertThat(mAudioRoutingManager.getHfpActiveDevice()).isEqualTo(mDualModeAudioDevice);

@@ -1050,46 +1014,45 @@ public class AudioRoutingManagerTest {

        leAudioConnected(mDualModeAudioDevice);
        TestUtils.waitForLooperToFinishScheduledTask(mAudioRoutingManager.getHandlerLooper());
        verify(mLeAudioService, timeout(TIMEOUT_MS)).setActiveDevice(mDualModeAudioDevice);
        verify(mLeAudioService).setActiveDevice(mDualModeAudioDevice);

        leAudioActiveDeviceChanged(mDualModeAudioDevice);
        TestUtils.waitForLooperToFinishScheduledTask(mAudioRoutingManager.getHandlerLooper());
        verify(mA2dpService, times(1)).removeActiveDevice(anyBoolean());
        verify(mHeadsetService, times(1)).setActiveDevice(null);
        verify(mHearingAidService, times(1)).removeActiveDevice(anyBoolean());
        verify(mA2dpService).removeActiveDevice(anyBoolean());
        verify(mHeadsetService).setActiveDevice(null);
        verify(mHearingAidService).removeActiveDevice(anyBoolean());

        a2dpConnected(mA2dpDevice, false);
        TestUtils.waitForLooperToFinishScheduledTask(mAudioRoutingManager.getHandlerLooper());
        verify(mA2dpService, timeout(TIMEOUT_MS)).setActiveDevice(mA2dpDevice);
        verify(mA2dpService).setActiveDevice(mA2dpDevice);
        verify(mLeAudioService, never()).removeActiveDevice(anyBoolean());

        a2dpConnected(mA2dpHeadsetDevice, true);
        headsetConnected(mA2dpHeadsetDevice, true);
        TestUtils.waitForLooperToFinishScheduledTask(mAudioRoutingManager.getHandlerLooper());
        verify(mA2dpService, timeout(TIMEOUT_MS).atLeastOnce()).setActiveDevice(mA2dpHeadsetDevice);
        verify(mHeadsetService, timeout(TIMEOUT_MS).atLeastOnce())
                .setActiveDevice(mA2dpHeadsetDevice);
        verify(mA2dpService, atLeastOnce()).setActiveDevice(mA2dpHeadsetDevice);
        verify(mHeadsetService, atLeastOnce()).setActiveDevice(mA2dpHeadsetDevice);
        verify(mLeAudioService, never()).removeActiveDevice(anyBoolean());

        headsetConnected(mHeadsetDevice, false);
        TestUtils.waitForLooperToFinishScheduledTask(mAudioRoutingManager.getHandlerLooper());
        verify(mHeadsetService, timeout(TIMEOUT_MS)).setActiveDevice(mHeadsetDevice);
        verify(mHeadsetService).setActiveDevice(mHeadsetDevice);
        verify(mLeAudioService, never()).removeActiveDevice(anyBoolean());

        hearingAidConnected(mHearingAidDevice);
        TestUtils.waitForLooperToFinishScheduledTask(mAudioRoutingManager.getHandlerLooper());
        verify(mHearingAidService, timeout(TIMEOUT_MS)).setActiveDevice(mHearingAidDevice);
        verify(mHearingAidService).setActiveDevice(mHearingAidDevice);
        verify(mLeAudioService, never()).removeActiveDevice(anyBoolean());
        verify(mA2dpService, times(1)).removeActiveDevice(anyBoolean());
        verify(mHeadsetService, times(1)).setActiveDevice(null);
        verify(mA2dpService).removeActiveDevice(anyBoolean());
        verify(mHeadsetService).setActiveDevice(null);

        leAudioConnected(mLeHearingAidDevice);
        leHearingAidConnected(mLeHearingAidDevice);
        TestUtils.waitForLooperToFinishScheduledTask(mAudioRoutingManager.getHandlerLooper());
        verify(mLeAudioService, times(2)).setActiveDevice(mLeHearingAidDevice);
        verify(mA2dpService, times(1)).removeActiveDevice(anyBoolean());
        verify(mHeadsetService, times(1)).setActiveDevice(null);
        verify(mHearingAidService, times(1)).removeActiveDevice(anyBoolean());
        verify(mA2dpService).removeActiveDevice(anyBoolean());
        verify(mHeadsetService).setActiveDevice(null);
        verify(mHearingAidService).removeActiveDevice(anyBoolean());
    }

    /** A wired audio device is connected. Then all active devices are set to null. */