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

Commit 441c9576 authored by Pranav Madapurmath's avatar Pranav Madapurmath Committed by Android (Google) Code Review
Browse files

Merge "Resolve user switch baseline route for video calls" into main

parents 48d6b0df 463dc7c6
Loading
Loading
Loading
Loading
+11 −0
Original line number Diff line number Diff line
@@ -118,3 +118,14 @@ flag {
    purpose: PURPOSE_BUGFIX
  }
}

# OWNER=pmadapurmath TARGET=25Q2
flag {
  name: "fix_user_request_baseline_route_video_call"
  namespace: "telecom"
  description: "Ensure that audio is routed out of speaker in a video call when we receive USER_SWITCH_BASELINE_ROUTE."
  bug: "374037591"
  metadata {
    purpose: PURPOSE_BUGFIX
  }
}
+24 −16
Original line number Diff line number Diff line
@@ -306,12 +306,12 @@ public class CallAudioRouteController implements CallAudioRouteAdapter {
                            break;
                        case SWITCH_BASELINE_ROUTE:
                            address = (String) ((SomeArgs) msg.obj).arg2;
                            handleSwitchBaselineRoute(msg.arg1 == INCLUDE_BLUETOOTH_IN_BASELINE,
                                    address);
                            handleSwitchBaselineRoute(false,
                                    msg.arg1 == INCLUDE_BLUETOOTH_IN_BASELINE, address);
                            break;
                        case USER_SWITCH_BASELINE_ROUTE:
                            handleSwitchBaselineRoute(msg.arg1 == INCLUDE_BLUETOOTH_IN_BASELINE,
                                    null);
                            handleSwitchBaselineRoute(true,
                                    msg.arg1 == INCLUDE_BLUETOOTH_IN_BASELINE, null);
                            break;
                        case SPEAKER_ON:
                            handleSpeakerOn();
@@ -889,7 +889,7 @@ public class CallAudioRouteController implements CallAudioRouteAdapter {
                    // speaker, route back to earpiece). If we're on BT, remain on BT if it's still
                    // connected.
                    AudioRoute route = mFeatureFlags.resolveActiveBtRoutingAndBtTimingIssue()
                            ? calculateBaselineRoute(true, null)
                            ? calculateBaselineRoute(false, true, null)
                            : mCurrentRoute;
                    routeTo(false, route);
                    // Clear pending messages
@@ -1010,7 +1010,8 @@ public class CallAudioRouteController implements CallAudioRouteAdapter {
        }
    }

    private void handleSwitchBaselineRoute(boolean includeBluetooth, String btAddressToExclude) {
    private void handleSwitchBaselineRoute(boolean isExplicitUserRequest, boolean includeBluetooth,
            String btAddressToExclude) {
        Log.i(this, "handleSwitchBaselineRoute: includeBluetooth: %b, "
                + "btAddressToExclude: %s", includeBluetooth, btAddressToExclude);
        boolean areExcludedBtAndDestBtSame = btAddressToExclude != null
@@ -1028,7 +1029,8 @@ public class CallAudioRouteController implements CallAudioRouteAdapter {
            Log.i(this, "BT device with address (%s) is currently connecting/connected. "
                    + "Ignore route switch.");
        } else {
            routeTo(mIsActive, calculateBaselineRoute(includeBluetooth, btAddressToExclude));
            routeTo(mIsActive, calculateBaselineRoute(isExplicitUserRequest, includeBluetooth,
                    btAddressToExclude));
        }
    }

@@ -1239,14 +1241,19 @@ public class CallAudioRouteController implements CallAudioRouteAdapter {
        return mAudioManager.getPreferredDeviceForStrategy(strategy);
    }

    private AudioRoute getPreferredAudioRouteFromDefault(boolean includeBluetooth,
            String btAddressToExclude) {
        boolean skipEarpiece;
    private AudioRoute getPreferredAudioRouteFromDefault(boolean isExplicitUserRequest,
            boolean includeBluetooth, String btAddressToExclude) {
        boolean skipEarpiece = false;
        Call foregroundCall = mCallAudioManager.getForegroundCall();
        if (!mFeatureFlags.fixUserRequestBaselineRouteVideoCall()) {
            isExplicitUserRequest = false;
        }
        if (!isExplicitUserRequest) {
            synchronized (mTelecomLock) {
                skipEarpiece = foregroundCall != null
                        && VideoProfile.isVideo(foregroundCall.getVideoState());
            }
        }
        // Route to earpiece, wired, or speaker route if there are not bluetooth routes or if there
        // are only wearables available.
        AudioRoute activeWatchOrNonWatchDeviceRoute =
@@ -1345,7 +1352,7 @@ public class CallAudioRouteController implements CallAudioRouteAdapter {
        Log.i(this, "getBaseRoute: preferred audio route is %s", destRoute);
        if (destRoute == null || (destRoute.getBluetoothAddress() != null && (!includeBluetooth
                || destRoute.getBluetoothAddress().equals(btAddressToExclude)))) {
            destRoute = getPreferredAudioRouteFromDefault(includeBluetooth, btAddressToExclude);
            destRoute = getPreferredAudioRouteFromDefault(false, includeBluetooth, btAddressToExclude);
        }
        if (destRoute != null && !getCallSupportedRoutes().contains(destRoute)) {
            destRoute = null;
@@ -1354,8 +1361,9 @@ public class CallAudioRouteController implements CallAudioRouteAdapter {
        return destRoute;
    }

    private AudioRoute calculateBaselineRoute(boolean includeBluetooth, String btAddressToExclude) {
        AudioRoute destRoute = getPreferredAudioRouteFromDefault(
    private AudioRoute calculateBaselineRoute(boolean isExplicitUserRequest,
            boolean includeBluetooth, String btAddressToExclude) {
        AudioRoute destRoute = getPreferredAudioRouteFromDefault(isExplicitUserRequest,
                includeBluetooth, btAddressToExclude);
        if (destRoute != null && !getCallSupportedRoutes().contains(destRoute)) {
            destRoute = null;
+6 −2
Original line number Diff line number Diff line
@@ -270,12 +270,16 @@ public class BluetoothStateReceiver extends BroadcastReceiver {
                    if (!mBluetoothDeviceManager.setCommunicationDeviceForAddress(
                            device.getAddress())) {
                        Log.i(this, "handleActiveDeviceChanged: Failed to set "
                                + "communication device for %s. Sending PENDING_ROUTE_FAILED to "
                                + "pending audio route.", device);
                                + "communication device for %s.", device);
                        if (!mFeatureFlags.resolveActiveBtRoutingAndBtTimingIssue()) {
                            Log.i(this, "Sending PENDING_ROUTE_FAILED "
                                    + "to pending audio route.");
                            mCallAudioRouteAdapter.getPendingAudioRoute()
                                    .onMessageReceived(new Pair<>(PENDING_ROUTE_FAILED,
                                            device.getAddress()), device.getAddress());
                        } else {
                            Log.i(this, "Refrain from sending PENDING_ROUTE_FAILED"
                                    + " to pending audio route.");
                        }
                    } else {
                        // Track the currently set communication device.
+41 −0
Original line number Diff line number Diff line
@@ -37,6 +37,7 @@ import static com.android.server.telecom.CallAudioRouteAdapter.STREAMING_FORCE_D
import static com.android.server.telecom.CallAudioRouteAdapter.STREAMING_FORCE_ENABLED;
import static com.android.server.telecom.CallAudioRouteAdapter.SWITCH_BASELINE_ROUTE;
import static com.android.server.telecom.CallAudioRouteAdapter.SWITCH_FOCUS;
import static com.android.server.telecom.CallAudioRouteAdapter.USER_SWITCH_BASELINE_ROUTE;
import static com.android.server.telecom.CallAudioRouteAdapter.USER_SWITCH_BLUETOOTH;
import static com.android.server.telecom.CallAudioRouteAdapter.USER_SWITCH_EARPIECE;
import static com.android.server.telecom.CallAudioRouteAdapter.USER_SWITCH_HEADSET;
@@ -194,6 +195,7 @@ public class CallAudioRouteControllerTest extends TelecomTestCase {
        when(mFeatureFlags.useRefactoredAudioRouteSwitching()).thenReturn(true);
        when(mFeatureFlags.resolveActiveBtRoutingAndBtTimingIssue()).thenReturn(false);
        when(mFeatureFlags.newAudioPathSpeakerBroadcastAndUnfocusedRouting()).thenReturn(false);
        when(mFeatureFlags.fixUserRequestBaselineRouteVideoCall()).thenReturn(false);
    }

    @After
@@ -1058,6 +1060,45 @@ public class CallAudioRouteControllerTest extends TelecomTestCase {
                any(CallAudioState.class), eq(expectedState));
    }

    @Test
    @SmallTest
    public void testUserSwitchBaselineRouteVideoCall() {
        when(mFeatureFlags.fixUserRequestBaselineRouteVideoCall()).thenReturn(true);
        mController.initialize();
        mController.setActive(true);
        // Set capabilities for video call.
        when(mCall.getVideoState()).thenReturn(VideoProfile.STATE_BIDIRECTIONAL);

        // Turn on speaker
        mController.sendMessageWithSessionInfo(SPEAKER_ON);
        CallAudioState expectedState = new CallAudioState(false, CallAudioState.ROUTE_SPEAKER,
                CallAudioState.ROUTE_EARPIECE | CallAudioState.ROUTE_SPEAKER, null,
                new HashSet<>());
        verify(mCallsManager, timeout(TEST_TIMEOUT)).onCallAudioStateChanged(
                any(CallAudioState.class), eq(expectedState));

        // USER_SWITCH_BASELINE_ROUTE (explicit user request). Verify that audio is routed back to
        // earpiece.
        mController.sendMessageWithSessionInfo(USER_SWITCH_BASELINE_ROUTE,
                CallAudioRouteController.INCLUDE_BLUETOOTH_IN_BASELINE);
        mController.sendMessageWithSessionInfo(SPEAKER_OFF);
        expectedState = new CallAudioState(false, CallAudioState.ROUTE_EARPIECE,
                CallAudioState.ROUTE_EARPIECE | CallAudioState.ROUTE_SPEAKER, null,
                new HashSet<>());
        verify(mCallsManager, timeout(TEST_TIMEOUT)).onCallAudioStateChanged(
                any(CallAudioState.class), eq(expectedState));

        // SWITCH_BASELINE_ROUTE. Verify that audio is routed to speaker for non-user requests.
        mController.sendMessageWithSessionInfo(SWITCH_BASELINE_ROUTE,
                CallAudioRouteController.INCLUDE_BLUETOOTH_IN_BASELINE);
        mController.sendMessageWithSessionInfo(SPEAKER_ON);
        expectedState = new CallAudioState(false, CallAudioState.ROUTE_SPEAKER,
                CallAudioState.ROUTE_EARPIECE | CallAudioState.ROUTE_SPEAKER, null,
                new HashSet<>());
        verify(mCallsManager, timeout(TEST_TIMEOUT)).onCallAudioStateChanged(
                any(CallAudioState.class), eq(expectedState));
    }

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