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

Commit 899e4b6a authored by Kunduz Baryktabasova's avatar Kunduz Baryktabasova
Browse files

Fix supported routes wrongly include bluetooth issue

setSystemAudioState is acting on mLastKnownCallAudioState, which was never updated to account for the change to mAvailableRoutes. This will make HfpCall's supported route wrongly include bluetooth.

Bug: 292599751
Test: unit test

Change-Id: I155972995a35b5eed01b307bc16ae026449ed3e4
parent 80a519ee
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@ aconfig_declarations {
      "telecom_call_filtering_flags.aconfig",
      "telecom_incallservice_flags.aconfig",
      "telecom_default_phone_account_flags.aconfig",
      "telecom_callaudioroutestatemachine_flags.aconfig"
    ],
}

+8 −0
Original line number Diff line number Diff line
package: "com.android.server.telecom.flags"

flag {
  name: "available_routes_never_updated_after_set_system_audio_state"
  namespace: "telecom"
  description: "Fix supported routes wrongly include bluetooth issue."
  bug: "292599751"
}
 No newline at end of file
+12 −2
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@ import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.content.pm.UserInfo;
import android.media.AudioDeviceInfo;
import android.media.AudioManager;
@@ -1739,9 +1740,13 @@ public class CallAudioRouteStateMachine extends StateMachine {
                }
                return;
            case UPDATE_SYSTEM_AUDIO_ROUTE:
                updateInternalCallAudioState();
                // Ensure available routes is updated.
                updateRouteForForegroundCall();
                resendSystemAudioState();
                // Ensure current audio state gets updated to take this into account.
                updateInternalCallAudioState();
                // Either resend the current audio state as it stands, or update to reflect any
                // changes put into place based on mAvailableRoutes
                setSystemAudioState(mCurrentCallAudioState, true);
                return;
            case RUN_RUNNABLE:
                java.lang.Runnable r = (java.lang.Runnable) msg.obj;
@@ -1884,6 +1889,11 @@ public class CallAudioRouteStateMachine extends StateMachine {
        setSystemAudioState(mLastKnownCallAudioState, true);
    }

    @VisibleForTesting
    public CallAudioState getLastKnownCallAudioState() {
        return mLastKnownCallAudioState;
    }

    private void setSystemAudioState(CallAudioState newCallAudioState, boolean force) {
        synchronized (mLock) {
            Log.i(this, "setSystemAudioState: changing from %s to %s", mLastKnownCallAudioState,
+52 −0
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.media.AudioDeviceInfo;
import android.media.AudioManager;
import android.media.IAudioService;
@@ -217,6 +218,57 @@ public class CallAudioRouteStateMachineTest extends TelecomTestCase {
                .onCallAudioStateChanged(any(), any());
    }

    @SmallTest
    @Test
    public void testSystemAudioStateIsUpdated() {
        CallAudioRouteStateMachine stateMachine = new CallAudioRouteStateMachine(
                mContext,
                mockCallsManager,
                mockBluetoothRouteManager,
                mockWiredHeadsetManager,
                mockStatusBarNotifier,
                mAudioServiceFactory,
                CallAudioRouteStateMachine.EARPIECE_AUTO_DETECT,
                mThreadHandler.getLooper(),
                Runnable::run /** do async stuff sync for test purposes */,
                mCommunicationDeviceTracker);
        stateMachine.setCallAudioManager(mockCallAudioManager);

        Set<Call> trackedCalls = new HashSet<>(Arrays.asList(fakeCall, fakeSelfManagedCall));
        when(mockCallsManager.getTrackedCalls()).thenReturn(trackedCalls);

        // start state --> ROUTE_EARPIECE
        CallAudioState initState = new CallAudioState(false, CallAudioState.ROUTE_EARPIECE,
                CallAudioState.ROUTE_EARPIECE | CallAudioState.ROUTE_SPEAKER);
        stateMachine.initialize(initState);

        stateMachine.setCallAudioManager(mockCallAudioManager);

        assertEquals(stateMachine.getCurrentCallAudioState().getRoute(),
                CallAudioRouteStateMachine.ROUTE_EARPIECE);

        // ROUTE_EARPIECE  --> ROUTE_SPEAKER
        stateMachine.sendMessageWithSessionInfo(CallAudioRouteStateMachine.SWITCH_SPEAKER,
                CallAudioRouteStateMachine.SPEAKER_ON);

        stateMachine.sendMessageWithSessionInfo(
                CallAudioRouteStateMachine.UPDATE_SYSTEM_AUDIO_ROUTE);

        waitForHandlerAction(stateMachine.getHandler(), TEST_TIMEOUT);
        waitForHandlerAction(stateMachine.getHandler(), TEST_TIMEOUT);

        CallAudioState expectedCallAudioState = stateMachine.getLastKnownCallAudioState();

        // assert expected end state
        assertEquals(stateMachine.getCurrentCallAudioState().getRoute(),
                CallAudioRouteStateMachine.ROUTE_SPEAKER);
        // should update the audio route on all tracked calls ...
        verify(mockConnectionServiceWrapper, times(trackedCalls.size()))
                .onCallAudioStateChanged(any(), any());

        assertEquals(expectedCallAudioState, stateMachine.getCurrentCallAudioState());
    }

    @MediumTest
    @Test
    public void testStreamRingMuteChange() {