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();