Add Emergency Number Test Mode

Add Emergency number in test mode in TelephonyShellCommand by supporting
add, print, remove, clear operations

Usage:
  adb shell cmd phone emergency-number-test-mode -p
    Print emergency number list
  adb shell cmd phone emergency-number-test-mode -r 1234
    Remove a test-mode emergency number 1234
  adb shell cmd phone emergency-number-test-mode -c
    Clear all the test-mode emergency numbers
  adb shell cmd phone emergency-number-test-mode -a 1234
    Add 1234 as a test mode emergency number

Test: Manual
Bug: 122840137
Change-Id: Id2a814f2532b489484fa28a3c7e78abbb57240aa
diff --git a/src/com/android/phone/PhoneInterfaceManager.java b/src/com/android/phone/PhoneInterfaceManager.java
index 3031d72..e58d60c 100755
--- a/src/com/android/phone/PhoneInterfaceManager.java
+++ b/src/com/android/phone/PhoneInterfaceManager.java
@@ -130,6 +130,7 @@
 import com.android.internal.telephony.SmsApplication.SmsApplicationData;
 import com.android.internal.telephony.SubscriptionController;
 import com.android.internal.telephony.TelephonyPermissions;
+import com.android.internal.telephony.emergency.EmergencyNumberTracker;
 import com.android.internal.telephony.euicc.EuiccConnector;
 import com.android.internal.telephony.uicc.IccIoResult;
 import com.android.internal.telephony.uicc.IccUtils;
@@ -153,9 +154,11 @@
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Locale;
 import java.util.Map;
+import java.util.Set;
 
 /**
  * Implementation of the ITelephony interface.
@@ -6061,6 +6064,52 @@
         }
     }
 
+    /**
+     * Update emergency number list for test mode.
+     */
+    @Override
+    public void updateEmergencyNumberListTestMode(int action, EmergencyNumber num) {
+        TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(),
+                "updateEmergencyNumberListTestMode");
+
+        final long identity = Binder.clearCallingIdentity();
+        try {
+            for (Phone phone: PhoneFactory.getPhones()) {
+                EmergencyNumberTracker tracker = phone.getEmergencyNumberTracker();
+                if (tracker != null) {
+                    tracker.executeEmergencyNumberTestModeCommand(action, num);
+                }
+            }
+        } finally {
+            Binder.restoreCallingIdentity(identity);
+        }
+    }
+
+    /**
+     * Get the full emergency number list for test mode.
+     */
+    @Override
+    public List<String> getEmergencyNumberListTestMode() {
+        TelephonyPermissions.enforceShellOnly(Binder.getCallingUid(),
+                "getEmergencyNumberListTestMode");
+
+        final long identity = Binder.clearCallingIdentity();
+        try {
+            Set<String> emergencyNumbers = new HashSet<>();
+            for (Phone phone: PhoneFactory.getPhones()) {
+                EmergencyNumberTracker tracker = phone.getEmergencyNumberTracker();
+                if (tracker != null) {
+                    for (EmergencyNumber num : tracker.getEmergencyNumberList()) {
+                        emergencyNumbers.add(num.getNumber());
+                    }
+                }
+            }
+            return new ArrayList<>(emergencyNumbers);
+        } finally {
+            Binder.restoreCallingIdentity(identity);
+        }
+    }
+
     @Override
     public List<String> getCertsFromCarrierPrivilegeAccessRules(int subId) {
         enforceReadPrivilegedPermission("getCertsFromCarrierPrivilegeAccessRules");
diff --git a/src/com/android/phone/TelephonyShellCommand.java b/src/com/android/phone/TelephonyShellCommand.java
index 9250118..956e0e2 100644
--- a/src/com/android/phone/TelephonyShellCommand.java
+++ b/src/com/android/phone/TelephonyShellCommand.java
@@ -22,11 +22,14 @@
 import android.os.ShellCommand;
 import android.os.UserHandle;
 import android.telephony.SubscriptionManager;
+import android.telephony.emergency.EmergencyNumber;
 import android.util.Log;
 
 import com.android.internal.telephony.ITelephony;
+import com.android.internal.telephony.emergency.EmergencyNumberTracker;
 
 import java.io.PrintWriter;
+import java.util.ArrayList;
 
 /**
  * Takes actions based on the adb commands given by "adb shell cmd phone ...". Be careful, no
@@ -44,6 +47,7 @@
     private static final String IMS_SUBCOMMAND = "ims";
     private static final String SMS_SUBCOMMAND = "sms";
     private static final String NUMBER_VERIFICATION_SUBCOMMAND = "numverify";
+    private static final String EMERGENCY_NUMBER_TEST_MODE = "emergency-number-test-mode";
 
     private static final String IMS_SET_CARRIER_SERVICE = "set-ims-service";
     private static final String IMS_GET_CARRIER_SERVICE = "get-ims-service";
@@ -79,6 +83,8 @@
             }
             case NUMBER_VERIFICATION_SUBCOMMAND:
                 return handleNumberVerificationCommand();
+            case EMERGENCY_NUMBER_TEST_MODE:
+                return handleEmergencyNumberTestModeCommand();
             default: {
                 return handleDefaultCommands(cmd);
             }
@@ -95,8 +101,11 @@
         pw.println("    IMS Commands.");
         pw.println("  sms");
         pw.println("    SMS Commands.");
+        pw.println("  emergency-number-test-mode");
+        pw.println("    Emergency Number Test Mode Commands.");
         onHelpIms();
         onHelpSms();
+        onHelpEmergencyNumber();
     }
 
     private void onHelpIms() {
@@ -147,6 +156,20 @@
         pw.println("    1 if the call would have been intercepted, 0 otherwise.");
     }
 
+    private void onHelpEmergencyNumber() {
+        PrintWriter pw = getOutPrintWriter();
+        pw.println("Emergency Number Test Mode Commands:");
+        pw.println("  emergency-number-test-mode ");
+        pw.println("    Add(-a), Clear(-c), Print (-p) or Remove(-r) the emergency number list in"
+                + " the test mode");
+        pw.println("      -a <emergency number address>: add an emergency number address for the"
+                + " test mode, only allows '0'-'9', '*', or '#'.");
+        pw.println("      -c: clear the emergency number list in the test mode.");
+        pw.println("      -r <emergency number address>: remove an existing emergency number"
+                + " address added by the test mode, only allows '0'-'9', '*', or '#'.");
+        pw.println("      -p: get the full emergency number list in the test mode.");
+    }
+
     private int handleImsCommand() {
         String arg = getNextArg();
         if (arg == null) {
@@ -172,6 +195,91 @@
         return -1;
     }
 
+    private int handleEmergencyNumberTestModeCommand() {
+        PrintWriter errPw = getErrPrintWriter();
+        String opt = getNextOption();
+        if (opt == null) {
+            onHelpEmergencyNumber();
+            return 0;
+        }
+
+        switch (opt) {
+            case "-a": {
+                String emergencyNumberCmd = getNextArgRequired();
+                if (emergencyNumberCmd == null
+                        || !EmergencyNumber.validateEmergencyNumberAddress(emergencyNumberCmd)) {
+                    errPw.println("An emergency number (only allow '0'-'9', '*', or '#') needs"
+                            + " to be specified after -a in the command ");
+                    return -1;
+                }
+                try {
+                    mInterface.updateEmergencyNumberListTestMode(
+                            EmergencyNumberTracker.ADD_EMERGENCY_NUMBER_TEST_MODE,
+                            new EmergencyNumber(emergencyNumberCmd, "", "",
+                                    EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED,
+                                    new ArrayList<String>(),
+                                    EmergencyNumber.EMERGENCY_NUMBER_SOURCE_TEST,
+                                    EmergencyNumber.EMERGENCY_CALL_ROUTING_UNKNOWN));
+                } catch (RemoteException ex) {
+                    Log.w(LOG_TAG, "emergency-number-test-mode -a " + emergencyNumberCmd
+                            + ", error " + ex.getMessage());
+                    errPw.println("Exception: " + ex.getMessage());
+                    return -1;
+                }
+                break;
+            }
+            case "-c": {
+                try {
+                    mInterface.updateEmergencyNumberListTestMode(
+                            EmergencyNumberTracker.RESET_EMERGENCY_NUMBER_TEST_MODE, null);
+                } catch (RemoteException ex) {
+                    Log.w(LOG_TAG, "emergency-number-test-mode -c " + "error " + ex.getMessage());
+                    errPw.println("Exception: " + ex.getMessage());
+                    return -1;
+                }
+                break;
+            }
+            case "-r": {
+                String emergencyNumberCmd = getNextArgRequired();
+                if (emergencyNumberCmd == null
+                        || !EmergencyNumber.validateEmergencyNumberAddress(emergencyNumberCmd)) {
+                    errPw.println("An emergency number (only allow '0'-'9', '*', or '#') needs"
+                            + " to be specified after -r in the command ");
+                    return -1;
+                }
+                try {
+                    mInterface.updateEmergencyNumberListTestMode(
+                            EmergencyNumberTracker.REMOVE_EMERGENCY_NUMBER_TEST_MODE,
+                            new EmergencyNumber(emergencyNumberCmd, "", "",
+                                    EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_UNSPECIFIED,
+                                    new ArrayList<String>(),
+                                    EmergencyNumber.EMERGENCY_NUMBER_SOURCE_TEST,
+                                    EmergencyNumber.EMERGENCY_CALL_ROUTING_UNKNOWN));
+                } catch (RemoteException ex) {
+                    Log.w(LOG_TAG, "emergency-number-test-mode -r " + emergencyNumberCmd
+                            + ", error " + ex.getMessage());
+                    errPw.println("Exception: " + ex.getMessage());
+                    return -1;
+                }
+                break;
+            }
+            case "-p": {
+                try {
+                    getOutPrintWriter().println(mInterface.getEmergencyNumberListTestMode());
+                } catch (RemoteException ex) {
+                    Log.w(LOG_TAG, "emergency-number-test-mode -p " + "error " + ex.getMessage());
+                    errPw.println("Exception: " + ex.getMessage());
+                    return -1;
+                }
+                break;
+            }
+            default:
+                onHelpEmergencyNumber();
+                break;
+        }
+        return 0;
+    }
+
     private int handleNumberVerificationCommand() {
         String arg = getNextArg();
         if (arg == null) {