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

Commit d776c178 authored by Pranav Madapurmath's avatar Pranav Madapurmath
Browse files

Use current active BT device in active routing

When we receive the BT_ACTIVE_DEVICE_PRESENT message in the
CallAudioRouteController, ensure that we only attempt to route into the
specified BT device if it's still the currently active device. When we
receive indication from the BT stack of what the new active device is
for any given BT profile, we update the active device cache stored in
CallAudioRouteController immediately before sending the message request
to process BT_ACTIVE_DEVICE_PRESENT. We have seen cases where by the
time the message is processed by the handler, the active device has
changed causing a potential loop when multiple BT devices are trying to
connect.

Bug: 389155187
Flag: EXEMPT bugfix
Test: atest CallAudioRouteControllerTest
Change-Id: I28004763cb21bc79f614f61ee41ec8d049d26d8d
parent 74b2a342
Loading
Loading
Loading
Loading
+5 −3
Original line number Diff line number Diff line
@@ -849,13 +849,15 @@ public class CallAudioRouteController implements CallAudioRouteAdapter {
    private void handleBtActiveDevicePresent(@AudioRoute.AudioRouteType int type,
            String deviceAddress) {
        AudioRoute bluetoothRoute = getBluetoothRoute(type, deviceAddress);
        if (bluetoothRoute != null) {
        boolean isBtDeviceCurrentActive = Objects.equals(bluetoothRoute,
                getArbitraryBluetoothDevice());
        if (bluetoothRoute != null && isBtDeviceCurrentActive) {
            Log.i(this, "request to route to bluetooth route: %s (active=%b)", bluetoothRoute,
                    mIsActive);
            routeTo(mIsActive, bluetoothRoute);
        } else {
            Log.i(this, "request to route to unavailable bluetooth route - type (%s), address (%s)",
                    type, deviceAddress);
            Log.i(this, "request to route to unavailable bluetooth route or the route isn't the "
                    + "currently active device - type (%s), address (%s)", type, deviceAddress);
        }
    }

+50 −0
Original line number Diff line number Diff line
@@ -1357,6 +1357,56 @@ public class CallAudioRouteControllerTest extends TelecomTestCase {
        verify(mCallAudioManager, timeout(TEST_TIMEOUT)).notifyAudioOperationsComplete();
    }

    @Test
    @SmallTest
    public void testActiveDevicePresentRoutesOnCurrentActive() {
        when(mFeatureFlags.resolveActiveBtRoutingAndBtTimingIssue()).thenReturn(true);
        // Connect first BT device.
        verifyConnectBluetoothDevice(AudioRoute.TYPE_BLUETOOTH_SCO);
        // Connect another BT device.
        String scoDeviceAddress = "00:00:00:00:00:03";
        BluetoothDevice scoDevice2 =
                BluetoothRouteManagerTest.makeBluetoothDevice(scoDeviceAddress);
        BLUETOOTH_DEVICES.add(scoDevice2);

        // Signal second BT device added in controller and verify routing to that device upon
        // receiving active focus.
        mController.sendMessageWithSessionInfo(BT_DEVICE_ADDED, AudioRoute.TYPE_BLUETOOTH_SCO,
                scoDevice2);
        CallAudioState expectedState = new CallAudioState(false, CallAudioState.ROUTE_BLUETOOTH,
                CallAudioState.ROUTE_EARPIECE | CallAudioState.ROUTE_SPEAKER
                        | CallAudioState.ROUTE_BLUETOOTH, BLUETOOTH_DEVICE_1, BLUETOOTH_DEVICES);
        mController.sendMessageWithSessionInfo(SWITCH_FOCUS, ACTIVE_FOCUS, 0);
        verify(mCallsManager, timeout(TEST_TIMEOUT)).onCallAudioStateChanged(
                any(CallAudioState.class), eq(expectedState));

        // Update the currently tracked active device to be BLUETOOTH_DEVICE_1.
        mController.updateActiveBluetoothDevice(
                new Pair<>(AudioRoute.TYPE_BLUETOOTH_SCO, BLUETOOTH_DEVICE_1.getAddress()));
        // Verify that sending BT_ACTIVE_DEVICE_PRESENT when BLUETOOTH_DEVICE_1 isn't the currently
        // tracked active device, that we ignore routing.
        mController.sendMessageWithSessionInfo(BT_ACTIVE_DEVICE_PRESENT,
                AudioRoute.TYPE_BLUETOOTH_SCO, scoDevice2.getAddress());
        verify(mCallsManager, timeout(TEST_TIMEOUT)).onCallAudioStateChanged(
                any(CallAudioState.class), eq(expectedState));

        // Now update the active device so that it's scoDevice2 and verify that
        // BT_ACTIVE_DEVICE_PRESENT is properly processed and that we route into the device.
        mController.updateActiveBluetoothDevice(
                new Pair<>(AudioRoute.TYPE_BLUETOOTH_SCO, scoDevice2.getAddress()));
        mController.sendMessageWithSessionInfo(BT_ACTIVE_DEVICE_PRESENT,
                AudioRoute.TYPE_BLUETOOTH_SCO, scoDevice2.getAddress());
        mController.sendMessageWithSessionInfo(BT_AUDIO_DISCONNECTED, 0,
                BLUETOOTH_DEVICE_1);
        mController.sendMessageWithSessionInfo(BT_AUDIO_CONNECTED,
                0, scoDevice2);
        expectedState = new CallAudioState(false, CallAudioState.ROUTE_BLUETOOTH,
                CallAudioState.ROUTE_EARPIECE | CallAudioState.ROUTE_SPEAKER
                        | CallAudioState.ROUTE_BLUETOOTH, scoDevice2, BLUETOOTH_DEVICES);
        verify(mCallsManager, timeout(TEST_TIMEOUT)).onCallAudioStateChanged(
                any(CallAudioState.class), eq(expectedState));
    }

    private void verifyConnectBluetoothDevice(int audioType) {
        mController.initialize();
        mController.setActive(true);