• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2019 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.server.pm;
18 
19 import android.annotation.IntDef;
20 import android.annotation.NonNull;
21 import android.annotation.Nullable;
22 import android.annotation.UserIdInt;
23 import android.content.pm.PackageManager;
24 import android.content.pm.PackageManagerInternal;
25 import android.content.res.Resources;
26 import android.os.SystemProperties;
27 import android.os.UserHandle;
28 import android.util.ArrayMap;
29 import android.util.ArraySet;
30 import android.util.DebugUtils;
31 import android.util.IndentingPrintWriter;
32 import android.util.Slog;
33 
34 import com.android.internal.annotations.VisibleForTesting;
35 import com.android.server.LocalServices;
36 import com.android.server.SystemConfig;
37 import com.android.server.pm.parsing.pkg.AndroidPackage;
38 
39 import java.lang.annotation.Retention;
40 import java.lang.annotation.RetentionPolicy;
41 import java.util.ArrayList;
42 import java.util.Arrays;
43 import java.util.Collections;
44 import java.util.List;
45 import java.util.Map;
46 import java.util.Set;
47 
48 /**
49  * Responsible for un/installing system packages based on user type.
50  *
51  * <p>Uses the SystemConfig's install-in-user-type allowlist;
52  * see {@link SystemConfig#getAndClearPackageToUserTypeWhitelist} and
53  * {@link SystemConfig#getAndClearPackageToUserTypeBlacklist}.
54  *
55  * <p>If {@link #isEnforceMode()} is false, then all system packages are always installed for all
56  * users. The following applies when it is true.
57  *
58  * <p>Any package can be in one of three states in the {@code SystemConfig} allowlist
59  * <ol>
60  *     <li>Explicitly denylisted for a particular user type</li>
61  *     <li>Explicitly allowlisted for a particular user type</li>
62  *     <li>Not mentioned at all, for any user type (neither allowlisted nor denylisted)</li>
63  * </ol>
64  *
65  * <p>Denylisting always takes precedence - if a package is denylisted for a particular user,
66  * it won't be installed on that type of user (even if it is also allowlisted for that user).
67  * Next comes allowlisting - if it is allowlisted for a particular user, it will be installed on
68  * that type of user (as long as it isn't denylisted).
69  * Finally, if the package is not mentioned at all (i.e. neither allowlisted nor denylisted for
70  * any user types) in the SystemConfig 'install-in-user-type' lists
71  * then:
72  * <ul>
73  *     <li>If {@link #isImplicitWhitelistMode()}, the package is implicitly treated as allowlisted
74  *          for <b>all</b> users</li>
75  *     <li>Otherwise, if {@link #isImplicitWhitelistSystemMode()}, the package is implicitly treated
76  *          as allowlisted for the <b>{@link UserHandle#USER_SYSTEM}</b> user (not other users),
77  *          which is useful for local development purposes</li>
78  *     <li>Otherwise, the package is implicitly treated as denylisted for all users</li>
79  * </ul>
80  *
81  * <p>Packages are only installed/uninstalled by this mechanism when a new user is created or during
82  * an update. In the case of updates:<ul>
83  *     <li>new packages are (un)installed per the allowlist/denylist</li>
84  *     <li>pre-existing installed denylisted packages are never uninstalled</li>
85  *     <li>pre-existing not-installed allowlisted packages are only installed if the reason why they
86  *     had been previously uninstalled was due to UserSystemPackageInstaller</li>
87  * </ul>
88  *
89  * <p><b>NOTE:</b> the {@code SystemConfig} state is only updated on first boot or after a system
90  * update. So, to verify changes during development, you can emulate the latter by calling:
91  * <pre><code>
92  * adb shell setprop persist.pm.mock-upgrade true
93  * </code></pre>
94  */
95 class UserSystemPackageInstaller {
96     private static final String TAG = "UserManagerService";
97 
98     private static final boolean DEBUG = false;
99 
100     /**
101      * System Property whether to only install system packages on a user if they're allowlisted for
102      * that user type. These are flags and can be freely combined.
103      * <ul>
104      * <li> 0  - disable allowlist (install all system packages; no logging)</li>
105      * <li> 1  - enforce (only install system packages if they are allowlisted)</li>
106      * <li> 2  - log (log non-allowlisted packages)</li>
107      * <li> 4  - for all users: implicitly allowlist any package not mentioned in the allowlist</li>
108      * <li> 8  - for SYSTEM: implicitly allowlist any package not mentioned in the allowlist</li>
109      * <li> 16 - ignore OTAs (don't install system packages during OTAs)</li>
110      * <li>-1  - use device default (as defined in res/res/values/config.xml)</li>
111      * </ul>
112      * Note: This list must be kept current with config_userTypePackageWhitelistMode in
113      * frameworks/base/core/res/res/values/config.xml
114      */
115     static final String PACKAGE_WHITELIST_MODE_PROP = "persist.debug.user.package_whitelist_mode";
116 
117     // NOTE: flags below are public so they can used by DebugUtils.flagsToString. And this class
118     // itself is package-protected, so it doesn't matter...
119     public static final int USER_TYPE_PACKAGE_WHITELIST_MODE_DISABLE = 0x00;
120     public static final int USER_TYPE_PACKAGE_WHITELIST_MODE_ENFORCE = 0x01;
121     public static final int USER_TYPE_PACKAGE_WHITELIST_MODE_LOG = 0x02;
122     public static final int USER_TYPE_PACKAGE_WHITELIST_MODE_IMPLICIT_WHITELIST = 0x04;
123     public static final int USER_TYPE_PACKAGE_WHITELIST_MODE_IMPLICIT_WHITELIST_SYSTEM = 0x08;
124     public static final int USER_TYPE_PACKAGE_WHITELIST_MODE_IGNORE_OTA = 0x10;
125     static final int USER_TYPE_PACKAGE_WHITELIST_MODE_DEVICE_DEFAULT = -1;
126 
127     // Used by Shell command only
128     static final int USER_TYPE_PACKAGE_WHITELIST_MODE_NONE = -1000;
129 
130     @IntDef(flag = true, prefix = "USER_TYPE_PACKAGE_WHITELIST_MODE_", value = {
131             USER_TYPE_PACKAGE_WHITELIST_MODE_DISABLE,
132             USER_TYPE_PACKAGE_WHITELIST_MODE_ENFORCE,
133             USER_TYPE_PACKAGE_WHITELIST_MODE_LOG,
134             USER_TYPE_PACKAGE_WHITELIST_MODE_IMPLICIT_WHITELIST,
135             USER_TYPE_PACKAGE_WHITELIST_MODE_IGNORE_OTA,
136     })
137     @Retention(RetentionPolicy.SOURCE)
138     public @interface PackageWhitelistMode {}
139 
140     /**
141      * Maps system package manifest names to a bitset representing (via {@link #getUserTypeMask})
142      * the user types on which they should be initially installed.
143      * <p>
144      * E.g. if package "pkg1" should be installed on "usertype_d", which is the user type for which
145      * {@link #getUserTypeMask}("usertype_d") returns (1 << 3)
146      * then mWhitelistedPackagesForUserTypes.get("pkg1") will be a Long whose
147      * bit in position 3 will equal 1.
148      * <p>
149      * Packages that are allowlisted, but then denylisted so that they aren't to be installed on
150      * any user, are purposefully still present in this list.
151      */
152     private final ArrayMap<String, Long> mWhitelistedPackagesForUserTypes;
153 
154     private final UserManagerService mUm;
155 
156     /**
157      * Alphabetically sorted list of user types.
158      * Throughout this class, a long (functioning as a bitset) has its ith bit representing
159      * the user type stored in mUserTypes[i].
160      * mUserTypes cannot exceed Long.SIZE (since we are using long for our bitset).
161      */
162     private final String[] mUserTypes;
163 
UserSystemPackageInstaller(UserManagerService um, ArrayMap<String, UserTypeDetails> userTypes)164     UserSystemPackageInstaller(UserManagerService um, ArrayMap<String, UserTypeDetails> userTypes) {
165         mUm = um;
166         mUserTypes = getAndSortKeysFromMap(userTypes);
167         if (mUserTypes.length > Long.SIZE) {
168             throw new IllegalArgumentException("Device contains " + userTypes.size()
169                     + " user types. However, UserSystemPackageInstaller does not work if there are"
170                     + " more than " + Long.SIZE + " user types.");
171             // UserSystemPackageInstaller could use a BitSet instead of Long in this case.
172             // But, currently, 64 user types is far beyond expectations, so we have not done so.
173         }
174         mWhitelistedPackagesForUserTypes =
175                 determineWhitelistedPackagesForUserTypes(SystemConfig.getInstance());
176     }
177 
178     /** Constructor for testing purposes. */
179     @VisibleForTesting
UserSystemPackageInstaller(UserManagerService ums, ArrayMap<String, Long> whitelist, String[] sortedUserTypes)180     UserSystemPackageInstaller(UserManagerService ums, ArrayMap<String, Long> whitelist,
181             String[] sortedUserTypes) {
182         mUm = ums;
183         mUserTypes = sortedUserTypes;
184         mWhitelistedPackagesForUserTypes = whitelist;
185     }
186 
187     /**
188      * During OTAs and first boot, install/uninstall all system packages for all users based on the
189      * user's user type and the SystemConfig allowlist.
190      * We do NOT uninstall packages during an OTA though.
191      *
192      * This is responsible for enforcing the allowlist for pre-existing users (i.e. USER_SYSTEM);
193      * enforcement for new users is done when they are created in UserManagerService.createUser().
194      *
195      * @param preExistingPackages list of packages on the device prior to the upgrade. Cannot be
196      *                            null if isUpgrade is true.
197      */
installWhitelistedSystemPackages(boolean isFirstBoot, boolean isUpgrade, @Nullable ArraySet<String> preExistingPackages)198     boolean installWhitelistedSystemPackages(boolean isFirstBoot, boolean isUpgrade,
199             @Nullable ArraySet<String> preExistingPackages) {
200         final int mode = getWhitelistMode();
201         checkWhitelistedSystemPackages(mode);
202         final boolean isConsideredUpgrade = isUpgrade && !isIgnoreOtaMode(mode);
203         if (!isConsideredUpgrade && !isFirstBoot) {
204             return false;
205         }
206         if (isFirstBoot && !isEnforceMode(mode)) {
207             // Note that if !isEnforceMode, we nonetheless still install packages if isUpgrade
208             // in order to undo any previous non-installing. isFirstBoot lacks this requirement.
209             return false;
210         }
211         Slog.i(TAG, "Reviewing whitelisted packages due to "
212                 + (isFirstBoot ? "[firstBoot]" : "") + (isConsideredUpgrade ? "[upgrade]" : ""));
213         final PackageManagerInternal pmInt = LocalServices.getService(PackageManagerInternal.class);
214         // Install/uninstall system packages per user.
215         for (int userId : mUm.getUserIds()) {
216             final Set<String> userWhitelist = getInstallablePackagesForUserId(userId);
217             pmInt.forEachPackageSetting(pkgSetting -> {
218                 AndroidPackage pkg = pkgSetting.pkg;
219                 if (pkg == null || !pkg.isSystem()) {
220                     return;
221                 }
222                 final boolean install =
223                         (userWhitelist == null || userWhitelist.contains(pkg.getPackageName()))
224                                 && !pkgSetting.getPkgState().isHiddenUntilInstalled();
225                 if (pkgSetting.getInstalled(userId) == install
226                         || !shouldChangeInstallationState(pkgSetting, install, userId, isFirstBoot,
227                                 isConsideredUpgrade, preExistingPackages)) {
228                     return;
229                 }
230                 pkgSetting.setInstalled(install, userId);
231                 pkgSetting.setUninstallReason(
232                         install ? PackageManager.UNINSTALL_REASON_UNKNOWN :
233                                 PackageManager.UNINSTALL_REASON_USER_TYPE,
234                         userId);
235                 Slog.i(TAG, (install ? "Installed " : "Uninstalled ")
236                         + pkg.getPackageName() + " for user " + userId);
237             });
238         }
239         return true;
240     }
241 
242     /**
243      * Returns whether to proceed with install/uninstall for the given package.
244      * In particular, do not install a package unless it was only uninstalled due to the user type;
245      * and do not uninstall a package if it previously was installed (prior to the OTA).
246      *
247      * Should be called only within PackageManagerInternal.forEachPackageSetting() since it
248      * requires the LP lock.
249      *
250      * @param preOtaPkgs list of packages on the device prior to the upgrade.
251      *                   Cannot be null if isUpgrade is true.
252      */
shouldChangeInstallationState(PackageSetting pkgSetting, boolean install, @UserIdInt int userId, boolean isFirstBoot, boolean isUpgrade, @Nullable ArraySet<String> preOtaPkgs)253     private static boolean shouldChangeInstallationState(PackageSetting pkgSetting,
254                                                          boolean install,
255                                                          @UserIdInt int userId,
256                                                          boolean isFirstBoot,
257                                                          boolean isUpgrade,
258                                                          @Nullable ArraySet<String> preOtaPkgs) {
259         if (install) {
260             // Only proceed with install if we are the only reason why it had been uninstalled.
261             return pkgSetting.getUninstallReason(userId)
262                     == PackageManager.UNINSTALL_REASON_USER_TYPE;
263         } else {
264             // Only proceed with uninstall if the package is new to the device.
265             return isFirstBoot || (isUpgrade && !preOtaPkgs.contains(pkgSetting.name));
266         }
267     }
268 
269     /**
270      * Checks whether the system packages and the mWhitelistedPackagesForUserTypes allowlist are
271      * in 1-to-1 correspondence.
272      */
checkWhitelistedSystemPackages(@ackageWhitelistMode int mode)273     private void checkWhitelistedSystemPackages(@PackageWhitelistMode int mode) {
274         if (!isLogMode(mode) && !isEnforceMode(mode)) {
275             return;
276         }
277         Slog.v(TAG,  "Checking that all system packages are whitelisted.");
278 
279         // Check whether all allowlisted packages are indeed on the system.
280         final List<String> warnings = getPackagesWhitelistWarnings();
281         final int numberWarnings = warnings.size();
282         if (numberWarnings == 0) {
283             Slog.v(TAG, "checkWhitelistedSystemPackages(mode=" + modeToString(mode)
284                     + ") has no warnings");
285         } else {
286             Slog.w(TAG, "checkWhitelistedSystemPackages(mode=" + modeToString(mode)
287                     + ") has " + numberWarnings + " warnings:");
288             for (int i = 0; i < numberWarnings; i++) {
289                 Slog.w(TAG, warnings.get(i));
290             }
291         }
292 
293         // Check whether all system packages are indeed allowlisted.
294         if (isImplicitWhitelistMode(mode) && !isLogMode(mode)) {
295             return;
296         }
297 
298         final List<String> errors = getPackagesWhitelistErrors(mode);
299         final int numberErrors = errors.size();
300 
301         if (numberErrors == 0) {
302             Slog.v(TAG, "checkWhitelistedSystemPackages(mode=" + modeToString(mode)
303                     + ") has no errors");
304             return;
305         }
306         Slog.e(TAG, "checkWhitelistedSystemPackages(mode=" + modeToString(mode) + ") has "
307                 + numberErrors + " errors:");
308 
309         boolean doWtf = !isImplicitWhitelistMode(mode);
310         for (int i = 0; i < numberErrors; i++) {
311             final String msg = errors.get(i);
312             if (doWtf) {
313                 Slog.wtf(TAG, msg);
314             } else {
315                 Slog.e(TAG, msg);
316             }
317         }
318     }
319 
320     /**
321      * Gets packages that are listed in the allowlist XML but are not present on the system image.
322      */
323     @NonNull
getPackagesWhitelistWarnings()324     private List<String> getPackagesWhitelistWarnings() {
325         final Set<String> allWhitelistedPackages = getWhitelistedSystemPackages();
326         final List<String> warnings = new ArrayList<>();
327         final PackageManagerInternal pmInt = LocalServices.getService(PackageManagerInternal.class);
328 
329         // Check whether all allowlisted packages are indeed on the system.
330         final String notPresentFmt = "%s is allowlisted but not present.";
331         final String notSystemFmt = "%s is allowlisted and present but not a system package.";
332         final String overlayFmt = "%s is allowlisted unnecessarily since it's a static overlay.";
333         for (String pkgName : allWhitelistedPackages) {
334             final AndroidPackage pkg = pmInt.getPackage(pkgName);
335             if (pkg == null) {
336                 warnings.add(String.format(notPresentFmt, pkgName));
337             } else if (!pkg.isSystem()) {
338                 warnings.add(String.format(notSystemFmt, pkgName));
339             } else if (shouldUseOverlayTargetName(pkg)) {
340                 warnings.add(String.format(overlayFmt, pkgName));
341             }
342         }
343         return warnings;
344     }
345 
346     /**
347      * Gets packages that are not listed in the allowlist XMLs when they should be.
348      */
349     @NonNull
getPackagesWhitelistErrors(@ackageWhitelistMode int mode)350     private List<String> getPackagesWhitelistErrors(@PackageWhitelistMode int mode) {
351         if ((!isEnforceMode(mode) || isImplicitWhitelistMode(mode)) && !isLogMode(mode)) {
352             return Collections.emptyList();
353         }
354 
355         final List<String> errors = new ArrayList<>();
356         final Set<String> allWhitelistedPackages = getWhitelistedSystemPackages();
357         final PackageManagerInternal pmInt = LocalServices.getService(PackageManagerInternal.class);
358 
359         // Check whether all system packages are indeed allowlisted.
360         final String logMessageFmt = "System package %s is not whitelisted using "
361                 + "'install-in-user-type' in SystemConfig for any user types!";
362         pmInt.forEachPackage(pkg -> {
363             if (!pkg.isSystem()) return;
364             final String pkgName = pkg.getManifestPackageName();
365             if (!allWhitelistedPackages.contains(pkgName)
366                     && !shouldUseOverlayTargetName(pmInt.getPackage(pkgName))) {
367                 errors.add(String.format(logMessageFmt, pkgName));
368             }
369         });
370 
371         return errors;
372     }
373 
374     /** Whether to only install system packages in new users for which they are allowlisted. */
isEnforceMode()375     boolean isEnforceMode() {
376         return isEnforceMode(getWhitelistMode());
377     }
378 
379     /**
380      * Whether to ignore OTAs, and therefore not install missing system packages during OTAs.
381      * <p>Note:
382      * If in this mode, old system packages will not be installed on pre-existing users during OTAs.
383      * Any system packages that had not been installed at the time of the user's creation,
384      * due to {@link UserSystemPackageInstaller}'s previous actions, will therefore continue to
385      * remain uninstalled, even if the allowlist (or enforcement mode) now declares that they should
386      * be.
387      */
isIgnoreOtaMode()388     boolean isIgnoreOtaMode() {
389         return isIgnoreOtaMode(getWhitelistMode());
390     }
391 
392     /**
393      * Whether to log a warning concerning potential problems with the user-type package allowlist.
394      */
isLogMode()395     boolean isLogMode() {
396         return isLogMode(getWhitelistMode());
397     }
398 
399     /**
400      * Whether to treat all packages that are not mentioned at all in the allowlist to be implicitly
401      * allowlisted for all users.
402      */
isImplicitWhitelistMode()403     boolean isImplicitWhitelistMode() {
404         return isImplicitWhitelistMode(getWhitelistMode());
405     }
406 
407     /**
408      * Whether to treat all packages that are not mentioned at all in the allowlist to be implicitly
409      * allowlisted for the SYSTEM user.
410      */
isImplicitWhitelistSystemMode()411     boolean isImplicitWhitelistSystemMode() {
412         return isImplicitWhitelistSystemMode(getWhitelistMode());
413     }
414 
415     /**
416      * Returns whether the package is a static overlay, whose installation should depend on the
417      * allowlisting of the overlay's target's package name, rather than of its own package name.
418      *
419      * @param pkg A package (which need not be an overlay)
420      */
shouldUseOverlayTargetName(AndroidPackage pkg)421     private static boolean shouldUseOverlayTargetName(AndroidPackage pkg) {
422         return pkg.isOverlayIsStatic();
423     }
424 
425     /** See {@link #isEnforceMode()}. */
isEnforceMode(int whitelistMode)426     private static boolean isEnforceMode(int whitelistMode) {
427         return (whitelistMode & USER_TYPE_PACKAGE_WHITELIST_MODE_ENFORCE) != 0;
428     }
429 
430     /** See {@link #isIgnoreOtaMode()}. */
isIgnoreOtaMode(int whitelistMode)431     private static boolean isIgnoreOtaMode(int whitelistMode) {
432         return (whitelistMode & USER_TYPE_PACKAGE_WHITELIST_MODE_IGNORE_OTA) != 0;
433     }
434 
435     /** See {@link #isLogMode()}. */
isLogMode(int whitelistMode)436     private static boolean isLogMode(int whitelistMode) {
437         return (whitelistMode & USER_TYPE_PACKAGE_WHITELIST_MODE_LOG) != 0;
438     }
439 
440     /** See {@link #isImplicitWhitelistMode()}. */
isImplicitWhitelistMode(int whitelistMode)441     private static boolean isImplicitWhitelistMode(int whitelistMode) {
442         return (whitelistMode & USER_TYPE_PACKAGE_WHITELIST_MODE_IMPLICIT_WHITELIST) != 0;
443     }
444 
445     /** See {@link #isImplicitWhitelistSystemMode()}. */
isImplicitWhitelistSystemMode(int whitelistMode)446     private static boolean isImplicitWhitelistSystemMode(int whitelistMode) {
447         return (whitelistMode & USER_TYPE_PACKAGE_WHITELIST_MODE_IMPLICIT_WHITELIST_SYSTEM) != 0;
448     }
449 
450     /** Gets the PackageWhitelistMode for use of {@link #mWhitelistedPackagesForUserTypes}. */
getWhitelistMode()451     private @PackageWhitelistMode int getWhitelistMode() {
452         final int runtimeMode = SystemProperties.getInt(
453                 PACKAGE_WHITELIST_MODE_PROP, USER_TYPE_PACKAGE_WHITELIST_MODE_DEVICE_DEFAULT);
454         if (runtimeMode != USER_TYPE_PACKAGE_WHITELIST_MODE_DEVICE_DEFAULT) {
455             return runtimeMode;
456         }
457         return getDeviceDefaultWhitelistMode();
458     }
459 
460     /** Gets the PackageWhitelistMode as defined by {@code config_userTypePackageWhitelistMode}. */
getDeviceDefaultWhitelistMode()461     private @PackageWhitelistMode int getDeviceDefaultWhitelistMode() {
462         return Resources.getSystem()
463                 .getInteger(com.android.internal.R.integer.config_userTypePackageWhitelistMode);
464     }
465 
modeToString(@ackageWhitelistMode int mode)466     static @NonNull String modeToString(@PackageWhitelistMode int mode) {
467         // Must handle some types separately because they're not bitwise flags
468         switch (mode) {
469             case USER_TYPE_PACKAGE_WHITELIST_MODE_DEVICE_DEFAULT:
470                 return "DEVICE_DEFAULT";
471             case USER_TYPE_PACKAGE_WHITELIST_MODE_NONE:
472                 return "NONE";
473             default:
474                 return DebugUtils.flagsToString(UserSystemPackageInstaller.class,
475                         "USER_TYPE_PACKAGE_WHITELIST_MODE_", mode);
476         }
477     }
478 
479     /**
480      * Gets the system packages names that should be installed on the given user.
481      * See {@link #getInstallablePackagesForUserType(String)}.
482      */
getInstallablePackagesForUserId(@serIdInt int userId)483     private @Nullable Set<String> getInstallablePackagesForUserId(@UserIdInt int userId) {
484         return getInstallablePackagesForUserType(mUm.getUserInfo(userId).userType);
485     }
486 
487     /**
488      * Gets the system package names that should be installed on users of the given user type, as
489      * determined by SystemConfig, the allowlist mode, and the apps actually on the device.
490      * Names are the {@link PackageParser.Package#packageName}, not necessarily the manifest names.
491      *
492      * Returns null if all system packages should be installed (due to enforce-mode being off).
493      */
getInstallablePackagesForUserType(String userType)494     @Nullable Set<String> getInstallablePackagesForUserType(String userType) {
495         final int mode = getWhitelistMode();
496         if (!isEnforceMode(mode)) {
497             return null;
498         }
499         final boolean implicitlyWhitelist = isImplicitWhitelistMode(mode)
500                 || (isImplicitWhitelistSystemMode(mode) && mUm.isUserTypeSubtypeOfSystem(userType));
501         final Set<String> whitelistedPackages = getWhitelistedPackagesForUserType(userType);
502 
503         final Set<String> installPackages = new ArraySet<>();
504         final PackageManagerInternal pmInt = LocalServices.getService(PackageManagerInternal.class);
505         pmInt.forEachPackage(pkg -> {
506             if (!pkg.isSystem()) {
507                 return;
508             }
509             if (shouldInstallPackage(pkg, mWhitelistedPackagesForUserTypes,
510                     whitelistedPackages, implicitlyWhitelist)) {
511                 // Although the allowlist uses manifest names, this function returns packageNames.
512                 installPackages.add(pkg.getPackageName());
513             }
514         });
515         return installPackages;
516     }
517 
518     /**
519      * Returns whether the given system package should be installed on the given user, based on the
520      * the given allowlist of system packages.
521      *
522      * @param sysPkg the system package. Must be a system package; no verification for this is done.
523      * @param userTypeWhitelist map of package manifest names to user types on which they should be
524      *                          installed. This is only used for overriding the userWhitelist in
525      *                          certain situations (based on its keyset).
526      * @param userWhitelist set of package manifest names that should be installed on this
527      *                      <b>particular</b> user. This must be consistent with userTypeWhitelist,
528      *                      but is passed in separately to avoid repeatedly calculating it from
529      *                      userTypeWhitelist.
530      * @param implicitlyWhitelist whether non-mentioned packages are implicitly allowlisted.
531      */
532     @VisibleForTesting
shouldInstallPackage(AndroidPackage sysPkg, @NonNull ArrayMap<String, Long> userTypeWhitelist, @NonNull Set<String> userWhitelist, boolean implicitlyWhitelist)533     static boolean shouldInstallPackage(AndroidPackage sysPkg,
534             @NonNull ArrayMap<String, Long> userTypeWhitelist,
535             @NonNull Set<String> userWhitelist, boolean implicitlyWhitelist) {
536         final String pkgName = shouldUseOverlayTargetName(sysPkg) ?
537                 sysPkg.getOverlayTarget() : sysPkg.getManifestPackageName();
538         return (implicitlyWhitelist && !userTypeWhitelist.containsKey(pkgName))
539                 || userWhitelist.contains(pkgName);
540     }
541 
542     /**
543      * Gets the package manifest names that are allowlisted for users of the given user type,
544      * as determined by SystemConfig.
545      */
546     @VisibleForTesting
getWhitelistedPackagesForUserType(String userType)547     @NonNull Set<String> getWhitelistedPackagesForUserType(String userType) {
548         final long userTypeMask = getUserTypeMask(userType);
549         final Set<String> installablePkgs = new ArraySet<>(mWhitelistedPackagesForUserTypes.size());
550         for (int i = 0; i < mWhitelistedPackagesForUserTypes.size(); i++) {
551             final String pkgName = mWhitelistedPackagesForUserTypes.keyAt(i);
552             final long whitelistedUserTypes = mWhitelistedPackagesForUserTypes.valueAt(i);
553             if ((userTypeMask & whitelistedUserTypes) != 0) {
554                 installablePkgs.add(pkgName);
555             }
556         }
557         return installablePkgs;
558     }
559 
560     /**
561      * Set of package manifest names that are included anywhere in the package-to-user-type
562      * allowlist, as determined by SystemConfig.
563      *
564      * Packages that are allowlisted, but then denylisted so that they aren't to be installed on
565      * any user, are still present in this list, since that is a valid scenario (e.g. if an OEM
566      * completely blacklists an AOSP app).
567      */
getWhitelistedSystemPackages()568     private Set<String> getWhitelistedSystemPackages() {
569         return mWhitelistedPackagesForUserTypes.keySet();
570     }
571 
572     /**
573      * Returns a map of package manifest names to the bit set representing (via
574      * {@link #getUserTypeMask}) the user types on which they are to be installed.
575      * Also, clears this data from SystemConfig where it was stored inefficiently (and therefore
576      * should be called exactly once, even if the data isn't useful).
577      *
578      * Any system packages not present in this map should not even be on the device at all.
579      * To enforce this:
580      * <ul>
581      *  <li>Illegal user types are ignored.</li>
582      *  <li>Packages that never allowlisted at all (even if they are explicitly denylisted) are
583      *          ignored.</li>
584      *  <li>Packages that are denylisted whenever they are allowlisted will be stored with the
585      *          value 0 (since this is a valid scenario, e.g. if an OEM completely blacklists an
586      *          AOSP app).</li>
587      * </ul>
588      *
589      * @see #mWhitelistedPackagesForUserTypes
590      */
591     @VisibleForTesting
determineWhitelistedPackagesForUserTypes(SystemConfig sysConfig)592     ArrayMap<String, Long> determineWhitelistedPackagesForUserTypes(SystemConfig sysConfig) {
593         // We first get the list of user types that correspond to FULL, SYSTEM, and PROFILE.
594         final Map<String, Long> baseTypeBitSets = getBaseTypeBitSets();
595 
596         final ArrayMap<String, Set<String>> whitelist =
597                 sysConfig.getAndClearPackageToUserTypeWhitelist();
598         // result maps packageName -> userTypes on which the package should be installed.
599         final ArrayMap<String, Long> result = new ArrayMap<>(whitelist.size() + 1);
600         // First, do the allowlisted user types.
601         for (int i = 0; i < whitelist.size(); i++) {
602             final String pkgName = whitelist.keyAt(i).intern();
603             final long typesBitSet = getTypesBitSet(whitelist.valueAt(i), baseTypeBitSets);
604             if (typesBitSet != 0) {
605                 result.put(pkgName, typesBitSet);
606             }
607         }
608         // Then, un-allowlist any denylisted user types.
609         final ArrayMap<String, Set<String>> blacklist =
610                 sysConfig.getAndClearPackageToUserTypeBlacklist();
611         for (int i = 0; i < blacklist.size(); i++) {
612             final String pkgName = blacklist.keyAt(i).intern();
613             final long nonTypesBitSet = getTypesBitSet(blacklist.valueAt(i), baseTypeBitSets);
614             final Long typesBitSet = result.get(pkgName);
615             if (typesBitSet != null) {
616                 result.put(pkgName, typesBitSet & ~nonTypesBitSet);
617             } else if (nonTypesBitSet != 0) {
618                 // Package was never allowlisted but is validly denylisted.
619                 result.put(pkgName, 0L);
620             }
621         }
622         // Regardless of the whitelists/blacklists, ensure mandatory packages.
623         result.put("android", ~0L);
624         return result;
625     }
626 
627     /**
628      * Returns the bitmask (with exactly one 1) corresponding to the given userType.
629      * Returns 0 if no such userType exists.
630      */
631     @VisibleForTesting
getUserTypeMask(String userType)632     long getUserTypeMask(String userType) {
633         final int userTypeIndex = Arrays.binarySearch(mUserTypes, userType);
634         final long userTypeMask = userTypeIndex >= 0 ? (1 << userTypeIndex) : 0;
635         return userTypeMask;
636     }
637 
638     /**
639      * Returns the mapping from the name of each base type to the bitset (as defined by
640      * {@link #getUserTypeMask}) of user types to which it corresponds (i.e. the base's subtypes).
641      * <p>
642      * E.g. if "android.type.ex" is a FULL user type for which getUserTypeMask() returns (1 << 3),
643      * then getBaseTypeBitSets().get("FULL") will contain true (1) in position 3.
644      */
getBaseTypeBitSets()645     private Map<String, Long> getBaseTypeBitSets() {
646         long typesBitSetFull = 0;
647         long typesBitSetSystem = 0;
648         long typesBitSetProfile = 0;
649         for (int idx = 0; idx < mUserTypes.length; idx++) {
650             if (mUm.isUserTypeSubtypeOfFull(mUserTypes[idx])) {
651                 typesBitSetFull |= (1 << idx);
652             }
653             if (mUm.isUserTypeSubtypeOfSystem(mUserTypes[idx])) {
654                 typesBitSetSystem |= (1 << idx);
655             }
656             if (mUm.isUserTypeSubtypeOfProfile(mUserTypes[idx])) {
657                 typesBitSetProfile |= (1 << idx);
658             }
659         }
660 
661         Map<String, Long> result = new ArrayMap<>(3);
662         result.put("FULL", typesBitSetFull);
663         result.put("SYSTEM", typesBitSetSystem);
664         result.put("PROFILE", typesBitSetProfile);
665         return result;
666     }
667 
668     /**
669      * Converts a list of user types and base types, as used in SystemConfig, to a bit set
670      * representing (via {@link #getUserTypeMask}) user types.
671      *
672      * Returns 0 if userTypes does not contain any valid user or base types.
673      *
674      * @param baseTypeBitSets a map from the base types (FULL/SYSTEM/PROFILE) to their subtypes
675      *                        (represented as a bitset, as defined by {@link #getUserTypeMask}).
676      *                        (This can be created by {@link #getBaseTypeBitSets}.)
677      */
getTypesBitSet(Iterable<String> userTypes, Map<String, Long> baseTypeBitSets)678     private long getTypesBitSet(Iterable<String> userTypes, Map<String, Long> baseTypeBitSets) {
679         long resultBitSet = 0;
680         for (String type : userTypes) {
681             // See if userType is a base type, like FULL.
682             final Long baseTypeBitSet = baseTypeBitSets.get(type);
683             if (baseTypeBitSet != null) {
684                 resultBitSet |= baseTypeBitSet;
685                 continue;
686             }
687             // userType wasn't a base type, so it should be the name of a specific user type.
688             final long userTypeBitSet = getUserTypeMask(type);
689             if (userTypeBitSet != 0) {
690                 resultBitSet |= userTypeBitSet;
691                 continue;
692             }
693             Slog.w(TAG, "SystemConfig contained an invalid user type: " + type);
694         }
695         return resultBitSet;
696     }
697 
698     /** Returns a sorted array consisting of the keyset of the provided map. */
getAndSortKeysFromMap(ArrayMap<String, ?> map)699     private static String[] getAndSortKeysFromMap(ArrayMap<String, ?> map) {
700         final String[] userTypeList = new String[map.size()];
701         for (int i = 0; i < map.size(); i++) {
702             userTypeList[i] = map.keyAt(i);
703         }
704         Arrays.sort(userTypeList);
705         return userTypeList;
706     }
707 
dump(IndentingPrintWriter pw)708     void dump(IndentingPrintWriter pw) {
709         final int mode = getWhitelistMode();
710         pw.println("Whitelisted packages per user type");
711 
712         pw.increaseIndent();
713         pw.print("Mode: ");
714         pw.print(mode);
715         pw.print(isEnforceMode(mode) ? " (enforced)" : "");
716         pw.print(isLogMode(mode) ? " (logged)" : "");
717         pw.print(isImplicitWhitelistMode(mode) ? " (implicit)" : "");
718         pw.print(isIgnoreOtaMode(mode) ? " (ignore OTAs)" : "");
719         pw.println();
720         pw.decreaseIndent();
721 
722         pw.increaseIndent();
723         pw.println("Legend");
724         pw.increaseIndent();
725         for (int idx = 0; idx < mUserTypes.length; idx++) {
726             pw.println(idx + " -> " + mUserTypes[idx]);
727         }
728         pw.decreaseIndent(); pw.decreaseIndent();
729 
730         pw.increaseIndent();
731         final int size = mWhitelistedPackagesForUserTypes.size();
732         if (size == 0) {
733             pw.println("No packages");
734             pw.decreaseIndent();
735             return;
736         }
737         pw.print(size); pw.println(" packages:");
738         pw.increaseIndent();
739         for (int pkgIdx = 0; pkgIdx < size; pkgIdx++) {
740             final String pkgName = mWhitelistedPackagesForUserTypes.keyAt(pkgIdx);
741             pw.print(pkgName); pw.print(": ");
742             final long userTypesBitSet = mWhitelistedPackagesForUserTypes.valueAt(pkgIdx);
743             for (int idx = 0; idx < mUserTypes.length; idx++) {
744                 if ((userTypesBitSet & (1 << idx)) != 0) {
745                     pw.print(idx); pw.print(" ");
746                 }
747             }
748             pw.println();
749         }
750         pw.decreaseIndent(); pw.decreaseIndent();
751 
752         pw.increaseIndent();
753         dumpPackageWhitelistProblems(pw, mode, /* verbose= */ true, /* criticalOnly= */ false);
754         pw.decreaseIndent();
755     }
756 
dumpPackageWhitelistProblems(IndentingPrintWriter pw, @PackageWhitelistMode int mode, boolean verbose, boolean criticalOnly)757     void dumpPackageWhitelistProblems(IndentingPrintWriter pw, @PackageWhitelistMode int mode,
758             boolean verbose, boolean criticalOnly) {
759         // Handle special cases first
760         if (mode == USER_TYPE_PACKAGE_WHITELIST_MODE_NONE) {
761             mode = getWhitelistMode();
762         } else if (mode == USER_TYPE_PACKAGE_WHITELIST_MODE_DEVICE_DEFAULT) {
763             mode = getDeviceDefaultWhitelistMode();
764         }
765         if (criticalOnly) {
766             // Ignore log mode (if set) since log-only issues are not critical.
767             mode &= ~USER_TYPE_PACKAGE_WHITELIST_MODE_LOG;
768         }
769         Slog.v(TAG, "dumpPackageWhitelistProblems(): using mode " + modeToString(mode));
770 
771         final List<String> errors = getPackagesWhitelistErrors(mode);
772         showIssues(pw, verbose, errors, "errors");
773 
774         if (criticalOnly) return;
775 
776         final List<String> warnings = getPackagesWhitelistWarnings();
777         showIssues(pw, verbose, warnings, "warnings");
778     }
779 
showIssues(IndentingPrintWriter pw, boolean verbose, List<String> issues, String issueType)780     private static void showIssues(IndentingPrintWriter pw, boolean verbose, List<String> issues,
781             String issueType) {
782         final int size = issues.size();
783         if (size == 0) {
784             if (verbose) {
785                 pw.print("No "); pw.println(issueType);
786             }
787             return;
788         }
789         if (verbose) {
790             pw.print(size); pw.print(' '); pw.println(issueType);
791             pw.increaseIndent();
792         }
793         for (int i = 0; i < size; i++) {
794             pw.println(issues.get(i));
795         }
796         if (verbose) {
797             pw.decreaseIndent();
798         }
799     }
800 }
801