Fix empty network type list in triggerEmergencyNetworkScan

If a carrier doesn't support CS emergency calls and dialing IMS call has
failed, then triggerEmergencyNetworkScan is invoked with empty network
type list.

Bug: 266030361
Test: atest EmergencyCallDomainSelectorTest
Change-Id: I844bf9387a20b44ed967f020b84bcb941182d723
diff --git a/src/com/android/services/telephony/domainselection/EmergencyCallDomainSelector.java b/src/com/android/services/telephony/domainselection/EmergencyCallDomainSelector.java
index 51becde..4aad5fe 100644
--- a/src/com/android/services/telephony/domainselection/EmergencyCallDomainSelector.java
+++ b/src/com/android/services/telephony/domainselection/EmergencyCallDomainSelector.java
@@ -632,7 +632,8 @@
      * @param csPreferred Indicates whether CS preferred scan is requested.
      * @return The list of preferred network types.
      */
-    private @RadioAccessNetworkType List<Integer> getNextPreferredNetworks(boolean csPreferred) {
+    @VisibleForTesting
+    public @RadioAccessNetworkType List<Integer> getNextPreferredNetworks(boolean csPreferred) {
         if (mRequiresVoLteEnabled && !isAdvancedCallingSettingEnabled()) {
             // Emergency call over IMS is not supported.
             logi("getNextPreferredNetworks VoLte setting is not enabled.");
@@ -652,7 +653,9 @@
             // Generate the list per the domain preference.
 
             if (psPriority == NOT_SUPPORTED && csPriority == NOT_SUPPORTED) {
-                // should not reach here.
+                // should not reach here. However, to avoid unexpected problems.
+                preferredNetworks = generatePreferredNetworks(getCsNetworkTypeConfiguration(),
+                        getImsNetworkTypeConfiguration());
             } else if (psPriority == NOT_SUPPORTED && csPriority > NOT_SUPPORTED) {
                 // CS networks only.
                 preferredNetworks = generatePreferredNetworks(getCsNetworkTypeConfiguration());
@@ -665,7 +668,7 @@
                         getCsNetworkTypeConfiguration());
             } else {
                 // CS preferred.
-                generatePreferredNetworks(getCsNetworkTypeConfiguration(),
+                preferredNetworks = generatePreferredNetworks(getCsNetworkTypeConfiguration(),
                         getImsNetworkTypeConfiguration());
             }
         } else if (csPreferred || mLastNetworkType == EUTRAN || mLastNetworkType == NGRAN) {
@@ -681,7 +684,7 @@
                         getImsNetworkTypeConfiguration());
             } else {
                 // CS not suppored.
-                generatePreferredNetworks(getImsNetworkTypeConfiguration());
+                preferredNetworks = generatePreferredNetworks(getImsNetworkTypeConfiguration());
             }
         } else {
             // CS tried, generate the list with PS preferred.
diff --git a/tests/src/com/android/services/telephony/domainselection/EmergencyCallDomainSelectorTest.java b/tests/src/com/android/services/telephony/domainselection/EmergencyCallDomainSelectorTest.java
index 27b3f0a..3f5b1af 100644
--- a/tests/src/com/android/services/telephony/domainselection/EmergencyCallDomainSelectorTest.java
+++ b/tests/src/com/android/services/telephony/domainselection/EmergencyCallDomainSelectorTest.java
@@ -52,6 +52,7 @@
 import static com.android.services.telephony.domainselection.EmergencyCallDomainSelector.MSG_NETWORK_SCAN_TIMEOUT;
 
 import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertFalse;
 import static junit.framework.Assert.assertTrue;
 
 import static org.mockito.ArgumentMatchers.any;
@@ -1128,6 +1129,280 @@
                 .onSelectionTerminated(eq(DisconnectCause.EMERGENCY_PERM_FAILURE));
     }
 
+    @Test
+    public void testCsThenPsPreference() throws Exception {
+        PersistableBundle bundle = getDefaultPersistableBundle();
+        int[] domainPreference = new int[] {
+                CarrierConfigManager.ImsEmergency.DOMAIN_CS,
+                CarrierConfigManager.ImsEmergency.DOMAIN_PS_3GPP,
+                };
+        bundle.putIntArray(KEY_EMERGENCY_DOMAIN_PREFERENCE_INT_ARRAY, domainPreference);
+
+        setupForScanListTest(bundle);
+
+        verifyCsPreferredScanList(mDomainSelector.getNextPreferredNetworks(false));
+    }
+
+    @Test
+    public void testPsThenCsPreference() throws Exception {
+        PersistableBundle bundle = getDefaultPersistableBundle();
+        int[] domainPreference = new int[] {
+                CarrierConfigManager.ImsEmergency.DOMAIN_PS_3GPP,
+                CarrierConfigManager.ImsEmergency.DOMAIN_CS,
+                };
+        bundle.putIntArray(KEY_EMERGENCY_DOMAIN_PREFERENCE_INT_ARRAY, domainPreference);
+
+        setupForScanListTest(bundle);
+
+        verifyPsPreferredScanList(mDomainSelector.getNextPreferredNetworks(false));
+    }
+
+    @Test
+    public void testPsOnlyPreference() throws Exception {
+        PersistableBundle bundle = getDefaultPersistableBundle();
+        int[] domainPreference = new int[] {
+                CarrierConfigManager.ImsEmergency.DOMAIN_PS_3GPP,
+                };
+        bundle.putIntArray(KEY_EMERGENCY_DOMAIN_PREFERENCE_INT_ARRAY, domainPreference);
+        bundle.putIntArray(KEY_EMERGENCY_OVER_CS_SUPPORTED_ACCESS_NETWORK_TYPES_INT_ARRAY,
+                new int[0]);
+
+        setupForScanListTest(bundle);
+
+        verifyPsOnlyScanList(mDomainSelector.getNextPreferredNetworks(false));
+    }
+
+    @Test
+    public void testCsOnlyPreference() throws Exception {
+        PersistableBundle bundle = getDefaultPersistableBundle();
+        int[] domainPreference = new int[] {
+                CarrierConfigManager.ImsEmergency.DOMAIN_CS,
+                };
+        bundle.putIntArray(KEY_EMERGENCY_DOMAIN_PREFERENCE_INT_ARRAY, domainPreference);
+        bundle.putIntArray(KEY_EMERGENCY_OVER_IMS_SUPPORTED_3GPP_NETWORK_TYPES_INT_ARRAY,
+                new int[0]);
+
+        setupForScanListTest(bundle);
+
+        verifyCsOnlyScanList(mDomainSelector.getNextPreferredNetworks(false));
+
+    }
+
+    @Test
+    public void testCsThenPsPreferenceCsPreferred() throws Exception {
+        PersistableBundle bundle = getDefaultPersistableBundle();
+        int[] domainPreference = new int[] {
+                CarrierConfigManager.ImsEmergency.DOMAIN_CS,
+                CarrierConfigManager.ImsEmergency.DOMAIN_PS_3GPP,
+                };
+        bundle.putIntArray(KEY_EMERGENCY_DOMAIN_PREFERENCE_INT_ARRAY, domainPreference);
+
+        setupForScanListTest(bundle);
+
+        verifyCsPreferredScanList(mDomainSelector.getNextPreferredNetworks(true));
+    }
+
+    @Test
+    public void testPsThenCsPreferenceCsPreferred() throws Exception {
+        PersistableBundle bundle = getDefaultPersistableBundle();
+        int[] domainPreference = new int[] {
+                CarrierConfigManager.ImsEmergency.DOMAIN_PS_3GPP,
+                CarrierConfigManager.ImsEmergency.DOMAIN_CS,
+                };
+        bundle.putIntArray(KEY_EMERGENCY_DOMAIN_PREFERENCE_INT_ARRAY, domainPreference);
+
+        setupForScanListTest(bundle);
+
+        verifyCsPreferredScanList(mDomainSelector.getNextPreferredNetworks(true));
+    }
+
+    @Test
+    public void testPsOnlyPreferenceCsPreferred() throws Exception {
+        PersistableBundle bundle = getDefaultPersistableBundle();
+        int[] domainPreference = new int[] {
+                CarrierConfigManager.ImsEmergency.DOMAIN_PS_3GPP,
+                CarrierConfigManager.ImsEmergency.DOMAIN_CS,
+                };
+        bundle.putIntArray(KEY_EMERGENCY_DOMAIN_PREFERENCE_INT_ARRAY, domainPreference);
+        bundle.putIntArray(KEY_EMERGENCY_OVER_CS_SUPPORTED_ACCESS_NETWORK_TYPES_INT_ARRAY,
+                new int[0]);
+
+        setupForScanListTest(bundle);
+
+        verifyPsOnlyScanList(mDomainSelector.getNextPreferredNetworks(true));
+    }
+
+    @Test
+    public void testCsOnlyPreferenceCsPreferred() throws Exception {
+        PersistableBundle bundle = getDefaultPersistableBundle();
+        int[] domainPreference = new int[] {
+                CarrierConfigManager.ImsEmergency.DOMAIN_CS,
+                };
+        bundle.putIntArray(KEY_EMERGENCY_DOMAIN_PREFERENCE_INT_ARRAY, domainPreference);
+        bundle.putIntArray(KEY_EMERGENCY_OVER_IMS_SUPPORTED_3GPP_NETWORK_TYPES_INT_ARRAY,
+                new int[0]);
+
+        setupForScanListTest(bundle);
+
+        verifyCsOnlyScanList(mDomainSelector.getNextPreferredNetworks(true));
+    }
+
+    @Test
+    public void testCsThenPsPreferencePsFail() throws Exception {
+        PersistableBundle bundle = getDefaultPersistableBundle();
+        int[] domainPreference = new int[] {
+                CarrierConfigManager.ImsEmergency.DOMAIN_CS,
+                CarrierConfigManager.ImsEmergency.DOMAIN_PS_3GPP,
+                };
+        bundle.putIntArray(KEY_EMERGENCY_DOMAIN_PREFERENCE_INT_ARRAY, domainPreference);
+
+        setupForScanListTest(bundle, true);
+
+        bindImsService();
+        processAllMessages();
+
+        verifyCsPreferredScanList(mDomainSelector.getNextPreferredNetworks(false));
+    }
+
+    @Test
+    public void testPsThenCsPreferencePsFail() throws Exception {
+        PersistableBundle bundle = getDefaultPersistableBundle();
+        int[] domainPreference = new int[] {
+                CarrierConfigManager.ImsEmergency.DOMAIN_PS_3GPP,
+                CarrierConfigManager.ImsEmergency.DOMAIN_CS,
+                };
+        bundle.putIntArray(KEY_EMERGENCY_DOMAIN_PREFERENCE_INT_ARRAY, domainPreference);
+
+        setupForScanListTest(bundle, true);
+
+        bindImsService();
+        processAllMessages();
+
+        verifyCsPreferredScanList(mDomainSelector.getNextPreferredNetworks(false));
+    }
+
+    @Test
+    public void testPsOnlyPreferencePsFail() throws Exception {
+        PersistableBundle bundle = getDefaultPersistableBundle();
+        int[] domainPreference = new int[] {
+                CarrierConfigManager.ImsEmergency.DOMAIN_PS_3GPP,
+                };
+        bundle.putIntArray(KEY_EMERGENCY_DOMAIN_PREFERENCE_INT_ARRAY, domainPreference);
+        bundle.putIntArray(KEY_EMERGENCY_OVER_CS_SUPPORTED_ACCESS_NETWORK_TYPES_INT_ARRAY,
+                new int[0]);
+
+        setupForScanListTest(bundle, true);
+
+        bindImsService();
+        processAllMessages();
+
+        verifyPsOnlyScanList(mDomainSelector.getNextPreferredNetworks(false));
+    }
+
+    @Test
+    public void testCsThenPsPreferencePsFailCsPreferred() throws Exception {
+        PersistableBundle bundle = getDefaultPersistableBundle();
+        int[] domainPreference = new int[] {
+                CarrierConfigManager.ImsEmergency.DOMAIN_CS,
+                CarrierConfigManager.ImsEmergency.DOMAIN_PS_3GPP,
+                };
+        bundle.putIntArray(KEY_EMERGENCY_DOMAIN_PREFERENCE_INT_ARRAY, domainPreference);
+
+        setupForScanListTest(bundle, true);
+
+        bindImsService();
+        processAllMessages();
+
+        verifyCsPreferredScanList(mDomainSelector.getNextPreferredNetworks(true));
+    }
+
+    @Test
+    public void testPsThenCsPreferencePsFailCsPreferred() throws Exception {
+        PersistableBundle bundle = getDefaultPersistableBundle();
+        int[] domainPreference = new int[] {
+                CarrierConfigManager.ImsEmergency.DOMAIN_PS_3GPP,
+                CarrierConfigManager.ImsEmergency.DOMAIN_CS,
+                };
+        bundle.putIntArray(KEY_EMERGENCY_DOMAIN_PREFERENCE_INT_ARRAY, domainPreference);
+
+        setupForScanListTest(bundle, true);
+
+        bindImsService();
+        processAllMessages();
+
+        verifyCsPreferredScanList(mDomainSelector.getNextPreferredNetworks(true));
+    }
+
+    @Test
+    public void testPsOnlyPreferencePsFailCsPreferred() throws Exception {
+        PersistableBundle bundle = getDefaultPersistableBundle();
+        int[] domainPreference = new int[] {
+                CarrierConfigManager.ImsEmergency.DOMAIN_PS_3GPP,
+                CarrierConfigManager.ImsEmergency.DOMAIN_CS,
+                };
+        bundle.putIntArray(KEY_EMERGENCY_DOMAIN_PREFERENCE_INT_ARRAY, domainPreference);
+        bundle.putIntArray(KEY_EMERGENCY_OVER_CS_SUPPORTED_ACCESS_NETWORK_TYPES_INT_ARRAY,
+                new int[0]);
+
+        setupForScanListTest(bundle, true);
+
+        bindImsService();
+        processAllMessages();
+
+        verifyPsOnlyScanList(mDomainSelector.getNextPreferredNetworks(true));
+    }
+
+    private void setupForScanListTest(PersistableBundle bundle) throws Exception {
+        setupForScanListTest(bundle, false);
+    }
+
+    private void setupForScanListTest(PersistableBundle bundle, boolean psFailed) throws Exception {
+        when(mCarrierConfigManager.getConfigForSubId(anyInt())).thenReturn(bundle);
+
+        createSelector(SLOT_0_SUB_ID);
+        unsolBarringInfoChanged(false);
+        EmergencyRegResult regResult = getEmergencyRegResult(EUTRAN, REGISTRATION_STATE_UNKNOWN,
+                0, false, false, 0, 0, "", "");
+        if (psFailed) {
+            regResult = getEmergencyRegResult(EUTRAN, REGISTRATION_STATE_HOME,
+                    NetworkRegistrationInfo.DOMAIN_PS, true, true, 0, 0, "", "");
+        }
+
+        SelectionAttributes attr = getSelectionAttributes(SLOT_0, SLOT_0_SUB_ID, regResult);
+        mDomainSelector.selectDomain(attr, mTransportSelectorCallback);
+        processAllMessages();
+    }
+
+    private void verifyCsPreferredScanList(List<Integer> networks) {
+        assertFalse(networks.isEmpty());
+        assertTrue(networks.contains(EUTRAN));
+        assertTrue(networks.contains(UTRAN));
+        assertTrue(networks.contains(GERAN));
+        assertTrue(networks.indexOf(UTRAN) < networks.indexOf(EUTRAN));
+    }
+
+    private void verifyPsPreferredScanList(List<Integer> networks) {
+        assertFalse(networks.isEmpty());
+        assertTrue(networks.contains(EUTRAN));
+        assertTrue(networks.contains(UTRAN));
+        assertTrue(networks.contains(GERAN));
+        assertTrue(networks.indexOf(EUTRAN) < networks.indexOf(UTRAN));
+    }
+
+    private void verifyPsOnlyScanList(List<Integer> networks) {
+        assertFalse(networks.isEmpty());
+        assertTrue(networks.contains(EUTRAN));
+        assertFalse(networks.contains(UTRAN));
+        assertFalse(networks.contains(GERAN));
+    }
+
+    private void verifyCsOnlyScanList(List<Integer> networks) {
+        assertFalse(networks.isEmpty());
+        assertFalse(networks.contains(EUTRAN));
+        assertTrue(networks.contains(UTRAN));
+        assertTrue(networks.contains(GERAN));
+    }
+
     private void createSelector(int subId) throws Exception {
         mDomainSelector = new EmergencyCallDomainSelector(
                 mContext, SLOT_0, subId, mHandlerThread.getLooper(),