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

Commit a76d556c authored by Tyler Gunn's avatar Tyler Gunn
Browse files

Prevent self-managed call control from TelecomManager APIs.

Prevent answerRingingCall and endCall from manipulating self-managed
calls.
Fix minor log spamming in Call.

Test: Add unit tests for new behavior change.
Bug: 173739006
Fixes: 183036796
Change-Id: I49f2ec0fb1f2007107bc0d5b24b1c541ed9a5d1b
parent 70decc1a
Loading
Loading
Loading
Loading
+4 −1
Original line number Diff line number Diff line
@@ -3760,7 +3760,10 @@ public class Call implements CreateConnectionResponse, EventManager.Loggable,
     * @param extras The extras.
     */
    public void onConnectionEvent(String event, Bundle extras) {
        // Don't log call quality reports; they're quite frequent and will clog the log.
        if (!Connection.EVENT_CALL_QUALITY_REPORT.equals(event)) {
            Log.addEvent(this, LogUtils.Events.CONNECTION_EVENT, event);
        }
        if (Connection.EVENT_ON_HOLD_TONE_START.equals(event)) {
            mIsRemotelyHeld = true;
            Log.addEvent(this, LogUtils.Events.REMOTELY_HELD);
+17 −4
Original line number Diff line number Diff line
@@ -948,7 +948,7 @@ public class TelecomServiceImpl {

                    long token = Binder.clearCallingIdentity();
                    try {
                        acceptRingingCallInternal(DEFAULT_VIDEO_STATE);
                        acceptRingingCallInternal(DEFAULT_VIDEO_STATE, packageName);
                    } finally {
                        Binder.restoreCallingIdentity(token);
                    }
@@ -971,7 +971,7 @@ public class TelecomServiceImpl {

                    long token = Binder.clearCallingIdentity();
                    try {
                        acceptRingingCallInternal(videoState);
                        acceptRingingCallInternal(videoState, packageName);
                    } finally {
                        Binder.restoreCallingIdentity(token);
                    }
@@ -2078,9 +2078,16 @@ public class TelecomServiceImpl {
        return false;
    }

    private void acceptRingingCallInternal(int videoState) {
        Call call = mCallsManager.getFirstCallWithState(CallState.RINGING, CallState.SIMULATED_RINGING);
    private void acceptRingingCallInternal(int videoState, String packageName) {
        Call call = mCallsManager.getFirstCallWithState(CallState.RINGING,
                CallState.SIMULATED_RINGING);
        if (call != null) {
            if (call.isSelfManaged()) {
                Log.addEvent(call, LogUtils.Events.REQUEST_ACCEPT,
                        "self-mgd accept ignored from " + packageName);
                return;
            }

            if (videoState == DEFAULT_VIDEO_STATE || !isValidAcceptVideoState(videoState)) {
                videoState = call.getVideoState();
            }
@@ -2108,6 +2115,12 @@ public class TelecomServiceImpl {
                return false;
            }

            if (call.isSelfManaged()) {
                Log.addEvent(call, LogUtils.Events.REQUEST_DISCONNECT,
                        "self-mgd disconnect ignored from " + callingPackage);
                return false;
            }

            if (call.getState() == CallState.RINGING
                    || call.getState() == CallState.SIMULATED_RINGING) {
                mCallsManager.rejectCall(call, false /* rejectWithMessage */, null);
+33 −0
Original line number Diff line number Diff line
@@ -1201,6 +1201,39 @@ public class TelecomServiceImplTest extends TelecomTestCase {
        verify(mFakeCallsManager, never()).hasOngoingCalls();
    }

    /**
     * Ensure self-managed calls cannot be ended using {@link TelecomManager#endCall()}.
     * @throws Exception
     */
    @SmallTest
    @Test
    public void testCannotEndSelfManagedCall() throws Exception {
        Call call = mock(Call.class);
        when(call.isSelfManaged()).thenReturn(true);
        when(call.getState()).thenReturn(CallState.ACTIVE);
        when(mFakeCallsManager.getFirstCallWithState(any()))
                .thenReturn(call);
        assertFalse(mTSIBinder.endCall(TEST_PACKAGE));
        verify(mFakeCallsManager, never()).disconnectCall(eq(call));
    }

    /**
     * Ensure self-managed calls cannot be answered using {@link TelecomManager#acceptRingingCall()}
     * or {@link TelecomManager#acceptRingingCall(int)}.
     * @throws Exception
     */
    @SmallTest
    @Test
    public void testCannotAnswerSelfManagedCall() throws Exception {
        Call call = mock(Call.class);
        when(call.isSelfManaged()).thenReturn(true);
        when(call.getState()).thenReturn(CallState.ACTIVE);
        when(mFakeCallsManager.getFirstCallWithState(any()))
                .thenReturn(call);
        mTSIBinder.acceptRingingCall(TEST_PACKAGE);
        verify(mFakeCallsManager, never()).answerCall(eq(call), anyInt());
    }

    /**
     * Register phone accounts for the supplied PhoneAccountHandles to make them
     * visible to all users (via the isVisibleToCaller method in TelecomServiceImpl.