Add tests for cross sim redialing of emergency calls

Bug: 260611129
Test: atest CrossSimRedialingTestOnMockModem
Change-Id: If61404ece897af6792801dc0f853136aef1c9854
diff --git a/tests/tests/telephony/current/src/android/telephony/ims/cts/CrossSimRedialingTestOnMockModem.java b/tests/tests/telephony/current/src/android/telephony/ims/cts/CrossSimRedialingTestOnMockModem.java
index ffbad0c..db89b61 100644
--- a/tests/tests/telephony/current/src/android/telephony/ims/cts/CrossSimRedialingTestOnMockModem.java
+++ b/tests/tests/telephony/current/src/android/telephony/ims/cts/CrossSimRedialingTestOnMockModem.java
@@ -18,9 +18,11 @@
 
 import static android.telephony.AccessNetworkConstants.AccessNetworkType.EUTRAN;
 import static android.telephony.AccessNetworkConstants.AccessNetworkType.GERAN;
+import static android.telephony.AccessNetworkConstants.AccessNetworkType.UNKNOWN;
 import static android.telephony.AccessNetworkConstants.AccessNetworkType.UTRAN;
 import static android.telephony.BarringInfo.BARRING_SERVICE_TYPE_EMERGENCY;
 import static android.telephony.BarringInfo.BarringServiceInfo.BARRING_TYPE_UNCONDITIONAL;
+import static android.telephony.CarrierConfigManager.ImsEmergency.KEY_CROSS_STACK_REDIAL_TIMER_SEC_INT;
 import static android.telephony.CarrierConfigManager.ImsEmergency.KEY_EMERGENCY_DOMAIN_PREFERENCE_INT_ARRAY;
 import static android.telephony.CarrierConfigManager.ImsEmergency.KEY_EMERGENCY_DOMAIN_PREFERENCE_ROAMING_INT_ARRAY;
 import static android.telephony.CarrierConfigManager.ImsEmergency.KEY_EMERGENCY_NETWORK_SCAN_TYPE_INT;
@@ -29,10 +31,16 @@
 import static android.telephony.CarrierConfigManager.ImsEmergency.KEY_EMERGENCY_OVER_IMS_ROAMING_SUPPORTED_3GPP_NETWORK_TYPES_INT_ARRAY;
 import static android.telephony.CarrierConfigManager.ImsEmergency.KEY_EMERGENCY_OVER_IMS_SUPPORTED_3GPP_NETWORK_TYPES_INT_ARRAY;
 import static android.telephony.CarrierConfigManager.ImsEmergency.KEY_PREFER_IMS_EMERGENCY_WHEN_VOICE_CALLS_ON_CS_BOOL;
+import static android.telephony.CarrierConfigManager.ImsEmergency.KEY_QUICK_CROSS_STACK_REDIAL_TIMER_SEC_INT;
+import static android.telephony.CarrierConfigManager.ImsEmergency.KEY_START_QUICK_CROSS_STACK_REDIAL_TIMER_WHEN_REGISTERED_BOOL;
+import static android.telephony.CarrierConfigManager.ImsEmergency.REDIAL_TIMER_DISABLED;
 import static android.telephony.CarrierConfigManager.ImsEmergency.SCAN_TYPE_NO_PREFERENCE;
 import static android.telephony.NetworkRegistrationInfo.REGISTRATION_STATE_HOME;
+import static android.telephony.NetworkRegistrationInfo.REGISTRATION_STATE_UNKNOWN;
 import static android.telephony.mockmodem.IRadioVoiceImpl.LATCH_EMERGENCY_DIAL;
 import static android.telephony.mockmodem.IRadioVoiceImpl.LATCH_GET_LAST_CALL_FAIL_CAUSE;
+import static android.telephony.mockmodem.MockNetworkService.LATCH_CANCEL_EMERGENCY_SCAN;
+import static android.telephony.mockmodem.MockNetworkService.LATCH_TRIGGER_EMERGENCY_SCAN;
 import static android.telephony.mockmodem.MockSimService.MOCK_SIM_PROFILE_ID_TWN_CHT;
 
 import static junit.framework.Assert.assertNotNull;
@@ -107,6 +115,9 @@
     // the timeout to wait for request in milliseconds
     private static final int WAIT_REQUEST_TIMEOUT_MS = 3000;
 
+    // the cross sim redialing timer in seconds
+    private static final int CROSS_STACK_TIMEOUT_SEC = 3;
+
     private static MockModemManager sMockModemManager;
 
     private static boolean sSupportDomainSelection = false;;
@@ -305,6 +316,34 @@
         assertTrue(waitForVoiceLatchCountdown(sOtherSlot, LATCH_EMERGENCY_DIAL));
     }
 
+    @Test
+    public void testCrossStackTimer() throws Exception {
+        // Setup pre-condition
+        unsolBarringInfoChanged(sTestSlot, false, false);
+        unsolBarringInfoChanged(sOtherSlot, false, false);
+
+        PersistableBundle bundle = getDefaultPersistableBundle();
+        bundle.putInt(KEY_CROSS_STACK_REDIAL_TIMER_SEC_INT, CROSS_STACK_TIMEOUT_SEC);
+        overrideCarrierConfig(bundle);
+
+        MockEmergencyRegResult regResult = getEmergencyRegResult(UNKNOWN,
+                REGISTRATION_STATE_UNKNOWN, 0, false, false, 0, 0, "", "");
+        setEmergencyRegResult(sTestSlot, regResult);
+        setEmergencyRegResult(sOtherSlot, regResult);
+
+        bindImsServiceUnregistered();
+
+        placeOutgoingCall(TEST_EMERGENCY_NUMBER);
+
+        assertTrue(waitForNetworkLatchCountdown(sTestSlot, LATCH_TRIGGER_EMERGENCY_SCAN));
+        assertTrue(waitForNetworkLatchCountdown(sTestSlot, LATCH_CANCEL_EMERGENCY_SCAN));
+
+        assertTrue(waitForNetworkLatchCountdown(sOtherSlot,
+                  LATCH_TRIGGER_EMERGENCY_SCAN, WAIT_UPDATE_TIMEOUT_MS));
+
+        unsolEmergencyNetworkScanResult(sOtherSlot);
+    }
+
     private void placeOutgoingCall(String address) throws Exception {
         TelecomManager telecomManager = (TelecomManager) InstrumentationRegistry
                 .getInstrumentation().getContext().getSystemService(Context.TELECOM_SERVICE);
@@ -361,15 +400,20 @@
                 };
         boolean imsWhenVoiceOnCs = false;
         int scanType = SCAN_TYPE_NO_PREFERENCE;
+        int crossStackTimer = 120;
+        int quickCrossStackTimer = REDIAL_TIMER_DISABLED;
+        boolean quickTimerWhenInService = true;
 
         return getPersistableBundle(imsRats, csRats,
-                domainPreference, imsWhenVoiceOnCs, scanType);
+                domainPreference, imsWhenVoiceOnCs, scanType,
+                crossStackTimer, quickCrossStackTimer, quickTimerWhenInService);
     }
 
     private static PersistableBundle getPersistableBundle(
             @Nullable int[] imsRats, @Nullable int[] csRats,
             @Nullable int[] domainPreference,
-            boolean imsWhenVoiceOnCs, int scanType) {
+            boolean imsWhenVoiceOnCs, int scanType,
+            int crossStackTimer, int quickCrossStackTimer, boolean quickTimerWhenInService) {
 
         PersistableBundle bundle  = new PersistableBundle();
         if (imsRats != null) {
@@ -391,6 +435,12 @@
         bundle.putBoolean(KEY_PREFER_IMS_EMERGENCY_WHEN_VOICE_CALLS_ON_CS_BOOL, imsWhenVoiceOnCs);
         bundle.putInt(KEY_EMERGENCY_NETWORK_SCAN_TYPE_INT, scanType);
 
+        bundle.putInt(KEY_CROSS_STACK_REDIAL_TIMER_SEC_INT, crossStackTimer);
+        bundle.putInt(KEY_QUICK_CROSS_STACK_REDIAL_TIMER_SEC_INT, quickCrossStackTimer);
+        bundle.putBoolean(KEY_START_QUICK_CROSS_STACK_REDIAL_TIMER_WHEN_REGISTERED_BOOL,
+                quickTimerWhenInService);
+
+
         return bundle;
     }
 
@@ -438,6 +488,14 @@
         sMockModemManager.clearAllCalls(slotId, cause);
     }
 
+    private boolean waitForNetworkLatchCountdown(int slotId, int latchIndex) {
+        return waitForNetworkLatchCountdown(slotId, latchIndex, WAIT_LATCH_TIMEOUT_MS);
+    }
+
+    public boolean waitForNetworkLatchCountdown(int slotId, int latchIndex, int waitMs) {
+        return sMockModemManager.waitForNetworkLatchCountdown(slotId, latchIndex, waitMs);
+    }
+
     private void resetNetworkAllLatchCountdown(int slotId) {
         sMockModemManager.resetNetworkAllLatchCountdown(slotId);
     }
@@ -449,4 +507,12 @@
     private void setEmergencyRegResult(int slotId, MockEmergencyRegResult regResult) {
         sMockModemManager.setEmergencyRegResult(slotId, regResult);
     }
+
+    private void unsolEmergencyNetworkScanResult(int slotId) throws Exception {
+        MockEmergencyRegResult regResult = getEmergencyRegResult(UTRAN,
+                REGISTRATION_STATE_HOME, NetworkRegistrationInfo.DOMAIN_CS,
+                false, false, 0, 0, "", "");
+        sMockModemManager.unsolEmergencyNetworkScanResult(slotId, regResult);
+        waitForVoiceLatchCountdown(slotId, LATCH_EMERGENCY_DIAL);
+    }
 }
diff --git a/tests/tests/telephony/current/src/android/telephony/ims/cts/EmergencyCallDomainSelectionTestOnMockModem.java b/tests/tests/telephony/current/src/android/telephony/ims/cts/EmergencyCallDomainSelectionTestOnMockModem.java
index b581050..f3f1cae 100644
--- a/tests/tests/telephony/current/src/android/telephony/ims/cts/EmergencyCallDomainSelectionTestOnMockModem.java
+++ b/tests/tests/telephony/current/src/android/telephony/ims/cts/EmergencyCallDomainSelectionTestOnMockModem.java
@@ -23,6 +23,7 @@
 import static android.telephony.AccessNetworkConstants.AccessNetworkType.UTRAN;
 import static android.telephony.BarringInfo.BARRING_SERVICE_TYPE_EMERGENCY;
 import static android.telephony.BarringInfo.BarringServiceInfo.BARRING_TYPE_UNCONDITIONAL;
+import static android.telephony.CarrierConfigManager.ImsEmergency.KEY_CROSS_STACK_REDIAL_TIMER_SEC_INT;
 import static android.telephony.CarrierConfigManager.ImsEmergency.KEY_EMERGENCY_CALL_SETUP_TIMER_ON_CURRENT_NETWORK_SEC_INT;
 import static android.telephony.CarrierConfigManager.ImsEmergency.KEY_EMERGENCY_CDMA_PREFERRED_NUMBERS_STRING_ARRAY;
 import static android.telephony.CarrierConfigManager.ImsEmergency.KEY_EMERGENCY_DOMAIN_PREFERENCE_INT_ARRAY;
@@ -38,6 +39,9 @@
 import static android.telephony.CarrierConfigManager.ImsEmergency.KEY_EMERGENCY_SCAN_TIMER_SEC_INT;
 import static android.telephony.CarrierConfigManager.ImsEmergency.KEY_MAXIMUM_NUMBER_OF_EMERGENCY_TRIES_OVER_VOWIFI_INT;
 import static android.telephony.CarrierConfigManager.ImsEmergency.KEY_PREFER_IMS_EMERGENCY_WHEN_VOICE_CALLS_ON_CS_BOOL;
+import static android.telephony.CarrierConfigManager.ImsEmergency.KEY_QUICK_CROSS_STACK_REDIAL_TIMER_SEC_INT;
+import static android.telephony.CarrierConfigManager.ImsEmergency.KEY_START_QUICK_CROSS_STACK_REDIAL_TIMER_WHEN_REGISTERED_BOOL;
+import static android.telephony.CarrierConfigManager.ImsEmergency.REDIAL_TIMER_DISABLED;
 import static android.telephony.CarrierConfigManager.ImsEmergency.SCAN_TYPE_NO_PREFERENCE;
 import static android.telephony.CarrierConfigManager.ImsWfc.KEY_EMERGENCY_CALL_OVER_EMERGENCY_PDN_BOOL;
 import static android.telephony.NetworkRegistrationInfo.REGISTRATION_STATE_HOME;
@@ -1217,11 +1221,15 @@
         boolean requiresVoLteEnabled = false;
         boolean ltePreferredAfterNrFailed = false;
         String[] cdmaPreferredNumbers = new String[] {};
+        int crossStackTimer = REDIAL_TIMER_DISABLED;
+        int quickCrossStackTimer = REDIAL_TIMER_DISABLED;
+        boolean quickTimerWhenInService = true;
 
         return getPersistableBundle(imsRats, csRats, imsRoamRats, csRoamRats,
                 domainPreference, roamDomainPreference, imsWhenVoiceOnCs, maxRetriesOverWiFi,
                 useEmergencyPdn, cellularScanTimerSec, scanType, requiresImsRegistration,
-                requiresVoLteEnabled, ltePreferredAfterNrFailed, cdmaPreferredNumbers);
+                requiresVoLteEnabled, ltePreferredAfterNrFailed, cdmaPreferredNumbers,
+                crossStackTimer, quickCrossStackTimer, quickTimerWhenInService);
     }
 
     private static PersistableBundle getPersistableBundle(
@@ -1231,7 +1239,8 @@
             boolean imsWhenVoiceOnCs, int maxRetriesOverWiFi, boolean useEmergencyPdn,
             int cellularScanTimerSec, int scanType, boolean requiresImsRegistration,
             boolean requiresVoLteEnabled, boolean ltePreferredAfterNrFailed,
-            @Nullable String[] cdmaPreferredNumbers) {
+            @Nullable String[] cdmaPreferredNumbers,
+            int crossStackTimer, int quickCrossStackTimer, boolean quickTimerWhenInService) {
 
         PersistableBundle bundle  = new PersistableBundle();
         if (imsRats != null) {
@@ -1275,6 +1284,11 @@
                     cdmaPreferredNumbers);
         }
 
+        bundle.putInt(KEY_CROSS_STACK_REDIAL_TIMER_SEC_INT, crossStackTimer);
+        bundle.putInt(KEY_QUICK_CROSS_STACK_REDIAL_TIMER_SEC_INT, quickCrossStackTimer);
+        bundle.putBoolean(KEY_START_QUICK_CROSS_STACK_REDIAL_TIMER_WHEN_REGISTERED_BOOL,
+                quickTimerWhenInService);
+
         return bundle;
     }