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

Commit b4cc8387 authored by Hall Liu's avatar Hall Liu
Browse files

Add new call states and refactor CAMSM parameters

Add the new simulated ringing and audio processing call states
Refactor CallAudioModeStateMachine's parameters to use a builder
Add stubs in CallAudioManager for the call state transitions

Bug: 140317205
Test: run unit tests
Change-Id: Ic9d6cf77cd2f822536eaab43640c6096d2ce100c
parent eae9faed
Loading
Loading
Loading
Loading
+32 −10
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@ import android.util.SparseArray;

import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.IndentingPrintWriter;
import com.android.server.telecom.CallAudioModeStateMachine.MessageArgs.Builder;
import com.android.server.telecom.bluetooth.BluetoothStateReceiver;

import java.util.Collection;
@@ -44,6 +45,7 @@ public class CallAudioManager extends CallsManagerListenerBase {
    private final LinkedHashSet<Call> mActiveDialingOrConnectingCalls;
    private final LinkedHashSet<Call> mRingingCalls;
    private final LinkedHashSet<Call> mHoldingCalls;
    private final LinkedHashSet<Call> mAudioProcessingCalls;
    private final Set<Call> mCalls;
    private final SparseArray<LinkedHashSet<Call>> mCallStateToCalls;

@@ -69,9 +71,10 @@ public class CallAudioManager extends CallsManagerListenerBase {
            RingbackPlayer ringbackPlayer,
            BluetoothStateReceiver bluetoothStateReceiver,
            DtmfLocalTonePlayer dtmfLocalTonePlayer) {
        mActiveDialingOrConnectingCalls = new LinkedHashSet<>();
        mRingingCalls = new LinkedHashSet<>();
        mHoldingCalls = new LinkedHashSet<>();
        mActiveDialingOrConnectingCalls = new LinkedHashSet<>(1);
        mRingingCalls = new LinkedHashSet<>(1);
        mHoldingCalls = new LinkedHashSet<>(1);
        mAudioProcessingCalls = new LinkedHashSet<>(1);
        mCalls = new HashSet<>();
        mCallStateToCalls = new SparseArray<LinkedHashSet<Call>>() {{
            put(CallState.CONNECTING, mActiveDialingOrConnectingCalls);
@@ -80,6 +83,8 @@ public class CallAudioManager extends CallsManagerListenerBase {
            put(CallState.PULLING, mActiveDialingOrConnectingCalls);
            put(CallState.RINGING, mRingingCalls);
            put(CallState.ON_HOLD, mHoldingCalls);
            put(CallState.SIMULATED_RINGING, mRingingCalls);
            put(CallState.AUDIO_PROCESSING, mAudioProcessingCalls);
        }};

        mCallAudioRouteStateMachine = callAudioRouteStateMachine;
@@ -534,6 +539,7 @@ public class CallAudioManager extends CallsManagerListenerBase {
                onCallLeavingActiveDialingOrConnecting();
                break;
            case CallState.RINGING:
            case CallState.SIMULATED_RINGING:
            case CallState.ANSWERED:
                onCallLeavingRinging();
                break;
@@ -547,6 +553,9 @@ public class CallAudioManager extends CallsManagerListenerBase {
                stopRingbackForCall(call);
                onCallLeavingActiveDialingOrConnecting();
                break;
            case CallState.AUDIO_PROCESSING:
                onCallLeavingAudioProcessing();
                break;
        }
    }

@@ -557,6 +566,7 @@ public class CallAudioManager extends CallsManagerListenerBase {
                onCallEnteringActiveDialingOrConnecting();
                break;
            case CallState.RINGING:
            case CallState.SIMULATED_RINGING:
                onCallEnteringRinging();
                break;
            case CallState.ON_HOLD:
@@ -574,7 +584,18 @@ public class CallAudioManager extends CallsManagerListenerBase {
                    onCallEnteringActiveDialingOrConnecting();
                }
                break;
            case CallState.AUDIO_PROCESSING:
                onCallEnteringAudioProcessing();
                break;
        }
    }

    private void onCallLeavingAudioProcessing() {
        // TODO: implement
    }

    private void onCallEnteringAudioProcessing() {
        // TODO: implement
    }

    private void onCallLeavingActiveDialingOrConnecting() {
@@ -655,13 +676,14 @@ public class CallAudioManager extends CallsManagerListenerBase {

    @NonNull
    private CallAudioModeStateMachine.MessageArgs makeArgsForModeStateMachine() {
        return new CallAudioModeStateMachine.MessageArgs(
                mActiveDialingOrConnectingCalls.size() > 0,
                mRingingCalls.size() > 0,
                mHoldingCalls.size() > 0,
                mIsTonePlaying,
                mForegroundCall != null && mForegroundCall.getIsVoipAudioMode(),
                Log.createSubsession());
        return new Builder()
                .setHasActiveOrDialingCalls(mActiveDialingOrConnectingCalls.size() > 0)
                .setHasRingingCalls(mRingingCalls.size() > 0)
                .setHasHoldingCalls(mHoldingCalls.size() > 0)
                .setIsTonePlaying(mIsTonePlaying)
                .setForegroundCallIsVoip(
                        mForegroundCall != null && mForegroundCall.getIsVoipAudioMode())
                .setSession(Log.createSubsession()).build();
    }

    private HashSet<Call> getBinForCall(Call call) {
+50 −6
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@ import com.android.internal.util.IState;
import com.android.internal.util.IndentingPrintWriter;
import com.android.internal.util.State;
import com.android.internal.util.StateMachine;
import com.android.server.telecom.CallAudioModeStateMachine.MessageArgs.Builder;

public class CallAudioModeStateMachine extends StateMachine {
    public static class Factory {
@@ -45,7 +46,7 @@ public class CallAudioModeStateMachine extends StateMachine {
        public boolean foregroundCallIsVoip;
        public Session session;

        public MessageArgs(boolean hasActiveOrDialingCalls, boolean hasRingingCalls,
        private MessageArgs(boolean hasActiveOrDialingCalls, boolean hasRingingCalls,
                boolean hasHoldingCalls, boolean isTonePlaying, boolean foregroundCallIsVoip,
                Session session) {
            this.hasActiveOrDialingCalls = hasActiveOrDialingCalls;
@@ -56,10 +57,6 @@ public class CallAudioModeStateMachine extends StateMachine {
            this.session = session;
        }

        public MessageArgs() {
            this.session = Log.createSubsession();
        }

        @Override
        public String toString() {
            return "MessageArgs{" +
@@ -71,6 +68,50 @@ public class CallAudioModeStateMachine extends StateMachine {
                    ", session=" + session +
                    '}';
        }

        public static class Builder {
            private boolean mHasActiveOrDialingCalls;
            private boolean mHasRingingCalls;
            private boolean mHasHoldingCalls;
            private boolean mIsTonePlaying;
            private boolean mForegroundCallIsVoip;
            private Session mSession;

            public Builder setHasActiveOrDialingCalls(boolean hasActiveOrDialingCalls) {
                mHasActiveOrDialingCalls = hasActiveOrDialingCalls;
                return this;
            }

            public Builder setHasRingingCalls(boolean hasRingingCalls) {
                mHasRingingCalls = hasRingingCalls;
                return this;
            }

            public Builder setHasHoldingCalls(boolean hasHoldingCalls) {
                mHasHoldingCalls = hasHoldingCalls;
                return this;
            }

            public Builder setIsTonePlaying(boolean isTonePlaying) {
                mIsTonePlaying = isTonePlaying;
                return this;
            }

            public Builder setForegroundCallIsVoip(boolean foregroundCallIsVoip) {
                mForegroundCallIsVoip = foregroundCallIsVoip;
                return this;
            }

            public Builder setSession(Session session) {
                mSession = session;
                return this;
            }

            public MessageArgs build() {
                return new MessageArgs(mHasActiveOrDialingCalls, mHasRingingCalls, mHasHoldingCalls,
                        mIsTonePlaying, mForegroundCallIsVoip, mSession);
            }
        }
    }

    public static final int INITIALIZE = 1;
@@ -529,7 +570,10 @@ public class CallAudioModeStateMachine extends StateMachine {
        addState(mOtherFocusState);
        setInitialState(mUnfocusedState);
        start();
        sendMessage(INITIALIZE, new MessageArgs());
        sendMessage(INITIALIZE, new Builder().setHasActiveOrDialingCalls(
                false).setHasRingingCalls(false).setHasHoldingCalls(false).setIsTonePlaying(
                false).setForegroundCallIsVoip(false).setSession(
                Log.createSubsession()).build());
    }

    public void setCallAudioManager(CallAudioManager callAudioManager) {
+17 −1
Original line number Diff line number Diff line
@@ -118,7 +118,19 @@ public final class CallState {
     * Indicates that an incoming call has been answered by the in-call UI, but Telephony hasn't yet
     * set the call to active.
     */
    public static final int ANSWERED = 11;
    public static final int ANSWERED = TelecomProtoEnums.ANSWERED; // = 11

    /**
     * Indicates that the call is undergoing audio processing by a different app in the background.
     * @see android.telecom.Call#STATE_AUDIO_PROCESSING
     */
    public static final int AUDIO_PROCESSING = TelecomProtoEnums.AUDIO_PROCESSING; // = 12

    /**
     * Indicates that the call is in a fake ringing state.
     * @see android.telecom.Call#STATE_SIMULATED_RINGING
     */
    public static final int SIMULATED_RINGING = TelecomProtoEnums.SIMULATED_RINGING; // = 13

    public static String toString(int callState) {
        switch (callState) {
@@ -146,6 +158,10 @@ public final class CallState {
                return "PULLING";
            case ANSWERED:
                return "ANSWERED";
            case AUDIO_PROCESSING:
                return "AUDIO_PROCESSING";
            case SIMULATED_RINGING:
                return "SIMULATED_RINGING";
            default:
                return "UNKNOWN";
        }
+58 −57
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@ import com.android.server.telecom.CallsManager;
import com.android.server.telecom.CallAudioManager;
import com.android.server.telecom.DtmfLocalTonePlayer;
import com.android.server.telecom.InCallTonePlayer;
import com.android.server.telecom.CallAudioModeStateMachine.MessageArgs.Builder;
import com.android.server.telecom.RingbackPlayer;
import com.android.server.telecom.Ringer;
import com.android.server.telecom.bluetooth.BluetoothStateReceiver;
@@ -117,14 +118,14 @@ public class CallAudioManagerTest extends TelecomTestCase {
        verify(mCallAudioModeStateMachine).sendMessageWithArgs(
                eq(CallAudioModeStateMachine.NO_MORE_RINGING_CALLS), captor.capture());
        CallAudioModeStateMachine.MessageArgs correctArgs =
                new CallAudioModeStateMachine.MessageArgs(
                        true, // hasActiveOrDialingCalls
                        false, // hasRingingCalls
                        false, // hasHoldingCalls
                        false, // isTonePlaying
                        false, // foregroundCallIsVoip
                        null // session
                );
                new Builder()
                        .setHasActiveOrDialingCalls(true)
                        .setHasRingingCalls(false)
                        .setHasHoldingCalls(false)
                        .setIsTonePlaying(false)
                        .setForegroundCallIsVoip(false)
                        .setSession(null)
                        .build();
        assertMessageArgEquality(correctArgs, captor.getValue());
        verify(mCallAudioModeStateMachine).sendMessageWithArgs(
                eq(CallAudioModeStateMachine.NEW_ACTIVE_OR_DIALING_CALL), captor.capture());
@@ -179,14 +180,14 @@ public class CallAudioManagerTest extends TelecomTestCase {
        verify(mCallAudioModeStateMachine).sendMessageWithArgs(
                eq(CallAudioModeStateMachine.NO_MORE_RINGING_CALLS), captor.capture());
        CallAudioModeStateMachine.MessageArgs correctArgs =
                new CallAudioModeStateMachine.MessageArgs(
                        true, // hasActiveOrDialingCalls
                        false, // hasRingingCalls
                        false, // hasHoldingCalls
                        false, // isTonePlaying
                        false, // foregroundCallIsVoip
                        null // session
                );
                new Builder()
                        .setHasActiveOrDialingCalls(true)
                        .setHasRingingCalls(false)
                        .setHasHoldingCalls(false)
                        .setIsTonePlaying(false)
                        .setForegroundCallIsVoip(false)
                        .setSession(null)
                        .build();
        assertMessageArgEquality(correctArgs, captor.getValue());
        verify(mCallAudioModeStateMachine).sendMessageWithArgs(
                eq(CallAudioModeStateMachine.NEW_ACTIVE_OR_DIALING_CALL), captor.capture());
@@ -216,14 +217,14 @@ public class CallAudioManagerTest extends TelecomTestCase {
        verify(mCallAudioModeStateMachine).sendMessageWithArgs(
                eq(CallAudioModeStateMachine.NO_MORE_RINGING_CALLS), captor.capture());
        CallAudioModeStateMachine.MessageArgs correctArgs =
                new CallAudioModeStateMachine.MessageArgs(
                        true, // hasActiveOrDialingCalls
                        false, // hasRingingCalls
                        false, // hasHoldingCalls
                        false, // isTonePlaying
                        false, // foregroundCallIsVoip
                        null // session
                );
                new Builder()
                        .setHasActiveOrDialingCalls(true)
                        .setHasRingingCalls(false)
                        .setHasHoldingCalls(false)
                        .setIsTonePlaying(false)
                        .setForegroundCallIsVoip(false)
                        .setSession(null)
                        .build();
        assertMessageArgEquality(correctArgs, captor.getValue());
        assertMessageArgEquality(correctArgs, captor.getValue());
        when(call.getState()).thenReturn(CallState.ACTIVE);
@@ -251,14 +252,14 @@ public class CallAudioManagerTest extends TelecomTestCase {
        verify(mCallAudioModeStateMachine).sendMessageWithArgs(
                eq(CallAudioModeStateMachine.NEW_ACTIVE_OR_DIALING_CALL), captor.capture());
        CallAudioModeStateMachine.MessageArgs expectedArgs =
                new CallAudioModeStateMachine.MessageArgs(
                        true, // hasActiveOrDialingCalls
                        false, // hasRingingCalls
                        false, // hasHoldingCalls
                        false, // isTonePlaying
                        false, // foregroundCallIsVoip
                        null // session
                );
                new Builder()
                        .setHasActiveOrDialingCalls(true)
                        .setHasRingingCalls(false)
                        .setHasHoldingCalls(false)
                        .setIsTonePlaying(false)
                        .setForegroundCallIsVoip(false)
                        .setSession(null)
                        .build();
        assertMessageArgEquality(expectedArgs, captor.getValue());

        when(call.getState()).thenReturn(CallState.DIALING);
@@ -297,14 +298,15 @@ public class CallAudioManagerTest extends TelecomTestCase {
                CallAudioRouteStateMachine.UPDATE_SYSTEM_AUDIO_ROUTE);
        verify(mCallAudioModeStateMachine).sendMessageWithArgs(
                eq(CallAudioModeStateMachine.NEW_RINGING_CALL), captor.capture());
        assertMessageArgEquality(new CallAudioModeStateMachine.MessageArgs(
                false, // hasActiveOrDialingCalls
                true, // hasRingingCalls
                false, // hasHoldingCalls
                false, // isTonePlaying
                false, // foregroundCallIsVoip
                null // session
        ), captor.getValue());
        assertMessageArgEquality(new Builder()
                        .setHasActiveOrDialingCalls(false)
                        .setHasRingingCalls(true)
                        .setHasHoldingCalls(false)
                        .setIsTonePlaying(false)
                        .setForegroundCallIsVoip(false)
                        .setSession(null)
                        .build(),
                captor.getValue());

        return call;
    }
@@ -320,14 +322,14 @@ public class CallAudioManagerTest extends TelecomTestCase {

        mCallAudioManager.onCallStateChanged(call, CallState.ACTIVE, CallState.DISCONNECTED);
        verify(mPlayerFactory).createPlayer(InCallTonePlayer.TONE_CALL_ENDED);
        correctArgs = new CallAudioModeStateMachine.MessageArgs(
                false, // hasActiveOrDialingCalls
                false, // hasRingingCalls
                false, // hasHoldingCalls
                true, // isTonePlaying
                false, // foregroundCallIsVoip
                null // session
        );
        correctArgs = new Builder()
                .setHasActiveOrDialingCalls(false)
                .setHasRingingCalls(false)
                .setHasHoldingCalls(false)
                .setIsTonePlaying(true)
                .setForegroundCallIsVoip(false)
                .setSession(null)
                .build();
        verify(mCallAudioModeStateMachine).sendMessageWithArgs(
                eq(CallAudioModeStateMachine.NO_MORE_ACTIVE_OR_DIALING_CALLS), captor.capture());
        assertMessageArgEquality(correctArgs, captor.getValue());
@@ -340,15 +342,14 @@ public class CallAudioManagerTest extends TelecomTestCase {
        ArgumentCaptor<CallAudioModeStateMachine.MessageArgs> captor =
                ArgumentCaptor.forClass(CallAudioModeStateMachine.MessageArgs.class);
        mCallAudioManager.setIsTonePlaying(false);
        CallAudioModeStateMachine.MessageArgs correctArgs =
                new CallAudioModeStateMachine.MessageArgs(
                        false, // hasActiveOrDialingCalls
                        false, // hasRingingCalls
                        false, // hasHoldingCalls
                        false, // isTonePlaying
                        false, // foregroundCallIsVoip
                        null // session
                );
        CallAudioModeStateMachine.MessageArgs correctArgs = new Builder()
                        .setHasActiveOrDialingCalls(false)
                        .setHasRingingCalls(false)
                        .setHasHoldingCalls(false)
                        .setIsTonePlaying(false)
                        .setForegroundCallIsVoip(false)
                        .setSession(null)
                        .build();
        verify(mCallAudioModeStateMachine).sendMessageWithArgs(
                eq(CallAudioModeStateMachine.TONE_STOPPED_PLAYING), captor.capture());
        assertMessageArgEquality(correctArgs, captor.getValue());
+33 −36
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@ import android.test.suitebuilder.annotation.SmallTest;
import com.android.server.telecom.CallAudioManager;
import com.android.server.telecom.CallAudioModeStateMachine;
import com.android.server.telecom.CallAudioRouteStateMachine;
import com.android.server.telecom.CallAudioModeStateMachine.MessageArgs.Builder;
import com.android.server.telecom.SystemStateHelper;

import org.junit.After;
@@ -79,15 +80,14 @@ public class CallAudioModeStateMachineTest extends TelecomTestCase {
        resetMocks();
        when(mCallAudioManager.startRinging()).thenReturn(false);

        sm.sendMessage(CallAudioModeStateMachine.NEW_RINGING_CALL,
                new CallAudioModeStateMachine.MessageArgs(
                        false, // hasActiveOrDialingCalls
                        true, // hasRingingCalls
                        false, // hasHoldingCalls
                        false, // isTonePlaying
                        false, // foregroundCallIsVoip
                        null // session
                ));
        sm.sendMessage(CallAudioModeStateMachine.NEW_RINGING_CALL, new Builder()
                .setHasActiveOrDialingCalls(false)
                .setHasRingingCalls(true)
                .setHasHoldingCalls(false)
                .setIsTonePlaying(false)
                .setForegroundCallIsVoip(false)
                .setSession(null)
                .build());
        waitForHandlerAction(sm.getHandler(), TEST_TIMEOUT);

        assertEquals(CallAudioModeStateMachine.RING_STATE_NAME, sm.getCurrentStateName());
@@ -107,29 +107,27 @@ public class CallAudioModeStateMachineTest extends TelecomTestCase {
                mAudioManager, mTestThread.getLooper());
        sm.setCallAudioManager(mCallAudioManager);
        sm.sendMessage(CallAudioModeStateMachine.ABANDON_FOCUS_FOR_TESTING);
        sm.sendMessage(CallAudioModeStateMachine.NEW_HOLDING_CALL,
                new CallAudioModeStateMachine.MessageArgs(
                        false, // hasActiveOrDialingCalls
                        false, // hasRingingCalls
                        true, // hasHoldingCalls
                        false, // isTonePlaying
                        false, // foregroundCallIsVoip
                        null // session
                ));
        sm.sendMessage(CallAudioModeStateMachine.NEW_HOLDING_CALL, new Builder()
                .setHasActiveOrDialingCalls(false)
                .setHasRingingCalls(false)
                .setHasHoldingCalls(true)
                .setIsTonePlaying(false)
                .setForegroundCallIsVoip(false)
                .setSession(null)
                .build());
        waitForHandlerAction(sm.getHandler(), TEST_TIMEOUT);
        assertEquals(CallAudioModeStateMachine.TONE_HOLD_STATE_NAME, sm.getCurrentStateName());
        when(mSystemStateHelper.isDeviceAtEar()).thenReturn(true);

        resetMocks();
        sm.sendMessage(CallAudioModeStateMachine.NEW_RINGING_CALL,
                new CallAudioModeStateMachine.MessageArgs(
                        false, // hasActiveOrDialingCalls
                        true, // hasRingingCalls
                        true, // hasHoldingCalls
                        false, // isTonePlaying
                        false, // foregroundCallIsVoip
                        null // session
                ));
        sm.sendMessage(CallAudioModeStateMachine.NEW_RINGING_CALL, new Builder()
                .setHasActiveOrDialingCalls(false)
                .setHasRingingCalls(true)
                .setHasHoldingCalls(true)
                .setIsTonePlaying(false)
                .setForegroundCallIsVoip(false)
                .setSession(null)
                .build());
        waitForHandlerAction(sm.getHandler(), TEST_TIMEOUT);

        verify(mAudioManager, never()).requestAudioFocusForCall(anyInt(), anyInt());
@@ -150,15 +148,14 @@ public class CallAudioModeStateMachineTest extends TelecomTestCase {
        resetMocks();
        when(mCallAudioManager.startRinging()).thenReturn(false);

        sm.sendMessage(CallAudioModeStateMachine.NEW_RINGING_CALL,
                new CallAudioModeStateMachine.MessageArgs(
                        false, // hasActiveOrDialingCalls
                        true, // hasRingingCalls
                        false, // hasHoldingCalls
                        false, // isTonePlaying
                        false, // foregroundCallIsVoip
                        null // session
                ));
        sm.sendMessage(CallAudioModeStateMachine.NEW_RINGING_CALL, new Builder()
                .setHasActiveOrDialingCalls(false)
                .setHasRingingCalls(true)
                .setHasHoldingCalls(false)
                .setIsTonePlaying(false)
                .setForegroundCallIsVoip(false)
                .setSession(null)
                .build());
        waitForHandlerAction(sm.getHandler(), TEST_TIMEOUT);

        assertEquals(CallAudioModeStateMachine.RING_STATE_NAME, sm.getCurrentStateName());
Loading