Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2bef1768 authored by Dario Freni's avatar Dario Freni
Browse files

Support /product-services partition

This CL is largely an adaptation of Change-Id
I16175933cebd9ec665d190cc5d564b5414a91827 . I also used the same way for
testing the change.

This CL will support the followings.
- installing a RRO package for framework from /product-services/overlay
- installing apps from /product-services/app
- installing priv-apps from /product-services/priv-app
- installing permissions from
  /product-services/etc/[default-permissions|permissions|sysconfig]

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

  And I moved vendor/overlay/framework-res__auto_generated_rro.apk
  into system/product-services/overlay/ on taimen, and I confirmed that the
  RRO was installed properly.

Change-Id: I7a6a30bf8e8db9f2738594d187bb9148f138b8da
(cherry picked from commit a4af41736894bd3bf5bdc2a279acbeed2a24dd3d)
parent 80457464
Loading
Loading
Loading
Loading
+13 −0
Original line number Diff line number Diff line
@@ -614,6 +614,13 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable {
     */
    public static final int PRIVATE_FLAG_PRODUCT = 1 << 19;

    /**
     * Value for {@link #privateFlags}: whether this app is pre-installed on the
     * google partition of the system image.
     * @hide
     */
    public static final int PRIVATE_FLAG_PRODUCT_SERVICES = 1 << 21;

    /**
     * Value for {@link #privateFlags}: whether this app is signed with the
     * platform key.
@@ -639,6 +646,7 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable {
            PRIVATE_FLAG_PARTIALLY_DIRECT_BOOT_AWARE,
            PRIVATE_FLAG_PRIVILEGED,
            PRIVATE_FLAG_PRODUCT,
            PRIVATE_FLAG_PRODUCT_SERVICES,
            PRIVATE_FLAG_REQUIRED_FOR_SYSTEM_USER,
            PRIVATE_FLAG_SIGNED_WITH_PLATFORM_KEY,
            PRIVATE_FLAG_STATIC_SHARED_LIBRARY,
@@ -1888,6 +1896,11 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable {
        return (privateFlags & ApplicationInfo.PRIVATE_FLAG_PRODUCT) != 0;
    }

    /** @hide */
    public boolean isProductServices() {
        return (privateFlags & ApplicationInfo.PRIVATE_FLAG_PRODUCT_SERVICES) != 0;
    }

    /**
     * Returns whether or not this application was installed as a virtual preload.
     */
+5 −0
Original line number Diff line number Diff line
@@ -6784,6 +6784,11 @@ public class PackageParser {
            return applicationInfo.isProduct();
        }

        /** @hide */
        public boolean isProductServices() {
            return applicationInfo.isProductServices();
        }

        /** @hide */
        public boolean isPrivileged() {
            return applicationInfo.isPrivilegedApp();
+13 −0
Original line number Diff line number Diff line
@@ -45,6 +45,7 @@ public class Environment {
    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";

    /** {@hide} */
    public static final String DIR_ANDROID = "Android";
@@ -67,6 +68,8 @@ public class Environment {
    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 UserEnvironment sCurrentUser;
    private static boolean sUserRequired;
@@ -195,6 +198,16 @@ public class Environment {
        return DIR_PRODUCT_ROOT;
    }

    /**
     * Return root directory of the "product_services" partition holding middleware
     * services if any. If present, the partition is mounted read-only.
     *
     * @hide
     */
    public static File getProductServicesDirectory() {
        return DIR_PRODUCT_SERVICES_ROOT;
    }

    /**
     * Return the system directory for a user. This is for use by system
     * services to store files relating to the user. This directory will be
+35 −7
Original line number Diff line number Diff line
@@ -169,6 +169,10 @@ public class SystemConfig {
    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, ArrayMap<String, Boolean>> mOemPermissions = new ArrayMap<>();

    public static SystemConfig getInstance() {
@@ -276,6 +280,14 @@ public class SystemConfig {
        return mProductPrivAppDenyPermissions.get(packageName);
    }

    public ArraySet<String> getProductServicesPrivAppPermissions(String packageName) {
        return mProductServicesPrivAppPermissions.get(packageName);
    }

    public ArraySet<String> getProductServicesPrivAppDenyPermissions(String packageName) {
        return mProductServicesPrivAppDenyPermissions.get(packageName);
    }

    public Map<String, Boolean> getOemPermissions(String packageName) {
        final Map<String, Boolean> oemPermissions = mOemPermissions.get(packageName);
        if (oemPermissions != null) {
@@ -326,6 +338,17 @@ public class SystemConfig {
                Environment.getProductDirectory(), "etc", "sysconfig"), productPermissionFlag);
        readPermissions(Environment.buildPath(
                Environment.getProductDirectory(), "etc", "permissions"), productPermissionFlag);

        // Allow /product_services to customize system configs around libs, features, permissions
        // and apps.
        int productServicesPermissionFlag = ALLOW_LIBS | ALLOW_FEATURES | ALLOW_PERMISSIONS |
                ALLOW_APP_CONFIGS | ALLOW_PRIVAPP_PERMISSIONS;
        readPermissions(Environment.buildPath(
                Environment.getProductServicesDirectory(), "etc", "sysconfig"),
                productServicesPermissionFlag);
        readPermissions(Environment.buildPath(
                Environment.getProductServicesDirectory(), "etc", "permissions"),
                productServicesPermissionFlag);
    }

    void readPermissions(File libraryDir, int permissionFlag) {
@@ -659,22 +682,27 @@ public class SystemConfig {
                    }
                    XmlUtils.skipCurrentTag(parser);
                } else if ("privapp-permissions".equals(name) && allowPrivappPermissions) {
                    // privapp permissions from system, vendor and product 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.
                    // privapp permissions from system, vendor, product and product_services
                    // 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.
                    boolean vendor = permFile.toPath().startsWith(
                            Environment.getVendorDirectory().toPath())
                            Environment.getVendorDirectory().toPath() + "/")
                            || permFile.toPath().startsWith(
                                Environment.getOdmDirectory().toPath());
                                Environment.getOdmDirectory().toPath() + "/");
                    boolean product = permFile.toPath().startsWith(
                            Environment.getProductDirectory().toPath());
                            Environment.getProductDirectory().toPath() + "/");
                    boolean productServices = permFile.toPath().startsWith(
                            Environment.getProductServicesDirectory().toPath() + "/");
                    if (vendor) {
                        readPrivAppPermissions(parser, mVendorPrivAppPermissions,
                                mVendorPrivAppDenyPermissions);
                    } else if (product) {
                        readPrivAppPermissions(parser, mProductPrivAppPermissions,
                                mProductPrivAppDenyPermissions);
                    } else if (productServices) {
                        readPrivAppPermissions(parser, mProductServicesPrivAppPermissions,
                                mProductServicesPrivAppDenyPermissions);
                    } else {
                        readPrivAppPermissions(parser, mPrivAppPermissions,
                                mPrivAppDenyPermissions);
+6 −4
Original line number Diff line number Diff line
@@ -365,10 +365,12 @@ public class OtaDexoptService extends IOtaDexopt.Stub {
                continue;
            }

            // If the path is in /system, /vendor or /product, ignore. It will have been
            // ota-dexopted into /data/ota and moved into the dalvik-cache already.
            if (pkg.codePath.startsWith("/system") || pkg.codePath.startsWith("/vendor")
                    || pkg.codePath.startsWith("/product")) {
            // If the path is in /system, /vendor, /product or /product_services, ignore. It will
            // have been ota-dexopted into /data/ota and moved into the dalvik-cache already.
            if (pkg.codePath.startsWith("/system")
                    || pkg.codePath.startsWith("/vendor")
                    || pkg.codePath.startsWith("/product")
                    || pkg.codePath.startsWith("/product_services")) {
                continue;
            }

Loading