/*
 * Copyright (C) 2019 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.server.pm;

import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.UserIdInt;
import android.content.pm.PackageManager;
import android.content.pm.PackageManagerInternal;
import android.content.res.Resources;
import android.os.SystemProperties;
import android.os.UserHandle;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.DebugUtils;
import android.util.Slog;

import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.IndentingPrintWriter;
import com.android.server.LocalServices;
import com.android.server.SystemConfig;
import com.android.server.pm.parsing.pkg.AndroidPackage;

import java.io.PrintWriter;
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;

/**
 * Responsible for un/installing system packages based on user type.
 *
 * <p>Uses the SystemConfig's install-in-user-type whitelist;
 * see {@link SystemConfig#getAndClearPackageToUserTypeWhitelist} and
 * {@link SystemConfig#getAndClearPackageToUserTypeBlacklist}.
 *
 * <p>If {@link #isEnforceMode()} is false, then all system packages are always installed for all
 * users. The following applies when it is true.
 *
 * <p>Any package can be in one of three states in the {@code SystemConfig} whitelist
 * <ol>
 *     <li>Explicitly blacklisted for a particular user type</li>
 *     <li>Explicitly whitelisted for a particular user type</li>
 *     <li>Not mentioned at all, for any user type (neither whitelisted nor blacklisted)</li>
 * </ol>
 *
 * <p>Blacklisting always takes precedence - if a package is blacklisted for a particular user,
 * it won't be installed on that type of user (even if it is also whitelisted for that user).
 * Next comes whitelisting - if it is whitelisted for a particular user, it will be installed on
 * that type of user (as long as it isn't blacklisted).
 * Finally, if the package is not mentioned at all (i.e. neither whitelisted nor blacklisted for
 * any user types) in the SystemConfig 'install-in-user-type' lists
 * then:
 * <ul>
 *     <li>If {@link #isImplicitWhitelistMode()}, the package is implicitly treated as whitelisted
 *          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>Packages are only installed/uninstalled by this mechanism when a new user is created or during
 * an update. In the case of updates:<ul>
 *     <li>new packages are (un)installed per the whitelist/blacklist</li>
 *     <li>pre-existing installed blacklisted packages are never uninstalled</li>
 *     <li>pre-existing not-installed whitelisted packages are only installed if the reason why they
 *     had been previously uninstalled was due to UserSystemPackageInstaller</li>
 * </ul>
 *
 * <p><b>NOTE:</b> the {@code SystemConfig} state is only updated on first boot or after a system
 * update. So, to verify changes during development, you can emulate the latter by calling:
 * <pre><code>
 * adb shell setprop persist.pm.mock-upgrade true
 * </code></pre>
 */
class UserSystemPackageInstaller {
    private static final String TAG = "UserManagerService";

    /**
     * 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  - 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 non-whitelisted packages)</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";

    // 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,
            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 {}

    /**
     * Maps system package manifest names to a bitset representing (via {@link #getUserTypeMask})
     * the user types on which they should be initially installed.
     * <p>
     * E.g. if package "pkg1" should be installed on "usertype_d", which is the user type for which
     * {@link #getUserTypeMask}("usertype_d") returns (1 << 3)
     * then mWhitelistedPackagesForUserTypes.get("pkg1") will be a Long whose
     * bit in position 3 will equal 1.
     * <p>
     * Packages that are whitelisted, but then blacklisted so that they aren't to be installed on
     * any user, are purposefully still present in this list.
     */
    private final ArrayMap<String, Long> mWhitelistedPackagesForUserTypes;

    private final UserManagerService mUm;

    /**
     * Alphabetically sorted list of user types.
     * Throughout this class, a long (functioning as a bitset) has its ith bit representing
     * the user type stored in mUserTypes[i].
     * mUserTypes cannot exceed Long.SIZE (since we are using long for our bitset).
     */
    private final String[] mUserTypes;

    UserSystemPackageInstaller(UserManagerService um, ArrayMap<String, UserTypeDetails> userTypes) {
        mUm = um;
        mUserTypes = getAndSortKeysFromMap(userTypes);
        if (mUserTypes.length > Long.SIZE) {
            throw new IllegalArgumentException("Device contains " + userTypes.size()
                    + " user types. However, UserSystemPackageInstaller does not work if there are"
                    + " more than " + Long.SIZE + " user types.");
            // UserSystemPackageInstaller could use a BitSet instead of Long in this case.
            // But, currently, 64 user types is far beyond expectations, so we have not done so.
        }
        mWhitelistedPackagesForUserTypes =
                determineWhitelistedPackagesForUserTypes(SystemConfig.getInstance());
    }

    /** Constructor for testing purposes. */
    @VisibleForTesting
    UserSystemPackageInstaller(UserManagerService ums, ArrayMap<String, Long> whitelist,
            String[] sortedUserTypes) {
        mUm = ums;
        mUserTypes = sortedUserTypes;
        mWhitelistedPackagesForUserTypes = whitelist;
    }

    /**
     * During OTAs and first boot, install/uninstall all system packages for all users based on the
     * user's user type and the SystemConfig whitelist.
     * We do NOT uninstall packages during an OTA though.
     *
     * This is responsible for enforcing the whitelist for pre-existing users (i.e. USER_SYSTEM);
     * enforcement for new users is done when they are created in UserManagerService.createUser().
     *
     * @param preExistingPackages list of packages on the device prior to the upgrade. Cannot be
     *                            null if isUpgrade is true.
     */
    boolean installWhitelistedSystemPackages(boolean isFirstBoot, boolean isUpgrade,
            @Nullable ArraySet<String> preExistingPackages) {
        final int mode = getWhitelistMode();
        checkWhitelistedSystemPackages(mode);
        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]" : "") + (isConsideredUpgrade ? "[upgrade]" : ""));
        final PackageManagerInternal pmInt = LocalServices.getService(PackageManagerInternal.class);
        // Install/uninstall system packages per user.
        for (int userId : mUm.getUserIds()) {
            final Set<String> userWhitelist = getInstallablePackagesForUserId(userId);
            pmInt.forEachPackageSetting(pkgSetting -> {
                AndroidPackage pkg = pkgSetting.pkg;
                if (pkg == null || !pkg.isSystem()) {
                    return;
                }
                final boolean install =
                        (userWhitelist == null || userWhitelist.contains(pkg.getPackageName()))
                                && !pkgSetting.getPkgState().isHiddenUntilInstalled();
                if (pkgSetting.getInstalled(userId) == install
                        || !shouldChangeInstallationState(pkgSetting, install, userId, isFirstBoot,
                                isConsideredUpgrade, preExistingPackages)) {
                    return;
                }
                pkgSetting.setInstalled(install, userId);
                pkgSetting.setUninstallReason(
                        install ? PackageManager.UNINSTALL_REASON_UNKNOWN :
                                PackageManager.UNINSTALL_REASON_USER_TYPE,
                        userId);
                Slog.i(TAG, (install ? "Installed " : "Uninstalled ")
                        + pkg.getPackageName() + " for user " + userId);
            });
        }
        return true;
    }

    /**
     * Returns whether to proceed with install/uninstall for the given package.
     * In particular, do not install a package unless it was only uninstalled due to the user type;
     * and do not uninstall a package if it previously was installed (prior to the OTA).
     *
     * Should be called only within PackageManagerInternal.forEachPackageSetting() since it
     * requires the LP lock.
     *
     * @param preOtaPkgs list of packages on the device prior to the upgrade.
     *                   Cannot be null if isUpgrade is true.
     */
    private static boolean shouldChangeInstallationState(PackageSetting pkgSetting,
                                                         boolean install,
                                                         @UserIdInt int userId,
                                                         boolean isFirstBoot,
                                                         boolean isUpgrade,
                                                         @Nullable ArraySet<String> preOtaPkgs) {
        if (install) {
            // Only proceed with install if we are the only reason why it had been uninstalled.
            return pkgSetting.getUninstallReason(userId)
                    == PackageManager.UNINSTALL_REASON_USER_TYPE;
        } else {
            // Only proceed with uninstall if the package is new to the device.
            return isFirstBoot || (isUpgrade && !preOtaPkgs.contains(pkgSetting.name));
        }
    }

    /**
     * Checks whether the system packages and the mWhitelistedPackagesForUserTypes whitelist are
     * in 1-to-1 correspondence.
     */
    private void checkWhitelistedSystemPackages(@PackageWhitelistMode int mode) {
        if (!isLogMode(mode) && !isEnforceMode(mode)) {
            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)) {
            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:");

        boolean doWtf = !isImplicitWhitelistMode(mode);
        for (int i = 0; i < numberErrors; i++) {
            final String msg = errors.get(i);
            if (doWtf) {
                Slog.wtf(TAG, msg);
            } else {
                Slog.e(TAG, msg);
            }
        }
    }

    /**
     * Gets packages that are listed in the whitelist XML but are not present on the system image.
     */
    @NonNull
    private List<String> getPackagesWhitelistWarnings() {
        final Set<String> allWhitelistedPackages = getWhitelistedSystemPackages();
        final List<String> warnings = new ArrayList<>();
        final PackageManagerInternal pmInt = LocalServices.getService(PackageManagerInternal.class);

        // Check whether all whitelisted packages are indeed on the system.
        final String notPresentFmt = "%s is whitelisted but not present.";
        final String notSystemFmt = "%s is whitelisted and present but not a system package.";
        for (String pkgName : allWhitelistedPackages) {
            final AndroidPackage pkg = pmInt.getPackage(pkgName);
            if (pkg == null) {
                warnings.add(String.format(notPresentFmt, pkgName));
            } else if (!pkg.isSystem()) {
                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))) {
            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!";
        pmInt.forEachPackage(pkg -> {
            if (!pkg.isSystem()) return;
            final String pkgName = pkg.getManifestPackageName();
            if (!allWhitelistedPackages.contains(pkgName)) {
                errors.add(String.format(logMessageFmt, pkgName));
            }
        });

        return errors;
    }

    /** Whether to only install system packages in new users for which they are whitelisted. */
    boolean isEnforceMode() {
        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.
     */
    boolean isLogMode() {
        return isLogMode(getWhitelistMode());
    }

    /**
     * Whether to treat all packages that are not mentioned at all in the whitelist to be implicitly
     * whitelisted for all users.
     */
    boolean isImplicitWhitelistMode() {
        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;
    }

    /** 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;
    }

    /** See {@link #isImplicitWhitelistMode()}. */
    private static boolean isImplicitWhitelistMode(int whitelistMode) {
        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(
                PACKAGE_WHITELIST_MODE_PROP, USER_TYPE_PACKAGE_WHITELIST_MODE_DEVICE_DEFAULT);
        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)}.
     */
    private @Nullable Set<String> getInstallablePackagesForUserId(@UserIdInt int userId) {
        return getInstallablePackagesForUserType(mUm.getUserInfo(userId).userType);
    }

    /**
     * Gets the system package names that should be installed on users of the given user type, as
     * determined by SystemConfig, the whitelist mode, and the apps actually on the device.
     * Names are the {@link PackageParser.Package#packageName}, not necessarily the manifest names.
     *
     * Returns null if all system packages should be installed (due to enforce-mode being off).
     */
    @Nullable Set<String> getInstallablePackagesForUserType(String userType) {
        final int mode = getWhitelistMode();
        if (!isEnforceMode(mode)) {
            return null;
        }
        final boolean implicitlyWhitelist = isImplicitWhitelistMode(mode)
                || (isImplicitWhitelistSystemMode(mode) && mUm.isUserTypeSubtypeOfSystem(userType));
        final Set<String> whitelistedPackages = getWhitelistedPackagesForUserType(userType);

        final Set<String> installPackages = new ArraySet<>();
        final PackageManagerInternal pmInt = LocalServices.getService(PackageManagerInternal.class);
        pmInt.forEachPackage(pkg -> {
            if (!pkg.isSystem()) {
                return;
            }
            if (shouldInstallPackage(pkg, mWhitelistedPackagesForUserTypes,
                    whitelistedPackages, implicitlyWhitelist)) {
                // Although the whitelist uses manifest names, this function returns packageNames.
                installPackages.add(pkg.getPackageName());
            }
        });
        return installPackages;
    }

    /**
     * Returns whether the given system package should be installed on the given user, based on the
     * the given whitelist of system packages.
     *
     * @param sysPkg the system package. Must be a system package; no verification for this is done.
     * @param userTypeWhitelist map of package manifest names to user types on which they should be
     *                          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
     *                      <b>particular</b> user. This must be consistent with userTypeWhitelist,
     *                      but is passed in separately to avoid repeatedly calculating it from
     *                      userTypeWhitelist.
     * @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 implicitlyWhitelist) {
        final String pkgName = sysPkg.getManifestPackageName();
        return (implicitlyWhitelist && !userTypeWhitelist.containsKey(pkgName))
                || userWhitelist.contains(pkgName);
    }

    /**
     * Gets the package manifest names that are whitelisted for users of the given user type,
     * as determined by SystemConfig.
     */
    @VisibleForTesting
    @NonNull Set<String> getWhitelistedPackagesForUserType(String userType) {
        final long userTypeMask = getUserTypeMask(userType);
        final Set<String> installablePkgs = new ArraySet<>(mWhitelistedPackagesForUserTypes.size());
        for (int i = 0; i < mWhitelistedPackagesForUserTypes.size(); i++) {
            final String pkgName = mWhitelistedPackagesForUserTypes.keyAt(i);
            final long whitelistedUserTypes = mWhitelistedPackagesForUserTypes.valueAt(i);
            if ((userTypeMask & whitelistedUserTypes) != 0) {
                installablePkgs.add(pkgName);
            }
        }
        return installablePkgs;
    }

    /**
     * Set of package manifest names that are included anywhere in the package-to-user-type
     * whitelist, as determined by SystemConfig.
     *
     * Packages that are whitelisted, but then blacklisted so that they aren't to be installed on
     * any user, are still present in this list, since that is a valid scenario (e.g. if an OEM
     * completely blacklists an AOSP app).
     */
    private Set<String> getWhitelistedSystemPackages() {
        return mWhitelistedPackagesForUserTypes.keySet();
    }

    /**
     * Returns a map of package manifest names to the bit set representing (via
     * {@link #getUserTypeMask}) the user types on which they are to be installed.
     * Also, clears this data from SystemConfig where it was stored inefficiently (and therefore
     * should be called exactly once, even if the data isn't useful).
     *
     * Any system packages not present in this map should not even be on the device at all.
     * To enforce this:
     * <ul>
     *  <li>Illegal user types are ignored.</li>
     *  <li>Packages that never whitelisted at all (even if they are explicitly blacklisted) are
     *          ignored.</li>
     *  <li>Packages that are blacklisted whenever they are whitelisted will be stored with the
     *          value 0 (since this is a valid scenario, e.g. if an OEM completely blacklists an
     *          AOSP app).</li>
     * </ul>
     *
     * @see #mWhitelistedPackagesForUserTypes
     */
    @VisibleForTesting
    ArrayMap<String, Long> determineWhitelistedPackagesForUserTypes(SystemConfig sysConfig) {
        // We first get the list of user types that correspond to FULL, SYSTEM, and PROFILE.
        final Map<String, Long> baseTypeBitSets = getBaseTypeBitSets();

        final ArrayMap<String, Set<String>> whitelist =
                sysConfig.getAndClearPackageToUserTypeWhitelist();
        // result maps packageName -> userTypes on which the package should be installed.
        final ArrayMap<String, Long> result = new ArrayMap<>(whitelist.size() + 1);
        // First, do the whitelisted user types.
        for (int i = 0; i < whitelist.size(); i++) {
            final String pkgName = whitelist.keyAt(i).intern();
            final long typesBitSet = getTypesBitSet(whitelist.valueAt(i), baseTypeBitSets);
            if (typesBitSet != 0) {
                result.put(pkgName, typesBitSet);
            }
        }
        // Then, un-whitelist any blacklisted user types.
        final ArrayMap<String, Set<String>> blacklist =
                sysConfig.getAndClearPackageToUserTypeBlacklist();
        for (int i = 0; i < blacklist.size(); i++) {
            final String pkgName = blacklist.keyAt(i).intern();
            final long nonTypesBitSet = getTypesBitSet(blacklist.valueAt(i), baseTypeBitSets);
            final Long typesBitSet = result.get(pkgName);
            if (typesBitSet != null) {
                result.put(pkgName, typesBitSet & ~nonTypesBitSet);
            } else if (nonTypesBitSet != 0) {
                // Package was never whitelisted but is validly blacklisted.
                result.put(pkgName, 0L);
            }
        }
        // Regardless of the whitelists/blacklists, ensure mandatory packages.
        result.put("android", ~0L);
        return result;
    }

    /**
     * Returns the bitmask (with exactly one 1) corresponding to the given userType.
     * Returns 0 if no such userType exists.
     */
    @VisibleForTesting
    long getUserTypeMask(String userType) {
        final int userTypeIndex = Arrays.binarySearch(mUserTypes, userType);
        final long userTypeMask = userTypeIndex >= 0 ? (1 << userTypeIndex) : 0;
        return userTypeMask;
    }

    /**
     * Returns the mapping from the name of each base type to the bitset (as defined by
     * {@link #getUserTypeMask}) of user types to which it corresponds (i.e. the base's subtypes).
     * <p>
     * E.g. if "android.type.ex" is a FULL user type for which getUserTypeMask() returns (1 << 3),
     * then getBaseTypeBitSets().get("FULL") will contain true (1) in position 3.
     */
    private Map<String, Long> getBaseTypeBitSets() {
        long typesBitSetFull = 0;
        long typesBitSetSystem = 0;
        long typesBitSetProfile = 0;
        for (int idx = 0; idx < mUserTypes.length; idx++) {
            if (mUm.isUserTypeSubtypeOfFull(mUserTypes[idx])) {
                typesBitSetFull |= (1 << idx);
            }
            if (mUm.isUserTypeSubtypeOfSystem(mUserTypes[idx])) {
                typesBitSetSystem |= (1 << idx);
            }
            if (mUm.isUserTypeSubtypeOfProfile(mUserTypes[idx])) {
                typesBitSetProfile |= (1 << idx);
            }
        }

        Map<String, Long> result = new ArrayMap<>(3);
        result.put("FULL", typesBitSetFull);
        result.put("SYSTEM", typesBitSetSystem);
        result.put("PROFILE", typesBitSetProfile);
        return result;
    }

    /**
     * Converts a list of user types and base types, as used in SystemConfig, to a bit set
     * representing (via {@link #getUserTypeMask}) user types.
     *
     * Returns 0 if userTypes does not contain any valid user or base types.
     *
     * @param baseTypeBitSets a map from the base types (FULL/SYSTEM/PROFILE) to their subtypes
     *                        (represented as a bitset, as defined by {@link #getUserTypeMask}).
     *                        (This can be created by {@link #getBaseTypeBitSets}.)
     */
    private long getTypesBitSet(Iterable<String> userTypes, Map<String, Long> baseTypeBitSets) {
        long resultBitSet = 0;
        for (String type : userTypes) {
            // See if userType is a base type, like FULL.
            final Long baseTypeBitSet = baseTypeBitSets.get(type);
            if (baseTypeBitSet != null) {
                resultBitSet |= baseTypeBitSet;
                continue;
            }
            // userType wasn't a base type, so it should be the name of a specific user type.
            final long userTypeBitSet = getUserTypeMask(type);
            if (userTypeBitSet != 0) {
                resultBitSet |= userTypeBitSet;
                continue;
            }
            Slog.w(TAG, "SystemConfig contained an invalid user type: " + type);
        }
        return resultBitSet;
    }

    /** Returns a sorted array consisting of the keyset of the provided map. */
    private static String[] getAndSortKeysFromMap(ArrayMap<String, ?> map) {
        final String[] userTypeList = new String[map.size()];
        for (int i = 0; i < map.size(); i++) {
            userTypeList[i] = map.keyAt(i);
        }
        Arrays.sort(userTypeList);
        return userTypeList;
    }

    void dump(PrintWriter pw) {
        try (IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "    ")) {
            dumpIndented(ipw);
        }
    }

    private void dumpIndented(IndentingPrintWriter pw) {
        final int mode = getWhitelistMode();
        pw.println("Whitelisted packages per user type");

        pw.increaseIndent();
        pw.print("Mode: ");
        pw.print(mode);
        pw.print(isEnforceMode(mode) ? " (enforced)" : "");
        pw.print(isLogMode(mode) ? " (logged)" : "");
        pw.print(isImplicitWhitelistMode(mode) ? " (implicit)" : "");
        pw.print(isIgnoreOtaMode(mode) ? " (ignore OTAs)" : "");
        pw.println();
        pw.decreaseIndent();

        pw.increaseIndent();
        pw.println("Legend");
        pw.increaseIndent();
        for (int idx = 0; idx < mUserTypes.length; idx++) {
            pw.println(idx + " -> " + mUserTypes[idx]);
        }
        pw.decreaseIndent(); pw.decreaseIndent();

        pw.increaseIndent();
        final int size = mWhitelistedPackagesForUserTypes.size();
        if (size == 0) {
            pw.println("No packages");
            pw.decreaseIndent();
            return;
        }
        pw.print(size); pw.println(" packages:");
        pw.increaseIndent();
        for (int pkgIdx = 0; pkgIdx < size; pkgIdx++) {
            final String pkgName = mWhitelistedPackagesForUserTypes.keyAt(pkgIdx);
            pw.print(pkgName); pw.print(": ");
            final long userTypesBitSet = mWhitelistedPackagesForUserTypes.valueAt(pkgIdx);
            for (int idx = 0; idx < mUserTypes.length; idx++) {
                if ((userTypesBitSet & (1 << idx)) != 0) {
                    pw.print(idx); pw.print(" ");
                }
            }
            pw.println();
        }
        pw.decreaseIndent(); pw.decreaseIndent();

        pw.increaseIndent();
        dumpPackageWhitelistProblems(pw, mode, /* verbose= */ true, /* criticalOnly= */ false);
        pw.decreaseIndent();
    }

    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();
        }
        if (criticalOnly) {
            // Flip-out log mode
            mode &= ~USER_TYPE_PACKAGE_WHITELIST_MODE_LOG;
        }
        Slog.v(TAG, "dumpPackageWhitelistProblems(): using mode " + modeToString(mode));

        final List<String> errors = getPackagesWhitelistErrors(mode);
        showIssues(pw, verbose, errors, "errors");

        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.print("No "); pw.println(issueType);
            }
            return;
        }
        if (verbose) {
            pw.print(size); pw.print(' '); pw.println(issueType);
            pw.increaseIndent();
        }
        for (int i = 0; i < size; i++) {
            pw.println(issues.get(i));
        }
        if (verbose) {
            pw.decreaseIndent();
        }
    }
}
