Ensure IMS calls are disconnected when WPS call is forced over CS.

When a WPS call is placed on the CS domain, ensure that we hangup any
ongoing calls on the IMS domain first.

Test: Added unit test to verify ImsPhoneCallTracker is asked to disconnect
all ongoing calls when a WPS call is placed over CS.
Test: Added unit test to verify ImsPhoneCallTracker is not asked to
disconnect all ongoing calls when a WPS call is placed over IMS.
Test: Manually overrode carrier config to ensure WPS calls go over CS,
started on device IMS call to another number.  Then attempted to place a
WPS call.  Verified that the ongoing IMS call disconnects and the WPS
call is placed.
Fixes: 172695501

Original change: https://android-review.googlesource.com/c/platform/frameworks/opt/telephony/+/1492301
Merged-In: I60382869482a78612a11b4a1672f0ba84f6068ed
Change-Id: I60382869482a78612a11b4a1672f0ba84f6068ed
(cherry picked from commit 28f1079976dea1cbc13822ec669a27b32905e486)
diff --git a/src/java/com/android/internal/telephony/GsmCdmaPhone.java b/src/java/com/android/internal/telephony/GsmCdmaPhone.java
index f64211b..52ce7bd 100644
--- a/src/java/com/android/internal/telephony/GsmCdmaPhone.java
+++ b/src/java/com/android/internal/telephony/GsmCdmaPhone.java
@@ -90,6 +90,7 @@
 import com.android.internal.telephony.emergency.EmergencyNumberTracker;
 import com.android.internal.telephony.gsm.GsmMmiCode;
 import com.android.internal.telephony.gsm.SuppServiceNotification;
+import com.android.internal.telephony.imsphone.ImsPhoneCallTracker;
 import com.android.internal.telephony.imsphone.ImsPhoneMmiCode;
 import com.android.internal.telephony.metrics.VoiceCallSessionStats;
 import com.android.internal.telephony.test.SimulatedRadioControl;
@@ -1367,6 +1368,12 @@
         }
 
         Phone.checkWfcWifiOnlyModeBeforeDial(mImsPhone, mPhoneId, mContext);
+        if (imsPhone != null && !allowWpsOverIms && !useImsForCall && isWpsCall
+                && imsPhone.getCallTracker() instanceof ImsPhoneCallTracker) {
+            logi("WPS call placed over CS; disconnecting all IMS calls..");
+            ImsPhoneCallTracker tracker = (ImsPhoneCallTracker) imsPhone.getCallTracker();
+            tracker.hangupAllConnections();
+        }
 
         if ((useImsForCall && (!isMmiCode || isPotentialUssdCode))
                 || (isMmiCode && useImsForUt)
diff --git a/src/java/com/android/internal/telephony/imsphone/ImsPhoneCallTracker.java b/src/java/com/android/internal/telephony/imsphone/ImsPhoneCallTracker.java
index 15e2d28..ce05675 100755
--- a/src/java/com/android/internal/telephony/imsphone/ImsPhoneCallTracker.java
+++ b/src/java/com/android/internal/telephony/imsphone/ImsPhoneCallTracker.java
@@ -1025,6 +1025,20 @@
         sendImsServiceStateIntent(ImsManager.ACTION_IMS_SERVICE_DOWN);
     }
 
+    /**
+     * Requests modem to hang up all connections.
+     */
+    public void hangupAllConnections() {
+        getConnections().stream().forEach(c -> {
+            logi("Disconnecting callId = " + c.getTelecomCallId());
+            try {
+                c.hangup();
+            } catch (CallStateException e) {
+                loge("Failed to disconnet call...");
+            }
+        });
+    }
+
     private void sendImsServiceStateIntent(String intentAction) {
         Intent intent = new Intent(intentAction);
         intent.putExtra(ImsManager.EXTRA_PHONE_ID, mPhone.getPhoneId());
diff --git a/tests/telephonytests/src/com/android/internal/telephony/GsmCdmaPhoneTest.java b/tests/telephonytests/src/com/android/internal/telephony/GsmCdmaPhoneTest.java
index 7ad41c2..0dd9121 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/GsmCdmaPhoneTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/GsmCdmaPhoneTest.java
@@ -43,6 +43,7 @@
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
 
 import android.content.Intent;
 import android.content.SharedPreferences;
@@ -494,6 +495,42 @@
 
     @Test
     @SmallTest
+    public void testWpsDialOverCs() throws Exception {
+        try {
+            setupForWpsCallTest();
+
+            mContextFixture.getCarrierConfigBundle().putBoolean(
+                    CarrierConfigManager.KEY_SUPPORT_WPS_OVER_IMS_BOOL, false);
+
+            Connection connection = mPhoneUT.dial("*27216505551212",
+                    new PhoneInternalInterface.DialArgs.Builder().build());
+            verify(mCT).dialGsm("*27216505551212", null, null);
+            verify(mImsCT).hangupAllConnections();
+        } catch (CallStateException e) {
+            fail();
+        }
+    }
+
+    @Test
+    @SmallTest
+    public void testWpsDialOverIms() throws Exception {
+        try {
+            setupForWpsCallTest();
+
+            mContextFixture.getCarrierConfigBundle().putBoolean(
+                    CarrierConfigManager.KEY_SUPPORT_WPS_OVER_IMS_BOOL, true);
+
+            Connection connection = mPhoneUT.dial("*27216505551212",
+                    new PhoneInternalInterface.DialArgs.Builder().build());
+            verify(mCT).dialGsm("*27216505551212", null, null);
+            verify(mImsCT, never()).hangupAllConnections();
+        } catch (CallStateException e) {
+            fail();
+        }
+    }
+
+    @Test
+    @SmallTest
     public void testHandlePinMmi() {
         assertFalse(mPhoneUT.handlePinMmi("1234567890"));
     }
@@ -1386,4 +1423,15 @@
         verify(mMockCi).getRadioCapability(captor.capture());
         assertEquals(captor.getValue().what, Phone.EVENT_GET_RADIO_CAPABILITY);
     }
+
+    private void setupForWpsCallTest() throws Exception {
+        mSST.mSS = mServiceState;
+        doReturn(ServiceState.STATE_IN_SERVICE).when(mServiceState).getState();
+        when(mImsPhone.getCallTracker()).thenReturn(mImsCT);
+        mCT.mForegroundCall = mGsmCdmaCall;
+        mCT.mBackgroundCall = mGsmCdmaCall;
+        mCT.mRingingCall = mGsmCdmaCall;
+        doReturn(GsmCdmaCall.State.IDLE).when(mGsmCdmaCall).getState();
+        replaceInstance(Phone.class, "mImsPhone", mPhoneUT, mImsPhone);
+    }
 }