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

Commit 2aea1e07 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "UserSystemPackageInstaller: Implicit System Mode"

parents 45352d5e eac923e3
Loading
Loading
Loading
Loading
+14 −7
Original line number Diff line number Diff line
@@ -2357,15 +2357,22 @@

    <!-- Whether to only install system packages on a user if they're whitelisted for that user
         type. These are flags and can be freely combined.
         0 (0b000) - disable whitelist (install all system packages; no logging)
         1 (0b001) - enforce (only install system packages if they are whitelisted)
         2 (0b010) - log (log when a non-whitelisted package is run)
         4 (0b100) - treat any package not mentioned in the whitelist file as implicitly whitelisted
         8 (0b1000) - ignore OTAs (don't install system packages during OTAs)
         0  - disable whitelist (install all system packages; no logging)
         1  - enforce (only install system packages if they are whitelisted)
         2  - log (log when a non-whitelisted package is run)
         4  - any package not mentioned in the whitelist file is implicitly whitelisted on all users
         8  - same as 4, but just for the SYSTEM user
         16 - ignore OTAs (don't install system packages during OTAs)
         Common scenarios:
          - to enable feature (fully enforced) for a complete whitelist: 1
          - to enable feature for an incomplete whitelist (so use implicit whitelist mode): 5
          - to enable feature but implicitly whitelist for SYSTEM user to ease local development: 9
          - to disable feature completely if it had never been enabled: 16
          - to henceforth disable feature and try to undo its previous effects: 0
        Note: This list must be kept current with PACKAGE_WHITELIST_MODE_PROP in
        frameworks/base/services/core/java/com/android/server/pm/UserSystemPackageInstaller.java -->
    <integer name="config_userTypePackageWhitelistMode">13</integer> <!-- 0b1101 -->
    <!-- TODO(b/143200798): Change to value 5, i.e. 0b0101, when b/143200798 is resolved. -->
    <integer name="config_userTypePackageWhitelistMode">29</integer> <!-- 1+4+8+16 -->
    <!-- TODO(b/143200798): Change to value 13, i.e. 1+4+8, when b/143200798 is resolved. -->

    <!-- Whether UI for multi user should be shown -->
    <bool name="config_enableMultiUserUI">false</bool>
+39 −36
Original line number Diff line number Diff line
@@ -67,10 +67,11 @@ import java.util.Set;
 * then:
 * <ul>
 *     <li>If {@link #isImplicitWhitelistMode()}, the package is implicitly treated as whitelisted
 *          for all users</li>
 *     <li>Otherwise, the package is implicitly treated as blacklisted for all non-SYSTEM users</li>
 *     <li>Either way, for {@link UserHandle#USER_SYSTEM}, the package will be implicitly
 *          whitelisted so that it can be used for local development purposes.</li>
 *          for <b>all</b> users</li>
 *     <li>Otherwise, if {@link #isImplicitWhitelistSystemMode()}, the package is implicitly treated
 *          as whitelisted for the <b>{@link UserHandle#USER_SYSTEM}</b> user (not other users),
 *          which is useful for local development purposes</li>
 *     <li>Otherwise, the package is implicitly treated as blacklisted for all users</li>
 * </ul>
 *
 * <p><b>NOTE:</b> the {@code SystemConfig} state is only updated on first boot or after a system
@@ -86,22 +87,24 @@ class UserSystemPackageInstaller {
     * System Property whether to only install system packages on a user if they're whitelisted for
     * that user type. These are flags and can be freely combined.
     * <ul>
     * <li> 0 (0b0000) - disable whitelist (install all system packages; no logging)</li>
     * <li> 1 (0b0001) - enforce (only install system packages if they are whitelisted)</li>
     * <li> 2 (0b0010) - log (log when a non-whitelisted package is run)</li>
     * <li> 4 (0b0100) - implicitly whitelist any package not mentioned in the whitelist</li>
     * <li> 8 (0b1000) - ignore OTAs (don't install system packages during OTAs)</li>
     * <li> 0  - disable whitelist (install all system packages; no logging)</li>
     * <li> 1  - enforce (only install system packages if they are whitelisted)</li>
     * <li> 2  - log (log when a non-whitelisted package is run)</li>
     * <li> 4  - for all users: implicitly whitelist any package not mentioned in the whitelist</li>
     * <li> 8  - for SYSTEM: implicitly whitelist any package not mentioned in the whitelist</li>
     * <li> 16 - ignore OTAs (don't install system packages during OTAs)</li>
     * <li>-1  - use device default (as defined in res/res/values/config.xml)</li>
     * </ul>
     * Note: This list must be kept current with config_userTypePackageWhitelistMode in
     * frameworks/base/core/res/res/values/config.xml
     */
    static final String PACKAGE_WHITELIST_MODE_PROP = "persist.debug.user.package_whitelist_mode";
    static final int USER_TYPE_PACKAGE_WHITELIST_MODE_DISABLE = 0;
    static final int USER_TYPE_PACKAGE_WHITELIST_MODE_ENFORCE = 0b0001;
    static final int USER_TYPE_PACKAGE_WHITELIST_MODE_LOG = 0b0010;
    static final int USER_TYPE_PACKAGE_WHITELIST_MODE_IMPLICIT_WHITELIST = 0b0100;
    static final int USER_TYPE_PACKAGE_WHITELIST_MODE_IGNORE_OTA = 0b1000;
    static final int USER_TYPE_PACKAGE_WHITELIST_MODE_DISABLE = 0x00;
    static final int USER_TYPE_PACKAGE_WHITELIST_MODE_ENFORCE = 0x01;
    static final int USER_TYPE_PACKAGE_WHITELIST_MODE_LOG = 0x02;
    static final int USER_TYPE_PACKAGE_WHITELIST_MODE_IMPLICIT_WHITELIST = 0x04;
    static final int USER_TYPE_PACKAGE_WHITELIST_MODE_IMPLICIT_WHITELIST_SYSTEM = 0x08;
    static final int USER_TYPE_PACKAGE_WHITELIST_MODE_IGNORE_OTA = 0x10;
    static final int USER_TYPE_PACKAGE_WHITELIST_MODE_DEVICE_DEFAULT = -1;

    @IntDef(flag = true, prefix = "USER_TYPE_PACKAGE_WHITELIST_MODE_", value = {
@@ -281,6 +284,14 @@ class UserSystemPackageInstaller {
        return isImplicitWhitelistMode(getWhitelistMode());
    }

    /**
     * Whether to treat all packages that are not mentioned at all in the whitelist to be implicitly
     * whitelisted for the SYSTEM user.
     */
    boolean isImplicitWhitelistSystemMode() {
        return isImplicitWhitelistSystemMode(getWhitelistMode());
    }

    /** See {@link #isEnforceMode()}. */
    private static boolean isEnforceMode(int whitelistMode) {
        return (whitelistMode & USER_TYPE_PACKAGE_WHITELIST_MODE_ENFORCE) != 0;
@@ -301,6 +312,11 @@ class UserSystemPackageInstaller {
        return (whitelistMode & USER_TYPE_PACKAGE_WHITELIST_MODE_IMPLICIT_WHITELIST) != 0;
    }

    /** See {@link #isImplicitWhitelistSystemMode()}. */
    private static boolean isImplicitWhitelistSystemMode(int whitelistMode) {
        return (whitelistMode & USER_TYPE_PACKAGE_WHITELIST_MODE_IMPLICIT_WHITELIST_SYSTEM) != 0;
    }

    /** Gets the PackageWhitelistMode for use of {@link #mWhitelistedPackagesForUserTypes}. */
    private @PackageWhitelistMode int getWhitelistMode() {
        final int runtimeMode = SystemProperties.getInt(
@@ -332,8 +348,8 @@ class UserSystemPackageInstaller {
        if (!isEnforceMode(mode)) {
            return null;
        }
        final boolean isSystemUser = mUm.isUserTypeSubtypeOfSystem(userType);
        final boolean isImplicitWhitelistMode = isImplicitWhitelistMode(mode);
        final boolean implicitlyWhitelist = isImplicitWhitelistMode(mode)
                || (isImplicitWhitelistSystemMode(mode) && mUm.isUserTypeSubtypeOfSystem(userType));
        final Set<String> whitelistedPackages = getWhitelistedPackagesForUserType(userType);

        final Set<String> installPackages = new ArraySet<>();
@@ -343,7 +359,7 @@ class UserSystemPackageInstaller {
                return;
            }
            if (shouldInstallPackage(pkg, mWhitelistedPackagesForUserTypes,
                    whitelistedPackages, isImplicitWhitelistMode, isSystemUser)) {
                    whitelistedPackages, implicitlyWhitelist)) {
                // Although the whitelist uses manifest names, this function returns packageNames.
                installPackages.add(pkg.getPackageName());
            }
@@ -360,31 +376,18 @@ class UserSystemPackageInstaller {
     *                          installed. This is only used for overriding the userWhitelist in
     *                          certain situations (based on its keyset).
     * @param userWhitelist set of package manifest names that should be installed on this
     *                      particular user. This must be consistent with userTypeWhitelist, but is
     *                      passed in separately to avoid repeatedly calculating it from
     *                      <b>particular</b> user. This must be consistent with userTypeWhitelist,
     *                      but is passed in separately to avoid repeatedly calculating it from
     *                      userTypeWhitelist.
     * @param isImplicitWhitelistMode whether non-mentioned packages are implicitly whitelisted.
     * @param isSystemUser whether the user is USER_SYSTEM (which gets special treatment).
     * @param implicitlyWhitelist whether non-mentioned packages are implicitly whitelisted.
     */
    @VisibleForTesting
    static boolean shouldInstallPackage(AndroidPackage sysPkg,
            @NonNull ArrayMap<String, Long> userTypeWhitelist,
            @NonNull Set<String> userWhitelist, boolean isImplicitWhitelistMode,
            boolean isSystemUser) {

            @NonNull Set<String> userWhitelist, boolean implicitlyWhitelist) {
        final String pkgName = sysPkg.getManifestPackageName();
        boolean install = (isImplicitWhitelistMode && !userTypeWhitelist.containsKey(pkgName))
        return (implicitlyWhitelist && !userTypeWhitelist.containsKey(pkgName))
                || userWhitelist.contains(pkgName);

        // For the purposes of local development, any package that isn't even mentioned in the
        // whitelist at all is implicitly treated as whitelisted for the SYSTEM user.
        if (!install && isSystemUser && !userTypeWhitelist.containsKey(pkgName)) {
            install = true;
            Slog.e(TAG, "System package " + pkgName + " is not mentioned "
                    + "in SystemConfig's 'install-in-user-type' but we are "
                    + "implicitly treating it as whitelisted for the SYSTEM user.");
        }
        return install;
    }

    /**
+23 −22
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@ import static com.android.server.pm.UserSystemPackageInstaller.USER_TYPE_PACKAGE
import static com.android.server.pm.UserSystemPackageInstaller.USER_TYPE_PACKAGE_WHITELIST_MODE_ENFORCE;
import static com.android.server.pm.UserSystemPackageInstaller.USER_TYPE_PACKAGE_WHITELIST_MODE_IGNORE_OTA;
import static com.android.server.pm.UserSystemPackageInstaller.USER_TYPE_PACKAGE_WHITELIST_MODE_IMPLICIT_WHITELIST;
import static com.android.server.pm.UserSystemPackageInstaller.USER_TYPE_PACKAGE_WHITELIST_MODE_IMPLICIT_WHITELIST_SYSTEM;
import static com.android.server.pm.UserSystemPackageInstaller.USER_TYPE_PACKAGE_WHITELIST_MODE_LOG;

import static org.junit.Assert.assertEquals;
@@ -262,39 +263,25 @@ public class UserSystemPackageInstallerTest {

        // No implicit whitelist, so only install pkg1.
        boolean implicit = false;
        boolean isSysUser = false;
        assertTrue(UserSystemPackageInstaller.shouldInstallPackage(
                pkg1, pkgBitSetMap, userWhitelist, implicit, isSysUser));
                pkg1, pkgBitSetMap, userWhitelist, implicit));
        assertFalse(UserSystemPackageInstaller.shouldInstallPackage(
                pkg2, pkgBitSetMap, userWhitelist, implicit, isSysUser));
                pkg2, pkgBitSetMap, userWhitelist, implicit));
        assertFalse(UserSystemPackageInstaller.shouldInstallPackage(
                pkg3, pkgBitSetMap, userWhitelist, implicit, isSysUser));
                pkg3, pkgBitSetMap, userWhitelist, implicit));
        assertFalse(UserSystemPackageInstaller.shouldInstallPackage(
                pkg4, pkgBitSetMap, userWhitelist, implicit, isSysUser));
                pkg4, pkgBitSetMap, userWhitelist, implicit));

        // Use implicit whitelist, so install pkg1 and pkg4
        implicit = true;
        isSysUser = false;
        assertTrue(UserSystemPackageInstaller.shouldInstallPackage(
                pkg1, pkgBitSetMap, userWhitelist, implicit, isSysUser));
                pkg1, pkgBitSetMap, userWhitelist, implicit));
        assertFalse(UserSystemPackageInstaller.shouldInstallPackage(
                pkg2, pkgBitSetMap, userWhitelist, implicit, isSysUser));
                pkg2, pkgBitSetMap, userWhitelist, implicit));
        assertFalse(UserSystemPackageInstaller.shouldInstallPackage(
                pkg3, pkgBitSetMap, userWhitelist, implicit, isSysUser));
                pkg3, pkgBitSetMap, userWhitelist, implicit));
        assertTrue(UserSystemPackageInstaller.shouldInstallPackage(
                pkg4, pkgBitSetMap, userWhitelist, implicit, isSysUser));

        // For user 0 specifically, we always implicitly whitelist.
        implicit = false;
        isSysUser = true;
        assertTrue(UserSystemPackageInstaller.shouldInstallPackage(
                pkg1, pkgBitSetMap, userWhitelist, implicit, isSysUser));
        assertFalse(UserSystemPackageInstaller.shouldInstallPackage(
                pkg2, pkgBitSetMap, userWhitelist, implicit, isSysUser));
        assertFalse(UserSystemPackageInstaller.shouldInstallPackage(
                pkg3, pkgBitSetMap, userWhitelist, implicit, isSysUser));
        assertTrue(UserSystemPackageInstaller.shouldInstallPackage(
                pkg4, pkgBitSetMap, userWhitelist, implicit, isSysUser));
                pkg4, pkgBitSetMap, userWhitelist, implicit));
    }

    /**
@@ -400,30 +387,42 @@ public class UserSystemPackageInstallerTest {
        assertFalse(mUserSystemPackageInstaller.isLogMode());
        assertFalse(mUserSystemPackageInstaller.isEnforceMode());
        assertFalse(mUserSystemPackageInstaller.isImplicitWhitelistMode());
        assertFalse(mUserSystemPackageInstaller.isImplicitWhitelistSystemMode());
        assertFalse(mUserSystemPackageInstaller.isIgnoreOtaMode());

        setUserTypePackageWhitelistMode(USER_TYPE_PACKAGE_WHITELIST_MODE_LOG);
        assertTrue(mUserSystemPackageInstaller.isLogMode());
        assertFalse(mUserSystemPackageInstaller.isEnforceMode());
        assertFalse(mUserSystemPackageInstaller.isImplicitWhitelistMode());
        assertFalse(mUserSystemPackageInstaller.isImplicitWhitelistSystemMode());
        assertFalse(mUserSystemPackageInstaller.isIgnoreOtaMode());

        setUserTypePackageWhitelistMode(USER_TYPE_PACKAGE_WHITELIST_MODE_ENFORCE);
        assertFalse(mUserSystemPackageInstaller.isLogMode());
        assertTrue(mUserSystemPackageInstaller.isEnforceMode());
        assertFalse(mUserSystemPackageInstaller.isImplicitWhitelistMode());
        assertFalse(mUserSystemPackageInstaller.isImplicitWhitelistSystemMode());
        assertFalse(mUserSystemPackageInstaller.isIgnoreOtaMode());

        setUserTypePackageWhitelistMode(USER_TYPE_PACKAGE_WHITELIST_MODE_IMPLICIT_WHITELIST);
        assertFalse(mUserSystemPackageInstaller.isLogMode());
        assertFalse(mUserSystemPackageInstaller.isEnforceMode());
        assertTrue(mUserSystemPackageInstaller.isImplicitWhitelistMode());
        assertFalse(mUserSystemPackageInstaller.isImplicitWhitelistSystemMode());
        assertFalse(mUserSystemPackageInstaller.isIgnoreOtaMode());

        setUserTypePackageWhitelistMode(USER_TYPE_PACKAGE_WHITELIST_MODE_IMPLICIT_WHITELIST_SYSTEM);
        assertFalse(mUserSystemPackageInstaller.isLogMode());
        assertFalse(mUserSystemPackageInstaller.isEnforceMode());
        assertFalse(mUserSystemPackageInstaller.isImplicitWhitelistMode());
        assertTrue(mUserSystemPackageInstaller.isImplicitWhitelistSystemMode());
        assertFalse(mUserSystemPackageInstaller.isIgnoreOtaMode());

        setUserTypePackageWhitelistMode(USER_TYPE_PACKAGE_WHITELIST_MODE_IGNORE_OTA);
        assertFalse(mUserSystemPackageInstaller.isLogMode());
        assertFalse(mUserSystemPackageInstaller.isEnforceMode());
        assertFalse(mUserSystemPackageInstaller.isImplicitWhitelistMode());
        assertFalse(mUserSystemPackageInstaller.isImplicitWhitelistSystemMode());
        assertTrue(mUserSystemPackageInstaller.isIgnoreOtaMode());

        setUserTypePackageWhitelistMode(
@@ -431,6 +430,7 @@ public class UserSystemPackageInstallerTest {
        assertTrue(mUserSystemPackageInstaller.isLogMode());
        assertTrue(mUserSystemPackageInstaller.isEnforceMode());
        assertFalse(mUserSystemPackageInstaller.isImplicitWhitelistMode());
        assertFalse(mUserSystemPackageInstaller.isImplicitWhitelistSystemMode());
        assertFalse(mUserSystemPackageInstaller.isIgnoreOtaMode());

        setUserTypePackageWhitelistMode(USER_TYPE_PACKAGE_WHITELIST_MODE_IMPLICIT_WHITELIST
@@ -438,6 +438,7 @@ public class UserSystemPackageInstallerTest {
        assertFalse(mUserSystemPackageInstaller.isLogMode());
        assertTrue(mUserSystemPackageInstaller.isEnforceMode());
        assertTrue(mUserSystemPackageInstaller.isImplicitWhitelistMode());
        assertFalse(mUserSystemPackageInstaller.isImplicitWhitelistSystemMode());
        assertFalse(mUserSystemPackageInstaller.isIgnoreOtaMode());
    }