Add ability for CTS to set itself as carrier service package

This change introduces a Carrier Service Package override, requiring
MODIFY_PHONE_STATE, ensuring that CTS can export a CarrierService, and
set itself as the carrier service.

The requirement for the application to also be carrier-privileged still
stands, but omits the SIM-certificate-match requirement, instead
allowing carrierConfig based certificates + carrier service package
override as a sufficient gate (which critically need to both be doable
with the CTS Shell permission identity)

Bug: 266904760
Test: Manually tested with a demo CTS build, will be used for Core
      Networking CTS tests
Change-Id: I09f3107b860618d207a016964515eb1440e7beba
Merged-In: I09f3107b860618d207a016964515eb1440e7beba
(cherry picked from commit 810b869a628a290e6c4d794fb63daa5268ef0650)
diff --git a/src/com/android/phone/TelephonyShellCommand.java b/src/com/android/phone/TelephonyShellCommand.java
index 1858fe2..14eba74 100644
--- a/src/com/android/phone/TelephonyShellCommand.java
+++ b/src/com/android/phone/TelephonyShellCommand.java
@@ -100,6 +100,10 @@
     private static final String DISABLE = "disable";
     private static final String QUERY = "query";
     private static final String CARRIER_RESTRICTION_STATUS_TEST = "carrier_restriction_status_test";
+    private static final String SET_CARRIER_SERVICE_PACKAGE_OVERRIDE =
+            "set-carrier-service-package-override";
+    private static final String CLEAR_CARRIER_SERVICE_PACKAGE_OVERRIDE =
+            "clear-carrier-service-package-override";
     private final String QUOTES = "\"";
 
     private static final String CALL_COMPOSER_TEST_MODE = "test-mode";
@@ -352,6 +356,10 @@
                 return handleRadioCommand();
             case CARRIER_RESTRICTION_STATUS_TEST:
                 return handleCarrierRestrictionStatusCommand();
+            case SET_CARRIER_SERVICE_PACKAGE_OVERRIDE:
+                return setCarrierServicePackageOverride();
+            case CLEAR_CARRIER_SERVICE_PACKAGE_OVERRIDE:
+                return clearCarrierServicePackageOverride();
             default: {
                 return handleDefaultCommands(cmd);
             }
@@ -3103,6 +3111,96 @@
         return result;
     }
 
+    // set-carrier-service-package-override
+    private int setCarrierServicePackageOverride() {
+        PrintWriter errPw = getErrPrintWriter();
+        int subId = SubscriptionManager.getDefaultSubscriptionId();
+
+        String opt;
+        while ((opt = getNextOption()) != null) {
+            switch (opt) {
+                case "-s":
+                    try {
+                        subId = Integer.parseInt(getNextArgRequired());
+                    } catch (NumberFormatException e) {
+                        errPw.println(
+                                "set-carrier-service-package-override requires an integer as a"
+                                        + " subscription ID.");
+                        return -1;
+                    }
+                    break;
+            }
+        }
+
+        String packageName = getNextArg();
+        if (packageName == null) {
+            errPw.println("set-carrier-service-package-override requires a override package name.");
+            return -1;
+        }
+
+        try {
+            mInterface.setCarrierServicePackageOverride(
+                    subId, packageName, mContext.getOpPackageName());
+
+            if (VDBG) {
+                Log.v(
+                        LOG_TAG,
+                        "set-carrier-service-package-override -s " + subId + " " + packageName);
+            }
+        } catch (RemoteException | IllegalArgumentException | IllegalStateException e) {
+            Log.w(
+                    LOG_TAG,
+                    "set-carrier-service-package-override -s "
+                            + subId
+                            + " "
+                            + packageName
+                            + ", error"
+                            + e.getMessage());
+            errPw.println("Exception: " + e.getMessage());
+            return -1;
+        }
+        return 0;
+    }
+
+    // clear-carrier-service-package-override
+    private int clearCarrierServicePackageOverride() {
+        PrintWriter errPw = getErrPrintWriter();
+        int subId = getDefaultSlot();
+
+        String opt;
+        while ((opt = getNextOption()) != null) {
+            switch (opt) {
+                case "-s":
+                    try {
+                        subId = Integer.parseInt(getNextArgRequired());
+                    } catch (NumberFormatException e) {
+                        errPw.println(
+                                "clear-carrier-service-package-override requires an integer as a"
+                                        + " subscription ID.");
+                        return -1;
+                    }
+                    break;
+            }
+        }
+
+        try {
+            mInterface.setCarrierServicePackageOverride(subId, null, mContext.getOpPackageName());
+
+            if (VDBG) {
+                Log.v(LOG_TAG, "clear-carrier-service-package-override -s " + subId);
+            }
+        } catch (RemoteException | IllegalArgumentException | IllegalStateException e) {
+            Log.w(
+                    LOG_TAG,
+                    "clear-carrier-service-package-override -s "
+                            + subId
+                            + ", error"
+                            + e.getMessage());
+            errPw.println("Exception: " + e.getMessage());
+            return -1;
+        }
+        return 0;
+    }
 
     /**
      * Building the string that can be used to build the JsonObject which supports to stub the data