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

Commit 7f11cdd1 authored by Hall Liu's avatar Hall Liu Committed by Android (Google) Code Review
Browse files

Merge "Add ringing state for bluetooth audio route" into nyc-mr1-dev

parents c928e2e4 e271f226
Loading
Loading
Loading
Loading
+4 −4
Original line number Diff line number Diff line
@@ -213,7 +213,7 @@ public class CallAudioModeStateMachine extends StateMachine {

            mCallAudioManager.stopCallWaiting();
            mCallAudioManager.startRinging();
            mCallAudioManager.setCallAudioRouteFocusState(CallAudioRouteStateMachine.HAS_FOCUS);
            mCallAudioManager.setCallAudioRouteFocusState(CallAudioRouteStateMachine.RINGING_FOCUS);
        }

        @Override
@@ -288,7 +288,7 @@ public class CallAudioModeStateMachine extends StateMachine {
                    AudioManager.AUDIOFOCUS_GAIN_TRANSIENT);
            mAudioManager.setMode(AudioManager.MODE_IN_CALL);
            mMostRecentMode = AudioManager.MODE_IN_CALL;
            mCallAudioManager.setCallAudioRouteFocusState(CallAudioRouteStateMachine.HAS_FOCUS);
            mCallAudioManager.setCallAudioRouteFocusState(CallAudioRouteStateMachine.ACTIVE_FOCUS);
        }

        @Override
@@ -350,7 +350,7 @@ public class CallAudioModeStateMachine extends StateMachine {
                    AudioManager.AUDIOFOCUS_GAIN_TRANSIENT);
            mAudioManager.setMode(AudioManager.MODE_IN_COMMUNICATION);
            mMostRecentMode = AudioManager.MODE_IN_COMMUNICATION;
            mCallAudioManager.setCallAudioRouteFocusState(CallAudioRouteStateMachine.HAS_FOCUS);
            mCallAudioManager.setCallAudioRouteFocusState(CallAudioRouteStateMachine.ACTIVE_FOCUS);
        }

        @Override
@@ -407,7 +407,7 @@ public class CallAudioModeStateMachine extends StateMachine {
            mAudioManager.requestAudioFocusForCall(AudioManager.STREAM_VOICE_CALL,
                    AudioManager.AUDIOFOCUS_GAIN_TRANSIENT);
            mAudioManager.setMode(mMostRecentMode);
            mCallAudioManager.setCallAudioRouteFocusState(CallAudioRouteStateMachine.HAS_FOCUS);
            mCallAudioManager.setCallAudioRouteFocusState(CallAudioRouteStateMachine.ACTIVE_FOCUS);
        }

        @Override
+108 −9
Original line number Diff line number Diff line
@@ -105,7 +105,8 @@ public class CallAudioRouteStateMachine extends StateMachine {

    /** Valid values for mAudioFocusType */
    public static final int NO_FOCUS = 1;
    public static final int HAS_FOCUS = 2;
    public static final int ACTIVE_FOCUS = 2;
    public static final int RINGING_FOCUS = 3;

    private static final SparseArray<String> AUDIO_ROUTE_TO_LOG_EVENT = new SparseArray<String>() {{
        put(CallAudioState.ROUTE_BLUETOOTH, Log.Events.AUDIO_ROUTE_BT);
@@ -135,6 +136,8 @@ public class CallAudioRouteStateMachine extends StateMachine {
        put(USER_SWITCH_SPEAKER, "USER_SWITCH_SPEAKER");
        put(USER_SWITCH_BASELINE_ROUTE, "USER_SWITCH_BASELINE_ROUTE");

        put(UPDATE_SYSTEM_AUDIO_ROUTE, "UPDATE_SYSTEM_AUDIO_ROUTE");

        put(MUTE_ON, "MUTE_ON");
        put(MUTE_OFF, "MUTE_OFF");
        put(TOGGLE_MUTE, "TOGGLE_MUTE");
@@ -148,6 +151,7 @@ public class CallAudioRouteStateMachine extends StateMachine {
    private static final String ACTIVE_BLUETOOTH_ROUTE_NAME = "ActiveBluetoothRoute";
    private static final String ACTIVE_SPEAKER_ROUTE_NAME = "ActiveSpeakerRoute";
    private static final String ACTIVE_HEADSET_ROUTE_NAME = "ActiveHeadsetRoute";
    private static final String RINGING_BLUETOOTH_ROUTE_NAME = "RingingBluetoothRoute";
    private static final String QUIESCENT_EARPIECE_ROUTE_NAME = "QuiescentEarpieceRoute";
    private static final String QUIESCENT_BLUETOOTH_ROUTE_NAME = "QuiescentBluetoothRoute";
    private static final String QUIESCENT_SPEAKER_ROUTE_NAME = "QuiescentSpeakerRoute";
@@ -160,7 +164,7 @@ public class CallAudioRouteStateMachine extends StateMachine {
        if (msg.obj != null && msg.obj instanceof Session) {
            String messageCodeName = MESSAGE_CODE_TO_NAME.get(msg.what, "unknown");
            Log.continueSession((Session) msg.obj, "CARSM.pM_" + messageCodeName);
            Log.i(this, "Message received: %s=%d", messageCodeName, msg.what);
            Log.i(this, "Message received: %s=%d, arg1=%d", messageCodeName, msg.what, msg.arg1);
        }
    }

@@ -217,6 +221,9 @@ public class CallAudioRouteStateMachine extends StateMachine {
                case USER_SWITCH_BASELINE_ROUTE:
                    sendInternalMessage(calculateBaselineRouteMessage(true));
                    return HANDLED;
                case SWITCH_FOCUS:
                    mAudioFocusType = msg.arg1;
                    return NOT_HANDLED;
                default:
                    return NOT_HANDLED;
            }
@@ -268,7 +275,8 @@ public class CallAudioRouteStateMachine extends StateMachine {
                case SWITCH_BLUETOOTH:
                case USER_SWITCH_BLUETOOTH:
                    if ((mAvailableRoutes & ROUTE_BLUETOOTH) != 0) {
                        transitionTo(mActiveBluetoothRoute);
                        transitionTo(mAudioFocusType == ACTIVE_FOCUS ?
                                mActiveBluetoothRoute : mRingingBluetoothRoute);
                    } else {
                        Log.w(this, "Ignoring switch to bluetooth command. Not available.");
                    }
@@ -350,7 +358,7 @@ public class CallAudioRouteStateMachine extends StateMachine {
                    transitionTo(mQuiescentSpeakerRoute);
                    return HANDLED;
                case SWITCH_FOCUS:
                    if (msg.arg1 == HAS_FOCUS) {
                    if (msg.arg1 == ACTIVE_FOCUS || msg.arg1 == RINGING_FOCUS) {
                        transitionTo(mActiveEarpieceRoute);
                    }
                    return HANDLED;
@@ -449,7 +457,8 @@ public class CallAudioRouteStateMachine extends StateMachine {
                case SWITCH_BLUETOOTH:
                case USER_SWITCH_BLUETOOTH:
                    if ((mAvailableRoutes & ROUTE_BLUETOOTH) != 0) {
                        transitionTo(mActiveBluetoothRoute);
                        transitionTo(mAudioFocusType == ACTIVE_FOCUS ?
                                mActiveBluetoothRoute : mRingingBluetoothRoute);
                    } else {
                        Log.w(this, "Ignoring switch to bluetooth command. Not available.");
                    }
@@ -527,7 +536,7 @@ public class CallAudioRouteStateMachine extends StateMachine {
                    transitionTo(mQuiescentSpeakerRoute);
                    return HANDLED;
                case SWITCH_FOCUS:
                    if (msg.arg1 == HAS_FOCUS) {
                    if (msg.arg1 == ACTIVE_FOCUS || msg.arg1 == RINGING_FOCUS) {
                        transitionTo(mActiveHeadsetRoute);
                    }
                    return HANDLED;
@@ -652,6 +661,8 @@ public class CallAudioRouteStateMachine extends StateMachine {
                case SWITCH_FOCUS:
                    if (msg.arg1 == NO_FOCUS) {
                        reinitialize();
                    } else if (msg.arg1 == RINGING_FOCUS) {
                        transitionTo(mRingingBluetoothRoute);
                    }
                    return HANDLED;
                case BT_AUDIO_DISCONNECT:
@@ -663,6 +674,87 @@ public class CallAudioRouteStateMachine extends StateMachine {
        }
    }

    class RingingBluetoothRoute extends BluetoothRoute {
        @Override
        public String getName() {
            return RINGING_BLUETOOTH_ROUTE_NAME;
        }

        @Override
        public boolean isActive() {
            return false;
        }

        @Override
        public void enter() {
            super.enter();
            setSpeakerphoneOn(false);
            // Do not enable SCO audio here, since RING is being sent to the headset.
            CallAudioState newState = new CallAudioState(mIsMuted, ROUTE_BLUETOOTH,
                    mAvailableRoutes);
            setSystemAudioState(newState);
            updateInternalCallAudioState();
        }

        @Override
        public void updateSystemAudioState() {
            updateInternalCallAudioState();
            setSystemAudioState(mCurrentCallAudioState);
        }

        @Override
        public boolean processMessage(Message msg) {
            if (super.processMessage(msg) == HANDLED) {
                return HANDLED;
            }
            switch (msg.what) {
                case USER_SWITCH_EARPIECE:
                    mHasUserExplicitlyLeftBluetooth = true;
                    // fall through
                case SWITCH_EARPIECE:
                    if ((mAvailableRoutes & ROUTE_EARPIECE) != 0) {
                        transitionTo(mActiveEarpieceRoute);
                    } else {
                        Log.w(this, "Ignoring switch to earpiece command. Not available.");
                    }
                    return HANDLED;
                case SWITCH_BLUETOOTH:
                case USER_SWITCH_BLUETOOTH:
                    // Nothing to do
                    return HANDLED;
                case USER_SWITCH_HEADSET:
                    mHasUserExplicitlyLeftBluetooth = true;
                    // fall through
                case SWITCH_HEADSET:
                    if ((mAvailableRoutes & ROUTE_WIRED_HEADSET) != 0) {
                        transitionTo(mActiveHeadsetRoute);
                    } else {
                        Log.w(this, "Ignoring switch to headset command. Not available.");
                    }
                    return HANDLED;
                case USER_SWITCH_SPEAKER:
                    mHasUserExplicitlyLeftBluetooth = true;
                    // fall through
                case SWITCH_SPEAKER:
                    transitionTo(mActiveSpeakerRoute);
                    return HANDLED;
                case SWITCH_FOCUS:
                    if (msg.arg1 == NO_FOCUS) {
                        reinitialize();
                    } else if (msg.arg1 == ACTIVE_FOCUS) {
                        transitionTo(mActiveBluetoothRoute);
                    }
                    return HANDLED;
                case BT_AUDIO_DISCONNECT:
                    // Ignore BT_AUDIO_DISCONNECT when ringing, since SCO audio should not be
                    // connected.
                    return HANDLED;
                default:
                    return NOT_HANDLED;
            }
        }
    }

    class QuiescentBluetoothRoute extends BluetoothRoute {
        @Override
        public String getName() {
@@ -717,8 +809,10 @@ public class CallAudioRouteStateMachine extends StateMachine {
                    transitionTo(mQuiescentSpeakerRoute);
                    return HANDLED;
                case SWITCH_FOCUS:
                    if (msg.arg1 == HAS_FOCUS) {
                    if (msg.arg1 == ACTIVE_FOCUS) {
                        transitionTo(mActiveBluetoothRoute);
                    } else if (msg.arg1 == RINGING_FOCUS) {
                        transitionTo(mRingingBluetoothRoute);
                    }
                    return HANDLED;
                case BT_AUDIO_DISCONNECT:
@@ -816,7 +910,8 @@ public class CallAudioRouteStateMachine extends StateMachine {
                    // fall through
                case SWITCH_BLUETOOTH:
                    if ((mAvailableRoutes & ROUTE_BLUETOOTH) != 0) {
                        transitionTo(mActiveBluetoothRoute);
                        transitionTo(mAudioFocusType == ACTIVE_FOCUS ?
                                mActiveBluetoothRoute : mRingingBluetoothRoute);
                    } else {
                        Log.w(this, "Ignoring switch to bluetooth command. Not available.");
                    }
@@ -906,7 +1001,7 @@ public class CallAudioRouteStateMachine extends StateMachine {
                    // Nothing to do
                    return HANDLED;
                case SWITCH_FOCUS:
                    if (msg.arg1 == HAS_FOCUS) {
                    if (msg.arg1 == ACTIVE_FOCUS || msg.arg1 == RINGING_FOCUS) {
                        transitionTo(mActiveSpeakerRoute);
                    }
                    return HANDLED;
@@ -962,6 +1057,7 @@ public class CallAudioRouteStateMachine extends StateMachine {
    private final ActiveHeadsetRoute mActiveHeadsetRoute = new ActiveHeadsetRoute();
    private final ActiveBluetoothRoute mActiveBluetoothRoute = new ActiveBluetoothRoute();
    private final ActiveSpeakerRoute mActiveSpeakerRoute = new ActiveSpeakerRoute();
    private final RingingBluetoothRoute mRingingBluetoothRoute = new RingingBluetoothRoute();
    private final QuiescentEarpieceRoute mQuiescentEarpieceRoute = new QuiescentEarpieceRoute();
    private final QuiescentHeadsetRoute mQuiescentHeadsetRoute = new QuiescentHeadsetRoute();
    private final QuiescentBluetoothRoute mQuiescentBluetoothRoute = new QuiescentBluetoothRoute();
@@ -972,6 +1068,7 @@ public class CallAudioRouteStateMachine extends StateMachine {
     * states
     */
    private int mAvailableRoutes;
    private int mAudioFocusType;
    private boolean mWasOnSpeaker;
    private boolean mIsMuted;

@@ -1006,6 +1103,7 @@ public class CallAudioRouteStateMachine extends StateMachine {
        addState(mActiveHeadsetRoute);
        addState(mActiveBluetoothRoute);
        addState(mActiveSpeakerRoute);
        addState(mRingingBluetoothRoute);
        addState(mQuiescentEarpieceRoute);
        addState(mQuiescentHeadsetRoute);
        addState(mQuiescentBluetoothRoute);
@@ -1025,6 +1123,7 @@ public class CallAudioRouteStateMachine extends StateMachine {
        mStateNameToRouteCode.put(mQuiescentBluetoothRoute.getName(), ROUTE_BLUETOOTH);
        mStateNameToRouteCode.put(mQuiescentHeadsetRoute.getName(), ROUTE_WIRED_HEADSET);
        mStateNameToRouteCode.put(mQuiescentSpeakerRoute.getName(), ROUTE_SPEAKER);
        mStateNameToRouteCode.put(mRingingBluetoothRoute.getName(), ROUTE_BLUETOOTH);
        mStateNameToRouteCode.put(mActiveEarpieceRoute.getName(), ROUTE_EARPIECE);
        mStateNameToRouteCode.put(mActiveBluetoothRoute.getName(), ROUTE_BLUETOOTH);
        mStateNameToRouteCode.put(mActiveHeadsetRoute.getName(), ROUTE_WIRED_HEADSET);
+70 −3
Original line number Diff line number Diff line
@@ -50,6 +50,7 @@ import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.timeout;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

@@ -177,7 +178,7 @@ public class CallAudioRouteStateMachineTest
        stateMachine.initialize(initState);

        stateMachine.sendMessageWithSessionInfo(CallAudioRouteStateMachine.SWITCH_FOCUS,
                CallAudioRouteStateMachine.HAS_FOCUS);
                CallAudioRouteStateMachine.ACTIVE_FOCUS);
        stateMachine.sendMessageWithSessionInfo(CallAudioRouteStateMachine.CONNECT_WIRED_HEADSET);
        CallAudioState expectedMiddleState = new CallAudioState(false,
                CallAudioState.ROUTE_WIRED_HEADSET,
@@ -209,7 +210,7 @@ public class CallAudioRouteStateMachineTest
        stateMachine.initialize(initState);

        stateMachine.sendMessageWithSessionInfo(CallAudioRouteStateMachine.SWITCH_FOCUS,
                CallAudioRouteStateMachine.HAS_FOCUS);
                CallAudioRouteStateMachine.ACTIVE_FOCUS);
        stateMachine.sendMessageWithSessionInfo(
                CallAudioRouteStateMachine.USER_SWITCH_BASELINE_ROUTE);
        CallAudioState expectedEndState = new CallAudioState(false,
@@ -230,6 +231,72 @@ public class CallAudioRouteStateMachineTest
        assertEquals(expectedEndState, stateMachine.getCurrentCallAudioState());
    }

    @MediumTest
    public void testBluetoothRinging() {
        CallAudioRouteStateMachine stateMachine = new CallAudioRouteStateMachine(
                mContext,
                mockCallsManager,
                mockBluetoothManager,
                mockWiredHeadsetManager,
                mockStatusBarNotifier,
                mAudioServiceFactory,
                true);

        when(mockBluetoothManager.isBluetoothAudioConnectedOrPending()).thenReturn(false);
        when(mockBluetoothManager.isBluetoothAvailable()).thenReturn(true);
        when(mockAudioManager.isSpeakerphoneOn()).thenReturn(false);
        CallAudioState initState = new CallAudioState(false, CallAudioState.ROUTE_BLUETOOTH,
                CallAudioState.ROUTE_EARPIECE | CallAudioState.ROUTE_BLUETOOTH);
        stateMachine.initialize(initState);

        stateMachine.sendMessageWithSessionInfo(CallAudioRouteStateMachine.SWITCH_FOCUS,
                CallAudioRouteStateMachine.RINGING_FOCUS);
        waitForStateMachineActionCompletion(stateMachine, CallAudioRouteStateMachine.RUN_RUNNABLE);

        verify(mockBluetoothManager, never()).connectBluetoothAudio();

        stateMachine.sendMessageWithSessionInfo(CallAudioRouteStateMachine.SWITCH_FOCUS,
                CallAudioRouteStateMachine.ACTIVE_FOCUS);
        waitForStateMachineActionCompletion(stateMachine, CallAudioRouteStateMachine.RUN_RUNNABLE);
        verify(mockBluetoothManager, times(1)).connectBluetoothAudio();
    }

    @MediumTest
    public void testConnectBluetoothDuringRinging() {
        CallAudioRouteStateMachine stateMachine = new CallAudioRouteStateMachine(
                mContext,
                mockCallsManager,
                mockBluetoothManager,
                mockWiredHeadsetManager,
                mockStatusBarNotifier,
                mAudioServiceFactory,
                true);

        when(mockBluetoothManager.isBluetoothAudioConnectedOrPending()).thenReturn(false);
        when(mockBluetoothManager.isBluetoothAvailable()).thenReturn(false);
        when(mockAudioManager.isSpeakerphoneOn()).thenReturn(false);
        CallAudioState initState = new CallAudioState(false, CallAudioState.ROUTE_EARPIECE,
                CallAudioState.ROUTE_EARPIECE);
        stateMachine.initialize(initState);

        stateMachine.sendMessageWithSessionInfo(CallAudioRouteStateMachine.SWITCH_FOCUS,
                CallAudioRouteStateMachine.RINGING_FOCUS);
        when(mockBluetoothManager.isBluetoothAvailable()).thenReturn(true);
        stateMachine.sendMessageWithSessionInfo(CallAudioRouteStateMachine.CONNECT_BLUETOOTH);
        waitForStateMachineActionCompletion(stateMachine, CallAudioRouteStateMachine.RUN_RUNNABLE);

        verify(mockBluetoothManager, never()).connectBluetoothAudio();
        CallAudioState expectedEndState = new CallAudioState(false,
                CallAudioState.ROUTE_BLUETOOTH,
                CallAudioState.ROUTE_EARPIECE | CallAudioState.ROUTE_BLUETOOTH);
        verifyNewSystemCallAudioState(initState, expectedEndState);

        stateMachine.sendMessageWithSessionInfo(CallAudioRouteStateMachine.SWITCH_FOCUS,
                CallAudioRouteStateMachine.ACTIVE_FOCUS);
        waitForStateMachineActionCompletion(stateMachine, CallAudioRouteStateMachine.RUN_RUNNABLE);
        verify(mockBluetoothManager, times(1)).connectBluetoothAudio();
    }

    @SmallTest
    public void testInitializationWithEarpieceNoHeadsetNoBluetooth() {
        CallAudioState expectedState = new CallAudioState(false, CallAudioState.ROUTE_EARPIECE,
@@ -677,7 +744,7 @@ public class CallAudioRouteStateMachineTest
        stateMachine.initialize(initState);
        // Make the state machine have focus so that we actually do something
        stateMachine.sendMessageWithSessionInfo(CallAudioRouteStateMachine.SWITCH_FOCUS,
                CallAudioRouteStateMachine.HAS_FOCUS);
                CallAudioRouteStateMachine.ACTIVE_FOCUS);
        stateMachine.sendMessageWithSessionInfo(params.action);

        waitForStateMachineActionCompletion(stateMachine, CallAudioRouteStateMachine.RUN_RUNNABLE);