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

Commit e677f01f authored by Yuming Mao's avatar Yuming Mao Committed by Hall Liu
Browse files

Add wired headset media button behavior for two calls

Add wired headset media button behavior during active + hold calls.
 - Short press: Swap calls
 - Long press: End current call

Bug: 110373642
Test: manual - Check that calls swap when wired headset media
button short pressed and current call end when wired headset media
button long pressed during two calls.
Test: auto - Passed "lite_test_telecom -c CallLogManagerTest"
Change-Id: Iccc6ec04c9bbe67b74a35d09e032be1ae29b7b6b
Merged-In: Iccc6ec04c9bbe67b74a35d09e032be1ae29b7b6b
parent 9eec68de
Loading
Loading
Loading
Loading
+22 −1
Original line number Diff line number Diff line
@@ -2110,11 +2110,22 @@ public class CallsManager extends Call.ListenerBase
        return getFirstCallWithState(CallState.RINGING, CallState.ANSWERED) != null;
    }

    boolean onMediaButton(int type) {
    @VisibleForTesting
    public boolean onMediaButton(int type) {
        if (hasAnyCalls()) {
            Call ringingCall = getFirstCallWithState(CallState.RINGING);
            if (HeadsetMediaButton.SHORT_PRESS == type) {
                if (ringingCall == null) {
                    Call activeCall = getFirstCallWithState(CallState.ACTIVE);
                    Call onHoldCall = getFirstCallWithState(CallState.ON_HOLD);
                    if (activeCall != null && onHoldCall != null) {
                        // Two calls, short-press -> switch calls
                        Log.addEvent(onHoldCall, LogUtils.Events.INFO,
                                "two calls, media btn short press - switch call.");
                        unholdCall(onHoldCall);
                        return true;
                    }

                    Call callToHangup = getFirstCallWithState(CallState.RINGING, CallState.DIALING,
                            CallState.PULLING, CallState.ACTIVE, CallState.ON_HOLD);
                    Log.addEvent(callToHangup, LogUtils.Events.INFO,
@@ -2133,6 +2144,16 @@ public class CallsManager extends Call.ListenerBase
                            LogUtils.Events.INFO, "media btn long press - reject");
                    ringingCall.reject(false, null);
                } else {
                    Call activeCall = getFirstCallWithState(CallState.ACTIVE);
                    Call onHoldCall = getFirstCallWithState(CallState.ON_HOLD);
                    if (activeCall != null && onHoldCall != null) {
                        // Two calls, long-press -> end current call
                        Log.addEvent(activeCall, LogUtils.Events.INFO,
                                "two calls, media btn long press - end current call.");
                        disconnectCall(activeCall);
                        return true;
                    }

                    Log.addEvent(getForegroundCall(), LogUtils.Events.INFO,
                            "media btn long press - mute");
                    mCallAudioManager.toggleMute();
+6 −2
Original line number Diff line number Diff line
@@ -26,14 +26,18 @@ import android.os.Message;
import android.telecom.Log;
import android.view.KeyEvent;

import com.android.internal.annotations.VisibleForTesting;

/**
 * Static class to handle listening to the headset media buttons.
 */
public class HeadsetMediaButton extends CallsManagerListenerBase {

    // Types of media button presses
    static final int SHORT_PRESS = 1;
    static final int LONG_PRESS = 2;
    @VisibleForTesting
    public static final int SHORT_PRESS = 1;
    @VisibleForTesting
    public static final int LONG_PRESS = 2;

    private static final AudioAttributes AUDIO_ATTRIBUTES = new AudioAttributes.Builder()
            .setContentType(AudioAttributes.CONTENT_TYPE_SPEECH)
+101 −0
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@ import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyChar;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.ArgumentMatchers.nullable;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.never;
@@ -719,6 +720,106 @@ public class CallsManagerTest extends TelecomTestCase {
        verify(incomingCall).setIsUsingCallFiltering(eq(false));
    }

    @SmallTest
    @Test
    public void testAcceptIncomingCallWhenHeadsetMediaButtonShortPress() {
        // GIVEN an incoming call
        Call incomingCall = addSpyCall();
        doReturn(CallState.RINGING).when(incomingCall).getState();

        // WHEN media button short press
        mCallsManager.onMediaButton(HeadsetMediaButton.SHORT_PRESS);

        // THEN the incoming call is answered
        verify(incomingCall).answer(VideoProfile.STATE_AUDIO_ONLY);
    }

    @SmallTest
    @Test
    public void testRejectIncomingCallWhenHeadsetMediaButtonLongPress() {
        // GIVEN an incoming call
        Call incomingCall = addSpyCall();
        doReturn(CallState.RINGING).when(incomingCall).getState();

        // WHEN media button long press
        mCallsManager.onMediaButton(HeadsetMediaButton.LONG_PRESS);

        // THEN the incoming call is rejected
        verify(incomingCall).reject(false, null);
    }

    @SmallTest
    @Test
    public void testHangupOngoingCallWhenHeadsetMediaButtonShortPress() {
        // GIVEN an ongoing call
        Call ongoingCall = addSpyCall();
        doReturn(CallState.ACTIVE).when(ongoingCall).getState();

        // WHEN media button short press
        mCallsManager.onMediaButton(HeadsetMediaButton.SHORT_PRESS);

        // THEN the active call is disconnected
        verify(ongoingCall).disconnect();
    }

    @SmallTest
    @Test
    public void testToggleMuteWhenHeadsetMediaButtonLongPressDuringOngoingCall() {
        // GIVEN an ongoing call
        Call ongoingCall = addSpyCall();
        doReturn(CallState.ACTIVE).when(ongoingCall).getState();

        // WHEN media button long press
        mCallsManager.onMediaButton(HeadsetMediaButton.LONG_PRESS);

        // THEN the microphone toggle mute
        verify(mCallAudioRouteStateMachine)
                .sendMessageWithSessionInfo(CallAudioRouteStateMachine.TOGGLE_MUTE);
    }

    @SmallTest
    @Test
    public void testSwapCallsWhenHeadsetMediaButtonShortPressDuringTwoCalls() {
        // GIVEN an ongoing call, and this call can be held
        Call ongoingCall = addSpyCall();
        doReturn(CallState.ACTIVE).when(ongoingCall).getState();
        doReturn(true).when(ongoingCall).can(Connection.CAPABILITY_HOLD);
        doReturn(true).when(ongoingCall).can(Connection.CAPABILITY_SUPPORT_HOLD);
        when(mConnectionSvrFocusMgr.getCurrentFocusCall()).thenReturn(ongoingCall);

        // and a held call
        Call heldCall = addSpyCall();
        doReturn(CallState.ON_HOLD).when(heldCall).getState();

        // WHEN media button short press
        mCallsManager.onMediaButton(HeadsetMediaButton.SHORT_PRESS);

        // THEN the ongoing call is held, and the focus request for heldCall call is sent
        verify(ongoingCall).hold(nullable(String.class));
        verifyFocusRequestAndExecuteCallback(heldCall);

        // and held call is unhold now
        verify(heldCall).unhold(nullable(String.class));
    }

    @SmallTest
    @Test
    public void testHangupActiveCallWhenHeadsetMediaButtonLongPressDuringTwoCalls() {
        // GIVEN an  ongoing call
        Call ongoingCall = addSpyCall();
        doReturn(CallState.ACTIVE).when(ongoingCall).getState();

        // and a held call
        Call heldCall = addSpyCall();
        doReturn(CallState.ON_HOLD).when(heldCall).getState();

        // WHEN media button long press
        mCallsManager.onMediaButton(HeadsetMediaButton.LONG_PRESS);

        // THEN the ongoing call is disconnected
        verify(ongoingCall).disconnect();
    }

    private Call addSpyCallWithConnectionService(ConnectionServiceWrapper connSvr) {
        Call call = addSpyCall();
        doReturn(connSvr).when(call).getConnectionService();