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

Commit 4b35f48e authored by xiaotonj's avatar xiaotonj
Browse files

Use actual device instead of requested device to enter a bluetooth

route.

Currently, we mistakenly use the requested device to get the
corresponding bluetooth route when try to transition state. While the
requeste bluetooth device address might be null so that this is only a
notification of a currently already connected device. Handle this
correctly to avoid further unexpected audio disconnection.

Bug: b/306113816
Test: atest BluetoothRouteManagerTest
Change-Id: I0dc5d8268d4ec495b4741fb17fb916547d0a7fdd
parent ec2e6728
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -34,6 +34,7 @@ aconfig_declarations {
      "telecom_callaudiomodestatemachine_flags.aconfig",
      "telecom_calllog_flags.aconfig",
      "telecom_resolve_hidden_dependencies.aconfig",
      "telecom_bluetoothroutemanager_flags.aconfig",
    ],
}
+9 −0
Original line number Diff line number Diff line
package: "com.android.server.telecom.flags"

flag {
  name: "use_actual_address_to_enter_connecting_state"
  namespace: "telecom"
  description: "Fix bugs that may add bluetooth device with null address."
  bug: "306113816"
}
+7 −2
Original line number Diff line number Diff line
@@ -393,8 +393,13 @@ public class BluetoothRouteManager extends StateMachine {
                        String actualAddress = connectBtAudio(address,
                            true /* switchingBtDevices*/);
                        if (actualAddress != null) {
                            if (mFeatureFlags.useActualAddressToEnterConnectingState()) {
                                transitionTo(getConnectingStateForAddress(actualAddress,
                                        "AudioConnected/CONNECT_BT"));
                            } else {
                                transitionTo(getConnectingStateForAddress(address,
                                        "AudioConnected/CONNECT_BT"));
                            }
                        } else {
                            Log.w(LOG_TAG, "Tried to connect to %s but failed" +
                                    " to connect to any BT device.", (String) args.arg2);
+27 −0
Original line number Diff line number Diff line
@@ -185,6 +185,33 @@ public class BluetoothRouteManagerTest extends TelecomTestCase {
        sm.quitNow();
    }

    @SmallTest
    @Test
    public void testConnectBtWithoutAddress() {
        when(mFeatureFlags.useActualAddressToEnterConnectingState()).thenReturn(true);
        BluetoothRouteManager sm = setupStateMachine(
                BluetoothRouteManager.AUDIO_CONNECTED_STATE_NAME_PREFIX, DEVICE1);
        setupConnectedDevices(new BluetoothDevice[]{DEVICE1, DEVICE2}, null, null, null, null,
                null);
        when(mTimeoutsAdapter.getRetryBluetoothConnectAudioBackoffMillis(
                nullable(ContentResolver.class))).thenReturn(0L);
        when(mBluetoothHeadset.connectAudio()).thenReturn(BluetoothStatusCodes.ERROR_UNKNOWN);
        executeRoutingAction(sm, BluetoothRouteManager.CONNECT_BT, null);
        // Wait 3 times: the first connection attempt is accounted for in executeRoutingAction,
        // so wait twice for the retry attempt, again to make sure there are only three attempts,
        // and once more for good luck.
        waitForHandlerAction(sm.getHandler(), TEST_TIMEOUT);
        waitForHandlerAction(sm.getHandler(), TEST_TIMEOUT);
        waitForHandlerAction(sm.getHandler(), TEST_TIMEOUT);
        waitForHandlerAction(sm.getHandler(), TEST_TIMEOUT);
        verifyConnectionAttempt(DEVICE1, 1);
        assertEquals(BluetoothRouteManager.AUDIO_CONNECTED_STATE_NAME_PREFIX
                        + ":" + DEVICE1.getAddress(),
                sm.getCurrentState().getName());
        sm.getHandler().removeMessages(BluetoothRouteManager.CONNECTION_TIMEOUT);
        sm.quitNow();
    }

    private BluetoothRouteManager setupStateMachine(String initialState,
            BluetoothDevice initialDevice) {
        resetMocks();