Switch stacks when the current stack has limited service

Per resource configuration, switch stacks
when current stack has limited service and there is
another stack with which normal service is available
in some countries.

Bug: 339568266
Test: atest EmergencyCallDomainSelectorTest
Change-Id: Ie14e79a262e4d0f80260ea28ab483641d8c08e5f
diff --git a/src/com/android/services/telephony/domainselection/EmergencyCallDomainSelector.java b/src/com/android/services/telephony/domainselection/EmergencyCallDomainSelector.java
index 3fb6ae8..099def8 100644
--- a/src/com/android/services/telephony/domainselection/EmergencyCallDomainSelector.java
+++ b/src/com/android/services/telephony/domainselection/EmergencyCallDomainSelector.java
@@ -333,6 +333,9 @@
         }
 
         if (result.getAccessNetwork() == UNKNOWN) {
+            if (maybeRedialOnTheOtherSlotInNormalService(mLastRegResult)) {
+                return;
+            }
             if ((mPreferredNetworkScanType == SCAN_TYPE_FULL_SERVICE_FOLLOWED_BY_LIMITED_SERVICE)
                       && (mScanType == DomainSelectionService.SCAN_TYPE_FULL_SERVICE)) {
                 mScanType = DomainSelectionService.SCAN_TYPE_LIMITED_SERVICE;
@@ -358,6 +361,13 @@
             return;
         }
 
+        if (result.getRegState() != REGISTRATION_STATE_HOME
+                && result.getRegState() != REGISTRATION_STATE_ROAMING) {
+            if (maybeRedialOnTheOtherSlotInNormalService(result)) {
+                return;
+            }
+        }
+
         mLastRegResult = result;
         removeMessages(MSG_NETWORK_SCAN_TIMEOUT);
         onWwanNetworkTypeSelected(getAccessNetworkType(result));
@@ -856,7 +866,7 @@
         boolean psInService = isPsInService();
 
         if (!csInService && !psInService) {
-            if (maybeRedialOnTheOtherSlotInNormalService()) {
+            if (maybeRedialOnTheOtherSlotInNormalService(mLastRegResult)) {
                 return;
             }
             mCsNetworkType = getSelectableCsNetworkType();
@@ -1647,14 +1657,28 @@
         return true;
     }
 
-    private boolean maybeRedialOnTheOtherSlotInNormalService() {
-        EmergencyRegistrationResult regResult =
-                mSelectionAttributes.getEmergencyRegistrationResult();
+    private String getCountryIso(String iso) {
+        if (TextUtils.isEmpty(iso)) {
+            TelephonyManager tm = mContext.getSystemService(TelephonyManager.class);
+            iso = tm.getNetworkCountryIso(getSlotId());
+            if (TextUtils.isEmpty(iso)) {
+                for (int i = 0; i < mModemCount; i++) {
+                    iso = tm.getNetworkCountryIso(i);
+                    if (!TextUtils.isEmpty(iso)) break;
+                }
+            }
+        }
+        return iso;
+    }
+
+    private boolean maybeRedialOnTheOtherSlotInNormalService(
+            EmergencyRegistrationResult regResult) {
         if (regResult == null) return false;
 
-        String iso = regResult.getCountryIso();
+        String iso = getCountryIso(regResult.getCountryIso());
         if (sPreferSlotWithNormalServiceList.contains(iso)
                 && mCrossSimRedialingController.isThereOtherSlotInService()) {
+            logi("maybeRedialOnTheOtherSlotInNormalService");
             terminateSelectionForCrossSimRedialing(false);
             return true;
         }
@@ -1678,6 +1702,8 @@
     }
 
     private void terminateSelection(int cause) {
+        removeMessages(MSG_NETWORK_SCAN_TIMEOUT);
+        removeMessages(MSG_MAX_CELLULAR_TIMEOUT);
         mTransportSelectorCallback.onSelectionTerminated(cause);
     }
 
diff --git a/tests/src/com/android/services/telephony/domainselection/EmergencyCallDomainSelectorTest.java b/tests/src/com/android/services/telephony/domainselection/EmergencyCallDomainSelectorTest.java
index 4690d6e..38c9677 100644
--- a/tests/src/com/android/services/telephony/domainselection/EmergencyCallDomainSelectorTest.java
+++ b/tests/src/com/android/services/telephony/domainselection/EmergencyCallDomainSelectorTest.java
@@ -1880,6 +1880,39 @@
     }
 
     @Test
+    public void testDualSimNormalServiceOnTheOtherSubscriptionAfterScan() throws Exception {
+        mResultConsumer = null;
+        createSelector(SLOT_0_SUB_ID);
+        unsolBarringInfoChanged(false);
+
+        doReturn(2).when(mTelephonyManager).getActiveModemCount();
+        doReturn(true).when(mCsrdCtrl).isThereOtherSlotInService();
+        doReturn(new String[] {"in"}).when(mResources).getStringArray(anyInt());
+
+        EmergencyRegistrationResult regResult = getEmergencyRegResult(UNKNOWN,
+                REGISTRATION_STATE_UNKNOWN,
+                0, false, false, 0, 0, "", "");
+        SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
+        mDomainSelector.selectDomain(attr, mTransportSelectorCallback);
+        processAllMessages();
+
+        bindImsServiceUnregistered();
+        processAllMessages();
+
+        verify(mWwanSelectorCallback, times(1)).onRequestEmergencyNetworkScan(
+                any(), anyInt(), eq(false), any(), any());
+        assertNotNull(mResultConsumer);
+
+        regResult = getEmergencyRegResult(EUTRAN, REGISTRATION_STATE_UNKNOWN,
+                0, false, false, 0, 0, "", "", "in");
+        mResultConsumer.accept(regResult);
+        processAllMessages();
+
+        verify(mTransportSelectorCallback, times(1))
+                .onSelectionTerminated(eq(DisconnectCause.EMERGENCY_TEMP_FAILURE));
+    }
+
+    @Test
     public void testEutranWithCsDomainOnly() throws Exception {
         setupForHandleScanResult();