Loading src/com/android/server/telecom/Call.java +31 −8 Original line number Diff line number Diff line Loading @@ -453,17 +453,24 @@ public class Call implements CreateConnectionResponse, EventManager.Loggable { private int mPendingRttRequestId = INVALID_RTT_REQUEST_ID; /** * When a call handover has been initiated via {@link #requestHandover(PhoneAccountHandle)}, * contains the call which this call is being handed over to. * When a call handover has been initiated via {@link #requestHandover(PhoneAccountHandle, * int, Bundle)}, contains the call which this call is being handed over to. */ private Call mHandoverToCall = null; /** * When a call handover has been initiated via {@link #requestHandover(PhoneAccountHandle)}, * contains the call which this call is being handed over from. * When a call handover has been initiated via {@link #requestHandover(PhoneAccountHandle, * int, Bundle)}, contains the call which this call is being handed over from. */ private Call mHandoverFromCall = null; /** * When a call handover has been initiated via {@link #requestHandover(PhoneAccountHandle, * int, Bundle)} and the handover has successfully succeeded, this field is set {@code true} to * indicate that the call was handed over from another call. */ private boolean mIsHandoverSuccessful = false; /** * Persists the specified parameters and initializes the new instance. * Loading Loading @@ -1078,20 +1085,32 @@ public class Call implements CreateConnectionResponse, EventManager.Loggable { } /** * Marks a handover as being completed, either as a result of failing to handover or completion * of handover. * Marks a handover as failed. */ public void markHandoverFailed() { markHandoverResult(false /* isComplete */); } /** * Marks a handover as being successful. */ public void markHandoverFinished() { public void markHandoverSuccess() { markHandoverResult(true /* isComplete */); } private void markHandoverResult(boolean isHandoverSuccessful) { if (mHandoverFromCall != null) { mHandoverFromCall.mIsHandoverSuccessful = isHandoverSuccessful; mHandoverFromCall.setHandoverFromCall(null); mHandoverFromCall.setHandoverToCall(null); mHandoverFromCall = null; } else if (mHandoverToCall != null) { mHandoverToCall.mIsHandoverSuccessful = isHandoverSuccessful; mHandoverToCall.setHandoverFromCall(null); mHandoverToCall.setHandoverToCall(null); mHandoverToCall = null; } mIsHandoverSuccessful = isHandoverSuccessful; } public boolean isHandoverInProgress() { Loading @@ -1114,6 +1133,10 @@ public class Call implements CreateConnectionResponse, EventManager.Loggable { mHandoverFromCall = call; } public boolean isHandoverSuccessful() { return mIsHandoverSuccessful; } private void configureIsWorkCall() { PhoneAccountRegistrar phoneAccountRegistrar = mCallsManager.getPhoneAccountRegistrar(); boolean isWorkCall = false; Loading src/com/android/server/telecom/CallsManager.java +4 −5 Original line number Diff line number Diff line Loading @@ -1721,7 +1721,7 @@ public class CallsManager extends Call.ListenerBase * Removes an existing disconnected call, and notifies the in-call app. */ void markCallAsRemoved(Call call) { call.markHandoverFinished(); call.markHandoverFailed(); removeCall(call); Call foregroundCall = mCallAudioManager.getPossiblyHeldForegroundCall(); Loading Loading @@ -2190,9 +2190,9 @@ public class CallsManager extends Call.ListenerBase android.telecom.Connection.EVENT_HANDOVER_COMPLETE, null); markCallAsDisconnected(handoverFrom, new DisconnectCause(DisconnectCause.LOCAL)); call.markHandoverSuccess(); markCallAsRemoved(handoverFrom); call.sendCallEvent(android.telecom.Call.EVENT_HANDOVER_COMPLETE, null); call.markHandoverFinished(); } else if (newState == CallState.DISCONNECTED) { Call handoverFrom = call.getHandoverFromCall(); Log.i(this, "Call %s failed to handover from %s.", Loading @@ -2211,13 +2211,12 @@ public class CallsManager extends Call.ListenerBase // able to send the call event. call.sendCallEvent(android.telecom.Call.EVENT_HANDOVER_FAILED, null); } call.markHandoverFinished(); call.markHandoverFailed(); } // If this call was disconnected because it was handed over TO another call, report the // handover as complete. } else if (call.getHandoverToCall() != null && newState == CallState.DISCONNECTED) { Call handoverTo = call.getHandoverToCall(); Log.addEvent(handoverTo, LogUtils.Events.HANDOVER_COMPLETE, "from=%s, to=%s", call.getId(), handoverTo.getId()); Log.addEvent(call, LogUtils.Events.HANDOVER_COMPLETE, "from=%s, to=%s", Loading @@ -2230,7 +2229,7 @@ public class CallsManager extends Call.ListenerBase // Inform the "to" ConnectionService that handover to it has completed. handoverTo.sendCallEvent(android.telecom.Call.EVENT_HANDOVER_COMPLETE, null); answerCall(handoverTo, handoverTo.getVideoState()); call.markHandoverFinished(); call.markHandoverSuccess(); } // Only broadcast state change for calls that are being tracked. Loading src/com/android/server/telecom/ui/IncomingCallNotifier.java +2 −3 Original line number Diff line number Diff line Loading @@ -23,7 +23,6 @@ import android.content.Context; import android.content.Intent; import android.os.Bundle; import android.telecom.Log; import android.telecom.PhoneAccount; import android.telecom.PhoneAccountHandle; import android.telecom.TelecomManager; import android.telecom.VideoProfile; Loading @@ -34,7 +33,6 @@ import android.text.style.ForegroundColorSpan; import android.util.ArraySet; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.telephony.CallerInfo; import com.android.server.telecom.Call; import com.android.server.telecom.CallState; import com.android.server.telecom.CallsManagerListenerBase; Loading Loading @@ -133,7 +131,8 @@ public class IncomingCallNotifier extends CallsManagerListenerBase { private void updateIncomingCall() { Optional<Call> incomingCallOp = mCalls.stream() .filter(call -> call.isSelfManaged() && call.isIncoming() && call.getState() == CallState.RINGING && !call.isHandoverInProgress()) call.getState() == CallState.RINGING && !call.isHandoverInProgress() && !call.isHandoverSuccessful()) .findFirst(); Call incomingCall = incomingCallOp.orElse(null); if (incomingCall != null && mCallsManagerProxy != null && Loading tests/src/com/android/server/telecom/tests/IncomingCallNotifierTest.java +40 −3 Original line number Diff line number Diff line Loading @@ -16,11 +16,9 @@ package com.android.server.telecom.tests; import android.app.Notification; import android.app.NotificationManager; import android.content.Context; import android.content.pm.ApplicationInfo; import android.content.res.Resources; import android.os.Build; import android.telecom.VideoProfile; import android.test.suitebuilder.annotation.SmallTest; Loading @@ -29,7 +27,6 @@ import com.android.server.telecom.Call; import com.android.server.telecom.CallState; import com.android.server.telecom.ui.IncomingCallNotifier; import org.mockito.ArgumentCaptor; import org.mockito.Mock; import static org.mockito.Matchers.any; Loading Loading @@ -73,6 +70,8 @@ public class IncomingCallNotifierTest extends TelecomTestCase { when(mRingingCall.getState()).thenReturn(CallState.RINGING); when(mRingingCall.getVideoState()).thenReturn(VideoProfile.STATE_AUDIO_ONLY); when(mRingingCall.getTargetPhoneAccountLabel()).thenReturn("Foo"); when(mRingingCall.isHandoverInProgress()).thenReturn(false); when(mRingingCall.isHandoverSuccessful()).thenReturn(false); } /** Loading Loading @@ -128,4 +127,42 @@ public class IncomingCallNotifierTest extends TelecomTestCase { verify(mNotificationManager).cancel(eq(IncomingCallNotifier.NOTIFICATION_TAG), eq(IncomingCallNotifier.NOTIFICATION_INCOMING_CALL)); } /** * Ensure notification doesn't show during handover. */ @SmallTest public void testDontShowDuringHandover1() { when(mCallsManagerProxy.hasCallsForOtherPhoneAccount(any())).thenReturn(true); when(mCallsManagerProxy.getNumCallsForOtherPhoneAccount(any())).thenReturn(1); when(mCallsManagerProxy.getActiveCall()).thenReturn(mAudioCall); when(mRingingCall.isHandoverInProgress()).thenReturn(true); when(mRingingCall.isHandoverSuccessful()).thenReturn(false); mIncomingCallNotifier.onCallAdded(mAudioCall); mIncomingCallNotifier.onCallAdded(mRingingCall); // Incoming call is in the middle of a handover, don't expect to be notified. verify(mNotificationManager, never()).notify(eq(IncomingCallNotifier.NOTIFICATION_TAG), eq(IncomingCallNotifier.NOTIFICATION_INCOMING_CALL), any());; } /** * Ensure notification doesn't show during handover. */ @SmallTest public void testDontShowDuringHandover2() { when(mCallsManagerProxy.hasCallsForOtherPhoneAccount(any())).thenReturn(true); when(mCallsManagerProxy.getNumCallsForOtherPhoneAccount(any())).thenReturn(1); when(mCallsManagerProxy.getActiveCall()).thenReturn(mAudioCall); when(mRingingCall.isHandoverInProgress()).thenReturn(false); when(mRingingCall.isHandoverSuccessful()).thenReturn(true); mIncomingCallNotifier.onCallAdded(mAudioCall); mIncomingCallNotifier.onCallAdded(mRingingCall); // Incoming call is done a handover, don't expect to be notified. verify(mNotificationManager, never()).notify(eq(IncomingCallNotifier.NOTIFICATION_TAG), eq(IncomingCallNotifier.NOTIFICATION_INCOMING_CALL), any());; } } Loading
src/com/android/server/telecom/Call.java +31 −8 Original line number Diff line number Diff line Loading @@ -453,17 +453,24 @@ public class Call implements CreateConnectionResponse, EventManager.Loggable { private int mPendingRttRequestId = INVALID_RTT_REQUEST_ID; /** * When a call handover has been initiated via {@link #requestHandover(PhoneAccountHandle)}, * contains the call which this call is being handed over to. * When a call handover has been initiated via {@link #requestHandover(PhoneAccountHandle, * int, Bundle)}, contains the call which this call is being handed over to. */ private Call mHandoverToCall = null; /** * When a call handover has been initiated via {@link #requestHandover(PhoneAccountHandle)}, * contains the call which this call is being handed over from. * When a call handover has been initiated via {@link #requestHandover(PhoneAccountHandle, * int, Bundle)}, contains the call which this call is being handed over from. */ private Call mHandoverFromCall = null; /** * When a call handover has been initiated via {@link #requestHandover(PhoneAccountHandle, * int, Bundle)} and the handover has successfully succeeded, this field is set {@code true} to * indicate that the call was handed over from another call. */ private boolean mIsHandoverSuccessful = false; /** * Persists the specified parameters and initializes the new instance. * Loading Loading @@ -1078,20 +1085,32 @@ public class Call implements CreateConnectionResponse, EventManager.Loggable { } /** * Marks a handover as being completed, either as a result of failing to handover or completion * of handover. * Marks a handover as failed. */ public void markHandoverFailed() { markHandoverResult(false /* isComplete */); } /** * Marks a handover as being successful. */ public void markHandoverFinished() { public void markHandoverSuccess() { markHandoverResult(true /* isComplete */); } private void markHandoverResult(boolean isHandoverSuccessful) { if (mHandoverFromCall != null) { mHandoverFromCall.mIsHandoverSuccessful = isHandoverSuccessful; mHandoverFromCall.setHandoverFromCall(null); mHandoverFromCall.setHandoverToCall(null); mHandoverFromCall = null; } else if (mHandoverToCall != null) { mHandoverToCall.mIsHandoverSuccessful = isHandoverSuccessful; mHandoverToCall.setHandoverFromCall(null); mHandoverToCall.setHandoverToCall(null); mHandoverToCall = null; } mIsHandoverSuccessful = isHandoverSuccessful; } public boolean isHandoverInProgress() { Loading @@ -1114,6 +1133,10 @@ public class Call implements CreateConnectionResponse, EventManager.Loggable { mHandoverFromCall = call; } public boolean isHandoverSuccessful() { return mIsHandoverSuccessful; } private void configureIsWorkCall() { PhoneAccountRegistrar phoneAccountRegistrar = mCallsManager.getPhoneAccountRegistrar(); boolean isWorkCall = false; Loading
src/com/android/server/telecom/CallsManager.java +4 −5 Original line number Diff line number Diff line Loading @@ -1721,7 +1721,7 @@ public class CallsManager extends Call.ListenerBase * Removes an existing disconnected call, and notifies the in-call app. */ void markCallAsRemoved(Call call) { call.markHandoverFinished(); call.markHandoverFailed(); removeCall(call); Call foregroundCall = mCallAudioManager.getPossiblyHeldForegroundCall(); Loading Loading @@ -2190,9 +2190,9 @@ public class CallsManager extends Call.ListenerBase android.telecom.Connection.EVENT_HANDOVER_COMPLETE, null); markCallAsDisconnected(handoverFrom, new DisconnectCause(DisconnectCause.LOCAL)); call.markHandoverSuccess(); markCallAsRemoved(handoverFrom); call.sendCallEvent(android.telecom.Call.EVENT_HANDOVER_COMPLETE, null); call.markHandoverFinished(); } else if (newState == CallState.DISCONNECTED) { Call handoverFrom = call.getHandoverFromCall(); Log.i(this, "Call %s failed to handover from %s.", Loading @@ -2211,13 +2211,12 @@ public class CallsManager extends Call.ListenerBase // able to send the call event. call.sendCallEvent(android.telecom.Call.EVENT_HANDOVER_FAILED, null); } call.markHandoverFinished(); call.markHandoverFailed(); } // If this call was disconnected because it was handed over TO another call, report the // handover as complete. } else if (call.getHandoverToCall() != null && newState == CallState.DISCONNECTED) { Call handoverTo = call.getHandoverToCall(); Log.addEvent(handoverTo, LogUtils.Events.HANDOVER_COMPLETE, "from=%s, to=%s", call.getId(), handoverTo.getId()); Log.addEvent(call, LogUtils.Events.HANDOVER_COMPLETE, "from=%s, to=%s", Loading @@ -2230,7 +2229,7 @@ public class CallsManager extends Call.ListenerBase // Inform the "to" ConnectionService that handover to it has completed. handoverTo.sendCallEvent(android.telecom.Call.EVENT_HANDOVER_COMPLETE, null); answerCall(handoverTo, handoverTo.getVideoState()); call.markHandoverFinished(); call.markHandoverSuccess(); } // Only broadcast state change for calls that are being tracked. Loading
src/com/android/server/telecom/ui/IncomingCallNotifier.java +2 −3 Original line number Diff line number Diff line Loading @@ -23,7 +23,6 @@ import android.content.Context; import android.content.Intent; import android.os.Bundle; import android.telecom.Log; import android.telecom.PhoneAccount; import android.telecom.PhoneAccountHandle; import android.telecom.TelecomManager; import android.telecom.VideoProfile; Loading @@ -34,7 +33,6 @@ import android.text.style.ForegroundColorSpan; import android.util.ArraySet; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.telephony.CallerInfo; import com.android.server.telecom.Call; import com.android.server.telecom.CallState; import com.android.server.telecom.CallsManagerListenerBase; Loading Loading @@ -133,7 +131,8 @@ public class IncomingCallNotifier extends CallsManagerListenerBase { private void updateIncomingCall() { Optional<Call> incomingCallOp = mCalls.stream() .filter(call -> call.isSelfManaged() && call.isIncoming() && call.getState() == CallState.RINGING && !call.isHandoverInProgress()) call.getState() == CallState.RINGING && !call.isHandoverInProgress() && !call.isHandoverSuccessful()) .findFirst(); Call incomingCall = incomingCallOp.orElse(null); if (incomingCall != null && mCallsManagerProxy != null && Loading
tests/src/com/android/server/telecom/tests/IncomingCallNotifierTest.java +40 −3 Original line number Diff line number Diff line Loading @@ -16,11 +16,9 @@ package com.android.server.telecom.tests; import android.app.Notification; import android.app.NotificationManager; import android.content.Context; import android.content.pm.ApplicationInfo; import android.content.res.Resources; import android.os.Build; import android.telecom.VideoProfile; import android.test.suitebuilder.annotation.SmallTest; Loading @@ -29,7 +27,6 @@ import com.android.server.telecom.Call; import com.android.server.telecom.CallState; import com.android.server.telecom.ui.IncomingCallNotifier; import org.mockito.ArgumentCaptor; import org.mockito.Mock; import static org.mockito.Matchers.any; Loading Loading @@ -73,6 +70,8 @@ public class IncomingCallNotifierTest extends TelecomTestCase { when(mRingingCall.getState()).thenReturn(CallState.RINGING); when(mRingingCall.getVideoState()).thenReturn(VideoProfile.STATE_AUDIO_ONLY); when(mRingingCall.getTargetPhoneAccountLabel()).thenReturn("Foo"); when(mRingingCall.isHandoverInProgress()).thenReturn(false); when(mRingingCall.isHandoverSuccessful()).thenReturn(false); } /** Loading Loading @@ -128,4 +127,42 @@ public class IncomingCallNotifierTest extends TelecomTestCase { verify(mNotificationManager).cancel(eq(IncomingCallNotifier.NOTIFICATION_TAG), eq(IncomingCallNotifier.NOTIFICATION_INCOMING_CALL)); } /** * Ensure notification doesn't show during handover. */ @SmallTest public void testDontShowDuringHandover1() { when(mCallsManagerProxy.hasCallsForOtherPhoneAccount(any())).thenReturn(true); when(mCallsManagerProxy.getNumCallsForOtherPhoneAccount(any())).thenReturn(1); when(mCallsManagerProxy.getActiveCall()).thenReturn(mAudioCall); when(mRingingCall.isHandoverInProgress()).thenReturn(true); when(mRingingCall.isHandoverSuccessful()).thenReturn(false); mIncomingCallNotifier.onCallAdded(mAudioCall); mIncomingCallNotifier.onCallAdded(mRingingCall); // Incoming call is in the middle of a handover, don't expect to be notified. verify(mNotificationManager, never()).notify(eq(IncomingCallNotifier.NOTIFICATION_TAG), eq(IncomingCallNotifier.NOTIFICATION_INCOMING_CALL), any());; } /** * Ensure notification doesn't show during handover. */ @SmallTest public void testDontShowDuringHandover2() { when(mCallsManagerProxy.hasCallsForOtherPhoneAccount(any())).thenReturn(true); when(mCallsManagerProxy.getNumCallsForOtherPhoneAccount(any())).thenReturn(1); when(mCallsManagerProxy.getActiveCall()).thenReturn(mAudioCall); when(mRingingCall.isHandoverInProgress()).thenReturn(false); when(mRingingCall.isHandoverSuccessful()).thenReturn(true); mIncomingCallNotifier.onCallAdded(mAudioCall); mIncomingCallNotifier.onCallAdded(mRingingCall); // Incoming call is done a handover, don't expect to be notified. verify(mNotificationManager, never()).notify(eq(IncomingCallNotifier.NOTIFICATION_TAG), eq(IncomingCallNotifier.NOTIFICATION_INCOMING_CALL), any());; } }