Merge "Fix issue where incoming call shows up while handing over call."
diff --git a/src/com/android/server/telecom/Call.java b/src/com/android/server/telecom/Call.java
index 6e4329d..d32468b 100644
--- a/src/com/android/server/telecom/Call.java
+++ b/src/com/android/server/telecom/Call.java
@@ -453,18 +453,25 @@
     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.
      *
      * @param context The context.
@@ -1078,20 +1085,32 @@
     }
 
     /**
-     * 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 markHandoverFinished() {
+    public void markHandoverFailed() {
+        markHandoverResult(false /* isComplete */);
+    }
+
+    /**
+     * Marks a handover as being successful.
+     */
+    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() {
@@ -1114,6 +1133,10 @@
         mHandoverFromCall = call;
     }
 
+    public boolean isHandoverSuccessful() {
+        return mIsHandoverSuccessful;
+    }
+
     private void configureIsWorkCall() {
         PhoneAccountRegistrar phoneAccountRegistrar = mCallsManager.getPhoneAccountRegistrar();
         boolean isWorkCall = false;
diff --git a/src/com/android/server/telecom/CallsManager.java b/src/com/android/server/telecom/CallsManager.java
index 5ad8c72..7416c26 100644
--- a/src/com/android/server/telecom/CallsManager.java
+++ b/src/com/android/server/telecom/CallsManager.java
@@ -1721,7 +1721,7 @@
      * 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();
@@ -2190,9 +2190,9 @@
                             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.",
@@ -2211,13 +2211,12 @@
                         // 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",
@@ -2230,7 +2229,7 @@
                 // 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.
diff --git a/src/com/android/server/telecom/ui/IncomingCallNotifier.java b/src/com/android/server/telecom/ui/IncomingCallNotifier.java
index ea3105d..0d281a5 100644
--- a/src/com/android/server/telecom/ui/IncomingCallNotifier.java
+++ b/src/com/android/server/telecom/ui/IncomingCallNotifier.java
@@ -23,7 +23,6 @@
 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;
@@ -34,7 +33,6 @@
 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;
@@ -133,7 +131,8 @@
     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 &&
diff --git a/tests/src/com/android/server/telecom/tests/IncomingCallNotifierTest.java b/tests/src/com/android/server/telecom/tests/IncomingCallNotifierTest.java
index 6f2d008..b320985 100644
--- a/tests/src/com/android/server/telecom/tests/IncomingCallNotifierTest.java
+++ b/tests/src/com/android/server/telecom/tests/IncomingCallNotifierTest.java
@@ -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;
@@ -29,7 +27,6 @@
 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;
@@ -73,6 +70,8 @@
         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);
     }
 
     /**
@@ -128,4 +127,42 @@
         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());;
+    }
 }