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

Commit 961c49f4 authored by Tyler Gunn's avatar Tyler Gunn Committed by Android (Google) Code Review
Browse files

Merge "Ensure audio mode is updated when the foreground call changes." into main

parents 0a3ab3d7 2d889159
Loading
Loading
Loading
Loading
+34 −4
Original line number Diff line number Diff line
@@ -36,6 +36,8 @@ import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
import java.util.LinkedHashSet;
import java.util.stream.Collectors;


public class CallAudioManager extends CallsManagerListenerBase {

@@ -116,7 +118,7 @@ public class CallAudioManager extends CallsManagerListenerBase {
            // State did not change, so no need to do anything.
            return;
        }
        Log.d(LOG_TAG, "Call state changed for TC@%s: %s -> %s", call.getId(),
        Log.i(this, "onCallStateChanged: Call state changed for TC@%s: %s -> %s", call.getId(),
                CallState.toString(oldState), CallState.toString(newState));

        removeCallFromAllBins(call);
@@ -761,6 +763,7 @@ public class CallAudioManager extends CallsManagerListenerBase {

    private void updateForegroundCall() {
        Call oldForegroundCall = mForegroundCall;

        if (mActiveDialingOrConnectingCalls.size() > 0) {
            // Give preference for connecting calls over active/dialing for foreground-ness.
            Call possibleConnectingCall = null;
@@ -769,8 +772,21 @@ public class CallAudioManager extends CallsManagerListenerBase {
                    possibleConnectingCall = call;
                }
            }
            mForegroundCall = possibleConnectingCall == null ?
                    mActiveDialingOrConnectingCalls.iterator().next() : possibleConnectingCall;
            // Prefer a connecting call
            if (possibleConnectingCall != null) {
                mForegroundCall = possibleConnectingCall;
            } else {
                // Next, prefer an active or dialing call which is not in the process of being
                // disconnected.
                mForegroundCall = mActiveDialingOrConnectingCalls
                        .stream()
                        .filter(c -> (c.getState() == CallState.ACTIVE
                                || c.getState() == CallState.DIALING)
                                && !c.isLocallyDisconnecting())
                        .findFirst()
                        // If we can't find one, then just fall back to the first one.
                        .orElse(mActiveDialingOrConnectingCalls.iterator().next());
            }
        } else if (mRingingCalls.size() > 0) {
            mForegroundCall = mRingingCalls.iterator().next();
        } else if (mHoldingCalls.size() > 0) {
@@ -778,10 +794,24 @@ public class CallAudioManager extends CallsManagerListenerBase {
        } else {
            mForegroundCall = null;
        }

        Log.i(this, "updateForegroundCall; oldFg=%s, newFg=%s, aDC=%s, ring=%s, hold=%s",
                (oldForegroundCall == null ? "none" : oldForegroundCall.getId()),
                (mForegroundCall == null ? "none" : mForegroundCall.getId()),
                mActiveDialingOrConnectingCalls.stream().map(c -> c.getId()).collect(
                        Collectors.joining(",")),
                mRingingCalls.stream().map(c -> c.getId()).collect(Collectors.joining(",")),
                mHoldingCalls.stream().map(c -> c.getId()).collect(Collectors.joining(","))
        );
        if (mForegroundCall != oldForegroundCall) {
            mCallAudioRouteStateMachine.sendMessageWithSessionInfo(
                    CallAudioRouteStateMachine.UPDATE_SYSTEM_AUDIO_ROUTE);

            if (mForegroundCall != null) {
                // Ensure the voip audio mode for the new foreground call is taken into account.
                mCallAudioModeStateMachine.sendMessageWithArgs(
                        CallAudioModeStateMachine.FOREGROUND_VOIP_MODE_CHANGE,
                        makeArgsForModeStateMachine());
            }
            mDtmfLocalTonePlayer.onForegroundCallChanged(oldForegroundCall, mForegroundCall);
            maybePlayHoldTone();
        }
+73 −3
Original line number Diff line number Diff line
@@ -59,6 +59,7 @@ import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.clearInvocations;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
@@ -277,7 +278,8 @@ public class CallAudioManagerTest extends TelecomTestCase {
        verify(mCallAudioModeStateMachine, times(2)).sendMessageWithArgs(
                eq(CallAudioModeStateMachine.NEW_ACTIVE_OR_DIALING_CALL), captor.capture());
        assertMessageArgEquality(expectedArgs, captor.getValue());
        verify(mCallAudioModeStateMachine, times(2)).sendMessageWithArgs(
        // Expet another invocation due to audio mode change signal.
        verify(mCallAudioModeStateMachine, times(3)).sendMessageWithArgs(
                anyInt(), any(CallAudioModeStateMachine.MessageArgs.class));


@@ -286,7 +288,7 @@ public class CallAudioManagerTest extends TelecomTestCase {
        verify(mCallAudioModeStateMachine, times(3)).sendMessageWithArgs(
                eq(CallAudioModeStateMachine.NEW_ACTIVE_OR_DIALING_CALL), captor.capture());
        assertMessageArgEquality(expectedArgs, captor.getValue());
        verify(mCallAudioModeStateMachine, times(3)).sendMessageWithArgs(
        verify(mCallAudioModeStateMachine, times(4)).sendMessageWithArgs(
                anyInt(), any(CallAudioModeStateMachine.MessageArgs.class));

        disconnectCall(call);
@@ -327,7 +329,8 @@ public class CallAudioManagerTest extends TelecomTestCase {
        verify(mCallAudioModeStateMachine, times(2)).sendMessageWithArgs(
                eq(CallAudioModeStateMachine.NEW_ACTIVE_OR_DIALING_CALL), captor.capture());
        assertMessageArgEquality(expectedArgs, captor.getValue());
        verify(mCallAudioModeStateMachine, times(2)).sendMessageWithArgs(
        // Expect an extra time due to audio mode change signal
        verify(mCallAudioModeStateMachine, times(3)).sendMessageWithArgs(
                anyInt(), any(CallAudioModeStateMachine.MessageArgs.class));

        // Ensure we started ringback.
@@ -702,6 +705,73 @@ public class CallAudioManagerTest extends TelecomTestCase {
        assertFalse(captor.getValue().isStreaming);
    }

    @SmallTest
    @Test
    public void testTriggerAudioManagerModeChange() {
        // Start with an incoming PSTN call
        Call pstnCall = mock(Call.class);
        when(pstnCall.getState()).thenReturn(CallState.RINGING);
        when(pstnCall.getIsVoipAudioMode()).thenReturn(false);
        ArgumentCaptor<CallAudioModeStateMachine.MessageArgs> captor = makeNewCaptor();

        // Add the call
        mCallAudioManager.onCallAdded(pstnCall);
        verify(mCallAudioModeStateMachine).sendMessageWithArgs(
                eq(CallAudioModeStateMachine.FOREGROUND_VOIP_MODE_CHANGE), captor.capture());
        CallAudioModeStateMachine.MessageArgs expectedArgs =
                new Builder()
                        .setHasActiveOrDialingCalls(false)
                        .setHasRingingCalls(true)
                        .setHasHoldingCalls(false)
                        .setIsTonePlaying(false)
                        .setHasAudioProcessingCalls(false)
                        .setForegroundCallIsVoip(false)
                        .setSession(null)
                        .setForegroundCallIsVoip(false)
                        .build();
        assertMessageArgEquality(expectedArgs, captor.getValue());
        clearInvocations(mCallAudioModeStateMachine); // Avoid verifying for previous calls

        // Make call active; don't expect there to be an audio mode transition.
        when(pstnCall.getState()).thenReturn(CallState.ACTIVE);
        mCallAudioManager.onCallStateChanged(pstnCall, CallState.RINGING, CallState.ACTIVE);
        verify(mCallAudioModeStateMachine, never()).sendMessageWithArgs(
                eq(CallAudioModeStateMachine.FOREGROUND_VOIP_MODE_CHANGE),
                any(CallAudioModeStateMachine.MessageArgs.class));
        clearInvocations(mCallAudioModeStateMachine); // Avoid verifying for previous calls

        // Add a new Voip call in ringing state; this should not result in a direct audio mode
        // change.
        Call voipCall = mock(Call.class);
        when(voipCall.getState()).thenReturn(CallState.RINGING);
        when(voipCall.getIsVoipAudioMode()).thenReturn(true);
        mCallAudioManager.onCallAdded(voipCall);
        verify(mCallAudioModeStateMachine, never()).sendMessageWithArgs(
                eq(CallAudioModeStateMachine.FOREGROUND_VOIP_MODE_CHANGE),
                any(CallAudioModeStateMachine.MessageArgs.class));
        clearInvocations(mCallAudioModeStateMachine); // Avoid verifying for previous calls

        // Make voip call active and set the PSTN call to locally disconnecting; the new foreground
        // call will be the voip call.
        when(pstnCall.isLocallyDisconnecting()).thenReturn(true);
        when(voipCall.getState()).thenReturn(CallState.ACTIVE);
        mCallAudioManager.onCallStateChanged(voipCall, CallState.RINGING, CallState.ACTIVE);
        verify(mCallAudioModeStateMachine).sendMessageWithArgs(
                eq(CallAudioModeStateMachine.FOREGROUND_VOIP_MODE_CHANGE), captor.capture());
        CallAudioModeStateMachine.MessageArgs expectedArgs2 =
                new Builder()
                        .setHasActiveOrDialingCalls(true)
                        .setHasRingingCalls(false)
                        .setHasHoldingCalls(false)
                        .setIsTonePlaying(false)
                        .setHasAudioProcessingCalls(false)
                        .setForegroundCallIsVoip(false)
                        .setSession(null)
                        .setForegroundCallIsVoip(true)
                        .build();
        assertMessageArgEquality(expectedArgs2, captor.getValue());
    }

    private Call createSimulatedRingingCall() {
        Call call = mock(Call.class);
        when(call.getState()).thenReturn(CallState.SIMULATED_RINGING);