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

Commit 0274a6ed authored by Bookatz's avatar Bookatz
Browse files

Allow UserSystemPackageInstaller to ignore OTAs

This cl provides a temporary workaround for a bug.

During OTAs, the UserSystemPackageInstaller goes through all the system
packages and installs them on a user if the package is whitelisted (or
if the feature is no longer being enforced). This ensures that if a package
becomes whitelisted during an OTA, it will be installed on the user,
even if that package had not been whitelisted at the time the user was
created.

This is currently causing ManagedProvisioning to accidently allow
non-required system packages to be installed during OTAs. We
therefore add a mode to this feature to allow ignoring OTAs, thereby
temporarily avoiding this bug.

Bug: 143200798 (temporary workaround)
Test: atest UserSystemPackageInstallerTest

Change-Id: I0a8a44f89c13f5772df57a6cfeea6f484d53d9ae
parent fe407f7a
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -2363,9 +2363,11 @@
         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)
        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">5</integer> <!-- 0b101 -->
    <integer name="config_userTypePackageWhitelistMode">13</integer> <!-- 0b1101 -->
    <!-- TODO(b/143200798): Change to value 5, i.e. 0b0101, when b/143200798 is resolved. -->

    <!-- Whether UI for multi user should be shown -->
    <bool name="config_enableMultiUserUI">false</bool>
+39 −12
Original line number Diff line number Diff line
@@ -84,10 +84,11 @@ 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 (0b000) - disable whitelist (install all system packages; no logging)</li>
     * <li> 1 (0b001) - enforce (only install system packages if they are whitelisted)</li>
     * <li> 2 (0b010) - log (log when a non-whitelisted package is run)</li>
     * <li> 4 (0b100) - implicitly whitelist any package not mentioned in the whitelist</li>
     * <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>-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
@@ -95,17 +96,18 @@ class UserSystemPackageInstaller {
     */
    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 = 0b001;
    static final int USER_TYPE_PACKAGE_WHITELIST_MODE_LOG = 0b010;
    static final int USER_TYPE_PACKAGE_WHITELIST_MODE_IMPLICIT_WHITELIST = 0b100;
    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_DEVICE_DEFAULT = -1;

    @IntDef(flag = true, prefix = "USER_TYPE_PACKAGE_WHITELIST_MODE_", value = {
            USER_TYPE_PACKAGE_WHITELIST_MODE_DISABLE,
            USER_TYPE_PACKAGE_WHITELIST_MODE_ENFORCE,
            USER_TYPE_PACKAGE_WHITELIST_MODE_ENFORCE,
            USER_TYPE_PACKAGE_WHITELIST_MODE_LOG,
            USER_TYPE_PACKAGE_WHITELIST_MODE_IMPLICIT_WHITELIST,
            USER_TYPE_PACKAGE_WHITELIST_MODE_IGNORE_OTA,
    })
    @Retention(RetentionPolicy.SOURCE)
    public @interface PackageWhitelistMode {}
@@ -144,11 +146,17 @@ class UserSystemPackageInstaller {
    boolean installWhitelistedSystemPackages(boolean isFirstBoot, boolean isUpgrade) {
        final int mode = getWhitelistMode();
        checkWhitelistedSystemPackages(mode);
        if (!isUpgrade && !isFirstBoot) {
        final boolean isConsideredUpgrade = isUpgrade && !isIgnoreOtaMode(mode);
        if (!isConsideredUpgrade && !isFirstBoot) {
            return false;
        }
        if (isFirstBoot && !isEnforceMode(mode)) {
            // Note that if !isEnforceMode, we nonetheless still install packages if isUpgrade
            // in order to undo any previous non-installing. isFirstBoot lacks this requirement.
            return false;
        }
        Slog.i(TAG, "Reviewing whitelisted packages due to "
                + (isFirstBoot ? "[firstBoot]" : "") + (isUpgrade ? "[upgrade]" : ""));
                + (isFirstBoot ? "[firstBoot]" : "") + (isConsideredUpgrade ? "[upgrade]" : ""));
        final PackageManagerInternal pmInt = LocalServices.getService(PackageManagerInternal.class);
        // Install/uninstall system packages per user.
        for (int userId : mUm.getUserIds()) {
@@ -160,7 +168,7 @@ class UserSystemPackageInstaller {
                final boolean install =
                        (userWhitelist == null || userWhitelist.contains(pkg.packageName))
                        && !pkg.applicationInfo.hiddenUntilInstalled;
                if (isUpgrade && !isFirstBoot && !install) {
                if (isConsideredUpgrade && !isFirstBoot && !install) {
                    return; // To be careful, we don’t uninstall apps during OTAs
                }
                final boolean changed = pmInt.setInstalled(pkg, userId, install);
@@ -219,6 +227,19 @@ class UserSystemPackageInstaller {
        return isEnforceMode(getWhitelistMode());
    }

    /**
     * Whether to ignore OTAs, and therefore not install missing system packages during OTAs.
     * <p>Note:
     * If in this mode, old system packages will not be installed on pre-existing users during OTAs.
     * Any system packages that had not been installed at the time of the user's creation,
     * due to {@link UserSystemPackageInstaller}'s previous actions, will therefore continue to
     * remain uninstalled, even if the whitelist (or enforcement mode) now declares that they should
     * be.
     */
    boolean isIgnoreOtaMode() {
        return isIgnoreOtaMode(getWhitelistMode());
    }

    /**
     * Whether to log a warning concerning potential problems with the user-type package whitelist.
     */
@@ -239,6 +260,11 @@ class UserSystemPackageInstaller {
        return (whitelistMode & USER_TYPE_PACKAGE_WHITELIST_MODE_ENFORCE) != 0;
    }

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

    /** See {@link #isLogMode()}. */
    private static boolean isLogMode(int whitelistMode) {
        return (whitelistMode & USER_TYPE_PACKAGE_WHITELIST_MODE_LOG) != 0;
@@ -465,6 +491,7 @@ class UserSystemPackageInstaller {
        pw.print(isEnforceMode(mode) ? " (enforced)" : "");
        pw.print(isLogMode(mode) ? " (logged)" : "");
        pw.print(isImplicitWhitelistMode(mode) ? " (implicit)" : "");
        pw.print(isIgnoreOtaMode(mode) ? " (ignore OTAs)" : "");
        pw.println();

        final int size = mWhitelistedPackagesForUserTypes.size();
+13 −0
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@ import static com.android.server.pm.UserSystemPackageInstaller.PACKAGE_WHITELIST
import static com.android.server.pm.UserSystemPackageInstaller.USER_TYPE_PACKAGE_WHITELIST_MODE_DEVICE_DEFAULT;
import static com.android.server.pm.UserSystemPackageInstaller.USER_TYPE_PACKAGE_WHITELIST_MODE_DISABLE;
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_LOG;

@@ -345,33 +346,45 @@ public class UserSystemPackageInstallerTest {
        assertFalse(mUserSystemPackageInstaller.isLogMode());
        assertFalse(mUserSystemPackageInstaller.isEnforceMode());
        assertFalse(mUserSystemPackageInstaller.isImplicitWhitelistMode());
        assertFalse(mUserSystemPackageInstaller.isIgnoreOtaMode());

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

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

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

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

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

        setUserTypePackageWhitelistMode(USER_TYPE_PACKAGE_WHITELIST_MODE_IMPLICIT_WHITELIST
                | USER_TYPE_PACKAGE_WHITELIST_MODE_ENFORCE);
        assertFalse(mUserSystemPackageInstaller.isLogMode());
        assertTrue(mUserSystemPackageInstaller.isEnforceMode());
        assertTrue(mUserSystemPackageInstaller.isImplicitWhitelistMode());
        assertFalse(mUserSystemPackageInstaller.isIgnoreOtaMode());
    }

    /** Sets the whitelist mode to the desired value via adb's setprop. */