Remove carrier specific emergency number prefixes.

Some carriers support dialing emergency numbers with prefix(es) to
apply specific features, e.g. hide the caller phone number. Numbers
with prefixes should be treated as emergency numbers in dialer and
emergency dialer. However, these numbers should not be suggested to
users in the shortcut list of Faster Emergency Launcher.

Workaround: remove prefixes from emergency number list returned from
getEmergencyNumberList().

Bug: 137225076
Test: Manually test: Insert AT&T SIM card in US and launch Faster
Emergency Launcher from power menu.

Change-Id: I38e9d79a73c347f9d52ce0edba0537577203def0
diff --git a/src/com/android/phone/ShortcutViewUtils.java b/src/com/android/phone/ShortcutViewUtils.java
index 8e5ab42..29e24ed 100644
--- a/src/com/android/phone/ShortcutViewUtils.java
+++ b/src/com/android/phone/ShortcutViewUtils.java
@@ -33,6 +33,9 @@
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 
+import com.android.internal.telephony.Phone;
+import com.android.internal.util.ArrayUtils;
+
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
@@ -293,12 +296,69 @@
         }
 
         if (promotedLists != null) {
-            emergencyNumberList = promotedLists.get(subId);
+            emergencyNumberList = removeCarrierSpecificPrefixes(handle, promotedLists.get(subId));
         }
 
         return new PhoneInfo(handle, canPlaceEmergencyCall, subId, countryIso, emergencyNumberList);
     }
 
+    @Nullable
+    private static String[] getCarrierSpecificPrefixes(@NonNull PhoneAccountHandle handle) {
+        Phone phone = PhoneUtils.getPhoneForPhoneAccountHandle(handle);
+        CarrierConfigManager configMgr = phone.getContext().getSystemService(
+                CarrierConfigManager.class);
+        if (configMgr == null) {
+            return null;
+        }
+        PersistableBundle b = configMgr.getConfigForSubId(phone.getSubId());
+        return b == null ? null : b.getStringArray(
+                CarrierConfigManager.KEY_EMERGENCY_NUMBER_PREFIX_STRING_ARRAY);
+    }
+
+    // Removes carrier specific emergency number prefixes (if there is any) from every emergency
+    // number and create a new list without duplications. Returns the original list if there is no
+    // prefixes.
+    @NonNull
+    private static List<EmergencyNumber> removeCarrierSpecificPrefixes(
+            @NonNull PhoneAccountHandle handle,
+            @NonNull List<EmergencyNumber> emergencyNumberList) {
+        String[] prefixes = getCarrierSpecificPrefixes(handle);
+        if (ArrayUtils.isEmpty(prefixes)) {
+            return emergencyNumberList;
+        }
+
+        List<EmergencyNumber> newList = new ArrayList<>(emergencyNumberList.size());
+        for (EmergencyNumber emergencyNumber : emergencyNumberList) {
+            // If no prefix was removed from emergencyNumber, add it to the newList directly.
+            EmergencyNumber newNumber = emergencyNumber;
+            String number = emergencyNumber.getNumber();
+            for (String prefix : prefixes) {
+                // If emergencyNumber starts with this prefix, remove this prefix to retrieve the
+                // actual emergency number.
+                // However, if emergencyNumber is exactly the same with this prefix, it could be
+                // either a real emergency number, or composed with another prefix. It shouldn't be
+                // processed with this prefix whatever.
+                if (!TextUtils.isEmpty(prefix) && number.startsWith(prefix)
+                        && !number.equals(prefix)) {
+                    newNumber = new EmergencyNumber(
+                            number.substring(prefix.length()),
+                            emergencyNumber.getCountryIso(),
+                            emergencyNumber.getMnc(),
+                            emergencyNumber.getEmergencyServiceCategoryBitmask(),
+                            emergencyNumber.getEmergencyUrns(),
+                            emergencyNumber.getEmergencyNumberSourceBitmask(),
+                            emergencyNumber.getEmergencyCallRouting());
+                    // There should not be more than one prefix attached to a number.
+                    break;
+                }
+            }
+            if (!newList.contains(newNumber)) {
+                newList.add(newNumber);
+            }
+        }
+        return newList;
+    }
+
     @NonNull
     private static Map<Integer, List<EmergencyNumber>> getPromotedEmergencyNumberLists(
             @NonNull TelephonyManager telephonyManager) {