Loading services/core/java/com/android/server/pm/UserManagerService.java +25 −11 Original line number Diff line number Diff line Loading @@ -4516,8 +4516,8 @@ public class UserManagerService extends IUserManager.Stub { switch(cmd) { case "list": return runList(pw, shell); case "list-missing-system-packages": return runListMissingSystemPackages(pw, shell); case "report-system-user-package-whitelist-problems": return runReportPackageWhitelistProblems(pw, shell); default: return shell.handleDefaultCommands(cmd); } Loading Loading @@ -4584,17 +4584,22 @@ public class UserManagerService extends IUserManager.Stub { } } private int runListMissingSystemPackages(PrintWriter pw, Shell shell) { private int runReportPackageWhitelistProblems(PrintWriter pw, Shell shell) { boolean verbose = false; boolean force = false; boolean criticalOnly = false; int mode = UserSystemPackageInstaller.USER_TYPE_PACKAGE_WHITELIST_MODE_NONE; String opt; while ((opt = shell.getNextOption()) != null) { switch (opt) { case "-v": case "--verbose": verbose = true; break; case "--force": force = true; case "--critical-only": criticalOnly = true; break; case "--mode": mode = Integer.parseInt(shell.getNextArgRequired()); break; default: pw.println("Invalid option: " + opt); Loading @@ -4602,8 +4607,12 @@ public class UserManagerService extends IUserManager.Stub { } } Slog.d(LOG_TAG, "runReportPackageWhitelistProblems(): verbose=" + verbose + ", criticalOnly=" + criticalOnly + ", mode=" + UserSystemPackageInstaller.modeToString(mode)); try (IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " ")) { mSystemPackageInstaller.dumpMissingSystemPackages(ipw, force, verbose); mSystemPackageInstaller.dumpPackageWhitelistProblems(ipw, mode, verbose, criticalOnly); } return 0; } Loading Loading @@ -5176,13 +5185,18 @@ public class UserManagerService extends IUserManager.Stub { final PrintWriter pw = getOutPrintWriter(); pw.println("User manager (user) commands:"); pw.println(" help"); pw.println(" Print this help text."); pw.println(" Prints this help text."); pw.println(""); pw.println(" list [-v] [-all]"); pw.println(" Prints all users on the system."); pw.println(" list-missing-system-packages [-v] [--force]"); pw.println(" Prints all system packages that were not explicitly configured to be " + "installed."); pw.println(" report-system-user-package-whitelist-problems [-v | --verbose] " + "[--critical-only] [--mode MODE]"); pw.println(" Reports all issues on user-type package whitelist XML files. Options:"); pw.println(" -v | --verbose : shows extra info, like number of issues"); pw.println(" --critical-only: show only critical issues, excluding warnings"); pw.println(" --mode MODE: shows what errors would be if device used mode MODE (where" + " MODE is the whitelist mode integer as defined by " + "config_userTypePackageWhitelistMode)"); } } Loading services/core/java/com/android/server/pm/UserSystemPackageInstaller.java +109 −62 Original line number Diff line number Diff line Loading @@ -27,7 +27,7 @@ import android.os.SystemProperties; import android.os.UserHandle; import android.util.ArrayMap; import android.util.ArraySet; import android.util.Pair; import android.util.DebugUtils; import android.util.Slog; import com.android.internal.annotations.VisibleForTesting; Loading @@ -41,6 +41,7 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Map; import java.util.Set; Loading Loading @@ -111,14 +112,20 @@ class UserSystemPackageInstaller { * 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 = 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; // NOTE: flags below are public so they can used by DebugUtils.flagsToString. And this class // itself is package-protected, so it doesn't matter... public static final int USER_TYPE_PACKAGE_WHITELIST_MODE_DISABLE = 0x00; public static final int USER_TYPE_PACKAGE_WHITELIST_MODE_ENFORCE = 0x01; public static final int USER_TYPE_PACKAGE_WHITELIST_MODE_LOG = 0x02; public static final int USER_TYPE_PACKAGE_WHITELIST_MODE_IMPLICIT_WHITELIST = 0x04; public static final int USER_TYPE_PACKAGE_WHITELIST_MODE_IMPLICIT_WHITELIST_SYSTEM = 0x08; public static final int USER_TYPE_PACKAGE_WHITELIST_MODE_IGNORE_OTA = 0x10; static final int USER_TYPE_PACKAGE_WHITELIST_MODE_DEVICE_DEFAULT = -1; // Used by Shell command only static final int USER_TYPE_PACKAGE_WHITELIST_MODE_NONE = -1000; @IntDef(flag = true, prefix = "USER_TYPE_PACKAGE_WHITELIST_MODE_", value = { USER_TYPE_PACKAGE_WHITELIST_MODE_DISABLE, USER_TYPE_PACKAGE_WHITELIST_MODE_ENFORCE, Loading Loading @@ -266,58 +273,56 @@ class UserSystemPackageInstaller { if (!isLogMode(mode) && !isEnforceMode(mode)) { return; } final List<Pair<Boolean, String>> warnings = checkSystemPackagesWhitelistWarnings(mode); final int size = warnings.size(); if (size == 0) { Slog.v(TAG, "checkWhitelistedSystemPackages(mode=" + mode + "): no warnings"); return; Slog.v(TAG, "Checking that all system packages are whitelisted."); // Check whether all whitelisted packages are indeed on the system. final List<String> warnings = getPackagesWhitelistWarnings(); final int numberWarnings = warnings.size(); if (numberWarnings == 0) { Slog.v(TAG, "checkWhitelistedSystemPackages(mode=" + modeToString(mode) + ") has no warnings"); } else { Slog.w(TAG, "checkWhitelistedSystemPackages(mode=" + modeToString(mode) + ") has " + numberWarnings + " warnings:"); for (int i = 0; i < numberWarnings; i++) { Slog.w(TAG, warnings.get(i)); } } // Check whether all system packages are indeed whitelisted. if (isImplicitWhitelistMode(mode) && !isLogMode(mode)) { // Only shows whether all whitelisted packages are indeed on the system. for (int i = 0; i < size; i++) { final Pair<Boolean, String> pair = warnings.get(i); final boolean isSevere = pair.first; if (!isSevere) { final String msg = pair.second; Slog.w(TAG, msg); } return; } final List<String> errors = getPackagesWhitelistErrors(mode); final int numberErrors = errors.size(); if (numberErrors == 0) { Slog.v(TAG, "checkWhitelistedSystemPackages(mode=" + modeToString(mode) + ") has no errors"); return; } Slog.e(TAG, "checkWhitelistedSystemPackages(mode=" + modeToString(mode) + ") has " + numberErrors + " errors:"); Slog.v(TAG, "checkWhitelistedSystemPackages(mode=" + mode + "): " + size + " warnings"); boolean doWtf = !isImplicitWhitelistMode(mode); for (int i = 0; i < size; i++) { final Pair<Boolean, String> pair = warnings.get(i); final boolean isSevere = pair.first; final String msg = pair.second; if (isSevere) { for (int i = 0; i < numberWarnings; i++) { final String msg = errors.get(i); if (doWtf) { Slog.wtf(TAG, msg); } else { Slog.e(TAG, msg); } } else { Slog.w(TAG, msg); } } } // TODO: method below was created to refactor the one-time logging logic so it can be used on // dump / cmd as well. It could to be further refactored (for example, creating a new // structure for the warnings so it doesn't need a Pair). /** * Gets warnings for system user whitelisting. * * @return list of warnings, where {@code Pair.first} is the severity ({@code true} for WTF, * {@code false} for WARN) and {@code Pair.second} the message. * Gets packages that are listed in the whitelist XML but are not present on the system image. */ @NonNull private List<Pair<Boolean, String>> checkSystemPackagesWhitelistWarnings( @PackageWhitelistMode int mode) { private List<String> getPackagesWhitelistWarnings() { final Set<String> allWhitelistedPackages = getWhitelistedSystemPackages(); final List<Pair<Boolean, String>> warnings = new ArrayList<>(); final List<String> warnings = new ArrayList<>(); final PackageManagerInternal pmInt = LocalServices.getService(PackageManagerInternal.class); // Check whether all whitelisted packages are indeed on the system. Loading @@ -326,25 +331,39 @@ class UserSystemPackageInstaller { for (String pkgName : allWhitelistedPackages) { final AndroidPackage pkg = pmInt.getPackage(pkgName); if (pkg == null) { warnings.add(new Pair<>(false, String.format(notPresentFmt, pkgName))); warnings.add(String.format(notPresentFmt, pkgName)); } else if (!pkg.isSystem()) { warnings.add(new Pair<>(false, String.format(notSystemFmt, pkgName))); warnings.add(String.format(notSystemFmt, pkgName)); } } return warnings; } /** * Gets packages that are not listed in the whitelist XMLs when they should be. */ @NonNull private List<String> getPackagesWhitelistErrors(@PackageWhitelistMode int mode) { if ((!isEnforceMode(mode) || isImplicitWhitelistMode(mode)) && !isLogMode(mode)) { return Collections.emptyList(); } final List<String> errors = new ArrayList<>(); final Set<String> allWhitelistedPackages = getWhitelistedSystemPackages(); final PackageManagerInternal pmInt = LocalServices.getService(PackageManagerInternal.class); // Check whether all system packages are indeed whitelisted. final String logMessageFmt = "System package %s is not whitelisted using " + "'install-in-user-type' in SystemConfig for any user types!"; final boolean isSevere = isEnforceMode(mode); pmInt.forEachPackage(pkg -> { if (!pkg.isSystem()) return; final String pkgName = pkg.getManifestPackageName(); if (!allWhitelistedPackages.contains(pkgName)) { warnings.add(new Pair<>(isSevere, String.format(logMessageFmt, pkgName))); errors.add(String.format(logMessageFmt, pkgName)); } }); return warnings; return errors; } /** Whether to only install system packages in new users for which they are whitelisted. */ Loading Loading @@ -420,10 +439,28 @@ class UserSystemPackageInstaller { if (runtimeMode != USER_TYPE_PACKAGE_WHITELIST_MODE_DEVICE_DEFAULT) { return runtimeMode; } return getDeviceDefaultWhitelistMode(); } /** Gets the PackageWhitelistMode as defined by {@code config_userTypePackageWhitelistMode}. */ private @PackageWhitelistMode int getDeviceDefaultWhitelistMode() { return Resources.getSystem() .getInteger(com.android.internal.R.integer.config_userTypePackageWhitelistMode); } static @NonNull String modeToString(@PackageWhitelistMode int mode) { // Must handle some types separately because they're not bitwise flags switch (mode) { case USER_TYPE_PACKAGE_WHITELIST_MODE_DEVICE_DEFAULT: return "DEVICE_DEFAULT"; case USER_TYPE_PACKAGE_WHITELIST_MODE_NONE: return "NONE"; default: return DebugUtils.flagsToString(UserSystemPackageInstaller.class, "USER_TYPE_PACKAGE_WHITELIST_MODE_", mode); } } /** * Gets the system packages names that should be installed on the given user. * See {@link #getInstallablePackagesForUserType(String)}. Loading Loading @@ -703,34 +740,44 @@ class UserSystemPackageInstaller { pw.decreaseIndent(); pw.decreaseIndent(); pw.increaseIndent(); dumpMissingSystemPackages(pw, /* force= */ true, /* verbose= */ true); dumpPackageWhitelistProblems(pw, mode, /* verbose= */ true, /* criticalOnly= */ false); pw.decreaseIndent(); } void dumpMissingSystemPackages(IndentingPrintWriter pw, boolean force, boolean verbose) { final int mode = getWhitelistMode(); final boolean show = force || (isEnforceMode(mode) && !isImplicitWhitelistMode(mode)); if (!show) return; void dumpPackageWhitelistProblems(IndentingPrintWriter pw, @PackageWhitelistMode int mode, boolean verbose, boolean criticalOnly) { // Handle special cases first if (mode == USER_TYPE_PACKAGE_WHITELIST_MODE_NONE) { mode = getWhitelistMode(); } else if (mode == USER_TYPE_PACKAGE_WHITELIST_MODE_DEVICE_DEFAULT) { mode = getDeviceDefaultWhitelistMode(); } Slog.v(TAG, "dumpPackageWhitelistProblems(): using mode " + modeToString(mode)); final List<String> errors = getPackagesWhitelistErrors(mode); showIssues(pw, verbose, errors, "errors"); final List<Pair<Boolean, String>> warnings = checkSystemPackagesWhitelistWarnings(mode); final int size = warnings.size(); if (criticalOnly) return; final List<String> warnings = getPackagesWhitelistWarnings(); showIssues(pw, verbose, warnings, "warnings"); } private static void showIssues(IndentingPrintWriter pw, boolean verbose, List<String> issues, String issueType) { final int size = issues.size(); if (size == 0) { if (verbose) { pw.println("All system packages are accounted for"); pw.print("No "); pw.println(issueType); } return; } if (verbose) { pw.print(size); pw.println(" warnings for system user:"); pw.print(size); pw.print(' '); pw.println(issueType); pw.increaseIndent(); } for (int i = 0; i < size; i++) { final Pair<Boolean, String> pair = warnings.get(i); final String lvl = pair.first ? "WTF" : "WARN"; final String msg = pair.second; pw.print(lvl); pw.print(": "); pw.println(msg); pw.println(issues.get(i)); } if (verbose) { pw.decreaseIndent(); Loading Loading
services/core/java/com/android/server/pm/UserManagerService.java +25 −11 Original line number Diff line number Diff line Loading @@ -4516,8 +4516,8 @@ public class UserManagerService extends IUserManager.Stub { switch(cmd) { case "list": return runList(pw, shell); case "list-missing-system-packages": return runListMissingSystemPackages(pw, shell); case "report-system-user-package-whitelist-problems": return runReportPackageWhitelistProblems(pw, shell); default: return shell.handleDefaultCommands(cmd); } Loading Loading @@ -4584,17 +4584,22 @@ public class UserManagerService extends IUserManager.Stub { } } private int runListMissingSystemPackages(PrintWriter pw, Shell shell) { private int runReportPackageWhitelistProblems(PrintWriter pw, Shell shell) { boolean verbose = false; boolean force = false; boolean criticalOnly = false; int mode = UserSystemPackageInstaller.USER_TYPE_PACKAGE_WHITELIST_MODE_NONE; String opt; while ((opt = shell.getNextOption()) != null) { switch (opt) { case "-v": case "--verbose": verbose = true; break; case "--force": force = true; case "--critical-only": criticalOnly = true; break; case "--mode": mode = Integer.parseInt(shell.getNextArgRequired()); break; default: pw.println("Invalid option: " + opt); Loading @@ -4602,8 +4607,12 @@ public class UserManagerService extends IUserManager.Stub { } } Slog.d(LOG_TAG, "runReportPackageWhitelistProblems(): verbose=" + verbose + ", criticalOnly=" + criticalOnly + ", mode=" + UserSystemPackageInstaller.modeToString(mode)); try (IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " ")) { mSystemPackageInstaller.dumpMissingSystemPackages(ipw, force, verbose); mSystemPackageInstaller.dumpPackageWhitelistProblems(ipw, mode, verbose, criticalOnly); } return 0; } Loading Loading @@ -5176,13 +5185,18 @@ public class UserManagerService extends IUserManager.Stub { final PrintWriter pw = getOutPrintWriter(); pw.println("User manager (user) commands:"); pw.println(" help"); pw.println(" Print this help text."); pw.println(" Prints this help text."); pw.println(""); pw.println(" list [-v] [-all]"); pw.println(" Prints all users on the system."); pw.println(" list-missing-system-packages [-v] [--force]"); pw.println(" Prints all system packages that were not explicitly configured to be " + "installed."); pw.println(" report-system-user-package-whitelist-problems [-v | --verbose] " + "[--critical-only] [--mode MODE]"); pw.println(" Reports all issues on user-type package whitelist XML files. Options:"); pw.println(" -v | --verbose : shows extra info, like number of issues"); pw.println(" --critical-only: show only critical issues, excluding warnings"); pw.println(" --mode MODE: shows what errors would be if device used mode MODE (where" + " MODE is the whitelist mode integer as defined by " + "config_userTypePackageWhitelistMode)"); } } Loading
services/core/java/com/android/server/pm/UserSystemPackageInstaller.java +109 −62 Original line number Diff line number Diff line Loading @@ -27,7 +27,7 @@ import android.os.SystemProperties; import android.os.UserHandle; import android.util.ArrayMap; import android.util.ArraySet; import android.util.Pair; import android.util.DebugUtils; import android.util.Slog; import com.android.internal.annotations.VisibleForTesting; Loading @@ -41,6 +41,7 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Map; import java.util.Set; Loading Loading @@ -111,14 +112,20 @@ class UserSystemPackageInstaller { * 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 = 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; // NOTE: flags below are public so they can used by DebugUtils.flagsToString. And this class // itself is package-protected, so it doesn't matter... public static final int USER_TYPE_PACKAGE_WHITELIST_MODE_DISABLE = 0x00; public static final int USER_TYPE_PACKAGE_WHITELIST_MODE_ENFORCE = 0x01; public static final int USER_TYPE_PACKAGE_WHITELIST_MODE_LOG = 0x02; public static final int USER_TYPE_PACKAGE_WHITELIST_MODE_IMPLICIT_WHITELIST = 0x04; public static final int USER_TYPE_PACKAGE_WHITELIST_MODE_IMPLICIT_WHITELIST_SYSTEM = 0x08; public static final int USER_TYPE_PACKAGE_WHITELIST_MODE_IGNORE_OTA = 0x10; static final int USER_TYPE_PACKAGE_WHITELIST_MODE_DEVICE_DEFAULT = -1; // Used by Shell command only static final int USER_TYPE_PACKAGE_WHITELIST_MODE_NONE = -1000; @IntDef(flag = true, prefix = "USER_TYPE_PACKAGE_WHITELIST_MODE_", value = { USER_TYPE_PACKAGE_WHITELIST_MODE_DISABLE, USER_TYPE_PACKAGE_WHITELIST_MODE_ENFORCE, Loading Loading @@ -266,58 +273,56 @@ class UserSystemPackageInstaller { if (!isLogMode(mode) && !isEnforceMode(mode)) { return; } final List<Pair<Boolean, String>> warnings = checkSystemPackagesWhitelistWarnings(mode); final int size = warnings.size(); if (size == 0) { Slog.v(TAG, "checkWhitelistedSystemPackages(mode=" + mode + "): no warnings"); return; Slog.v(TAG, "Checking that all system packages are whitelisted."); // Check whether all whitelisted packages are indeed on the system. final List<String> warnings = getPackagesWhitelistWarnings(); final int numberWarnings = warnings.size(); if (numberWarnings == 0) { Slog.v(TAG, "checkWhitelistedSystemPackages(mode=" + modeToString(mode) + ") has no warnings"); } else { Slog.w(TAG, "checkWhitelistedSystemPackages(mode=" + modeToString(mode) + ") has " + numberWarnings + " warnings:"); for (int i = 0; i < numberWarnings; i++) { Slog.w(TAG, warnings.get(i)); } } // Check whether all system packages are indeed whitelisted. if (isImplicitWhitelistMode(mode) && !isLogMode(mode)) { // Only shows whether all whitelisted packages are indeed on the system. for (int i = 0; i < size; i++) { final Pair<Boolean, String> pair = warnings.get(i); final boolean isSevere = pair.first; if (!isSevere) { final String msg = pair.second; Slog.w(TAG, msg); } return; } final List<String> errors = getPackagesWhitelistErrors(mode); final int numberErrors = errors.size(); if (numberErrors == 0) { Slog.v(TAG, "checkWhitelistedSystemPackages(mode=" + modeToString(mode) + ") has no errors"); return; } Slog.e(TAG, "checkWhitelistedSystemPackages(mode=" + modeToString(mode) + ") has " + numberErrors + " errors:"); Slog.v(TAG, "checkWhitelistedSystemPackages(mode=" + mode + "): " + size + " warnings"); boolean doWtf = !isImplicitWhitelistMode(mode); for (int i = 0; i < size; i++) { final Pair<Boolean, String> pair = warnings.get(i); final boolean isSevere = pair.first; final String msg = pair.second; if (isSevere) { for (int i = 0; i < numberWarnings; i++) { final String msg = errors.get(i); if (doWtf) { Slog.wtf(TAG, msg); } else { Slog.e(TAG, msg); } } else { Slog.w(TAG, msg); } } } // TODO: method below was created to refactor the one-time logging logic so it can be used on // dump / cmd as well. It could to be further refactored (for example, creating a new // structure for the warnings so it doesn't need a Pair). /** * Gets warnings for system user whitelisting. * * @return list of warnings, where {@code Pair.first} is the severity ({@code true} for WTF, * {@code false} for WARN) and {@code Pair.second} the message. * Gets packages that are listed in the whitelist XML but are not present on the system image. */ @NonNull private List<Pair<Boolean, String>> checkSystemPackagesWhitelistWarnings( @PackageWhitelistMode int mode) { private List<String> getPackagesWhitelistWarnings() { final Set<String> allWhitelistedPackages = getWhitelistedSystemPackages(); final List<Pair<Boolean, String>> warnings = new ArrayList<>(); final List<String> warnings = new ArrayList<>(); final PackageManagerInternal pmInt = LocalServices.getService(PackageManagerInternal.class); // Check whether all whitelisted packages are indeed on the system. Loading @@ -326,25 +331,39 @@ class UserSystemPackageInstaller { for (String pkgName : allWhitelistedPackages) { final AndroidPackage pkg = pmInt.getPackage(pkgName); if (pkg == null) { warnings.add(new Pair<>(false, String.format(notPresentFmt, pkgName))); warnings.add(String.format(notPresentFmt, pkgName)); } else if (!pkg.isSystem()) { warnings.add(new Pair<>(false, String.format(notSystemFmt, pkgName))); warnings.add(String.format(notSystemFmt, pkgName)); } } return warnings; } /** * Gets packages that are not listed in the whitelist XMLs when they should be. */ @NonNull private List<String> getPackagesWhitelistErrors(@PackageWhitelistMode int mode) { if ((!isEnforceMode(mode) || isImplicitWhitelistMode(mode)) && !isLogMode(mode)) { return Collections.emptyList(); } final List<String> errors = new ArrayList<>(); final Set<String> allWhitelistedPackages = getWhitelistedSystemPackages(); final PackageManagerInternal pmInt = LocalServices.getService(PackageManagerInternal.class); // Check whether all system packages are indeed whitelisted. final String logMessageFmt = "System package %s is not whitelisted using " + "'install-in-user-type' in SystemConfig for any user types!"; final boolean isSevere = isEnforceMode(mode); pmInt.forEachPackage(pkg -> { if (!pkg.isSystem()) return; final String pkgName = pkg.getManifestPackageName(); if (!allWhitelistedPackages.contains(pkgName)) { warnings.add(new Pair<>(isSevere, String.format(logMessageFmt, pkgName))); errors.add(String.format(logMessageFmt, pkgName)); } }); return warnings; return errors; } /** Whether to only install system packages in new users for which they are whitelisted. */ Loading Loading @@ -420,10 +439,28 @@ class UserSystemPackageInstaller { if (runtimeMode != USER_TYPE_PACKAGE_WHITELIST_MODE_DEVICE_DEFAULT) { return runtimeMode; } return getDeviceDefaultWhitelistMode(); } /** Gets the PackageWhitelistMode as defined by {@code config_userTypePackageWhitelistMode}. */ private @PackageWhitelistMode int getDeviceDefaultWhitelistMode() { return Resources.getSystem() .getInteger(com.android.internal.R.integer.config_userTypePackageWhitelistMode); } static @NonNull String modeToString(@PackageWhitelistMode int mode) { // Must handle some types separately because they're not bitwise flags switch (mode) { case USER_TYPE_PACKAGE_WHITELIST_MODE_DEVICE_DEFAULT: return "DEVICE_DEFAULT"; case USER_TYPE_PACKAGE_WHITELIST_MODE_NONE: return "NONE"; default: return DebugUtils.flagsToString(UserSystemPackageInstaller.class, "USER_TYPE_PACKAGE_WHITELIST_MODE_", mode); } } /** * Gets the system packages names that should be installed on the given user. * See {@link #getInstallablePackagesForUserType(String)}. Loading Loading @@ -703,34 +740,44 @@ class UserSystemPackageInstaller { pw.decreaseIndent(); pw.decreaseIndent(); pw.increaseIndent(); dumpMissingSystemPackages(pw, /* force= */ true, /* verbose= */ true); dumpPackageWhitelistProblems(pw, mode, /* verbose= */ true, /* criticalOnly= */ false); pw.decreaseIndent(); } void dumpMissingSystemPackages(IndentingPrintWriter pw, boolean force, boolean verbose) { final int mode = getWhitelistMode(); final boolean show = force || (isEnforceMode(mode) && !isImplicitWhitelistMode(mode)); if (!show) return; void dumpPackageWhitelistProblems(IndentingPrintWriter pw, @PackageWhitelistMode int mode, boolean verbose, boolean criticalOnly) { // Handle special cases first if (mode == USER_TYPE_PACKAGE_WHITELIST_MODE_NONE) { mode = getWhitelistMode(); } else if (mode == USER_TYPE_PACKAGE_WHITELIST_MODE_DEVICE_DEFAULT) { mode = getDeviceDefaultWhitelistMode(); } Slog.v(TAG, "dumpPackageWhitelistProblems(): using mode " + modeToString(mode)); final List<String> errors = getPackagesWhitelistErrors(mode); showIssues(pw, verbose, errors, "errors"); final List<Pair<Boolean, String>> warnings = checkSystemPackagesWhitelistWarnings(mode); final int size = warnings.size(); if (criticalOnly) return; final List<String> warnings = getPackagesWhitelistWarnings(); showIssues(pw, verbose, warnings, "warnings"); } private static void showIssues(IndentingPrintWriter pw, boolean verbose, List<String> issues, String issueType) { final int size = issues.size(); if (size == 0) { if (verbose) { pw.println("All system packages are accounted for"); pw.print("No "); pw.println(issueType); } return; } if (verbose) { pw.print(size); pw.println(" warnings for system user:"); pw.print(size); pw.print(' '); pw.println(issueType); pw.increaseIndent(); } for (int i = 0; i < size; i++) { final Pair<Boolean, String> pair = warnings.get(i); final String lvl = pair.first ? "WTF" : "WARN"; final String msg = pair.second; pw.print(lvl); pw.print(": "); pw.println(msg); pw.println(issues.get(i)); } if (verbose) { pw.decreaseIndent(); Loading