Loading src/com/android/server/telecom/CallsManager.java +49 −32 Original line number Diff line number Diff line Loading @@ -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(); Loading @@ -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 && Loading @@ -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; }); } /** Loading tests/src/com/android/server/telecom/tests/CallsManagerTest.java +48 −0 Original line number Diff line number Diff line Loading @@ -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() { Loading Loading
src/com/android/server/telecom/CallsManager.java +49 −32 Original line number Diff line number Diff line Loading @@ -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(); Loading @@ -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 && Loading @@ -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; }); } /** Loading
tests/src/com/android/server/telecom/tests/CallsManagerTest.java +48 −0 Original line number Diff line number Diff line Loading @@ -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() { Loading