Support /system_ext partition

This commit is mainly from I7a6a30bf8e8db9f2738594d187bb9148f138b8da, so
test cases and features are mostly same.

We change product_services partition name to "system_ext" because this
partition's purpose changes.

 - installing a RRO package for framework from /system_ext/overlay
 - installing apps from /system_ext/app
 - installing priv-apps from /system_ext/priv-app
 - installing permissions from
   /system_ext/etc/[default-permissions|permissions|sysconfig]

Bug: 134359158
Test: `mma` under frameworks/base/tests/[libs|privapp]-permissions
      adb sync && adb reboot
      adb shell cmd package list libraries
        => confirmed com.android.test.libs.system_ext library
      adb shell cmd package dump \
        com.android.framework.permission.privapp.tests.system_ext
        => confirmed that the package is a priv-app

Change-Id: Ibbccbba64156a7bc464ffb3785fb8fe69ebb973c
diff --git a/core/java/android/content/pm/ApplicationInfo.java b/core/java/android/content/pm/ApplicationInfo.java
index 9bc5f80..d6b70e0 100644
--- a/core/java/android/content/pm/ApplicationInfo.java
+++ b/core/java/android/content/pm/ApplicationInfo.java
@@ -614,10 +614,10 @@
 
     /**
      * Value for {@link #privateFlags}: whether this app is pre-installed on the
-     * google partition of the system image.
+     * system_ext partition of the system image.
      * @hide
      */
-    public static final int PRIVATE_FLAG_PRODUCT_SERVICES = 1 << 21;
+    public static final int PRIVATE_FLAG_SYSTEM_EXT = 1 << 21;
 
     /**
      * Indicates whether this package requires access to non-SDK APIs.
@@ -713,7 +713,7 @@
             PRIVATE_FLAG_USE_EMBEDDED_DEX,
             PRIVATE_FLAG_PRIVILEGED,
             PRIVATE_FLAG_PRODUCT,
-            PRIVATE_FLAG_PRODUCT_SERVICES,
+            PRIVATE_FLAG_SYSTEM_EXT,
             PRIVATE_FLAG_PROFILEABLE_BY_SHELL,
             PRIVATE_FLAG_REQUIRED_FOR_SYSTEM_USER,
             PRIVATE_FLAG_SIGNED_WITH_PLATFORM_KEY,
@@ -2047,8 +2047,8 @@
     }
 
     /** @hide */
-    public boolean isProductServices() {
-        return (privateFlags & ApplicationInfo.PRIVATE_FLAG_PRODUCT_SERVICES) != 0;
+    public boolean isSystemExt() {
+        return (privateFlags & ApplicationInfo.PRIVATE_FLAG_SYSTEM_EXT) != 0;
     }
 
     /** @hide */
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index a74c34f..42f5e0f 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -6897,8 +6897,8 @@
         }
 
         /** @hide */
-        public boolean isProductServices() {
-            return applicationInfo.isProductServices();
+        public boolean isSystemExt() {
+            return applicationInfo.isSystemExt();
         }
 
         /** @hide */
diff --git a/core/java/android/os/Build.java b/core/java/android/os/Build.java
index 9f4118e..b3125d8 100755
--- a/core/java/android/os/Build.java
+++ b/core/java/android/os/Build.java
@@ -1191,7 +1191,7 @@
         ArrayList<Partition> partitions = new ArrayList();
 
         String[] names = new String[] {
-            "bootimage", "odm", "product", "product_services", Partition.PARTITION_NAME_SYSTEM,
+            "bootimage", "odm", "product", "system_ext", Partition.PARTITION_NAME_SYSTEM,
             "vendor"
         };
         for (String name : names) {
diff --git a/core/java/android/os/Environment.java b/core/java/android/os/Environment.java
index 0ee9a11..3462d1f 100644
--- a/core/java/android/os/Environment.java
+++ b/core/java/android/os/Environment.java
@@ -54,7 +54,7 @@
     private static final String ENV_ODM_ROOT = "ODM_ROOT";
     private static final String ENV_VENDOR_ROOT = "VENDOR_ROOT";
     private static final String ENV_PRODUCT_ROOT = "PRODUCT_ROOT";
-    private static final String ENV_PRODUCT_SERVICES_ROOT = "PRODUCT_SERVICES_ROOT";
+    private static final String ENV_SYSTEM_EXT_ROOT = "SYSTEM_EXT_ROOT";
 
     /** {@hide} */
     public static final String DIR_ANDROID = "Android";
@@ -77,8 +77,8 @@
     private static final File DIR_ODM_ROOT = getDirectory(ENV_ODM_ROOT, "/odm");
     private static final File DIR_VENDOR_ROOT = getDirectory(ENV_VENDOR_ROOT, "/vendor");
     private static final File DIR_PRODUCT_ROOT = getDirectory(ENV_PRODUCT_ROOT, "/product");
-    private static final File DIR_PRODUCT_SERVICES_ROOT = getDirectory(ENV_PRODUCT_SERVICES_ROOT,
-                                                           "/product_services");
+    private static final File DIR_SYSTEM_EXT_ROOT = getDirectory(ENV_SYSTEM_EXT_ROOT,
+                                                           "/system_ext");
 
     @UnsupportedAppUsage
     private static UserEnvironment sCurrentUser;
@@ -222,11 +222,26 @@
      * Return root directory of the "product_services" partition holding middleware
      * services if any. If present, the partition is mounted read-only.
      *
+     * @deprecated This directory is not guaranteed to exist.
+     *             Its name is changed to "system_ext" because the partition's purpose is changed.
+     *             {@link #getSystemExtDirectory()}
      * @hide
      */
     @SystemApi
+    @Deprecated
     public static @NonNull File getProductServicesDirectory() {
-        return DIR_PRODUCT_SERVICES_ROOT;
+        return getDirectory("PRODUCT_SERVICES_ROOT", "/product_services");
+    }
+
+    /**
+     * Return root directory of the "system_ext" partition holding system partition's extension
+     * If present, the partition is mounted read-only.
+     *
+     * @hide
+     */
+    @SystemApi
+    public static @NonNull File getSystemExtDirectory() {
+        return DIR_SYSTEM_EXT_ROOT;
     }
 
     /**
diff --git a/core/java/com/android/server/SystemConfig.java b/core/java/com/android/server/SystemConfig.java
index 9fc79cb..364278d 100644
--- a/core/java/com/android/server/SystemConfig.java
+++ b/core/java/com/android/server/SystemConfig.java
@@ -194,9 +194,8 @@
     final ArrayMap<String, ArraySet<String>> mProductPrivAppPermissions = new ArrayMap<>();
     final ArrayMap<String, ArraySet<String>> mProductPrivAppDenyPermissions = new ArrayMap<>();
 
-    final ArrayMap<String, ArraySet<String>> mProductServicesPrivAppPermissions = new ArrayMap<>();
-    final ArrayMap<String, ArraySet<String>> mProductServicesPrivAppDenyPermissions =
-            new ArrayMap<>();
+    final ArrayMap<String, ArraySet<String>> mSystemExtPrivAppPermissions = new ArrayMap<>();
+    final ArrayMap<String, ArraySet<String>> mSystemExtPrivAppDenyPermissions = new ArrayMap<>();
 
     final ArrayMap<String, ArrayMap<String, Boolean>> mOemPermissions = new ArrayMap<>();
 
@@ -321,12 +320,20 @@
         return mProductPrivAppDenyPermissions.get(packageName);
     }
 
-    public ArraySet<String> getProductServicesPrivAppPermissions(String packageName) {
-        return mProductServicesPrivAppPermissions.get(packageName);
+    /**
+     * Read from "permission" tags in /system_ext/etc/permissions/*.xml
+     * @return Set of privileged permissions that are explicitly granted.
+     */
+    public ArraySet<String> getSystemExtPrivAppPermissions(String packageName) {
+        return mSystemExtPrivAppPermissions.get(packageName);
     }
 
-    public ArraySet<String> getProductServicesPrivAppDenyPermissions(String packageName) {
-        return mProductServicesPrivAppDenyPermissions.get(packageName);
+    /**
+     * Read from "deny-permission" tags in /system_ext/etc/permissions/*.xml
+     * @return Set of privileged permissions that are explicitly denied.
+     */
+    public ArraySet<String> getSystemExtPrivAppDenyPermissions(String packageName) {
+        return mSystemExtPrivAppDenyPermissions.get(packageName);
     }
 
     public Map<String, Boolean> getOemPermissions(String packageName) {
@@ -398,11 +405,11 @@
         readPermissions(Environment.buildPath(
                 Environment.getProductDirectory(), "etc", "permissions"), ALLOW_ALL);
 
-        // Allow /product_services to customize all system configs
+        // Allow /system_ext to customize all system configs
         readPermissions(Environment.buildPath(
-                Environment.getProductServicesDirectory(), "etc", "sysconfig"), ALLOW_ALL);
+                Environment.getSystemExtDirectory(), "etc", "sysconfig"), ALLOW_ALL);
         readPermissions(Environment.buildPath(
-                Environment.getProductServicesDirectory(), "etc", "permissions"), ALLOW_ALL);
+                Environment.getSystemExtDirectory(), "etc", "permissions"), ALLOW_ALL);
     }
 
     void readPermissions(File libraryDir, int permissionFlag) {
@@ -848,7 +855,7 @@
                     } break;
                     case "privapp-permissions": {
                         if (allowPrivappPermissions) {
-                            // privapp permissions from system, vendor, product and product_services
+                            // privapp permissions from system, vendor, product and system_ext
                             // partitions are stored separately. This is to prevent xml files in
                             // the vendor partition from granting permissions to priv apps in the
                             // system partition and vice versa.
@@ -858,17 +865,17 @@
                                     Environment.getOdmDirectory().toPath() + "/");
                             boolean product = permFile.toPath().startsWith(
                                     Environment.getProductDirectory().toPath() + "/");
-                            boolean productServices = permFile.toPath().startsWith(
-                                    Environment.getProductServicesDirectory().toPath() + "/");
+                            boolean systemExt = permFile.toPath().startsWith(
+                                    Environment.getSystemExtDirectory().toPath() + "/");
                             if (vendor) {
                                 readPrivAppPermissions(parser, mVendorPrivAppPermissions,
                                         mVendorPrivAppDenyPermissions);
                             } else if (product) {
                                 readPrivAppPermissions(parser, mProductPrivAppPermissions,
                                         mProductPrivAppDenyPermissions);
-                            } else if (productServices) {
-                                readPrivAppPermissions(parser, mProductServicesPrivAppPermissions,
-                                        mProductServicesPrivAppDenyPermissions);
+                            } else if (systemExt) {
+                                readPrivAppPermissions(parser, mSystemExtPrivAppPermissions,
+                                        mSystemExtPrivAppDenyPermissions);
                             } else {
                                 readPrivAppPermissions(parser, mPrivAppPermissions,
                                         mPrivAppDenyPermissions);