Get the Phone to use for an emergency call of the emergency number address
a) If there are multiple Phones with the Subscriptions that support the
emergency number address, and one of them is the default voice Phone,
consider the default voice phone if 1.4 HAL is supported, or if it is
available for emergency call.
b) If there are multiple Phones with the Subscriptions that support the
emergency number address, and none of them is the default voice Phone,
use one of these Phones if 1.4 HAL is supported, or if it is available
for emergency call.
c) If there is no Phone that supports the emergency call for the address,
use the defined Priority list to select the Phone via
{@link #getFirstPhoneForEmergencyCall}.
Test: Treehugger
Bug: 112657134
Change-Id: I43787876ea999a005622deec6da7d6dece876f06
diff --git a/src/com/android/phone/PhoneInterfaceManager.java b/src/com/android/phone/PhoneInterfaceManager.java
index 66fdbe6..b16a75b 100755
--- a/src/com/android/phone/PhoneInterfaceManager.java
+++ b/src/com/android/phone/PhoneInterfaceManager.java
@@ -6062,77 +6062,6 @@
}
}
- private Map<Integer, List<EmergencyNumber>> getEmergencyNumberListInternal() {
- Map<Integer, List<EmergencyNumber>> emergencyNumberListInternal = new HashMap<>();
-
- for (Phone phone: PhoneFactory.getPhones()) {
- if (phone.getEmergencyNumberTracker() != null
- && phone.getEmergencyNumberTracker().getEmergencyNumberList() != null) {
- emergencyNumberListInternal.put(
- phone.getSubId(),
- phone.getEmergencyNumberTracker().getEmergencyNumberList());
- }
- }
- return emergencyNumberListInternal;
- }
-
- private List<EmergencyNumber> getEmergencyNumberListFromEccList(int subscriptionId) {
- SubscriptionManager sm = (SubscriptionManager) mApp.getSystemService(
- Context.TELEPHONY_SUBSCRIPTION_SERVICE);
- List<EmergencyNumber> emergencyNumberList = new ArrayList<>();
- int slotId = sm.getSlotIndex(subscriptionId);
-
- String ecclist = (slotId <= 0) ? "ril.ecclist" : ("ril.ecclist" + slotId);
- String emergencyNumbers = SystemProperties.get(ecclist, "");
- if (TextUtils.isEmpty(emergencyNumbers)) {
- // then read-only ecclist property since old RIL only uses this
- emergencyNumbers = SystemProperties.get("ro.ril.ecclist");
- }
- if (!TextUtils.isEmpty(emergencyNumbers)) {
- // searches through the comma-separated list for a match,
- // return true if one is found.
- for (String emergencyNum : emergencyNumbers.split(",")) {
- emergencyNumberList.add(new EmergencyNumber(emergencyNum, "", "",
- EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED, 0));
- }
- }
- emergencyNumbers = ((slotId < 0) ? "112,911,000,08,110,118,119,999" : "112,911");
- for (String emergencyNum : emergencyNumbers.split(",")) {
- emergencyNumberList.add(new EmergencyNumber(emergencyNum, "", "",
- EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED, 0));
- }
- EmergencyNumber.mergeSameNumbersInEmergencyNumberList(emergencyNumberList);
- return emergencyNumberList;
- }
-
- /**
- * Get Emergency number list based on EccList. This util is used for solving backward
- * compatibility if device does not support the 1.4 IRadioIndication HAL that reports
- * emergency number list.
- *
- * @return Map including the key as the active subscription ID (Note: if there is no active
- * subscription, the key is {@link SubscriptionManager#getDefaultSubscriptionId})
- * and the value as the list of {@link EmergencyNumber}.
- */
- private Map<Integer, List<EmergencyNumber>> getEmergencyNumberListFromEccList() {
- Map<Integer, List<EmergencyNumber>> results = new HashMap<>();
- SubscriptionManager sm = (SubscriptionManager) mApp.getSystemService(
- Context.TELEPHONY_SUBSCRIPTION_SERVICE);
- int[] activeSubscriptionIds = sm.getActiveSubscriptionIdList();
-
- if (activeSubscriptionIds.length == 0) {
- int defaultSubscriptionId = getDefaultSubscription();
- results.put(defaultSubscriptionId,
- getEmergencyNumberListFromEccList(defaultSubscriptionId));
- } else {
- for (int activeSubscriptionId : activeSubscriptionIds) {
- results.put(activeSubscriptionId,
- getEmergencyNumberListFromEccList(activeSubscriptionId));
- }
- }
- return results;
- }
-
@Override
public List<String> getCertsFromCarrierPrivilegeAccessRules(int subId) {
enforceReadPrivilegedPermission("getCertsFromCarrierPrivilegeAccessRules");
diff --git a/src/com/android/services/telephony/TelephonyConnectionService.java b/src/com/android/services/telephony/TelephonyConnectionService.java
index 8ae7b8a..00b24e9 100644
--- a/src/com/android/services/telephony/TelephonyConnectionService.java
+++ b/src/com/android/services/telephony/TelephonyConnectionService.java
@@ -52,6 +52,7 @@
import com.android.internal.telephony.Phone;
import com.android.internal.telephony.PhoneConstants;
import com.android.internal.telephony.PhoneFactory;
+import com.android.internal.telephony.RIL;
import com.android.internal.telephony.imsphone.ImsExternalCallTracker;
import com.android.internal.telephony.imsphone.ImsPhone;
import com.android.internal.telephony.imsphone.ImsPhoneConnection;
@@ -316,7 +317,8 @@
if (PhoneAccount.SCHEME_VOICEMAIL.equals(scheme)) {
// TODO: We don't check for SecurityException here (requires
// CALL_PRIVILEGED permission).
- final Phone phone = getPhoneForAccount(request.getAccountHandle(), false);
+ final Phone phone = getPhoneForAccount(request.getAccountHandle(), false,
+ handle.getSchemeSpecificPart());
if (phone == null) {
Log.d(this, "onCreateOutgoingConnection, phone is null");
return Connection.createFailedConnection(
@@ -354,7 +356,8 @@
"Unable to parse number"));
}
- final Phone phone = getPhoneForAccount(request.getAccountHandle(), false);
+ final Phone phone = getPhoneForAccount(request.getAccountHandle(), false,
+ handle.getSchemeSpecificPart());
if (phone != null && CDMA_ACTIVATION_CODE_REGEX_PATTERN.matcher(number).matches()) {
// Obtain the configuration for the outgoing phone's SIM. If the outgoing number
// matches the *228 regex pattern, fail the call. This number is used for OTASP, and
@@ -381,7 +384,8 @@
// Convert into emergency number if necessary
// This is required in some regions (e.g. Taiwan).
if (!PhoneNumberUtils.isLocalEmergencyNumber(this, number)) {
- final Phone phone = getPhoneForAccount(request.getAccountHandle(), false);
+ final Phone phone = getPhoneForAccount(request.getAccountHandle(), false,
+ handle.getSchemeSpecificPart());
// We only do the conversion if the phone is not in service. The un-converted
// emergency numbers will go to the correct destination when the phone is in-service,
// so they will only need the special emergency call setup when the phone is out of
@@ -459,7 +463,8 @@
}
// Get the right phone object from the account data passed in.
- final Phone phone = getPhoneForAccount(request.getAccountHandle(), isEmergencyNumber);
+ final Phone phone = getPhoneForAccount(request.getAccountHandle(), isEmergencyNumber,
+ handle.getSchemeSpecificPart());
Connection resultConnection = getTelephonyConnection(request, numberToDial,
isEmergencyNumber, handle, phone);
// If there was a failure, the resulting connection will not be a TelephonyConnection,
@@ -504,7 +509,7 @@
// Get the right phone object since the radio has been turned on
// successfully.
final Phone phone = getPhoneForAccount(request.getAccountHandle(),
- isEmergencyNumber);
+ isEmergencyNumber, handle.getSchemeSpecificPart());
// If the PhoneType of the Phone being used is different than the Default Phone, then we
// need create a new Connection using that PhoneType and replace it in Telecom.
if (phone.getPhoneType() != originalPhoneType) {
@@ -722,7 +727,8 @@
"Treat as an Emergency Call.");
isEmergency = true;
}
- Phone phone = getPhoneForAccount(accountHandle, isEmergency);
+ Phone phone = getPhoneForAccount(accountHandle, isEmergency,
+ request.getAddress().getSchemeSpecificPart());
if (phone == null) {
return Connection.createFailedConnection(
DisconnectCauseUtil.toTelecomDisconnectCause(
@@ -833,7 +839,8 @@
"Treat as an Emergency Call.");
isEmergency = true;
}
- Phone phone = getPhoneForAccount(accountHandle, isEmergency);
+ Phone phone = getPhoneForAccount(accountHandle, isEmergency,
+ request.getAddress().getSchemeSpecificPart());
if (phone == null) {
return Connection.createFailedConnection(
DisconnectCauseUtil.toTelecomDisconnectCause(
@@ -1223,7 +1230,8 @@
return false;
}
- private Phone getPhoneForAccount(PhoneAccountHandle accountHandle, boolean isEmergency) {
+ private Phone getPhoneForAccount(PhoneAccountHandle accountHandle, boolean isEmergency,
+ String emergencyNumberAddress) {
Phone chosenPhone = null;
int subId = PhoneUtils.getSubIdForPhoneAccountHandle(accountHandle);
if (subId != SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
@@ -1237,7 +1245,7 @@
.getServiceState().getState())) {
Log.d(this, "getPhoneForAccount: phone for phone acct handle %s is out of service "
+ "or invalid for emergency call.", accountHandle);
- chosenPhone = getFirstPhoneForEmergencyCall();
+ chosenPhone = getPhoneForEmergencyCall(emergencyNumberAddress);
Log.d(this, "getPhoneForAccount: using subId: " +
(chosenPhone == null ? "null" : chosenPhone.getSubId()));
}
@@ -1245,6 +1253,48 @@
}
/**
+ * Get the Phone to use for an emergency call of the given emergency number address:
+ * a) If there are multiple Phones with the Subscriptions that support the emergency number
+ * address, and one of them is the default voice Phone, consider the default voice phone
+ * if 1.4 HAL is supported, or if it is available for emergency call.
+ * b) If there are multiple Phones with the Subscriptions that support the emergency number
+ * address, and none of them is the default voice Phone, use one of these Phones if 1.4 HAL
+ * is supported, or if it is available for emergency call.
+ * c) If there is no Phone that supports the emergency call for the address, use the defined
+ * Priority list to select the Phone via {@link #getFirstPhoneForEmergencyCall}.
+ */
+ public Phone getPhoneForEmergencyCall(String emergencyNumberAddress) {
+ // Find the list of available Phones for the given emergency number address
+ List<Phone> potentialEmergencyPhones = new ArrayList<>();
+ int defaultVoicePhoneId = mSubscriptionManagerProxy.getDefaultVoicePhoneId();
+ for (Phone phone : mPhoneFactoryProxy.getPhones()) {
+ if (phone.getEmergencyNumberTracker() != null) {
+ if (phone.getEmergencyNumberTracker().isEmergencyNumber(
+ emergencyNumberAddress, true)) {
+ if (phone.getHalVersion().greaterOrEqual(RIL.RADIO_HAL_VERSION_1_4)
+ || isAvailableForEmergencyCalls(phone)) {
+ // a)
+ if (phone.getPhoneId() == defaultVoicePhoneId) {
+ Log.i(this, "getPhoneForEmergencyCall, Phone Id that supports"
+ + " emergency number: " + phone.getPhoneId());
+ return phone;
+ }
+ potentialEmergencyPhones.add(phone);
+ }
+ }
+ }
+ }
+ // b)
+ if (potentialEmergencyPhones.size() > 0) {
+ Log.i(this, "getPhoneForEmergencyCall, Phone Id that supports emergency number:"
+ + potentialEmergencyPhones.get(0).getPhoneId());
+ return potentialEmergencyPhones.get(0);
+ }
+ // c)
+ return getFirstPhoneForEmergencyCall();
+ }
+
+ /**
* Retrieves the most sensible Phone to use for an emergency call using the following Priority
* list (for multi-SIM devices):
* 1) The User's SIM preference for Voice calling