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

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

Merge "Ensure calls are not unheld between apps automatically." into udc-dev

parents 4eb22a9d 2cc89e4a
Loading
Loading
Loading
Loading
+49 −32
Original line number Diff line number Diff line
@@ -3656,7 +3656,27 @@ public class CallsManager extends Call.ListenerBase
     * @param call The call.
     */
    private void performRemoval(Call call) {
        if (mInCallController.getBindingFuture() != null) {
            mInCallController.getBindingFuture().thenRunAsync(() -> {
                        doRemoval(call);
                    }, new LoggedHandlerExecutor(mHandler, "CM.pR", mLock))
                    .exceptionally((throwable) -> {
                        Log.e(TAG, throwable, "Error while executing call removal");
                        mAnomalyReporter.reportAnomaly(CALL_REMOVAL_EXECUTION_ERROR_UUID,
                                CALL_REMOVAL_EXECUTION_ERROR_MSG);
                        return null;
                    });
        } else {
            doRemoval(call);
        }
    }

    /**
     * Code to perform removal of a call.  Called above from {@link #performRemoval(Call)} either
     * async (in live code) or sync (in testing).
     * @param call the call to remove.
     */
    private void doRemoval(Call call) {
        call.maybeCleanupHandover();
        removeCall(call);
        Call foregroundCall = mCallAudioManager.getPossiblyHeldForegroundCall();
@@ -3668,8 +3688,12 @@ public class CallsManager extends Call.ListenerBase
            // Auto-unhold the foreground call due to a locally disconnected call, except if the
            // call which was disconnected is a member of a conference (don't want to auto
            // un-hold the conference if we remove a member of the conference).
            // Also, ensure that the call we're removing is from the same ConnectionService as
            // the one we're removing.  We don't want to auto-unhold between ConnectionService
            // implementations, especially if one is managed and the other is a VoIP CS.
            if (!isDisconnectingChildCall && foregroundCall != null
                        && foregroundCall.getState() == CallState.ON_HOLD) {
                    && foregroundCall.getState() == CallState.ON_HOLD
                    && areFromSameSource(foregroundCall, call)) {
                foregroundCall.unhold();
            }
        } else if (foregroundCall != null &&
@@ -3683,13 +3707,6 @@ public class CallsManager extends Call.ListenerBase
                    + "support hold)");
            foregroundCall.unhold();
        }
        }, new LoggedHandlerExecutor(mHandler, "CM.pR", mLock))
                .exceptionally((throwable) -> {
                    Log.e(TAG, throwable, "Error while executing call removal");
                    mAnomalyReporter.reportAnomaly(CALL_REMOVAL_EXECUTION_ERROR_UUID,
                            CALL_REMOVAL_EXECUTION_ERROR_MSG);
                    return null;
                });
    }

    /**
+48 −0
Original line number Diff line number Diff line
@@ -688,6 +688,54 @@ public class CallsManagerTest extends TelecomTestCase {
        verify(heldCall).unhold(any());
    }

    /**
     * Ensures we don't auto-unhold a call from a different app when we locally disconnect a call.
     */
    @SmallTest
    @Test
    public void testDontUnholdCallsBetweenConnectionServices() {
        // GIVEN a CallsManager with ongoing call
        Call ongoingCall = addSpyCall(SIM_1_HANDLE, CallState.ACTIVE);
        when(ongoingCall.isDisconnectHandledViaFuture()).thenReturn(false);
        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 which has different ConnectionService
        Call heldCall = addSpyCall(VOIP_1_HANDLE, CallState.ON_HOLD);

        // Disconnect and cleanup the active ongoing call.
        mCallsManager.disconnectCall(ongoingCall);
        mCallsManager.markCallAsRemoved(ongoingCall);

        // Should not unhold the held call since its in another app.
        verify(heldCall, never()).unhold();
    }

    /**
     * Ensures we do auto-unhold a call from the same app when we locally disconnect a call.
     */
    @SmallTest
    @Test
    public void testUnholdCallWhenDisconnectingInSameApp() {
        // GIVEN a CallsManager with ongoing call
        Call ongoingCall = addSpyCall(SIM_1_HANDLE, CallState.ACTIVE);
        when(ongoingCall.isDisconnectHandledViaFuture()).thenReturn(false);
        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 which has same ConnectionService
        Call heldCall = addSpyCall(SIM_1_HANDLE, CallState.ON_HOLD);

        // Disconnect and cleanup the active ongoing call.
        mCallsManager.disconnectCall(ongoingCall);
        mCallsManager.markCallAsRemoved(ongoingCall);

        // Should auto-unhold the held call since its in the same app.
        verify(heldCall).unhold();
    }

    @SmallTest
    @Test
    public void testUnholdCallWhenOngoingEmergCallCanNotBeHeldAndFromDifferentConnectionService() {