Handle KEY_USE_ONLY_DIALED_SIM_ECC_LIST_BOOL

Usually, emergency number is identified based on all the active subscriptions,
no matter which subscription could be used.

If CarrierConfigManager.KEY_USE_ONLY_DIALED_SIM_ECC_LIST_BOOL is true
and the dialing number is not judged as an emergency number for the
given subscription on which dialing is placed, GsmCdmaPhone routes the dialing
as a normal call.

In that case, AP domain selection should do normal call domain
selection instead of emergency call domain selection.

Bug: 308863188
Test: atest TelephonyConnectionServiceTest
Change-Id: I991a103f1aa5d3bba7113c6e148a589fee13a862
diff --git a/src/com/android/services/telephony/TelephonyConnectionService.java b/src/com/android/services/telephony/TelephonyConnectionService.java
index b925c43..cad71c4 100644
--- a/src/com/android/services/telephony/TelephonyConnectionService.java
+++ b/src/com/android/services/telephony/TelephonyConnectionService.java
@@ -16,6 +16,7 @@
 
 package com.android.services.telephony;
 
+import static android.telephony.CarrierConfigManager.KEY_USE_ONLY_DIALED_SIM_ECC_LIST_BOOL;
 import static android.telephony.DomainSelectionService.SELECTOR_TYPE_CALLING;
 import static android.telephony.TelephonyManager.HAL_SERVICE_VOICE;
 import static com.android.internal.telephony.PhoneConstants.PHONE_TYPE_GSM;
@@ -35,6 +36,7 @@
 import android.net.Uri;
 import android.os.Bundle;
 import android.os.ParcelUuid;
+import android.os.PersistableBundle;
 import android.provider.DeviceConfig;
 import android.telecom.Conference;
 import android.telecom.Conferenceable;
@@ -2597,7 +2599,36 @@
         return false;
     }
 
+    private boolean isEmergencyNumberAllowedOnDialedSim(Phone phone, String number) {
+        CarrierConfigManager cfgManager = (CarrierConfigManager)
+                phone.getContext().getSystemService(Context.CARRIER_CONFIG_SERVICE);
+        if (cfgManager != null) {
+            PersistableBundle b = cfgManager.getConfigForSubId(phone.getSubId(),
+                    KEY_USE_ONLY_DIALED_SIM_ECC_LIST_BOOL);
+            if (b == null) {
+                b = CarrierConfigManager.getDefaultConfig();
+            }
+            // We need to check only when KEY_USE_ONLY_DIALED_SIM_ECC_LIST_BOOL is true.
+            if (b.getBoolean(KEY_USE_ONLY_DIALED_SIM_ECC_LIST_BOOL, false)
+                      && (phone.getEmergencyNumberTracker() != null)) {
+                if (!phone.getEmergencyNumberTracker().isEmergencyNumber(number)) {
+                    Log.i(this, "isEmergencyNumberAllowedOnDialedSim false");
+                    return false;
+                }
+            }
+        }
+        return true;
+    }
+
     private boolean isNormalRouting(Phone phone, String number) {
+        // Check isEmergencyNumberAllowedOnDialedSim(): some carriers do not want to handle
+        // dial requests for numbers which are in the emergency number list on another SIM,
+        // but not on their own. Such numbers shall be handled by normal call domain selector.
+        return (isNormalRoutingNumber(phone, number)
+                || !isEmergencyNumberAllowedOnDialedSim(phone, number));
+    }
+
+    private boolean isNormalRoutingNumber(Phone phone, String number) {
         if (phone.getEmergencyNumberTracker() != null) {
             // Note: There can potentially be multiple instances of EmergencyNumber found; if any of
             // them have normal routing, then use normal routing.
@@ -2619,7 +2650,7 @@
     public Phone getPhoneForNormalRoutedEmergencyCall(String number) {
         return Stream.of(mPhoneFactoryProxy.getPhones())
                 .filter(p -> p.shouldPreferInServiceSimForNormalRoutedEmergencyCall()
-                        && isNormalRouting(p, number)
+                        && isNormalRoutingNumber(p, number)
                         && isAvailableForEmergencyCalls(p,
                                 EmergencyNumber.EMERGENCY_CALL_ROUTING_NORMAL))
                 .findFirst().orElse(null);
diff --git a/tests/src/com/android/services/telephony/TelephonyConnectionServiceTest.java b/tests/src/com/android/services/telephony/TelephonyConnectionServiceTest.java
index d467def..8027969 100644
--- a/tests/src/com/android/services/telephony/TelephonyConnectionServiceTest.java
+++ b/tests/src/com/android/services/telephony/TelephonyConnectionServiceTest.java
@@ -2278,6 +2278,88 @@
     }
 
     @Test
+    public void testDomainSelectionDialedSimEmergencyNumberOnlyFalse() throws Exception {
+        setupForCallTest();
+
+        int selectedDomain = DOMAIN_PS;
+
+        EmergencyNumber emergencyNumber = new EmergencyNumber(TEST_EMERGENCY_NUMBER, "", "",
+                EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED,
+                Collections.emptyList(),
+                EmergencyNumber.EMERGENCY_NUMBER_SOURCE_DATABASE,
+                EmergencyNumber.EMERGENCY_CALL_ROUTING_EMERGENCY);
+
+        setupForDialForDomainSelection(mPhone0, selectedDomain, true);
+        doReturn(emergencyNumber).when(mEmergencyNumberTracker).getEmergencyNumber(anyString());
+        doReturn(Arrays.asList(emergencyNumber)).when(mEmergencyNumberTracker).getEmergencyNumbers(
+                anyString());
+        doReturn(false).when(mEmergencyNumberTracker).isEmergencyNumber(anyString());
+        getTestContext().getCarrierConfig(0 /*subId*/).putBoolean(
+                CarrierConfigManager.KEY_USE_ONLY_DIALED_SIM_ECC_LIST_BOOL, false);
+
+        mTestConnectionService.onCreateOutgoingConnection(PHONE_ACCOUNT_HANDLE_1,
+                createConnectionRequest(PHONE_ACCOUNT_HANDLE_1,
+                        TEST_EMERGENCY_NUMBER, TELECOM_CALL_ID1));
+
+        verify(mDomainSelectionResolver)
+                .getDomainSelectionConnection(eq(mPhone0), eq(SELECTOR_TYPE_CALLING), eq(true));
+        verify(mEmergencyStateTracker)
+                .startEmergencyCall(eq(mPhone0), eq(TELECOM_CALL_ID1), eq(false));
+        verify(mSatelliteSOSMessageRecommender).onEmergencyCallStarted(any(), eq(mPhone0));
+        verify(mEmergencyCallDomainSelectionConnection).createEmergencyConnection(any(), any());
+
+        ArgumentCaptor<DialArgs> argsCaptor = ArgumentCaptor.forClass(DialArgs.class);
+
+        verify(mPhone0).dial(anyString(), argsCaptor.capture(), any());
+        DialArgs dialArgs = argsCaptor.getValue();
+        assertNotNull("DialArgs param is null", dialArgs);
+        assertNotNull("intentExtras is null", dialArgs.intentExtras);
+        assertTrue(dialArgs.intentExtras.containsKey(PhoneConstants.EXTRA_DIAL_DOMAIN));
+        assertEquals(selectedDomain,
+                dialArgs.intentExtras.getInt(PhoneConstants.EXTRA_DIAL_DOMAIN, -1));
+    }
+
+    @Test
+    public void testDomainSelectionDialedSimEmergencyNumberOnlyTrue() throws Exception {
+        setupForCallTest();
+        int selectedDomain = DOMAIN_PS;
+
+        EmergencyNumber emergencyNumber = new EmergencyNumber(TEST_EMERGENCY_NUMBER, "", "",
+                EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED,
+                Collections.emptyList(),
+                EmergencyNumber.EMERGENCY_NUMBER_SOURCE_DATABASE,
+                EmergencyNumber.EMERGENCY_CALL_ROUTING_EMERGENCY);
+
+        setupForDialForDomainSelection(mPhone0, selectedDomain, false);
+        doReturn(true).when(mTelephonyManagerProxy).isCurrentEmergencyNumber(anyString());
+        doReturn(emergencyNumber).when(mEmergencyNumberTracker).getEmergencyNumber(anyString());
+        doReturn(Arrays.asList(emergencyNumber)).when(mEmergencyNumberTracker).getEmergencyNumbers(
+                anyString());
+        doReturn(false).when(mEmergencyNumberTracker).isEmergencyNumber(anyString());
+        getTestContext().getCarrierConfig(0 /*subId*/).putBoolean(
+                CarrierConfigManager.KEY_USE_ONLY_DIALED_SIM_ECC_LIST_BOOL, true);
+
+        mTestConnectionService.onCreateOutgoingConnection(PHONE_ACCOUNT_HANDLE_1,
+                createConnectionRequest(PHONE_ACCOUNT_HANDLE_1,
+                        TEST_EMERGENCY_NUMBER, TELECOM_CALL_ID1));
+
+        verify(mDomainSelectionResolver)
+                .getDomainSelectionConnection(eq(mPhone0), eq(SELECTOR_TYPE_CALLING), eq(false));
+        verify(mNormalCallDomainSelectionConnection).createNormalConnection(any(), any());
+        verify(mSatelliteSOSMessageRecommender).onEmergencyCallStarted(any(), eq(mPhone0));
+
+        ArgumentCaptor<DialArgs> argsCaptor = ArgumentCaptor.forClass(DialArgs.class);
+
+        verify(mPhone0).dial(anyString(), argsCaptor.capture(), any());
+        DialArgs dialArgs = argsCaptor.getValue();
+        assertNotNull("DialArgs param is null", dialArgs);
+        assertNotNull("intentExtras is null", dialArgs.intentExtras);
+        assertTrue(dialArgs.intentExtras.containsKey(PhoneConstants.EXTRA_DIAL_DOMAIN));
+        assertEquals(
+                selectedDomain, dialArgs.intentExtras.getInt(PhoneConstants.EXTRA_DIAL_DOMAIN, -1));
+    }
+
+    @Test
     public void testDomainSelectionNormalRoutingEmergencyNumber_exitingApm_InService()
             throws Exception {
         setupForCallTest();