/*
 * Copyright (C) 2006 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 static android.Manifest.permission.DELETE_PACKAGES;
import static android.Manifest.permission.INSTALL_PACKAGES;
import static android.Manifest.permission.MANAGE_DEVICE_ADMINS;
import static android.Manifest.permission.MANAGE_PROFILE_AND_DEVICE_OWNERS;
import static android.Manifest.permission.READ_EXTERNAL_STORAGE;
import static android.Manifest.permission.REQUEST_DELETE_PACKAGES;
import static android.Manifest.permission.SET_HARMFUL_APP_WARNINGS;
import static android.Manifest.permission.WRITE_EXTERNAL_STORAGE;
import static android.content.Intent.ACTION_MAIN;
import static android.content.Intent.CATEGORY_DEFAULT;
import static android.content.Intent.CATEGORY_HOME;
import static android.content.pm.PackageManager.CERT_INPUT_RAW_X509;
import static android.content.pm.PackageManager.CERT_INPUT_SHA256;
import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED;
import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER;
import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED;
import static android.content.pm.PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
import static android.content.pm.PackageManager.FLAG_PERMISSION_POLICY_FIXED;
import static android.content.pm.PackageManager.FLAG_PERMISSION_REVOKED_COMPAT;
import static android.content.pm.PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_FIXED;
import static android.content.pm.PackageManager.FLAG_PERMISSION_USER_SET;
import static android.content.pm.PackageManager.FLAG_PERMISSION_WHITELIST_INSTALLER;
import static android.content.pm.PackageManager.INSTALL_FAILED_ALREADY_EXISTS;
import static android.content.pm.PackageManager.INSTALL_FAILED_DUPLICATE_PACKAGE;
import static android.content.pm.PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION;
import static android.content.pm.PackageManager.INSTALL_FAILED_INSTANT_APP_INVALID;
import static android.content.pm.PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
import static android.content.pm.PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
import static android.content.pm.PackageManager.INSTALL_FAILED_INVALID_APK;
import static android.content.pm.PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
import static android.content.pm.PackageManager.INSTALL_FAILED_MISSING_SHARED_LIBRARY;
import static android.content.pm.PackageManager.INSTALL_FAILED_PACKAGE_CHANGED;
import static android.content.pm.PackageManager.INSTALL_FAILED_SHARED_USER_INCOMPATIBLE;
import static android.content.pm.PackageManager.INSTALL_FAILED_TEST_ONLY;
import static android.content.pm.PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE;
import static android.content.pm.PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE;
import static android.content.pm.PackageManager.INSTALL_INTERNAL;
import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES;
import static android.content.pm.PackageManager.INSTALL_SUCCEEDED;
import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS;
import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK;
import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK;
import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER;
import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
import static android.content.pm.PackageManager.MATCH_ALL;
import static android.content.pm.PackageManager.MATCH_ANY_USER;
import static android.content.pm.PackageManager.MATCH_APEX;
import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE;
import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
import static android.content.pm.PackageManager.MATCH_DISABLED_COMPONENTS;
import static android.content.pm.PackageManager.MATCH_FACTORY_ONLY;
import static android.content.pm.PackageManager.MATCH_KNOWN_PACKAGES;
import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
import static android.content.pm.PackageManager.MOVE_FAILED_3RD_PARTY_NOT_ALLOWED_ON_INTERNAL;
import static android.content.pm.PackageManager.MOVE_FAILED_DEVICE_ADMIN;
import static android.content.pm.PackageManager.MOVE_FAILED_DOESNT_EXIST;
import static android.content.pm.PackageManager.MOVE_FAILED_INTERNAL_ERROR;
import static android.content.pm.PackageManager.MOVE_FAILED_LOCKED_USER;
import static android.content.pm.PackageManager.MOVE_FAILED_OPERATION_PENDING;
import static android.content.pm.PackageManager.MOVE_FAILED_SYSTEM_PACKAGE;
import static android.content.pm.PackageManager.PERMISSION_DENIED;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
import static android.content.pm.PackageManager.RESTRICTION_NONE;
import static android.content.pm.PackageParser.isApkFile;
import static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER;
import static android.os.incremental.IncrementalManager.isIncrementalPath;
import static android.os.storage.StorageManager.FLAG_STORAGE_CE;
import static android.os.storage.StorageManager.FLAG_STORAGE_DE;
import static android.os.storage.StorageManager.FLAG_STORAGE_EXTERNAL;
import static android.permission.PermissionManager.KILL_APP_REASON_GIDS_CHANGED;

import static com.android.internal.annotations.VisibleForTesting.Visibility;
import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_MANAGED_PROFILE;
import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_PARENT;
import static com.android.internal.content.NativeLibraryHelper.LIB_DIR_NAME;
import static com.android.server.pm.ComponentResolver.RESOLVE_PRIORITY_SORTER;
import static com.android.server.pm.InstructionSets.getAppDexInstructionSets;
import static com.android.server.pm.InstructionSets.getDexCodeInstructionSet;
import static com.android.server.pm.InstructionSets.getDexCodeInstructionSets;
import static com.android.server.pm.InstructionSets.getPreferredInstructionSet;
import static com.android.server.pm.PackageManagerServiceCompilerMapping.getDefaultCompilerFilter;
import static com.android.server.pm.PackageManagerServiceUtils.compareSignatures;
import static com.android.server.pm.PackageManagerServiceUtils.compressedFileExists;
import static com.android.server.pm.PackageManagerServiceUtils.decompressFile;
import static com.android.server.pm.PackageManagerServiceUtils.deriveAbiOverride;
import static com.android.server.pm.PackageManagerServiceUtils.dumpCriticalInfo;
import static com.android.server.pm.PackageManagerServiceUtils.getCompressedFiles;
import static com.android.server.pm.PackageManagerServiceUtils.getLastModifiedTime;
import static com.android.server.pm.PackageManagerServiceUtils.logCriticalInfo;
import static com.android.server.pm.PackageManagerServiceUtils.verifySignatures;

import android.Manifest;
import android.annotation.AppIdInt;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.UserIdInt;
import android.app.ActivityManager;
import android.app.AppOpsManager;
import android.app.BroadcastOptions;
import android.app.IActivityManager;
import android.app.ResourcesManager;
import android.app.admin.IDevicePolicyManager;
import android.app.admin.SecurityLog;
import android.app.backup.IBackupManager;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.Context;
import android.content.IIntentReceiver;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.IntentSender;
import android.content.IntentSender.SendIntentException;
import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
import android.content.pm.AuxiliaryResolveInfo;
import android.content.pm.ChangedPackages;
import android.content.pm.ComponentInfo;
import android.content.pm.FallbackCategoryProvider;
import android.content.pm.FeatureInfo;
import android.content.pm.IDexModuleRegisterCallback;
import android.content.pm.IPackageDataObserver;
import android.content.pm.IPackageDeleteObserver;
import android.content.pm.IPackageDeleteObserver2;
import android.content.pm.IPackageInstallObserver2;
import android.content.pm.IPackageInstaller;
import android.content.pm.IPackageManager;
import android.content.pm.IPackageManagerNative;
import android.content.pm.IPackageMoveObserver;
import android.content.pm.IPackageStatsObserver;
import android.content.pm.InstallSourceInfo;
import android.content.pm.InstantAppInfo;
import android.content.pm.InstantAppRequest;
import android.content.pm.InstrumentationInfo;
import android.content.pm.IntentFilterVerificationInfo;
import android.content.pm.KeySet;
import android.content.pm.ModuleInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageInfoLite;
import android.content.pm.PackageInstaller;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.LegacyPackageDeleteObserver;
import android.content.pm.PackageManager.ModuleInfoFlags;
import android.content.pm.PackageManagerInternal;
import android.content.pm.PackageManagerInternal.PackageListObserver;
import android.content.pm.PackageParser;
import android.content.pm.PackageParser.PackageLite;
import android.content.pm.PackageParser.PackageParserException;
import android.content.pm.PackageParser.ParseFlags;
import android.content.pm.PackageParser.SigningDetails;
import android.content.pm.PackageParser.SigningDetails.SignatureSchemeVersion;
import android.content.pm.PackageStats;
import android.content.pm.PackageUserState;
import android.content.pm.ParceledListSlice;
import android.content.pm.PermissionGroupInfo;
import android.content.pm.PermissionInfo;
import android.content.pm.ProviderInfo;
import android.content.pm.ResolveInfo;
import android.content.pm.SELinuxUtil;
import android.content.pm.ServiceInfo;
import android.content.pm.SharedLibraryInfo;
import android.content.pm.Signature;
import android.content.pm.SuspendDialogInfo;
import android.content.pm.UserInfo;
import android.content.pm.VerifierDeviceIdentity;
import android.content.pm.VerifierInfo;
import android.content.pm.VersionedPackage;
import android.content.pm.dex.ArtManager;
import android.content.pm.dex.DexMetadataHelper;
import android.content.pm.dex.IArtManager;
import android.content.pm.parsing.AndroidPackage;
import android.content.pm.parsing.ApkParseUtils;
import android.content.pm.parsing.ComponentParseUtils.ParsedActivity;
import android.content.pm.parsing.ComponentParseUtils.ParsedActivityIntentInfo;
import android.content.pm.parsing.ComponentParseUtils.ParsedComponent;
import android.content.pm.parsing.ComponentParseUtils.ParsedInstrumentation;
import android.content.pm.parsing.ComponentParseUtils.ParsedPermission;
import android.content.pm.parsing.ComponentParseUtils.ParsedProvider;
import android.content.pm.parsing.ComponentParseUtils.ParsedService;
import android.content.pm.parsing.PackageImpl;
import android.content.pm.parsing.PackageInfoUtils;
import android.content.pm.parsing.ParsedPackage;
import android.content.pm.parsing.library.PackageBackwardCompatibility;
import android.content.res.Resources;
import android.content.rollback.IRollbackManager;
import android.database.ContentObserver;
import android.graphics.Bitmap;
import android.hardware.display.DisplayManager;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Binder;
import android.os.Build;
import android.os.Bundle;
import android.os.Debug;
import android.os.Environment;
import android.os.FileUtils;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
import android.os.Parcel;
import android.os.PatternMatcher;
import android.os.PersistableBundle;
import android.os.Process;
import android.os.RemoteCallbackList;
import android.os.RemoteException;
import android.os.ResultReceiver;
import android.os.SELinux;
import android.os.ServiceManager;
import android.os.ShellCallback;
import android.os.SystemClock;
import android.os.SystemProperties;
import android.os.Trace;
import android.os.UserHandle;
import android.os.UserManager;
import android.os.UserManagerInternal;
import android.os.incremental.IncrementalManager;
import android.os.storage.DiskInfo;
import android.os.storage.IStorageManager;
import android.os.storage.StorageEventListener;
import android.os.storage.StorageManager;
import android.os.storage.StorageManagerInternal;
import android.os.storage.VolumeInfo;
import android.os.storage.VolumeRecord;
import android.permission.IPermissionManager;
import android.provider.DeviceConfig;
import android.provider.MediaStore;
import android.provider.Settings.Global;
import android.provider.Settings.Secure;
import android.security.KeyStore;
import android.security.SystemKeyStore;
import android.service.pm.PackageServiceDumpProto;
import android.stats.storage.StorageEnums;
import android.system.ErrnoException;
import android.system.Os;
import android.text.TextUtils;
import android.text.format.DateUtils;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.Base64;
import android.util.DisplayMetrics;
import android.util.EventLog;
import android.util.ExceptionUtils;
import android.util.IntArray;
import android.util.Log;
import android.util.LogPrinter;
import android.util.LongSparseArray;
import android.util.LongSparseLongArray;
import android.util.MathUtils;
import android.util.PackageUtils;
import android.util.Pair;
import android.util.PrintStreamPrinter;
import android.util.Slog;
import android.util.SparseArray;
import android.util.SparseBooleanArray;
import android.util.SparseIntArray;
import android.util.StatsLog;
import android.util.TimingsTraceLog;
import android.util.Xml;
import android.util.jar.StrictJarFile;
import android.util.proto.ProtoOutputStream;
import android.view.Display;

import com.android.internal.R;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.app.ResolverActivity;
import com.android.internal.content.NativeLibraryHelper;
import com.android.internal.content.PackageHelper;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.os.SomeArgs;
import com.android.internal.os.Zygote;
import com.android.internal.telephony.CarrierAppUtils;
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.ConcurrentUtils;
import com.android.internal.util.DumpUtils;
import com.android.internal.util.FastXmlSerializer;
import com.android.internal.util.IndentingPrintWriter;
import com.android.internal.util.Preconditions;
import com.android.server.AttributeCache;
import com.android.server.DeviceIdleInternal;
import com.android.server.EventLogTags;
import com.android.server.FgThread;
import com.android.server.LocalServices;
import com.android.server.LockGuard;
import com.android.server.PackageWatchdog;
import com.android.server.ServiceThread;
import com.android.server.SystemConfig;
import com.android.server.SystemServerInitThreadPool;
import com.android.server.Watchdog;
import com.android.server.compat.PlatformCompat;
import com.android.server.net.NetworkPolicyManagerInternal;
import com.android.server.pm.Installer.InstallerException;
import com.android.server.pm.Settings.DatabaseVersion;
import com.android.server.pm.Settings.VersionInfo;
import com.android.server.pm.dex.ArtManagerService;
import com.android.server.pm.dex.DexManager;
import com.android.server.pm.dex.DexoptOptions;
import com.android.server.pm.dex.PackageDexUsage;
import com.android.server.pm.dex.ViewCompiler;
import com.android.server.pm.permission.BasePermission;
import com.android.server.pm.permission.PermissionManagerService;
import com.android.server.pm.permission.PermissionManagerServiceInternal;
import com.android.server.pm.permission.PermissionsState;
import com.android.server.policy.PermissionPolicyInternal;
import com.android.server.security.VerityUtils;
import com.android.server.storage.DeviceStorageMonitorInternal;
import com.android.server.utils.TimingsTraceAndSlog;
import com.android.server.wm.ActivityTaskManagerInternal;

import dalvik.system.CloseGuard;
import dalvik.system.VMRuntime;

import libcore.io.IoUtils;
import libcore.util.EmptyArray;
import libcore.util.HexEncoding;

import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlSerializer;

import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileDescriptor;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.PrintWriter;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.nio.charset.StandardCharsets;
import java.security.DigestException;
import java.security.DigestInputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.PublicKey;
import java.security.SecureRandom;
import java.security.cert.CertificateException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.stream.Collectors;

/**
 * Keep track of all those APKs everywhere.
 * <p>
 * Internally there are two important locks:
 * <ul>
 * <li>{@link #mLock} is used to guard all in-memory parsed package details
 * and other related state. It is a fine-grained lock that should only be held
 * momentarily, as it's one of the most contended locks in the system.
 * <li>{@link #mInstallLock} is used to guard all {@code installd} access, whose
 * operations typically involve heavy lifting of application data on disk. Since
 * {@code installd} is single-threaded, and it's operations can often be slow,
 * this lock should never be acquired while already holding {@link #mLock}.
 * Conversely, it's safe to acquire {@link #mLock} momentarily while already
 * holding {@link #mInstallLock}.
 * </ul>
 * Many internal methods rely on the caller to hold the appropriate locks, and
 * this contract is expressed through method name suffixes:
 * <ul>
 * <li>fooLI(): the caller must hold {@link #mInstallLock}
 * <li>fooLIF(): the caller must hold {@link #mInstallLock} and the package
 * being modified must be frozen
 * <li>fooLPr(): the caller must hold {@link #mLock} for reading
 * <li>fooLPw(): the caller must hold {@link #mLock} for writing
 * </ul>
 * <p>
 * Because this class is very central to the platform's security; please run all
 * CTS and unit tests whenever making modifications:
 *
 * <pre>
 * $ runtest -c android.content.pm.PackageManagerTests frameworks-core
 * $ cts-tradefed run commandAndExit cts -m CtsAppSecurityHostTestCases
 * </pre>
 */
public class PackageManagerService extends IPackageManager.Stub
        implements PackageSender {
    static final String TAG = "PackageManager";
    public static final boolean DEBUG_SETTINGS = false;
    static final boolean DEBUG_PREFERRED = false;
    static final boolean DEBUG_UPGRADE = false;
    static final boolean DEBUG_DOMAIN_VERIFICATION = false;
    private static final boolean DEBUG_BACKUP = false;
    public static final boolean DEBUG_INSTALL = false;
    public static final boolean DEBUG_REMOVE = false;
    private static final boolean DEBUG_BROADCASTS = false;
    private static final boolean DEBUG_PACKAGE_INFO = false;
    private static final boolean DEBUG_INTENT_MATCHING = false;
    public static final boolean DEBUG_PACKAGE_SCANNING = false;
    private static final boolean DEBUG_VERIFY = false;
    public static final boolean DEBUG_PERMISSIONS = false;
    private static final boolean DEBUG_SHARED_LIBRARIES = false;
    public static final boolean DEBUG_COMPRESSION = Build.IS_DEBUGGABLE;

    // Debug output for dexopting. This is shared between PackageManagerService, OtaDexoptService
    // and PackageDexOptimizer. All these classes have their own flag to allow switching a single
    // user, but by default initialize to this.
    public static final boolean DEBUG_DEXOPT = false;

    static final boolean DEBUG_ABI_SELECTION = false;
    private static final boolean DEBUG_INSTANT = Build.IS_DEBUGGABLE;
    private static final boolean DEBUG_APP_DATA = false;

    /** REMOVE. According to Svet, this was only used to reset permissions during development. */
    static final boolean CLEAR_RUNTIME_PERMISSIONS_ON_UPGRADE = false;

    private static final boolean HIDE_EPHEMERAL_APIS = false;

    private static final boolean ENABLE_FREE_CACHE_V2 =
            SystemProperties.getBoolean("fw.free_cache_v2", true);

    private static final String PRECOMPILE_LAYOUTS = "pm.precompile_layouts";

    private static final int RADIO_UID = Process.PHONE_UID;
    private static final int LOG_UID = Process.LOG_UID;
    private static final int NFC_UID = Process.NFC_UID;
    private static final int BLUETOOTH_UID = Process.BLUETOOTH_UID;
    private static final int SHELL_UID = Process.SHELL_UID;
    private static final int SE_UID = Process.SE_UID;
    private static final int NETWORKSTACK_UID = Process.NETWORK_STACK_UID;

    static final int SCAN_NO_DEX = 1 << 0;
    static final int SCAN_UPDATE_SIGNATURE = 1 << 1;
    static final int SCAN_NEW_INSTALL = 1 << 2;
    static final int SCAN_UPDATE_TIME = 1 << 3;
    static final int SCAN_BOOTING = 1 << 4;
    static final int SCAN_REQUIRE_KNOWN = 1 << 7;
    static final int SCAN_MOVE = 1 << 8;
    static final int SCAN_INITIAL = 1 << 9;
    static final int SCAN_DONT_KILL_APP = 1 << 10;
    static final int SCAN_IGNORE_FROZEN = 1 << 11;
    static final int SCAN_FIRST_BOOT_OR_UPGRADE = 1 << 12;
    static final int SCAN_AS_INSTANT_APP = 1 << 13;
    static final int SCAN_AS_FULL_APP = 1 << 14;
    static final int SCAN_AS_VIRTUAL_PRELOAD = 1 << 15;
    static final int SCAN_AS_SYSTEM = 1 << 16;
    static final int SCAN_AS_PRIVILEGED = 1 << 17;
    static final int SCAN_AS_OEM = 1 << 18;
    static final int SCAN_AS_VENDOR = 1 << 19;
    static final int SCAN_AS_PRODUCT = 1 << 20;
    static final int SCAN_AS_SYSTEM_EXT = 1 << 21;
    static final int SCAN_AS_ODM = 1 << 22;

    @IntDef(flag = true, prefix = { "SCAN_" }, value = {
            SCAN_NO_DEX,
            SCAN_UPDATE_SIGNATURE,
            SCAN_NEW_INSTALL,
            SCAN_UPDATE_TIME,
            SCAN_BOOTING,
            SCAN_REQUIRE_KNOWN,
            SCAN_MOVE,
            SCAN_INITIAL,
            SCAN_DONT_KILL_APP,
            SCAN_IGNORE_FROZEN,
            SCAN_FIRST_BOOT_OR_UPGRADE,
            SCAN_AS_INSTANT_APP,
            SCAN_AS_FULL_APP,
            SCAN_AS_VIRTUAL_PRELOAD,
    })
    @Retention(RetentionPolicy.SOURCE)
    public @interface ScanFlags {}

    private static final String STATIC_SHARED_LIB_DELIMITER = "_";
    /** Extension of the compressed packages */
    public final static String COMPRESSED_EXTENSION = ".gz";
    /** Suffix of stub packages on the system partition */
    public final static String STUB_SUFFIX = "-Stub";

    private static final int[] EMPTY_INT_ARRAY = new int[0];

    private static final int TYPE_UNKNOWN = 0;
    private static final int TYPE_ACTIVITY = 1;
    private static final int TYPE_RECEIVER = 2;
    private static final int TYPE_SERVICE = 3;
    private static final int TYPE_PROVIDER = 4;
    @IntDef(prefix = { "TYPE_" }, value = {
            TYPE_UNKNOWN,
            TYPE_ACTIVITY,
            TYPE_RECEIVER,
            TYPE_SERVICE,
            TYPE_PROVIDER,
    })
    @Retention(RetentionPolicy.SOURCE)
    public @interface ComponentType {}

    /**
     * Timeout (in milliseconds) after which the watchdog should declare that
     * our handler thread is wedged.  The usual default for such things is one
     * minute but we sometimes do very lengthy I/O operations on this thread,
     * such as installing multi-gigabyte applications, so ours needs to be longer.
     */
    static final long WATCHDOG_TIMEOUT = 1000*60*10;     // ten minutes

    /**
     * Wall-clock timeout (in milliseconds) after which we *require* that an fstrim
     * be run on this device.  We use the value in the Settings.Global.MANDATORY_FSTRIM_INTERVAL
     * settings entry if available, otherwise we use the hardcoded default.  If it's been
     * more than this long since the last fstrim, we force one during the boot sequence.
     *
     * This backstops other fstrim scheduling:  if the device is alive at midnight+idle,
     * one gets run at the next available charging+idle time.  This final mandatory
     * no-fstrim check kicks in only of the other scheduling criteria is never met.
     */
    private static final long DEFAULT_MANDATORY_FSTRIM_INTERVAL = 3 * DateUtils.DAY_IN_MILLIS;

    /**
     * Whether verification is enabled by default.
     */
    private static final boolean DEFAULT_VERIFY_ENABLE = true;

    /**
     * The default maximum time to wait for the verification agent to return in
     * milliseconds.
     */
    private static final long DEFAULT_VERIFICATION_TIMEOUT = 10 * 1000;

    /**
     * Timeout duration in milliseconds for enabling package rollback. If we fail to enable
     * rollback within that period, the install will proceed without rollback enabled.
     *
     * <p>If flag value is negative, the default value will be assigned.
     *
     * Flag type: {@code long}
     * Namespace: NAMESPACE_ROLLBACK
     */
    private static final String PROPERTY_ENABLE_ROLLBACK_TIMEOUT_MILLIS = "enable_rollback_timeout";

    /**
     * The default duration to wait for rollback to be enabled in
     * milliseconds.
     */
    private static final long DEFAULT_ENABLE_ROLLBACK_TIMEOUT_MILLIS = 10 * 1000;

    /**
     * The default response for package verification timeout.
     *
     * This can be either PackageManager.VERIFICATION_ALLOW or
     * PackageManager.VERIFICATION_REJECT.
     */
    private static final int DEFAULT_VERIFICATION_RESPONSE = PackageManager.VERIFICATION_ALLOW;

    public static final String PLATFORM_PACKAGE_NAME = "android";

    private static final String PACKAGE_MIME_TYPE = "application/vnd.android.package-archive";

    private static final String PACKAGE_SCHEME = "package";

    /** Canonical intent used to identify what counts as a "web browser" app */
    private static final Intent sBrowserIntent;
    static {
        sBrowserIntent = new Intent();
        sBrowserIntent.setAction(Intent.ACTION_VIEW);
        sBrowserIntent.addCategory(Intent.CATEGORY_BROWSABLE);
        sBrowserIntent.setData(Uri.parse("http:"));
        sBrowserIntent.addFlags(Intent.FLAG_IGNORE_EPHEMERAL);
    }

    // Compilation reasons.
    public static final int REASON_UNKNOWN = -1;
    public static final int REASON_FIRST_BOOT = 0;
    public static final int REASON_BOOT = 1;
    public static final int REASON_INSTALL = 2;
    public static final int REASON_BACKGROUND_DEXOPT = 3;
    public static final int REASON_AB_OTA = 4;
    public static final int REASON_INACTIVE_PACKAGE_DOWNGRADE = 5;
    public static final int REASON_SHARED = 6;

    public static final int REASON_LAST = REASON_SHARED;

    /**
     * The initial enabled state of the cache before other checks are done.
     */
    private static final boolean DEFAULT_PACKAGE_PARSER_CACHE_ENABLED = true;

    /**
     * Whether to skip all other checks and force the cache to be enabled.
     *
     * Setting this to true will cause the cache to be named "debug" to avoid eviction from
     * build fingerprint changes.
     */
    private static final boolean FORCE_PACKAGE_PARSED_CACHE_ENABLED = false;

    /**
     * Permissions required in order to receive instant application lifecycle broadcasts.
     */
    private static final String[] INSTANT_APP_BROADCAST_PERMISSION =
            new String[] { android.Manifest.permission.ACCESS_INSTANT_APPS };

    final ServiceThread mHandlerThread;

    final PackageHandler mHandler;

    private final ProcessLoggingHandler mProcessLoggingHandler;

    final int mSdkVersion = Build.VERSION.SDK_INT;

    final Context mContext;
    final boolean mFactoryTest;
    final boolean mOnlyCore;
    final DisplayMetrics mMetrics;
    final int mDefParseFlags;
    final String[] mSeparateProcesses;
    final boolean mIsUpgrade;
    final boolean mIsPreNUpgrade;
    final boolean mIsPreNMR1Upgrade;
    final boolean mIsPreQUpgrade;

    @GuardedBy("mLock")
    private boolean mDexOptDialogShown;

    // Used for privilege escalation. MUST NOT BE CALLED WITH mPackages
    // LOCK HELD.  Can be called with mInstallLock held.
    @GuardedBy("mInstallLock")
    final Installer mInstaller;

    /** Directory where installed applications are stored */
    private static final File sAppInstallDir =
            new File(Environment.getDataDirectory(), "app");
    /** Directory where installed application's 32-bit native libraries are copied. */
    @VisibleForTesting
    static final File sAppLib32InstallDir =
            new File(Environment.getDataDirectory(), "app-lib");

    // ----------------------------------------------------------------

    // Lock for state used when installing and doing other long running
    // operations.  Methods that must be called with this lock held have
    // the suffix "LI".
    final Object mInstallLock;

    // ----------------------------------------------------------------

    // Lock for global state used when modifying package state or settings.
    // Methods that must be called with this lock held have
    // the suffix "Locked". Some methods may use the legacy suffix "LP"
    final Object mLock;

    // Keys are String (package name), values are Package.
    @GuardedBy("mLock")
    final ArrayMap<String, AndroidPackage> mPackages = new ArrayMap<>();

    // Keys are isolated uids and values are the uid of the application
    // that created the isolated proccess.
    @GuardedBy("mLock")
    final SparseIntArray mIsolatedOwners = new SparseIntArray();

    /**
     * Tracks new system packages [received in an OTA] that we expect to
     * find updated user-installed versions. Keys are package name, values
     * are package location.
     */
    final private ArrayMap<String, File> mExpectingBetter = new ArrayMap<>();

    /**
     * Tracks existing system packages prior to receiving an OTA. Keys are package name.
     */
    final private ArraySet<String> mExistingSystemPackages = new ArraySet<>();
    /**
     * Whether or not system app permissions should be promoted from install to runtime.
     */
    boolean mPromoteSystemApps;

    private final PackageManagerInternal mPmInternal;


    @GuardedBy("mLock")
    final Settings mSettings;

    /**
     * Set of package names that are currently "frozen", which means active
     * surgery is being done on the code/data for that package. The platform
     * will refuse to launch frozen packages to avoid race conditions.
     *
     * @see PackageFreezer
     */
    @GuardedBy("mLock")
    final ArraySet<String> mFrozenPackages = new ArraySet<>();

    final ProtectedPackages mProtectedPackages;

    @GuardedBy("mLoadedVolumes")
    final ArraySet<String> mLoadedVolumes = new ArraySet<>();

    boolean mFirstBoot;

    PackageManagerInternal.ExternalSourcesPolicy mExternalSourcesPolicy;

    @GuardedBy("mAvailableFeatures")
    final ArrayMap<String, FeatureInfo> mAvailableFeatures;

    private final InstantAppRegistry mInstantAppRegistry;

    @GuardedBy("mLock")
    int mChangedPackagesSequenceNumber;
    /**
     * List of changed [installed, removed or updated] packages.
     * mapping from user id -> sequence number -> package name
     */
    @GuardedBy("mLock")
    final SparseArray<SparseArray<String>> mChangedPackages = new SparseArray<>();
    /**
     * The sequence number of the last change to a package.
     * mapping from user id -> package name -> sequence number
     */
    @GuardedBy("mLock")
    final SparseArray<Map<String, Integer>> mChangedPackagesSequenceNumbers = new SparseArray<>();

    @GuardedBy("mLock")
    final private ArraySet<PackageListObserver> mPackageListObservers = new ArraySet<>();

    @GuardedBy("mLock")
    private final SparseIntArray mDefaultPermissionsGrantedUsers = new SparseIntArray();

    private final ModuleInfoProvider mModuleInfoProvider;

    private final ApexManager mApexManager;

    private final Injector mInjector;

    /**
     * The list of all system partitions that may contain packages in ascending order of
     * specificity (the more generic, the earlier in the list a partition appears).
     */
    @VisibleForTesting(visibility = Visibility.PRIVATE)
    public static final List<SystemPartition> SYSTEM_PARTITIONS = Collections.unmodifiableList(
            Arrays.asList(
                    new SystemPartition(Environment.getRootDirectory(), 0 /* scanFlag */,
                            false /* hasOverlays */),
                    new SystemPartition(Environment.getVendorDirectory(), SCAN_AS_VENDOR,
                            true /* hasOverlays */),
                    new SystemPartition(Environment.getOdmDirectory(), SCAN_AS_ODM,
                            true /* hasOverlays */),
                    new SystemPartition(Environment.getOemDirectory(), SCAN_AS_OEM,
                            true /* hasOverlays */),
                    new SystemPartition(Environment.getProductDirectory(), SCAN_AS_PRODUCT,
                            true /* hasOverlays */),
                    new SystemPartition(Environment.getSystemExtDirectory(), SCAN_AS_SYSTEM_EXT,
                            true /* hasOverlays */)));

    private final List<SystemPartition> mDirsToScanAsSystem;

    /**
     * Unit tests will instantiate, extend and/or mock to mock dependencies / behaviors.
     *
     * NOTE: All getters should return the same instance for every call.
     */
    @VisibleForTesting(visibility = Visibility.PRIVATE)
    public static class Injector {

        @VisibleForTesting(visibility = Visibility.PRIVATE)
        interface Producer<T> {
            /** Produce an instance of type {@link T} */
            T produce(Injector injector, PackageManagerService packageManager);
        }

        static class LocalServicesProducer<T> implements Producer<T> {
            private final Class<T> mProducingClass;
            LocalServicesProducer(Class<T> clazz) {
                this.mProducingClass = clazz;
            }
            public T produce(Injector injector, PackageManagerService packageManager) {
                return LocalServices.getService(mProducingClass);
            }
        }

        static class SystemServiceProducer<T> implements Producer<T> {
            private final Class<T> mProducingClass;
            SystemServiceProducer(Class<T> clazz) {
                this.mProducingClass = clazz;
            }
            public T produce(Injector injector, PackageManagerService packageManager) {
                return packageManager.mContext.getSystemService(mProducingClass);
            }
        }

        @VisibleForTesting(visibility = Visibility.PRIVATE)
        static class Singleton<T> {
            private final Producer<T> mProducer;
            private volatile T mInstance = null;
            Singleton(Producer<T> producer) {
                this.mProducer = producer;
            }
            T get(Injector injector, PackageManagerService packageManagerService) {
                if (mInstance == null) {
                    mInstance = mProducer.produce(injector, packageManagerService);
                }
                return mInstance;
            }
        }

        private PackageManagerService mPackageManager;

        private final PackageAbiHelper mAbiHelper;
        private final Context mContext;
        private final Object mLock;
        private final Installer mInstaller;
        private final Object mInstallLock;

        // ----- producers -----
        private final Singleton<ComponentResolver> mComponentResolverProducer;
        private final Singleton<PermissionManagerServiceInternal> mPermissionManagerProducer;
        private final Singleton<UserManagerService> mUserManagerProducer;
        private final Singleton<Settings> mSettingsProducer;
        private final Singleton<ActivityTaskManagerInternal> mActivityTaskManagerProducer;
        private final Singleton<DeviceIdleInternal> mLocalDeviceIdleController;
        private final Singleton<StorageManagerInternal> mStorageManagerInternalProducer;
        private final Singleton<NetworkPolicyManagerInternal> mNetworkPolicyManagerProducer;
        private final Singleton<PermissionPolicyInternal> mPermissionPolicyProducer;
        private final Singleton<DeviceStorageMonitorInternal> mDeviceStorageMonitorProducer;
        private final Singleton<DisplayManager> mDisplayManagerProducer;
        private final Singleton<StorageManager> mStorageManagerProducer;
        private final Singleton<AppOpsManager> mAppOpsManagerProducer;
        private final Singleton<AppsFilter> mAppsFilterProducer;
        private final Singleton<PlatformCompat> mPlatformCompatProducer;

        Injector(Context context, Object lock, Installer installer,
                Object installLock, PackageAbiHelper abiHelper,
                Producer<ComponentResolver> componentResolverProducer,
                Producer<PermissionManagerServiceInternal> permissionManagerProducer,
                Producer<UserManagerService> userManagerProducer,
                Producer<Settings> settingsProducer,
                Producer<ActivityTaskManagerInternal> activityTaskManagerProducer,
                Producer<DeviceIdleInternal> deviceIdleControllerProducer,
                Producer<StorageManagerInternal> storageManagerInternalProducer,
                Producer<NetworkPolicyManagerInternal> networkPolicyManagerProducer,
                Producer<PermissionPolicyInternal> permissionPolicyProvider,
                Producer<DeviceStorageMonitorInternal> deviceStorageMonitorProducer,
                Producer<DisplayManager> displayManagerProducer,
                Producer<StorageManager> storageManagerProducer,
                Producer<AppOpsManager> appOpsManagerProducer,
                Producer<AppsFilter> appsFilterProducer,
                Producer<PlatformCompat> platformCompatProducer) {
            mContext = context;
            mLock = lock;
            mInstaller = installer;
            mAbiHelper = abiHelper;
            mInstallLock = installLock;
            mComponentResolverProducer = new Singleton<>(componentResolverProducer);
            mPermissionManagerProducer = new Singleton<>(permissionManagerProducer);
            mUserManagerProducer = new Singleton<>(userManagerProducer);
            mSettingsProducer = new Singleton<>(settingsProducer);
            mActivityTaskManagerProducer = new Singleton<>(activityTaskManagerProducer);
            mLocalDeviceIdleController = new Singleton<>(deviceIdleControllerProducer);
            mStorageManagerInternalProducer = new Singleton<>(storageManagerInternalProducer);
            mNetworkPolicyManagerProducer = new Singleton<>(networkPolicyManagerProducer);
            mPermissionPolicyProducer = new Singleton<>(permissionPolicyProvider);
            mDeviceStorageMonitorProducer = new Singleton<>(deviceStorageMonitorProducer);
            mDisplayManagerProducer = new Singleton<>(displayManagerProducer);
            mStorageManagerProducer = new Singleton<>(storageManagerProducer);
            mAppOpsManagerProducer = new Singleton<>(appOpsManagerProducer);
            mAppsFilterProducer = new Singleton<>(appsFilterProducer);
            mPlatformCompatProducer = new Singleton<>(platformCompatProducer);
        }

        /**
         * Bootstraps this injector with the {@link PackageManagerService instance to which it
         * belongs.
         */
        public void bootstrap(PackageManagerService pm) {
            this.mPackageManager = pm;
        }

        public UserManagerInternal getUserManagerInternal() {
            return getUserManagerService().getInternalForInjectorOnly();
        }

        public PackageAbiHelper getAbiHelper() {
            return mAbiHelper;
        }

        public Object getInstallLock() {
            return mInstallLock;
        }

        public UserManagerService getUserManagerService() {
            return mUserManagerProducer.get(this, mPackageManager);
        }

        public Object getLock() {
            return mLock;
        }

        public Installer getInstaller() {
            return mInstaller;
        }

        public ComponentResolver getComponentResolver() {
            return mComponentResolverProducer.get(this, mPackageManager);
        }

        public PermissionManagerServiceInternal getPermissionManagerServiceInternal() {
            return mPermissionManagerProducer.get(this, mPackageManager);
        }

        public Context getContext() {
            return mContext;
        }

        public Settings getSettings() {
            return mSettingsProducer.get(this, mPackageManager);
        }

        public ActivityTaskManagerInternal getActivityTaskManagerInternal() {
            return mActivityTaskManagerProducer.get(this, mPackageManager);
        }

        public DeviceIdleInternal getLocalDeviceIdleController() {
            return mLocalDeviceIdleController.get(this, mPackageManager);
        }

        public StorageManagerInternal getStorageManagerInternal() {
            return mStorageManagerInternalProducer.get(this, mPackageManager);
        }

        public NetworkPolicyManagerInternal getNetworkPolicyManagerInternal() {
            return mNetworkPolicyManagerProducer.get(this, mPackageManager);
        }

        public PermissionPolicyInternal getPermissionPolicyInternal() {
            return mPermissionPolicyProducer.get(this, mPackageManager);
        }

        public DeviceStorageMonitorInternal getDeviceStorageMonitorInternal() {
            return mDeviceStorageMonitorProducer.get(this, mPackageManager);
        }

        public DisplayManager getDisplayManager() {
            return mDisplayManagerProducer.get(this, mPackageManager);
        }

        public StorageManager getStorageManager() {
            return mStorageManagerProducer.get(this, mPackageManager);
        }

        public AppOpsManager getAppOpsManager() {
            return mAppOpsManagerProducer.get(this, mPackageManager);
        }

        public AppsFilter getAppsFilter() {
            return mAppsFilterProducer.get(this, mPackageManager);
        }

        public PlatformCompat getCompatibility() {
            return mPlatformCompatProducer.get(this, mPackageManager);
        }
    }

    private final AppsFilter mAppsFilter;

    class PackageParserCallback implements PackageParser.Callback {
        @Override public final boolean hasFeature(String feature) {
            return PackageManagerService.this.hasSystemFeature(feature, 0);
        }
    }

    final PackageParser.Callback mPackageParserCallback = new PackageParserCallback();

    // Currently known shared libraries.
    final ArrayMap<String, LongSparseArray<SharedLibraryInfo>> mSharedLibraries = new ArrayMap<>();
    final ArrayMap<String, LongSparseArray<SharedLibraryInfo>> mStaticLibsByDeclaringPackage =
            new ArrayMap<>();

    // Mapping from instrumentation class names to info about them.
    final ArrayMap<ComponentName, ParsedInstrumentation> mInstrumentation =
            new ArrayMap<>();

    // Packages whose data we have transfered into another package, thus
    // should no longer exist.
    final ArraySet<String> mTransferredPackages = new ArraySet<>();

    // Broadcast actions that are only available to the system.
    @GuardedBy("mProtectedBroadcasts")
    final ArraySet<String> mProtectedBroadcasts = new ArraySet<>();

    /** List of packages waiting for verification. */
    final SparseArray<PackageVerificationState> mPendingVerification = new SparseArray<>();

    /** List of packages waiting for rollback to be enabled. */
    final SparseArray<InstallParams> mPendingEnableRollback = new SparseArray<>();

    final PackageInstallerService mInstallerService;

    final ArtManagerService mArtManagerService;

    private final PackageDexOptimizer mPackageDexOptimizer;
    // DexManager handles the usage of dex files (e.g. secondary files, whether or not a package
    // is used by other apps).
    private final DexManager mDexManager;

    private final ViewCompiler mViewCompiler;

    private AtomicInteger mNextMoveId = new AtomicInteger();
    private final MoveCallbacks mMoveCallbacks;

    // Cache of users who need badging.
    private final SparseBooleanArray mUserNeedsBadging = new SparseBooleanArray();

    /** Token for keys in mPendingVerification. */
    private int mPendingVerificationToken = 0;

    /** Token for keys in mPendingEnableRollback. */
    private int mPendingEnableRollbackToken = 0;

    volatile boolean mSystemReady;
    volatile boolean mSafeMode;
    volatile boolean mHasSystemUidErrors;
    private volatile SparseBooleanArray mWebInstantAppsDisabled = new SparseBooleanArray();

    ApplicationInfo mAndroidApplication;
    final ActivityInfo mResolveActivity = new ActivityInfo();
    final ResolveInfo mResolveInfo = new ResolveInfo();
    ComponentName mResolveComponentName;
    AndroidPackage mPlatformPackage;
    ComponentName mCustomResolverComponentName;

    boolean mResolverReplaced = false;

    private final @Nullable ComponentName mIntentFilterVerifierComponent;
    private final @Nullable IntentFilterVerifier<ParsedActivityIntentInfo> mIntentFilterVerifier;

    private int mIntentFilterVerificationToken = 0;

    /** The service connection to the ephemeral resolver */
    final InstantAppResolverConnection mInstantAppResolverConnection;
    /** Component used to show resolver settings for Instant Apps */
    final ComponentName mInstantAppResolverSettingsComponent;

    /** Activity used to install instant applications */
    ActivityInfo mInstantAppInstallerActivity;
    final ResolveInfo mInstantAppInstallerInfo = new ResolveInfo();

    private final Map<String, Pair<PackageInstalledInfo, IPackageInstallObserver2>>
            mNoKillInstallObservers = Collections.synchronizedMap(new HashMap<>());

    final SparseArray<IntentFilterVerificationState> mIntentFilterVerificationStates
            = new SparseArray<>();

    // Internal interface for permission manager
    private final PermissionManagerServiceInternal mPermissionManager;
    // Public interface for permission manager
    private final IPermissionManager mPermissionManagerService;

    private final ComponentResolver mComponentResolver;
    // List of packages names to keep cached, even if they are uninstalled for all users
    private List<String> mKeepUninstalledPackages;

    private File mCacheDir;

    private Future<?> mPrepareAppDataFuture;

    private final IncrementalManager mIncrementalManager;

    private static class IFVerificationParams {
        String packageName;
        boolean hasDomainUrls;
        List<ParsedActivity> activities;
        boolean replacing;
        int userId;
        int verifierUid;

        public IFVerificationParams(String packageName, boolean hasDomainUrls,
                List<ParsedActivity> activities, boolean _replacing,
                int _userId, int _verifierUid) {
            this.packageName = packageName;
            this.hasDomainUrls = hasDomainUrls;
            this.activities = activities;
            replacing = _replacing;
            userId = _userId;
            verifierUid = _verifierUid;
        }
    }

    private interface IntentFilterVerifier<T extends IntentFilter> {
        boolean addOneIntentFilterVerification(int verifierId, int userId, int verificationId,
                                               T filter, String packageName);
        void startVerifications(int userId);
        void receiveVerificationResponse(int verificationId);
    }

    private class IntentVerifierProxy implements IntentFilterVerifier<ParsedActivityIntentInfo> {
        private Context mContext;
        private ComponentName mIntentFilterVerifierComponent;
        private ArrayList<Integer> mCurrentIntentFilterVerifications = new ArrayList<>();

        public IntentVerifierProxy(Context context, ComponentName verifierComponent) {
            mContext = context;
            mIntentFilterVerifierComponent = verifierComponent;
        }

        private String getDefaultScheme() {
            return IntentFilter.SCHEME_HTTPS;
        }

        @Override
        public void startVerifications(int userId) {
            // Launch verifications requests
            int count = mCurrentIntentFilterVerifications.size();
            for (int n=0; n<count; n++) {
                int verificationId = mCurrentIntentFilterVerifications.get(n);
                final IntentFilterVerificationState ivs =
                        mIntentFilterVerificationStates.get(verificationId);

                String packageName = ivs.getPackageName();

                ArrayList<ParsedActivityIntentInfo> filters = ivs.getFilters();
                final int filterCount = filters.size();
                ArraySet<String> domainsSet = new ArraySet<>();
                for (int m=0; m<filterCount; m++) {
                    ParsedActivityIntentInfo filter = filters.get(m);
                    domainsSet.addAll(filter.getHostsList());
                }
                synchronized (mLock) {
                    if (mSettings.createIntentFilterVerificationIfNeededLPw(
                            packageName, domainsSet) != null) {
                        scheduleWriteSettingsLocked();
                    }
                }
                sendVerificationRequest(verificationId, ivs);
            }
            mCurrentIntentFilterVerifications.clear();
        }

        private void sendVerificationRequest(int verificationId, IntentFilterVerificationState ivs) {
            Intent verificationIntent = new Intent(Intent.ACTION_INTENT_FILTER_NEEDS_VERIFICATION);
            verificationIntent.putExtra(
                    PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_ID,
                    verificationId);
            verificationIntent.putExtra(
                    PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_URI_SCHEME,
                    getDefaultScheme());
            verificationIntent.putExtra(
                    PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_HOSTS,
                    ivs.getHostsString());
            verificationIntent.putExtra(
                    PackageManager.EXTRA_INTENT_FILTER_VERIFICATION_PACKAGE_NAME,
                    ivs.getPackageName());
            verificationIntent.setComponent(mIntentFilterVerifierComponent);
            verificationIntent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);

            final long whitelistTimeout = getVerificationTimeout();
            final BroadcastOptions options = BroadcastOptions.makeBasic();
            options.setTemporaryAppWhitelistDuration(whitelistTimeout);

            DeviceIdleInternal idleController =
                    mInjector.getLocalDeviceIdleController();
            idleController.addPowerSaveTempWhitelistApp(Process.myUid(),
                    mIntentFilterVerifierComponent.getPackageName(), whitelistTimeout,
                    UserHandle.USER_SYSTEM, true, "intent filter verifier");

            mContext.sendBroadcastAsUser(verificationIntent, UserHandle.SYSTEM,
                    null, options.toBundle());
            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
                    "Sending IntentFilter verification broadcast");
        }

        public void receiveVerificationResponse(int verificationId) {
            IntentFilterVerificationState ivs = mIntentFilterVerificationStates.get(verificationId);

            final boolean verified = ivs.isVerified();

            ArrayList<ParsedActivityIntentInfo> filters = ivs.getFilters();
            final int count = filters.size();
            if (DEBUG_DOMAIN_VERIFICATION) {
                Slog.i(TAG, "Received verification response " + verificationId
                        + " for " + count + " filters, verified=" + verified);
            }
            for (int n=0; n<count; n++) {
                ParsedActivityIntentInfo filter = filters.get(n);
                filter.setVerified(verified);

                if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "IntentFilter " + filter.toString()
                        + " verified with result:" + verified + " and hosts:"
                        + ivs.getHostsString());
            }

            mIntentFilterVerificationStates.remove(verificationId);

            final String packageName = ivs.getPackageName();
            IntentFilterVerificationInfo ivi;

            synchronized (mLock) {
                ivi = mSettings.getIntentFilterVerificationLPr(packageName);
            }
            if (ivi == null) {
                Slog.w(TAG, "IntentFilterVerificationInfo not found for verificationId:"
                        + verificationId + " packageName:" + packageName);
                return;
            }

            synchronized (mLock) {
                if (verified) {
                    ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS);
                } else {
                    ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK);
                }
                scheduleWriteSettingsLocked();

                final int userId = ivs.getUserId();
                if (userId != UserHandle.USER_ALL) {
                    final int userStatus =
                            mSettings.getIntentFilterVerificationStatusLPr(packageName, userId);

                    int updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
                    boolean needUpdate = false;

                    if (DEBUG_DOMAIN_VERIFICATION) {
                        Slog.d(TAG,
                                "Updating IntentFilterVerificationInfo for package " + packageName
                                + " verificationId:" + verificationId
                                + " verified=" + verified);
                    }

                    // In a success case, we promote from undefined or ASK to ALWAYS.  This
                    // supports a flow where the app fails validation but then ships an updated
                    // APK that passes, and therefore deserves to be in ALWAYS.
                    //
                    // If validation failed, the undefined state winds up in the basic ASK behavior,
                    // but apps that previously passed and became ALWAYS are *demoted* out of
                    // that state, since they would not deserve the ALWAYS behavior in case of a
                    // clean install.
                    switch (userStatus) {
                        case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS:
                            if (!verified) {
                                // Don't demote if sysconfig says 'always'
                                SystemConfig systemConfig = SystemConfig.getInstance();
                                ArraySet<String> packages = systemConfig.getLinkedApps();
                                if (!packages.contains(packageName)) {
                                    // updatedStatus is already UNDEFINED
                                    needUpdate = true;

                                    if (DEBUG_DOMAIN_VERIFICATION) {
                                        Slog.d(TAG, "Formerly validated but now failing; demoting");
                                    }
                                } else {
                                    if (DEBUG_DOMAIN_VERIFICATION) {
                                        Slog.d(TAG, "Updating bundled package " + packageName
                                                + " failed autoVerify, but sysconfig supersedes");
                                    }
                                    // leave needUpdate == false here intentionally
                                }
                            }
                            break;

                        case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED:
                            // Stay in 'undefined' on verification failure
                            if (verified) {
                                updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS;
                            }
                            needUpdate = true;
                            if (DEBUG_DOMAIN_VERIFICATION) {
                                Slog.d(TAG, "Applying update; old=" + userStatus
                                        + " new=" + updatedStatus);
                            }
                            break;

                        case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK:
                            // Keep in 'ask' on failure
                            if (verified) {
                                updatedStatus = INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS;
                                needUpdate = true;
                            }
                            break;

                        default:
                            // Nothing to do
                    }

                    if (needUpdate) {
                        mSettings.updateIntentFilterVerificationStatusLPw(
                                packageName, updatedStatus, userId);
                        scheduleWritePackageRestrictionsLocked(userId);
                    }
                } else {
                    Slog.i(TAG, "autoVerify ignored when installing for all users");
                }
            }
        }

        @Override
        public boolean addOneIntentFilterVerification(int verifierUid, int userId, int verificationId,
                ParsedActivityIntentInfo filter, String packageName) {
            if (!hasValidDomains(filter)) {
                return false;
            }
            IntentFilterVerificationState ivs = mIntentFilterVerificationStates.get(verificationId);
            if (ivs == null) {
                ivs = createDomainVerificationState(verifierUid, userId, verificationId,
                        packageName);
            }
            if (DEBUG_DOMAIN_VERIFICATION) {
                Slog.d(TAG, "Adding verification filter for " + packageName + ": " + filter);
            }
            ivs.addFilter(filter);
            return true;
        }

        private IntentFilterVerificationState createDomainVerificationState(int verifierUid,
                int userId, int verificationId, String packageName) {
            IntentFilterVerificationState ivs = new IntentFilterVerificationState(
                    verifierUid, userId, packageName);
            ivs.setPendingState();
            synchronized (mLock) {
                mIntentFilterVerificationStates.append(verificationId, ivs);
                mCurrentIntentFilterVerifications.add(verificationId);
            }
            return ivs;
        }
    }

    private static boolean hasValidDomains(ParsedActivityIntentInfo filter) {
        return filter.hasCategory(Intent.CATEGORY_BROWSABLE)
                && (filter.hasDataScheme(IntentFilter.SCHEME_HTTP) ||
                        filter.hasDataScheme(IntentFilter.SCHEME_HTTPS));
    }

    // Set of pending broadcasts for aggregating enable/disable of components.
    static class PendingPackageBroadcasts {
        // for each user id, a map of <package name -> components within that package>
        final SparseArray<ArrayMap<String, ArrayList<String>>> mUidMap;

        public PendingPackageBroadcasts() {
            mUidMap = new SparseArray<>(2);
        }

        public ArrayList<String> get(int userId, String packageName) {
            ArrayMap<String, ArrayList<String>> packages = getOrAllocate(userId);
            return packages.get(packageName);
        }

        public void put(int userId, String packageName, ArrayList<String> components) {
            ArrayMap<String, ArrayList<String>> packages = getOrAllocate(userId);
            packages.put(packageName, components);
        }

        public void remove(int userId, String packageName) {
            ArrayMap<String, ArrayList<String>> packages = mUidMap.get(userId);
            if (packages != null) {
                packages.remove(packageName);
            }
        }

        public void remove(int userId) {
            mUidMap.remove(userId);
        }

        public int userIdCount() {
            return mUidMap.size();
        }

        public int userIdAt(int n) {
            return mUidMap.keyAt(n);
        }

        public ArrayMap<String, ArrayList<String>> packagesForUserId(int userId) {
            return mUidMap.get(userId);
        }

        public int size() {
            // total number of pending broadcast entries across all userIds
            int num = 0;
            for (int i = 0; i< mUidMap.size(); i++) {
                num += mUidMap.valueAt(i).size();
            }
            return num;
        }

        public void clear() {
            mUidMap.clear();
        }

        private ArrayMap<String, ArrayList<String>> getOrAllocate(int userId) {
            ArrayMap<String, ArrayList<String>> map = mUidMap.get(userId);
            if (map == null) {
                map = new ArrayMap<>();
                mUidMap.put(userId, map);
            }
            return map;
        }
    }
    final PendingPackageBroadcasts mPendingBroadcasts = new PendingPackageBroadcasts();

    static final int SEND_PENDING_BROADCAST = 1;
    static final int INIT_COPY = 5;
    static final int POST_INSTALL = 9;
    static final int WRITE_SETTINGS = 13;
    static final int WRITE_PACKAGE_RESTRICTIONS = 14;
    static final int PACKAGE_VERIFIED = 15;
    static final int CHECK_PENDING_VERIFICATION = 16;
    static final int START_INTENT_FILTER_VERIFICATIONS = 17;
    static final int INTENT_FILTER_VERIFIED = 18;
    static final int WRITE_PACKAGE_LIST = 19;
    static final int INSTANT_APP_RESOLUTION_PHASE_TWO = 20;
    static final int ENABLE_ROLLBACK_STATUS = 21;
    static final int ENABLE_ROLLBACK_TIMEOUT = 22;
    static final int DEFERRED_NO_KILL_POST_DELETE = 23;
    static final int DEFERRED_NO_KILL_INSTALL_OBSERVER = 24;
    static final int INTEGRITY_VERIFICATION_COMPLETE = 25;

    static final int DEFERRED_NO_KILL_POST_DELETE_DELAY_MS = 3 * 1000;
    static final int DEFERRED_NO_KILL_INSTALL_OBSERVER_DELAY_MS = 500;

    static final int WRITE_SETTINGS_DELAY = 10*1000;  // 10 seconds

    private static final long BROADCAST_DELAY_DURING_STARTUP = 10 * 1000L; // 10 seconds (in millis)
    private static final long BROADCAST_DELAY = 1 * 1000L; // 1 second (in millis)

    // When the service constructor finished plus a delay (used for broadcast delay computation)
    private long mServiceStartWithDelay;

    private static final long DEFAULT_UNUSED_STATIC_SHARED_LIB_MIN_CACHE_PERIOD =
            2 * 60 * 60 * 1000L; /* two hours */

    UserManagerService mUserManager;

    // Stores a list of users whose package restrictions file needs to be updated
    private ArraySet<Integer> mDirtyUsers = new ArraySet<>();

    // Recordkeeping of restore-after-install operations that are currently in flight
    // between the Package Manager and the Backup Manager
    static class PostInstallData {
        public final InstallArgs args;
        public final PackageInstalledInfo res;
        public final Runnable mPostInstallRunnable;

        PostInstallData(InstallArgs _a, PackageInstalledInfo _r, Runnable postInstallRunnable) {
            args = _a;
            res = _r;
            mPostInstallRunnable = postInstallRunnable;
        }
    }

    final SparseArray<PostInstallData> mRunningInstalls = new SparseArray<>();
    int mNextInstallToken = 1;  // nonzero; will be wrapped back to 1 when ++ overflows

    // XML tags for backup/restore of various bits of state
    private static final String TAG_PREFERRED_BACKUP = "pa";
    private static final String TAG_DEFAULT_APPS = "da";
    private static final String TAG_INTENT_FILTER_VERIFICATION = "iv";

    private static final String TAG_PERMISSION_BACKUP = "perm-grant-backup";
    private static final String TAG_ALL_GRANTS = "rt-grants";
    private static final String TAG_GRANT = "grant";
    private static final String ATTR_PACKAGE_NAME = "pkg";

    private static final String TAG_PERMISSION = "perm";
    private static final String ATTR_PERMISSION_NAME = "name";
    private static final String ATTR_IS_GRANTED = "g";
    private static final String ATTR_USER_SET = "set";
    private static final String ATTR_USER_FIXED = "fixed";
    private static final String ATTR_REVOKE_ON_UPGRADE = "rou";

    // System/policy permission grants are not backed up
    private static final int SYSTEM_RUNTIME_GRANT_MASK =
            FLAG_PERMISSION_POLICY_FIXED
            | FLAG_PERMISSION_SYSTEM_FIXED
            | FLAG_PERMISSION_GRANTED_BY_DEFAULT;

    // And we back up these user-adjusted states
    private static final int USER_RUNTIME_GRANT_MASK =
            FLAG_PERMISSION_USER_SET
            | FLAG_PERMISSION_USER_FIXED
            | FLAG_PERMISSION_REVOKED_COMPAT;

    final @Nullable String mRequiredVerifierPackage;
    final @NonNull String mRequiredInstallerPackage;
    final @NonNull String mRequiredUninstallerPackage;
    final @NonNull String mRequiredPermissionControllerPackage;
    final @Nullable String mSetupWizardPackage;
    final @Nullable String mStorageManagerPackage;
    final @Nullable String mSystemTextClassifierPackage;
    final @Nullable String mWellbeingPackage;
    final @Nullable String mDocumenterPackage;
    final @Nullable String mConfiguratorPackage;
    final @Nullable String mAppPredictionServicePackage;
    final @Nullable String mIncidentReportApproverPackage;
    final @Nullable String[] mTelephonyPackages;
    final @NonNull String mServicesSystemSharedLibraryPackageName;
    final @NonNull String mSharedSystemSharedLibraryPackageName;

    private final PackageUsage mPackageUsage = new PackageUsage();
    private final CompilerStats mCompilerStats = new CompilerStats();

    class PackageHandler extends Handler {

        PackageHandler(Looper looper) {
            super(looper);
        }

        public void handleMessage(Message msg) {
            try {
                doHandleMessage(msg);
            } finally {
                Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
            }
        }

        void doHandleMessage(Message msg) {
            switch (msg.what) {
                case INIT_COPY: {
                    HandlerParams params = (HandlerParams) msg.obj;
                    if (params != null) {
                        if (DEBUG_INSTALL) Slog.i(TAG, "init_copy: " + params);
                        Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
                                System.identityHashCode(params));
                        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "startCopy");
                        params.startCopy();
                        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
                    }
                    break;
                }
                case SEND_PENDING_BROADCAST: {
                    String packages[];
                    ArrayList<String> components[];
                    int size = 0;
                    int uids[];
                    Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
                    synchronized (mLock) {
                        size = mPendingBroadcasts.size();
                        if (size <= 0) {
                            // Nothing to be done. Just return
                            return;
                        }
                        packages = new String[size];
                        components = new ArrayList[size];
                        uids = new int[size];
                        int i = 0;  // filling out the above arrays

                        for (int n = 0; n < mPendingBroadcasts.userIdCount(); n++) {
                            int packageUserId = mPendingBroadcasts.userIdAt(n);
                            Iterator<Map.Entry<String, ArrayList<String>>> it
                                    = mPendingBroadcasts.packagesForUserId(packageUserId)
                                            .entrySet().iterator();
                            while (it.hasNext() && i < size) {
                                Map.Entry<String, ArrayList<String>> ent = it.next();
                                packages[i] = ent.getKey();
                                components[i] = ent.getValue();
                                PackageSetting ps = mSettings.mPackages.get(ent.getKey());
                                uids[i] = (ps != null)
                                        ? UserHandle.getUid(packageUserId, ps.appId)
                                        : -1;
                                i++;
                            }
                        }
                        size = i;
                        mPendingBroadcasts.clear();
                    }
                    // Send broadcasts
                    for (int i = 0; i < size; i++) {
                        sendPackageChangedBroadcast(packages[i], true /* dontKillApp */,
                                components[i], uids[i], null /* reason */);
                    }
                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
                    break;
                }
                case POST_INSTALL: {
                    if (DEBUG_INSTALL) Log.v(TAG, "Handling post-install for " + msg.arg1);

                    PostInstallData data = mRunningInstalls.get(msg.arg1);
                    final boolean didRestore = (msg.arg2 != 0);
                    mRunningInstalls.delete(msg.arg1);

                    if (data != null && data.res.freezer != null) {
                        data.res.freezer.close();
                    }

                    if (data != null && data.mPostInstallRunnable != null) {
                        data.mPostInstallRunnable.run();
                    } else if (data != null) {
                        InstallArgs args = data.args;
                        PackageInstalledInfo parentRes = data.res;

                        final boolean grantPermissions = (args.installFlags
                                & PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS) != 0;
                        final boolean killApp = (args.installFlags
                                & PackageManager.INSTALL_DONT_KILL_APP) == 0;
                        final boolean virtualPreload = ((args.installFlags
                                & PackageManager.INSTALL_VIRTUAL_PRELOAD) != 0);
                        final String[] grantedPermissions = args.installGrantPermissions;
                        final List<String> whitelistedRestrictedPermissions = ((args.installFlags
                                & PackageManager.INSTALL_ALL_WHITELIST_RESTRICTED_PERMISSIONS) != 0
                                    && parentRes.pkg != null)
                                ? parentRes.pkg.getRequestedPermissions()
                                : args.whitelistedRestrictedPermissions;

                        // Handle the parent package
                        handlePackagePostInstall(parentRes, grantPermissions,
                                killApp, virtualPreload, grantedPermissions,
                                whitelistedRestrictedPermissions, didRestore,
                                args.installSource.installerPackageName, args.observer);

                        // Handle the child packages
                        final int childCount = (parentRes.addedChildPackages != null)
                                ? parentRes.addedChildPackages.size() : 0;
                        for (int i = 0; i < childCount; i++) {
                            PackageInstalledInfo childRes = parentRes.addedChildPackages.valueAt(i);
                            handlePackagePostInstall(childRes, grantPermissions,
                                    killApp, virtualPreload, grantedPermissions,
                                    whitelistedRestrictedPermissions, false /*didRestore*/,
                                    args.installSource.installerPackageName, args.observer);
                        }

                        // Log tracing if needed
                        if (args.traceMethod != null) {
                            Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, args.traceMethod,
                                    args.traceCookie);
                        }
                    } else if (DEBUG_INSTALL) {
                        // No post-install when we run restore from installExistingPackageForUser
                        Slog.i(TAG, "Nothing to do for post-install token " + msg.arg1);
                    }

                    Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "postInstall", msg.arg1);
                } break;
                case DEFERRED_NO_KILL_POST_DELETE: {
                    synchronized (mInstallLock) {
                        InstallArgs args = (InstallArgs) msg.obj;
                        if (args != null) {
                            args.doPostDeleteLI(true);
                        }
                    }
                } break;
                case DEFERRED_NO_KILL_INSTALL_OBSERVER: {
                    String packageName = (String) msg.obj;
                    if (packageName != null) {
                        notifyInstallObserver(packageName);
                    }
                } break;
                case WRITE_SETTINGS: {
                    Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
                    synchronized (mLock) {
                        removeMessages(WRITE_SETTINGS);
                        removeMessages(WRITE_PACKAGE_RESTRICTIONS);
                        mSettings.writeLPr();
                        mDirtyUsers.clear();
                    }
                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
                } break;
                case WRITE_PACKAGE_RESTRICTIONS: {
                    Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
                    synchronized (mLock) {
                        removeMessages(WRITE_PACKAGE_RESTRICTIONS);
                        for (int userId : mDirtyUsers) {
                            mSettings.writePackageRestrictionsLPr(userId);
                        }
                        mDirtyUsers.clear();
                    }
                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
                } break;
                case WRITE_PACKAGE_LIST: {
                    Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
                    synchronized (mLock) {
                        removeMessages(WRITE_PACKAGE_LIST);
                        mSettings.writePackageListLPr(msg.arg1);
                    }
                    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
                } break;
                case CHECK_PENDING_VERIFICATION: {
                    final int verificationId = msg.arg1;
                    final PackageVerificationState state = mPendingVerification.get(verificationId);

                    if ((state != null) && !state.timeoutExtended()) {
                        final InstallParams params = state.getInstallParams();
                        final InstallArgs args = params.mArgs;
                        final Uri originUri = Uri.fromFile(args.origin.resolvedFile);

                        Slog.i(TAG, "Verification timed out for " + originUri);
                        mPendingVerification.remove(verificationId);

                        final UserHandle user = args.getUser();
                        if (getDefaultVerificationResponse(user)
                                == PackageManager.VERIFICATION_ALLOW) {
                            Slog.i(TAG, "Continuing with installation of " + originUri);
                            state.setVerifierResponse(Binder.getCallingUid(),
                                    PackageManager.VERIFICATION_ALLOW_WITHOUT_SUFFICIENT);
                            broadcastPackageVerified(verificationId, originUri,
                                    PackageManager.VERIFICATION_ALLOW, user);
                        } else {
                            broadcastPackageVerified(verificationId, originUri,
                                    PackageManager.VERIFICATION_REJECT, user);
                            params.setReturnCode(
                                    PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE);
                        }

                        Trace.asyncTraceEnd(
                                TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId);
                        params.handleVerificationFinished();
                    }
                    break;
                }
                case PACKAGE_VERIFIED: {
                    final int verificationId = msg.arg1;

                    final PackageVerificationState state = mPendingVerification.get(verificationId);
                    if (state == null) {
                        Slog.w(TAG, "Invalid verification token " + verificationId + " received");
                        break;
                    }

                    final PackageVerificationResponse response = (PackageVerificationResponse) msg.obj;

                    state.setVerifierResponse(response.callerUid, response.code);

                    if (state.isVerificationComplete()) {
                        mPendingVerification.remove(verificationId);

                        final InstallParams params = state.getInstallParams();
                        final InstallArgs args = params.mArgs;
                        final Uri originUri = Uri.fromFile(args.origin.resolvedFile);

                        if (state.isInstallAllowed()) {
                            broadcastPackageVerified(verificationId, originUri,
                                    response.code, args.getUser());
                        } else {
                            params.setReturnCode(
                                    PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE);
                        }

                        Trace.asyncTraceEnd(
                                TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId);

                        params.handleVerificationFinished();
                    }

                    break;
                }
                case INTEGRITY_VERIFICATION_COMPLETE: {
                    // TODO: implement this case.
                    break;
                }
                case START_INTENT_FILTER_VERIFICATIONS: {
                    IFVerificationParams params = (IFVerificationParams) msg.obj;
                    verifyIntentFiltersIfNeeded(params.userId, params.verifierUid, params.replacing,
                            params.packageName, params.hasDomainUrls, params.activities);
                    break;
                }
                case INTENT_FILTER_VERIFIED: {
                    final int verificationId = msg.arg1;

                    final IntentFilterVerificationState state = mIntentFilterVerificationStates.get(
                            verificationId);
                    if (state == null) {
                        Slog.w(TAG, "Invalid IntentFilter verification token "
                                + verificationId + " received");
                        break;
                    }

                    final int userId = state.getUserId();

                    if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
                            "Processing IntentFilter verification with token:"
                            + verificationId + " and userId:" + userId);

                    final IntentFilterVerificationResponse response =
                            (IntentFilterVerificationResponse) msg.obj;

                    state.setVerifierResponse(response.callerUid, response.code);

                    if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
                            "IntentFilter verification with token:" + verificationId
                            + " and userId:" + userId
                            + " is settings verifier response with response code:"
                            + response.code);

                    if (response.code == PackageManager.INTENT_FILTER_VERIFICATION_FAILURE) {
                        if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Domains failing verification: "
                                + response.getFailedDomainsString());
                    }

                    if (state.isVerificationComplete()) {
                        mIntentFilterVerifier.receiveVerificationResponse(verificationId);
                    } else {
                        if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
                                "IntentFilter verification with token:" + verificationId
                                + " was not said to be complete");
                    }

                    break;
                }
                case INSTANT_APP_RESOLUTION_PHASE_TWO: {
                    InstantAppResolver.doInstantAppResolutionPhaseTwo(mContext,
                            mInstantAppResolverConnection,
                            (InstantAppRequest) msg.obj,
                            mInstantAppInstallerActivity,
                            mHandler);
                    break;
                }
                case ENABLE_ROLLBACK_STATUS: {
                    final int enableRollbackToken = msg.arg1;
                    final int enableRollbackCode = msg.arg2;
                    InstallParams params = mPendingEnableRollback.get(enableRollbackToken);
                    if (params == null) {
                        Slog.w(TAG, "Invalid rollback enabled token "
                                + enableRollbackToken + " received");
                        break;
                    }

                    mPendingEnableRollback.remove(enableRollbackToken);

                    if (enableRollbackCode != PackageManagerInternal.ENABLE_ROLLBACK_SUCCEEDED) {
                        final InstallArgs args = params.mArgs;
                        final Uri originUri = Uri.fromFile(args.origin.resolvedFile);
                        Slog.w(TAG, "Failed to enable rollback for " + originUri);
                        Slog.w(TAG, "Continuing with installation of " + originUri);
                    }

                    Trace.asyncTraceEnd(
                            TRACE_TAG_PACKAGE_MANAGER, "enable_rollback", enableRollbackToken);

                    params.handleRollbackEnabled();
                    break;
                }
                case ENABLE_ROLLBACK_TIMEOUT: {
                    final int enableRollbackToken = msg.arg1;
                    final InstallParams params = mPendingEnableRollback.get(enableRollbackToken);
                    if (params != null) {
                        final InstallArgs args = params.mArgs;
                        final Uri originUri = Uri.fromFile(args.origin.resolvedFile);

                        Slog.w(TAG, "Enable rollback timed out for " + originUri);
                        mPendingEnableRollback.remove(enableRollbackToken);

                        Slog.w(TAG, "Continuing with installation of " + originUri);
                        Trace.asyncTraceEnd(
                                TRACE_TAG_PACKAGE_MANAGER, "enable_rollback", enableRollbackToken);
                        params.handleRollbackEnabled();
                        Intent rollbackTimeoutIntent = new Intent(
                                Intent.ACTION_CANCEL_ENABLE_ROLLBACK);
                        rollbackTimeoutIntent.putExtra(
                                PackageManagerInternal.EXTRA_ENABLE_ROLLBACK_TOKEN,
                                enableRollbackToken);
                        rollbackTimeoutIntent.addFlags(
                                Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
                        mContext.sendBroadcastAsUser(rollbackTimeoutIntent, UserHandle.SYSTEM,
                                android.Manifest.permission.PACKAGE_ROLLBACK_AGENT);
                    }
                    break;
                }
            }
        }
    }

    private void handlePackagePostInstall(PackageInstalledInfo res, boolean grantPermissions,
            boolean killApp, boolean virtualPreload,
            String[] grantedPermissions, List<String> whitelistedRestrictedPermissions,
            boolean launchedForRestore, String installerPackage,
            IPackageInstallObserver2 installObserver) {
        final boolean succeeded = res.returnCode == PackageManager.INSTALL_SUCCEEDED;
        final boolean update = res.removedInfo != null && res.removedInfo.removedPackage != null;

        if (succeeded) {
            // Send the removed broadcasts
            if (res.removedInfo != null) {
                res.removedInfo.sendPackageRemovedBroadcasts(killApp);
            }

            // Whitelist any restricted permissions first as some may be runtime
            // that the installer requested to be granted at install time.
            if (whitelistedRestrictedPermissions != null
                    && !whitelistedRestrictedPermissions.isEmpty()) {
                mPermissionManager.setWhitelistedRestrictedPermissions(
                        res.pkg, res.newUsers, whitelistedRestrictedPermissions,
                        Process.myUid(), FLAG_PERMISSION_WHITELIST_INSTALLER);
            }

            // Now that we successfully installed the package, grant runtime
            // permissions if requested before broadcasting the install. Also
            // for legacy apps in permission review mode we clear the permission
            // review flag which is used to emulate runtime permissions for
            // legacy apps.
            if (grantPermissions) {
                final int callingUid = Binder.getCallingUid();
                mPermissionManager.grantRequestedRuntimePermissions(
                        res.pkg, res.newUsers, grantedPermissions, callingUid);
            }

            final String installerPackageName =
                    res.installerPackageName != null
                            ? res.installerPackageName
                            : res.removedInfo != null
                                    ? res.removedInfo.installerPackageName
                                    : null;

            synchronized (mLock) {
                mInstantAppRegistry.onPackageInstalledLPw(res.pkg, res.newUsers);
            }

            final String packageName = res.pkg.getAppInfoPackageName();

            // Determine the set of users who are adding this package for
            // the first time vs. those who are seeing an update.
            int[] firstUserIds = EMPTY_INT_ARRAY;
            int[] firstInstantUserIds = EMPTY_INT_ARRAY;
            int[] updateUserIds = EMPTY_INT_ARRAY;
            int[] instantUserIds = EMPTY_INT_ARRAY;
            final boolean allNewUsers = res.origUsers == null || res.origUsers.length == 0;
            final PackageSetting ps = getPackageSetting(res.pkg.getPackageName());
            for (int newUser : res.newUsers) {
                final boolean isInstantApp = ps.getInstantApp(newUser);
                if (allNewUsers) {
                    if (isInstantApp) {
                        firstInstantUserIds = ArrayUtils.appendInt(firstInstantUserIds, newUser);
                    } else {
                        firstUserIds = ArrayUtils.appendInt(firstUserIds, newUser);
                    }
                    continue;
                }
                boolean isNew = true;
                for (int origUser : res.origUsers) {
                    if (origUser == newUser) {
                        isNew = false;
                        break;
                    }
                }
                if (isNew) {
                    if (isInstantApp) {
                        firstInstantUserIds = ArrayUtils.appendInt(firstInstantUserIds, newUser);
                    } else {
                        firstUserIds = ArrayUtils.appendInt(firstUserIds, newUser);
                    }
                } else {
                    if (isInstantApp) {
                        instantUserIds = ArrayUtils.appendInt(instantUserIds, newUser);
                    } else {
                        updateUserIds = ArrayUtils.appendInt(updateUserIds, newUser);
                    }
                }
            }

            // Send installed broadcasts if the package is not a static shared lib.
            if (res.pkg.getStaticSharedLibName() == null) {
                mProcessLoggingHandler.invalidateProcessLoggingBaseApkHash(
                        res.pkg.getBaseCodePath());

                // Send added for users that see the package for the first time
                // sendPackageAddedForNewUsers also deals with system apps
                int appId = UserHandle.getAppId(res.uid);
                boolean isSystem = res.pkg.isSystemApp();
                sendPackageAddedForNewUsers(packageName, isSystem || virtualPreload,
                        virtualPreload /*startReceiver*/, appId, firstUserIds, firstInstantUserIds);

                // Send added for users that don't see the package for the first time
                Bundle extras = new Bundle(1);
                extras.putInt(Intent.EXTRA_UID, res.uid);
                if (update) {
                    extras.putBoolean(Intent.EXTRA_REPLACING, true);
                }
                sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName,
                        extras, 0 /*flags*/,
                        null /*targetPackage*/, null /*finishedReceiver*/,
                        updateUserIds, instantUserIds);
                if (installerPackageName != null) {
                    sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName,
                            extras, 0 /*flags*/,
                            installerPackageName, null /*finishedReceiver*/,
                            updateUserIds, instantUserIds);
                }
                // if the required verifier is defined, but, is not the installer of record
                // for the package, it gets notified
                final boolean notifyVerifier = mRequiredVerifierPackage != null
                        && !mRequiredVerifierPackage.equals(installerPackageName);
                if (notifyVerifier) {
                    sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName,
                            extras, 0 /*flags*/,
                            mRequiredVerifierPackage, null /*finishedReceiver*/,
                            updateUserIds, instantUserIds);
                }
                // If package installer is defined, notify package installer about new
                // app installed
                if (mRequiredInstallerPackage != null) {
                    sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName,
                            extras, Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND /*flags*/,
                            mRequiredInstallerPackage, null /*finishedReceiver*/,
                            firstUserIds, instantUserIds);
                }

                // Send replaced for users that don't see the package for the first time
                if (update) {
                    sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED,
                            packageName, extras, 0 /*flags*/,
                            null /*targetPackage*/, null /*finishedReceiver*/,
                            updateUserIds, instantUserIds);
                    if (installerPackageName != null) {
                        sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, packageName,
                                extras, 0 /*flags*/,
                                installerPackageName, null /*finishedReceiver*/,
                                updateUserIds, instantUserIds);
                    }
                    if (notifyVerifier) {
                        sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, packageName,
                                extras, 0 /*flags*/,
                                mRequiredVerifierPackage, null /*finishedReceiver*/,
                                updateUserIds, instantUserIds);
                    }
                    sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED,
                            null /*package*/, null /*extras*/, 0 /*flags*/,
                            packageName /*targetPackage*/,
                            null /*finishedReceiver*/, updateUserIds, instantUserIds);
                } else if (launchedForRestore && !isSystemApp(res.pkg)) {
                    // First-install and we did a restore, so we're responsible for the
                    // first-launch broadcast.
                    if (DEBUG_BACKUP) {
                        Slog.i(TAG, "Post-restore of " + packageName
                                + " sending FIRST_LAUNCH in " + Arrays.toString(firstUserIds));
                    }
                    sendFirstLaunchBroadcast(packageName, installerPackage,
                            firstUserIds, firstInstantUserIds);
                }

                // Send broadcast package appeared if external for all users
                if (isExternal(res.pkg)) {
                    if (!update) {
                        final StorageManager storage = mInjector.getStorageManager();
                        VolumeInfo volume =
                                storage.findVolumeByUuid(
                                        res.pkg.getStorageUuid().toString());
                        int packageExternalStorageType =
                                getPackageExternalStorageType(volume, isExternal(res.pkg));
                        // If the package was installed externally, log it.
                        if (packageExternalStorageType != StorageEnums.UNKNOWN) {
                            StatsLog.write(StatsLog.APP_INSTALL_ON_EXTERNAL_STORAGE_REPORTED,
                                    packageExternalStorageType, res.pkg.getPackageName());
                        }
                    }
                    if (DEBUG_INSTALL) {
                        Slog.i(TAG, "upgrading pkg " + res.pkg + " is external");
                    }
                    final int[] uidArray = new int[]{res.pkg.getUid()};
                    ArrayList<String> pkgList = new ArrayList<>(1);
                    pkgList.add(packageName);
                    sendResourcesChangedBroadcast(true, true, pkgList, uidArray, null);
                }
            } else if (!ArrayUtils.isEmpty(res.libraryConsumers)) { // if static shared lib
                for (int i = 0; i < res.libraryConsumers.size(); i++) {
                    AndroidPackage pkg = res.libraryConsumers.get(i);
                    // send broadcast that all consumers of the static shared library have changed
                    sendPackageChangedBroadcast(pkg.getPackageName(), false /* dontKillApp */,
                            new ArrayList<>(Collections.singletonList(pkg.getPackageName())),
                            pkg.getUid(), null);
                }
            }

            // Work that needs to happen on first install within each user
            if (firstUserIds != null && firstUserIds.length > 0) {
                for (int userId : firstUserIds) {
                    // If this app is a browser and it's newly-installed for some
                    // users, clear any default-browser state in those users. The
                    // app's nature doesn't depend on the user, so we can just check
                    // its browser nature in any user and generalize.
                    if (packageIsBrowser(packageName, userId)) {
                        // If this browser is restored from user's backup, do not clear
                        // default-browser state for this user
                        synchronized (mLock) {
                            final PackageSetting pkgSetting = mSettings.mPackages.get(packageName);
                            if (pkgSetting.getInstallReason(userId)
                                    != PackageManager.INSTALL_REASON_DEVICE_RESTORE) {
                                mPermissionManager.setDefaultBrowser(null, true, true, userId);
                            }
                        }
                    }

                    // We may also need to apply pending (restored) runtime permission grants
                    // within these users.
                    mPermissionManager.restoreDelayedRuntimePermissions(packageName,
                            UserHandle.of(userId));

                    // Persistent preferred activity might have came into effect due to this
                    // install.
                    updateDefaultHomeNotLocked(userId);
                }
            }

            if (allNewUsers && !update) {
                notifyPackageAdded(packageName, res.uid);
            } else {
                notifyPackageChanged(packageName, res.uid);
            }

            // Log current value of "unknown sources" setting
            EventLog.writeEvent(EventLogTags.UNKNOWN_SOURCES_ENABLED,
                    getUnknownSourcesSettings());

            // Remove the replaced package's older resources safely now
            InstallArgs args = res.removedInfo != null ? res.removedInfo.args : null;
            if (args != null) {
                if (!killApp) {
                    // If we didn't kill the app, defer the deletion of code/resource files, since
                    // they may still be in use by the running application. This mitigates problems
                    // in cases where resources or code is loaded by a new Activity before
                    // ApplicationInfo changes have propagated to all application threads.
                    scheduleDeferredNoKillPostDelete(args);
                } else {
                    synchronized (mInstallLock) {
                        args.doPostDeleteLI(true);
                    }
                }
            } else {
                // Force a gc to clear up things. Ask for a background one, it's fine to go on
                // and not block here.
                VMRuntime.getRuntime().requestConcurrentGC();
            }

            // Notify DexManager that the package was installed for new users.
            // The updated users should already be indexed and the package code paths
            // should not change.
            // Don't notify the manager for ephemeral apps as they are not expected to
            // survive long enough to benefit of background optimizations.
            for (int userId : firstUserIds) {
                PackageInfo info = getPackageInfo(packageName, /*flags*/ 0, userId);
                // There's a race currently where some install events may interleave with an
                // uninstall. This can lead to package info being null (b/36642664).
                if (info != null) {
                    mDexManager.notifyPackageInstalled(info, userId);
                }
            }
        }

        final boolean deferInstallObserver = succeeded && update && !killApp;
        if (deferInstallObserver) {
            scheduleDeferredNoKillInstallObserver(res, installObserver);
        } else {
            notifyInstallObserver(res, installObserver);
        }
    }

    @Override
    public void notifyPackagesReplacedReceived(String[] packages) {
        final int callingUid = Binder.getCallingUid();
        final int callingUserId = UserHandle.getUserId(callingUid);

        for (String packageName : packages) {
            PackageSetting setting = mSettings.mPackages.get(packageName);
            if (setting != null
                    && shouldFilterApplicationLocked(setting, callingUid, callingUserId)) {
                notifyInstallObserver(packageName);
            }
        }
    }

    private void notifyInstallObserver(String packageName) {
        Pair<PackageInstalledInfo, IPackageInstallObserver2> pair =
                mNoKillInstallObservers.remove(packageName);

        if (pair != null) {
            notifyInstallObserver(pair.first, pair.second);
        }
    }

    private void notifyInstallObserver(PackageInstalledInfo info,
            IPackageInstallObserver2 installObserver) {
        if (installObserver != null) {
            try {
                Bundle extras = extrasForInstallResult(info);
                installObserver.onPackageInstalled(info.name, info.returnCode,
                        info.returnMsg, extras);
            } catch (RemoteException e) {
                Slog.i(TAG, "Observer no longer exists.");
            }
        }
    }

    private void scheduleDeferredNoKillPostDelete(InstallArgs args) {
        Message message = mHandler.obtainMessage(DEFERRED_NO_KILL_POST_DELETE, args);
        mHandler.sendMessageDelayed(message, DEFERRED_NO_KILL_POST_DELETE_DELAY_MS);
    }

    private void scheduleDeferredNoKillInstallObserver(PackageInstalledInfo info,
            IPackageInstallObserver2 observer) {
        String packageName = info.pkg.getPackageName();
        mNoKillInstallObservers.put(packageName, Pair.create(info, observer));
        Message message = mHandler.obtainMessage(DEFERRED_NO_KILL_INSTALL_OBSERVER, packageName);
        mHandler.sendMessageDelayed(message, DEFERRED_NO_KILL_INSTALL_OBSERVER_DELAY_MS);
    }

    /**
     * Gets the type of the external storage a package is installed on.
     * @param packageVolume The storage volume of the package.
     * @param packageIsExternal true if the package is currently installed on
     * external/removable/unprotected storage.
     * @return {@link StorageEnums#UNKNOWN} if the package is not stored externally or the
     * corresponding {@link StorageEnums} storage type value if it is.
     * corresponding {@link StorageEnums} storage type value if it is.
     */
    private static int getPackageExternalStorageType(VolumeInfo packageVolume,
            boolean packageIsExternal) {
        if (packageVolume != null) {
            DiskInfo disk = packageVolume.getDisk();
            if (disk != null) {
                if (disk.isSd()) {
                    return StorageEnums.SD_CARD;
                }
                if (disk.isUsb()) {
                    return StorageEnums.USB;
                }
                if (packageIsExternal) {
                    return StorageEnums.OTHER;
                }
            }
        }
        return StorageEnums.UNKNOWN;
    }

    private StorageEventListener mStorageListener = new StorageEventListener() {
        @Override
        public void onVolumeStateChanged(VolumeInfo vol, int oldState, int newState) {
            if (vol.type == VolumeInfo.TYPE_PRIVATE) {
                if (vol.state == VolumeInfo.STATE_MOUNTED) {
                    final String volumeUuid = vol.getFsUuid();

                    // Clean up any users or apps that were removed or recreated
                    // while this volume was missing
                    mUserManager.reconcileUsers(volumeUuid);
                    reconcileApps(volumeUuid);

                    // Clean up any install sessions that expired or were
                    // cancelled while this volume was missing
                    mInstallerService.onPrivateVolumeMounted(volumeUuid);

                    loadPrivatePackages(vol);

                } else if (vol.state == VolumeInfo.STATE_EJECTING) {
                    unloadPrivatePackages(vol);
                }
            }
        }

        @Override
        public void onVolumeForgotten(String fsUuid) {
            if (TextUtils.isEmpty(fsUuid)) {
                Slog.e(TAG, "Forgetting internal storage is probably a mistake; ignoring");
                return;
            }

            // Remove any apps installed on the forgotten volume
            synchronized (mLock) {
                final List<PackageSetting> packages = mSettings.getVolumePackagesLPr(fsUuid);
                for (PackageSetting ps : packages) {
                    Slog.d(TAG, "Destroying " + ps.name + " because volume was forgotten");
                    deletePackageVersioned(new VersionedPackage(ps.name,
                            PackageManager.VERSION_CODE_HIGHEST),
                            new LegacyPackageDeleteObserver(null).getBinder(),
                            UserHandle.USER_SYSTEM, PackageManager.DELETE_ALL_USERS);
                    // Try very hard to release any references to this package
                    // so we don't risk the system server being killed due to
                    // open FDs
                    AttributeCache.instance().removePackage(ps.name);
                }

                mSettings.onVolumeForgotten(fsUuid);
                mSettings.writeLPr();
            }
        }
    };

    Bundle extrasForInstallResult(PackageInstalledInfo res) {
        Bundle extras = null;
        switch (res.returnCode) {
            case PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION: {
                extras = new Bundle();
                extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PERMISSION,
                        res.origPermission);
                extras.putString(PackageManager.EXTRA_FAILURE_EXISTING_PACKAGE,
                        res.origPackage);
                break;
            }
            case PackageManager.INSTALL_SUCCEEDED: {
                extras = new Bundle();
                extras.putBoolean(Intent.EXTRA_REPLACING,
                        res.removedInfo != null && res.removedInfo.removedPackage != null);
                break;
            }
        }
        return extras;
    }

    void scheduleWriteSettingsLocked() {
        if (!mHandler.hasMessages(WRITE_SETTINGS)) {
            mHandler.sendEmptyMessageDelayed(WRITE_SETTINGS, WRITE_SETTINGS_DELAY);
        }
    }

    void scheduleWritePackageListLocked(int userId) {
        if (!mHandler.hasMessages(WRITE_PACKAGE_LIST)) {
            Message msg = mHandler.obtainMessage(WRITE_PACKAGE_LIST);
            msg.arg1 = userId;
            mHandler.sendMessageDelayed(msg, WRITE_SETTINGS_DELAY);
        }
    }

    void scheduleWritePackageRestrictionsLocked(UserHandle user) {
        final int userId = user == null ? UserHandle.USER_ALL : user.getIdentifier();
        scheduleWritePackageRestrictionsLocked(userId);
    }

    void scheduleWritePackageRestrictionsLocked(int userId) {
        final int[] userIds = (userId == UserHandle.USER_ALL)
                ? mUserManager.getUserIds() : new int[]{userId};
        for (int nextUserId : userIds) {
            if (!mUserManager.exists(nextUserId)) return;
            mDirtyUsers.add(nextUserId);
            if (!mHandler.hasMessages(WRITE_PACKAGE_RESTRICTIONS)) {
                mHandler.sendEmptyMessageDelayed(WRITE_PACKAGE_RESTRICTIONS, WRITE_SETTINGS_DELAY);
            }
        }
    }

    public static PackageManagerService main(Context context, Installer installer,
            boolean factoryTest, boolean onlyCore) {
        // Self-check for initial settings.
        PackageManagerServiceCompilerMapping.checkProperties();
        final TimingsTraceAndSlog t = new TimingsTraceAndSlog(TAG + "Timing",
                Trace.TRACE_TAG_PACKAGE_MANAGER);
        t.traceBegin("create package manager");
        final Object lock = new Object();
        final Object installLock = new Object();

        Injector injector = new Injector(
                context, lock, installer, installLock, new PackageAbiHelperImpl(),
                (i, pm) ->
                        new ComponentResolver(i.getUserManagerService(), pm.mPmInternal, lock),
                (i, pm) ->
                        PermissionManagerService.create(context, lock),
                (i, pm) ->
                        new UserManagerService(context, pm,
                                new UserDataPreparer(installer, installLock, context, onlyCore),
                                lock),
                (i, pm) ->
                        new Settings(Environment.getDataDirectory(),
                                i.getPermissionManagerServiceInternal().getPermissionSettings(),
                                lock),
                new Injector.LocalServicesProducer<>(ActivityTaskManagerInternal.class),
                new Injector.LocalServicesProducer<>(DeviceIdleInternal.class),
                new Injector.LocalServicesProducer<>(StorageManagerInternal.class),
                new Injector.LocalServicesProducer<>(NetworkPolicyManagerInternal.class),
                new Injector.LocalServicesProducer<>(PermissionPolicyInternal.class),
                new Injector.LocalServicesProducer<>(DeviceStorageMonitorInternal.class),
                new Injector.SystemServiceProducer<>(DisplayManager.class),
                new Injector.SystemServiceProducer<>(StorageManager.class),
                new Injector.SystemServiceProducer<>(AppOpsManager.class),
                (i, pm) -> AppsFilter.create(i),
                (i, pm) -> (PlatformCompat) ServiceManager.getService("platform_compat"));

        PackageManagerService m = new PackageManagerService(injector, factoryTest, onlyCore);
        t.traceEnd(); // "create package manager"

        injector.getCompatibility().registerListener(SELinuxMMAC.SELINUX_LATEST_CHANGES,
                packageName -> {
                    synchronized (m.mInstallLock) {
                        final AndroidPackage pkg;
                        final SharedUserSetting sharedUser;
                        synchronized (m.mLock) {
                            PackageSetting ps = m.mSettings.getPackageLPr(packageName);
                            if (ps == null) {
                                Slog.e(TAG, "Failed to find package setting " + packageName);
                                return;
                            }
                            pkg = ps.pkg;
                            sharedUser = ps.sharedUser;
                        }

                        if (pkg == null) {
                            Slog.e(TAG, "Failed to find package " + packageName);
                            return;
                        }
                        final String newSeInfo = SELinuxMMAC.getSeInfo(pkg, sharedUser,
                                m.mInjector.getCompatibility());

                        if (!newSeInfo.equals(pkg.getSeInfo())) {
                            Slog.i(TAG, "Updating seInfo for package " + packageName + " from: "
                                    + pkg.getSeInfo() + " to: " + newSeInfo);
                            pkg.mutate().setSeInfo(newSeInfo);
                            m.prepareAppDataAfterInstallLIF(pkg);
                        }
                    }
                });

        m.installWhitelistedSystemPackages();
        ServiceManager.addService("package", m);
        final PackageManagerNative pmn = m.new PackageManagerNative();
        ServiceManager.addService("package_native", pmn);
        return m;
    }

    /** Install/uninstall system packages for all users based on their user-type, as applicable. */
    private void installWhitelistedSystemPackages() {
        synchronized (mLock) {
            final boolean scheduleWrite = mUserManager.installWhitelistedSystemPackages(
                    isFirstBoot(), isDeviceUpgrading());
            if (scheduleWrite) {
                scheduleWritePackageRestrictionsLocked(UserHandle.USER_ALL);
            }
        }
    }

    private static void getDefaultDisplayMetrics(
            DisplayManager displayManager, DisplayMetrics metrics) {
        displayManager.getDisplay(Display.DEFAULT_DISPLAY).getMetrics(metrics);
    }

    /**
     * Requests that files preopted on a secondary system partition be copied to the data partition
     * if possible.  Note that the actual copying of the files is accomplished by init for security
     * reasons. This simply requests that the copy takes place and awaits confirmation of its
     * completion. See platform/system/extras/cppreopt/ for the implementation of the actual copy.
     */
    private static void requestCopyPreoptedFiles() {
        final int WAIT_TIME_MS = 100;
        final String CP_PREOPT_PROPERTY = "sys.cppreopt";
        if (SystemProperties.getInt("ro.cp_system_other_odex", 0) == 1) {
            SystemProperties.set(CP_PREOPT_PROPERTY, "requested");
            // We will wait for up to 100 seconds.
            final long timeStart = SystemClock.uptimeMillis();
            final long timeEnd = timeStart + 100 * 1000;
            long timeNow = timeStart;
            while (!SystemProperties.get(CP_PREOPT_PROPERTY).equals("finished")) {
                try {
                    Thread.sleep(WAIT_TIME_MS);
                } catch (InterruptedException e) {
                    // Do nothing
                }
                timeNow = SystemClock.uptimeMillis();
                if (timeNow > timeEnd) {
                    SystemProperties.set(CP_PREOPT_PROPERTY, "timed-out");
                    Slog.wtf(TAG, "cppreopt did not finish!");
                    break;
                }
            }

            Slog.i(TAG, "cppreopts took " + (timeNow - timeStart) + " ms");
        }
    }

    @VisibleForTesting(visibility = Visibility.PRIVATE)
    public static class SystemPartition {
        public final File folder;
        public final int scanFlag;
        public final File appFolder;
        @Nullable
        public final File privAppFolder;
        @Nullable
        public final File overlayFolder;


        private static boolean shouldScanPrivApps(@ScanFlags int scanFlags) {
            if ((scanFlags & SCAN_AS_OEM) != 0) {
                return false;
            }
            if (scanFlags == 0) {  // /system partition
                return true;
            }
            if ((scanFlags
                    & (SCAN_AS_VENDOR | SCAN_AS_ODM | SCAN_AS_PRODUCT | SCAN_AS_SYSTEM_EXT)) != 0) {
                return true;
            }
            return false;
        }

        private SystemPartition(File folder, int scanFlag, boolean hasOverlays) {
            this.folder = folder;
            this.scanFlag = scanFlag;
            this.appFolder = toCanonical(new File(folder, "app"));
            this.privAppFolder = shouldScanPrivApps(scanFlag)
                    ? toCanonical(new File(folder, "priv-app"))
                    : null;
            this.overlayFolder = hasOverlays ? toCanonical(new File(folder, "overlay")) : null;
        }

        public boolean containsPrivApp(File scanFile) {
            return FileUtils.contains(privAppFolder, scanFile);
        }

        public boolean containsApp(File scanFile) {
            return FileUtils.contains(appFolder, scanFile);
        }

        public boolean containsPath(String path) {
            return path.startsWith(folder.getPath() + "/");
        }

        public boolean containsPrivPath(String path) {
            return privAppFolder != null && path.startsWith(privAppFolder.getPath() + "/");
        }

        private static File toCanonical(File dir) {
            try {
                return dir.getCanonicalFile();
            } catch (IOException e) {
                // failed to look up canonical path, continue with original one
                return dir;
            }
        }
    }

    public PackageManagerService(Injector injector, boolean onlyCore, boolean factoryTest) {
        final TimingsTraceAndSlog t = new TimingsTraceAndSlog(TAG + "Timing",
                Trace.TRACE_TAG_PACKAGE_MANAGER);
        mInjector = injector;
        mInjector.bootstrap(this);
        mLock = injector.getLock();
        mInstallLock = injector.getInstallLock();
        LockGuard.installLock(mLock, LockGuard.INDEX_PACKAGES);
        EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_START,
                SystemClock.uptimeMillis());

        if (mSdkVersion <= 0) {
            Slog.w(TAG, "**** ro.build.version.sdk not set!");
        }

        mContext = injector.getContext();
        mFactoryTest = factoryTest;
        mOnlyCore = onlyCore;
        mMetrics = new DisplayMetrics();
        mInstaller = injector.getInstaller();

        // Create sub-components that provide services / data. Order here is important.
        t.traceBegin("createSubComponents");

        // Expose private service for system components to use.
        mPmInternal = new PackageManagerInternalImpl();
        LocalServices.addService(PackageManagerInternal.class, mPmInternal);
        mUserManager = injector.getUserManagerService();
        mComponentResolver = injector.getComponentResolver();
        mPermissionManager = injector.getPermissionManagerServiceInternal();
        mSettings = injector.getSettings();
        mPermissionManagerService = (IPermissionManager) ServiceManager.getService("permissionmgr");
        mIncrementalManager =
                (IncrementalManager) mContext.getSystemService(Context.INCREMENTAL_SERVICE);

        // CHECKSTYLE:ON IndentationCheck
        t.traceEnd();

        t.traceBegin("addSharedUsers");
        mSettings.addSharedUserLPw("android.uid.system", Process.SYSTEM_UID,
                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
        mSettings.addSharedUserLPw("android.uid.phone", RADIO_UID,
                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
        mSettings.addSharedUserLPw("android.uid.log", LOG_UID,
                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
        mSettings.addSharedUserLPw("android.uid.nfc", NFC_UID,
                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
        mSettings.addSharedUserLPw("android.uid.bluetooth", BLUETOOTH_UID,
                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
        mSettings.addSharedUserLPw("android.uid.shell", SHELL_UID,
                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
        mSettings.addSharedUserLPw("android.uid.se", SE_UID,
                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
        mSettings.addSharedUserLPw("android.uid.networkstack", NETWORKSTACK_UID,
                ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
        t.traceEnd();

        String separateProcesses = SystemProperties.get("debug.separate_processes");
        if (separateProcesses != null && separateProcesses.length() > 0) {
            if ("*".equals(separateProcesses)) {
                mDefParseFlags = PackageParser.PARSE_IGNORE_PROCESSES;
                mSeparateProcesses = null;
                Slog.w(TAG, "Running with debug.separate_processes: * (ALL)");
            } else {
                mDefParseFlags = 0;
                mSeparateProcesses = separateProcesses.split(",");
                Slog.w(TAG, "Running with debug.separate_processes: "
                        + separateProcesses);
            }
        } else {
            mDefParseFlags = 0;
            mSeparateProcesses = null;
        }

        mPackageDexOptimizer = new PackageDexOptimizer(mInstaller, mInstallLock, mContext,
                "*dexopt*");
        mDexManager =
                new DexManager(mContext, this, mPackageDexOptimizer, mInstaller, mInstallLock);
        mArtManagerService = new ArtManagerService(mContext, this, mInstaller, mInstallLock);
        mMoveCallbacks = new MoveCallbacks(FgThread.get().getLooper());

        mViewCompiler = new ViewCompiler(mInstallLock, mInstaller);

        getDefaultDisplayMetrics(mInjector.getDisplayManager(), mMetrics);

        t.traceBegin("get system config");
        SystemConfig systemConfig = SystemConfig.getInstance();
        mAvailableFeatures = systemConfig.getAvailableFeatures();
        t.traceEnd();

        mProtectedPackages = new ProtectedPackages(mContext);

        mApexManager = ApexManager.getInstance();
        mAppsFilter = mInjector.getAppsFilter();

        mDirsToScanAsSystem = new ArrayList<>();
        mDirsToScanAsSystem.addAll(SYSTEM_PARTITIONS);
        mDirsToScanAsSystem.addAll(mApexManager.getActiveApexInfos().stream()
                .map(ai -> resolveApexToSystemPartition(ai))
                .filter(Objects::nonNull).collect(Collectors.toList()));
        Slog.d(TAG,
                "Directories scanned as system partitions: [" + mDirsToScanAsSystem.stream().map(
                        d -> (d.folder.getAbsolutePath() + ":" + d.scanFlag))
                        .collect(Collectors.joining(",")) + "]");

        // CHECKSTYLE:OFF IndentationCheck
        synchronized (mInstallLock) {
        // writer
        synchronized (mLock) {
            mHandlerThread = new ServiceThread(TAG,
                    Process.THREAD_PRIORITY_BACKGROUND, true /*allowIo*/);
            mHandlerThread.start();
            mHandler = new PackageHandler(mHandlerThread.getLooper());
            mProcessLoggingHandler = new ProcessLoggingHandler();
            Watchdog.getInstance().addThread(mHandler, WATCHDOG_TIMEOUT);
            mInstantAppRegistry = new InstantAppRegistry(this);

            ArrayMap<String, SystemConfig.SharedLibraryEntry> libConfig
                    = systemConfig.getSharedLibraries();
            final int builtInLibCount = libConfig.size();
            for (int i = 0; i < builtInLibCount; i++) {
                String name = libConfig.keyAt(i);
                SystemConfig.SharedLibraryEntry entry = libConfig.valueAt(i);
                addBuiltInSharedLibraryLocked(entry.filename, name);
            }

            // Now that we have added all the libraries, iterate again to add dependency
            // information IFF their dependencies are added.
            long undefinedVersion = SharedLibraryInfo.VERSION_UNDEFINED;
            for (int i = 0; i < builtInLibCount; i++) {
                String name = libConfig.keyAt(i);
                SystemConfig.SharedLibraryEntry entry = libConfig.valueAt(i);
                final int dependencyCount = entry.dependencies.length;
                for (int j = 0; j < dependencyCount; j++) {
                    final SharedLibraryInfo dependency =
                        getSharedLibraryInfoLPr(entry.dependencies[j], undefinedVersion);
                    if (dependency != null) {
                        getSharedLibraryInfoLPr(name, undefinedVersion).addDependency(dependency);
                    }
                }
            }

            SELinuxMMAC.readInstallPolicy();

            t.traceBegin("loadFallbacks");
            FallbackCategoryProvider.loadFallbacks();
            t.traceEnd();

            t.traceBegin("read user settings");
            mFirstBoot = !mSettings.readLPw(mUserManager.getUsers(false));
            t.traceEnd();

            // Clean up orphaned packages for which the code path doesn't exist
            // and they are an update to a system app - caused by bug/32321269
            final int packageSettingCount = mSettings.mPackages.size();
            for (int i = packageSettingCount - 1; i >= 0; i--) {
                PackageSetting ps = mSettings.mPackages.valueAt(i);
                if (!isExternal(ps) && (ps.codePath == null || !ps.codePath.exists())
                        && mSettings.getDisabledSystemPkgLPr(ps.name) != null) {
                    mSettings.mPackages.removeAt(i);
                    mSettings.enableSystemPackageLPw(ps.name);
                }
            }

            if (!mOnlyCore && mFirstBoot) {
                requestCopyPreoptedFiles();
            }

            String customResolverActivityName = Resources.getSystem().getString(
                    R.string.config_customResolverActivity);
            if (!TextUtils.isEmpty(customResolverActivityName)) {
                mCustomResolverComponentName = ComponentName.unflattenFromString(
                        customResolverActivityName);
            }

            long startTime = SystemClock.uptimeMillis();

            EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SYSTEM_SCAN_START,
                    startTime);

            final String bootClassPath = System.getenv("BOOTCLASSPATH");
            final String systemServerClassPath = System.getenv("SYSTEMSERVERCLASSPATH");

            if (bootClassPath == null) {
                Slog.w(TAG, "No BOOTCLASSPATH found!");
            }

            if (systemServerClassPath == null) {
                Slog.w(TAG, "No SYSTEMSERVERCLASSPATH found!");
            }

            File frameworkDir = new File(Environment.getRootDirectory(), "framework");

            final VersionInfo ver = mSettings.getInternalVersion();
            mIsUpgrade = !Build.FINGERPRINT.equals(ver.fingerprint);
            if (mIsUpgrade) {
                logCriticalInfo(Log.INFO,
                        "Upgrading from " + ver.fingerprint + " to " + Build.FINGERPRINT);
            }

            // when upgrading from pre-M, promote system app permissions from install to runtime
            mPromoteSystemApps =
                    mIsUpgrade && ver.sdkVersion <= Build.VERSION_CODES.LOLLIPOP_MR1;

            // When upgrading from pre-N, we need to handle package extraction like first boot,
            // as there is no profiling data available.
            mIsPreNUpgrade = mIsUpgrade && ver.sdkVersion < Build.VERSION_CODES.N;

            mIsPreNMR1Upgrade = mIsUpgrade && ver.sdkVersion < Build.VERSION_CODES.N_MR1;
            mIsPreQUpgrade = mIsUpgrade && ver.sdkVersion < Build.VERSION_CODES.Q;

            // save off the names of pre-existing system packages prior to scanning; we don't
            // want to automatically grant runtime permissions for new system apps
            if (mPromoteSystemApps) {
                for (PackageSetting ps : mSettings.mPackages.values()) {
                    if (isSystemApp(ps)) {
                        mExistingSystemPackages.add(ps.name);
                    }
                }
            }

            mCacheDir = preparePackageParserCache();

            // Set flag to monitor and not change apk file paths when
            // scanning install directories.
            int scanFlags = SCAN_BOOTING | SCAN_INITIAL;

            if (mIsUpgrade || mFirstBoot) {
                scanFlags = scanFlags | SCAN_FIRST_BOOT_OR_UPGRADE;
            }

            // Collect vendor/product/system_ext overlay packages. (Do this before scanning
            // any apps.)
            // For security and version matching reason, only consider overlay packages if they
            // reside in the right directory.
            final int systemParseFlags = mDefParseFlags | PackageParser.PARSE_IS_SYSTEM_DIR;
            final int systemScanFlags = scanFlags | SCAN_AS_SYSTEM;
            for (int i = mDirsToScanAsSystem.size() - 1; i >= 0; i--) {
                final SystemPartition partition = mDirsToScanAsSystem.get(i);
                if (partition.overlayFolder == null) {
                    continue;
                }
                scanDirTracedLI(partition.overlayFolder, systemParseFlags,
                        systemScanFlags | partition.scanFlag, 0);
            }

            scanDirTracedLI(frameworkDir, systemParseFlags,
                    systemScanFlags | SCAN_NO_DEX | SCAN_AS_PRIVILEGED, 0);
            if (!mPackages.containsKey("android")) {
                throw new IllegalStateException(
                        "Failed to load frameworks package; check log for warnings");
            }
            for (int i = 0, size = mDirsToScanAsSystem.size(); i < size; i++) {
                final SystemPartition partition = mDirsToScanAsSystem.get(i);
                if (partition.privAppFolder != null) {
                    scanDirTracedLI(partition.privAppFolder, systemParseFlags,
                            systemScanFlags | SCAN_AS_PRIVILEGED | partition.scanFlag, 0);
                }
                scanDirTracedLI(partition.appFolder, systemParseFlags,
                        systemScanFlags | partition.scanFlag, 0);
            }


            // Prune any system packages that no longer exist.
            final List<String> possiblyDeletedUpdatedSystemApps = new ArrayList<>();
            // Stub packages must either be replaced with full versions in the /data
            // partition or be disabled.
            final List<String> stubSystemApps = new ArrayList<>();
            if (!mOnlyCore) {
                // do this first before mucking with mPackages for the "expecting better" case
                final Iterator<AndroidPackage> pkgIterator = mPackages.values().iterator();
                while (pkgIterator.hasNext()) {
                    final AndroidPackage pkg = pkgIterator.next();
                    if (pkg.isStub()) {
                        stubSystemApps.add(pkg.getPackageName());
                    }
                }

                final Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator();
                while (psit.hasNext()) {
                    PackageSetting ps = psit.next();

                    /*
                     * If this is not a system app, it can't be a
                     * disable system app.
                     */
                    if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0) {
                        continue;
                    }

                    /*
                     * If the package is scanned, it's not erased.
                     */
                    final AndroidPackage scannedPkg = mPackages.get(ps.name);
                    if (scannedPkg != null) {
                        /*
                         * If the system app is both scanned and in the
                         * disabled packages list, then it must have been
                         * added via OTA. Remove it from the currently
                         * scanned package so the previously user-installed
                         * application can be scanned.
                         */
                        if (mSettings.isDisabledSystemPackageLPr(ps.name)) {
                            logCriticalInfo(Log.WARN,
                                    "Expecting better updated system app for " + ps.name
                                    + "; removing system app.  Last known"
                                    + " codePath=" + ps.codePathString
                                    + ", versionCode=" + ps.versionCode
                                    + "; scanned versionCode=" + scannedPkg.getLongVersionCode());
                            removePackageLI(scannedPkg, true);
                            mExpectingBetter.put(ps.name, ps.codePath);
                        }

                        continue;
                    }

                    if (!mSettings.isDisabledSystemPackageLPr(ps.name)) {
                        psit.remove();
                        logCriticalInfo(Log.WARN, "System package " + ps.name
                                + " no longer exists; it's data will be wiped");
                        // Actual deletion of code and data will be handled by later
                        // reconciliation step
                    } else {
                        // we still have a disabled system package, but, it still might have
                        // been removed. check the code path still exists and check there's
                        // still a package. the latter can happen if an OTA keeps the same
                        // code path, but, changes the package name.
                        final PackageSetting disabledPs =
                                mSettings.getDisabledSystemPkgLPr(ps.name);
                        if (disabledPs.codePath == null || !disabledPs.codePath.exists()
                                || disabledPs.pkg == null) {
                            possiblyDeletedUpdatedSystemApps.add(ps.name);
                        } else {
                            // We're expecting that the system app should remain disabled, but add
                            // it to expecting better to recover in case the data version cannot
                            // be scanned.
                            mExpectingBetter.put(disabledPs.name, disabledPs.codePath);
                        }
                    }
                }
            }

            //delete tmp files
            deleteTempPackageFiles();

            final int cachedSystemApps = PackageParser.sCachedPackageReadCount.get();

            // Remove any shared userIDs that have no associated packages
            mSettings.pruneSharedUsersLPw();
            final long systemScanTime = SystemClock.uptimeMillis() - startTime;
            final int systemPackagesCount = mPackages.size();
            Slog.i(TAG, "Finished scanning system apps. Time: " + systemScanTime
                    + " ms, packageCount: " + systemPackagesCount
                    + " , timePerPackage: "
                    + (systemPackagesCount == 0 ? 0 : systemScanTime / systemPackagesCount)
                    + " , cached: " + cachedSystemApps);
            if (mIsUpgrade && systemPackagesCount > 0) {
                MetricsLogger.histogram(null, "ota_package_manager_system_app_avg_scan_time",
                        ((int) systemScanTime) / systemPackagesCount);
            }
            if (!mOnlyCore) {
                EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_DATA_SCAN_START,
                        SystemClock.uptimeMillis());
                scanDirTracedLI(sAppInstallDir, 0, scanFlags | SCAN_REQUIRE_KNOWN, 0);

                // Remove disable package settings for updated system apps that were
                // removed via an OTA. If the update is no longer present, remove the
                // app completely. Otherwise, revoke their system privileges.
                for (int i = possiblyDeletedUpdatedSystemApps.size() - 1; i >= 0; --i) {
                    final String packageName = possiblyDeletedUpdatedSystemApps.get(i);
                    final AndroidPackage pkg = mPackages.get(packageName);
                    final String msg;

                    // remove from the disabled system list; do this first so any future
                    // scans of this package are performed without this state
                    mSettings.removeDisabledSystemPackageLPw(packageName);

                    if (pkg == null) {
                        // should have found an update, but, we didn't; remove everything
                        msg = "Updated system package " + packageName
                                + " no longer exists; removing its data";
                        // Actual deletion of code and data will be handled by later
                        // reconciliation step
                    } else {
                        // found an update; revoke system privileges
                        msg = "Updated system package " + packageName
                                + " no longer exists; rescanning package on data";

                        // NOTE: We don't do anything special if a stub is removed from the
                        // system image. But, if we were [like removing the uncompressed
                        // version from the /data partition], this is where it'd be done.

                        // remove the package from the system and re-scan it without any
                        // special privileges
                        removePackageLI(pkg, true);
                        try {
                            final File codePath = new File(pkg.getAppInfoCodePath());
                            scanPackageTracedLI(codePath, 0, scanFlags, 0, null);
                        } catch (PackageManagerException e) {
                            Slog.e(TAG, "Failed to parse updated, ex-system package: "
                                    + e.getMessage());
                        }
                    }

                    // one final check. if we still have a package setting [ie. it was
                    // previously scanned and known to the system], but, we don't have
                    // a package [ie. there was an error scanning it from the /data
                    // partition], completely remove the package data.
                    final PackageSetting ps = mSettings.mPackages.get(packageName);
                    if (ps != null && mPackages.get(packageName) == null) {
                        removePackageDataLIF(ps, null, null, 0, false);

                    }
                    logCriticalInfo(Log.WARN, msg);
                }

                /*
                 * Make sure all system apps that we expected to appear on
                 * the userdata partition actually showed up. If they never
                 * appeared, crawl back and revive the system version.
                 */
                for (int i = 0; i < mExpectingBetter.size(); i++) {
                    final String packageName = mExpectingBetter.keyAt(i);
                    if (!mPackages.containsKey(packageName)) {
                        final File scanFile = mExpectingBetter.valueAt(i);

                        logCriticalInfo(Log.WARN, "Expected better " + packageName
                                + " but never showed up; reverting to system");

                        @ParseFlags int reparseFlags = 0;
                        @ScanFlags int rescanFlags = 0;
                        for (int i1 = 0, size = mDirsToScanAsSystem.size(); i1 < size; i1++) {
                            SystemPartition partition = mDirsToScanAsSystem.get(i1);
                            if (partition.containsPrivApp(scanFile)) {
                                reparseFlags = systemParseFlags;
                                rescanFlags = systemScanFlags | SCAN_AS_PRIVILEGED
                                        | partition.scanFlag;
                                break;
                            }
                            if (partition.containsApp(scanFile)) {
                                reparseFlags = systemParseFlags;
                                rescanFlags = systemScanFlags | partition.scanFlag;
                                break;
                            }
                        }
                        if (rescanFlags == 0) {
                            Slog.e(TAG, "Ignoring unexpected fallback path " + scanFile);
                            continue;
                        }
                        mSettings.enableSystemPackageLPw(packageName);

                        try {
                            scanPackageTracedLI(scanFile, reparseFlags, rescanFlags, 0, null);
                        } catch (PackageManagerException e) {
                            Slog.e(TAG, "Failed to parse original system package: "
                                    + e.getMessage());
                        }
                    }
                }

                // Uncompress and install any stubbed system applications.
                // This must be done last to ensure all stubs are replaced or disabled.
                installSystemStubPackages(stubSystemApps, scanFlags);

                final int cachedNonSystemApps = PackageParser.sCachedPackageReadCount.get()
                                - cachedSystemApps;

                final long dataScanTime = SystemClock.uptimeMillis() - systemScanTime - startTime;
                final int dataPackagesCount = mPackages.size() - systemPackagesCount;
                Slog.i(TAG, "Finished scanning non-system apps. Time: " + dataScanTime
                        + " ms, packageCount: " + dataPackagesCount
                        + " , timePerPackage: "
                        + (dataPackagesCount == 0 ? 0 : dataScanTime / dataPackagesCount)
                        + " , cached: " + cachedNonSystemApps);
                if (mIsUpgrade && dataPackagesCount > 0) {
                    MetricsLogger.histogram(null, "ota_package_manager_data_app_avg_scan_time",
                            ((int) dataScanTime) / dataPackagesCount);
                }
            }
            mExpectingBetter.clear();

            // Resolve the storage manager.
            mStorageManagerPackage = getStorageManagerPackageName();

            // Resolve protected action filters. Only the setup wizard is allowed to
            // have a high priority filter for these actions.
            mSetupWizardPackage = getSetupWizardPackageNameImpl();
            mComponentResolver.fixProtectedFilterPriorities();

            mSystemTextClassifierPackage = getSystemTextClassifierPackageName();

            mWellbeingPackage = getWellbeingPackageName();
            mDocumenterPackage = getDocumenterPackageName();
            mConfiguratorPackage = getDeviceConfiguratorPackageName();
            mAppPredictionServicePackage = getAppPredictionServicePackageName();
            mIncidentReportApproverPackage = getIncidentReportApproverPackageName();
            mTelephonyPackages = getTelephonyPackageNames();

            // Now that we know all of the shared libraries, update all clients to have
            // the correct library paths.
            updateAllSharedLibrariesLocked(null, Collections.unmodifiableMap(mPackages));

            for (SharedUserSetting setting : mSettings.getAllSharedUsersLPw()) {
                // NOTE: We ignore potential failures here during a system scan (like
                // the rest of the commands above) because there's precious little we
                // can do about it. A settings error is reported, though.
                final List<String> changedAbiCodePath =
                        applyAdjustedAbiToSharedUser(setting, null /*scannedPackage*/,
                        mInjector.getAbiHelper().getAdjustedAbiForSharedUser(
                                setting.packages, null /*scannedPackage*/));
                if (changedAbiCodePath != null && changedAbiCodePath.size() > 0) {
                    for (int i = changedAbiCodePath.size() - 1; i >= 0; --i) {
                        final String codePathString = changedAbiCodePath.get(i);
                        try {
                            mInstaller.rmdex(codePathString,
                                    getDexCodeInstructionSet(getPreferredInstructionSet()));
                        } catch (InstallerException ignored) {
                        }
                    }
                }
                // Adjust seInfo to ensure apps which share a sharedUserId are placed in the same
                // SELinux domain.
                setting.fixSeInfoLocked();
            }

            // Now that we know all the packages we are keeping,
            // read and update their last usage times.
            mPackageUsage.read(mPackages);
            mCompilerStats.read();

            EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_SCAN_END,
                    SystemClock.uptimeMillis());
            Slog.i(TAG, "Time to scan packages: "
                    + ((SystemClock.uptimeMillis()-startTime)/1000f)
                    + " seconds");

            // If the platform SDK has changed since the last time we booted,
            // we need to re-grant app permission to catch any new ones that
            // appear.  This is really a hack, and means that apps can in some
            // cases get permissions that the user didn't initially explicitly
            // allow...  it would be nice to have some better way to handle
            // this situation.
            final boolean sdkUpdated = (ver.sdkVersion != mSdkVersion);
            if (sdkUpdated) {
                Slog.i(TAG, "Platform changed from " + ver.sdkVersion + " to "
                        + mSdkVersion + "; regranting permissions for internal storage");
            }
            mPermissionManager.updateAllPermissions(
                    StorageManager.UUID_PRIVATE_INTERNAL, sdkUpdated);
            ver.sdkVersion = mSdkVersion;

            // If this is the first boot or an update from pre-M, and it is a normal
            // boot, then we need to initialize the default preferred apps across
            // all defined users.
            if (!mOnlyCore && (mPromoteSystemApps || mFirstBoot)) {
                for (UserInfo user : mUserManager.getUsers(true)) {
                    mSettings.applyDefaultPreferredAppsLPw(user.id);
                    primeDomainVerificationsLPw(user.id);
                }
            }

            // Prepare storage for system user really early during boot,
            // since core system apps like SettingsProvider and SystemUI
            // can't wait for user to start
            final int storageFlags;
            if (StorageManager.isFileEncryptedNativeOrEmulated()) {
                storageFlags = StorageManager.FLAG_STORAGE_DE;
            } else {
                storageFlags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
            }
            List<String> deferPackages = reconcileAppsDataLI(StorageManager.UUID_PRIVATE_INTERNAL,
                    UserHandle.USER_SYSTEM, storageFlags, true /* migrateAppData */,
                    true /* onlyCoreApps */);
            mPrepareAppDataFuture = SystemServerInitThreadPool.submit(() -> {
                TimingsTraceLog traceLog = new TimingsTraceLog("SystemServerTimingAsync",
                        Trace.TRACE_TAG_PACKAGE_MANAGER);
                traceLog.traceBegin("AppDataFixup");
                try {
                    mInstaller.fixupAppData(StorageManager.UUID_PRIVATE_INTERNAL,
                            StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE);
                } catch (InstallerException e) {
                    Slog.w(TAG, "Trouble fixing GIDs", e);
                }
                traceLog.traceEnd();

                traceLog.traceBegin("AppDataPrepare");
                if (deferPackages == null || deferPackages.isEmpty()) {
                    return;
                }
                int count = 0;
                for (String pkgName : deferPackages) {
                    AndroidPackage pkg = null;
                    synchronized (mLock) {
                        PackageSetting ps = mSettings.getPackageLPr(pkgName);
                        if (ps != null && ps.getInstalled(UserHandle.USER_SYSTEM)) {
                            pkg = ps.pkg;
                        }
                    }
                    if (pkg != null) {
                        synchronized (mInstallLock) {
                            prepareAppDataAndMigrateLIF(pkg, UserHandle.USER_SYSTEM, storageFlags,
                                    true /* maybeMigrateAppData */);
                        }
                        count++;
                    }
                }
                traceLog.traceEnd();
                Slog.i(TAG, "Deferred reconcileAppsData finished " + count + " packages");
            }, "prepareAppData");

            // If this is first boot after an OTA, and a normal boot, then
            // we need to clear code cache directories.
            // Note that we do *not* clear the application profiles. These remain valid
            // across OTAs and are used to drive profile verification (post OTA) and
            // profile compilation (without waiting to collect a fresh set of profiles).
            if (mIsUpgrade && !mOnlyCore) {
                Slog.i(TAG, "Build fingerprint changed; clearing code caches");
                for (int i = 0; i < mSettings.mPackages.size(); i++) {
                    final PackageSetting ps = mSettings.mPackages.valueAt(i);
                    if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, ps.volumeUuid)) {
                        // No apps are running this early, so no need to freeze
                        clearAppDataLIF(ps.pkg, UserHandle.USER_ALL,
                                FLAG_STORAGE_DE | FLAG_STORAGE_CE | FLAG_STORAGE_EXTERNAL
                                        | Installer.FLAG_CLEAR_CODE_CACHE_ONLY
                                        | Installer.FLAG_CLEAR_APP_DATA_KEEP_ART_PROFILES);
                    }
                }
                ver.fingerprint = Build.FINGERPRINT;
            }

            // Grandfather existing (installed before Q) non-system apps to hide
            // their icons in launcher.
            if (!mOnlyCore && mIsPreQUpgrade) {
                Slog.i(TAG, "Whitelisting all existing apps to hide their icons");
                int size = mSettings.mPackages.size();
                for (int i = 0; i < size; i++) {
                    final PackageSetting ps = mSettings.mPackages.valueAt(i);
                    if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0) {
                        continue;
                    }
                    ps.disableComponentLPw(PackageManager.APP_DETAILS_ACTIVITY_CLASS_NAME,
                            UserHandle.USER_SYSTEM);
                }
            }

            // clear only after permissions and other defaults have been updated
            mExistingSystemPackages.clear();
            mPromoteSystemApps = false;

            // All the changes are done during package scanning.
            ver.databaseVersion = Settings.CURRENT_DATABASE_VERSION;

            // can downgrade to reader
            t.traceBegin("write settings");
            mSettings.writeLPr();
            t.traceEnd();
            EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_READY,
                    SystemClock.uptimeMillis());

            if (!mOnlyCore) {
                mRequiredVerifierPackage = getRequiredButNotReallyRequiredVerifierLPr();
                mRequiredInstallerPackage = getRequiredInstallerLPr();
                mRequiredUninstallerPackage = getRequiredUninstallerLPr();
                mIntentFilterVerifierComponent = getIntentFilterVerifierComponentNameLPr();
                if (mIntentFilterVerifierComponent != null) {
                    mIntentFilterVerifier = new IntentVerifierProxy(mContext,
                            mIntentFilterVerifierComponent);
                } else {
                    mIntentFilterVerifier = null;
                }
                mServicesSystemSharedLibraryPackageName = getRequiredSharedLibraryLPr(
                        PackageManager.SYSTEM_SHARED_LIBRARY_SERVICES,
                        SharedLibraryInfo.VERSION_UNDEFINED);
                mSharedSystemSharedLibraryPackageName = getRequiredSharedLibraryLPr(
                        PackageManager.SYSTEM_SHARED_LIBRARY_SHARED,
                        SharedLibraryInfo.VERSION_UNDEFINED);
            } else {
                mRequiredVerifierPackage = null;
                mRequiredInstallerPackage = null;
                mRequiredUninstallerPackage = null;
                mIntentFilterVerifierComponent = null;
                mIntentFilterVerifier = null;
                mServicesSystemSharedLibraryPackageName = null;
                mSharedSystemSharedLibraryPackageName = null;
            }
            // PermissionController hosts default permission granting and role management, so it's a
            // critical part of the core system.
            mRequiredPermissionControllerPackage = getRequiredPermissionControllerLPr();

            // Initialize InstantAppRegistry's Instant App list for all users.
            final int[] userIds = UserManagerService.getInstance().getUserIds();
            for (AndroidPackage pkg : mPackages.values()) {
                if (pkg.isSystem()) {
                    continue;
                }
                for (int userId : userIds) {
                    final PackageSetting ps = getPackageSetting(pkg.getPackageName());
                    if (ps == null || !ps.getInstantApp(userId) || !ps.getInstalled(userId)) {
                        continue;
                    }
                    mInstantAppRegistry.addInstantAppLPw(userId, ps.appId);
                }
            }

            mInstallerService = new PackageInstallerService(mContext, this, mApexManager);
            final Pair<ComponentName, String> instantAppResolverComponent =
                    getInstantAppResolverLPr();
            if (instantAppResolverComponent != null) {
                if (DEBUG_INSTANT) {
                    Slog.d(TAG, "Set ephemeral resolver: " + instantAppResolverComponent);
                }
                mInstantAppResolverConnection = new InstantAppResolverConnection(
                        mContext, instantAppResolverComponent.first,
                        instantAppResolverComponent.second);
                mInstantAppResolverSettingsComponent =
                        getInstantAppResolverSettingsLPr(instantAppResolverComponent.first);
            } else {
                mInstantAppResolverConnection = null;
                mInstantAppResolverSettingsComponent = null;
            }
            updateInstantAppInstallerLocked(null);

            // Read and update the usage of dex files.
            // Do this at the end of PM init so that all the packages have their
            // data directory reconciled.
            // At this point we know the code paths of the packages, so we can validate
            // the disk file and build the internal cache.
            // The usage file is expected to be small so loading and verifying it
            // should take a fairly small time compare to the other activities (e.g. package
            // scanning).
            final Map<Integer, List<PackageInfo>> userPackages = new HashMap<>();
            for (int userId : userIds) {
                userPackages.put(userId, getInstalledPackages(/*flags*/ 0, userId).getList());
            }
            mDexManager.load(userPackages);
            if (mIsUpgrade) {
                MetricsLogger.histogram(null, "ota_package_manager_init_time",
                        (int) (SystemClock.uptimeMillis() - startTime));
            }
        } // synchronized (mLock)
        } // synchronized (mInstallLock)
        // CHECKSTYLE:ON IndentationCheck

        mModuleInfoProvider = new ModuleInfoProvider(mContext, this);

        // Now after opening every single application zip, make sure they
        // are all flushed.  Not really needed, but keeps things nice and
        // tidy.
        t.traceBegin("GC");
        Runtime.getRuntime().gc();
        t.traceEnd();

        // The initial scanning above does many calls into installd while
        // holding the mPackages lock, but we're mostly interested in yelling
        // once we have a booted system.
        mInstaller.setWarnIfHeld(mLock);

        PackageParser.readConfigUseRoundIcon(mContext.getResources());

        mServiceStartWithDelay = SystemClock.uptimeMillis() + (60 * 1000L);
    }

    /**
     * Uncompress and install stub applications.
     * <p>In order to save space on the system partition, some applications are shipped in a
     * compressed form. In addition the compressed bits for the full application, the
     * system image contains a tiny stub comprised of only the Android manifest.
     * <p>During the first boot, attempt to uncompress and install the full application. If
     * the application can't be installed for any reason, disable the stub and prevent
     * uncompressing the full application during future boots.
     * <p>In order to forcefully attempt an installation of a full application, go to app
     * settings and enable the application.
     */
    private void installSystemStubPackages(@NonNull List<String> systemStubPackageNames,
            @ScanFlags int scanFlags) {
        for (int i = systemStubPackageNames.size() - 1; i >= 0; --i) {
            final String packageName = systemStubPackageNames.get(i);
            // skip if the system package is already disabled
            if (mSettings.isDisabledSystemPackageLPr(packageName)) {
                systemStubPackageNames.remove(i);
                continue;
            }
            // skip if the package isn't installed (?!); this should never happen
            final AndroidPackage pkg = mPackages.get(packageName);
            if (pkg == null) {
                systemStubPackageNames.remove(i);
                continue;
            }
            // skip if the package has been disabled by the user
            final PackageSetting ps = mSettings.mPackages.get(packageName);
            if (ps != null) {
                final int enabledState = ps.getEnabled(UserHandle.USER_SYSTEM);
                if (enabledState == PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER) {
                    systemStubPackageNames.remove(i);
                    continue;
                }
            }

            // install the package to replace the stub on /system
            try {
                installStubPackageLI(pkg, 0, scanFlags);
                ps.setEnabled(PackageManager.COMPONENT_ENABLED_STATE_DEFAULT,
                        UserHandle.USER_SYSTEM, "android");
                systemStubPackageNames.remove(i);
            } catch (PackageManagerException e) {
                Slog.e(TAG, "Failed to parse uncompressed system package: " + e.getMessage());
            }

            // any failed attempt to install the package will be cleaned up later
        }

        // disable any stub still left; these failed to install the full application
        for (int i = systemStubPackageNames.size() - 1; i >= 0; --i) {
            final String pkgName = systemStubPackageNames.get(i);
            final PackageSetting ps = mSettings.mPackages.get(pkgName);
            ps.setEnabled(PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
                    UserHandle.USER_SYSTEM, "android");
            logCriticalInfo(Log.ERROR, "Stub disabled; pkg: " + pkgName);
        }
    }

    /**
     * Extract, install and enable a stub package.
     * <p>If the compressed file can not be extracted / installed for any reason, the stub
     * APK will be installed and the package will be disabled. To recover from this situation,
     * the user will need to go into system settings and re-enable the package.
     */
    private boolean enableCompressedPackage(AndroidPackage stubPkg) {
        final int parseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY
                | PackageParser.PARSE_ENFORCE_CODE;
        synchronized (mInstallLock) {
            final AndroidPackage pkg;
            try (PackageFreezer freezer =
                    freezePackage(stubPkg.getPackageName(), "setEnabledSetting")) {
                pkg = installStubPackageLI(stubPkg, parseFlags, 0 /*scanFlags*/);
                synchronized (mLock) {
                    prepareAppDataAfterInstallLIF(pkg);
                    try {
                        updateSharedLibrariesLocked(pkg, null,
                                Collections.unmodifiableMap(mPackages));
                    } catch (PackageManagerException e) {
                        Slog.e(TAG, "updateAllSharedLibrariesLPw failed: ", e);
                    }
                    mPermissionManager.updatePermissions(pkg.getPackageName(), pkg);
                    mSettings.writeLPr();
                }
            } catch (PackageManagerException e) {
                // Whoops! Something went very wrong; roll back to the stub and disable the package
                try (PackageFreezer freezer =
                        freezePackage(stubPkg.getPackageName(), "setEnabledSetting")) {
                    synchronized (mLock) {
                        // NOTE: Ensure the system package is enabled; even for a compressed stub.
                        // If we don't, installing the system package fails during scan
                        enableSystemPackageLPw(stubPkg);
                    }
                    installPackageFromSystemLIF(stubPkg.getCodePath(),
                            null /*allUserHandles*/, null /*origUserHandles*/,
                            null /*origPermissionsState*/, true /*writeSettings*/);
                } catch (PackageManagerException pme) {
                    // Serious WTF; we have to be able to install the stub
                    Slog.wtf(TAG, "Failed to restore system package:" + stubPkg.getPackageName(),
                            pme);
                } finally {
                    // Disable the package; the stub by itself is not runnable
                    synchronized (mLock) {
                        final PackageSetting stubPs = mSettings.mPackages.get(
                                stubPkg.getPackageName());
                        if (stubPs != null) {
                            stubPs.setEnabled(COMPONENT_ENABLED_STATE_DISABLED,
                                    UserHandle.USER_SYSTEM, "android");
                        }
                        mSettings.writeLPr();
                    }
                }
                return false;
            }
            clearAppDataLIF(pkg, UserHandle.USER_ALL, FLAG_STORAGE_DE | FLAG_STORAGE_CE
                    | FLAG_STORAGE_EXTERNAL | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
            mDexManager.notifyPackageUpdated(pkg.getPackageName(),
                    pkg.getBaseCodePath(), pkg.getSplitCodePaths());
        }
        return true;
    }

    private AndroidPackage installStubPackageLI(AndroidPackage stubPkg,
            @ParseFlags int parseFlags, @ScanFlags int scanFlags)
                    throws PackageManagerException {
        if (DEBUG_COMPRESSION) {
            Slog.i(TAG, "Uncompressing system stub; pkg: " + stubPkg.getPackageName());
        }
        // uncompress the binary to its eventual destination on /data
        final File scanFile = decompressPackage(stubPkg.getPackageName(), stubPkg.getCodePath());
        if (scanFile == null) {
            throw new PackageManagerException(
                    "Unable to decompress stub at " + stubPkg.getCodePath());
        }
        synchronized (mLock) {
            mSettings.disableSystemPackageLPw(stubPkg.getPackageName(), true /*replaced*/);
        }
        removePackageLI(stubPkg, true /*chatty*/);
        try {
            return scanPackageTracedLI(scanFile, parseFlags, scanFlags, 0, null);
        } catch (PackageManagerException e) {
            Slog.w(TAG, "Failed to install compressed system package:" + stubPkg.getPackageName(),
                    e);
            // Remove the failed install
            removeCodePathLI(scanFile);
            throw e;
        }
    }

    /**
     * Decompresses the given package on the system image onto
     * the /data partition.
     * @return The directory the package was decompressed into. Otherwise, {@code null}.
     */
    private File decompressPackage(String packageName, String codePath) {
        final File[] compressedFiles = getCompressedFiles(codePath);
        if (compressedFiles == null || compressedFiles.length == 0) {
            if (DEBUG_COMPRESSION) {
                Slog.i(TAG, "No files to decompress: " + codePath);
            }
            return null;
        }
        final File dstCodePath =
                getNextCodePath(Environment.getDataAppDirectory(null), packageName);
        int ret = PackageManager.INSTALL_SUCCEEDED;
        try {
            Os.mkdir(dstCodePath.getAbsolutePath(), 0755);
            Os.chmod(dstCodePath.getAbsolutePath(), 0755);
            for (File srcFile : compressedFiles) {
                final String srcFileName = srcFile.getName();
                final String dstFileName = srcFileName.substring(
                        0, srcFileName.length() - COMPRESSED_EXTENSION.length());
                final File dstFile = new File(dstCodePath, dstFileName);
                ret = decompressFile(srcFile, dstFile);
                if (ret != PackageManager.INSTALL_SUCCEEDED) {
                    logCriticalInfo(Log.ERROR, "Failed to decompress"
                            + "; pkg: " + packageName
                            + ", file: " + dstFileName);
                    break;
                }
            }
        } catch (ErrnoException e) {
            logCriticalInfo(Log.ERROR, "Failed to decompress"
                    + "; pkg: " + packageName
                    + ", err: " + e.errno);
        }
        if (ret == PackageManager.INSTALL_SUCCEEDED) {
            final File libraryRoot = new File(dstCodePath, LIB_DIR_NAME);
            NativeLibraryHelper.Handle handle = null;
            try {
                handle = NativeLibraryHelper.Handle.create(dstCodePath);
                ret = NativeLibraryHelper.copyNativeBinariesWithOverride(handle, libraryRoot,
                        null /*abiOverride*/);
            } catch (IOException e) {
                logCriticalInfo(Log.ERROR, "Failed to extract native libraries"
                        + "; pkg: " + packageName);
                ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
            } finally {
                IoUtils.closeQuietly(handle);
            }
        }
        if (ret != PackageManager.INSTALL_SUCCEEDED) {
            if (!dstCodePath.exists()) {
                return null;
            }
            removeCodePathLI(dstCodePath);
            return null;
        }

        return dstCodePath;
    }

    @GuardedBy("mLock")
    private void updateInstantAppInstallerLocked(String modifiedPackage) {
        // we're only interested in updating the installer appliction when 1) it's not
        // already set or 2) the modified package is the installer
        if (mInstantAppInstallerActivity != null
                && !mInstantAppInstallerActivity.getComponentName().getPackageName()
                        .equals(modifiedPackage)) {
            return;
        }
        setUpInstantAppInstallerActivityLP(getInstantAppInstallerLPr());
    }

    private static @Nullable File preparePackageParserCache() {
        if (!FORCE_PACKAGE_PARSED_CACHE_ENABLED) {
            if (!DEFAULT_PACKAGE_PARSER_CACHE_ENABLED) {
                return null;
            }

            // Disable package parsing on eng builds to allow for faster incremental development.
            if (Build.IS_ENG) {
                return null;
            }

            if (SystemProperties.getBoolean("pm.boot.disable_package_cache", false)) {
                Slog.i(TAG, "Disabling package parser cache due to system property.");
                return null;
            }
        }

        // The base directory for the package parser cache lives under /data/system/.
        final File cacheBaseDir = Environment.getPackageCacheDirectory();
        if (!FileUtils.createDir(cacheBaseDir)) {
            return null;
        }

        // There are several items that need to be combined together to safely
        // identify cached items. In particular, changing the value of certain
        // feature flags should cause us to invalidate any caches.
        final String cacheName = FORCE_PACKAGE_PARSED_CACHE_ENABLED ? "debug"
                : SystemProperties.digestOf(
                        "ro.build.fingerprint",
                        StorageManager.PROP_ISOLATED_STORAGE,
                        StorageManager.PROP_ISOLATED_STORAGE_SNAPSHOT
                );

        // Reconcile cache directories, keeping only what we'd actually use.
        for (File cacheDir : FileUtils.listFilesOrEmpty(cacheBaseDir)) {
            if (Objects.equals(cacheName, cacheDir.getName())) {
                Slog.d(TAG, "Keeping known cache " + cacheDir.getName());
            } else {
                Slog.d(TAG, "Destroying unknown cache " + cacheDir.getName());
                FileUtils.deleteContentsAndDir(cacheDir);
            }
        }

        // Return the versioned package cache directory.
        File cacheDir = FileUtils.createDir(cacheBaseDir, cacheName);

        if (cacheDir == null) {
            // Something went wrong. Attempt to delete everything and return.
            Slog.wtf(TAG, "Cache directory cannot be created - wiping base dir " + cacheBaseDir);
            FileUtils.deleteContentsAndDir(cacheBaseDir);
            return null;
        }

        // The following is a workaround to aid development on non-numbered userdebug
        // builds or cases where "adb sync" is used on userdebug builds. If we detect that
        // the system partition is newer.
        //
        // NOTE: When no BUILD_NUMBER is set by the build system, it defaults to a build
        // that starts with "eng." to signify that this is an engineering build and not
        // destined for release.
        if (Build.IS_USERDEBUG && Build.VERSION.INCREMENTAL.startsWith("eng.")) {
            Slog.w(TAG, "Wiping cache directory because the system partition changed.");

            // Heuristic: If the /system directory has been modified recently due to an "adb sync"
            // or a regular make, then blow away the cache. Note that mtimes are *NOT* reliable
            // in general and should not be used for production changes. In this specific case,
            // we know that they will work.
            File frameworkDir = new File(Environment.getRootDirectory(), "framework");
            if (cacheDir.lastModified() < frameworkDir.lastModified()) {
                FileUtils.deleteContents(cacheBaseDir);
                cacheDir = FileUtils.createDir(cacheBaseDir, cacheName);
            }
        }

        return cacheDir;
    }

    @Override
    public boolean isFirstBoot() {
        // allow instant applications
        return mFirstBoot;
    }

    @Override
    public boolean isOnlyCoreApps() {
        // allow instant applications
        return mOnlyCore;
    }

    @Override
    public boolean isDeviceUpgrading() {
        // allow instant applications
        // The system property allows testing ota flow when upgraded to the same image.
        return mIsUpgrade || SystemProperties.getBoolean(
                "persist.pm.mock-upgrade", false /* default */);
    }

    private @Nullable String getRequiredButNotReallyRequiredVerifierLPr() {
        final Intent intent = new Intent(Intent.ACTION_PACKAGE_NEEDS_VERIFICATION);

        final List<ResolveInfo> matches = queryIntentReceiversInternal(intent, PACKAGE_MIME_TYPE,
                MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
                UserHandle.USER_SYSTEM, false /*allowDynamicSplits*/);
        if (matches.size() == 1) {
            return matches.get(0).getComponentInfo().packageName;
        } else if (matches.size() == 0) {
            Log.e(TAG, "There should probably be a verifier, but, none were found");
            return null;
        }
        throw new RuntimeException("There must be exactly one verifier; found " + matches);
    }

    private @NonNull String getRequiredSharedLibraryLPr(String name, int version) {
        synchronized (mLock) {
            SharedLibraryInfo libraryInfo = getSharedLibraryInfoLPr(name, version);
            if (libraryInfo == null) {
                throw new IllegalStateException("Missing required shared library:" + name);
            }
            String packageName = libraryInfo.getPackageName();
            if (packageName == null) {
                throw new IllegalStateException("Expected a package for shared library " + name);
            }
            return packageName;
        }
    }

    private @NonNull String getRequiredInstallerLPr() {
        final Intent intent = new Intent(Intent.ACTION_INSTALL_PACKAGE);
        intent.addCategory(Intent.CATEGORY_DEFAULT);
        intent.setDataAndType(Uri.parse("content://com.example/foo.apk"), PACKAGE_MIME_TYPE);

        final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, PACKAGE_MIME_TYPE,
                MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
                UserHandle.USER_SYSTEM);
        if (matches.size() == 1) {
            ResolveInfo resolveInfo = matches.get(0);
            if (!resolveInfo.activityInfo.applicationInfo.isPrivilegedApp()) {
                throw new RuntimeException("The installer must be a privileged app");
            }
            return matches.get(0).getComponentInfo().packageName;
        } else {
            throw new RuntimeException("There must be exactly one installer; found " + matches);
        }
    }

    private @NonNull String getRequiredUninstallerLPr() {
        final Intent intent = new Intent(Intent.ACTION_UNINSTALL_PACKAGE);
        intent.addCategory(Intent.CATEGORY_DEFAULT);
        intent.setData(Uri.fromParts(PACKAGE_SCHEME, "foo.bar", null));

        final ResolveInfo resolveInfo = resolveIntent(intent, null,
                MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
                UserHandle.USER_SYSTEM);
        if (resolveInfo == null ||
                mResolveActivity.name.equals(resolveInfo.getComponentInfo().name)) {
            throw new RuntimeException("There must be exactly one uninstaller; found "
                    + resolveInfo);
        }
        return resolveInfo.getComponentInfo().packageName;
    }

    private @NonNull String getRequiredPermissionControllerLPr() {
        final Intent intent = new Intent(Intent.ACTION_MANAGE_PERMISSIONS);
        intent.addCategory(Intent.CATEGORY_DEFAULT);

        final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, null,
                MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
                UserHandle.USER_SYSTEM);
        if (matches.size() == 1) {
            ResolveInfo resolveInfo = matches.get(0);
            if (!resolveInfo.activityInfo.applicationInfo.isPrivilegedApp()) {
                throw new RuntimeException("The permissions manager must be a privileged app");
            }
            return matches.get(0).getComponentInfo().packageName;
        } else {
            throw new RuntimeException("There must be exactly one permissions manager; found "
                    + matches);
        }
    }

    private @NonNull ComponentName getIntentFilterVerifierComponentNameLPr() {
        final Intent intent = new Intent(Intent.ACTION_INTENT_FILTER_NEEDS_VERIFICATION);

        final List<ResolveInfo> matches = queryIntentReceiversInternal(intent, PACKAGE_MIME_TYPE,
                MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
                UserHandle.USER_SYSTEM, false /*allowDynamicSplits*/);
        ResolveInfo best = null;
        final int N = matches.size();
        for (int i = 0; i < N; i++) {
            final ResolveInfo cur = matches.get(i);
            final String packageName = cur.getComponentInfo().packageName;
            if (checkPermission(android.Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT,
                    packageName, UserHandle.USER_SYSTEM) != PackageManager.PERMISSION_GRANTED) {
                continue;
            }

            if (best == null || cur.priority > best.priority) {
                best = cur;
            }
        }

        if (best != null) {
            return best.getComponentInfo().getComponentName();
        }
        Slog.w(TAG, "Intent filter verifier not found");
        return null;
    }

    @Override
    public @Nullable ComponentName getInstantAppResolverComponent() {
        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
            return null;
        }
        synchronized (mLock) {
            final Pair<ComponentName, String> instantAppResolver = getInstantAppResolverLPr();
            if (instantAppResolver == null) {
                return null;
            }
            return instantAppResolver.first;
        }
    }

    private @Nullable Pair<ComponentName, String> getInstantAppResolverLPr() {
        final String[] packageArray =
                mContext.getResources().getStringArray(R.array.config_ephemeralResolverPackage);
        if (packageArray.length == 0 && !Build.IS_DEBUGGABLE) {
            if (DEBUG_INSTANT) {
                Slog.d(TAG, "Ephemeral resolver NOT found; empty package list");
            }
            return null;
        }

        final int callingUid = Binder.getCallingUid();
        final int resolveFlags =
                MATCH_DIRECT_BOOT_AWARE
                | MATCH_DIRECT_BOOT_UNAWARE
                | (!Build.IS_DEBUGGABLE ? MATCH_SYSTEM_ONLY : 0);
        String actionName = Intent.ACTION_RESOLVE_INSTANT_APP_PACKAGE;
        final Intent resolverIntent = new Intent(actionName);
        List<ResolveInfo> resolvers = queryIntentServicesInternal(resolverIntent, null,
                resolveFlags, UserHandle.USER_SYSTEM, callingUid, false /*includeInstantApps*/);
        final int N = resolvers.size();
        if (N == 0) {
            if (DEBUG_INSTANT) {
                Slog.d(TAG, "Ephemeral resolver NOT found; no matching intent filters");
            }
            return null;
        }

        final Set<String> possiblePackages = new ArraySet<>(Arrays.asList(packageArray));
        for (int i = 0; i < N; i++) {
            final ResolveInfo info = resolvers.get(i);

            if (info.serviceInfo == null) {
                continue;
            }

            final String packageName = info.serviceInfo.packageName;
            if (!possiblePackages.contains(packageName) && !Build.IS_DEBUGGABLE) {
                if (DEBUG_INSTANT) {
                    Slog.d(TAG, "Ephemeral resolver not in allowed package list;"
                            + " pkg: " + packageName + ", info:" + info);
                }
                continue;
            }

            if (DEBUG_INSTANT) {
                Slog.v(TAG, "Ephemeral resolver found;"
                        + " pkg: " + packageName + ", info:" + info);
            }
            return new Pair<>(new ComponentName(packageName, info.serviceInfo.name), actionName);
        }
        if (DEBUG_INSTANT) {
            Slog.v(TAG, "Ephemeral resolver NOT found");
        }
        return null;
    }

    @GuardedBy("mLock")
    private @Nullable ActivityInfo getInstantAppInstallerLPr() {
        String[] orderedActions = Build.IS_ENG
                ? new String[]{
                        Intent.ACTION_INSTALL_INSTANT_APP_PACKAGE + "_TEST",
                        Intent.ACTION_INSTALL_INSTANT_APP_PACKAGE}
                : new String[]{
                        Intent.ACTION_INSTALL_INSTANT_APP_PACKAGE};

        final int resolveFlags =
                MATCH_DIRECT_BOOT_AWARE
                        | MATCH_DIRECT_BOOT_UNAWARE
                        | Intent.FLAG_IGNORE_EPHEMERAL
                        | (!Build.IS_ENG ? MATCH_SYSTEM_ONLY : 0);
        final Intent intent = new Intent();
        intent.addCategory(Intent.CATEGORY_DEFAULT);
        intent.setDataAndType(Uri.fromFile(new File("foo.apk")), PACKAGE_MIME_TYPE);
        List<ResolveInfo> matches = null;
        for (String action : orderedActions) {
            intent.setAction(action);
            matches = queryIntentActivitiesInternal(intent, PACKAGE_MIME_TYPE,
                    resolveFlags, UserHandle.USER_SYSTEM);
            if (matches.isEmpty()) {
                if (DEBUG_INSTANT) {
                    Slog.d(TAG, "Instant App installer not found with " + action);
                }
            } else {
                break;
            }
        }
        Iterator<ResolveInfo> iter = matches.iterator();
        while (iter.hasNext()) {
            final ResolveInfo rInfo = iter.next();
            final PackageSetting ps = mSettings.mPackages.get(rInfo.activityInfo.packageName);
            if (ps != null) {
                final PermissionsState permissionsState = ps.getPermissionsState();
                if (permissionsState.hasPermission(Manifest.permission.INSTALL_PACKAGES, 0)
                        || Build.IS_ENG) {
                    continue;
                }
            }
            iter.remove();
        }
        if (matches.size() == 0) {
            return null;
        } else if (matches.size() == 1) {
            return (ActivityInfo) matches.get(0).getComponentInfo();
        } else {
            throw new RuntimeException(
                    "There must be at most one ephemeral installer; found " + matches);
        }
    }

    private @Nullable ComponentName getInstantAppResolverSettingsLPr(
            @NonNull ComponentName resolver) {
        final Intent intent =  new Intent(Intent.ACTION_INSTANT_APP_RESOLVER_SETTINGS)
                .addCategory(Intent.CATEGORY_DEFAULT)
                .setPackage(resolver.getPackageName());
        final int resolveFlags = MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE;
        List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, null, resolveFlags,
                UserHandle.USER_SYSTEM);
        if (matches.isEmpty()) {
            return null;
        }
        return matches.get(0).getComponentInfo().getComponentName();
    }

    @GuardedBy("mLock")
    private void primeDomainVerificationsLPw(int userId) {
        if (DEBUG_DOMAIN_VERIFICATION) {
            Slog.d(TAG, "Priming domain verifications in user " + userId);
        }

        SystemConfig systemConfig = SystemConfig.getInstance();
        ArraySet<String> packages = systemConfig.getLinkedApps();

        for (String packageName : packages) {
            AndroidPackage pkg = mPackages.get(packageName);
            if (pkg != null) {
                if (!pkg.isSystem()) {
                    Slog.w(TAG, "Non-system app '" + packageName + "' in sysconfig <app-link>");
                    continue;
                }

                ArraySet<String> domains = null;
                if (pkg.getActivities() != null) {
                    for (ParsedActivity a : pkg.getActivities()) {
                        for (ParsedActivityIntentInfo filter : a.intents) {
                            if (hasValidDomains(filter)) {
                                if (domains == null) {
                                    domains = new ArraySet<>();
                                }
                                domains.addAll(filter.getHostsList());
                            }
                        }
                    }
                }

                if (domains != null && domains.size() > 0) {
                    if (DEBUG_DOMAIN_VERIFICATION) {
                        Slog.v(TAG, "      + " + packageName);
                    }
                    // 'Undefined' in the global IntentFilterVerificationInfo, i.e. the usual
                    // state w.r.t. the formal app-linkage "no verification attempted" state;
                    // and then 'always' in the per-user state actually used for intent resolution.
                    final IntentFilterVerificationInfo ivi;
                    ivi = mSettings.createIntentFilterVerificationIfNeededLPw(packageName, domains);
                    ivi.setStatus(INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED);
                    mSettings.updateIntentFilterVerificationStatusLPw(packageName,
                            INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS, userId);
                } else {
                    Slog.w(TAG, "Sysconfig <app-link> package '" + packageName
                            + "' does not handle web links");
                }
            } else {
                Slog.w(TAG, "Unknown package " + packageName + " in sysconfig <app-link>");
            }
        }

        scheduleWritePackageRestrictionsLocked(userId);
        scheduleWriteSettingsLocked();
    }

    private boolean packageIsBrowser(String packageName, int userId) {
        List<ResolveInfo> list = queryIntentActivitiesInternal(sBrowserIntent, null,
                PackageManager.MATCH_ALL, userId);
        final int N = list.size();
        for (int i = 0; i < N; i++) {
            ResolveInfo info = list.get(i);
            if (info.priority >= 0 && packageName.equals(info.activityInfo.packageName)) {
                return true;
            }
        }
        return false;
    }

    @Override
    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
            throws RemoteException {
        try {
            return super.onTransact(code, data, reply, flags);
        } catch (RuntimeException e) {
            if (!(e instanceof SecurityException) && !(e instanceof IllegalArgumentException)) {
                Slog.wtf(TAG, "Package Manager Crash", e);
            }
            throw e;
        }
    }

    /**
     * Returns whether or not a full application can see an instant application.
     * <p>
     * Currently, there are four cases in which this can occur:
     * <ol>
     * <li>The calling application is a "special" process. Special processes
     *     are those with a UID < {@link Process#FIRST_APPLICATION_UID}.</li>
     * <li>The calling application has the permission
     *     {@link android.Manifest.permission#ACCESS_INSTANT_APPS}.</li>
     * <li>The calling application is the default launcher on the
     *     system partition.</li>
     * <li>The calling application is the default app prediction service.</li>
     * </ol>
     */
    private boolean canViewInstantApps(int callingUid, int userId) {
        if (callingUid < Process.FIRST_APPLICATION_UID) {
            return true;
        }
        if (mContext.checkCallingOrSelfPermission(
                android.Manifest.permission.ACCESS_INSTANT_APPS) == PERMISSION_GRANTED) {
            return true;
        }
        if (mContext.checkCallingOrSelfPermission(
                android.Manifest.permission.VIEW_INSTANT_APPS) == PERMISSION_GRANTED) {
            final ComponentName homeComponent = getDefaultHomeActivity(userId);
            if (homeComponent != null
                    && isCallerSameApp(homeComponent.getPackageName(), callingUid)) {
                return true;
            }
            // TODO(b/122900055) Change/Remove this and replace with new permission role.
            if (mAppPredictionServicePackage != null
                    && isCallerSameApp(mAppPredictionServicePackage, callingUid)) {
                return true;
            }
        }
        return false;
    }

    private PackageInfo generatePackageInfo(PackageSetting ps, int flags, int userId) {
        if (!mUserManager.exists(userId)) return null;
        if (ps == null) {
            return null;
        }
        final int callingUid = Binder.getCallingUid();
        // Filter out ephemeral app metadata:
        //   * The system/shell/root can see metadata for any app
        //   * An installed app can see metadata for 1) other installed apps
        //     and 2) ephemeral apps that have explicitly interacted with it
        //   * Ephemeral apps can only see their own data and exposed installed apps
        //   * Holding a signature permission allows seeing instant apps
        if (shouldFilterApplicationLocked(ps, callingUid, userId)) {
            return null;
        }

        if ((flags & MATCH_UNINSTALLED_PACKAGES) != 0
                && ps.isSystem()) {
            flags |= MATCH_ANY_USER;
        }

        final PackageUserState state = ps.readUserState(userId);
        AndroidPackage p = ps.pkg;
        if (p != null) {
            final PermissionsState permissionsState = ps.getPermissionsState();

            // Compute GIDs only if requested
            final int[] gids = (flags & PackageManager.GET_GIDS) == 0
                    ? EMPTY_INT_ARRAY : permissionsState.computeGids(userId);
            // Compute granted permissions only if package has requested permissions
            final Set<String> permissions = ArrayUtils.isEmpty(p.getRequestedPermissions())
                    ? Collections.emptySet() : permissionsState.getPermissions(userId);

            PackageInfo packageInfo = PackageInfoUtils.generate(p, gids, flags,
                    ps.firstInstallTime, ps.lastUpdateTime, permissions, state, userId);

            if (packageInfo == null) {
                return null;
            }

            packageInfo.packageName = packageInfo.applicationInfo.packageName =
                    resolveExternalPackageNameLPr(p);

            return packageInfo;
        } else if ((flags & MATCH_UNINSTALLED_PACKAGES) != 0 && state.isAvailable(flags)) {
            PackageInfo pi = new PackageInfo();
            pi.packageName = ps.name;
            pi.setLongVersionCode(ps.versionCode);
            pi.sharedUserId = (ps.sharedUser != null) ? ps.sharedUser.name : null;
            pi.firstInstallTime = ps.firstInstallTime;
            pi.lastUpdateTime = ps.lastUpdateTime;

            ApplicationInfo ai = new ApplicationInfo();
            ai.packageName = ps.name;
            ai.uid = UserHandle.getUid(userId, ps.appId);
            ai.primaryCpuAbi = ps.primaryCpuAbiString;
            ai.secondaryCpuAbi = ps.secondaryCpuAbiString;
            ai.setVersionCode(ps.versionCode);
            ai.flags = ps.pkgFlags;
            ai.privateFlags = ps.pkgPrivateFlags;
            pi.applicationInfo = PackageParser.generateApplicationInfo(ai, flags, state, userId);

            if (DEBUG_PACKAGE_INFO) Log.v(TAG, "ps.pkg is n/a for ["
                    + ps.name + "]. Provides a minimum info.");
            return pi;
        } else {
            return null;
        }
    }

    @Override
    public void checkPackageStartable(String packageName, int userId) {
        final int callingUid = Binder.getCallingUid();
        if (getInstantAppPackageName(callingUid) != null) {
            throw new SecurityException("Instant applications don't have access to this method");
        }
        final boolean userKeyUnlocked = StorageManager.isUserKeyUnlocked(userId);
        synchronized (mLock) {
            final PackageSetting ps = mSettings.mPackages.get(packageName);
            if (ps == null || shouldFilterApplicationLocked(ps, callingUid, userId)) {
                throw new SecurityException("Package " + packageName + " was not found!");
            }

            if (!ps.getInstalled(userId)) {
                throw new SecurityException(
                        "Package " + packageName + " was not installed for user " + userId + "!");
            }

            if (mSafeMode && !ps.isSystem()) {
                throw new SecurityException("Package " + packageName + " not a system app!");
            }

            if (mFrozenPackages.contains(packageName)) {
                throw new SecurityException("Package " + packageName + " is currently frozen!");
            }

            if (!userKeyUnlocked && !ps.pkg.isEncryptionAware()) {
                throw new SecurityException("Package " + packageName + " is not encryption aware!");
            }
        }
    }

    @Override
    public boolean isPackageAvailable(String packageName, int userId) {
        if (!mUserManager.exists(userId)) return false;
        final int callingUid = Binder.getCallingUid();
        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
                false /*requireFullPermission*/, false /*checkShell*/, "is package available");
        synchronized (mLock) {
            AndroidPackage p = mPackages.get(packageName);
            if (p != null) {
                final PackageSetting ps = getPackageSetting(p.getPackageName());
                if (shouldFilterApplicationLocked(ps, callingUid, userId)) {
                    return false;
                }
                if (ps != null) {
                    final PackageUserState state = ps.readUserState(userId);
                    if (state != null) {
                        return PackageParser.isAvailable(state);
                    }
                }
            }
        }
        return false;
    }

    @Override
    public PackageInfo getPackageInfo(String packageName, int flags, int userId) {
        return getPackageInfoInternal(packageName, PackageManager.VERSION_CODE_HIGHEST,
                flags, Binder.getCallingUid(), userId);
    }

    @Override
    public PackageInfo getPackageInfoVersioned(VersionedPackage versionedPackage,
            int flags, int userId) {
        return getPackageInfoInternal(versionedPackage.getPackageName(),
                versionedPackage.getLongVersionCode(), flags, Binder.getCallingUid(), userId);
    }

    /**
     * Important: The provided filterCallingUid is used exclusively to filter out packages
     * that can be seen based on user state. It's typically the original caller uid prior
     * to clearing. Because it can only be provided by trusted code, it's value can be
     * trusted and will be used as-is; unlike userId which will be validated by this method.
     */
    private PackageInfo getPackageInfoInternal(String packageName, long versionCode,
            int flags, int filterCallingUid, int userId) {
        if (!mUserManager.exists(userId)) return null;
        flags = updateFlagsForPackage(flags, userId);
        mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId,
                false /* requireFullPermission */, false /* checkShell */, "get package info");

        // reader
        synchronized (mLock) {
            // Normalize package name to handle renamed packages and static libs
            packageName = resolveInternalPackageNameLPr(packageName, versionCode);

            final boolean matchFactoryOnly = (flags & MATCH_FACTORY_ONLY) != 0;
            if (matchFactoryOnly) {
                // Instant app filtering for APEX modules is ignored
                if ((flags & MATCH_APEX) != 0) {
                    return mApexManager.getPackageInfo(packageName,
                            ApexManager.MATCH_FACTORY_PACKAGE);
                }
                final PackageSetting ps = mSettings.getDisabledSystemPkgLPr(packageName);
                if (ps != null) {
                    if (filterSharedLibPackageLPr(ps, filterCallingUid, userId, flags)) {
                        return null;
                    }
                    if (shouldFilterApplicationLocked(ps, filterCallingUid, userId)) {
                        return null;
                    }
                    return generatePackageInfo(ps, flags, userId);
                }
            }

            AndroidPackage p = mPackages.get(packageName);
            if (matchFactoryOnly && p != null && !isSystemApp(p)) {
                return null;
            }
            if (DEBUG_PACKAGE_INFO)
                Log.v(TAG, "getPackageInfo " + packageName + ": " + p);
            if (p != null) {
                final PackageSetting ps = getPackageSetting(p.getPackageName());
                if (filterSharedLibPackageLPr(ps, filterCallingUid, userId, flags)) {
                    return null;
                }
                if (ps != null && shouldFilterApplicationLocked(ps, filterCallingUid, userId)) {
                    return null;
                }

                return generatePackageInfo(ps, flags, userId);
            }
            if (!matchFactoryOnly && (flags & MATCH_KNOWN_PACKAGES) != 0) {
                final PackageSetting ps = mSettings.mPackages.get(packageName);
                if (ps == null) return null;
                if (filterSharedLibPackageLPr(ps, filterCallingUid, userId, flags)) {
                    return null;
                }
                if (shouldFilterApplicationLocked(ps, filterCallingUid, userId)) {
                    return null;
                }
                return generatePackageInfo(ps, flags, userId);
            }
            if ((flags & MATCH_APEX) != 0) {
                return mApexManager.getPackageInfo(packageName, ApexManager.MATCH_ACTIVE_PACKAGE);
            }
        }
        return null;
    }

    private boolean isComponentVisibleToInstantApp(@Nullable ComponentName component) {
        if (isComponentVisibleToInstantApp(component, TYPE_ACTIVITY)) {
            return true;
        }
        if (isComponentVisibleToInstantApp(component, TYPE_SERVICE)) {
            return true;
        }
        if (isComponentVisibleToInstantApp(component, TYPE_PROVIDER)) {
            return true;
        }
        return false;
    }

    private boolean isComponentVisibleToInstantApp(
            @Nullable ComponentName component, @ComponentType int type) {
        if (type == TYPE_ACTIVITY) {
            final ParsedActivity activity = mComponentResolver.getActivity(component);
            if (activity == null) {
                return false;
            }
            final boolean visibleToInstantApp =
                    (activity.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0;
            final boolean explicitlyVisibleToInstantApp =
                    (activity.flags & ActivityInfo.FLAG_IMPLICITLY_VISIBLE_TO_INSTANT_APP) == 0;
            return visibleToInstantApp && explicitlyVisibleToInstantApp;
        } else if (type == TYPE_RECEIVER) {
            final ParsedActivity activity = mComponentResolver.getReceiver(component);
            if (activity == null) {
                return false;
            }
            final boolean visibleToInstantApp =
                    (activity.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0;
            final boolean explicitlyVisibleToInstantApp =
                    (activity.flags & ActivityInfo.FLAG_IMPLICITLY_VISIBLE_TO_INSTANT_APP) == 0;
            return visibleToInstantApp && !explicitlyVisibleToInstantApp;
        } else if (type == TYPE_SERVICE) {
            final ParsedService service = mComponentResolver.getService(component);
            return service != null
                    ? (service.flags & ServiceInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0
                    : false;
        } else if (type == TYPE_PROVIDER) {
            final ParsedProvider provider = mComponentResolver.getProvider(component);
            return provider != null
                    ? (provider.getFlags() & ProviderInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0
                    : false;
        } else if (type == TYPE_UNKNOWN) {
            return isComponentVisibleToInstantApp(component);
        }
        return false;
    }

    /**
     * Returns whether or not access to the application should be filtered.
     * <p>
     * Access may be limited based upon whether the calling or target applications
     * are instant applications.
     *
     * @see #canViewInstantApps(int, int)
     */
    @GuardedBy("mLock")
    private boolean shouldFilterApplicationLocked(@Nullable PackageSetting ps, int callingUid,
            @Nullable ComponentName component, @ComponentType int componentType, int userId) {
        // if we're in an isolated process, get the real calling UID
        if (Process.isIsolated(callingUid)) {
            callingUid = mIsolatedOwners.get(callingUid);
        }
        final String instantAppPkgName = getInstantAppPackageName(callingUid);
        final boolean callerIsInstantApp = instantAppPkgName != null;
        if (ps == null) {
            if (callerIsInstantApp) {
                // pretend the application exists, but, needs to be filtered
                return true;
            }
            return false;
        }
        // if the target and caller are the same application, don't filter
        if (isCallerSameApp(ps.name, callingUid)) {
            return false;
        }
        if (callerIsInstantApp) {
            // both caller and target are both instant, but, different applications, filter
            if (ps.getInstantApp(userId)) {
                return true;
            }
            // request for a specific component; if it hasn't been explicitly exposed through
            // property or instrumentation target, filter
            if (component != null) {
                final ParsedInstrumentation instrumentation =
                        mInstrumentation.get(component);
                if (instrumentation != null
                        && isCallerSameApp(instrumentation.getTargetPackage(), callingUid)) {
                    return false;
                }
                return !isComponentVisibleToInstantApp(component, componentType);
            }
            // request for application; if no components have been explicitly exposed, filter
            return !ps.pkg.isVisibleToInstantApps();
        }
        if (ps.getInstantApp(userId)) {
            // caller can see all components of all instant applications, don't filter
            if (canViewInstantApps(callingUid, userId)) {
                return false;
            }
            // request for a specific instant application component, filter
            if (component != null) {
                return true;
            }
            // request for an instant application; if the caller hasn't been granted access, filter
            return !mInstantAppRegistry.isInstantAccessGranted(
                    userId, UserHandle.getAppId(callingUid), ps.appId);
        }
        int appId = UserHandle.getAppId(callingUid);
        final SettingBase callingPs = mSettings.getSettingLPr(appId);
        return mAppsFilter.shouldFilterApplication(callingUid, callingPs, ps, userId);
    }

    /**
     * @see #shouldFilterApplicationLocked(PackageSetting, int, ComponentName, int, int)
     */
    @GuardedBy("mLock")
    private boolean shouldFilterApplicationLocked(
            @Nullable PackageSetting ps, int callingUid, int userId) {
        return shouldFilterApplicationLocked(ps, callingUid, null, TYPE_UNKNOWN, userId);
    }

    @GuardedBy("mLock")
    private boolean filterSharedLibPackageLPr(@Nullable PackageSetting ps, int uid, int userId,
            int flags) {
        // Callers can access only the libs they depend on, otherwise they need to explicitly
        // ask for the shared libraries given the caller is allowed to access all static libs.
        if ((flags & PackageManager.MATCH_STATIC_SHARED_LIBRARIES) != 0) {
            // System/shell/root get to see all static libs
            final int appId = UserHandle.getAppId(uid);
            if (appId == Process.SYSTEM_UID || appId == Process.SHELL_UID
                    || appId == Process.ROOT_UID) {
                return false;
            }
            // Installer gets to see all static libs.
            if (PackageManager.PERMISSION_GRANTED
                    == checkUidPermission(Manifest.permission.INSTALL_PACKAGES, uid)) {
                return false;
            }
        }

        // No package means no static lib as it is always on internal storage
        if (ps == null || ps.pkg == null || !ps.pkg.isStaticSharedLibrary()) {
            return false;
        }

        final SharedLibraryInfo libraryInfo = getSharedLibraryInfoLPr(
                ps.pkg.getStaticSharedLibName(), ps.pkg.getStaticSharedLibVersion());
        if (libraryInfo == null) {
            return false;
        }

        final int resolvedUid = UserHandle.getUid(userId, UserHandle.getAppId(uid));
        final String[] uidPackageNames = getPackagesForUid(resolvedUid);
        if (uidPackageNames == null) {
            return true;
        }

        for (String uidPackageName : uidPackageNames) {
            if (ps.name.equals(uidPackageName)) {
                return false;
            }
            PackageSetting uidPs = mSettings.getPackageLPr(uidPackageName);
            if (uidPs != null) {
                final int index = ArrayUtils.indexOf(uidPs.usesStaticLibraries,
                        libraryInfo.getName());
                if (index < 0) {
                    continue;
                }
                if (uidPs.pkg.getUsesStaticLibrariesVersions()[index]
                        == libraryInfo.getLongVersion()) {
                    return false;
                }
            }
        }
        return true;
    }

    @Override
    public String[] currentToCanonicalPackageNames(String[] names) {
        final int callingUid = Binder.getCallingUid();
        if (getInstantAppPackageName(callingUid) != null) {
            return names;
        }
        final String[] out = new String[names.length];
        // reader
        synchronized (mLock) {
            final int callingUserId = UserHandle.getUserId(callingUid);
            final boolean canViewInstantApps = canViewInstantApps(callingUid, callingUserId);
            for (int i=names.length-1; i>=0; i--) {
                final PackageSetting ps = mSettings.mPackages.get(names[i]);
                boolean translateName = false;
                if (ps != null && ps.realName != null) {
                    final boolean targetIsInstantApp = ps.getInstantApp(callingUserId);
                    translateName = !targetIsInstantApp
                            || canViewInstantApps
                            || mInstantAppRegistry.isInstantAccessGranted(callingUserId,
                                    UserHandle.getAppId(callingUid), ps.appId);
                }
                out[i] = translateName ? ps.realName : names[i];
            }
        }
        return out;
    }

    @Override
    public String[] canonicalToCurrentPackageNames(String[] names) {
        final int callingUid = Binder.getCallingUid();
        if (getInstantAppPackageName(callingUid) != null) {
            return names;
        }
        final String[] out = new String[names.length];
        // reader
        synchronized (mLock) {
            final int callingUserId = UserHandle.getUserId(callingUid);
            final boolean canViewInstantApps = canViewInstantApps(callingUid, callingUserId);
            for (int i=names.length-1; i>=0; i--) {
                final String cur = mSettings.getRenamedPackageLPr(names[i]);
                boolean translateName = false;
                if (cur != null) {
                    final PackageSetting ps = mSettings.mPackages.get(names[i]);
                    final boolean targetIsInstantApp =
                            ps != null && ps.getInstantApp(callingUserId);
                    translateName = !targetIsInstantApp
                            || canViewInstantApps
                            || mInstantAppRegistry.isInstantAccessGranted(callingUserId,
                                    UserHandle.getAppId(callingUid), ps.appId);
                }
                out[i] = translateName ? cur : names[i];
            }
        }
        return out;
    }

    @Override
    public int getPackageUid(String packageName, int flags, int userId) {
        if (!mUserManager.exists(userId)) return -1;
        final int callingUid = Binder.getCallingUid();
        flags = updateFlagsForPackage(flags, userId);
        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
                false /*requireFullPermission*/, false /*checkShell*/, "getPackageUid");

        // reader
        synchronized (mLock) {
            final AndroidPackage p = mPackages.get(packageName);
            if (p != null && p.isMatch(flags)) {
                PackageSetting ps = getPackageSetting(p.getPackageName());
                if (shouldFilterApplicationLocked(ps, callingUid, userId)) {
                    return -1;
                }
                return UserHandle.getUid(userId, p.getUid());
            }
            if ((flags & MATCH_KNOWN_PACKAGES) != 0) {
                final PackageSetting ps = mSettings.mPackages.get(packageName);
                if (ps != null && ps.isMatch(flags)
                        && !shouldFilterApplicationLocked(ps, callingUid, userId)) {
                    return UserHandle.getUid(userId, ps.appId);
                }
            }
        }

        return -1;
    }

    @Override
    public int[] getPackageGids(String packageName, int flags, int userId) {
        if (!mUserManager.exists(userId)) return null;
        final int callingUid = Binder.getCallingUid();
        flags = updateFlagsForPackage(flags, userId);
        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
                false /*requireFullPermission*/, false /*checkShell*/, "getPackageGids");

        // reader
        synchronized (mLock) {
            final AndroidPackage p = mPackages.get(packageName);
            if (p != null && p.isMatch(flags)) {
                PackageSetting ps = getPackageSetting(p.getPackageName());
                if (shouldFilterApplicationLocked(ps, callingUid, userId)) {
                    return null;
                }
                // TODO: Shouldn't this be checking for package installed state for userId and
                // return null?
                return ps.getPermissionsState().computeGids(userId);
            }
            if ((flags & MATCH_KNOWN_PACKAGES) != 0) {
                final PackageSetting ps = mSettings.mPackages.get(packageName);
                if (ps != null && ps.isMatch(flags)
                        && !shouldFilterApplicationLocked(ps, callingUid, userId)) {
                    return ps.getPermissionsState().computeGids(userId);
                }
            }
        }

        return null;
    }

    // NOTE: Can't remove due to unsupported app usage
    @Override
    public PermissionGroupInfo getPermissionGroupInfo(String groupName, int flags) {
        try {
            // Because this is accessed via the package manager service AIDL,
            // go through the permission manager service AIDL
            return mPermissionManagerService.getPermissionGroupInfo(groupName, flags);
        } catch (RemoteException ignore) { }
        return null;
    }

    @GuardedBy("mLock")
    private ApplicationInfo generateApplicationInfoFromSettingsLPw(String packageName, int flags,
            int filterCallingUid, int userId) {
        if (!mUserManager.exists(userId)) return null;
        PackageSetting ps = mSettings.mPackages.get(packageName);
        if (ps != null) {
            if (filterSharedLibPackageLPr(ps, filterCallingUid, userId, flags)) {
                return null;
            }
            if (shouldFilterApplicationLocked(ps, filterCallingUid, userId)) {
                return null;
            }
            if (ps.pkg == null) {
                final PackageInfo pInfo = generatePackageInfo(ps, flags, userId);
                if (pInfo != null) {
                    return pInfo.applicationInfo;
                }
                return null;
            }
            ApplicationInfo ai = PackageInfoUtils.generateApplicationInfo(ps.pkg, flags,
                    ps.readUserState(userId), userId);
            if (ai != null) {
                ai.packageName = resolveExternalPackageNameLPr(ps.pkg);
            }
            return ai;
        }
        return null;
    }

    @Override
    public ApplicationInfo getApplicationInfo(String packageName, int flags, int userId) {
        return getApplicationInfoInternal(packageName, flags, Binder.getCallingUid(), userId);
    }

    /**
     * Important: The provided filterCallingUid is used exclusively to filter out applications
     * that can be seen based on user state. It's typically the original caller uid prior
     * to clearing. Because it can only be provided by trusted code, it's value can be
     * trusted and will be used as-is; unlike userId which will be validated by this method.
     */
    private ApplicationInfo getApplicationInfoInternal(String packageName, int flags,
            int filterCallingUid, int userId) {
        if (!mUserManager.exists(userId)) return null;
        flags = updateFlagsForApplication(flags, userId);

        if (!isRecentsAccessingChildProfiles(Binder.getCallingUid(), userId)) {
            mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId,
                    false /* requireFullPermission */, false /* checkShell */,
                    "get application info");
        }

        // writer
        synchronized (mLock) {
            // Normalize package name to handle renamed packages and static libs
            packageName = resolveInternalPackageNameLPr(packageName,
                    PackageManager.VERSION_CODE_HIGHEST);

            AndroidPackage p = mPackages.get(packageName);
            if (DEBUG_PACKAGE_INFO) Log.v(
                    TAG, "getApplicationInfo " + packageName
                    + ": " + p);
            if (p != null) {
                PackageSetting ps = mSettings.mPackages.get(packageName);
                if (ps == null) return null;
                if (filterSharedLibPackageLPr(ps, filterCallingUid, userId, flags)) {
                    return null;
                }
                if (shouldFilterApplicationLocked(ps, filterCallingUid, userId)) {
                    return null;
                }
                // Note: isEnabledLP() does not apply here - always return info
                ApplicationInfo ai = PackageInfoUtils.generateApplicationInfo(
                        p, flags, ps.readUserState(userId), userId);
                if (ai != null) {
                    ai.packageName = resolveExternalPackageNameLPr(p);
                }
                return ai;
            }
            if ("android".equals(packageName)||"system".equals(packageName)) {
                return mAndroidApplication;
            }
            if ((flags & MATCH_KNOWN_PACKAGES) != 0) {
                // Already generates the external package name
                return generateApplicationInfoFromSettingsLPw(packageName,
                        flags, filterCallingUid, userId);
            }
        }
        return null;
    }

    @GuardedBy("mLock")
    private String normalizePackageNameLPr(String packageName) {
        String normalizedPackageName = mSettings.getRenamedPackageLPr(packageName);
        return normalizedPackageName != null ? normalizedPackageName : packageName;
    }

    @Override
    public void deletePreloadsFileCache() {
        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.CLEAR_APP_CACHE,
                "deletePreloadsFileCache");
        File dir = Environment.getDataPreloadsFileCacheDirectory();
        Slog.i(TAG, "Deleting preloaded file cache " + dir);
        FileUtils.deleteContents(dir);
    }

    @Override
    public void freeStorageAndNotify(final String volumeUuid, final long freeStorageSize,
            final int storageFlags, final IPackageDataObserver observer) {
        mContext.enforceCallingOrSelfPermission(
                android.Manifest.permission.CLEAR_APP_CACHE, null);
        mHandler.post(() -> {
            boolean success = false;
            try {
                freeStorage(volumeUuid, freeStorageSize, storageFlags);
                success = true;
            } catch (IOException e) {
                Slog.w(TAG, e);
            }
            if (observer != null) {
                try {
                    observer.onRemoveCompleted(null, success);
                } catch (RemoteException e) {
                    Slog.w(TAG, e);
                }
            }
        });
    }

    @Override
    public void freeStorage(final String volumeUuid, final long freeStorageSize,
            final int storageFlags, final IntentSender pi) {
        mContext.enforceCallingOrSelfPermission(
                android.Manifest.permission.CLEAR_APP_CACHE, TAG);
        mHandler.post(() -> {
            boolean success = false;
            try {
                freeStorage(volumeUuid, freeStorageSize, storageFlags);
                success = true;
            } catch (IOException e) {
                Slog.w(TAG, e);
            }
            if (pi != null) {
                try {
                    pi.sendIntent(null, success ? 1 : 0, null, null, null);
                } catch (SendIntentException e) {
                    Slog.w(TAG, e);
                }
            }
        });
    }

    /**
     * Blocking call to clear various types of cached data across the system
     * until the requested bytes are available.
     */
    public void freeStorage(String volumeUuid, long bytes, int storageFlags) throws IOException {
        final StorageManager storage = mInjector.getStorageManager();
        final File file = storage.findPathForUuid(volumeUuid);
        if (file.getUsableSpace() >= bytes) return;

        if (ENABLE_FREE_CACHE_V2) {
            final boolean internalVolume = Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL,
                    volumeUuid);
            final boolean aggressive = (storageFlags
                    & StorageManager.FLAG_ALLOCATE_AGGRESSIVE) != 0;
            final long reservedBytes = storage.getStorageCacheBytes(file, storageFlags);

            // 1. Pre-flight to determine if we have any chance to succeed
            // 2. Consider preloaded data (after 1w honeymoon, unless aggressive)
            if (internalVolume && (aggressive || SystemProperties
                    .getBoolean("persist.sys.preloads.file_cache_expired", false))) {
                deletePreloadsFileCache();
                if (file.getUsableSpace() >= bytes) return;
            }

            // 3. Consider parsed APK data (aggressive only)
            if (internalVolume && aggressive) {
                FileUtils.deleteContents(mCacheDir);
                if (file.getUsableSpace() >= bytes) return;
            }

            // 4. Consider cached app data (above quotas)
            try {
                mInstaller.freeCache(volumeUuid, bytes, reservedBytes,
                        Installer.FLAG_FREE_CACHE_V2);
            } catch (InstallerException ignored) {
            }
            if (file.getUsableSpace() >= bytes) return;

            // 5. Consider shared libraries with refcount=0 and age>min cache period
            if (internalVolume && pruneUnusedStaticSharedLibraries(bytes,
                    android.provider.Settings.Global.getLong(mContext.getContentResolver(),
                            Global.UNUSED_STATIC_SHARED_LIB_MIN_CACHE_PERIOD,
                            DEFAULT_UNUSED_STATIC_SHARED_LIB_MIN_CACHE_PERIOD))) {
                return;
            }

            // 6. Consider dexopt output (aggressive only)
            // TODO: Implement

            // 7. Consider installed instant apps unused longer than min cache period
            if (internalVolume && mInstantAppRegistry.pruneInstalledInstantApps(bytes,
                    android.provider.Settings.Global.getLong(mContext.getContentResolver(),
                            Global.INSTALLED_INSTANT_APP_MIN_CACHE_PERIOD,
                            InstantAppRegistry.DEFAULT_INSTALLED_INSTANT_APP_MIN_CACHE_PERIOD))) {
                return;
            }

            // 8. Consider cached app data (below quotas)
            try {
                mInstaller.freeCache(volumeUuid, bytes, reservedBytes,
                        Installer.FLAG_FREE_CACHE_V2 | Installer.FLAG_FREE_CACHE_V2_DEFY_QUOTA);
            } catch (InstallerException ignored) {
            }
            if (file.getUsableSpace() >= bytes) return;

            // 9. Consider DropBox entries
            // TODO: Implement

            // 10. Consider instant meta-data (uninstalled apps) older that min cache period
            if (internalVolume && mInstantAppRegistry.pruneUninstalledInstantApps(bytes,
                    android.provider.Settings.Global.getLong(mContext.getContentResolver(),
                            Global.UNINSTALLED_INSTANT_APP_MIN_CACHE_PERIOD,
                            InstantAppRegistry.DEFAULT_UNINSTALLED_INSTANT_APP_MIN_CACHE_PERIOD))) {
                return;
            }
        } else {
            try {
                mInstaller.freeCache(volumeUuid, bytes, 0, 0);
            } catch (InstallerException ignored) {
            }
            if (file.getUsableSpace() >= bytes) return;
        }

        throw new IOException("Failed to free " + bytes + " on storage device at " + file);
    }

    private boolean pruneUnusedStaticSharedLibraries(long neededSpace, long maxCachePeriod)
            throws IOException {
        final StorageManager storage = mInjector.getStorageManager();
        final File volume = storage.findPathForUuid(StorageManager.UUID_PRIVATE_INTERNAL);

        List<VersionedPackage> packagesToDelete = null;
        final long now = System.currentTimeMillis();

        synchronized (mLock) {
            final int[] allUsers = mUserManager.getUserIds();
            final int libCount = mSharedLibraries.size();
            for (int i = 0; i < libCount; i++) {
                final LongSparseArray<SharedLibraryInfo> versionedLib
                        = mSharedLibraries.valueAt(i);
                if (versionedLib == null) {
                    continue;
                }
                final int versionCount = versionedLib.size();
                for (int j = 0; j < versionCount; j++) {
                    SharedLibraryInfo libInfo = versionedLib.valueAt(j);
                    // Skip packages that are not static shared libs.
                    if (!libInfo.isStatic()) {
                        break;
                    }
                    // Important: We skip static shared libs used for some user since
                    // in such a case we need to keep the APK on the device. The check for
                    // a lib being used for any user is performed by the uninstall call.
                    final VersionedPackage declaringPackage = libInfo.getDeclaringPackage();
                    // Resolve the package name - we use synthetic package names internally
                    final String internalPackageName = resolveInternalPackageNameLPr(
                            declaringPackage.getPackageName(),
                            declaringPackage.getLongVersionCode());
                    final PackageSetting ps = mSettings.getPackageLPr(internalPackageName);
                    // Skip unused static shared libs cached less than the min period
                    // to prevent pruning a lib needed by a subsequently installed package.
                    if (ps == null || now - ps.lastUpdateTime < maxCachePeriod) {
                        continue;
                    }

                    if (ps.pkg.isSystem()) {
                        continue;
                    }

                    if (packagesToDelete == null) {
                        packagesToDelete = new ArrayList<>();
                    }
                    packagesToDelete.add(new VersionedPackage(internalPackageName,
                            declaringPackage.getLongVersionCode()));
                }
            }
        }

        if (packagesToDelete != null) {
            final int packageCount = packagesToDelete.size();
            for (int i = 0; i < packageCount; i++) {
                final VersionedPackage pkgToDelete = packagesToDelete.get(i);
                // Delete the package synchronously (will fail of the lib used for any user).
                if (deletePackageX(pkgToDelete.getPackageName(), pkgToDelete.getLongVersionCode(),
                        UserHandle.USER_SYSTEM, PackageManager.DELETE_ALL_USERS)
                                == PackageManager.DELETE_SUCCEEDED) {
                    if (volume.getUsableSpace() >= neededSpace) {
                        return true;
                    }
                }
            }
        }

        return false;
    }

    /**
     * Update given flags based on encryption status of current user.
     */
    private int updateFlags(int flags, int userId) {
        if ((flags & (PackageManager.MATCH_DIRECT_BOOT_UNAWARE
                | PackageManager.MATCH_DIRECT_BOOT_AWARE)) != 0) {
            // Caller expressed an explicit opinion about what encryption
            // aware/unaware components they want to see, so fall through and
            // give them what they want
        } else {
            // Caller expressed no opinion, so match based on user state
            if (mUserManager.isUserUnlockingOrUnlocked(userId)) {
                flags |= PackageManager.MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE;
            } else {
                flags |= PackageManager.MATCH_DIRECT_BOOT_AWARE;
            }
        }
        return flags;
    }

    /**
     * Update given flags when being used to request {@link PackageInfo}.
     */
    private int updateFlagsForPackage(int flags, int userId) {
        final boolean isCallerSystemUser = UserHandle.getCallingUserId() == UserHandle.USER_SYSTEM;
        if ((flags & PackageManager.MATCH_ANY_USER) != 0) {
            // require the permission to be held; the calling uid and given user id referring
            // to the same user is not sufficient
            mPermissionManager.enforceCrossUserPermission(
                    Binder.getCallingUid(), userId, false, false,
                    !isRecentsAccessingChildProfiles(Binder.getCallingUid(), userId),
                    "MATCH_ANY_USER flag requires INTERACT_ACROSS_USERS permission at "
                    + Debug.getCallers(5));
        } else if ((flags & PackageManager.MATCH_UNINSTALLED_PACKAGES) != 0 && isCallerSystemUser
                && mUserManager.hasManagedProfile(UserHandle.USER_SYSTEM)) {
            // If the caller wants all packages and has a restricted profile associated with it,
            // then match all users. This is to make sure that launchers that need to access work
            // profile apps don't start breaking. TODO: Remove this hack when launchers stop using
            // MATCH_UNINSTALLED_PACKAGES to query apps in other profiles. b/31000380
            flags |= PackageManager.MATCH_ANY_USER;
        }
        return updateFlags(flags, userId);
    }

    /**
     * Update given flags when being used to request {@link ApplicationInfo}.
     */
    private int updateFlagsForApplication(int flags, int userId) {
        return updateFlagsForPackage(flags, userId);
    }

    /**
     * Update given flags when being used to request {@link ComponentInfo}.
     */
    private int updateFlagsForComponent(int flags, int userId) {
        return updateFlags(flags, userId);
    }

    /**
     * Update given intent when being used to request {@link ResolveInfo}.
     */
    private Intent updateIntentForResolve(Intent intent) {
        if (intent.getSelector() != null) {
            intent = intent.getSelector();
        }
        if (DEBUG_PREFERRED) {
            intent.addFlags(Intent.FLAG_DEBUG_LOG_RESOLUTION);
        }
        return intent;
    }

    /**
     * Update given flags when being used to request {@link ResolveInfo}.
     * <p>Instant apps are resolved specially, depending upon context. Minimally,
     * {@code}flags{@code} must have the {@link PackageManager#MATCH_INSTANT}
     * flag set. However, this flag is only honoured in three circumstances:
     * <ul>
     * <li>when called from a system process</li>
     * <li>when the caller holds the permission {@code android.permission.ACCESS_INSTANT_APPS}</li>
     * <li>when resolution occurs to start an activity with a {@code android.intent.action.VIEW}
     * action and a {@code android.intent.category.BROWSABLE} category</li>
     * </ul>
     */
    int updateFlagsForResolve(int flags, int userId, int callingUid, boolean wantInstantApps) {
        return updateFlagsForResolve(flags, userId, callingUid,
                wantInstantApps, false /*onlyExposedExplicitly*/);
    }

    int updateFlagsForResolve(int flags, int userId, int callingUid,
            boolean wantInstantApps, boolean onlyExposedExplicitly) {
        // Safe mode means we shouldn't match any third-party components
        if (mSafeMode) {
            flags |= PackageManager.MATCH_SYSTEM_ONLY;
        }
        if (getInstantAppPackageName(callingUid) != null) {
            // But, ephemeral apps see both ephemeral and exposed, non-ephemeral components
            if (onlyExposedExplicitly) {
                flags |= PackageManager.MATCH_EXPLICITLY_VISIBLE_ONLY;
            }
            flags |= PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY;
            flags |= PackageManager.MATCH_INSTANT;
        } else {
            final boolean wantMatchInstant = (flags & PackageManager.MATCH_INSTANT) != 0;
            final boolean allowMatchInstant = wantInstantApps
                    || (wantMatchInstant && canViewInstantApps(callingUid, userId));
            flags &= ~(PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY
                    | PackageManager.MATCH_EXPLICITLY_VISIBLE_ONLY);
            if (!allowMatchInstant) {
                flags &= ~PackageManager.MATCH_INSTANT;
            }
        }
        return updateFlagsForComponent(flags, userId);
    }

    @Override
    public ActivityInfo getActivityInfo(ComponentName component, int flags, int userId) {
        return getActivityInfoInternal(component, flags, Binder.getCallingUid(), userId);
    }

    /**
     * Important: The provided filterCallingUid is used exclusively to filter out activities
     * that can be seen based on user state. It's typically the original caller uid prior
     * to clearing. Because it can only be provided by trusted code, it's value can be
     * trusted and will be used as-is; unlike userId which will be validated by this method.
     */
    private ActivityInfo getActivityInfoInternal(ComponentName component, int flags,
            int filterCallingUid, int userId) {
        if (!mUserManager.exists(userId)) return null;
        flags = updateFlagsForComponent(flags, userId);

        if (!isRecentsAccessingChildProfiles(Binder.getCallingUid(), userId)) {
            mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId,
                    false /* requireFullPermission */, false /* checkShell */, "get activity info");
        }

        synchronized (mLock) {
            ParsedActivity a = mComponentResolver.getActivity(component);

            if (DEBUG_PACKAGE_INFO) Log.v(TAG, "getActivityInfo " + component + ": " + a);

            AndroidPackage pkg = a == null ? null : mPackages.get(a.getPackageName());
            if (pkg != null && mSettings.isEnabledAndMatchLPr(pkg, a, flags, userId)) {
                PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
                if (ps == null) return null;
                if (shouldFilterApplicationLocked(
                        ps, filterCallingUid, component, TYPE_ACTIVITY, userId)) {
                    return null;
                }
                return PackageInfoUtils.generateActivityInfo(pkg,
                        a, flags, ps.readUserState(userId), userId);
            }
            if (mResolveComponentName.equals(component)) {
                return PackageParser.generateActivityInfo(
                        mResolveActivity, flags, new PackageUserState(), userId);
            }
        }
        return null;
    }

    private boolean isRecentsAccessingChildProfiles(int callingUid, int targetUserId) {
        if (!mInjector.getActivityTaskManagerInternal().isCallerRecents(callingUid)) {
            return false;
        }
        final long token = Binder.clearCallingIdentity();
        try {
            final int callingUserId = UserHandle.getUserId(callingUid);
            if (ActivityManager.getCurrentUser() != callingUserId) {
                return false;
            }
            return mUserManager.isSameProfileGroup(callingUserId, targetUserId);
        } finally {
            Binder.restoreCallingIdentity(token);
        }
    }

    @Override
    public boolean activitySupportsIntent(ComponentName component, Intent intent,
            String resolvedType) {
        synchronized (mLock) {
            if (component.equals(mResolveComponentName)) {
                // The resolver supports EVERYTHING!
                return true;
            }
            final int callingUid = Binder.getCallingUid();
            final int callingUserId = UserHandle.getUserId(callingUid);
            ParsedActivity a = mComponentResolver.getActivity(component);
            if (a == null) {
                return false;
            }
            PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
            if (ps == null) {
                return false;
            }
            if (shouldFilterApplicationLocked(
                    ps, callingUid, component, TYPE_ACTIVITY, callingUserId)) {
                return false;
            }
            for (int i=0; i<a.intents.size(); i++) {
                if (a.intents.get(i).match(intent.getAction(), resolvedType, intent.getScheme(),
                        intent.getData(), intent.getCategories(), TAG) >= 0) {
                    return true;
                }
            }
            return false;
        }
    }

    @Override
    public ActivityInfo getReceiverInfo(ComponentName component, int flags, int userId) {
        if (!mUserManager.exists(userId)) return null;
        final int callingUid = Binder.getCallingUid();
        flags = updateFlagsForComponent(flags, userId);
        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
                false /* requireFullPermission */, false /* checkShell */, "get receiver info");
        synchronized (mLock) {
            ParsedActivity a = mComponentResolver.getReceiver(component);
            if (DEBUG_PACKAGE_INFO) Log.v(
                TAG, "getReceiverInfo " + component + ": " + a);

            if (a == null) {
                return null;
            }

            AndroidPackage pkg = mPackages.get(a.getPackageName());
            if (pkg == null) {
                return null;
            }

            if (mSettings.isEnabledAndMatchLPr(pkg, a, flags, userId)) {
                PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
                if (ps == null) return null;
                if (shouldFilterApplicationLocked(
                        ps, callingUid, component, TYPE_RECEIVER, userId)) {
                    return null;
                }
                return PackageInfoUtils.generateActivityInfo(pkg,
                        a, flags, ps.readUserState(userId), userId);
            }
        }
        return null;
    }

    @Override
    public ParceledListSlice<SharedLibraryInfo> getSharedLibraries(String packageName,
            int flags, int userId) {
        if (!mUserManager.exists(userId)) return null;
        Preconditions.checkArgumentNonnegative(userId, "userId must be >= 0");
        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
            return null;
        }

        flags = updateFlagsForPackage(flags, userId);

        final boolean canSeeStaticLibraries =
                mContext.checkCallingOrSelfPermission(INSTALL_PACKAGES)
                        == PERMISSION_GRANTED
                || mContext.checkCallingOrSelfPermission(DELETE_PACKAGES)
                        == PERMISSION_GRANTED
                || canRequestPackageInstallsInternal(packageName,
                        PackageManager.MATCH_STATIC_SHARED_LIBRARIES, userId,
                        false  /* throwIfPermNotDeclared*/)
                || mContext.checkCallingOrSelfPermission(REQUEST_DELETE_PACKAGES)
                        == PERMISSION_GRANTED
                || mContext.checkCallingOrSelfPermission(
                        Manifest.permission.ACCESS_SHARED_LIBRARIES) == PERMISSION_GRANTED;

        synchronized (mLock) {
            List<SharedLibraryInfo> result = null;

            final int libCount = mSharedLibraries.size();
            for (int i = 0; i < libCount; i++) {
                LongSparseArray<SharedLibraryInfo> versionedLib = mSharedLibraries.valueAt(i);
                if (versionedLib == null) {
                    continue;
                }

                final int versionCount = versionedLib.size();
                for (int j = 0; j < versionCount; j++) {
                    SharedLibraryInfo libInfo = versionedLib.valueAt(j);
                    if (!canSeeStaticLibraries && libInfo.isStatic()) {
                        break;
                    }
                    final long identity = Binder.clearCallingIdentity();
                    try {
                        PackageInfo packageInfo = getPackageInfoVersioned(
                                libInfo.getDeclaringPackage(), flags
                                        | PackageManager.MATCH_STATIC_SHARED_LIBRARIES, userId);
                        if (packageInfo == null) {
                            continue;
                        }
                    } finally {
                        Binder.restoreCallingIdentity(identity);
                    }

                    SharedLibraryInfo resLibInfo = new SharedLibraryInfo(libInfo.getPath(),
                            libInfo.getPackageName(), libInfo.getAllCodePaths(),
                            libInfo.getName(), libInfo.getLongVersion(),
                            libInfo.getType(), libInfo.getDeclaringPackage(),
                            getPackagesUsingSharedLibraryLPr(libInfo, flags, userId),
                            (libInfo.getDependencies() == null
                                    ? null
                                    : new ArrayList<>(libInfo.getDependencies())));

                    if (result == null) {
                        result = new ArrayList<>();
                    }
                    result.add(resLibInfo);
                }
            }

            return result != null ? new ParceledListSlice<>(result) : null;
        }
    }

    @Nullable
    @Override
    public ParceledListSlice<SharedLibraryInfo> getDeclaredSharedLibraries(
            @NonNull String packageName, int flags, @NonNull int userId) {
        mContext.enforceCallingOrSelfPermission(Manifest.permission.ACCESS_SHARED_LIBRARIES,
                "getDeclaredSharedLibraries");
        int callingUid = Binder.getCallingUid();
        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
                true /* requireFullPermission */, false /* checkShell */,
                "getDeclaredSharedLibraries");

        Preconditions.checkNotNull(packageName, "packageName cannot be null");
        Preconditions.checkArgumentNonnegative(userId, "userId must be >= 0");
        if (!mUserManager.exists(userId)) {
            return null;
        }

        if (getInstantAppPackageName(callingUid) != null) {
            return null;
        }

        synchronized (mLock) {
            List<SharedLibraryInfo> result = null;

            int libraryCount = mSharedLibraries.size();
            for (int i = 0; i < libraryCount; i++) {
                LongSparseArray<SharedLibraryInfo> versionedLibrary = mSharedLibraries.valueAt(i);
                if (versionedLibrary == null) {
                    continue;
                }

                int versionCount = versionedLibrary.size();
                for (int j = 0; j < versionCount; j++) {
                    SharedLibraryInfo libraryInfo = versionedLibrary.valueAt(j);

                    VersionedPackage declaringPackage = libraryInfo.getDeclaringPackage();
                    if (!Objects.equals(declaringPackage.getPackageName(), packageName)) {
                        continue;
                    }

                    long identity = Binder.clearCallingIdentity();
                    try {
                        PackageInfo packageInfo = getPackageInfoVersioned(declaringPackage, flags
                                | PackageManager.MATCH_STATIC_SHARED_LIBRARIES, userId);
                        if (packageInfo == null) {
                            continue;
                        }
                    } finally {
                        Binder.restoreCallingIdentity(identity);
                    }

                    SharedLibraryInfo resultLibraryInfo = new SharedLibraryInfo(
                            libraryInfo.getPath(), libraryInfo.getPackageName(),
                            libraryInfo.getAllCodePaths(), libraryInfo.getName(),
                            libraryInfo.getLongVersion(), libraryInfo.getType(),
                            libraryInfo.getDeclaringPackage(), getPackagesUsingSharedLibraryLPr(
                            libraryInfo, flags, userId), libraryInfo.getDependencies() == null
                            ? null : new ArrayList<>(libraryInfo.getDependencies()));

                    if (result == null) {
                        result = new ArrayList<>();
                    }
                    result.add(resultLibraryInfo);
                }
            }

            return result != null ? new ParceledListSlice<>(result) : null;
        }
    }

    @GuardedBy("mLock")
    private List<VersionedPackage> getPackagesUsingSharedLibraryLPr(
            SharedLibraryInfo libInfo, int flags, int userId) {
        List<VersionedPackage> versionedPackages = null;
        final int packageCount = mSettings.mPackages.size();
        for (int i = 0; i < packageCount; i++) {
            PackageSetting ps = mSettings.mPackages.valueAt(i);

            if (ps == null) {
                continue;
            }

            if (!ps.readUserState(userId).isAvailable(flags)) {
                continue;
            }

            final String libName = libInfo.getName();
            if (libInfo.isStatic()) {
                final int libIdx = ArrayUtils.indexOf(ps.usesStaticLibraries, libName);
                if (libIdx < 0) {
                    continue;
                }
                if (ps.usesStaticLibrariesVersions[libIdx] != libInfo.getLongVersion()) {
                    continue;
                }
                if (versionedPackages == null) {
                    versionedPackages = new ArrayList<>();
                }
                // If the dependent is a static shared lib, use the public package name
                String dependentPackageName = ps.name;
                if (ps.pkg != null && ps.pkg.isStaticSharedLibrary()) {
                    dependentPackageName = ps.pkg.getManifestPackageName();
                }
                versionedPackages.add(new VersionedPackage(dependentPackageName, ps.versionCode));
            } else if (ps.pkg != null) {
                if (ArrayUtils.contains(ps.pkg.getUsesLibraries(), libName)
                        || ArrayUtils.contains(ps.pkg.getUsesOptionalLibraries(), libName)) {
                    if (versionedPackages == null) {
                        versionedPackages = new ArrayList<>();
                    }
                    versionedPackages.add(new VersionedPackage(ps.name, ps.versionCode));
                }
            }
        }

        return versionedPackages;
    }

    @Override
    public ServiceInfo getServiceInfo(ComponentName component, int flags, int userId) {
        if (!mUserManager.exists(userId)) return null;
        final int callingUid = Binder.getCallingUid();
        flags = updateFlagsForComponent(flags, userId);
        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
                false /* requireFullPermission */, false /* checkShell */, "get service info");
        synchronized (mLock) {
            ParsedService s = mComponentResolver.getService(component);
            if (DEBUG_PACKAGE_INFO) Log.v(
                    TAG, "getServiceInfo " + component + ": " + s);
            if (s == null) {
                return null;
            }

            AndroidPackage pkg = mPackages.get(s.getPackageName());
            if (mSettings.isEnabledAndMatchLPr(pkg, s, flags, userId)) {
                PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
                if (ps == null) return null;
                if (shouldFilterApplicationLocked(
                        ps, callingUid, component, TYPE_SERVICE, userId)) {
                    return null;
                }
                return PackageInfoUtils.generateServiceInfo(pkg,
                        s, flags, ps.readUserState(userId), userId);
            }
        }
        return null;
    }

    @Override
    public ProviderInfo getProviderInfo(ComponentName component, int flags, int userId) {
        if (!mUserManager.exists(userId)) return null;
        final int callingUid = Binder.getCallingUid();
        flags = updateFlagsForComponent(flags, userId);
        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
                false /* requireFullPermission */, false /* checkShell */, "get provider info");
        synchronized (mLock) {
            ParsedProvider p = mComponentResolver.getProvider(component);
            if (DEBUG_PACKAGE_INFO) Log.v(
                    TAG, "getProviderInfo " + component + ": " + p);
            if (p == null) {
                return null;
            }

            AndroidPackage pkg = mPackages.get(p.getPackageName());
            if (pkg == null) {
                return null;
            }

            if (mSettings.isEnabledAndMatchLPr(pkg, p, flags, userId)) {
                PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
                if (ps == null) return null;
                if (shouldFilterApplicationLocked(
                        ps, callingUid, component, TYPE_PROVIDER, userId)) {
                    return null;
                }
                PackageUserState state = ps.readUserState(userId);
                return PackageInfoUtils.generateProviderInfo(pkg, p, flags, state, userId);
            }
        }
        return null;
    }

    @Override
    public ModuleInfo getModuleInfo(String packageName, @ModuleInfoFlags int flags) {
        return mModuleInfoProvider.getModuleInfo(packageName, flags);
    }

    @Override
    public List<ModuleInfo> getInstalledModules(int flags) {
        return mModuleInfoProvider.getInstalledModules(flags);
    }

    @Override
    public String[] getSystemSharedLibraryNames() {
        // allow instant applications
        synchronized (mLock) {
            Set<String> libs = null;
            final int libCount = mSharedLibraries.size();
            for (int i = 0; i < libCount; i++) {
                LongSparseArray<SharedLibraryInfo> versionedLib = mSharedLibraries.valueAt(i);
                if (versionedLib == null) {
                    continue;
                }
                final int versionCount = versionedLib.size();
                for (int j = 0; j < versionCount; j++) {
                    SharedLibraryInfo libraryInfo = versionedLib.valueAt(j);
                    if (!libraryInfo.isStatic()) {
                        if (libs == null) {
                            libs = new ArraySet<>();
                        }
                        libs.add(libraryInfo.getName());
                        break;
                    }
                    PackageSetting ps = mSettings.getPackageLPr(libraryInfo.getPackageName());
                    if (ps != null && !filterSharedLibPackageLPr(ps, Binder.getCallingUid(),
                            UserHandle.getUserId(Binder.getCallingUid()),
                            PackageManager.MATCH_STATIC_SHARED_LIBRARIES)) {
                        if (libs == null) {
                            libs = new ArraySet<>();
                        }
                        libs.add(libraryInfo.getName());
                        break;
                    }
                }
            }

            if (libs != null) {
                String[] libsArray = new String[libs.size()];
                libs.toArray(libsArray);
                return libsArray;
            }

            return null;
        }
    }

    @Override
    public @NonNull String getServicesSystemSharedLibraryPackageName() {
        // allow instant applications
        synchronized (mLock) {
            return mServicesSystemSharedLibraryPackageName;
        }
    }

    @Override
    public @NonNull String getSharedSystemSharedLibraryPackageName() {
        // allow instant applications
        synchronized (mLock) {
            return mSharedSystemSharedLibraryPackageName;
        }
    }

    @GuardedBy("mLock")
    private void updateSequenceNumberLP(PackageSetting pkgSetting, int[] userList) {
        for (int i = userList.length - 1; i >= 0; --i) {
            final int userId = userList[i];
            // don't add instant app to the list of updates
            if (pkgSetting.getInstantApp(userId)) {
                continue;
            }
            SparseArray<String> changedPackages = mChangedPackages.get(userId);
            if (changedPackages == null) {
                changedPackages = new SparseArray<>();
                mChangedPackages.put(userId, changedPackages);
            }
            Map<String, Integer> sequenceNumbers = mChangedPackagesSequenceNumbers.get(userId);
            if (sequenceNumbers == null) {
                sequenceNumbers = new HashMap<>();
                mChangedPackagesSequenceNumbers.put(userId, sequenceNumbers);
            }
            final Integer sequenceNumber = sequenceNumbers.get(pkgSetting.name);
            if (sequenceNumber != null) {
                changedPackages.remove(sequenceNumber);
            }
            changedPackages.put(mChangedPackagesSequenceNumber, pkgSetting.name);
            sequenceNumbers.put(pkgSetting.name, mChangedPackagesSequenceNumber);
        }
        mChangedPackagesSequenceNumber++;
    }

    @Override
    public ChangedPackages getChangedPackages(int sequenceNumber, int userId) {
        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
            return null;
        }
        synchronized (mLock) {
            if (sequenceNumber >= mChangedPackagesSequenceNumber) {
                return null;
            }
            final SparseArray<String> changedPackages = mChangedPackages.get(userId);
            if (changedPackages == null) {
                return null;
            }
            final List<String> packageNames =
                    new ArrayList<>(mChangedPackagesSequenceNumber - sequenceNumber);
            for (int i = sequenceNumber; i < mChangedPackagesSequenceNumber; i++) {
                final String packageName = changedPackages.get(i);
                if (packageName != null) {
                    packageNames.add(packageName);
                }
            }
            return packageNames.isEmpty()
                    ? null : new ChangedPackages(mChangedPackagesSequenceNumber, packageNames);
        }
    }

    @Override
    public @NonNull ParceledListSlice<FeatureInfo> getSystemAvailableFeatures() {
        // allow instant applications
        ArrayList<FeatureInfo> res;
        synchronized (mAvailableFeatures) {
            res = new ArrayList<>(mAvailableFeatures.size() + 1);
            res.addAll(mAvailableFeatures.values());
        }
        final FeatureInfo fi = new FeatureInfo();
        fi.reqGlEsVersion = SystemProperties.getInt("ro.opengles.version",
                FeatureInfo.GL_ES_VERSION_UNDEFINED);
        res.add(fi);

        return new ParceledListSlice<>(res);
    }

    @Override
    public boolean hasSystemFeature(String name, int version) {
        // allow instant applications
        synchronized (mAvailableFeatures) {
            final FeatureInfo feat = mAvailableFeatures.get(name);
            if (feat == null) {
                return false;
            } else {
                return feat.version >= version;
            }
        }
    }

    // NOTE: Can't remove due to unsupported app usage
    @Override
    public int checkPermission(String permName, String pkgName, int userId) {
        try {
            // Because this is accessed via the package manager service AIDL,
            // go through the permission manager service AIDL
            return mPermissionManagerService.checkPermission(permName, pkgName, userId);
        } catch (RemoteException ignore) { }
        return PackageManager.PERMISSION_DENIED;
    }

    // NOTE: Can't remove without a major refactor. Keep around for now.
    @Override
    public int checkUidPermission(String permName, int uid) {
        try {
            // Because this is accessed via the package manager service AIDL,
            // go through the permission manager service AIDL
            return mPermissionManagerService.checkUidPermission(permName, uid);
        } catch (RemoteException ignore) { }
        return PackageManager.PERMISSION_DENIED;
    }

    @Override
    public String getPermissionControllerPackageName() {
        synchronized (mLock) {
            return mRequiredPermissionControllerPackage;
        }
    }

    String getPackageInstallerPackageName() {
        synchronized (mLock) {
            return mRequiredInstallerPackage;
        }
    }

    // NOTE: Can't remove due to unsupported app usage
    @Override
    public boolean addPermission(PermissionInfo info) {
        try {
            // Because this is accessed via the package manager service AIDL,
            // go through the permission manager service AIDL
            return mPermissionManagerService.addPermission(info, false);
        } catch (RemoteException ignore) { }
        return false;
    }

    // NOTE: Can't remove due to unsupported app usage
    @Override
    public boolean addPermissionAsync(PermissionInfo info) {
        try {
            // Because this is accessed via the package manager service AIDL,
            // go through the permission manager service AIDL
            return mPermissionManagerService.addPermission(info, true);
        } catch (RemoteException ignore) { }
        return false;
    }

    // NOTE: Can't remove due to unsupported app usage
    @Override
    public void removePermission(String permName) {
        try {
            // Because this is accessed via the package manager service AIDL,
            // go through the permission manager service AIDL
            mPermissionManagerService.removePermission(permName);
        } catch (RemoteException ignore) { }
    }

    // NOTE: Can't remove due to unsupported app usage
    @Override
    public void grantRuntimePermission(String packageName, String permName, final int userId) {
        try {
            // Because this is accessed via the package manager service AIDL,
            // go through the permission manager service AIDL
            mPermissionManagerService.grantRuntimePermission(packageName, permName, userId);
        } catch (RemoteException ignore) { }
    }

    @Override
    public boolean isProtectedBroadcast(String actionName) {
        // allow instant applications
        synchronized (mProtectedBroadcasts) {
            if (mProtectedBroadcasts.contains(actionName)) {
                return true;
            } else if (actionName != null) {
                // TODO: remove these terrible hacks
                if (actionName.startsWith("android.net.netmon.lingerExpired")
                        || actionName.startsWith("com.android.server.sip.SipWakeupTimer")
                        || actionName.startsWith("com.android.internal.telephony.data-reconnect")
                        || actionName.startsWith("android.net.netmon.launchCaptivePortalApp")) {
                    return true;
                }
            }
        }
        return false;
    }

    @Override
    public int checkSignatures(String pkg1, String pkg2) {
        synchronized (mLock) {
            final AndroidPackage p1 = mPackages.get(pkg1);
            final AndroidPackage p2 = mPackages.get(pkg2);
            final PackageSetting ps1 = p1 == null ? null : getPackageSetting(p1.getPackageName());
            final PackageSetting ps2 = p2 == null ? null : getPackageSetting(p2.getPackageName());
            if (p1 == null || ps1 == null || p2 == null || ps2 == null) {
                return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
            }
            final int callingUid = Binder.getCallingUid();
            final int callingUserId = UserHandle.getUserId(callingUid);
            if (shouldFilterApplicationLocked(ps1, callingUid, callingUserId)
                    || shouldFilterApplicationLocked(ps2, callingUid, callingUserId)) {
                return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
            }
            return compareSignatures(p1.getSigningDetails().signatures,
                    p2.getSigningDetails().signatures);
        }
    }

    @Override
    public int checkUidSignatures(int uid1, int uid2) {
        final int callingUid = Binder.getCallingUid();
        final int callingUserId = UserHandle.getUserId(callingUid);
        final boolean isCallerInstantApp = getInstantAppPackageName(callingUid) != null;
        // Map to base uids.
        final int appId1 = UserHandle.getAppId(uid1);
        final int appId2 = UserHandle.getAppId(uid2);
        // reader
        synchronized (mLock) {
            Signature[] s1;
            Signature[] s2;
            Object obj = mSettings.getSettingLPr(appId1);
            if (obj != null) {
                if (obj instanceof SharedUserSetting) {
                    if (isCallerInstantApp) {
                        return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
                    }
                    s1 = ((SharedUserSetting)obj).signatures.mSigningDetails.signatures;
                } else if (obj instanceof PackageSetting) {
                    final PackageSetting ps = (PackageSetting) obj;
                    if (shouldFilterApplicationLocked(ps, callingUid, callingUserId)) {
                        return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
                    }
                    s1 = ps.signatures.mSigningDetails.signatures;
                } else {
                    return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
                }
            } else {
                return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
            }
            obj = mSettings.getSettingLPr(appId2);
            if (obj != null) {
                if (obj instanceof SharedUserSetting) {
                    if (isCallerInstantApp) {
                        return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
                    }
                    s2 = ((SharedUserSetting)obj).signatures.mSigningDetails.signatures;
                } else if (obj instanceof PackageSetting) {
                    final PackageSetting ps = (PackageSetting) obj;
                    if (shouldFilterApplicationLocked(ps, callingUid, callingUserId)) {
                        return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
                    }
                    s2 = ps.signatures.mSigningDetails.signatures;
                } else {
                    return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
                }
            } else {
                return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
            }
            return compareSignatures(s1, s2);
        }
    }

    @Override
    public boolean hasSigningCertificate(
            String packageName, byte[] certificate, @PackageManager.CertificateInputType int type) {

        synchronized (mLock) {
            final AndroidPackage p = mPackages.get(packageName);
            final PackageSetting ps = getPackageSetting(p.getPackageName());
            if (p == null || ps == null) {
                return false;
            }
            final int callingUid = Binder.getCallingUid();
            final int callingUserId = UserHandle.getUserId(callingUid);
            if (shouldFilterApplicationLocked(ps, callingUid, callingUserId)) {
                return false;
            }
            switch (type) {
                case CERT_INPUT_RAW_X509:
                    return p.getSigningDetails().hasCertificate(certificate);
                case CERT_INPUT_SHA256:
                    return p.getSigningDetails().hasSha256Certificate(certificate);
                default:
                    return false;
            }
        }
    }

    @Override
    public boolean hasUidSigningCertificate(
            int uid, byte[] certificate, @PackageManager.CertificateInputType int type) {
        final int callingUid = Binder.getCallingUid();
        final int callingUserId = UserHandle.getUserId(callingUid);
        // Map to base uids.
        final int appId = UserHandle.getAppId(uid);
        // reader
        synchronized (mLock) {
            final PackageParser.SigningDetails signingDetails;
            final Object obj = mSettings.getSettingLPr(appId);
            if (obj != null) {
                if (obj instanceof SharedUserSetting) {
                    final boolean isCallerInstantApp = getInstantAppPackageName(callingUid) != null;
                    if (isCallerInstantApp) {
                        return false;
                    }
                    signingDetails = ((SharedUserSetting)obj).signatures.mSigningDetails;
                } else if (obj instanceof PackageSetting) {
                    final PackageSetting ps = (PackageSetting) obj;
                    if (shouldFilterApplicationLocked(ps, callingUid, callingUserId)) {
                        return false;
                    }
                    signingDetails = ps.signatures.mSigningDetails;
                } else {
                    return false;
                }
            } else {
                return false;
            }
            switch (type) {
                case CERT_INPUT_RAW_X509:
                    return signingDetails.hasCertificate(certificate);
                case CERT_INPUT_SHA256:
                    return signingDetails.hasSha256Certificate(certificate);
                default:
                    return false;
            }
        }
    }

    /**
     * If the database version for this type of package (internal storage or
     * external storage) is less than the version where package signatures
     * were updated, return true.
     */
    private boolean isCompatSignatureUpdateNeeded(AndroidPackage pkg) {
        return isCompatSignatureUpdateNeeded(getSettingsVersionForPackage(pkg));
    }

    private static boolean isCompatSignatureUpdateNeeded(VersionInfo ver) {
        return ver.databaseVersion < DatabaseVersion.SIGNATURE_END_ENTITY;
    }

    private boolean isRecoverSignatureUpdateNeeded(AndroidPackage pkg) {
        return isRecoverSignatureUpdateNeeded(getSettingsVersionForPackage(pkg));
    }

    private static boolean isRecoverSignatureUpdateNeeded(VersionInfo ver) {
        return ver.databaseVersion < DatabaseVersion.SIGNATURE_MALFORMED_RECOVER;
    }

    @Override
    public List<String> getAllPackages() {
        final int callingUid = Binder.getCallingUid();
        final int callingUserId = UserHandle.getUserId(callingUid);
        synchronized (mLock) {
            if (canViewInstantApps(callingUid, callingUserId)) {
                return new ArrayList<>(mPackages.keySet());
            }
            final String instantAppPkgName = getInstantAppPackageName(callingUid);
            final List<String> result = new ArrayList<>();
            if (instantAppPkgName != null) {
                // caller is an instant application; filter unexposed applications
                for (AndroidPackage pkg : mPackages.values()) {
                    if (!pkg.isVisibleToInstantApps()) {
                        continue;
                    }
                    result.add(pkg.getPackageName());
                }
            } else {
                // caller is a normal application; filter instant applications
                for (AndroidPackage pkg : mPackages.values()) {
                    final PackageSetting ps = getPackageSetting(pkg.getPackageName());
                    if (ps != null
                            && ps.getInstantApp(callingUserId)
                            && !mInstantAppRegistry.isInstantAccessGranted(
                                    callingUserId, UserHandle.getAppId(callingUid), ps.appId)) {
                        continue;
                    }
                    result.add(pkg.getPackageName());
                }
            }
            return result;
        }
    }

    /**
     * <em>IMPORTANT:</em> Not all packages returned by this method may be known
     * to the system. There are two conditions in which this may occur:
     * <ol>
     *   <li>The package is on adoptable storage and the device has been removed</li>
     *   <li>The package is being removed and the internal structures are partially updated</li>
     * </ol>
     * The second is an artifact of the current data structures and should be fixed. See
     * b/111075456 for one such instance.
     */
    @Override
    public String[] getPackagesForUid(int uid) {
        final int callingUid = Binder.getCallingUid();
        final boolean isCallerInstantApp = getInstantAppPackageName(callingUid) != null;
        final int userId = UserHandle.getUserId(uid);
        final int appId = UserHandle.getAppId(uid);
        // reader
        synchronized (mLock) {
            final Object obj = mSettings.getSettingLPr(appId);
            if (obj instanceof SharedUserSetting) {
                if (isCallerInstantApp) {
                    return null;
                }
                final SharedUserSetting sus = (SharedUserSetting) obj;
                final int N = sus.packages.size();
                String[] res = new String[N];
                final Iterator<PackageSetting> it = sus.packages.iterator();
                int i = 0;
                while (it.hasNext()) {
                    PackageSetting ps = it.next();
                    if (ps.getInstalled(userId)) {
                        res[i++] = ps.name;
                    }
                }
                return ArrayUtils.trimToSize(res, i);
            } else if (obj instanceof PackageSetting) {
                final PackageSetting ps = (PackageSetting) obj;
                if (ps.getInstalled(userId)
                        && !shouldFilterApplicationLocked(ps, callingUid, userId)) {
                    return new String[]{ps.name};
                }
            }
        }
        return null;
    }

    @Override
    public String getNameForUid(int uid) {
        final int callingUid = Binder.getCallingUid();
        if (getInstantAppPackageName(callingUid) != null) {
            return null;
        }
        final int appId = UserHandle.getAppId(uid);
        synchronized (mLock) {
            final Object obj = mSettings.getSettingLPr(appId);
            if (obj instanceof SharedUserSetting) {
                final SharedUserSetting sus = (SharedUserSetting) obj;
                return sus.name + ":" + sus.userId;
            } else if (obj instanceof PackageSetting) {
                final PackageSetting ps = (PackageSetting) obj;
                if (shouldFilterApplicationLocked(
                        ps, callingUid, UserHandle.getUserId(callingUid))) {
                    return null;
                }
                return ps.name;
            }
            return null;
        }
    }

    @Override
    public String[] getNamesForUids(int[] uids) {
        if (uids == null || uids.length == 0) {
            return null;
        }
        final int callingUid = Binder.getCallingUid();
        if (getInstantAppPackageName(callingUid) != null) {
            return null;
        }
        final String[] names = new String[uids.length];
        synchronized (mLock) {
            for (int i = uids.length - 1; i >= 0; i--) {
                final int appId = UserHandle.getAppId(uids[i]);
                final Object obj = mSettings.getSettingLPr(appId);
                if (obj instanceof SharedUserSetting) {
                    final SharedUserSetting sus = (SharedUserSetting) obj;
                    names[i] = "shared:" + sus.name;
                } else if (obj instanceof PackageSetting) {
                    final PackageSetting ps = (PackageSetting) obj;
                    if (shouldFilterApplicationLocked(
                            ps, callingUid, UserHandle.getUserId(callingUid))) {
                        names[i] = null;
                    } else {
                        names[i] = ps.name;
                    }
                } else {
                    names[i] = null;
                }
            }
        }
        return names;
    }

    @Override
    public int getUidForSharedUser(String sharedUserName) {
        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
            return -1;
        }
        if (sharedUserName == null) {
            return -1;
        }
        // reader
        synchronized (mLock) {
            SharedUserSetting suid;
            try {
                suid = mSettings.getSharedUserLPw(sharedUserName, 0, 0, false);
                if (suid != null) {
                    return suid.userId;
                }
            } catch (PackageManagerException ignore) {
                // can't happen, but, still need to catch it
            }
            return -1;
        }
    }

    @Override
    public int getFlagsForUid(int uid) {
        final int callingUid = Binder.getCallingUid();
        if (getInstantAppPackageName(callingUid) != null) {
            return 0;
        }
        final int appId = UserHandle.getAppId(uid);
        synchronized (mLock) {
            final Object obj = mSettings.getSettingLPr(appId);
            if (obj instanceof SharedUserSetting) {
                final SharedUserSetting sus = (SharedUserSetting) obj;
                return sus.pkgFlags;
            } else if (obj instanceof PackageSetting) {
                final PackageSetting ps = (PackageSetting) obj;
                if (shouldFilterApplicationLocked(
                        ps, callingUid, UserHandle.getUserId(callingUid))) {
                    return 0;
                }
                return ps.pkgFlags;
            }
        }
        return 0;
    }

    @Override
    public int getPrivateFlagsForUid(int uid) {
        final int callingUid = Binder.getCallingUid();
        if (getInstantAppPackageName(callingUid) != null) {
            return 0;
        }
        final int appId = UserHandle.getAppId(uid);
        synchronized (mLock) {
            final Object obj = mSettings.getSettingLPr(appId);
            if (obj instanceof SharedUserSetting) {
                final SharedUserSetting sus = (SharedUserSetting) obj;
                return sus.pkgPrivateFlags;
            } else if (obj instanceof PackageSetting) {
                final PackageSetting ps = (PackageSetting) obj;
                if (shouldFilterApplicationLocked(
                        ps, callingUid, UserHandle.getUserId(callingUid))) {
                    return 0;
                }
                return ps.pkgPrivateFlags;
            }
        }
        return 0;
    }

    @Override
    public boolean isUidPrivileged(int uid) {
        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
            return false;
        }
        final int appId = UserHandle.getAppId(uid);
        // reader
        synchronized (mLock) {
            final Object obj = mSettings.getSettingLPr(appId);
            if (obj instanceof SharedUserSetting) {
                final SharedUserSetting sus = (SharedUserSetting) obj;
                final Iterator<PackageSetting> it = sus.packages.iterator();
                while (it.hasNext()) {
                    if (it.next().isPrivileged()) {
                        return true;
                    }
                }
            } else if (obj instanceof PackageSetting) {
                final PackageSetting ps = (PackageSetting) obj;
                return ps.isPrivileged();
            }
        }
        return false;
    }

    // NOTE: Can't remove due to unsupported app usage
    @Override
    public String[] getAppOpPermissionPackages(String permName) {
        try {
            // Because this is accessed via the package manager service AIDL,
            // go through the permission manager service AIDL
            return mPermissionManagerService.getAppOpPermissionPackages(permName);
        } catch (RemoteException ignore) { }
        return null;
    }

    @Override
    public ResolveInfo resolveIntent(Intent intent, String resolvedType,
            int flags, int userId) {
        return resolveIntentInternal(intent, resolvedType, flags, userId, false,
                Binder.getCallingUid());
    }

    /**
     * Normally instant apps can only be resolved when they're visible to the caller.
     * However, if {@code resolveForStart} is {@code true}, all instant apps are visible
     * since we need to allow the system to start any installed application.
     */
    private ResolveInfo resolveIntentInternal(Intent intent, String resolvedType,
            int flags, int userId, boolean resolveForStart, int filterCallingUid) {
        try {
            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "resolveIntent");

            if (!mUserManager.exists(userId)) return null;
            final int callingUid = Binder.getCallingUid();
            flags = updateFlagsForResolve(flags, userId, filterCallingUid, resolveForStart);
            mPermissionManager.enforceCrossUserPermission(callingUid, userId,
                    false /*requireFullPermission*/, false /*checkShell*/, "resolve intent");

            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "queryIntentActivities");
            final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType,
                    flags, filterCallingUid, userId, resolveForStart, true /*allowDynamicSplits*/);
            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);

            final ResolveInfo bestChoice =
                    chooseBestActivity(intent, resolvedType, flags, query, userId);
            return bestChoice;
        } finally {
            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
        }
    }

    @Override
    public ResolveInfo findPersistentPreferredActivity(Intent intent, int userId) {
        if (!UserHandle.isSameApp(Binder.getCallingUid(), Process.SYSTEM_UID)) {
            throw new SecurityException(
                    "findPersistentPreferredActivity can only be run by the system");
        }
        if (!mUserManager.exists(userId)) {
            return null;
        }
        final int callingUid = Binder.getCallingUid();
        intent = updateIntentForResolve(intent);
        final String resolvedType = intent.resolveTypeIfNeeded(mContext.getContentResolver());
        final int flags = updateFlagsForResolve(
                0, userId, callingUid, false /*includeInstantApps*/);
        final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, flags,
                userId);
        synchronized (mLock) {
            return findPersistentPreferredActivityLP(intent, resolvedType, flags, query, false,
                    userId);
        }
    }

    @Override
    public void setLastChosenActivity(Intent intent, String resolvedType, int flags,
            IntentFilter filter, int match, ComponentName activity) {
        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
            return;
        }
        final int userId = UserHandle.getCallingUserId();
        if (DEBUG_PREFERRED) {
            Log.v(TAG, "setLastChosenActivity intent=" + intent
                + " resolvedType=" + resolvedType
                + " flags=" + flags
                + " filter=" + filter
                + " match=" + match
                + " activity=" + activity);
            filter.dump(new PrintStreamPrinter(System.out), "    ");
        }
        intent.setComponent(null);
        final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, flags,
                userId);
        // Find any earlier preferred or last chosen entries and nuke them
        findPreferredActivityNotLocked(
                intent, resolvedType, flags, query, 0, false, true, false, userId);
        // Add the new activity as the last chosen for this filter
        addPreferredActivityInternal(filter, match, null, activity, false, userId,
                "Setting last chosen");
    }

    @Override
    public ResolveInfo getLastChosenActivity(Intent intent, String resolvedType, int flags) {
        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
            return null;
        }
        final int userId = UserHandle.getCallingUserId();
        if (DEBUG_PREFERRED) Log.v(TAG, "Querying last chosen activity for " + intent);
        final List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType, flags,
                userId);
        return findPreferredActivityNotLocked(
                intent, resolvedType, flags, query, 0, false, false, false, userId);
    }

    /**
     * Returns whether or not instant apps have been disabled remotely.
     */
    private boolean areWebInstantAppsDisabled(int userId) {
        return mWebInstantAppsDisabled.get(userId);
    }

    private boolean isInstantAppResolutionAllowed(
            Intent intent, List<ResolveInfo> resolvedActivities, int userId,
            boolean skipPackageCheck) {
        if (mInstantAppResolverConnection == null) {
            return false;
        }
        if (mInstantAppInstallerActivity == null) {
            return false;
        }
        if (intent.getComponent() != null) {
            return false;
        }
        if ((intent.getFlags() & Intent.FLAG_IGNORE_EPHEMERAL) != 0) {
            return false;
        }
        if (!skipPackageCheck && intent.getPackage() != null) {
            return false;
        }
        if (!intent.isWebIntent()) {
            // for non web intents, we should not resolve externally if an app already exists to
            // handle it or if the caller didn't explicitly request it.
            if ((resolvedActivities != null && resolvedActivities.size() != 0)
                    || (intent.getFlags() & Intent.FLAG_ACTIVITY_MATCH_EXTERNAL) == 0) {
                return false;
            }
        } else {
            if (intent.getData() == null || TextUtils.isEmpty(intent.getData().getHost())) {
                return false;
            } else if (areWebInstantAppsDisabled(userId)) {
                return false;
            }
        }
        // Deny ephemeral apps if the user chose _ALWAYS or _ALWAYS_ASK for intent resolution.
        // Or if there's already an ephemeral app installed that handles the action
        synchronized (mLock) {
            final int count = (resolvedActivities == null ? 0 : resolvedActivities.size());
            for (int n = 0; n < count; n++) {
                final ResolveInfo info = resolvedActivities.get(n);
                final String packageName = info.activityInfo.packageName;
                final PackageSetting ps = mSettings.mPackages.get(packageName);
                if (ps != null) {
                    // only check domain verification status if the app is not a browser
                    if (!info.handleAllWebDataURI) {
                        // Try to get the status from User settings first
                        final long packedStatus = getDomainVerificationStatusLPr(ps, userId);
                        final int status = (int) (packedStatus >> 32);
                        if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS
                            || status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK) {
                            if (DEBUG_INSTANT) {
                                Slog.v(TAG, "DENY instant app;"
                                    + " pkg: " + packageName + ", status: " + status);
                            }
                            return false;
                        }
                    }
                    if (ps.getInstantApp(userId)) {
                        if (DEBUG_INSTANT) {
                            Slog.v(TAG, "DENY instant app installed;"
                                    + " pkg: " + packageName);
                        }
                        return false;
                    }
                }
            }
        }
        // We've exhausted all ways to deny ephemeral application; let the system look for them.
        return true;
    }

    private void requestInstantAppResolutionPhaseTwo(AuxiliaryResolveInfo responseObj,
            Intent origIntent, String resolvedType, String callingPackage,
            Bundle verificationBundle, int userId) {
        final Message msg = mHandler.obtainMessage(INSTANT_APP_RESOLUTION_PHASE_TWO,
                new InstantAppRequest(responseObj, origIntent, resolvedType,
                        callingPackage, userId, verificationBundle, false /*resolveForStart*/));
        mHandler.sendMessage(msg);
    }

    private ResolveInfo chooseBestActivity(Intent intent, String resolvedType,
            int flags, List<ResolveInfo> query, int userId) {
        if (query != null) {
            final int N = query.size();
            if (N == 1) {
                return query.get(0);
            } else if (N > 1) {
                final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
                // If there is more than one activity with the same priority,
                // then let the user decide between them.
                ResolveInfo r0 = query.get(0);
                ResolveInfo r1 = query.get(1);
                if (DEBUG_INTENT_MATCHING || debug) {
                    Slog.v(TAG, r0.activityInfo.name + "=" + r0.priority + " vs "
                            + r1.activityInfo.name + "=" + r1.priority);
                }
                // If the first activity has a higher priority, or a different
                // default, then it is always desirable to pick it.
                if (r0.priority != r1.priority
                        || r0.preferredOrder != r1.preferredOrder
                        || r0.isDefault != r1.isDefault) {
                    return query.get(0);
                }
                // If we have saved a preference for a preferred activity for
                // this Intent, use that.
                ResolveInfo ri = findPreferredActivityNotLocked(intent, resolvedType,
                        flags, query, r0.priority, true, false, debug, userId);
                if (ri != null) {
                    return ri;
                }
                // If we have an ephemeral app, use it
                for (int i = 0; i < N; i++) {
                    ri = query.get(i);
                    if (ri.activityInfo.applicationInfo.isInstantApp()) {
                        final String packageName = ri.activityInfo.packageName;
                        final PackageSetting ps = mSettings.mPackages.get(packageName);
                        final long packedStatus = getDomainVerificationStatusLPr(ps, userId);
                        final int status = (int)(packedStatus >> 32);
                        if (status != INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK) {
                            return ri;
                        }
                    }
                }
                ri = new ResolveInfo(mResolveInfo);
                ri.activityInfo = new ActivityInfo(ri.activityInfo);
                ri.activityInfo.labelRes = ResolverActivity.getLabelRes(intent.getAction());
                // If all of the options come from the same package, show the application's
                // label and icon instead of the generic resolver's.
                // Some calls like Intent.resolveActivityInfo query the ResolveInfo from here
                // and then throw away the ResolveInfo itself, meaning that the caller loses
                // the resolvePackageName. Therefore the activityInfo.labelRes above provides
                // a fallback for this case; we only set the target package's resources on
                // the ResolveInfo, not the ActivityInfo.
                final String intentPackage = intent.getPackage();
                if (!TextUtils.isEmpty(intentPackage) && allHavePackage(query, intentPackage)) {
                    final ApplicationInfo appi = query.get(0).activityInfo.applicationInfo;
                    ri.resolvePackageName = intentPackage;
                    if (userNeedsBadging(userId)) {
                        ri.noResourceId = true;
                    } else {
                        ri.icon = appi.icon;
                    }
                    ri.iconResourceId = appi.icon;
                    ri.labelRes = appi.labelRes;
                }
                ri.activityInfo.applicationInfo = new ApplicationInfo(
                        ri.activityInfo.applicationInfo);
                if (userId != 0) {
                    ri.activityInfo.applicationInfo.uid = UserHandle.getUid(userId,
                            UserHandle.getAppId(ri.activityInfo.applicationInfo.uid));
                }
                // Make sure that the resolver is displayable in car mode
                if (ri.activityInfo.metaData == null) ri.activityInfo.metaData = new Bundle();
                ri.activityInfo.metaData.putBoolean(Intent.METADATA_DOCK_HOME, true);
                return ri;
            }
        }
        return null;
    }

    /**
     * Return true if the given list is not empty and all of its contents have
     * an activityInfo with the given package name.
     */
    private boolean allHavePackage(List<ResolveInfo> list, String packageName) {
        if (ArrayUtils.isEmpty(list)) {
            return false;
        }
        for (int i = 0, N = list.size(); i < N; i++) {
            final ResolveInfo ri = list.get(i);
            final ActivityInfo ai = ri != null ? ri.activityInfo : null;
            if (ai == null || !packageName.equals(ai.packageName)) {
                return false;
            }
        }
        return true;
    }

    @GuardedBy("mLock")
    private ResolveInfo findPersistentPreferredActivityLP(Intent intent, String resolvedType,
            int flags, List<ResolveInfo> query, boolean debug, int userId) {
        final int N = query.size();
        PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities
                .get(userId);
        // Get the list of persistent preferred activities that handle the intent
        if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for presistent preferred activities...");
        List<PersistentPreferredActivity> pprefs = ppir != null
                ? ppir.queryIntent(intent, resolvedType,
                        (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
                        userId)
                : null;
        if (pprefs != null && pprefs.size() > 0) {
            final int M = pprefs.size();
            for (int i=0; i<M; i++) {
                final PersistentPreferredActivity ppa = pprefs.get(i);
                if (DEBUG_PREFERRED || debug) {
                    Slog.v(TAG, "Checking PersistentPreferredActivity ds="
                            + (ppa.countDataSchemes() > 0 ? ppa.getDataScheme(0) : "<none>")
                            + "\n  component=" + ppa.mComponent);
                    ppa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
                }
                final ActivityInfo ai = getActivityInfo(ppa.mComponent,
                        flags | MATCH_DISABLED_COMPONENTS, userId);
                if (DEBUG_PREFERRED || debug) {
                    Slog.v(TAG, "Found persistent preferred activity:");
                    if (ai != null) {
                        ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
                    } else {
                        Slog.v(TAG, "  null");
                    }
                }
                if (ai == null) {
                    // This previously registered persistent preferred activity
                    // component is no longer known. Ignore it and do NOT remove it.
                    continue;
                }
                for (int j=0; j<N; j++) {
                    final ResolveInfo ri = query.get(j);
                    if (!ri.activityInfo.applicationInfo.packageName
                            .equals(ai.applicationInfo.packageName)) {
                        continue;
                    }
                    if (!ri.activityInfo.name.equals(ai.name)) {
                        continue;
                    }
                    //  Found a persistent preference that can handle the intent.
                    if (DEBUG_PREFERRED || debug) {
                        Slog.v(TAG, "Returning persistent preferred activity: " +
                                ri.activityInfo.packageName + "/" + ri.activityInfo.name);
                    }
                    return ri;
                }
            }
        }
        return null;
    }

    private boolean isHomeIntent(Intent intent) {
        return ACTION_MAIN.equals(intent.getAction())
                && intent.hasCategory(CATEGORY_HOME)
                && intent.hasCategory(CATEGORY_DEFAULT);
    }

    // TODO: handle preferred activities missing while user has amnesia
    /** <b>must not hold {@link #mLock}</b> */
    ResolveInfo findPreferredActivityNotLocked(Intent intent, String resolvedType, int flags,
            List<ResolveInfo> query, int priority, boolean always,
            boolean removeMatches, boolean debug, int userId) {
        if (Thread.holdsLock(mLock)) {
            Slog.wtf(TAG, "Calling thread " + Thread.currentThread().getName()
                    + " is holding mLock", new Throwable());
        }
        if (!mUserManager.exists(userId)) return null;
        final int callingUid = Binder.getCallingUid();
        // Do NOT hold the packages lock; this calls up into the settings provider which
        // could cause a deadlock.
        final boolean isDeviceProvisioned =
                android.provider.Settings.Global.getInt(mContext.getContentResolver(),
                        android.provider.Settings.Global.DEVICE_PROVISIONED, 0) == 1;
        flags = updateFlagsForResolve(
                flags, userId, callingUid, false /*includeInstantApps*/);
        intent = updateIntentForResolve(intent);
        // writer
        synchronized (mLock) {
            // Try to find a matching persistent preferred activity.
            ResolveInfo pri = findPersistentPreferredActivityLP(intent, resolvedType, flags, query,
                    debug, userId);

            // If a persistent preferred activity matched, use it.
            if (pri != null) {
                return pri;
            }

            PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
            // Get the list of preferred activities that handle the intent
            if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Looking for preferred activities...");
            List<PreferredActivity> prefs = pir != null
                    ? pir.queryIntent(intent, resolvedType,
                            (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
                            userId)
                    : null;
            if (prefs != null && prefs.size() > 0) {
                boolean changed = false;
                try {
                    // First figure out how good the original match set is.
                    // We will only allow preferred activities that came
                    // from the same match quality.
                    int match = 0;

                    if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Figuring out best match...");

                    final int N = query.size();
                    for (int j=0; j<N; j++) {
                        final ResolveInfo ri = query.get(j);
                        if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Match for " + ri.activityInfo
                                + ": 0x" + Integer.toHexString(match));
                        if (ri.match > match) {
                            match = ri.match;
                        }
                    }

                    if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Best match: 0x"
                            + Integer.toHexString(match));

                    match &= IntentFilter.MATCH_CATEGORY_MASK;
                    final int M = prefs.size();
                    for (int i=0; i<M; i++) {
                        final PreferredActivity pa = prefs.get(i);
                        if (DEBUG_PREFERRED || debug) {
                            Slog.v(TAG, "Checking PreferredActivity ds="
                                    + (pa.countDataSchemes() > 0 ? pa.getDataScheme(0) : "<none>")
                                    + "\n  component=" + pa.mPref.mComponent);
                            pa.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
                        }
                        if (pa.mPref.mMatch != match) {
                            if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping bad match "
                                    + Integer.toHexString(pa.mPref.mMatch));
                            continue;
                        }
                        // If it's not an "always" type preferred activity and that's what we're
                        // looking for, skip it.
                        if (always && !pa.mPref.mAlways) {
                            if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Skipping mAlways=false entry");
                            continue;
                        }
                        final ActivityInfo ai = getActivityInfo(
                                pa.mPref.mComponent, flags | MATCH_DISABLED_COMPONENTS
                                        | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE,
                                userId);
                        if (DEBUG_PREFERRED || debug) {
                            Slog.v(TAG, "Found preferred activity:");
                            if (ai != null) {
                                ai.dump(new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM), "  ");
                            } else {
                                Slog.v(TAG, "  null");
                            }
                        }
                        final boolean excludeSetupWizardHomeActivity = isHomeIntent(intent)
                                && !isDeviceProvisioned;
                        if (ai == null) {
                            // Do not remove launcher's preferred activity during SetupWizard
                            // due to it may not install yet
                            if (excludeSetupWizardHomeActivity) {
                                continue;
                            }

                            // This previously registered preferred activity
                            // component is no longer known.  Most likely an update
                            // to the app was installed and in the new version this
                            // component no longer exists.  Clean it up by removing
                            // it from the preferred activities list, and skip it.
                            Slog.w(TAG, "Removing dangling preferred activity: "
                                    + pa.mPref.mComponent);
                            pir.removeFilter(pa);
                            changed = true;
                            continue;
                        }
                        for (int j=0; j<N; j++) {
                            final ResolveInfo ri = query.get(j);
                            if (!ri.activityInfo.applicationInfo.packageName
                                    .equals(ai.applicationInfo.packageName)) {
                                continue;
                            }
                            if (!ri.activityInfo.name.equals(ai.name)) {
                                continue;
                            }

                            if (removeMatches) {
                                pir.removeFilter(pa);
                                changed = true;
                                if (DEBUG_PREFERRED) {
                                    Slog.v(TAG, "Removing match " + pa.mPref.mComponent);
                                }
                                break;
                            }

                            // Okay we found a previously set preferred or last chosen app.
                            // If the result set is different from when this
                            // was created, and is not a subset of the preferred set, we need to
                            // clear it and re-ask the user their preference, if we're looking for
                            // an "always" type entry.

                            if (always && !pa.mPref.sameSet(query, excludeSetupWizardHomeActivity)) {
                                if (pa.mPref.isSuperset(query, excludeSetupWizardHomeActivity)) {
                                    if (!excludeSetupWizardHomeActivity) {
                                        // some components of the set are no longer present in
                                        // the query, but the preferred activity can still be reused
                                        if (DEBUG_PREFERRED) {
                                            Slog.i(TAG, "Result set changed, but PreferredActivity"
                                                    + " is still valid as only non-preferred"
                                                    + " components were removed for " + intent
                                                    + " type " + resolvedType);
                                        }
                                        // remove obsolete components and re-add the up-to-date
                                        // filter
                                        PreferredActivity freshPa = new PreferredActivity(pa,
                                                pa.mPref.mMatch,
                                                pa.mPref.discardObsoleteComponents(query),
                                                pa.mPref.mComponent,
                                                pa.mPref.mAlways);
                                        pir.removeFilter(pa);
                                        pir.addFilter(freshPa);
                                        changed = true;
                                    } else {
                                        if (DEBUG_PREFERRED) {
                                            Slog.i(TAG, "Do not remove preferred activity for launcher"
                                                    + " during SetupWizard");
                                        }
                                    }
                                } else {
                                    Slog.i(TAG,
                                            "Result set changed, dropping preferred activity for "
                                                    + intent + " type " + resolvedType);
                                    if (DEBUG_PREFERRED) {
                                        Slog.v(TAG, "Removing preferred activity since set changed "
                                                + pa.mPref.mComponent);
                                    }
                                    pir.removeFilter(pa);
                                    // Re-add the filter as a "last chosen" entry (!always)
                                    PreferredActivity lastChosen = new PreferredActivity(
                                            pa, pa.mPref.mMatch, null, pa.mPref.mComponent, false);
                                    pir.addFilter(lastChosen);
                                    changed = true;
                                    return null;
                                }
                            }

                            // Yay! Either the set matched or we're looking for the last chosen
                            if (DEBUG_PREFERRED || debug) Slog.v(TAG, "Returning preferred activity: "
                                    + ri.activityInfo.packageName + "/" + ri.activityInfo.name);
                            return ri;
                        }
                    }
                } finally {
                    if (changed) {
                        if (DEBUG_PREFERRED) {
                            Slog.v(TAG, "Preferred activity bookkeeping changed; writing restrictions");
                        }
                        scheduleWritePackageRestrictionsLocked(userId);
                    }
                }
            }
        }
        if (DEBUG_PREFERRED || debug) Slog.v(TAG, "No preferred activity to return");
        return null;
    }

    /*
     * Returns if intent can be forwarded from the sourceUserId to the targetUserId
     */
    @Override
    public boolean canForwardTo(Intent intent, String resolvedType, int sourceUserId,
            int targetUserId) {
        mContext.enforceCallingOrSelfPermission(
                android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
        List<CrossProfileIntentFilter> matches =
                getMatchingCrossProfileIntentFilters(intent, resolvedType, sourceUserId);
        if (matches != null) {
            int size = matches.size();
            for (int i = 0; i < size; i++) {
                if (matches.get(i).getTargetUserId() == targetUserId) return true;
            }
        }
        if (intent.hasWebURI()) {
            // cross-profile app linking works only towards the parent.
            final int callingUid = Binder.getCallingUid();
            final UserInfo parent = getProfileParent(sourceUserId);
            synchronized (mLock) {
                int flags = updateFlagsForResolve(0, parent.id, callingUid,
                        false /*includeInstantApps*/);
                CrossProfileDomainInfo xpDomainInfo = getCrossProfileDomainPreferredLpr(
                        intent, resolvedType, flags, sourceUserId, parent.id);
                return xpDomainInfo != null;
            }
        }
        return false;
    }

    private UserInfo getProfileParent(int userId) {
        final long identity = Binder.clearCallingIdentity();
        try {
            return mUserManager.getProfileParent(userId);
        } finally {
            Binder.restoreCallingIdentity(identity);
        }
    }

    private List<CrossProfileIntentFilter> getMatchingCrossProfileIntentFilters(Intent intent,
            String resolvedType, int userId) {
        CrossProfileIntentResolver resolver = mSettings.mCrossProfileIntentResolvers.get(userId);
        if (resolver != null) {
            return resolver.queryIntent(intent, resolvedType, false /*defaultOnly*/, userId);
        }
        return null;
    }

    @Override
    public @NonNull ParceledListSlice<ResolveInfo> queryIntentActivities(Intent intent,
            String resolvedType, int flags, int userId) {
        try {
            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "queryIntentActivities");

            return new ParceledListSlice<>(
                    queryIntentActivitiesInternal(intent, resolvedType, flags, userId));
        } finally {
            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
        }
    }

    /**
     * Returns the package name of the calling Uid if it's an instant app. If it isn't
     * instant, returns {@code null}.
     */
    private String getInstantAppPackageName(int callingUid) {
        synchronized (mLock) {
            // If the caller is an isolated app use the owner's uid for the lookup.
            if (Process.isIsolated(callingUid)) {
                callingUid = mIsolatedOwners.get(callingUid);
            }
            final int appId = UserHandle.getAppId(callingUid);
            final Object obj = mSettings.getSettingLPr(appId);
            if (obj instanceof PackageSetting) {
                final PackageSetting ps = (PackageSetting) obj;
                final boolean isInstantApp = ps.getInstantApp(UserHandle.getUserId(callingUid));
                return isInstantApp ? ps.pkg.getPackageName() : null;
            }
        }
        return null;
    }

    private @NonNull List<ResolveInfo> queryIntentActivitiesInternal(Intent intent,
            String resolvedType, int flags, int userId) {
        return queryIntentActivitiesInternal(
                intent, resolvedType, flags, Binder.getCallingUid(), userId,
                false /*resolveForStart*/, true /*allowDynamicSplits*/);
    }

    private @NonNull List<ResolveInfo> queryIntentActivitiesInternal(Intent intent,
            String resolvedType, int flags, int filterCallingUid, int userId,
            boolean resolveForStart, boolean allowDynamicSplits) {
        if (!mUserManager.exists(userId)) return Collections.emptyList();
        final String instantAppPkgName = getInstantAppPackageName(filterCallingUid);
        mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId,
                false /* requireFullPermission */, false /* checkShell */,
                "query intent activities");
        final String pkgName = intent.getPackage();
        ComponentName comp = intent.getComponent();
        if (comp == null) {
            if (intent.getSelector() != null) {
                intent = intent.getSelector();
                comp = intent.getComponent();
            }
        }

        flags = updateFlagsForResolve(flags, userId, filterCallingUid, resolveForStart,
                comp != null || pkgName != null /*onlyExposedExplicitly*/);
        if (comp != null) {
            final List<ResolveInfo> list = new ArrayList<>(1);
            final ActivityInfo ai = getActivityInfo(comp, flags, userId);
            if (ai != null) {
                // When specifying an explicit component, we prevent the activity from being
                // used when either 1) the calling package is normal and the activity is within
                // an ephemeral application or 2) the calling package is ephemeral and the
                // activity is not visible to ephemeral applications.
                final boolean matchInstantApp =
                        (flags & PackageManager.MATCH_INSTANT) != 0;
                final boolean matchVisibleToInstantAppOnly =
                        (flags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
                final boolean matchExplicitlyVisibleOnly =
                        (flags & PackageManager.MATCH_EXPLICITLY_VISIBLE_ONLY) != 0;
                final boolean isCallerInstantApp =
                        instantAppPkgName != null;
                final boolean isTargetSameInstantApp =
                        comp.getPackageName().equals(instantAppPkgName);
                final boolean isTargetInstantApp =
                        (ai.applicationInfo.privateFlags
                                & ApplicationInfo.PRIVATE_FLAG_INSTANT) != 0;
                final boolean isTargetVisibleToInstantApp =
                        (ai.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0;
                final boolean isTargetExplicitlyVisibleToInstantApp =
                        isTargetVisibleToInstantApp
                        && (ai.flags & ActivityInfo.FLAG_IMPLICITLY_VISIBLE_TO_INSTANT_APP) == 0;
                final boolean isTargetHiddenFromInstantApp =
                        !isTargetVisibleToInstantApp
                        || (matchExplicitlyVisibleOnly && !isTargetExplicitlyVisibleToInstantApp);
                final boolean blockResolution =
                        !isTargetSameInstantApp
                        && ((!matchInstantApp && !isCallerInstantApp && isTargetInstantApp)
                                || (matchVisibleToInstantAppOnly && isCallerInstantApp
                                        && isTargetHiddenFromInstantApp));
                if (!blockResolution) {
                    final ResolveInfo ri = new ResolveInfo();
                    ri.activityInfo = ai;
                    list.add(ri);
                }
            }

            List<ResolveInfo> result = applyPostResolutionFilter(
                    list, instantAppPkgName, allowDynamicSplits, filterCallingUid, resolveForStart,
                    userId, intent);
            return result;
        }

        // reader
        boolean sortResult = false;
        boolean addInstant = false;
        List<ResolveInfo> result;
        synchronized (mLock) {
            if (pkgName == null) {
                List<CrossProfileIntentFilter> matchingFilters =
                        getMatchingCrossProfileIntentFilters(intent, resolvedType, userId);
                // Check for results that need to skip the current profile.
                ResolveInfo xpResolveInfo  = querySkipCurrentProfileIntents(matchingFilters, intent,
                        resolvedType, flags, userId);
                if (xpResolveInfo != null) {
                    List<ResolveInfo> xpResult = new ArrayList<>(1);
                    xpResult.add(xpResolveInfo);
                    return applyPostResolutionFilter(
                            filterIfNotSystemUser(xpResult, userId), instantAppPkgName,
                            allowDynamicSplits, filterCallingUid, resolveForStart, userId, intent);
                }

                // Check for results in the current profile.
                result = filterIfNotSystemUser(mComponentResolver.queryActivities(
                        intent, resolvedType, flags, userId), userId);
                addInstant = isInstantAppResolutionAllowed(intent, result, userId,
                        false /*skipPackageCheck*/);
                // Check for cross profile results.
                boolean hasNonNegativePriorityResult = hasNonNegativePriority(result);
                xpResolveInfo = queryCrossProfileIntents(
                        matchingFilters, intent, resolvedType, flags, userId,
                        hasNonNegativePriorityResult);
                if (xpResolveInfo != null && isUserEnabled(xpResolveInfo.targetUserId)) {
                    boolean isVisibleToUser = filterIfNotSystemUser(
                            Collections.singletonList(xpResolveInfo), userId).size() > 0;
                    if (isVisibleToUser) {
                        result.add(xpResolveInfo);
                        sortResult = true;
                    }
                }
                if (intent.hasWebURI()) {
                    CrossProfileDomainInfo xpDomainInfo = null;
                    final UserInfo parent = getProfileParent(userId);
                    if (parent != null) {
                        xpDomainInfo = getCrossProfileDomainPreferredLpr(intent, resolvedType,
                                flags, userId, parent.id);
                    }
                    if (xpDomainInfo != null) {
                        if (xpResolveInfo != null) {
                            // If we didn't remove it, the cross-profile ResolveInfo would be twice
                            // in the result.
                            result.remove(xpResolveInfo);
                        }
                        if (result.size() == 0 && !addInstant) {
                            // No result in current profile, but found candidate in parent user.
                            // And we are not going to add emphemeral app, so we can return the
                            // result straight away.
                            result.add(xpDomainInfo.resolveInfo);
                            return applyPostResolutionFilter(result, instantAppPkgName,
                                    allowDynamicSplits, filterCallingUid, resolveForStart, userId,
                                    intent);
                        }
                    } else if (result.size() <= 1 && !addInstant) {
                        // No result in parent user and <= 1 result in current profile, and we
                        // are not going to add emphemeral app, so we can return the result without
                        // further processing.
                        return applyPostResolutionFilter(result, instantAppPkgName,
                                allowDynamicSplits, filterCallingUid, resolveForStart, userId,
                                intent);
                    }
                    // We have more than one candidate (combining results from current and parent
                    // profile), so we need filtering and sorting.
                    result = filterCandidatesWithDomainPreferredActivitiesLPr(
                            intent, flags, result, xpDomainInfo, userId);
                    sortResult = true;
                }
            } else {
                final AndroidPackage pkg = mPackages.get(pkgName);
                result = null;
                if (pkg != null) {
                    result = filterIfNotSystemUser(mComponentResolver.queryActivities(
                            intent, resolvedType, flags, pkg.getActivities(), userId), userId);
                }
                if (result == null || result.size() == 0) {
                    // the caller wants to resolve for a particular package; however, there
                    // were no installed results, so, try to find an ephemeral result
                    addInstant = isInstantAppResolutionAllowed(
                                    intent, null /*result*/, userId, true /*skipPackageCheck*/);
                    if (result == null) {
                        result = new ArrayList<>();
                    }
                }
            }
        }
        if (addInstant) {
            result = maybeAddInstantAppInstaller(
                    result, intent, resolvedType, flags, userId, resolveForStart);
        }
        if (sortResult) {
            Collections.sort(result, RESOLVE_PRIORITY_SORTER);
        }
        return applyPostResolutionFilter(
                result, instantAppPkgName, allowDynamicSplits, filterCallingUid, resolveForStart,
                userId, intent);
    }

    private List<ResolveInfo> maybeAddInstantAppInstaller(List<ResolveInfo> result, Intent intent,
            String resolvedType, int flags, int userId, boolean resolveForStart) {
        // first, check to see if we've got an instant app already installed
        final boolean alreadyResolvedLocally = (flags & PackageManager.MATCH_INSTANT) != 0;
        ResolveInfo localInstantApp = null;
        boolean blockResolution = false;
        if (!alreadyResolvedLocally) {
            final List<ResolveInfo> instantApps = mComponentResolver.queryActivities(
                    intent,
                    resolvedType,
                    flags
                        | PackageManager.GET_RESOLVED_FILTER
                        | PackageManager.MATCH_INSTANT
                        | PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY,
                    userId);
            for (int i = instantApps.size() - 1; i >= 0; --i) {
                final ResolveInfo info = instantApps.get(i);
                final String packageName = info.activityInfo.packageName;
                final PackageSetting ps = mSettings.mPackages.get(packageName);
                if (ps.getInstantApp(userId)) {
                    final long packedStatus = getDomainVerificationStatusLPr(ps, userId);
                    final int status = (int)(packedStatus >> 32);
                    if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
                        // there's a local instant application installed, but, the user has
                        // chosen to never use it; skip resolution and don't acknowledge
                        // an instant application is even available
                        if (DEBUG_INSTANT) {
                            Slog.v(TAG, "Instant app marked to never run; pkg: " + packageName);
                        }
                        blockResolution = true;
                        break;
                    } else {
                        // we have a locally installed instant application; skip resolution
                        // but acknowledge there's an instant application available
                        if (DEBUG_INSTANT) {
                            Slog.v(TAG, "Found installed instant app; pkg: " + packageName);
                        }
                        localInstantApp = info;
                        break;
                    }
                }
            }
        }
        // no app installed, let's see if one's available
        AuxiliaryResolveInfo auxiliaryResponse = null;
        if (!blockResolution) {
            if (localInstantApp == null) {
                // we don't have an instant app locally, resolve externally
                Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "resolveEphemeral");
                final InstantAppRequest requestObject = new InstantAppRequest(
                        null /*responseObj*/, intent /*origIntent*/, resolvedType,
                        null /*callingPackage*/, userId, null /*verificationBundle*/,
                        resolveForStart);
                auxiliaryResponse = InstantAppResolver.doInstantAppResolutionPhaseOne(
                        mInstantAppResolverConnection, requestObject);
                Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
            } else {
                // we have an instant application locally, but, we can't admit that since
                // callers shouldn't be able to determine prior browsing. create a dummy
                // auxiliary response so the downstream code behaves as if there's an
                // instant application available externally. when it comes time to start
                // the instant application, we'll do the right thing.
                final ApplicationInfo ai = localInstantApp.activityInfo.applicationInfo;
                auxiliaryResponse = new AuxiliaryResolveInfo(null /* failureActivity */,
                                        ai.packageName, ai.longVersionCode, null /* splitName */);
            }
        }
        if (intent.isWebIntent() && auxiliaryResponse == null) {
            return result;
        }
        final PackageSetting ps = mSettings.mPackages.get(mInstantAppInstallerActivity.packageName);
        if (ps == null
                || !ps.readUserState(userId).isEnabled(mInstantAppInstallerActivity, 0)) {
            return result;
        }
        final ResolveInfo ephemeralInstaller = new ResolveInfo(mInstantAppInstallerInfo);
        ephemeralInstaller.activityInfo = PackageParser.generateActivityInfo(
                mInstantAppInstallerActivity, 0, ps.readUserState(userId), userId);
        ephemeralInstaller.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
                | IntentFilter.MATCH_ADJUSTMENT_NORMAL;
        // add a non-generic filter
        ephemeralInstaller.filter = new IntentFilter();
        if (intent.getAction() != null) {
            ephemeralInstaller.filter.addAction(intent.getAction());
        }
        if (intent.getData() != null && intent.getData().getPath() != null) {
            ephemeralInstaller.filter.addDataPath(
                    intent.getData().getPath(), PatternMatcher.PATTERN_LITERAL);
        }
        ephemeralInstaller.isInstantAppAvailable = true;
        // make sure this resolver is the default
        ephemeralInstaller.isDefault = true;
        ephemeralInstaller.auxiliaryInfo = auxiliaryResponse;
        if (DEBUG_INSTANT) {
            Slog.v(TAG, "Adding ephemeral installer to the ResolveInfo list");
        }

        result.add(ephemeralInstaller);
        return result;
    }

    private static class CrossProfileDomainInfo {
        /* ResolveInfo for IntentForwarderActivity to send the intent to the other profile */
        ResolveInfo resolveInfo;
        /* Best domain verification status of the activities found in the other profile */
        int bestDomainVerificationStatus;
    }

    private CrossProfileDomainInfo getCrossProfileDomainPreferredLpr(Intent intent,
            String resolvedType, int flags, int sourceUserId, int parentUserId) {
        if (!mUserManager.hasUserRestriction(UserManager.ALLOW_PARENT_PROFILE_APP_LINKING,
                sourceUserId)) {
            return null;
        }
        List<ResolveInfo> resultTargetUser = mComponentResolver.queryActivities(intent,
                resolvedType, flags, parentUserId);

        if (resultTargetUser == null || resultTargetUser.isEmpty()) {
            return null;
        }
        CrossProfileDomainInfo result = null;
        int size = resultTargetUser.size();
        for (int i = 0; i < size; i++) {
            ResolveInfo riTargetUser = resultTargetUser.get(i);
            // Intent filter verification is only for filters that specify a host. So don't return
            // those that handle all web uris.
            if (riTargetUser.handleAllWebDataURI) {
                continue;
            }
            String packageName = riTargetUser.activityInfo.packageName;
            PackageSetting ps = mSettings.mPackages.get(packageName);
            if (ps == null) {
                continue;
            }
            long verificationState = getDomainVerificationStatusLPr(ps, parentUserId);
            int status = (int)(verificationState >> 32);
            if (result == null) {
                result = new CrossProfileDomainInfo();
                result.resolveInfo = createForwardingResolveInfoUnchecked(new IntentFilter(),
                        sourceUserId, parentUserId);
                result.bestDomainVerificationStatus = status;
            } else {
                result.bestDomainVerificationStatus = bestDomainVerificationStatus(status,
                        result.bestDomainVerificationStatus);
            }
        }
        // Don't consider matches with status NEVER across profiles.
        if (result != null && result.bestDomainVerificationStatus
                == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
            return null;
        }
        return result;
    }

    /**
     * Verification statuses are ordered from the worse to the best, except for
     * INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER, which is the worse.
     */
    private int bestDomainVerificationStatus(int status1, int status2) {
        if (status1 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
            return status2;
        }
        if (status2 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
            return status1;
        }
        return (int) MathUtils.max(status1, status2);
    }

    private boolean isUserEnabled(int userId) {
        long callingId = Binder.clearCallingIdentity();
        try {
            UserInfo userInfo = mUserManager.getUserInfo(userId);
            return userInfo != null && userInfo.isEnabled();
        } finally {
            Binder.restoreCallingIdentity(callingId);
        }
    }

    /**
     * Filter out activities with systemUserOnly flag set, when current user is not System.
     *
     * @return filtered list
     */
    private List<ResolveInfo> filterIfNotSystemUser(List<ResolveInfo> resolveInfos, int userId) {
        if (userId == UserHandle.USER_SYSTEM) {
            return resolveInfos;
        }
        for (int i = resolveInfos.size() - 1; i >= 0; i--) {
            ResolveInfo info = resolveInfos.get(i);
            if ((info.activityInfo.flags & ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
                resolveInfos.remove(i);
            }
        }
        return resolveInfos;
    }

    /**
     * Filters out ephemeral activities.
     * <p>When resolving for an ephemeral app, only activities that 1) are defined in the
     * ephemeral app or 2) marked with {@code visibleToEphemeral} are returned.
     *
     * @param resolveInfos The pre-filtered list of resolved activities
     * @param ephemeralPkgName The ephemeral package name. If {@code null}, no filtering
     *          is performed.
     * @param intent
     * @return A filtered list of resolved activities.
     */
    private List<ResolveInfo> applyPostResolutionFilter(@NonNull List<ResolveInfo> resolveInfos,
            String ephemeralPkgName, boolean allowDynamicSplits, int filterCallingUid,
            boolean resolveForStart, int userId, Intent intent) {
        final boolean blockInstant = intent.isWebIntent() && areWebInstantAppsDisabled(userId);
        for (int i = resolveInfos.size() - 1; i >= 0; i--) {
            final ResolveInfo info = resolveInfos.get(i);
            // remove locally resolved instant app web results when disabled
            if (info.isInstantAppAvailable && blockInstant) {
                resolveInfos.remove(i);
                continue;
            }
            // allow activities that are defined in the provided package
            if (allowDynamicSplits
                    && info.activityInfo != null
                    && info.activityInfo.splitName != null
                    && !ArrayUtils.contains(info.activityInfo.applicationInfo.splitNames,
                            info.activityInfo.splitName)) {
                if (mInstantAppInstallerActivity == null) {
                    if (DEBUG_INSTALL) {
                        Slog.v(TAG, "No installer - not adding it to the ResolveInfo list");
                    }
                    resolveInfos.remove(i);
                    continue;
                }
                if (blockInstant && isInstantApp(info.activityInfo.packageName, userId)) {
                    resolveInfos.remove(i);
                    continue;
                }
                // requested activity is defined in a split that hasn't been installed yet.
                // add the installer to the resolve list
                if (DEBUG_INSTALL) {
                    Slog.v(TAG, "Adding installer to the ResolveInfo list");
                }
                final ResolveInfo installerInfo = new ResolveInfo(
                        mInstantAppInstallerInfo);
                final ComponentName installFailureActivity = findInstallFailureActivity(
                        info.activityInfo.packageName,  filterCallingUid, userId);
                installerInfo.auxiliaryInfo = new AuxiliaryResolveInfo(
                        installFailureActivity,
                        info.activityInfo.packageName,
                        info.activityInfo.applicationInfo.longVersionCode,
                        info.activityInfo.splitName);
                // add a non-generic filter
                installerInfo.filter = new IntentFilter();

                // This resolve info may appear in the chooser UI, so let us make it
                // look as the one it replaces as far as the user is concerned which
                // requires loading the correct label and icon for the resolve info.
                installerInfo.resolvePackageName = info.getComponentInfo().packageName;
                installerInfo.labelRes = info.resolveLabelResId();
                installerInfo.icon = info.resolveIconResId();
                installerInfo.isInstantAppAvailable = true;
                resolveInfos.set(i, installerInfo);
                continue;
            }
            // caller is a full app, don't need to apply any other filtering
            if (ephemeralPkgName == null) {
                continue;
            } else if (ephemeralPkgName.equals(info.activityInfo.packageName)) {
                // caller is same app; don't need to apply any other filtering
                continue;
            } else if (resolveForStart
                    && (intent.isWebIntent()
                            || (intent.getFlags() & Intent.FLAG_ACTIVITY_MATCH_EXTERNAL) != 0)
                    && intent.getPackage() == null
                    && intent.getComponent() == null) {
                // ephemeral apps can launch other ephemeral apps indirectly
                continue;
            }
            // allow activities that have been explicitly exposed to ephemeral apps
            final boolean isEphemeralApp = info.activityInfo.applicationInfo.isInstantApp();
            if (!isEphemeralApp
                    && ((info.activityInfo.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0)) {
                continue;
            }
            resolveInfos.remove(i);
        }
        return resolveInfos;
    }

    /**
     * Returns the activity component that can handle install failures.
     * <p>By default, the instant application installer handles failures. However, an
     * application may want to handle failures on its own. Applications do this by
     * creating an activity with an intent filter that handles the action
     * {@link Intent#ACTION_INSTALL_FAILURE}.
     */
    private @Nullable ComponentName findInstallFailureActivity(
            String packageName, int filterCallingUid, int userId) {
        final Intent failureActivityIntent = new Intent(Intent.ACTION_INSTALL_FAILURE);
        failureActivityIntent.setPackage(packageName);
        // IMPORTANT: disallow dynamic splits to avoid an infinite loop
        final List<ResolveInfo> result = queryIntentActivitiesInternal(
                failureActivityIntent, null /*resolvedType*/, 0 /*flags*/, filterCallingUid, userId,
                false /*resolveForStart*/, false /*allowDynamicSplits*/);
        final int NR = result.size();
        if (NR > 0) {
            for (int i = 0; i < NR; i++) {
                final ResolveInfo info = result.get(i);
                if (info.activityInfo.splitName != null) {
                    continue;
                }
                return new ComponentName(packageName, info.activityInfo.name);
            }
        }
        return null;
    }

    /**
     * @param resolveInfos list of resolve infos in descending priority order
     * @return if the list contains a resolve info with non-negative priority
     */
    private boolean hasNonNegativePriority(List<ResolveInfo> resolveInfos) {
        return resolveInfos.size() > 0 && resolveInfos.get(0).priority >= 0;
    }

    private List<ResolveInfo> filterCandidatesWithDomainPreferredActivitiesLPr(Intent intent,
            int matchFlags, List<ResolveInfo> candidates, CrossProfileDomainInfo xpDomainInfo,
            int userId) {
        final boolean debug = (intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0;

        if (DEBUG_PREFERRED || DEBUG_DOMAIN_VERIFICATION) {
            Slog.v(TAG, "Filtering results with preferred activities. Candidates count: " +
                    candidates.size());
        }

        final ArrayList<ResolveInfo> result = new ArrayList<>();
        final ArrayList<ResolveInfo> alwaysList = new ArrayList<>();
        final ArrayList<ResolveInfo> undefinedList = new ArrayList<>();
        final ArrayList<ResolveInfo> alwaysAskList = new ArrayList<>();
        final ArrayList<ResolveInfo> neverList = new ArrayList<>();
        final ArrayList<ResolveInfo> matchAllList = new ArrayList<>();

        synchronized (mLock) {
            final int count = candidates.size();
            // First, try to use linked apps. Partition the candidates into four lists:
            // one for the final results, one for the "do not use ever", one for "undefined status"
            // and finally one for "browser app type".
            for (int n=0; n<count; n++) {
                ResolveInfo info = candidates.get(n);
                String packageName = info.activityInfo.packageName;
                PackageSetting ps = mSettings.mPackages.get(packageName);
                if (ps != null) {
                    // Add to the special match all list (Browser use case)
                    if (info.handleAllWebDataURI) {
                        matchAllList.add(info);
                        continue;
                    }
                    // Try to get the status from User settings first
                    long packedStatus = getDomainVerificationStatusLPr(ps, userId);
                    int status = (int)(packedStatus >> 32);
                    int linkGeneration = (int)(packedStatus & 0xFFFFFFFF);
                    if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS) {
                        if (DEBUG_DOMAIN_VERIFICATION || debug) {
                            Slog.i(TAG, "  + always: " + info.activityInfo.packageName
                                    + " : linkgen=" + linkGeneration);
                        }
                        // Use link-enabled generation as preferredOrder, i.e.
                        // prefer newly-enabled over earlier-enabled.
                        info.preferredOrder = linkGeneration;
                        alwaysList.add(info);
                    } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
                        if (DEBUG_DOMAIN_VERIFICATION || debug) {
                            Slog.i(TAG, "  + never: " + info.activityInfo.packageName);
                        }
                        neverList.add(info);
                    } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS_ASK) {
                        if (DEBUG_DOMAIN_VERIFICATION || debug) {
                            Slog.i(TAG, "  + always-ask: " + info.activityInfo.packageName);
                        }
                        alwaysAskList.add(info);
                    } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED ||
                            status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK) {
                        if (DEBUG_DOMAIN_VERIFICATION || debug) {
                            Slog.i(TAG, "  + ask: " + info.activityInfo.packageName);
                        }
                        undefinedList.add(info);
                    }
                }
            }

            // We'll want to include browser possibilities in a few cases
            boolean includeBrowser = false;

            // First try to add the "always" resolution(s) for the current user, if any
            if (alwaysList.size() > 0) {
                result.addAll(alwaysList);
            } else {
                // Add all undefined apps as we want them to appear in the disambiguation dialog.
                result.addAll(undefinedList);
                // Maybe add one for the other profile.
                if (xpDomainInfo != null && (
                        xpDomainInfo.bestDomainVerificationStatus
                        != INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER)) {
                    result.add(xpDomainInfo.resolveInfo);
                }
                includeBrowser = true;
            }

            // The presence of any 'always ask' alternatives means we'll also offer browsers.
            // If there were 'always' entries their preferred order has been set, so we also
            // back that off to make the alternatives equivalent
            if (alwaysAskList.size() > 0) {
                for (ResolveInfo i : result) {
                    i.preferredOrder = 0;
                }
                result.addAll(alwaysAskList);
                includeBrowser = true;
            }

            if (includeBrowser) {
                // Also add browsers (all of them or only the default one)
                if (DEBUG_DOMAIN_VERIFICATION) {
                    Slog.v(TAG, "   ...including browsers in candidate set");
                }
                if ((matchFlags & MATCH_ALL) != 0) {
                    result.addAll(matchAllList);
                } else {
                    // Browser/generic handling case.  If there's a default browser, go straight
                    // to that (but only if there is no other higher-priority match).
                    final String defaultBrowserPackageName =
                            mPermissionManager.getDefaultBrowser(userId);
                    int maxMatchPrio = 0;
                    ResolveInfo defaultBrowserMatch = null;
                    final int numCandidates = matchAllList.size();
                    for (int n = 0; n < numCandidates; n++) {
                        ResolveInfo info = matchAllList.get(n);
                        // track the highest overall match priority...
                        if (info.priority > maxMatchPrio) {
                            maxMatchPrio = info.priority;
                        }
                        // ...and the highest-priority default browser match
                        if (info.activityInfo.packageName.equals(defaultBrowserPackageName)) {
                            if (defaultBrowserMatch == null
                                    || (defaultBrowserMatch.priority < info.priority)) {
                                if (debug) {
                                    Slog.v(TAG, "Considering default browser match " + info);
                                }
                                defaultBrowserMatch = info;
                            }
                        }
                    }
                    if (defaultBrowserMatch != null
                            && defaultBrowserMatch.priority >= maxMatchPrio
                            && !TextUtils.isEmpty(defaultBrowserPackageName))
                    {
                        if (debug) {
                            Slog.v(TAG, "Default browser match " + defaultBrowserMatch);
                        }
                        result.add(defaultBrowserMatch);
                    } else {
                        result.addAll(matchAllList);
                    }
                }

                // If there is nothing selected, add all candidates and remove the ones that the user
                // has explicitly put into the INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER state
                if (result.size() == 0) {
                    result.addAll(candidates);
                    result.removeAll(neverList);
                }
            }
        }
        if (DEBUG_PREFERRED || DEBUG_DOMAIN_VERIFICATION) {
            Slog.v(TAG, "Filtered results with preferred activities. New candidates count: " +
                    result.size());
            for (ResolveInfo info : result) {
                Slog.v(TAG, "  + " + info.activityInfo);
            }
        }
        return result;
    }

    // Returns a packed value as a long:
    //
    // high 'int'-sized word: link status: undefined/ask/never/always.
    // low 'int'-sized word: relative priority among 'always' results.
    private long getDomainVerificationStatusLPr(PackageSetting ps, int userId) {
        long result = ps.getDomainVerificationStatusForUser(userId);
        // if none available, get the master status
        if (result >> 32 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED) {
            if (ps.getIntentFilterVerificationInfo() != null) {
                result = ((long)ps.getIntentFilterVerificationInfo().getStatus()) << 32;
            }
        }
        return result;
    }

    private ResolveInfo querySkipCurrentProfileIntents(
            List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType,
            int flags, int sourceUserId) {
        if (matchingFilters != null) {
            int size = matchingFilters.size();
            for (int i = 0; i < size; i ++) {
                CrossProfileIntentFilter filter = matchingFilters.get(i);
                if ((filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) != 0) {
                    // Checking if there are activities in the target user that can handle the
                    // intent.
                    ResolveInfo resolveInfo = createForwardingResolveInfo(filter, intent,
                            resolvedType, flags, sourceUserId);
                    if (resolveInfo != null) {
                        return resolveInfo;
                    }
                }
            }
        }
        return null;
    }

    // Return matching ResolveInfo in target user if any.
    private ResolveInfo queryCrossProfileIntents(
            List<CrossProfileIntentFilter> matchingFilters, Intent intent, String resolvedType,
            int flags, int sourceUserId, boolean matchInCurrentProfile) {
        if (matchingFilters != null) {
            // Two {@link CrossProfileIntentFilter}s can have the same targetUserId and
            // match the same intent. For performance reasons, it is better not to
            // run queryIntent twice for the same userId
            SparseBooleanArray alreadyTriedUserIds = new SparseBooleanArray();
            int size = matchingFilters.size();
            for (int i = 0; i < size; i++) {
                CrossProfileIntentFilter filter = matchingFilters.get(i);
                int targetUserId = filter.getTargetUserId();
                boolean skipCurrentProfile =
                        (filter.getFlags() & PackageManager.SKIP_CURRENT_PROFILE) != 0;
                boolean skipCurrentProfileIfNoMatchFound =
                        (filter.getFlags() & PackageManager.ONLY_IF_NO_MATCH_FOUND) != 0;
                if (!skipCurrentProfile && !alreadyTriedUserIds.get(targetUserId)
                        && (!skipCurrentProfileIfNoMatchFound || !matchInCurrentProfile)) {
                    // Checking if there are activities in the target user that can handle the
                    // intent.
                    ResolveInfo resolveInfo = createForwardingResolveInfo(filter, intent,
                            resolvedType, flags, sourceUserId);
                    if (resolveInfo != null) return resolveInfo;
                    alreadyTriedUserIds.put(targetUserId, true);
                }
            }
        }
        return null;
    }

    /**
     * If the filter's target user can handle the intent and is enabled: returns a ResolveInfo that
     * will forward the intent to the filter's target user.
     * Otherwise, returns null.
     */
    private ResolveInfo createForwardingResolveInfo(CrossProfileIntentFilter filter, Intent intent,
            String resolvedType, int flags, int sourceUserId) {
        int targetUserId = filter.getTargetUserId();
        List<ResolveInfo> resultTargetUser = mComponentResolver.queryActivities(intent,
                resolvedType, flags, targetUserId);
        if (resultTargetUser != null && isUserEnabled(targetUserId)) {
            // If all the matches in the target profile are suspended, return null.
            for (int i = resultTargetUser.size() - 1; i >= 0; i--) {
                if ((resultTargetUser.get(i).activityInfo.applicationInfo.flags
                        & ApplicationInfo.FLAG_SUSPENDED) == 0) {
                    return createForwardingResolveInfoUnchecked(filter, sourceUserId,
                            targetUserId);
                }
            }
        }
        return null;
    }

    private ResolveInfo createForwardingResolveInfoUnchecked(IntentFilter filter,
            int sourceUserId, int targetUserId) {
        ResolveInfo forwardingResolveInfo = new ResolveInfo();
        long ident = Binder.clearCallingIdentity();
        boolean targetIsProfile;
        try {
            targetIsProfile = mUserManager.getUserInfo(targetUserId).isManagedProfile();
        } finally {
            Binder.restoreCallingIdentity(ident);
        }
        String className;
        if (targetIsProfile) {
            className = FORWARD_INTENT_TO_MANAGED_PROFILE;
        } else {
            className = FORWARD_INTENT_TO_PARENT;
        }
        ComponentName forwardingActivityComponentName = new ComponentName(
                mAndroidApplication.packageName, className);
        ActivityInfo forwardingActivityInfo = getActivityInfo(forwardingActivityComponentName, 0,
                sourceUserId);
        if (!targetIsProfile) {
            forwardingActivityInfo.showUserIcon = targetUserId;
            forwardingResolveInfo.noResourceId = true;
        }
        forwardingResolveInfo.activityInfo = forwardingActivityInfo;
        forwardingResolveInfo.priority = 0;
        forwardingResolveInfo.preferredOrder = 0;
        forwardingResolveInfo.match = 0;
        forwardingResolveInfo.isDefault = true;
        forwardingResolveInfo.filter = filter;
        forwardingResolveInfo.targetUserId = targetUserId;
        return forwardingResolveInfo;
    }

    @Override
    public @NonNull ParceledListSlice<ResolveInfo> queryIntentActivityOptions(ComponentName caller,
            Intent[] specifics, String[] specificTypes, Intent intent,
            String resolvedType, int flags, int userId) {
        return new ParceledListSlice<>(queryIntentActivityOptionsInternal(caller, specifics,
                specificTypes, intent, resolvedType, flags, userId));
    }

    private @NonNull List<ResolveInfo> queryIntentActivityOptionsInternal(ComponentName caller,
            Intent[] specifics, String[] specificTypes, Intent intent,
            String resolvedType, int flags, int userId) {
        if (!mUserManager.exists(userId)) return Collections.emptyList();
        final int callingUid = Binder.getCallingUid();
        flags = updateFlagsForResolve(flags, userId, callingUid, false /*includeInstantApps*/);
        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
                false /*requireFullPermission*/, false /*checkShell*/,
                "query intent activity options");
        final String resultsAction = intent.getAction();

        final List<ResolveInfo> results = queryIntentActivitiesInternal(intent, resolvedType, flags
                | PackageManager.GET_RESOLVED_FILTER, userId);

        if (DEBUG_INTENT_MATCHING) {
            Log.v(TAG, "Query " + intent + ": " + results);
        }

        int specificsPos = 0;
        int N;

        // todo: note that the algorithm used here is O(N^2).  This
        // isn't a problem in our current environment, but if we start running
        // into situations where we have more than 5 or 10 matches then this
        // should probably be changed to something smarter...

        // First we go through and resolve each of the specific items
        // that were supplied, taking care of removing any corresponding
        // duplicate items in the generic resolve list.
        if (specifics != null) {
            for (int i=0; i<specifics.length; i++) {
                final Intent sintent = specifics[i];
                if (sintent == null) {
                    continue;
                }

                if (DEBUG_INTENT_MATCHING) {
                    Log.v(TAG, "Specific #" + i + ": " + sintent);
                }

                String action = sintent.getAction();
                if (resultsAction != null && resultsAction.equals(action)) {
                    // If this action was explicitly requested, then don't
                    // remove things that have it.
                    action = null;
                }

                ResolveInfo ri = null;
                ActivityInfo ai = null;

                ComponentName comp = sintent.getComponent();
                if (comp == null) {
                    ri = resolveIntent(
                        sintent,
                        specificTypes != null ? specificTypes[i] : null,
                            flags, userId);
                    if (ri == null) {
                        continue;
                    }
                    if (ri == mResolveInfo) {
                        // ACK!  Must do something better with this.
                    }
                    ai = ri.activityInfo;
                    comp = new ComponentName(ai.applicationInfo.packageName,
                            ai.name);
                } else {
                    ai = getActivityInfo(comp, flags, userId);
                    if (ai == null) {
                        continue;
                    }
                }

                // Look for any generic query activities that are duplicates
                // of this specific one, and remove them from the results.
                if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Specific #" + i + ": " + ai);
                N = results.size();
                int j;
                for (j=specificsPos; j<N; j++) {
                    ResolveInfo sri = results.get(j);
                    if ((sri.activityInfo.name.equals(comp.getClassName())
                            && sri.activityInfo.applicationInfo.packageName.equals(
                                    comp.getPackageName()))
                        || (action != null && sri.filter.matchAction(action))) {
                        results.remove(j);
                        if (DEBUG_INTENT_MATCHING) Log.v(
                            TAG, "Removing duplicate item from " + j
                            + " due to specific " + specificsPos);
                        if (ri == null) {
                            ri = sri;
                        }
                        j--;
                        N--;
                    }
                }

                // Add this specific item to its proper place.
                if (ri == null) {
                    ri = new ResolveInfo();
                    ri.activityInfo = ai;
                }
                results.add(specificsPos, ri);
                ri.specificIndex = i;
                specificsPos++;
            }
        }

        // Now we go through the remaining generic results and remove any
        // duplicate actions that are found here.
        N = results.size();
        for (int i=specificsPos; i<N-1; i++) {
            final ResolveInfo rii = results.get(i);
            if (rii.filter == null) {
                continue;
            }

            // Iterate over all of the actions of this result's intent
            // filter...  typically this should be just one.
            final Iterator<String> it = rii.filter.actionsIterator();
            if (it == null) {
                continue;
            }
            while (it.hasNext()) {
                final String action = it.next();
                if (resultsAction != null && resultsAction.equals(action)) {
                    // If this action was explicitly requested, then don't
                    // remove things that have it.
                    continue;
                }
                for (int j=i+1; j<N; j++) {
                    final ResolveInfo rij = results.get(j);
                    if (rij.filter != null && rij.filter.hasAction(action)) {
                        results.remove(j);
                        if (DEBUG_INTENT_MATCHING) Log.v(
                            TAG, "Removing duplicate item from " + j
                            + " due to action " + action + " at " + i);
                        j--;
                        N--;
                    }
                }
            }

            // If the caller didn't request filter information, drop it now
            // so we don't have to marshall/unmarshall it.
            if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) {
                rii.filter = null;
            }
        }

        // Filter out the caller activity if so requested.
        if (caller != null) {
            N = results.size();
            for (int i=0; i<N; i++) {
                ActivityInfo ainfo = results.get(i).activityInfo;
                if (caller.getPackageName().equals(ainfo.applicationInfo.packageName)
                        && caller.getClassName().equals(ainfo.name)) {
                    results.remove(i);
                    break;
                }
            }
        }

        // If the caller didn't request filter information,
        // drop them now so we don't have to
        // marshall/unmarshall it.
        if ((flags&PackageManager.GET_RESOLVED_FILTER) == 0) {
            N = results.size();
            for (int i=0; i<N; i++) {
                results.get(i).filter = null;
            }
        }

        if (DEBUG_INTENT_MATCHING) Log.v(TAG, "Result: " + results);
        return results;
    }

    @Override
    public @NonNull ParceledListSlice<ResolveInfo> queryIntentReceivers(Intent intent,
            String resolvedType, int flags, int userId) {
        return new ParceledListSlice<>(
                queryIntentReceiversInternal(intent, resolvedType, flags, userId,
                        false /*allowDynamicSplits*/));
    }

    private @NonNull List<ResolveInfo> queryIntentReceiversInternal(Intent intent,
            String resolvedType, int flags, int userId, boolean allowDynamicSplits) {
        if (!mUserManager.exists(userId)) return Collections.emptyList();
        final int callingUid = Binder.getCallingUid();
        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
                false /*requireFullPermission*/, false /*checkShell*/,
                "query intent receivers");
        final String instantAppPkgName = getInstantAppPackageName(callingUid);
        flags = updateFlagsForResolve(flags, userId, callingUid, false /*includeInstantApps*/);
        ComponentName comp = intent.getComponent();
        if (comp == null) {
            if (intent.getSelector() != null) {
                intent = intent.getSelector();
                comp = intent.getComponent();
            }
        }
        if (comp != null) {
            final List<ResolveInfo> list = new ArrayList<>(1);
            final ActivityInfo ai = getReceiverInfo(comp, flags, userId);
            if (ai != null) {
                // When specifying an explicit component, we prevent the activity from being
                // used when either 1) the calling package is normal and the activity is within
                // an instant application or 2) the calling package is ephemeral and the
                // activity is not visible to instant applications.
                final boolean matchInstantApp =
                        (flags & PackageManager.MATCH_INSTANT) != 0;
                final boolean matchVisibleToInstantAppOnly =
                        (flags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
                final boolean matchExplicitlyVisibleOnly =
                        (flags & PackageManager.MATCH_EXPLICITLY_VISIBLE_ONLY) != 0;
                final boolean isCallerInstantApp =
                        instantAppPkgName != null;
                final boolean isTargetSameInstantApp =
                        comp.getPackageName().equals(instantAppPkgName);
                final boolean isTargetInstantApp =
                        (ai.applicationInfo.privateFlags
                                & ApplicationInfo.PRIVATE_FLAG_INSTANT) != 0;
                final boolean isTargetVisibleToInstantApp =
                        (ai.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0;
                final boolean isTargetExplicitlyVisibleToInstantApp =
                        isTargetVisibleToInstantApp
                        && (ai.flags & ActivityInfo.FLAG_IMPLICITLY_VISIBLE_TO_INSTANT_APP) == 0;
                final boolean isTargetHiddenFromInstantApp =
                        !isTargetVisibleToInstantApp
                        || (matchExplicitlyVisibleOnly && !isTargetExplicitlyVisibleToInstantApp);
                final boolean blockResolution =
                        !isTargetSameInstantApp
                        && ((!matchInstantApp && !isCallerInstantApp && isTargetInstantApp)
                                || (matchVisibleToInstantAppOnly && isCallerInstantApp
                                        && isTargetHiddenFromInstantApp));
                if (!blockResolution) {
                    ResolveInfo ri = new ResolveInfo();
                    ri.activityInfo = ai;
                    list.add(ri);
                }
            }
            return applyPostResolutionFilter(
                    list, instantAppPkgName, allowDynamicSplits, callingUid, false, userId,
                    intent);
        }

        // reader
        synchronized (mLock) {
            String pkgName = intent.getPackage();
            if (pkgName == null) {
                final List<ResolveInfo> result =
                        mComponentResolver.queryReceivers(intent, resolvedType, flags, userId);
                if (result == null) {
                    return Collections.emptyList();
                }
                return applyPostResolutionFilter(
                        result, instantAppPkgName, allowDynamicSplits, callingUid, false, userId,
                        intent);
            }
            final AndroidPackage pkg = mPackages.get(pkgName);
            if (pkg != null) {
                final List<ResolveInfo> result = mComponentResolver.queryReceivers(
                        intent, resolvedType, flags, pkg.getReceivers(), userId);
                if (result == null) {
                    return Collections.emptyList();
                }
                return applyPostResolutionFilter(
                        result, instantAppPkgName, allowDynamicSplits, callingUid, false, userId,
                        intent);
            }
            return Collections.emptyList();
        }
    }

    @Override
    public ResolveInfo resolveService(Intent intent, String resolvedType, int flags, int userId) {
        final int callingUid = Binder.getCallingUid();
        return resolveServiceInternal(intent, resolvedType, flags, userId, callingUid);
    }

    private ResolveInfo resolveServiceInternal(Intent intent, String resolvedType, int flags,
            int userId, int callingUid) {
        if (!mUserManager.exists(userId)) return null;
        flags = updateFlagsForResolve(flags, userId, callingUid, false /*includeInstantApps*/);
        List<ResolveInfo> query = queryIntentServicesInternal(
                intent, resolvedType, flags, userId, callingUid, false /*includeInstantApps*/);
        if (query != null) {
            if (query.size() >= 1) {
                // If there is more than one service with the same priority,
                // just arbitrarily pick the first one.
                return query.get(0);
            }
        }
        return null;
    }

    @Override
    public @NonNull ParceledListSlice<ResolveInfo> queryIntentServices(Intent intent,
            String resolvedType, int flags, int userId) {
        final int callingUid = Binder.getCallingUid();
        return new ParceledListSlice<>(queryIntentServicesInternal(
                intent, resolvedType, flags, userId, callingUid, false /*includeInstantApps*/));
    }

    private @NonNull List<ResolveInfo> queryIntentServicesInternal(Intent intent,
            String resolvedType, int flags, int userId, int callingUid,
            boolean includeInstantApps) {
        if (!mUserManager.exists(userId)) return Collections.emptyList();
        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
                false /*requireFullPermission*/, false /*checkShell*/,
                "query intent receivers");
        final String instantAppPkgName = getInstantAppPackageName(callingUid);
        flags = updateFlagsForResolve(flags, userId, callingUid, includeInstantApps);
        ComponentName comp = intent.getComponent();
        if (comp == null) {
            if (intent.getSelector() != null) {
                intent = intent.getSelector();
                comp = intent.getComponent();
            }
        }
        if (comp != null) {
            final List<ResolveInfo> list = new ArrayList<>(1);
            final ServiceInfo si = getServiceInfo(comp, flags, userId);
            if (si != null) {
                // When specifying an explicit component, we prevent the service from being
                // used when either 1) the service is in an instant application and the
                // caller is not the same instant application or 2) the calling package is
                // ephemeral and the activity is not visible to ephemeral applications.
                final boolean matchInstantApp =
                        (flags & PackageManager.MATCH_INSTANT) != 0;
                final boolean matchVisibleToInstantAppOnly =
                        (flags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
                final boolean isCallerInstantApp =
                        instantAppPkgName != null;
                final boolean isTargetSameInstantApp =
                        comp.getPackageName().equals(instantAppPkgName);
                final boolean isTargetInstantApp =
                        (si.applicationInfo.privateFlags
                                & ApplicationInfo.PRIVATE_FLAG_INSTANT) != 0;
                final boolean isTargetHiddenFromInstantApp =
                        (si.flags & ServiceInfo.FLAG_VISIBLE_TO_INSTANT_APP) == 0;
                final boolean blockResolution =
                        !isTargetSameInstantApp
                        && ((!matchInstantApp && !isCallerInstantApp && isTargetInstantApp)
                                || (matchVisibleToInstantAppOnly && isCallerInstantApp
                                        && isTargetHiddenFromInstantApp));
                if (!blockResolution) {
                    final ResolveInfo ri = new ResolveInfo();
                    ri.serviceInfo = si;
                    list.add(ri);
                }
            }
            return list;
        }

        // reader
        synchronized (mLock) {
            String pkgName = intent.getPackage();
            if (pkgName == null) {
                final List<ResolveInfo> resolveInfos = mComponentResolver.queryServices(intent,
                        resolvedType, flags, userId);
                if (resolveInfos == null) {
                    return Collections.emptyList();
                }
                return applyPostServiceResolutionFilter(
                        resolveInfos,
                        instantAppPkgName);
            }
            final AndroidPackage pkg = mPackages.get(pkgName);
            if (pkg != null) {
                final List<ResolveInfo> resolveInfos = mComponentResolver.queryServices(intent,
                        resolvedType, flags, pkg.getServices(),
                        userId);
                if (resolveInfos == null) {
                    return Collections.emptyList();
                }
                return applyPostServiceResolutionFilter(
                        resolveInfos,
                        instantAppPkgName);
            }
            return Collections.emptyList();
        }
    }

    private List<ResolveInfo> applyPostServiceResolutionFilter(List<ResolveInfo> resolveInfos,
            String instantAppPkgName) {
        if (instantAppPkgName == null) {
            return resolveInfos;
        }
        for (int i = resolveInfos.size() - 1; i >= 0; i--) {
            final ResolveInfo info = resolveInfos.get(i);
            final boolean isEphemeralApp = info.serviceInfo.applicationInfo.isInstantApp();
            // allow services that are defined in the provided package
            if (isEphemeralApp && instantAppPkgName.equals(info.serviceInfo.packageName)) {
                if (info.serviceInfo.splitName != null
                        && !ArrayUtils.contains(info.serviceInfo.applicationInfo.splitNames,
                                info.serviceInfo.splitName)) {
                    // requested service is defined in a split that hasn't been installed yet.
                    // add the installer to the resolve list
                    if (DEBUG_INSTANT) {
                        Slog.v(TAG, "Adding ephemeral installer to the ResolveInfo list");
                    }
                    final ResolveInfo installerInfo = new ResolveInfo(
                            mInstantAppInstallerInfo);
                    installerInfo.auxiliaryInfo = new AuxiliaryResolveInfo(
                            null /* installFailureActivity */,
                            info.serviceInfo.packageName,
                            info.serviceInfo.applicationInfo.longVersionCode,
                            info.serviceInfo.splitName);
                    // add a non-generic filter
                    installerInfo.filter = new IntentFilter();
                    // load resources from the correct package
                    installerInfo.resolvePackageName = info.getComponentInfo().packageName;
                    resolveInfos.set(i, installerInfo);
                }
                continue;
            }
            // allow services that have been explicitly exposed to ephemeral apps
            if (!isEphemeralApp
                    && ((info.serviceInfo.flags & ServiceInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0)) {
                continue;
            }
            resolveInfos.remove(i);
        }
        return resolveInfos;
    }

    @Override
    public @NonNull ParceledListSlice<ResolveInfo> queryIntentContentProviders(Intent intent,
            String resolvedType, int flags, int userId) {
        return new ParceledListSlice<>(
                queryIntentContentProvidersInternal(intent, resolvedType, flags, userId));
    }

    private @NonNull List<ResolveInfo> queryIntentContentProvidersInternal(
            Intent intent, String resolvedType, int flags, int userId) {
        if (!mUserManager.exists(userId)) return Collections.emptyList();
        final int callingUid = Binder.getCallingUid();
        final String instantAppPkgName = getInstantAppPackageName(callingUid);
        flags = updateFlagsForResolve(flags, userId, callingUid, false /*includeInstantApps*/);
        ComponentName comp = intent.getComponent();
        if (comp == null) {
            if (intent.getSelector() != null) {
                intent = intent.getSelector();
                comp = intent.getComponent();
            }
        }
        if (comp != null) {
            final List<ResolveInfo> list = new ArrayList<>(1);
            final ProviderInfo pi = getProviderInfo(comp, flags, userId);
            if (pi != null) {
                // When specifying an explicit component, we prevent the provider from being
                // used when either 1) the provider is in an instant application and the
                // caller is not the same instant application or 2) the calling package is an
                // instant application and the provider is not visible to instant applications.
                final boolean matchInstantApp =
                        (flags & PackageManager.MATCH_INSTANT) != 0;
                final boolean matchVisibleToInstantAppOnly =
                        (flags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
                final boolean isCallerInstantApp =
                        instantAppPkgName != null;
                final boolean isTargetSameInstantApp =
                        comp.getPackageName().equals(instantAppPkgName);
                final boolean isTargetInstantApp =
                        (pi.applicationInfo.privateFlags
                                & ApplicationInfo.PRIVATE_FLAG_INSTANT) != 0;
                final boolean isTargetHiddenFromInstantApp =
                        (pi.flags & ProviderInfo.FLAG_VISIBLE_TO_INSTANT_APP) == 0;
                final boolean blockResolution =
                        !isTargetSameInstantApp
                        && ((!matchInstantApp && !isCallerInstantApp && isTargetInstantApp)
                                || (matchVisibleToInstantAppOnly && isCallerInstantApp
                                        && isTargetHiddenFromInstantApp));
                if (!blockResolution) {
                    final ResolveInfo ri = new ResolveInfo();
                    ri.providerInfo = pi;
                    list.add(ri);
                }
            }
            return list;
        }

        // reader
        synchronized (mLock) {
            String pkgName = intent.getPackage();
            if (pkgName == null) {
                final List<ResolveInfo> resolveInfos = mComponentResolver.queryProviders(intent,
                        resolvedType, flags, userId);
                if (resolveInfos == null) {
                    return Collections.emptyList();
                }
                return applyPostContentProviderResolutionFilter(
                        resolveInfos,
                        instantAppPkgName);
            }
            final AndroidPackage pkg = mPackages.get(pkgName);
            if (pkg != null) {
                final List<ResolveInfo> resolveInfos = mComponentResolver.queryProviders(intent,
                        resolvedType, flags,
                        pkg.getProviders(), userId);
                if (resolveInfos == null) {
                    return Collections.emptyList();
                }
                return applyPostContentProviderResolutionFilter(
                        resolveInfos,
                        instantAppPkgName);
            }
            return Collections.emptyList();
        }
    }

    private List<ResolveInfo> applyPostContentProviderResolutionFilter(
            List<ResolveInfo> resolveInfos, String instantAppPkgName) {
        if (instantAppPkgName == null) {
            return resolveInfos;
        }
        for (int i = resolveInfos.size() - 1; i >= 0; i--) {
            final ResolveInfo info = resolveInfos.get(i);
            final boolean isEphemeralApp = info.providerInfo.applicationInfo.isInstantApp();
            // allow providers that are defined in the provided package
            if (isEphemeralApp && instantAppPkgName.equals(info.providerInfo.packageName)) {
                if (info.providerInfo.splitName != null
                        && !ArrayUtils.contains(info.providerInfo.applicationInfo.splitNames,
                                info.providerInfo.splitName)) {
                    // requested provider is defined in a split that hasn't been installed yet.
                    // add the installer to the resolve list
                    if (DEBUG_INSTANT) {
                        Slog.v(TAG, "Adding ephemeral installer to the ResolveInfo list");
                    }
                    final ResolveInfo installerInfo = new ResolveInfo(
                            mInstantAppInstallerInfo);
                    installerInfo.auxiliaryInfo = new AuxiliaryResolveInfo(
                            null /*failureActivity*/,
                            info.providerInfo.packageName,
                            info.providerInfo.applicationInfo.longVersionCode,
                            info.providerInfo.splitName);
                    // add a non-generic filter
                    installerInfo.filter = new IntentFilter();
                    // load resources from the correct package
                    installerInfo.resolvePackageName = info.getComponentInfo().packageName;
                    resolveInfos.set(i, installerInfo);
                }
                continue;
            }
            // allow providers that have been explicitly exposed to instant applications
            if (!isEphemeralApp
                    && ((info.providerInfo.flags & ProviderInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0)) {
                continue;
            }
            resolveInfos.remove(i);
        }
        return resolveInfos;
    }

    @Override
    public ParceledListSlice<PackageInfo> getInstalledPackages(int flags, int userId) {
        final int callingUid = Binder.getCallingUid();
        if (getInstantAppPackageName(callingUid) != null) {
            return ParceledListSlice.emptyList();
        }
        if (!mUserManager.exists(userId)) return ParceledListSlice.emptyList();
        flags = updateFlagsForPackage(flags, userId);
        final boolean listUninstalled = (flags & MATCH_KNOWN_PACKAGES) != 0;
        final boolean listApex = (flags & MATCH_APEX) != 0;
        final boolean listFactory = (flags & MATCH_FACTORY_ONLY) != 0;

        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
                false /* requireFullPermission */, false /* checkShell */,
                "get installed packages");

        // writer
        synchronized (mLock) {
            ArrayList<PackageInfo> list;
            if (listUninstalled) {
                list = new ArrayList<>(mSettings.mPackages.size());
                for (PackageSetting ps : mSettings.mPackages.values()) {
                    if (filterSharedLibPackageLPr(ps, callingUid, userId, flags)) {
                        continue;
                    }
                    if (shouldFilterApplicationLocked(ps, callingUid, userId)) {
                        continue;
                    }
                    final PackageInfo pi = generatePackageInfo(ps, flags, userId);
                    if (pi != null) {
                        list.add(pi);
                    }
                }
            } else {
                list = new ArrayList<>(mPackages.size());
                for (AndroidPackage p : mPackages.values()) {
                    final PackageSetting ps = getPackageSetting(p.getPackageName());
                    if (filterSharedLibPackageLPr(ps, callingUid, userId, flags)) {
                        continue;
                    }
                    if (shouldFilterApplicationLocked(ps, callingUid, userId)) {
                        continue;
                    }
                    final PackageInfo pi = generatePackageInfo(ps, flags, userId);
                    if (pi != null) {
                        list.add(pi);
                    }
                }
            }
            if (listApex) {
                if (listFactory) {
                    list.addAll(mApexManager.getFactoryPackages());
                } else {
                    list.addAll(mApexManager.getActivePackages());
                }
                if (listUninstalled) {
                    list.addAll(mApexManager.getInactivePackages());
                }
            }
            return new ParceledListSlice<>(list);
        }
    }

    private void addPackageHoldingPermissions(ArrayList<PackageInfo> list, PackageSetting ps,
            String[] permissions, boolean[] tmp, int flags, int userId) {
        int numMatch = 0;
        final PermissionsState permissionsState = ps.getPermissionsState();
        for (int i=0; i<permissions.length; i++) {
            final String permission = permissions[i];
            if (permissionsState.hasPermission(permission, userId)) {
                tmp[i] = true;
                numMatch++;
            } else {
                tmp[i] = false;
            }
        }
        if (numMatch == 0) {
            return;
        }
        final PackageInfo pi = generatePackageInfo(ps, flags, userId);

        // The above might return null in cases of uninstalled apps or install-state
        // skew across users/profiles.
        if (pi != null) {
            if ((flags&PackageManager.GET_PERMISSIONS) == 0) {
                if (numMatch == permissions.length) {
                    pi.requestedPermissions = permissions;
                } else {
                    pi.requestedPermissions = new String[numMatch];
                    numMatch = 0;
                    for (int i=0; i<permissions.length; i++) {
                        if (tmp[i]) {
                            pi.requestedPermissions[numMatch] = permissions[i];
                            numMatch++;
                        }
                    }
                }
            }
            list.add(pi);
        }
    }

    @Override
    public ParceledListSlice<PackageInfo> getPackagesHoldingPermissions(
            String[] permissions, int flags, int userId) {
        if (!mUserManager.exists(userId)) return ParceledListSlice.emptyList();
        flags = updateFlagsForPackage(flags, userId);
        mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId,
                true /* requireFullPermission */, false /* checkShell */,
                "get packages holding permissions");
        final boolean listUninstalled = (flags & MATCH_KNOWN_PACKAGES) != 0;

        // writer
        synchronized (mLock) {
            ArrayList<PackageInfo> list = new ArrayList<>();
            boolean[] tmpBools = new boolean[permissions.length];
            if (listUninstalled) {
                for (PackageSetting ps : mSettings.mPackages.values()) {
                    addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags,
                            userId);
                }
            } else {
                for (AndroidPackage pkg : mPackages.values()) {
                    PackageSetting ps = getPackageSetting(pkg.getPackageName());
                    if (ps != null) {
                        addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags,
                                userId);
                    }
                }
            }

            return new ParceledListSlice<>(list);
        }
    }

    @Override
    public ParceledListSlice<ApplicationInfo> getInstalledApplications(int flags, int userId) {
        final int callingUid = Binder.getCallingUid();
        return new ParceledListSlice<>(
                getInstalledApplicationsListInternal(flags, userId, callingUid));
    }

    private List<ApplicationInfo> getInstalledApplicationsListInternal(int flags, int userId,
            int callingUid) {
        if (getInstantAppPackageName(callingUid) != null) {
            return Collections.emptyList();
        }
        if (!mUserManager.exists(userId)) return Collections.emptyList();
        flags = updateFlagsForApplication(flags, userId);
        final boolean listUninstalled = (flags & MATCH_KNOWN_PACKAGES) != 0;

        mPermissionManager.enforceCrossUserPermission(
            callingUid,
            userId,
            false /* requireFullPermission */,
            false /* checkShell */,
            "get installed application info");

        // writer
        synchronized (mLock) {
            ArrayList<ApplicationInfo> list;
            if (listUninstalled) {
                list = new ArrayList<>(mSettings.mPackages.size());
                for (PackageSetting ps : mSettings.mPackages.values()) {
                    ApplicationInfo ai;
                    int effectiveFlags = flags;
                    if (ps.isSystem()) {
                        effectiveFlags |= PackageManager.MATCH_ANY_USER;
                    }
                    if (ps.pkg != null) {
                        if (filterSharedLibPackageLPr(ps, callingUid, userId, flags)) {
                            continue;
                        }
                        if (shouldFilterApplicationLocked(ps, callingUid, userId)) {
                            continue;
                        }
                        ai = PackageInfoUtils.generateApplicationInfo(ps.pkg, effectiveFlags,
                                ps.readUserState(userId), userId);
                        if (ai != null) {
                            ai.packageName = resolveExternalPackageNameLPr(ps.pkg);
                        }
                    } else {
                        // Shared lib filtering done in generateApplicationInfoFromSettingsLPw
                        // and already converts to externally visible package name
                        ai = generateApplicationInfoFromSettingsLPw(ps.name,
                                callingUid, effectiveFlags, userId);
                    }
                    if (ai != null) {
                        list.add(ai);
                    }
                }
            } else {
                list = new ArrayList<>(mPackages.size());
                for (AndroidPackage p : mPackages.values()) {
                    final PackageSetting ps = getPackageSetting(p.getPackageName());
                    if (ps != null) {
                        if (filterSharedLibPackageLPr(ps, Binder.getCallingUid(), userId, flags)) {
                            continue;
                        }
                        if (shouldFilterApplicationLocked(ps, callingUid, userId)) {
                            continue;
                        }
                        ApplicationInfo ai = PackageInfoUtils.generateApplicationInfo(p, flags,
                                ps.readUserState(userId), userId);
                        if (ai != null) {
                            ai.packageName = resolveExternalPackageNameLPr(p);
                            list.add(ai);
                        }
                    }
                }
            }

            return list;
        }
    }

    @Override
    public ParceledListSlice<InstantAppInfo> getInstantApps(int userId) {
        if (HIDE_EPHEMERAL_APIS) {
            return null;
        }
        if (!canViewInstantApps(Binder.getCallingUid(), userId)) {
            mContext.enforceCallingOrSelfPermission(Manifest.permission.ACCESS_INSTANT_APPS,
                    "getEphemeralApplications");
        }
        mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId,
                true /* requireFullPermission */, false /* checkShell */,
                "getEphemeralApplications");
        synchronized (mLock) {
            List<InstantAppInfo> instantApps = mInstantAppRegistry
                    .getInstantAppsLPr(userId);
            if (instantApps != null) {
                return new ParceledListSlice<>(instantApps);
            }
        }
        return null;
    }

    @Override
    public boolean isInstantApp(String packageName, int userId) {
        final int callingUid = Binder.getCallingUid();
        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
                true /* requireFullPermission */, false /* checkShell */,
                "isInstantApp");

        return isInstantAppInternal(packageName, userId, callingUid);
    }

    private boolean isInstantAppInternal(String packageName, @UserIdInt int userId,
            int callingUid) {
        if (HIDE_EPHEMERAL_APIS) {
            return false;
        }
        synchronized (mLock) {
            if (Process.isIsolated(callingUid)) {
                callingUid = mIsolatedOwners.get(callingUid);
            }
            final PackageSetting ps = mSettings.mPackages.get(packageName);
            final boolean returnAllowed =
                    ps != null
                    && (isCallerSameApp(packageName, callingUid)
                            || canViewInstantApps(callingUid, userId)
                            || mInstantAppRegistry.isInstantAccessGranted(
                                    userId, UserHandle.getAppId(callingUid), ps.appId));
            if (returnAllowed) {
                return ps.getInstantApp(userId);
            }
        }
        return false;
    }

    @Override
    public byte[] getInstantAppCookie(String packageName, int userId) {
        if (HIDE_EPHEMERAL_APIS) {
            return null;
        }

        mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId,
                true /* requireFullPermission */, false /* checkShell */,
                "getInstantAppCookie");
        if (!isCallerSameApp(packageName, Binder.getCallingUid())) {
            return null;
        }
        synchronized (mLock) {
            return mInstantAppRegistry.getInstantAppCookieLPw(
                    packageName, userId);
        }
    }

    @Override
    public boolean setInstantAppCookie(String packageName, byte[] cookie, int userId) {
        if (HIDE_EPHEMERAL_APIS) {
            return true;
        }

        mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId,
                true /* requireFullPermission */, true /* checkShell */,
                "setInstantAppCookie");
        if (!isCallerSameApp(packageName, Binder.getCallingUid())) {
            return false;
        }
        synchronized (mLock) {
            return mInstantAppRegistry.setInstantAppCookieLPw(
                    packageName, cookie, userId);
        }
    }

    @Override
    public Bitmap getInstantAppIcon(String packageName, int userId) {
        if (HIDE_EPHEMERAL_APIS) {
            return null;
        }

        if (!canViewInstantApps(Binder.getCallingUid(), userId)) {
            mContext.enforceCallingOrSelfPermission(Manifest.permission.ACCESS_INSTANT_APPS,
                    "getInstantAppIcon");
        }
        mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId,
                true /* requireFullPermission */, false /* checkShell */,
                "getInstantAppIcon");

        synchronized (mLock) {
            return mInstantAppRegistry.getInstantAppIconLPw(
                    packageName, userId);
        }
    }

    private boolean isCallerSameApp(String packageName, int uid) {
        AndroidPackage pkg = mPackages.get(packageName);
        return pkg != null
                && UserHandle.getAppId(uid) == pkg.getUid();
    }

    @Override
    public @NonNull ParceledListSlice<ApplicationInfo> getPersistentApplications(int flags) {
        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
            return ParceledListSlice.emptyList();
        }
        return new ParceledListSlice<>(getPersistentApplicationsInternal(flags));
    }

    private @NonNull List<ApplicationInfo> getPersistentApplicationsInternal(int flags) {
        final ArrayList<ApplicationInfo> finalList = new ArrayList<>();

        // reader
        synchronized (mLock) {
            final Iterator<AndroidPackage> i = mPackages.values().iterator();
            final int userId = UserHandle.getCallingUserId();
            while (i.hasNext()) {
                final AndroidPackage p = i.next();

                final boolean matchesUnaware = ((flags & MATCH_DIRECT_BOOT_UNAWARE) != 0)
                        && !p.isDirectBootAware();
                final boolean matchesAware = ((flags & MATCH_DIRECT_BOOT_AWARE) != 0)
                        && p.isDirectBootAware();

                if ((p.getFlags() & ApplicationInfo.FLAG_PERSISTENT) != 0
                        && (!mSafeMode || isSystemApp(p))
                        && (matchesUnaware || matchesAware)) {
                    PackageSetting ps = mSettings.mPackages.get(p.getPackageName());
                    if (ps != null) {
                        ApplicationInfo ai = PackageInfoUtils.generateApplicationInfo(p, flags,
                                ps.readUserState(userId), userId);
                        if (ai != null) {
                            finalList.add(ai);
                        }
                    }
                }
            }
        }

        return finalList;
    }

    @Override
    public ProviderInfo resolveContentProvider(String name, int flags, int userId) {
        return resolveContentProviderInternal(name, flags, userId);
    }

    private ProviderInfo resolveContentProviderInternal(String name, int flags, int userId) {
        if (!mUserManager.exists(userId)) return null;
        flags = updateFlagsForComponent(flags, userId);
        final int callingUid = Binder.getCallingUid();
        final ProviderInfo providerInfo = mComponentResolver.queryProvider(name, flags, userId);
        if (providerInfo == null) {
            return null;
        }
        if (!mSettings.isEnabledAndMatchLPr(providerInfo, flags, userId)) {
            return null;
        }
        synchronized (mLock) {
            final PackageSetting ps = mSettings.mPackages.get(providerInfo.packageName);
            final ComponentName component =
                    new ComponentName(providerInfo.packageName, providerInfo.name);
            if (shouldFilterApplicationLocked(ps, callingUid, component, TYPE_PROVIDER, userId)) {
                return null;
            }
            return providerInfo;
        }
    }

    /**
     * @deprecated
     */
    @Deprecated
    public void querySyncProviders(List<String> outNames, List<ProviderInfo> outInfo) {
        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
            return;
        }
        mComponentResolver.querySyncProviders(
                outNames, outInfo, mSafeMode, UserHandle.getCallingUserId());
    }

    @Override
    public @NonNull ParceledListSlice<ProviderInfo> queryContentProviders(String processName,
            int uid, int flags, String metaDataKey) {
        final int callingUid = Binder.getCallingUid();
        final int userId = processName != null ? UserHandle.getUserId(uid)
                : UserHandle.getCallingUserId();
        if (!mUserManager.exists(userId)) return ParceledListSlice.emptyList();
        flags = updateFlagsForComponent(flags, userId);
        ArrayList<ProviderInfo> finalList = null;
        final List<ProviderInfo> matchList =
                mComponentResolver.queryProviders(processName, metaDataKey, uid, flags, userId);
        final int listSize = (matchList == null ? 0 : matchList.size());
        synchronized (mLock) {
            for (int i = 0; i < listSize; i++) {
                final ProviderInfo providerInfo = matchList.get(i);
                if (!mSettings.isEnabledAndMatchLPr(providerInfo, flags, userId)) {
                    continue;
                }
                final PackageSetting ps = mSettings.mPackages.get(providerInfo.packageName);
                final ComponentName component =
                        new ComponentName(providerInfo.packageName, providerInfo.name);
                if (shouldFilterApplicationLocked(
                        ps, callingUid, component, TYPE_PROVIDER, userId)) {
                    continue;
                }
                if (finalList == null) {
                    finalList = new ArrayList<>(listSize - i);
                }
                finalList.add(providerInfo);
            }
        }

        if (finalList != null) {
            finalList.sort(sProviderInitOrderSorter);
            return new ParceledListSlice<>(finalList);
        }

        return ParceledListSlice.emptyList();
    }

    @Override
    public InstrumentationInfo getInstrumentationInfo(ComponentName component, int flags) {
        // reader
        synchronized (mLock) {
            final int callingUid = Binder.getCallingUid();
            final int callingUserId = UserHandle.getUserId(callingUid);
            String packageName = component.getPackageName();
            final PackageSetting ps = mSettings.mPackages.get(packageName);
            AndroidPackage pkg = mPackages.get(packageName);
            if (ps == null || pkg == null) return null;
            if (shouldFilterApplicationLocked(
                    ps, callingUid, component, TYPE_UNKNOWN, callingUserId)) {
                return null;
            }
            final ParsedInstrumentation i = mInstrumentation.get(component);
            return PackageInfoUtils.generateInstrumentationInfo(i, pkg, flags);
        }
    }

    @Override
    public @NonNull ParceledListSlice<InstrumentationInfo> queryInstrumentation(
            String targetPackage, int flags) {
        final int callingUid = Binder.getCallingUid();
        final int callingUserId = UserHandle.getUserId(callingUid);
        final PackageSetting ps = mSettings.mPackages.get(targetPackage);
        if (shouldFilterApplicationLocked(ps, callingUid, callingUserId)) {
            return ParceledListSlice.emptyList();
        }
        return new ParceledListSlice<>(queryInstrumentationInternal(targetPackage, flags));
    }

    private @NonNull List<InstrumentationInfo> queryInstrumentationInternal(String targetPackage,
            int flags) {
        ArrayList<InstrumentationInfo> finalList = new ArrayList<>();

        // reader
        synchronized (mLock) {
            final Iterator<ParsedInstrumentation> i = mInstrumentation.values().iterator();
            while (i.hasNext()) {
                final ParsedInstrumentation p = i.next();
                if (targetPackage == null
                        || targetPackage.equals(p.getTargetPackage())) {
                    AndroidPackage pkg = mPackages.get(p.getPackageName());
                    if (pkg != null) {
                        InstrumentationInfo ii = PackageInfoUtils.generateInstrumentationInfo(p,
                                pkg, flags);
                        if (ii != null) {
                            finalList.add(ii);
                        }
                    }
                }
            }
        }

        return finalList;
    }

    private void scanDirTracedLI(File scanDir, final int parseFlags, int scanFlags, long currentTime) {
        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanDir [" + scanDir.getAbsolutePath() + "]");
        try {
            scanDirLI(scanDir, parseFlags, scanFlags, currentTime);
        } finally {
            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
        }
    }

    private void scanDirLI(File scanDir, int parseFlags, int scanFlags, long currentTime) {
        final File[] files = scanDir.listFiles();
        if (ArrayUtils.isEmpty(files)) {
            Log.d(TAG, "No files in app dir " + scanDir);
            return;
        }

        if (DEBUG_PACKAGE_SCANNING) {
            Log.d(TAG, "Scanning app dir " + scanDir + " scanFlags=" + scanFlags
                    + " flags=0x" + Integer.toHexString(parseFlags));
        }
        try (ParallelPackageParser parallelPackageParser = new ParallelPackageParser(
                mSeparateProcesses, mOnlyCore, mMetrics, mCacheDir,
                mPackageParserCallback)) {
            // Submit files for parsing in parallel
            int fileCount = 0;
            for (File file : files) {
                final boolean isPackage = (isApkFile(file) || file.isDirectory())
                        && !PackageInstallerService.isStageName(file.getName());
                if (!isPackage) {
                    // Ignore entries which are not packages
                    continue;
                }
                parallelPackageParser.submit(file, parseFlags);
                fileCount++;
            }

            // Process results one by one
            for (; fileCount > 0; fileCount--) {
                ParallelPackageParser.ParseResult parseResult = parallelPackageParser.take();
                Throwable throwable = parseResult.throwable;
                int errorCode = PackageManager.INSTALL_SUCCEEDED;

                if (throwable == null) {
                    // TODO(toddke): move lower in the scan chain
                    // Static shared libraries have synthetic package names
                    if (parseResult.parsedPackage.isStaticSharedLibrary()) {
                        renameStaticSharedLibraryPackage(parseResult.parsedPackage);
                    }
                    try {
                        addForInitLI(parseResult.parsedPackage, parseFlags, scanFlags,
                                currentTime, null);
                    } catch (PackageManagerException e) {
                        errorCode = e.error;
                        Slog.w(TAG, "Failed to scan " + parseResult.scanFile + ": " + e.getMessage());
                    }
                } else if (throwable instanceof PackageParserException) {
                    PackageParserException e = (PackageParserException)
                            throwable;
                    errorCode = e.error;
                    Slog.w(TAG, "Failed to parse " + parseResult.scanFile + ": " + e.getMessage());
                } else {
                    throw new IllegalStateException("Unexpected exception occurred while parsing "
                            + parseResult.scanFile, throwable);
                }

                // Delete invalid userdata apps
                if ((scanFlags & SCAN_AS_SYSTEM) == 0 &&
                        errorCode != PackageManager.INSTALL_SUCCEEDED) {
                    logCriticalInfo(Log.WARN,
                            "Deleting invalid package at " + parseResult.scanFile);
                    removeCodePathLI(parseResult.scanFile);
                }
            }
        }
    }

    public static void reportSettingsProblem(int priority, String msg) {
        logCriticalInfo(priority, msg);
    }

    private void collectCertificatesLI(PackageSetting ps, ParsedPackage parsedPackage,
            boolean forceCollect, boolean skipVerify) throws PackageManagerException {
        // When upgrading from pre-N MR1, verify the package time stamp using the package
        // directory and not the APK file.
        final long lastModifiedTime = mIsPreNMR1Upgrade
                ? new File(parsedPackage.getCodePath()).lastModified()
                : getLastModifiedTime(parsedPackage);
        final VersionInfo settingsVersionForPackage = getSettingsVersionForPackage(parsedPackage);
        if (ps != null && !forceCollect
                && ps.codePathString.equals(parsedPackage.getCodePath())
                && ps.timeStamp == lastModifiedTime
                && !isCompatSignatureUpdateNeeded(settingsVersionForPackage)
                && !isRecoverSignatureUpdateNeeded(settingsVersionForPackage)) {
            if (ps.signatures.mSigningDetails.signatures != null
                    && ps.signatures.mSigningDetails.signatures.length != 0
                    && ps.signatures.mSigningDetails.signatureSchemeVersion
                            != SignatureSchemeVersion.UNKNOWN) {
                // Optimization: reuse the existing cached signing data
                // if the package appears to be unchanged.
                parsedPackage.setSigningDetails(
                        new PackageParser.SigningDetails(ps.signatures.mSigningDetails));
                return;
            }

            Slog.w(TAG, "PackageSetting for " + ps.name
                    + " is missing signatures.  Collecting certs again to recover them.");
        } else {
            Slog.i(TAG, parsedPackage.getCodePath() + " changed; collecting certs" +
                    (forceCollect ? " (forced)" : ""));
        }

        try {
            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "collectCertificates");
            ApkParseUtils.collectCertificates(parsedPackage, skipVerify);
        } catch (PackageParserException e) {
            throw PackageManagerException.from(e);
        } finally {
            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
        }
    }

    /**
     * Clear the package profile if this was an upgrade and the package
     * version was updated.
     */
    private void maybeClearProfilesForUpgradesLI(
            @Nullable PackageSetting originalPkgSetting,
            @NonNull AndroidPackage pkg) {
        if (originalPkgSetting == null || !isDeviceUpgrading()) {
          return;
        }
        if (originalPkgSetting.versionCode == pkg.getVersionCode()) {
          return;
        }

        clearAppProfilesLIF(pkg, UserHandle.USER_ALL);
        if (DEBUG_INSTALL) {
            Slog.d(TAG, originalPkgSetting.name
                  + " clear profile due to version change "
                  + originalPkgSetting.versionCode + " != "
                  + pkg.getVersionCode());
        }
    }

    /**
     *  Traces a package scan.
     *  @see #scanPackageLI(File, int, int, long, UserHandle)
     */
    @GuardedBy({"mInstallLock", "mLock"})
    private AndroidPackage scanPackageTracedLI(File scanFile, final int parseFlags,
            int scanFlags, long currentTime, UserHandle user) throws PackageManagerException {
        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanPackage [" + scanFile.toString() + "]");
        try {
            return scanPackageLI(scanFile, parseFlags, scanFlags, currentTime, user);
        } finally {
            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
        }
    }

    /**
     *  Scans a package and returns the newly parsed package.
     *  Returns {@code null} in case of errors and the error code is stored in mLastScanError
     */
    @GuardedBy({"mInstallLock", "mLock"})
    private AndroidPackage scanPackageLI(File scanFile, int parseFlags, int scanFlags,
            long currentTime, UserHandle user) throws PackageManagerException {
        if (DEBUG_INSTALL) Slog.d(TAG, "Parsing: " + scanFile);
        PackageParser pp = new PackageParser();
        pp.setSeparateProcesses(mSeparateProcesses);
        pp.setOnlyCoreApps(mOnlyCore);
        pp.setDisplayMetrics(mMetrics);
        pp.setCallback(mPackageParserCallback);

        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "parsePackage");
        final ParsedPackage parsedPackage;
        try {
            parsedPackage = pp.parseParsedPackage(scanFile, parseFlags, false);
        } catch (PackageParserException e) {
            throw PackageManagerException.from(e);
        } finally {
            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
        }

        // Static shared libraries have synthetic package names
        if (parsedPackage.isStaticSharedLibrary()) {
            renameStaticSharedLibraryPackage(parsedPackage);
        }

        return addForInitLI(parsedPackage, parseFlags, scanFlags, currentTime, user);
    }

    /**
     * Returns if forced apk verification can be skipped for the whole package, including splits.
     */
    private boolean canSkipForcedPackageVerification(AndroidPackage pkg) {
        if (!canSkipForcedApkVerification(pkg.getBaseCodePath())) {
            return false;
        }
        // TODO: Allow base and splits to be verified individually.
        String[] splitCodePaths = pkg.getSplitCodePaths();
        if (!ArrayUtils.isEmpty(splitCodePaths)) {
            for (int i = 0; i < splitCodePaths.length; i++) {
                if (!canSkipForcedApkVerification(splitCodePaths[i])) {
                    return false;
                }
            }
        }
        return true;
    }

    /**
     * Returns if forced apk verification can be skipped, depending on current FSVerity setup and
     * whether the apk contains signed root hash.  Note that the signer's certificate still needs to
     * match one in a trusted source, and should be done separately.
     */
    private boolean canSkipForcedApkVerification(String apkPath) {
        if (!PackageManagerServiceUtils.isLegacyApkVerityEnabled()) {
            return VerityUtils.hasFsverity(apkPath);
        }

        try {
            final byte[] rootHashObserved = VerityUtils.generateApkVerityRootHash(apkPath);
            if (rootHashObserved == null) {
                return false;  // APK does not contain Merkle tree root hash.
            }
            synchronized (mInstallLock) {
                // Returns whether the observed root hash matches what kernel has.
                mInstaller.assertFsverityRootHashMatches(apkPath, rootHashObserved);
                return true;
            }
        } catch (InstallerException | IOException | DigestException |
                NoSuchAlgorithmException e) {
            Slog.w(TAG, "Error in fsverity check. Fallback to full apk verification.", e);
        }
        return false;
    }

    /**
     * Adds a new package to the internal data structures during platform initialization.
     * <p>After adding, the package is known to the system and available for querying.
     * <p>For packages located on the device ROM [eg. packages located in /system, /vendor,
     * etc...], additional checks are performed. Basic verification [such as ensuring
     * matching signatures, checking version codes, etc...] occurs if the package is
     * identical to a previously known package. If the package fails a signature check,
     * the version installed on /data will be removed. If the version of the new package
     * is less than or equal than the version on /data, it will be ignored.
     * <p>Regardless of the package location, the results are applied to the internal
     * structures and the package is made available to the rest of the system.
     * <p>NOTE: The return value should be removed. It's the passed in package object.
     */
    @GuardedBy({"mInstallLock", "mLock"})
    private AndroidPackage addForInitLI(ParsedPackage parsedPackage,
            @ParseFlags int parseFlags, @ScanFlags int scanFlags, long currentTime,
            @Nullable UserHandle user)
                    throws PackageManagerException {
        final boolean scanSystemPartition = (parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0;
        final String renamedPkgName;
        final PackageSetting disabledPkgSetting;
        final boolean isSystemPkgUpdated;
        final boolean pkgAlreadyExists;
        PackageSetting pkgSetting;

        // NOTE: installPackageLI() has the same code to setup the package's
        // application info. This probably should be done lower in the call
        // stack [such as scanPackageOnly()]. However, we verify the application
        // info prior to that [in scanPackageNew()] and thus have to setup
        // the application info early.
        // TODO(b/135203078): Remove all of these application info calls
        parsedPackage.setApplicationVolumeUuid(parsedPackage.getVolumeUuid())
                .setApplicationInfoCodePath(parsedPackage.getCodePath())
                .setApplicationInfoResourcePath(parsedPackage.getCodePath())
                .setApplicationInfoBaseResourcePath(parsedPackage.getBaseCodePath())
                .setApplicationInfoSplitResourcePaths(parsedPackage.getSplitCodePaths());

        synchronized (mLock) {
            renamedPkgName = mSettings.getRenamedPackageLPr(parsedPackage.getRealPackage());
            final String realPkgName = getRealPackageName(parsedPackage, renamedPkgName);
            if (realPkgName != null) {
                ensurePackageRenamed(parsedPackage, renamedPkgName);
            }
            final PackageSetting originalPkgSetting = getOriginalPackageLocked(parsedPackage,
                    renamedPkgName);
            final PackageSetting installedPkgSetting = mSettings.getPackageLPr(
                    parsedPackage.getPackageName());
            pkgSetting = originalPkgSetting == null ? installedPkgSetting : originalPkgSetting;
            pkgAlreadyExists = pkgSetting != null;
            final String disabledPkgName = pkgAlreadyExists
                    ? pkgSetting.name : parsedPackage.getPackageName();
            if (scanSystemPartition && !pkgAlreadyExists
                    && mSettings.getDisabledSystemPkgLPr(disabledPkgName) != null) {
                // The updated-package data for /system apk remains inconsistently
                // after the package data for /data apk is lost accidentally.
                // To recover it, enable /system apk and install it as non-updated system app.
                Slog.w(TAG, "Inconsistent package setting of updated system app for "
                        + disabledPkgName + ". To recover it, enable the system app"
                        + "and install it as non-updated system app.");
                mSettings.removeDisabledSystemPackageLPw(disabledPkgName);
            }
            disabledPkgSetting = mSettings.getDisabledSystemPkgLPr(disabledPkgName);
            isSystemPkgUpdated = disabledPkgSetting != null;

            if (DEBUG_INSTALL && isSystemPkgUpdated) {
                Slog.d(TAG, "updatedPkg = " + disabledPkgSetting);
            }

            final SharedUserSetting sharedUserSetting = (parsedPackage.getSharedUserId() != null)
                    ? mSettings.getSharedUserLPw(parsedPackage.getSharedUserId(),
                            0 /*pkgFlags*/, 0 /*pkgPrivateFlags*/, true)
                    : null;
            if (DEBUG_PACKAGE_SCANNING
                    && (parseFlags & PackageParser.PARSE_CHATTY) != 0
                    && sharedUserSetting != null) {
                Log.d(TAG, "Shared UserID " + parsedPackage.getSharedUserId()
                        + " (uid=" + sharedUserSetting.userId + "):"
                        + " packages=" + sharedUserSetting.packages);
            }

            if (scanSystemPartition) {
                if (isSystemPkgUpdated) {
                    // we're updating the disabled package, so, scan it as the package setting
                    boolean isPlatformPackage = mPlatformPackage != null
                            && Objects.equals(mPlatformPackage.getPackageName(),
                            parsedPackage.getPackageName());
                    final ScanRequest request = new ScanRequest(parsedPackage, sharedUserSetting,
                            null, disabledPkgSetting /* pkgSetting */,
                            null /* disabledPkgSetting */, null /* originalPkgSetting */,
                            null, parseFlags, scanFlags, isPlatformPackage, user);
                    applyPolicy(parsedPackage, parseFlags, scanFlags, mPlatformPackage);
                    final ScanResult scanResult =
                            scanPackageOnlyLI(request, mInjector, mFactoryTest, -1L);
                    if (scanResult.existingSettingCopied && scanResult.request.pkgSetting != null) {
                        scanResult.request.pkgSetting.updateFrom(scanResult.pkgSetting);
                    }
                }
            }
        }

        final boolean newPkgChangedPaths =
                pkgAlreadyExists && !pkgSetting.codePathString.equals(parsedPackage.getCodePath());
        final boolean newPkgVersionGreater =
                pkgAlreadyExists && parsedPackage.getLongVersionCode() > pkgSetting.versionCode;
        final boolean isSystemPkgBetter = scanSystemPartition && isSystemPkgUpdated
                && newPkgChangedPaths && newPkgVersionGreater;
        if (isSystemPkgBetter) {
            // The version of the application on /system is greater than the version on
            // /data. Switch back to the application on /system.
            // It's safe to assume the application on /system will correctly scan. If not,
            // there won't be a working copy of the application.
            synchronized (mLock) {
                // just remove the loaded entries from package lists
                mPackages.remove(pkgSetting.name);
            }

            logCriticalInfo(Log.WARN,
                    "System package updated;"
                    + " name: " + pkgSetting.name
                    + "; " + pkgSetting.versionCode + " --> " + parsedPackage.getLongVersionCode()
                    + "; " + pkgSetting.codePathString + " --> " + parsedPackage.getCodePath());

            final InstallArgs args = createInstallArgsForExisting(
                    pkgSetting.codePathString,
                    pkgSetting.resourcePathString, getAppDexInstructionSets(
                            pkgSetting.primaryCpuAbiString, pkgSetting.secondaryCpuAbiString));
            args.cleanUpResourcesLI();
            synchronized (mLock) {
                mSettings.enableSystemPackageLPw(pkgSetting.name);
            }
        }

        if (scanSystemPartition && isSystemPkgUpdated && !isSystemPkgBetter) {
            // The version of the application on the /system partition is less than or
            // equal to the version on the /data partition. Throw an exception and use
            // the application already installed on the /data partition.
            throw new PackageManagerException(Log.WARN, "Package " + parsedPackage.getPackageName()
                    + " at " + parsedPackage.getCodePath() + " ignored: updated version "
                    + pkgSetting.versionCode + " better than this "
                    + parsedPackage.getLongVersionCode());
        }

        // Verify certificates against what was last scanned. Force re-collecting certificate in two
        // special cases:
        // 1) when scanning system, force re-collect only if system is upgrading.
        // 2) when scannning /data, force re-collect only if the app is privileged (updated from
        // preinstall, or treated as privileged, e.g. due to shared user ID).
        final boolean forceCollect = scanSystemPartition ? mIsUpgrade
                : PackageManagerServiceUtils.isApkVerificationForced(pkgSetting);
        if (DEBUG_VERIFY && forceCollect) {
            Slog.d(TAG, "Force collect certificate of " + parsedPackage.getPackageName());
        }

        // Full APK verification can be skipped during certificate collection, only if the file is
        // in verified partition, or can be verified on access (when apk verity is enabled). In both
        // cases, only data in Signing Block is verified instead of the whole file.
        // TODO(b/136132412): skip for Incremental installation
        final boolean skipVerify = scanSystemPartition
                || (forceCollect && canSkipForcedPackageVerification(parsedPackage));
        collectCertificatesLI(pkgSetting, parsedPackage, forceCollect, skipVerify);

        // Reset profile if the application version is changed
        maybeClearProfilesForUpgradesLI(pkgSetting, parsedPackage);

        /*
         * A new system app appeared, but we already had a non-system one of the
         * same name installed earlier.
         */
        boolean shouldHideSystemApp = false;
        // A new application appeared on /system, but, we already have a copy of
        // the application installed on /data.
        if (scanSystemPartition && !isSystemPkgUpdated && pkgAlreadyExists
                && !pkgSetting.isSystem()) {

            if (!parsedPackage.getSigningDetails()
                    .checkCapability(pkgSetting.signatures.mSigningDetails,
                    PackageParser.SigningDetails.CertCapabilities.INSTALLED_DATA)
                            && !pkgSetting.signatures.mSigningDetails.checkCapability(
                                    parsedPackage.getSigningDetails(),
                                    PackageParser.SigningDetails.CertCapabilities.ROLLBACK)) {
                logCriticalInfo(Log.WARN,
                        "System package signature mismatch;"
                        + " name: " + pkgSetting.name);
                try (@SuppressWarnings("unused") PackageFreezer freezer = freezePackage(
                        parsedPackage.getPackageName(),
                        "scanPackageInternalLI")) {
                    deletePackageLIF(parsedPackage.getPackageName(), null, true, null, 0, null,
                            false, null);
                }
                pkgSetting = null;
            } else if (newPkgVersionGreater) {
                // The application on /system is newer than the application on /data.
                // Simply remove the application on /data [keeping application data]
                // and replace it with the version on /system.
                logCriticalInfo(Log.WARN,
                        "System package enabled;"
                                + " name: " + pkgSetting.name
                                + "; " + pkgSetting.versionCode + " --> "
                                + parsedPackage.getLongVersionCode()
                                + "; " + pkgSetting.codePathString + " --> "
                                + parsedPackage.getCodePath());
                InstallArgs args = createInstallArgsForExisting(
                        pkgSetting.codePathString,
                        pkgSetting.resourcePathString, getAppDexInstructionSets(
                                pkgSetting.primaryCpuAbiString, pkgSetting.secondaryCpuAbiString));
                synchronized (mInstallLock) {
                    args.cleanUpResourcesLI();
                }
            } else {
                // The application on /system is older than the application on /data. Hide
                // the application on /system and the version on /data will be scanned later
                // and re-added like an update.
                shouldHideSystemApp = true;
                logCriticalInfo(Log.INFO,
                        "System package disabled;"
                                + " name: " + pkgSetting.name
                                + "; old: " + pkgSetting.codePathString + " @ "
                                + pkgSetting.versionCode
                                + "; new: " + parsedPackage.getCodePath() + " @ "
                                + parsedPackage.getCodePath());
            }
        }

        final ScanResult scanResult = scanPackageNewLI(parsedPackage, parseFlags, scanFlags
                | SCAN_UPDATE_SIGNATURE, currentTime, user);
        if (scanResult.success) {
            synchronized (mLock) {
                boolean appIdCreated = false;
                try {
                    final String pkgName = scanResult.pkgSetting.name;
                    final Map<String, ReconciledPackage> reconcileResult = reconcilePackagesLocked(
                            new ReconcileRequest(
                                    Collections.singletonMap(pkgName, scanResult),
                                    mSharedLibraries,
                                    mPackages,
                                    Collections.singletonMap(
                                            pkgName, getSettingsVersionForPackage(parsedPackage)),
                                    Collections.singletonMap(pkgName,
                                            getSharedLibLatestVersionSetting(scanResult))),
                            mSettings.mKeySetManagerService);
                    appIdCreated = optimisticallyRegisterAppId(scanResult);
                    commitReconciledScanResultLocked(reconcileResult.get(pkgName));
                } catch (PackageManagerException e) {
                    if (appIdCreated) {
                        cleanUpAppIdCreation(scanResult);
                    }
                    throw e;
                }
            }
        }

        if (shouldHideSystemApp) {
            synchronized (mLock) {
                mSettings.disableSystemPackageLPw(parsedPackage.getPackageName(), true);
            }
        }
        return scanResult.pkgSetting.pkg;
    }

    // TODO:(b/135203078): Move to parsing
    private static void renameStaticSharedLibraryPackage(ParsedPackage parsedPackage) {
        // Derive the new package synthetic package name
        parsedPackage.setPackageName(parsedPackage.getPackageName() + STATIC_SHARED_LIB_DELIMITER
                + parsedPackage.getStaticSharedLibVersion());
    }

    static String fixProcessName(String defProcessName, String processName) {
        if (processName == null) {
            return defProcessName;
        }
        return processName;
    }

    /**
     * Enforces that only the system UID or root's UID can call a method exposed
     * via Binder.
     *
     * @param message used as message if SecurityException is thrown
     * @throws SecurityException if the caller is not system or root
     */
    private static void enforceSystemOrRoot(String message) {
        final int uid = Binder.getCallingUid();
        if (uid != Process.SYSTEM_UID && uid != Process.ROOT_UID) {
            throw new SecurityException(message);
        }
    }

    /**
     * Enforces that only the system UID or root's UID or shell's UID can call
     * a method exposed via Binder.
     *
     * @param message used as message if SecurityException is thrown
     * @throws SecurityException if the caller is not system or shell
     */
    private static void enforceSystemOrRootOrShell(String message) {
        final int uid = Binder.getCallingUid();
        if (uid != Process.SYSTEM_UID && uid != Process.ROOT_UID && uid != Process.SHELL_UID) {
            throw new SecurityException(message);
        }
    }

    @Override
    public void performFstrimIfNeeded() {
        enforceSystemOrRoot("Only the system can request fstrim");

        // Before everything else, see whether we need to fstrim.
        try {
            IStorageManager sm = PackageHelper.getStorageManager();
            if (sm != null) {
                boolean doTrim = false;
                final long interval = android.provider.Settings.Global.getLong(
                        mContext.getContentResolver(),
                        android.provider.Settings.Global.FSTRIM_MANDATORY_INTERVAL,
                        DEFAULT_MANDATORY_FSTRIM_INTERVAL);
                if (interval > 0) {
                    final long timeSinceLast = System.currentTimeMillis() - sm.lastMaintenance();
                    if (timeSinceLast > interval) {
                        doTrim = true;
                        Slog.w(TAG, "No disk maintenance in " + timeSinceLast
                                + "; running immediately");
                    }
                }
                if (doTrim) {
                    final boolean dexOptDialogShown;
                    synchronized (mLock) {
                        dexOptDialogShown = mDexOptDialogShown;
                    }
                    if (!isFirstBoot() && dexOptDialogShown) {
                        try {
                            ActivityManager.getService().showBootMessage(
                                    mContext.getResources().getString(
                                            R.string.android_upgrading_fstrim), true);
                        } catch (RemoteException e) {
                        }
                    }
                    sm.runMaintenance();
                }
            } else {
                Slog.e(TAG, "storageManager service unavailable!");
            }
        } catch (RemoteException e) {
            // Can't happen; StorageManagerService is local
        }
    }

    @Override
    public void updatePackagesIfNeeded() {
        enforceSystemOrRoot("Only the system can request package update");

        // We need to re-extract after an OTA.
        boolean causeUpgrade = isDeviceUpgrading();

        // First boot or factory reset.
        // Note: we also handle devices that are upgrading to N right now as if it is their
        //       first boot, as they do not have profile data.
        boolean causeFirstBoot = isFirstBoot() || mIsPreNUpgrade;

        // We need to re-extract after a pruned cache, as AoT-ed files will be out of date.
        boolean causePrunedCache = VMRuntime.didPruneDalvikCache();

        if (!causeUpgrade && !causeFirstBoot && !causePrunedCache) {
            return;
        }

        List<AndroidPackage> pkgs;
        synchronized (mLock) {
            pkgs = PackageManagerServiceUtils.getPackagesForDexopt(mPackages.values(), this);
        }

        final long startTime = System.nanoTime();
        final int[] stats = performDexOptUpgrade(pkgs, mIsPreNUpgrade /* showDialog */,
                    causeFirstBoot ? REASON_FIRST_BOOT : REASON_BOOT,
                    false /* bootComplete */);

        final int elapsedTimeSeconds =
                (int) TimeUnit.NANOSECONDS.toSeconds(System.nanoTime() - startTime);

        MetricsLogger.histogram(mContext, "opt_dialog_num_dexopted", stats[0]);
        MetricsLogger.histogram(mContext, "opt_dialog_num_skipped", stats[1]);
        MetricsLogger.histogram(mContext, "opt_dialog_num_failed", stats[2]);
        MetricsLogger.histogram(mContext, "opt_dialog_num_total", getOptimizablePackages().size());
        MetricsLogger.histogram(mContext, "opt_dialog_time_s", elapsedTimeSeconds);
    }

    /*
     * Return the prebuilt profile path given a package base code path.
     */
    private static String getPrebuildProfilePath(AndroidPackage pkg) {
        return pkg.getBaseCodePath() + ".prof";
    }

    /**
     * Performs dexopt on the set of packages in {@code packages} and returns an int array
     * containing statistics about the invocation. The array consists of three elements,
     * which are (in order) {@code numberOfPackagesOptimized}, {@code numberOfPackagesSkipped}
     * and {@code numberOfPackagesFailed}.
     */
    private int[] performDexOptUpgrade(List<AndroidPackage> pkgs, boolean showDialog,
            final int compilationReason, boolean bootComplete) {

        int numberOfPackagesVisited = 0;
        int numberOfPackagesOptimized = 0;
        int numberOfPackagesSkipped = 0;
        int numberOfPackagesFailed = 0;
        final int numberOfPackagesToDexopt = pkgs.size();

        for (AndroidPackage pkg : pkgs) {
            numberOfPackagesVisited++;

            boolean useProfileForDexopt = false;

            if ((isFirstBoot() || isDeviceUpgrading()) && isSystemApp(pkg)) {
                // Copy over initial preopt profiles since we won't get any JIT samples for methods
                // that are already compiled.
                File profileFile = new File(getPrebuildProfilePath(pkg));
                // Copy profile if it exists.
                if (profileFile.exists()) {
                    try {
                        // We could also do this lazily before calling dexopt in
                        // PackageDexOptimizer to prevent this happening on first boot. The issue
                        // is that we don't have a good way to say "do this only once".
                        if (!mInstaller.copySystemProfile(profileFile.getAbsolutePath(),
                                pkg.getUid(), pkg.getPackageName(),
                                ArtManager.getProfileName(null))) {
                            Log.e(TAG, "Installer failed to copy system profile!");
                        } else {
                            // Disabled as this causes speed-profile compilation during first boot
                            // even if things are already compiled.
                            // useProfileForDexopt = true;
                        }
                    } catch (Exception e) {
                        Log.e(TAG, "Failed to copy profile " + profileFile.getAbsolutePath() + " ",
                                e);
                    }
                } else {
                    PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(
                            pkg.getPackageName());
                    // Handle compressed APKs in this path. Only do this for stubs with profiles to
                    // minimize the number off apps being speed-profile compiled during first boot.
                    // The other paths will not change the filter.
                    if (disabledPs != null && disabledPs.pkg.isStub()) {
                        // The package is the stub one, remove the stub suffix to get the normal
                        // package and APK names.
                        String systemProfilePath =
                                getPrebuildProfilePath(disabledPs.pkg).replace(STUB_SUFFIX, "");
                        profileFile = new File(systemProfilePath);
                        // If we have a profile for a compressed APK, copy it to the reference
                        // location.
                        // Note that copying the profile here will cause it to override the
                        // reference profile every OTA even though the existing reference profile
                        // may have more data. We can't copy during decompression since the
                        // directories are not set up at that point.
                        if (profileFile.exists()) {
                            try {
                                // We could also do this lazily before calling dexopt in
                                // PackageDexOptimizer to prevent this happening on first boot. The
                                // issue is that we don't have a good way to say "do this only
                                // once".
                                if (!mInstaller.copySystemProfile(profileFile.getAbsolutePath(),
                                        pkg.getUid(), pkg.getPackageName(),
                                        ArtManager.getProfileName(null))) {
                                    Log.e(TAG, "Failed to copy system profile for stub package!");
                                } else {
                                    useProfileForDexopt = true;
                                }
                            } catch (Exception e) {
                                Log.e(TAG, "Failed to copy profile " +
                                        profileFile.getAbsolutePath() + " ", e);
                            }
                        }
                    }
                }
            }

            if (!PackageDexOptimizer.canOptimizePackage(pkg)) {
                if (DEBUG_DEXOPT) {
                    Log.i(TAG, "Skipping update of non-optimizable app " + pkg.getPackageName());
                }
                numberOfPackagesSkipped++;
                continue;
            }

            if (DEBUG_DEXOPT) {
                Log.i(TAG, "Updating app " + numberOfPackagesVisited + " of " +
                        numberOfPackagesToDexopt + ": " + pkg.getPackageName());
            }

            if (showDialog) {
                try {
                    ActivityManager.getService().showBootMessage(
                            mContext.getResources().getString(R.string.android_upgrading_apk,
                                    numberOfPackagesVisited, numberOfPackagesToDexopt), true);
                } catch (RemoteException e) {
                }
                synchronized (mLock) {
                    mDexOptDialogShown = true;
                }
            }

            int pkgCompilationReason = compilationReason;
            if (useProfileForDexopt) {
                // Use background dexopt mode to try and use the profile. Note that this does not
                // guarantee usage of the profile.
                pkgCompilationReason = PackageManagerService.REASON_BACKGROUND_DEXOPT;
            }

            if (SystemProperties.getBoolean(PRECOMPILE_LAYOUTS, false)) {
                mArtManagerService.compileLayouts(pkg);
            }

            // checkProfiles is false to avoid merging profiles during boot which
            // might interfere with background compilation (b/28612421).
            // Unfortunately this will also means that "pm.dexopt.boot=speed-profile" will
            // behave differently than "pm.dexopt.bg-dexopt=speed-profile" but that's a
            // trade-off worth doing to save boot time work.
            int dexoptFlags = bootComplete ? DexoptOptions.DEXOPT_BOOT_COMPLETE : 0;
            if (compilationReason == REASON_FIRST_BOOT) {
                // TODO: This doesn't cover the upgrade case, we should check for this too.
                dexoptFlags |= DexoptOptions.DEXOPT_INSTALL_WITH_DEX_METADATA_FILE;
            }
            int primaryDexOptStaus = performDexOptTraced(new DexoptOptions(
                    pkg.getPackageName(),
                    pkgCompilationReason,
                    dexoptFlags));

            switch (primaryDexOptStaus) {
                case PackageDexOptimizer.DEX_OPT_PERFORMED:
                    numberOfPackagesOptimized++;
                    break;
                case PackageDexOptimizer.DEX_OPT_SKIPPED:
                    numberOfPackagesSkipped++;
                    break;
                case PackageDexOptimizer.DEX_OPT_FAILED:
                    numberOfPackagesFailed++;
                    break;
                default:
                    Log.e(TAG, "Unexpected dexopt return code " + primaryDexOptStaus);
                    break;
            }
        }

        return new int[] { numberOfPackagesOptimized, numberOfPackagesSkipped,
                numberOfPackagesFailed };
    }

    @Override
    public void notifyPackageUse(String packageName, int reason) {
        synchronized (mLock) {
            final int callingUid = Binder.getCallingUid();
            final int callingUserId = UserHandle.getUserId(callingUid);
            if (getInstantAppPackageName(callingUid) != null) {
                if (!isCallerSameApp(packageName, callingUid)) {
                    return;
                }
            } else {
                if (isInstantApp(packageName, callingUserId)) {
                    return;
                }
            }
            notifyPackageUseLocked(packageName, reason);
        }
    }

    @GuardedBy("mLock")
    private void notifyPackageUseLocked(String packageName, int reason) {
        final AndroidPackage p = mPackages.get(packageName);
        if (p == null) {
            return;
        }
        p.mutate().setLastPackageUsageTimeInMills(reason, System.currentTimeMillis());
    }

    @Override
    public void notifyDexLoad(String loadingPackageName, List<String> classLoaderNames,
            List<String> classPaths, String loaderIsa) {
        int userId = UserHandle.getCallingUserId();
        ApplicationInfo ai = getApplicationInfo(loadingPackageName, /*flags*/ 0, userId);
        if (ai == null) {
            Slog.w(TAG, "Loading a package that does not exist for the calling user. package="
                + loadingPackageName + ", user=" + userId);
            return;
        }
        mDexManager.notifyDexLoad(ai, classLoaderNames, classPaths, loaderIsa, userId);
    }

    @Override
    public void registerDexModule(String packageName, String dexModulePath, boolean isSharedModule,
            IDexModuleRegisterCallback callback) {
        int userId = UserHandle.getCallingUserId();
        ApplicationInfo ai = getApplicationInfo(packageName, /*flags*/ 0, userId);
        DexManager.RegisterDexModuleResult result;
        if (ai == null) {
            Slog.w(TAG, "Registering a dex module for a package that does not exist for the" +
                     " calling user. package=" + packageName + ", user=" + userId);
            result = new DexManager.RegisterDexModuleResult(false, "Package not installed");
        } else {
            result = mDexManager.registerDexModule(ai, dexModulePath, isSharedModule, userId);
        }

        if (callback != null) {
            mHandler.post(() -> {
                try {
                    callback.onDexModuleRegistered(dexModulePath, result.success, result.message);
                } catch (RemoteException e) {
                    Slog.w(TAG, "Failed to callback after module registration " + dexModulePath, e);
                }
            });
        }
    }

    /**
     * Ask the package manager to perform a dex-opt with the given compiler filter.
     *
     * Note: exposed only for the shell command to allow moving packages explicitly to a
     *       definite state.
     */
    @Override
    public boolean performDexOptMode(String packageName,
            boolean checkProfiles, String targetCompilerFilter, boolean force,
            boolean bootComplete, String splitName) {
        int flags = (checkProfiles ? DexoptOptions.DEXOPT_CHECK_FOR_PROFILES_UPDATES : 0) |
                (force ? DexoptOptions.DEXOPT_FORCE : 0) |
                (bootComplete ? DexoptOptions.DEXOPT_BOOT_COMPLETE : 0);
        return performDexOpt(new DexoptOptions(packageName, REASON_UNKNOWN,
                targetCompilerFilter, splitName, flags));
    }

    /**
     * Ask the package manager to perform a dex-opt with the given compiler filter on the
     * secondary dex files belonging to the given package.
     *
     * Note: exposed only for the shell command to allow moving packages explicitly to a
     *       definite state.
     */
    @Override
    public boolean performDexOptSecondary(String packageName, String compilerFilter,
            boolean force) {
        int flags = DexoptOptions.DEXOPT_ONLY_SECONDARY_DEX |
                DexoptOptions.DEXOPT_CHECK_FOR_PROFILES_UPDATES |
                DexoptOptions.DEXOPT_BOOT_COMPLETE |
                (force ? DexoptOptions.DEXOPT_FORCE : 0);
        return performDexOpt(new DexoptOptions(packageName, compilerFilter, flags));
    }

    /**
    * Ask the package manager to compile layouts in the given package.
    */
    @Override
    public boolean compileLayouts(String packageName) {
        AndroidPackage pkg;
        synchronized (mLock) {
            pkg = mPackages.get(packageName);
            if (pkg == null) {
                return false;
            }
        }
        return mViewCompiler.compileLayouts(pkg);
    }

    /*package*/ boolean performDexOpt(DexoptOptions options) {
        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
            return false;
        } else if (isInstantApp(options.getPackageName(), UserHandle.getCallingUserId())) {
            return false;
        }

        if (options.isDexoptOnlySecondaryDex()) {
            return mDexManager.dexoptSecondaryDex(options);
        } else {
            int dexoptStatus = performDexOptWithStatus(options);
            return dexoptStatus != PackageDexOptimizer.DEX_OPT_FAILED;
        }
    }

    /**
     * Perform dexopt on the given package and return one of following result:
     *  {@link PackageDexOptimizer#DEX_OPT_SKIPPED}
     *  {@link PackageDexOptimizer#DEX_OPT_PERFORMED}
     *  {@link PackageDexOptimizer#DEX_OPT_FAILED}
     */
    /* package */ int performDexOptWithStatus(DexoptOptions options) {
        return performDexOptTraced(options);
    }

    private int performDexOptTraced(DexoptOptions options) {
        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
        try {
            return performDexOptInternal(options);
        } finally {
            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
        }
    }

    // Run dexopt on a given package. Returns true if dexopt did not fail, i.e.
    // if the package can now be considered up to date for the given filter.
    private int performDexOptInternal(DexoptOptions options) {
        AndroidPackage p;
        synchronized (mLock) {
            p = mPackages.get(options.getPackageName());
            if (p == null) {
                // Package could not be found. Report failure.
                return PackageDexOptimizer.DEX_OPT_FAILED;
            }
            mPackageUsage.maybeWriteAsync(mPackages);
            mCompilerStats.maybeWriteAsync();
        }
        long callingId = Binder.clearCallingIdentity();
        try {
            synchronized (mInstallLock) {
                return performDexOptInternalWithDependenciesLI(p, options);
            }
        } finally {
            Binder.restoreCallingIdentity(callingId);
        }
    }

    public ArraySet<String> getOptimizablePackages() {
        ArraySet<String> pkgs = new ArraySet<>();
        synchronized (mLock) {
            for (AndroidPackage p : mPackages.values()) {
                if (PackageDexOptimizer.canOptimizePackage(p)) {
                    pkgs.add(p.getPackageName());
                }
            }
        }
        return pkgs;
    }

    private int performDexOptInternalWithDependenciesLI(AndroidPackage p,
            DexoptOptions options) {
        // Select the dex optimizer based on the force parameter.
        // Note: The force option is rarely used (cmdline input for testing, mostly), so it's OK to
        //       allocate an object here.
        PackageDexOptimizer pdo = options.isForce()
                ? new PackageDexOptimizer.ForcedUpdatePackageDexOptimizer(mPackageDexOptimizer)
                : mPackageDexOptimizer;

        // Dexopt all dependencies first. Note: we ignore the return value and march on
        // on errors.
        // Note that we are going to call performDexOpt on those libraries as many times as
        // they are referenced in packages. When we do a batch of performDexOpt (for example
        // at boot, or background job), the passed 'targetCompilerFilter' stays the same,
        // and the first package that uses the library will dexopt it. The
        // others will see that the compiled code for the library is up to date.
        Collection<SharedLibraryInfo> deps = findSharedLibraries(p);
        final String[] instructionSets = getAppDexInstructionSets(p.getPrimaryCpuAbi(),
                p.getSecondaryCpuAbi());
        if (!deps.isEmpty()) {
            DexoptOptions libraryOptions = new DexoptOptions(options.getPackageName(),
                    options.getCompilationReason(), options.getCompilerFilter(),
                    options.getSplitName(),
                    options.getFlags() | DexoptOptions.DEXOPT_AS_SHARED_LIBRARY);
            for (SharedLibraryInfo info : deps) {
                AndroidPackage depPackage = null;
                synchronized (mLock) {
                    depPackage = mPackages.get(info.getPackageName());
                }
                if (depPackage != null) {
                    // TODO: Analyze and investigate if we (should) profile libraries.
                    pdo.performDexOpt(depPackage, instructionSets,
                            getOrCreateCompilerPackageStats(depPackage),
                            mDexManager.getPackageUseInfoOrDefault(depPackage.getPackageName()),
                            libraryOptions);
                } else {
                    // TODO(ngeoffray): Support dexopting system shared libraries.
                }
            }
        }
        return pdo.performDexOpt(p, instructionSets,
                getOrCreateCompilerPackageStats(p),
                mDexManager.getPackageUseInfoOrDefault(p.getPackageName()), options);
    }

    /**
     * Reconcile the information we have about the secondary dex files belonging to
     * {@code packageName} and the actual dex files. For all dex files that were
     * deleted, update the internal records and delete the generated oat files.
     */
    @Override
    public void reconcileSecondaryDexFiles(String packageName) {
        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
            return;
        } else if (isInstantApp(packageName, UserHandle.getCallingUserId())) {
            return;
        }
        mDexManager.reconcileSecondaryDexFiles(packageName);
    }

    // TODO(calin): this is only needed for BackgroundDexOptService. Find a cleaner way to inject
    // a reference there.
    /*package*/ DexManager getDexManager() {
        return mDexManager;
    }

    /**
     * Execute the background dexopt job immediately.
     */
    @Override
    public boolean runBackgroundDexoptJob(@Nullable List<String> packageNames) {
        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
            return false;
        }
        enforceSystemOrRootOrShell("runBackgroundDexoptJob");
        final long identity = Binder.clearCallingIdentity();
        try {
            return BackgroundDexOptService.runIdleOptimizationsNow(this, mContext, packageNames);
        } finally {
            Binder.restoreCallingIdentity(identity);
        }
    }

    private static List<SharedLibraryInfo> findSharedLibraries(AndroidPackage p) {
        if (p.getUsesLibraryInfos() != null) {
            ArrayList<SharedLibraryInfo> retValue = new ArrayList<>();
            Set<String> collectedNames = new HashSet<>();
            for (SharedLibraryInfo info : p.getUsesLibraryInfos()) {
                findSharedLibrariesRecursive(info, retValue, collectedNames);
            }
            return retValue;
        } else {
            return Collections.emptyList();
        }
    }

    private static void findSharedLibrariesRecursive(SharedLibraryInfo info,
            ArrayList<SharedLibraryInfo> collected, Set<String> collectedNames) {
        if (!collectedNames.contains(info.getName())) {
            collectedNames.add(info.getName());
            collected.add(info);

            if (info.getDependencies() != null) {
                for (SharedLibraryInfo dep : info.getDependencies()) {
                    findSharedLibrariesRecursive(dep, collected, collectedNames);
                }
            }
        }
    }

    List<AndroidPackage> findSharedNonSystemLibraries(AndroidPackage pkg) {
        List<SharedLibraryInfo> deps = findSharedLibraries(pkg);
        if (!deps.isEmpty()) {
            ArrayList<AndroidPackage> retValue = new ArrayList<>();
            synchronized (mLock) {
                for (SharedLibraryInfo info : deps) {
                    AndroidPackage depPackage = mPackages.get(info.getPackageName());
                    if (depPackage != null) {
                        retValue.add(depPackage);
                    }
                }
            }
            return retValue;
        } else {
            return Collections.emptyList();
        }
    }

    @Nullable
    private SharedLibraryInfo getSharedLibraryInfoLPr(String name, long version) {
        return getSharedLibraryInfo(name, version, mSharedLibraries, null);
    }

    @Nullable
    private static SharedLibraryInfo getSharedLibraryInfo(String name, long version,
            Map<String, LongSparseArray<SharedLibraryInfo>> existingLibraries,
            @Nullable Map<String, LongSparseArray<SharedLibraryInfo>> newLibraries) {
        if (newLibraries != null) {
            final LongSparseArray<SharedLibraryInfo> versionedLib = newLibraries.get(name);
            SharedLibraryInfo info = null;
            if (versionedLib != null) {
                info = versionedLib.get(version);
            }
            if (info != null) {
                return info;
            }
        }
        final LongSparseArray<SharedLibraryInfo> versionedLib = existingLibraries.get(name);
        if (versionedLib == null) {
            return null;
        }
        return versionedLib.get(version);
    }

    private SharedLibraryInfo getLatestSharedLibraVersionLPr(AndroidPackage pkg) {
        LongSparseArray<SharedLibraryInfo> versionedLib = mSharedLibraries.get(
                pkg.getStaticSharedLibName());
        if (versionedLib == null) {
            return null;
        }
        long previousLibVersion = -1;
        final int versionCount = versionedLib.size();
        for (int i = 0; i < versionCount; i++) {
            final long libVersion = versionedLib.keyAt(i);
            if (libVersion < pkg.getStaticSharedLibVersion()) {
                previousLibVersion = Math.max(previousLibVersion, libVersion);
            }
        }
        if (previousLibVersion >= 0) {
            return versionedLib.get(previousLibVersion);
        }
        return null;
    }


    @Nullable
    private PackageSetting getSharedLibLatestVersionSetting(@NonNull ScanResult scanResult) {
        PackageSetting sharedLibPackage = null;
        synchronized (mLock) {
            final SharedLibraryInfo latestSharedLibraVersionLPr =
                    getLatestSharedLibraVersionLPr(scanResult.request.parsedPackage);
            if (latestSharedLibraVersionLPr != null) {
                sharedLibPackage = mSettings.getPackageLPr(
                        latestSharedLibraVersionLPr.getPackageName());
            }
        }
        return sharedLibPackage;
    }

    public void shutdown() {
        mPackageUsage.writeNow(mPackages);
        mCompilerStats.writeNow();
        mDexManager.writePackageDexUsageNow();
        PackageWatchdog.getInstance(mContext).writeNow();

        // This is the last chance to write out pending restriction settings
        synchronized (mLock) {
            if (mHandler.hasMessages(WRITE_PACKAGE_RESTRICTIONS)) {
                mHandler.removeMessages(WRITE_PACKAGE_RESTRICTIONS);
                for (int userId : mDirtyUsers) {
                    mSettings.writePackageRestrictionsLPr(userId);
                }
                mDirtyUsers.clear();
            }
        }
    }

    @Override
    public void dumpProfiles(String packageName) {
        AndroidPackage pkg;
        synchronized (mLock) {
            pkg = mPackages.get(packageName);
            if (pkg == null) {
                throw new IllegalArgumentException("Unknown package: " + packageName);
            }
        }
        /* Only the shell, root, or the app user should be able to dump profiles. */
        int callingUid = Binder.getCallingUid();
        if (callingUid != Process.SHELL_UID &&
            callingUid != Process.ROOT_UID &&
            callingUid != pkg.getUid()) {
            throw new SecurityException("dumpProfiles");
        }

        synchronized (mInstallLock) {
            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dump profiles");
            mArtManagerService.dumpProfiles(pkg);
            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
        }
    }

    @Override
    public void forceDexOpt(String packageName) {
        enforceSystemOrRoot("forceDexOpt");

        AndroidPackage pkg;
        synchronized (mLock) {
            pkg = mPackages.get(packageName);
            if (pkg == null) {
                throw new IllegalArgumentException("Unknown package: " + packageName);
            }
        }

        synchronized (mInstallLock) {
            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");

            // Whoever is calling forceDexOpt wants a compiled package.
            // Don't use profiles since that may cause compilation to be skipped.
            final int res = performDexOptInternalWithDependenciesLI(
                    pkg,
                    new DexoptOptions(packageName,
                            getDefaultCompilerFilter(),
                            DexoptOptions.DEXOPT_FORCE | DexoptOptions.DEXOPT_BOOT_COMPLETE));

            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
            if (res != PackageDexOptimizer.DEX_OPT_PERFORMED) {
                throw new IllegalStateException("Failed to dexopt: " + res);
            }
        }
    }

    @GuardedBy("mLock")
    private boolean verifyPackageUpdateLPr(PackageSetting oldPkg, AndroidPackage newPkg) {
        if ((oldPkg.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0) {
            Slog.w(TAG, "Unable to update from " + oldPkg.name
                    + " to " + newPkg.getPackageName()
                    + ": old package not in system partition");
            return false;
        } else if (mPackages.get(oldPkg.name) != null) {
            Slog.w(TAG, "Unable to update from " + oldPkg.name
                    + " to " + newPkg.getPackageName()
                    + ": old package still exists");
            return false;
        }
        return true;
    }

    @GuardedBy("mInstallLock")
    void removeCodePathLI(File codePath) {
        if (codePath.isDirectory()) {
            try {
                mInstaller.rmPackageDir(codePath.getAbsolutePath());
            } catch (InstallerException e) {
                Slog.w(TAG, "Failed to remove code path", e);
            }
        } else {
            codePath.delete();
        }
    }

    private int[] resolveUserIds(int userId) {
        return (userId == UserHandle.USER_ALL) ? mUserManager.getUserIds() : new int[] { userId };
    }

    private void clearAppDataLIF(AndroidPackage pkg, int userId, int flags) {
        if (pkg == null) {
            Slog.wtf(TAG, "Package was null!", new Throwable());
            return;
        }
        clearAppDataLeafLIF(pkg, userId, flags);

        if ((flags & Installer.FLAG_CLEAR_APP_DATA_KEEP_ART_PROFILES) == 0) {
            clearAppProfilesLIF(pkg, UserHandle.USER_ALL);
        }
    }

    private void clearAppDataLeafLIF(AndroidPackage pkg, int userId, int flags) {
        final PackageSetting ps;
        synchronized (mLock) {
            ps = mSettings.mPackages.get(pkg.getPackageName());
        }
        for (int realUserId : resolveUserIds(userId)) {
            final long ceDataInode = (ps != null) ? ps.getCeDataInode(realUserId) : 0;
            try {
                mInstaller.clearAppData(pkg.getVolumeUuid(), pkg.getPackageName(), realUserId,
                        flags, ceDataInode);
            } catch (InstallerException e) {
                Slog.w(TAG, String.valueOf(e));
            }
        }
    }

    private void destroyAppDataLIF(AndroidPackage pkg, int userId, int flags) {
        if (pkg == null) {
            Slog.wtf(TAG, "Package was null!", new Throwable());
            return;
        }
        destroyAppDataLeafLIF(pkg, userId, flags);
    }

    private void destroyAppDataLeafLIF(AndroidPackage pkg, int userId, int flags) {
        final PackageSetting ps;
        synchronized (mLock) {
            ps = mSettings.mPackages.get(pkg.getPackageName());
        }
        for (int realUserId : resolveUserIds(userId)) {
            final long ceDataInode = (ps != null) ? ps.getCeDataInode(realUserId) : 0;
            try {
                mInstaller.destroyAppData(pkg.getVolumeUuid(), pkg.getPackageName(), realUserId,
                        flags, ceDataInode);
            } catch (InstallerException e) {
                Slog.w(TAG, String.valueOf(e));
            }
            mDexManager.notifyPackageDataDestroyed(pkg.getPackageName(), userId);
        }
    }

    private void destroyAppProfilesLIF(AndroidPackage pkg) {
        if (pkg == null) {
            Slog.wtf(TAG, "Package was null!", new Throwable());
            return;
        }
        destroyAppProfilesLeafLIF(pkg);
    }

    private void destroyAppProfilesLeafLIF(AndroidPackage pkg) {
        try {
            mInstaller.destroyAppProfiles(pkg.getPackageName());
        } catch (InstallerException e) {
            Slog.w(TAG, String.valueOf(e));
        }
    }

    private void clearAppProfilesLIF(AndroidPackage pkg, int userId) {
        if (pkg == null) {
            Slog.wtf(TAG, "Package was null!", new Throwable());
            return;
        }
        mArtManagerService.clearAppProfiles(pkg);
    }

    @GuardedBy("mLock")
    private void applyDefiningSharedLibraryUpdateLocked(
            AndroidPackage pkg, SharedLibraryInfo libInfo,
            BiConsumer<SharedLibraryInfo, SharedLibraryInfo> action) {
        // Note that libraries defined by this package may be null if:
        // - Package manager was unable to create the shared library. The package still
        //   gets installed, but the shared library does not get created.
        // Or:
        // - Package manager is in a state where package isn't scanned yet. This will
        //   get called again after scanning to fix the dependencies.
        if (pkg.isLibrary()) {
            if (pkg.getStaticSharedLibName() != null) {
                SharedLibraryInfo definedLibrary = getSharedLibraryInfoLPr(
                        pkg.getStaticSharedLibName(), pkg.getStaticSharedLibVersion());
                if (definedLibrary != null) {
                    action.accept(definedLibrary, libInfo);
                }
            } else {
                for (String libraryName : pkg.getLibraryNames()) {
                    SharedLibraryInfo definedLibrary = getSharedLibraryInfoLPr(
                            libraryName, SharedLibraryInfo.VERSION_UNDEFINED);
                    if (definedLibrary != null) {
                        action.accept(definedLibrary, libInfo);
                    }
                }
            }
        }
    }

    @GuardedBy("mLock")
    private void addSharedLibraryLPr(AndroidPackage pkg, Set<String> usesLibraryFiles,
            SharedLibraryInfo libInfo, AndroidPackage changingLib) {
        if (libInfo.getPath() != null) {
            usesLibraryFiles.add(libInfo.getPath());
            return;
        }
        AndroidPackage p = mPackages.get(libInfo.getPackageName());
        if (changingLib != null && changingLib.getPackageName().equals(libInfo.getPackageName())) {
            // If we are doing this while in the middle of updating a library apk,
            // then we need to make sure to use that new apk for determining the
            // dependencies here.  (We haven't yet finished committing the new apk
            // to the package manager state.)
            if (p == null || p.getPackageName().equals(changingLib.getPackageName())) {
                p = changingLib;
            }
        }
        if (p != null) {
            usesLibraryFiles.addAll(p.getAllCodePaths());
            // If the package provides libraries, add the dependency to them.
            applyDefiningSharedLibraryUpdateLocked(pkg, libInfo, (definingLibrary, dependency) -> {
                definingLibrary.addDependency(dependency);
            });
            if (p.getUsesLibraryFiles() != null) {
                Collections.addAll(usesLibraryFiles, p.getUsesLibraryFiles());
            }
        }
    }

    @GuardedBy("mLock")
    private void updateSharedLibrariesLocked(AndroidPackage pkg,
            AndroidPackage changingLib, Map<String, AndroidPackage> availablePackages)
                    throws PackageManagerException {
        final ArrayList<SharedLibraryInfo> sharedLibraryInfos =
                collectSharedLibraryInfos(pkg, availablePackages, mSharedLibraries, null);
        executeSharedLibrariesUpdateLPr(pkg, changingLib, sharedLibraryInfos);
    }

    private static ArrayList<SharedLibraryInfo> collectSharedLibraryInfos(AndroidPackage pkg,
            Map<String, AndroidPackage> availablePackages,
            @NonNull final Map<String, LongSparseArray<SharedLibraryInfo>> existingLibraries,
            @Nullable final Map<String, LongSparseArray<SharedLibraryInfo>> newLibraries)
            throws PackageManagerException {
        if (pkg == null) {
            return null;
        }
        // The collection used here must maintain the order of addition (so
        // that libraries are searched in the correct order) and must have no
        // duplicates.
        ArrayList<SharedLibraryInfo> usesLibraryInfos = null;
        if (pkg.getUsesLibraries() != null) {
            usesLibraryInfos = collectSharedLibraryInfos(pkg.getUsesLibraries(), null, null,
                    pkg.getPackageName(), true, pkg.getTargetSdkVersion(), null,
                    availablePackages, existingLibraries, newLibraries);
        }
        if (pkg.getUsesStaticLibraries() != null) {
            usesLibraryInfos = collectSharedLibraryInfos(pkg.getUsesStaticLibraries(),
                    pkg.getUsesStaticLibrariesVersions(), pkg.getUsesStaticLibrariesCertDigests(),
                    pkg.getPackageName(), true, pkg.getTargetSdkVersion(), usesLibraryInfos,
                    availablePackages, existingLibraries, newLibraries);
        }
        if (pkg.getUsesOptionalLibraries() != null) {
            usesLibraryInfos = collectSharedLibraryInfos(pkg.getUsesOptionalLibraries(),
                    null, null, pkg.getPackageName(), false, pkg.getTargetSdkVersion(),
                    usesLibraryInfos, availablePackages, existingLibraries, newLibraries);
        }
        return usesLibraryInfos;
    }

    private void executeSharedLibrariesUpdateLPr(AndroidPackage pkg,
            AndroidPackage changingLib, ArrayList<SharedLibraryInfo> usesLibraryInfos) {
        // If the package provides libraries, clear their old dependencies.
        // This method will set them up again.
        applyDefiningSharedLibraryUpdateLocked(pkg, null, (definingLibrary, dependency) -> {
            definingLibrary.clearDependencies();
        });
        if (usesLibraryInfos != null) {
            pkg.mutate().setUsesLibraryInfos(usesLibraryInfos);
            // Use LinkedHashSet to preserve the order of files added to
            // usesLibraryFiles while eliminating duplicates.
            Set<String> usesLibraryFiles = new LinkedHashSet<>();
            for (SharedLibraryInfo libInfo : usesLibraryInfos) {
                addSharedLibraryLPr(pkg, usesLibraryFiles, libInfo, changingLib);
            }
            pkg.mutate().setUsesLibraryFiles(usesLibraryFiles.toArray(
                    new String[usesLibraryFiles.size()]));
        } else {
            pkg.mutate().setUsesLibraryInfos(null)
                    .setUsesLibraryFiles(null);
        }
    }

    @GuardedBy("mLock")
    private static ArrayList<SharedLibraryInfo> collectSharedLibraryInfos(
            @NonNull List<String> requestedLibraries,
            @Nullable long[] requiredVersions, @Nullable String[][] requiredCertDigests,
            @NonNull String packageName, boolean required, int targetSdk,
            @Nullable ArrayList<SharedLibraryInfo> outUsedLibraries,
            @NonNull final Map<String, AndroidPackage> availablePackages,
            @NonNull final Map<String, LongSparseArray<SharedLibraryInfo>> existingLibraries,
            @Nullable final Map<String, LongSparseArray<SharedLibraryInfo>> newLibraries)
            throws PackageManagerException {
        final int libCount = requestedLibraries.size();
        for (int i = 0; i < libCount; i++) {
            final String libName = requestedLibraries.get(i);
            final long libVersion = requiredVersions != null ? requiredVersions[i]
                    : SharedLibraryInfo.VERSION_UNDEFINED;
            final SharedLibraryInfo libraryInfo = getSharedLibraryInfo(libName, libVersion,
                    existingLibraries, newLibraries);
            if (libraryInfo == null) {
                if (required) {
                    throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
                            "Package " + packageName + " requires unavailable shared library "
                                    + libName + "; failing!");
                } else if (DEBUG_SHARED_LIBRARIES) {
                    Slog.i(TAG, "Package " + packageName
                            + " desires unavailable shared library "
                            + libName + "; ignoring!");
                }
            } else {
                if (requiredVersions != null && requiredCertDigests != null) {
                    if (libraryInfo.getLongVersion() != requiredVersions[i]) {
                        throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
                            "Package " + packageName + " requires unavailable static shared"
                                    + " library " + libName + " version "
                                    + libraryInfo.getLongVersion() + "; failing!");
                    }
                    AndroidPackage pkg = availablePackages.get(libraryInfo.getPackageName());
                    SigningDetails libPkg = pkg == null ? null : pkg.getSigningDetails();
                    if (libPkg == null) {
                        throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
                                "Package " + packageName + " requires unavailable static shared"
                                        + " library; failing!");
                    }
                    final String[] expectedCertDigests = requiredCertDigests[i];
                    if (expectedCertDigests.length > 1) {
                        // For apps targeting O MR1 we require explicit enumeration of all certs.
                        final String[] libCertDigests = (targetSdk >= Build.VERSION_CODES.O_MR1)
                                ? PackageUtils.computeSignaturesSha256Digests(
                                libPkg.signatures)
                                : PackageUtils.computeSignaturesSha256Digests(
                                        new Signature[]{libPkg.signatures[0]});

                        // Take a shortcut if sizes don't match. Note that if an app doesn't
                        // target O we don't parse the "additional-certificate" tags similarly
                        // how we only consider all certs only for apps targeting O (see above).
                        // Therefore, the size check is safe to make.
                        if (expectedCertDigests.length != libCertDigests.length) {
                            throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
                                    "Package " + packageName + " requires differently signed" +
                                            " static shared library; failing!");
                        }

                        // Use a predictable order as signature order may vary
                        Arrays.sort(libCertDigests);
                        Arrays.sort(expectedCertDigests);

                        final int certCount = libCertDigests.length;
                        for (int j = 0; j < certCount; j++) {
                            if (!libCertDigests[j].equalsIgnoreCase(expectedCertDigests[j])) {
                                throw new PackageManagerException(
                                        INSTALL_FAILED_MISSING_SHARED_LIBRARY,
                                        "Package " + packageName + " requires differently signed" +
                                                " static shared library; failing!");
                            }
                        }
                    } else {
                        // lib signing cert could have rotated beyond the one expected, check to see
                        // if the new one has been blessed by the old
                        byte[] digestBytes = HexEncoding.decode(
                                expectedCertDigests[0], false /* allowSingleChar */);
                        if (!libPkg.hasSha256Certificate(digestBytes)) {
                            throw new PackageManagerException(
                                    INSTALL_FAILED_MISSING_SHARED_LIBRARY,
                                    "Package " + packageName + " requires differently signed" +
                                            " static shared library; failing!");
                        }
                    }
                }
                if (outUsedLibraries == null) {
                    outUsedLibraries = new ArrayList<>();
                }
                outUsedLibraries.add(libraryInfo);
            }
        }
        return outUsedLibraries;
    }

    private static boolean hasString(List<String> list, List<String> which) {
        if (list == null || which == null) {
            return false;
        }
        for (int i=list.size()-1; i>=0; i--) {
            for (int j=which.size()-1; j>=0; j--) {
                if (which.get(j).equals(list.get(i))) {
                    return true;
                }
            }
        }
        return false;
    }

    @GuardedBy("mLock")
    private ArrayList<AndroidPackage> updateAllSharedLibrariesLocked(
            AndroidPackage updatedPkg,
            Map<String, AndroidPackage> availablePackages) {
        ArrayList<AndroidPackage> resultList = null;
        // Set of all descendants of a library; used to eliminate cycles
        ArraySet<String> descendants = null;
        // The current list of packages that need updating
        ArrayList<AndroidPackage> needsUpdating = null;
        if (updatedPkg != null) {
            needsUpdating = new ArrayList<>(1);
            needsUpdating.add(updatedPkg);
        }
        do {
            final AndroidPackage changingPkg =
                    (needsUpdating == null) ? null : needsUpdating.remove(0);
            for (int i = mPackages.size() - 1; i >= 0; --i) {
                final AndroidPackage pkg = mPackages.valueAt(i);
                if (changingPkg != null
                        && !hasString(pkg.getUsesLibraries(), changingPkg.getLibraryNames())
                        && !hasString(pkg.getUsesOptionalLibraries(), changingPkg.getLibraryNames())
                        && !ArrayUtils.contains(pkg.getUsesStaticLibraries(),
                                changingPkg.getStaticSharedLibName())) {
                    continue;
                }
                if (resultList == null) {
                    resultList = new ArrayList<>();
                }
                resultList.add(pkg);
                // if we're updating a shared library, all of its descendants must be updated
                if (changingPkg != null) {
                    if (descendants == null) {
                        descendants = new ArraySet<>();
                    }
                    if (!descendants.contains(pkg.getPackageName())) {
                        descendants.add(pkg.getPackageName());
                        needsUpdating.add(pkg);
                    }
                }
                try {
                    updateSharedLibrariesLocked(pkg, changingPkg, availablePackages);
                } catch (PackageManagerException e) {
                    // If a system app update or an app and a required lib missing we
                    // delete the package and for updated system apps keep the data as
                    // it is better for the user to reinstall than to be in an limbo
                    // state. Also libs disappearing under an app should never happen
                    // - just in case.
                    if (!pkg.isSystem() || pkg.isUpdatedSystemApp()) {
                        final int flags = pkg.isUpdatedSystemApp()
                                ? PackageManager.DELETE_KEEP_DATA : 0;
                        deletePackageLIF(pkg.getPackageName(), null, true,
                                mUserManager.getUserIds(), flags, null,
                                true, null);
                    }
                    Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
                }
            }
        } while (needsUpdating != null && needsUpdating.size() > 0);
        return resultList;
    }

    @GuardedBy({"mInstallLock", "mLock"})
    private ScanResult scanPackageTracedLI(ParsedPackage parsedPackage,
            final @ParseFlags int parseFlags, @ScanFlags int scanFlags, long currentTime,
            @Nullable UserHandle user) throws PackageManagerException {
        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanPackage");
        try {
            return scanPackageNewLI(parsedPackage, parseFlags, scanFlags, currentTime, user);
        } finally {
            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
        }
    }

    /** The result of a package scan. */
    @VisibleForTesting
    static class ScanResult {
        /** The request that initiated the scan that produced this result. */
        public final ScanRequest request;
        /** Whether or not the package scan was successful */
        public final boolean success;
        /**
         * Whether or not the original PackageSetting needs to be updated with this result on
         * commit.
         */
        public final boolean existingSettingCopied;
        /**
         * The final package settings. This may be the same object passed in
         * the {@link ScanRequest}, but, with modified values.
         */
        @Nullable public final PackageSetting pkgSetting;
        /** ABI code paths that have changed in the package scan */
        @Nullable public final List<String> changedAbiCodePath;

        public final SharedLibraryInfo staticSharedLibraryInfo;

        public final List<SharedLibraryInfo> dynamicSharedLibraryInfos;

        public ScanResult(
                ScanRequest request, boolean success,
                @Nullable PackageSetting pkgSetting,
                @Nullable List<String> changedAbiCodePath, boolean existingSettingCopied,
                SharedLibraryInfo staticSharedLibraryInfo,
                List<SharedLibraryInfo> dynamicSharedLibraryInfos) {
            this.request = request;
            this.success = success;
            this.pkgSetting = pkgSetting;
            this.changedAbiCodePath = changedAbiCodePath;
            this.existingSettingCopied = existingSettingCopied;
            this.staticSharedLibraryInfo = staticSharedLibraryInfo;
            this.dynamicSharedLibraryInfos = dynamicSharedLibraryInfos;
        }
    }

    /** A package to be scanned */
    @VisibleForTesting
    static class ScanRequest {
        /** The parsed package */
        @NonNull public final ParsedPackage parsedPackage;
        /** The package this package replaces */
        @Nullable public final AndroidPackage oldPkg;
        /** Shared user settings, if the package has a shared user */
        @Nullable public final SharedUserSetting sharedUserSetting;
        /**
         * Package settings of the currently installed version.
         * <p><em>IMPORTANT:</em> The contents of this object may be modified
         * during scan.
         */
        @Nullable public final PackageSetting pkgSetting;
        /** A copy of the settings for the currently installed version */
        @Nullable public final PackageSetting oldPkgSetting;
        /** Package settings for the disabled version on the /system partition */
        @Nullable public final PackageSetting disabledPkgSetting;
        /** Package settings for the installed version under its original package name */
        @Nullable public final PackageSetting originalPkgSetting;
        /** The real package name of a renamed application */
        @Nullable public final String realPkgName;
        public final @ParseFlags int parseFlags;
        public final @ScanFlags int scanFlags;
        /** The user for which the package is being scanned */
        @Nullable public final UserHandle user;
        /** Whether or not the platform package is being scanned */
        public final boolean isPlatformPackage;
        public ScanRequest(
                @NonNull ParsedPackage parsedPackage,
                @Nullable SharedUserSetting sharedUserSetting,
                @Nullable AndroidPackage oldPkg,
                @Nullable PackageSetting pkgSetting,
                @Nullable PackageSetting disabledPkgSetting,
                @Nullable PackageSetting originalPkgSetting,
                @Nullable String realPkgName,
                @ParseFlags int parseFlags,
                @ScanFlags int scanFlags,
                boolean isPlatformPackage,
                @Nullable UserHandle user) {
            this.parsedPackage = parsedPackage;
            this.oldPkg = oldPkg;
            this.pkgSetting = pkgSetting;
            this.sharedUserSetting = sharedUserSetting;
            this.oldPkgSetting = pkgSetting == null ? null : new PackageSetting(pkgSetting);
            this.disabledPkgSetting = disabledPkgSetting;
            this.originalPkgSetting = originalPkgSetting;
            this.realPkgName = realPkgName;
            this.parseFlags = parseFlags;
            this.scanFlags = scanFlags;
            this.isPlatformPackage = isPlatformPackage;
            this.user = user;
        }
    }

    /**
     * Returns the actual scan flags depending upon the state of the other settings.
     * <p>Updated system applications will not have the following flags set
     * by default and need to be adjusted after the fact:
     * <ul>
     * <li>{@link #SCAN_AS_SYSTEM}</li>
     * <li>{@link #SCAN_AS_PRIVILEGED}</li>
     * <li>{@link #SCAN_AS_OEM}</li>
     * <li>{@link #SCAN_AS_VENDOR}</li>
     * <li>{@link #SCAN_AS_PRODUCT}</li>
     * <li>{@link #SCAN_AS_SYSTEM_EXT}</li>
     * <li>{@link #SCAN_AS_INSTANT_APP}</li>
     * <li>{@link #SCAN_AS_VIRTUAL_PRELOAD}</li>
     * <li>{@link #SCAN_AS_ODM}</li>
     * </ul>
     */
    private @ScanFlags int adjustScanFlags(@ScanFlags int scanFlags,
            PackageSetting pkgSetting, PackageSetting disabledPkgSetting, UserHandle user,
            AndroidPackage pkg) {

        // TODO(patb): Do away entirely with disabledPkgSetting here. PkgSetting will always contain
        // the correct isSystem value now that we don't disable system packages before scan.
        final PackageSetting systemPkgSetting =
                (scanFlags & SCAN_NEW_INSTALL) != 0 && disabledPkgSetting == null
                        && pkgSetting != null && pkgSetting.isSystem()
                        ? pkgSetting
                        : disabledPkgSetting;
        if (systemPkgSetting != null)  {
            // updated system application, must at least have SCAN_AS_SYSTEM
            scanFlags |= SCAN_AS_SYSTEM;
            if ((systemPkgSetting.pkgPrivateFlags
                    & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0) {
                scanFlags |= SCAN_AS_PRIVILEGED;
            }
            if ((systemPkgSetting.pkgPrivateFlags
                    & ApplicationInfo.PRIVATE_FLAG_OEM) != 0) {
                scanFlags |= SCAN_AS_OEM;
            }
            if ((systemPkgSetting.pkgPrivateFlags
                    & ApplicationInfo.PRIVATE_FLAG_VENDOR) != 0) {
                scanFlags |= SCAN_AS_VENDOR;
            }
            if ((systemPkgSetting.pkgPrivateFlags
                    & ApplicationInfo.PRIVATE_FLAG_PRODUCT) != 0) {
                scanFlags |= SCAN_AS_PRODUCT;
            }
            if ((systemPkgSetting.pkgPrivateFlags
                    & ApplicationInfo.PRIVATE_FLAG_SYSTEM_EXT) != 0) {
                scanFlags |= SCAN_AS_SYSTEM_EXT;
            }
            if ((systemPkgSetting.pkgPrivateFlags
                    & ApplicationInfo.PRIVATE_FLAG_ODM) != 0) {
                scanFlags |= SCAN_AS_ODM;
            }
        }
        if (pkgSetting != null) {
            final int userId = ((user == null) ? 0 : user.getIdentifier());
            if (pkgSetting.getInstantApp(userId)) {
                scanFlags |= SCAN_AS_INSTANT_APP;
            }
            if (pkgSetting.getVirtulalPreload(userId)) {
                scanFlags |= SCAN_AS_VIRTUAL_PRELOAD;
            }
        }

        // Scan as privileged apps that share a user with a priv-app.
        final boolean skipVendorPrivilegeScan = ((scanFlags & SCAN_AS_VENDOR) != 0)
                && SystemProperties.getInt("ro.vndk.version", 28) < 28;
        if (((scanFlags & SCAN_AS_PRIVILEGED) == 0)
                && !pkg.isPrivileged()
                && (pkg.getSharedUserId() != null)
                && !skipVendorPrivilegeScan) {
            SharedUserSetting sharedUserSetting = null;
            try {
                sharedUserSetting = mSettings.getSharedUserLPw(pkg.getSharedUserId(), 0,
                        0, false);
            } catch (PackageManagerException ignore) {
            }
            if (sharedUserSetting != null && sharedUserSetting.isPrivileged()) {
                // Exempt SharedUsers signed with the platform key.
                // TODO(b/72378145) Fix this exemption. Force signature apps
                // to whitelist their privileged permissions just like other
                // priv-apps.
                synchronized (mLock) {
                    PackageSetting platformPkgSetting = mSettings.mPackages.get("android");
                    if ((compareSignatures(platformPkgSetting.signatures.mSigningDetails.signatures,
                            pkg.getSigningDetails().signatures)
                            != PackageManager.SIGNATURE_MATCH)) {
                        scanFlags |= SCAN_AS_PRIVILEGED;
                    }
                }
            }
        }

        return scanFlags;
    }

    // TODO: scanPackageNewLI() and scanPackageOnly() should be merged. But, first, commiting
    // the results / removing app data needs to be moved up a level to the callers of this
    // method. Also, we need to solve the problem of potentially creating a new shared user
    // setting. That can probably be done later and patch things up after the fact.
    @GuardedBy({"mInstallLock", "mLock"})
    private ScanResult scanPackageNewLI(@NonNull ParsedPackage parsedPackage,
            final @ParseFlags int parseFlags, @ScanFlags int scanFlags, long currentTime,
            @Nullable UserHandle user) throws PackageManagerException {

        final String renamedPkgName = mSettings.getRenamedPackageLPr(
                parsedPackage.getRealPackage());
        final String realPkgName = getRealPackageName(parsedPackage, renamedPkgName);
        if (realPkgName != null) {
            ensurePackageRenamed(parsedPackage, renamedPkgName);
        }
        final PackageSetting originalPkgSetting = getOriginalPackageLocked(parsedPackage,
                renamedPkgName);
        final PackageSetting pkgSetting = mSettings.getPackageLPr(parsedPackage.getPackageName());
        final PackageSetting disabledPkgSetting =
                mSettings.getDisabledSystemPkgLPr(parsedPackage.getPackageName());

        if (mTransferredPackages.contains(parsedPackage.getPackageName())) {
            Slog.w(TAG, "Package " + parsedPackage.getPackageName()
                    + " was transferred to another, but its .apk remains");
        }

        scanFlags = adjustScanFlags(scanFlags, pkgSetting, disabledPkgSetting, user, parsedPackage);
        synchronized (mLock) {
            applyPolicy(parsedPackage, parseFlags, scanFlags, mPlatformPackage);
            assertPackageIsValid(parsedPackage, parseFlags, scanFlags);

            SharedUserSetting sharedUserSetting = null;
            if (parsedPackage.getSharedUserId() != null) {
                // SIDE EFFECTS; may potentially allocate a new shared user
                sharedUserSetting = mSettings.getSharedUserLPw(parsedPackage.getSharedUserId(),
                        0 /*pkgFlags*/, 0 /*pkgPrivateFlags*/, true /*create*/);
                if (DEBUG_PACKAGE_SCANNING) {
                    if ((parseFlags & PackageParser.PARSE_CHATTY) != 0)
                        Log.d(TAG, "Shared UserID " + parsedPackage.getSharedUserId()
                                + " (uid=" + sharedUserSetting.userId + "):"
                                + " packages=" + sharedUserSetting.packages);
                }
            }
            String platformPackageName = mPlatformPackage == null
                    ? null : mPlatformPackage.getPackageName();
            final ScanRequest request = new ScanRequest(parsedPackage, sharedUserSetting,
                    pkgSetting == null ? null : pkgSetting.pkg, pkgSetting, disabledPkgSetting,
                    originalPkgSetting, realPkgName, parseFlags, scanFlags,
                    Objects.equals(parsedPackage.getPackageName(), platformPackageName), user);
            return scanPackageOnlyLI(request, mInjector, mFactoryTest, currentTime);
        }
    }


    /**
     * Prepares the system to commit a {@link ScanResult} in a way that will not fail by registering
     * the app ID required for reconcile.
     * @return {@code true} if a new app ID was registered and will need to be cleaned up on
     *         failure.
     */
    private boolean optimisticallyRegisterAppId(@NonNull ScanResult result)
            throws PackageManagerException {
        if (!result.existingSettingCopied) {
            // THROWS: when we can't allocate a user id. add call to check if there's
            // enough space to ensure we won't throw; otherwise, don't modify state
            return mSettings.registerAppIdLPw(result.pkgSetting);
        }
        return false;
    }

    /**
     * Reverts any app ID creation that were made by
     * {@link #optimisticallyRegisterAppId(ScanResult)}. Note: this is only necessary if the
     * referenced method returned true.
     */
    private void cleanUpAppIdCreation(@NonNull ScanResult result) {
        // iff we've acquired an app ID for a new package setting, remove it so that it can be
        // acquired by another request.
        if (result.pkgSetting.appId > 0) {
            mSettings.removeAppIdLPw(result.pkgSetting.appId);
        }
    }

    /**
     * Commits the package scan and modifies system state.
     * <p><em>WARNING:</em> The method may throw an excpetion in the middle
     * of committing the package, leaving the system in an inconsistent state.
     * This needs to be fixed so, once we get to this point, no errors are
     * possible and the system is not left in an inconsistent state.
     */
    @GuardedBy({"mLock", "mInstallLock"})
    private AndroidPackage commitReconciledScanResultLocked(
            @NonNull ReconciledPackage reconciledPkg) {
        final ScanResult result = reconciledPkg.scanResult;
        final ScanRequest request = result.request;
        // TODO(b/135203078): Move this even further away
        ParsedPackage parsedPackage = request.parsedPackage;
        if ("android".equals(parsedPackage.getPackageName())) {
            // TODO(b/135203078): Move this to initial parse
            parsedPackage.setVersionCode(mSdkVersion)
                    .setVersionCodeMajor(0);
        }
        final AndroidPackage oldPkg = request.oldPkg;
        final @ParseFlags int parseFlags = request.parseFlags;
        final @ScanFlags int scanFlags = request.scanFlags;
        final PackageSetting oldPkgSetting = request.oldPkgSetting;
        final PackageSetting originalPkgSetting = request.originalPkgSetting;
        final UserHandle user = request.user;
        final String realPkgName = request.realPkgName;
        final List<String> changedAbiCodePath = result.changedAbiCodePath;
        final PackageSetting pkgSetting;
        if (request.pkgSetting != null && request.pkgSetting.sharedUser != null
                && request.pkgSetting.sharedUser != result.pkgSetting.sharedUser) {
            // shared user changed, remove from old shared user
            request.pkgSetting.sharedUser.removePackage(request.pkgSetting);
        }
        if (result.existingSettingCopied) {
            pkgSetting = request.pkgSetting;
            pkgSetting.updateFrom(result.pkgSetting);
        } else {
            pkgSetting = result.pkgSetting;
            if (originalPkgSetting != null) {
                mSettings.addRenamedPackageLPw(parsedPackage.getPackageName(),
                        originalPkgSetting.name);
                mTransferredPackages.add(originalPkgSetting.name);
            }
        }
        if (pkgSetting.sharedUser != null) {
            pkgSetting.sharedUser.addPackage(pkgSetting);
        }
        // TODO(toddke): Consider a method specifically for modifying the Package object
        // post scan; or, moving this stuff out of the Package object since it has nothing
        // to do with the package on disk.
        // We need to have this here because addUserToSettingLPw() is sometimes responsible
        // for creating the application ID. If we did this earlier, we would be saving the
        // correct ID.
        parsedPackage.setUid(pkgSetting.appId);
        final AndroidPackage pkg = parsedPackage.hideAsFinal();

        mSettings.writeUserRestrictionsLPw(pkgSetting, oldPkgSetting);

        if (realPkgName != null) {
            mTransferredPackages.add(pkg.getPackageName());
        }

        if (reconciledPkg.collectedSharedLibraryInfos != null) {
            executeSharedLibrariesUpdateLPr(pkg, null, reconciledPkg.collectedSharedLibraryInfos);
        }

        final KeySetManagerService ksms = mSettings.mKeySetManagerService;
        if (reconciledPkg.removeAppKeySetData) {
            ksms.removeAppKeySetDataLPw(pkg.getPackageName());
        }
        if (reconciledPkg.sharedUserSignaturesChanged) {
            pkgSetting.sharedUser.signaturesChanged = Boolean.TRUE;
            pkgSetting.sharedUser.signatures.mSigningDetails = reconciledPkg.signingDetails;
        }
        pkgSetting.signatures.mSigningDetails = reconciledPkg.signingDetails;

        if (pkg.getAdoptPermissions() != null) {
            // This package wants to adopt ownership of permissions from
            // another package.
            for (int i = pkg.getAdoptPermissions().size() - 1; i >= 0; i--) {
                final String origName = pkg.getAdoptPermissions().get(i);
                final PackageSetting orig = mSettings.getPackageLPr(origName);
                if (orig != null) {
                    if (verifyPackageUpdateLPr(orig, pkg)) {
                        Slog.i(TAG, "Adopting permissions from " + origName + " to "
                                + pkg.getPackageName());
                        mSettings.mPermissions.transferPermissions(origName, pkg.getPackageName());
                    }
                }
            }
        }

        if (changedAbiCodePath != null && changedAbiCodePath.size() > 0) {
            for (int i = changedAbiCodePath.size() - 1; i >= 0; --i) {
                final String codePathString = changedAbiCodePath.get(i);
                try {
                    mInstaller.rmdex(codePathString,
                            getDexCodeInstructionSet(getPreferredInstructionSet()));
                } catch (InstallerException ignored) {
                }
            }
        }

        final int userId = user == null ? 0 : user.getIdentifier();
        // Modify state for the given package setting
        commitPackageSettings(pkg, oldPkg, pkgSetting, scanFlags,
                (parseFlags & PackageParser.PARSE_CHATTY) != 0 /*chatty*/, reconciledPkg);
        if (pkgSetting.getInstantApp(userId)) {
            mInstantAppRegistry.addInstantAppLPw(userId, pkgSetting.appId);
        }

        return pkg;
    }

    /**
     * Returns the "real" name of the package.
     * <p>This may differ from the package's actual name if the application has already
     * been installed under one of this package's original names.
     */
    private static @Nullable String getRealPackageName(@NonNull AndroidPackage pkg,
            @Nullable String renamedPkgName) {
        if (isPackageRenamed(pkg, renamedPkgName)) {
            return pkg.getRealPackage();
        }
        return null;
    }

    /** Returns {@code true} if the package has been renamed. Otherwise, {@code false}. */
    private static boolean isPackageRenamed(@NonNull AndroidPackage pkg,
            @Nullable String renamedPkgName) {
        return pkg.getOriginalPackages() != null
                && pkg.getOriginalPackages().contains(renamedPkgName);
    }

    /**
     * Returns the original package setting.
     * <p>A package can migrate its name during an update. In this scenario, a package
     * designates a set of names that it considers as one of its original names.
     * <p>An original package must be signed identically and it must have the same
     * shared user [if any].
     */
    @GuardedBy("mLock")
    private @Nullable PackageSetting getOriginalPackageLocked(@NonNull AndroidPackage pkg,
            @Nullable String renamedPkgName) {
        if (!isPackageRenamed(pkg, renamedPkgName)) {
            return null;
        }
        for (int i = ArrayUtils.size(pkg.getOriginalPackages()) - 1; i >= 0; --i) {
            final PackageSetting originalPs =
                    mSettings.getPackageLPr(pkg.getOriginalPackages().get(i));
            if (originalPs != null) {
                // the package is already installed under its original name...
                // but, should we use it?
                if (!verifyPackageUpdateLPr(originalPs, pkg)) {
                    // the new package is incompatible with the original
                    continue;
                } else if (originalPs.sharedUser != null) {
                    if (!originalPs.sharedUser.name.equals(pkg.getSharedUserId())) {
                        // the shared user id is incompatible with the original
                        Slog.w(TAG, "Unable to migrate data from " + originalPs.name
                                + " to " + pkg.getPackageName() + ": old uid "
                                + originalPs.sharedUser.name
                                + " differs from " + pkg.getSharedUserId());
                        continue;
                    }
                    // TODO: Add case when shared user id is added [b/28144775]
                } else {
                    if (DEBUG_UPGRADE) Log.v(TAG, "Renaming new package "
                            + pkg.getPackageName() + " to old name " + originalPs.name);
                }
                return originalPs;
            }
        }
        return null;
    }

    /**
     * Renames the package if it was installed under a different name.
     * <p>When we've already installed the package under an original name, update
     * the new package so we can continue to have the old name.
     */
    private static void ensurePackageRenamed(@NonNull ParsedPackage parsedPackage,
            @NonNull String renamedPackageName) {
        if (parsedPackage.getOriginalPackages() == null
                || !parsedPackage.getOriginalPackages().contains(renamedPackageName)
                || parsedPackage.getPackageName().equals(renamedPackageName)) {
            return;
        }
        parsedPackage.setPackageName(renamedPackageName);
    }

    /**
     * Applies the adjusted ABI calculated by
     * {@link PackageAbiHelper#getAdjustedAbiForSharedUser(Set, AndroidPackage)} to all
     * relevant packages and settings.
     * @param sharedUserSetting The {@code SharedUserSetting} to adjust
     * @param scannedPackage the package being scanned or null
     * @param adjustedAbi the adjusted ABI calculated by {@link PackageAbiHelper}
     * @return the list of code paths that belong to packages that had their ABIs adjusted.
     */
    private static List<String> applyAdjustedAbiToSharedUser(SharedUserSetting sharedUserSetting,
            ParsedPackage scannedPackage, String adjustedAbi) {
        if (scannedPackage != null)  {
            scannedPackage.setPrimaryCpuAbi(adjustedAbi);
        }
        List<String> changedAbiCodePath = null;
        for (PackageSetting ps : sharedUserSetting.packages) {
            if (scannedPackage == null || !scannedPackage.getPackageName().equals(ps.name)) {
                if (ps.primaryCpuAbiString != null) {
                    continue;
                }

                ps.primaryCpuAbiString = adjustedAbi;
                if (ps.pkg != null && !TextUtils.equals(adjustedAbi, ps.pkg.getPrimaryCpuAbi())) {
                    ps.pkg.mutate().setPrimaryCpuAbi(adjustedAbi);
                    if (DEBUG_ABI_SELECTION) {
                        Slog.i(TAG,
                                "Adjusting ABI for " + ps.name + " to " + adjustedAbi
                                        + " (scannedPackage="
                                        + (scannedPackage != null ? scannedPackage : "null")
                                        + ")");
                    }
                    if (changedAbiCodePath == null) {
                        changedAbiCodePath = new ArrayList<>();
                    }
                    changedAbiCodePath.add(ps.codePathString);
                }
            }
        }
        return changedAbiCodePath;
    }

    /**
     * Sets the enabled state of components configured through {@link SystemConfig}.
     * This modifies the {@link PackageSetting} object.
     **/
    static void configurePackageComponents(AndroidPackage pkg) {
        final ArrayMap<String, Boolean> componentsEnabledStates = SystemConfig.getInstance()
                .getComponentsEnabledStates(pkg.getPackageName());
        if (componentsEnabledStates == null) {
            return;
        }

        for (int i = ArrayUtils.size(pkg.getActivities()) - 1; i >= 0; i--) {
            final ParsedActivity component = pkg.getActivities().get(i);
            final Boolean enabled = componentsEnabledStates.get(component.className);
            if (enabled != null) {
                component.setEnabled(enabled);
            }
        }

        for (int i = ArrayUtils.size(pkg.getReceivers()) - 1; i >= 0; i--) {
            final ParsedActivity component = pkg.getReceivers().get(i);
            final Boolean enabled = componentsEnabledStates.get(component.className);
            if (enabled != null) {
                component.setEnabled(enabled);
            }
        }

        for (int i = ArrayUtils.size(pkg.getProviders()) - 1; i >= 0; i--) {
            final ParsedProvider component = pkg.getProviders().get(i);
            final Boolean enabled = componentsEnabledStates.get(component.className);
            if (enabled != null) {
                component.setEnabled(enabled);
            }
        }

        for (int i = ArrayUtils.size(pkg.getServices()) - 1; i >= 0; i--) {
            final ParsedService component = pkg.getServices().get(i);
            final Boolean enabled = componentsEnabledStates.get(component.className);
            if (enabled != null) {
                component.setEnabled(enabled);
            }
        }
    }


    /**
     * Just scans the package without any side effects.
     * <p>Not entirely true at the moment. There is still one side effect -- this
     * method potentially modifies a live {@link PackageSetting} object representing
     * the package being scanned. This will be resolved in the future.
     *
     * @param injector injector for acquiring dependencies
     * @param request Information about the package to be scanned
     * @param isUnderFactoryTest Whether or not the device is under factory test
     * @param currentTime The current time, in millis
     * @return The results of the scan
     */
    @GuardedBy("mInstallLock")
    @VisibleForTesting
    @NonNull
    static ScanResult scanPackageOnlyLI(@NonNull ScanRequest request,
            Injector injector,
            boolean isUnderFactoryTest, long currentTime)
            throws PackageManagerException {
        final PackageAbiHelper packageAbiHelper = injector.getAbiHelper();
        final UserManagerInternal userManager = injector.getUserManagerInternal();
        ParsedPackage parsedPackage = request.parsedPackage;
        PackageSetting pkgSetting = request.pkgSetting;
        final PackageSetting disabledPkgSetting = request.disabledPkgSetting;
        final PackageSetting originalPkgSetting = request.originalPkgSetting;
        final @ParseFlags int parseFlags = request.parseFlags;
        final @ScanFlags int scanFlags = request.scanFlags;
        final String realPkgName = request.realPkgName;
        final SharedUserSetting sharedUserSetting = request.sharedUserSetting;
        final UserHandle user = request.user;
        final boolean isPlatformPackage = request.isPlatformPackage;

        List<String> changedAbiCodePath = null;

        if (DEBUG_PACKAGE_SCANNING) {
            if ((parseFlags & PackageParser.PARSE_CHATTY) != 0)
                Log.d(TAG, "Scanning package " + parsedPackage.getPackageName());
        }

        // Initialize package source and resource directories
        final File destCodeFile = new File(parsedPackage.getAppInfoCodePath());
        final File destResourceFile = new File(parsedPackage.getAppInfoResourcePath());

        // We keep references to the derived CPU Abis from settings in oder to reuse
        // them in the case where we're not upgrading or booting for the first time.
        String primaryCpuAbiFromSettings = null;
        String secondaryCpuAbiFromSettings = null;
        boolean needToDeriveAbi = (scanFlags & SCAN_FIRST_BOOT_OR_UPGRADE) != 0;
        if (!needToDeriveAbi) {
            if (pkgSetting != null) {
                primaryCpuAbiFromSettings = pkgSetting.primaryCpuAbiString;
                secondaryCpuAbiFromSettings = pkgSetting.secondaryCpuAbiString;
            } else {
                // Re-scanning a system package after uninstalling updates; need to derive ABI
                needToDeriveAbi = true;
            }
        }

        if (pkgSetting != null && pkgSetting.sharedUser != sharedUserSetting) {
            PackageManagerService.reportSettingsProblem(Log.WARN,
                    "Package " + parsedPackage.getPackageName() + " shared user changed from "
                            + (pkgSetting.sharedUser != null
                            ? pkgSetting.sharedUser.name : "<nothing>")
                            + " to "
                            + (sharedUserSetting != null ? sharedUserSetting.name : "<nothing>")
                            + "; replacing with new");
            pkgSetting = null;
        }

        String[] usesStaticLibraries = null;
        if (parsedPackage.getUsesStaticLibraries() != null) {
            usesStaticLibraries = new String[parsedPackage.getUsesStaticLibraries().size()];
            parsedPackage.getUsesStaticLibraries().toArray(usesStaticLibraries);
        }
        final boolean createNewPackage = (pkgSetting == null);
        if (createNewPackage) {
            final boolean instantApp = (scanFlags & SCAN_AS_INSTANT_APP) != 0;
            final boolean virtualPreload = (scanFlags & SCAN_AS_VIRTUAL_PRELOAD) != 0;
            // REMOVE SharedUserSetting from method; update in a separate call
            pkgSetting = Settings.createNewSetting(parsedPackage.getPackageName(),
                    originalPkgSetting, disabledPkgSetting, realPkgName, sharedUserSetting,
                    destCodeFile, destResourceFile, parsedPackage.getNativeLibraryRootDir(),
                    parsedPackage.getPrimaryCpuAbi(), parsedPackage.getSecondaryCpuAbi(),
                    parsedPackage.getVersionCode(), parsedPackage.getFlags(),
                    parsedPackage.getPrivateFlags(), user, true /*allowInstall*/, instantApp,
                    virtualPreload, UserManagerService.getInstance(), usesStaticLibraries,
                    parsedPackage.getUsesStaticLibrariesVersions());
        } else {
            // make a deep copy to avoid modifying any existing system state.
            pkgSetting = new PackageSetting(pkgSetting);
            // TODO(b/135203078): Remove entirely. Set package directly.
            parsedPackage.setPackageSettingCallback(pkgSetting);

            // REMOVE SharedUserSetting from method; update in a separate call.
            //
            // TODO(narayan): This update is bogus. nativeLibraryDir & primaryCpuAbi,
            // secondaryCpuAbi are not known at this point so we always update them
            // to null here, only to reset them at a later point.
            Settings.updatePackageSetting(pkgSetting, disabledPkgSetting, sharedUserSetting,
                    destCodeFile, destResourceFile, parsedPackage.getNativeLibraryDir(),
                    parsedPackage.getPrimaryCpuAbi(), parsedPackage.getSecondaryCpuAbi(),
                    parsedPackage.getFlags(), parsedPackage.getPrivateFlags(),
                    UserManagerService.getInstance(),
                    usesStaticLibraries, parsedPackage.getUsesStaticLibrariesVersions());
        }
        if (createNewPackage && originalPkgSetting != null) {
            // This is the initial transition from the original package, so,
            // fix up the new package's name now. We must do this after looking
            // up the package under its new name, so getPackageLP takes care of
            // fiddling things correctly.
            parsedPackage.setPackageName(originalPkgSetting.name);

            // File a report about this.
            String msg = "New package " + pkgSetting.realName
                    + " renamed to replace old package " + pkgSetting.name;
            reportSettingsProblem(Log.WARN, msg);
        }

        final int userId = (user == null ? UserHandle.USER_SYSTEM : user.getIdentifier());
        // for existing packages, change the install state; but, only if it's explicitly specified
        if (!createNewPackage) {
            final boolean instantApp = (scanFlags & SCAN_AS_INSTANT_APP) != 0;
            final boolean fullApp = (scanFlags & SCAN_AS_FULL_APP) != 0;
            setInstantAppForUser(injector, pkgSetting, userId, instantApp, fullApp);
        }
        // TODO(patb): see if we can do away with disabled check here.
        if (disabledPkgSetting != null
                || (0 != (scanFlags & SCAN_NEW_INSTALL)
                && pkgSetting != null && pkgSetting.isSystem())) {
            parsedPackage.mutate().setUpdatedSystemApp(true);
        }

        parsedPackage
                .setSeInfo(SELinuxMMAC.getSeInfo(parsedPackage, sharedUserSetting,
                        injector.getCompatibility()))
                .setSeInfoUser(SELinuxUtil.assignSeinfoUser(pkgSetting.readUserState(
                        userId == UserHandle.USER_ALL ? UserHandle.USER_SYSTEM : userId)))
                .setProcessName(fixProcessName(parsedPackage.getPackageName(),
                        parsedPackage.getProcessName()));

        if (!isPlatformPackage) {
            // Get all of our default paths setup
            parsedPackage.initForUser(UserHandle.USER_SYSTEM);
        }

        if (parsedPackage.isSystem()) {
            configurePackageComponents(parsedPackage);
        }

        final String cpuAbiOverride = deriveAbiOverride(parsedPackage.getCpuAbiOverride(),
                pkgSetting);

        if ((scanFlags & SCAN_NEW_INSTALL) == 0) {
            if (needToDeriveAbi) {
                Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "derivePackageAbi");
                final boolean extractNativeLibs = !parsedPackage.isLibrary();
                final Pair<PackageAbiHelper.Abis, PackageAbiHelper.NativeLibraryPaths> derivedAbi =
                        packageAbiHelper.derivePackageAbi(parsedPackage, cpuAbiOverride,
                                extractNativeLibs);
                derivedAbi.first.applyTo(parsedPackage);
                derivedAbi.second.applyTo(parsedPackage);
                Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);

                // Some system apps still use directory structure for native libraries
                // in which case we might end up not detecting abi solely based on apk
                // structure. Try to detect abi based on directory structure.
                if (isSystemApp(parsedPackage) && !parsedPackage.isUpdatedSystemApp() &&
                        parsedPackage.getPrimaryCpuAbi() == null) {
                    final PackageAbiHelper.Abis abis = packageAbiHelper.getBundledAppAbis(
                            parsedPackage);
                    abis.applyTo(parsedPackage);
                    abis.applyTo(pkgSetting);
                    final PackageAbiHelper.NativeLibraryPaths nativeLibraryPaths =
                            packageAbiHelper.getNativeLibraryPaths(parsedPackage,
                                    sAppLib32InstallDir);
                    nativeLibraryPaths.applyTo(parsedPackage);
                }
            } else {
                // This is not a first boot or an upgrade, don't bother deriving the
                // ABI during the scan. Instead, trust the value that was stored in the
                // package setting.
                parsedPackage.setPrimaryCpuAbi(primaryCpuAbiFromSettings)
                        .setSecondaryCpuAbi(secondaryCpuAbiFromSettings);

                final PackageAbiHelper.NativeLibraryPaths nativeLibraryPaths =
                        packageAbiHelper.getNativeLibraryPaths(parsedPackage, sAppLib32InstallDir);
                nativeLibraryPaths.applyTo(parsedPackage);

                if (DEBUG_ABI_SELECTION) {
                    Slog.i(TAG, "Using ABIS and native lib paths from settings : " +
                            parsedPackage.getPackageName() + " " + parsedPackage.getPrimaryCpuAbi()
                            + ", " + parsedPackage.getSecondaryCpuAbi());
                }
            }
        } else {
            if ((scanFlags & SCAN_MOVE) != 0) {
                // We haven't run dex-opt for this move (since we've moved the compiled output too)
                // but we already have this packages package info in the PackageSetting. We just
                // use that and derive the native library path based on the new codepath.
                parsedPackage.setPrimaryCpuAbi(pkgSetting.primaryCpuAbiString)
                        .setSecondaryCpuAbi(pkgSetting.secondaryCpuAbiString);
            }

            // Set native library paths again. For moves, the path will be updated based on the
            // ABIs we've determined above. For non-moves, the path will be updated based on the
            // ABIs we determined during compilation, but the path will depend on the final
            // package path (after the rename away from the stage path).
            final PackageAbiHelper.NativeLibraryPaths nativeLibraryPaths =
                    packageAbiHelper.getNativeLibraryPaths(parsedPackage, sAppLib32InstallDir);
            nativeLibraryPaths.applyTo(parsedPackage);
        }

        // This is a special case for the "system" package, where the ABI is
        // dictated by the zygote configuration (and init.rc). We should keep track
        // of this ABI so that we can deal with "normal" applications that run under
        // the same UID correctly.
        if (isPlatformPackage) {
            parsedPackage.setPrimaryCpuAbi(VMRuntime.getRuntime().is64Bit() ?
                    Build.SUPPORTED_64_BIT_ABIS[0] : Build.SUPPORTED_32_BIT_ABIS[0]);
        }

        // If there's a mismatch between the abi-override in the package setting
        // and the abiOverride specified for the install. Warn about this because we
        // would've already compiled the app without taking the package setting into
        // account.
        if ((scanFlags & SCAN_NO_DEX) == 0 && (scanFlags & SCAN_NEW_INSTALL) != 0) {
            if (cpuAbiOverride == null && parsedPackage.getPackageName() != null) {
                Slog.w(TAG, "Ignoring persisted ABI override " + cpuAbiOverride +
                        " for package " + parsedPackage.getPackageName());
            }
        }

        pkgSetting.primaryCpuAbiString = parsedPackage.getPrimaryCpuAbi();
        pkgSetting.secondaryCpuAbiString = parsedPackage.getSecondaryCpuAbi();
        pkgSetting.cpuAbiOverrideString = cpuAbiOverride;

        // Copy the derived override back to the parsed package, so that we can
        // update the package settings accordingly.
        parsedPackage.setCpuAbiOverride(cpuAbiOverride);

        if (DEBUG_ABI_SELECTION) {
            Slog.d(TAG, "Resolved nativeLibraryRoot for " + parsedPackage.getPackageName()
                    + " to root=" + parsedPackage.getNativeLibraryRootDir() + ", isa="
                    + parsedPackage.isNativeLibraryRootRequiresIsa());
        }

        // Push the derived path down into PackageSettings so we know what to
        // clean up at uninstall time.
        pkgSetting.legacyNativeLibraryPathString = parsedPackage.getNativeLibraryRootDir();

        if (DEBUG_ABI_SELECTION) {
            Log.d(TAG, "Abis for package[" + parsedPackage.getPackageName() + "] are" +
                    " primary=" + parsedPackage.getPrimaryCpuAbi() +
                    " secondary=" + parsedPackage.getSecondaryCpuAbi());
        }

        if ((scanFlags & SCAN_BOOTING) == 0 && pkgSetting.sharedUser != null) {
            // We don't do this here during boot because we can do it all
            // at once after scanning all existing packages.
            //
            // We also do this *before* we perform dexopt on this package, so that
            // we can avoid redundant dexopts, and also to make sure we've got the
            // code and package path correct.
            changedAbiCodePath = applyAdjustedAbiToSharedUser(pkgSetting.sharedUser, parsedPackage,
                    packageAbiHelper.getAdjustedAbiForSharedUser(
                            pkgSetting.sharedUser.packages, parsedPackage));
        }

        parsedPackage.setFactoryTest(isUnderFactoryTest && parsedPackage.getRequestedPermissions()
                .contains(android.Manifest.permission.FACTORY_TEST));

        if (parsedPackage.isSystem()) {
            pkgSetting.setIsOrphaned(true);
        }

        // Take care of first install / last update times.
        final long scanFileTime = getLastModifiedTime(parsedPackage);
        if (currentTime != 0) {
            if (pkgSetting.firstInstallTime == 0) {
                pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = currentTime;
            } else if ((scanFlags & SCAN_UPDATE_TIME) != 0) {
                pkgSetting.lastUpdateTime = currentTime;
            }
        } else if (pkgSetting.firstInstallTime == 0) {
            // We need *something*.  Take time time stamp of the file.
            pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = scanFileTime;
        } else if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0) {
            if (scanFileTime != pkgSetting.timeStamp) {
                // A package on the system image has changed; consider this
                // to be an update.
                pkgSetting.lastUpdateTime = scanFileTime;
            }
        }
        pkgSetting.setTimeStamp(scanFileTime);
        // TODO(b/135203078): Remove, move to constructor
        parsedPackage.setPackageSettingCallback(pkgSetting);
        pkgSetting.pkgFlags = parsedPackage.getFlags();
        if (parsedPackage.getLongVersionCode() != pkgSetting.versionCode) {
            pkgSetting.versionCode = parsedPackage.getLongVersionCode();
        }
        // Update volume if needed
        final String volumeUuid = parsedPackage.getApplicationInfoVolumeUuid();
        if (!Objects.equals(volumeUuid, pkgSetting.volumeUuid)) {
            Slog.i(PackageManagerService.TAG,
                    "Update" + (pkgSetting.isSystem() ? " system" : "")
                    + " package " + parsedPackage.getPackageName()
                    + " volume from " + pkgSetting.volumeUuid
                    + " to " + volumeUuid);
            pkgSetting.volumeUuid = volumeUuid;
        }

        SharedLibraryInfo staticSharedLibraryInfo = null;
        if (!TextUtils.isEmpty(parsedPackage.getStaticSharedLibName())) {
            staticSharedLibraryInfo = SharedLibraryInfo.createForStatic(parsedPackage);
        }
        List<SharedLibraryInfo> dynamicSharedLibraryInfos = null;
        if (!ArrayUtils.isEmpty(parsedPackage.getLibraryNames())) {
            dynamicSharedLibraryInfos = new ArrayList<>(parsedPackage.getLibraryNames().size());
            for (String name : parsedPackage.getLibraryNames()) {
                dynamicSharedLibraryInfos.add(
                        SharedLibraryInfo.createForDynamic(parsedPackage, name));
            }
        }

        return new ScanResult(request, true, pkgSetting, changedAbiCodePath,
                !createNewPackage /* existingSettingCopied */, staticSharedLibraryInfo,
                dynamicSharedLibraryInfos);
    }

    /**
     * Returns {@code true} if the given file contains code. Otherwise {@code false}.
     */
    private static boolean apkHasCode(String fileName) {
        StrictJarFile jarFile = null;
        try {
            jarFile = new StrictJarFile(fileName,
                    false /*verify*/, false /*signatureSchemeRollbackProtectionsEnforced*/);
            return jarFile.findEntry("classes.dex") != null;
        } catch (IOException ignore) {
        } finally {
            try {
                if (jarFile != null) {
                    jarFile.close();
                }
            } catch (IOException ignore) {}
        }
        return false;
    }

    /**
     * Enforces code policy for the package. This ensures that if an APK has
     * declared hasCode="true" in its manifest that the APK actually contains
     * code.
     *
     * @throws PackageManagerException If bytecode could not be found when it should exist
     */
    private static void assertCodePolicy(AndroidPackage pkg)
            throws PackageManagerException {
        final boolean shouldHaveCode = (pkg.getFlags() & ApplicationInfo.FLAG_HAS_CODE) != 0;
        if (shouldHaveCode && !apkHasCode(pkg.getBaseCodePath())) {
            throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
                    "Package " + pkg.getBaseCodePath() + " code is missing");
        }

        if (!ArrayUtils.isEmpty(pkg.getSplitCodePaths())) {
            for (int i = 0; i < pkg.getSplitCodePaths().length; i++) {
                final boolean splitShouldHaveCode =
                        (pkg.getSplitFlags()[i] & ApplicationInfo.FLAG_HAS_CODE) != 0;
                if (splitShouldHaveCode && !apkHasCode(pkg.getSplitCodePaths()[i])) {
                    throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
                            "Package " + pkg.getSplitCodePaths()[i] + " code is missing");
                }
            }
        }
    }

    /**
     * Applies policy to the parsed package based upon the given policy flags.
     * Ensures the package is in a good state.
     * <p>
     * Implementation detail: This method must NOT have any side effect. It would
     * ideally be static, but, it requires locks to read system state.
     */
    private static void applyPolicy(ParsedPackage parsedPackage, final @ParseFlags int parseFlags,
            final @ScanFlags int scanFlags, AndroidPackage platformPkg) {
        if ((scanFlags & SCAN_AS_SYSTEM) != 0) {
            parsedPackage.setSystem(true);
            // TODO(b/135203078): Can this be done in PackageParser? Or just inferred when the flag
            //  is set during parse.
            if (parsedPackage.isDirectBootAware()) {
                parsedPackage.setAllComponentsDirectBootAware(true);
            }
            if (compressedFileExists(parsedPackage.getCodePath())) {
                parsedPackage.setIsStub(true);
            }
        } else {
            parsedPackage
                    // non system apps can't be flagged as core
                    .setCoreApp(false)
                    // clear flags not applicable to regular apps
                    .setPersistent(false)
                    .setDefaultToDeviceProtectedStorage(false)
                    .setDirectBootAware(false)
                    // non system apps can't have permission priority
                    .capPermissionPriorities();
        }
        if ((scanFlags & SCAN_AS_PRIVILEGED) == 0) {
            parsedPackage
                    .clearProtectedBroadcasts()
                    .markNotActivitiesAsNotExportedIfSingleUser();
        }

        parsedPackage.setPrivileged((scanFlags & SCAN_AS_PRIVILEGED) != 0)
                .setOem((scanFlags & SCAN_AS_OEM) != 0)
                .setVendor((scanFlags & SCAN_AS_VENDOR) != 0)
                .setProduct((scanFlags & SCAN_AS_PRODUCT) != 0)
                .setSystemExt((scanFlags & SCAN_AS_SYSTEM_EXT) != 0)
                .setOdm((scanFlags & SCAN_AS_ODM) != 0);

        // Check if the package is signed with the same key as the platform package.
        parsedPackage.setSignedWithPlatformKey(
                (PLATFORM_PACKAGE_NAME.equals(parsedPackage.getPackageName())
                        || (platformPkg != null && compareSignatures(
                        platformPkg.getSigningDetails().signatures,
                        parsedPackage.getSigningDetails().signatures
                ) == PackageManager.SIGNATURE_MATCH))
        );

        if (!isSystemApp(parsedPackage)) {
            // Only system apps can use these features.
            parsedPackage.clearOriginalPackages()
                    .setRealPackage(null)
                    .clearAdoptPermissions();
        }

        PackageBackwardCompatibility.modifySharedLibraries(parsedPackage);
    }

    private static @NonNull <T> T assertNotNull(@Nullable T object, String message)
            throws PackageManagerException {
        if (object == null) {
            throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR, message);
        }
        return object;
    }

    /**
     * Asserts the parsed package is valid according to the given policy. If the
     * package is invalid, for whatever reason, throws {@link PackageManagerException}.
     * <p>
     * Implementation detail: This method must NOT have any side effects. It would
     * ideally be static, but, it requires locks to read system state.
     *
     * @throws PackageManagerException If the package fails any of the validation checks
     */
    private void assertPackageIsValid(AndroidPackage pkg, final @ParseFlags int parseFlags,
            final @ScanFlags int scanFlags)
                    throws PackageManagerException {
        if ((parseFlags & PackageParser.PARSE_ENFORCE_CODE) != 0) {
            assertCodePolicy(pkg);
        }

        if (pkg.getAppInfoCodePath() == null ||
                pkg.getAppInfoResourcePath() == null) {
            // Bail out. The resource and code paths haven't been set.
            throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
                    "Code and resource paths haven't been set correctly");
        }

        // Check that there is an APEX package with the same name only during install/first boot
        // after OTA.
        final boolean isUserInstall = (scanFlags & SCAN_BOOTING) == 0;
        final boolean isFirstBootOrUpgrade = (scanFlags & SCAN_FIRST_BOOT_OR_UPGRADE) != 0;
        if ((isUserInstall || isFirstBootOrUpgrade)
                && mApexManager.isApexPackage(pkg.getPackageName())) {
            throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE,
                    pkg.getPackageName()
                            + " is an APEX package and can't be installed as an APK.");
        }

        // Make sure we're not adding any bogus keyset info
        final KeySetManagerService ksms = mSettings.mKeySetManagerService;
        ksms.assertScannedPackageValid(pkg);

        synchronized (mLock) {
            // The special "android" package can only be defined once
            if (pkg.getPackageName().equals("android")) {
                if (mAndroidApplication != null) {
                    Slog.w(TAG, "*************************************************");
                    Slog.w(TAG, "Core android package being redefined.  Skipping.");
                    Slog.w(TAG, " codePath=" + pkg.getCodePath());
                    Slog.w(TAG, "*************************************************");
                    throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE,
                            "Core android package being redefined.  Skipping.");
                }
            }

            // A package name must be unique; don't allow duplicates
            if ((scanFlags & SCAN_NEW_INSTALL) == 0
                    && mPackages.containsKey(pkg.getPackageName())) {
                throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE,
                        "Application package " + pkg.getPackageName()
                        + " already installed.  Skipping duplicate.");
            }

            if (pkg.isStaticSharedLibrary()) {
                // Static libs have a synthetic package name containing the version
                // but we still want the base name to be unique.
                if ((scanFlags & SCAN_NEW_INSTALL) == 0
                        && mPackages.containsKey(pkg.getManifestPackageName())) {
                    throw new PackageManagerException(
                            "Duplicate static shared lib provider package");
                }

                // Static shared libraries should have at least O target SDK
                if (pkg.getTargetSdkVersion() < Build.VERSION_CODES.O) {
                    throw new PackageManagerException(
                            "Packages declaring static-shared libs must target O SDK or higher");
                }

                // Package declaring static a shared lib cannot be instant apps
                if ((scanFlags & SCAN_AS_INSTANT_APP) != 0) {
                    throw new PackageManagerException(
                            "Packages declaring static-shared libs cannot be instant apps");
                }

                // Package declaring static a shared lib cannot be renamed since the package
                // name is synthetic and apps can't code around package manager internals.
                if (!ArrayUtils.isEmpty(pkg.getOriginalPackages())) {
                    throw new PackageManagerException(
                            "Packages declaring static-shared libs cannot be renamed");
                }

                // Package declaring static a shared lib cannot declare dynamic libs
                if (!ArrayUtils.isEmpty(pkg.getLibraryNames())) {
                    throw new PackageManagerException(
                            "Packages declaring static-shared libs cannot declare dynamic libs");
                }

                // Package declaring static a shared lib cannot declare shared users
                if (pkg.getSharedUserId() != null) {
                    throw new PackageManagerException(
                            "Packages declaring static-shared libs cannot declare shared users");
                }

                // Static shared libs cannot declare activities
                if (pkg.getActivities() != null && !pkg.getActivities().isEmpty()) {
                    throw new PackageManagerException(
                            "Static shared libs cannot declare activities");
                }

                // Static shared libs cannot declare services
                if (pkg.getServices() != null && !pkg.getServices().isEmpty()) {
                    throw new PackageManagerException(
                            "Static shared libs cannot declare services");
                }

                // Static shared libs cannot declare providers
                if (pkg.getProviders() != null && !pkg.getProviders().isEmpty()) {
                    throw new PackageManagerException(
                            "Static shared libs cannot declare content providers");
                }

                // Static shared libs cannot declare receivers
                if (pkg.getReceivers() != null && !pkg.getReceivers().isEmpty()) {
                    throw new PackageManagerException(
                            "Static shared libs cannot declare broadcast receivers");
                }

                // Static shared libs cannot declare permission groups
                if (pkg.getPermissionGroups() != null && !pkg.getPermissionGroups().isEmpty()) {
                    throw new PackageManagerException(
                            "Static shared libs cannot declare permission groups");
                }

                // Static shared libs cannot declare permissions
                if (pkg.getPermissions() != null && !pkg.getPermissions().isEmpty()) {
                    throw new PackageManagerException(
                            "Static shared libs cannot declare permissions");
                }

                // Static shared libs cannot declare protected broadcasts
                if (pkg.getProtectedBroadcasts() != null) {
                    throw new PackageManagerException(
                            "Static shared libs cannot declare protected broadcasts");
                }

                // Static shared libs cannot be overlay targets
                if (pkg.getOverlayTarget() != null) {
                    throw new PackageManagerException(
                            "Static shared libs cannot be overlay targets");
                }

                // The version codes must be ordered as lib versions
                long minVersionCode = Long.MIN_VALUE;
                long maxVersionCode = Long.MAX_VALUE;

                LongSparseArray<SharedLibraryInfo> versionedLib = mSharedLibraries.get(
                        pkg.getStaticSharedLibName());
                if (versionedLib != null) {
                    final int versionCount = versionedLib.size();
                    for (int i = 0; i < versionCount; i++) {
                        SharedLibraryInfo libInfo = versionedLib.valueAt(i);
                        final long libVersionCode = libInfo.getDeclaringPackage()
                                .getLongVersionCode();
                        if (libInfo.getLongVersion() < pkg.getStaticSharedLibVersion()) {
                            minVersionCode = Math.max(minVersionCode, libVersionCode + 1);
                        } else if (libInfo.getLongVersion()
                                > pkg.getStaticSharedLibVersion()) {
                            maxVersionCode = Math.min(maxVersionCode, libVersionCode - 1);
                        } else {
                            minVersionCode = maxVersionCode = libVersionCode;
                            break;
                        }
                    }
                }
                if (pkg.getLongVersionCode() < minVersionCode
                        || pkg.getLongVersionCode() > maxVersionCode) {
                    throw new PackageManagerException("Static shared"
                            + " lib version codes must be ordered as lib versions");
                }
            }

            // If we're only installing presumed-existing packages, require that the
            // scanned APK is both already known and at the path previously established
            // for it.  Previously unknown packages we pick up normally, but if we have an
            // a priori expectation about this package's install presence, enforce it.
            // With a singular exception for new system packages. When an OTA contains
            // a new system package, we allow the codepath to change from a system location
            // to the user-installed location. If we don't allow this change, any newer,
            // user-installed version of the application will be ignored.
            if ((scanFlags & SCAN_REQUIRE_KNOWN) != 0) {
                if (mExpectingBetter.containsKey(pkg.getPackageName())) {
                    logCriticalInfo(Log.WARN,
                            "Relax SCAN_REQUIRE_KNOWN requirement for package "
                                    + pkg.getPackageName());
                } else {
                    PackageSetting known = mSettings.getPackageLPr(pkg.getPackageName());
                    if (known != null) {
                        if (DEBUG_PACKAGE_SCANNING) {
                            Log.d(TAG, "Examining " + pkg.getCodePath()
                                    + " and requiring known paths " + known.codePathString
                                    + " & " + known.resourcePathString);
                        }
                        if (!pkg.getAppInfoCodePath().equals(known.codePathString)
                                || !pkg.getAppInfoResourcePath().equals(
                                        known.resourcePathString)) {
                            throw new PackageManagerException(INSTALL_FAILED_PACKAGE_CHANGED,
                                    "Application package " + pkg.getPackageName()
                                    + " found at " + pkg.getAppInfoCodePath()
                                    + " but expected at " + known.codePathString
                                    + "; ignoring.");
                        }
                    } else {
                        throw new PackageManagerException(INSTALL_FAILED_INVALID_INSTALL_LOCATION,
                                "Application package " + pkg.getPackageName()
                                + " not found; ignoring.");
                    }
                }
            }

            // Verify that this new package doesn't have any content providers
            // that conflict with existing packages.  Only do this if the
            // package isn't already installed, since we don't want to break
            // things that are installed.
            if ((scanFlags & SCAN_NEW_INSTALL) != 0) {
                mComponentResolver.assertProvidersNotDefined(pkg);
            }

            // Verify that packages sharing a user with a privileged app are marked as privileged.
            if (!pkg.isPrivileged() && (pkg.getSharedUserId() != null)) {
                SharedUserSetting sharedUserSetting = null;
                try {
                    sharedUserSetting = mSettings.getSharedUserLPw(pkg.getSharedUserId(),
                            0, 0, false);
                } catch (PackageManagerException ignore) {
                }
                if (sharedUserSetting != null && sharedUserSetting.isPrivileged()) {
                    // Exempt SharedUsers signed with the platform key.
                    PackageSetting platformPkgSetting = mSettings.mPackages.get("android");
                    if ((platformPkgSetting.signatures.mSigningDetails
                            != PackageParser.SigningDetails.UNKNOWN)
                            && (compareSignatures(
                                    platformPkgSetting.signatures.mSigningDetails.signatures,
                            pkg.getSigningDetails().signatures)
                                            != PackageManager.SIGNATURE_MATCH)) {
                        throw new PackageManagerException("Apps that share a user with a " +
                                "privileged app must themselves be marked as privileged. " +
                                pkg.getPackageName() + " shares privileged user " +
                                pkg.getSharedUserId() + ".");
                    }
                }
            }

            // Apply policies specific for runtime resource overlays (RROs).
            if (pkg.getOverlayTarget() != null) {
                // System overlays have some restrictions on their use of the 'static' state.
                if ((scanFlags & SCAN_AS_SYSTEM) != 0) {
                    // We are scanning a system overlay. This can be the first scan of the
                    // system/vendor/oem partition, or an update to the system overlay.
                    if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
                        // This must be an update to a system overlay.
                        final PackageSetting previousPkg = assertNotNull(
                                mSettings.getPackageLPr(pkg.getPackageName()),
                                "previous package state not present");

                        // previousPkg.pkg may be null: the package will be not be scanned if the
                        // package manager knows there is a newer version on /data.
                        // TODO[b/79435695]: Find a better way to keep track of the "static"
                        // property for RROs instead of having to parse packages on /system
                        AndroidPackage ppkg = previousPkg.pkg;
                        if (ppkg == null) {
                            try {
                                final PackageParser pp = new PackageParser();
                                // TODO(b/135203078): Do we really need to parse here? Maybe use
                                //  a shortened path?
                                ppkg = pp.parseParsedPackage(previousPkg.codePath,
                                        parseFlags | PackageParser.PARSE_IS_SYSTEM_DIR,
                                        false)
                                        .hideAsFinal();
                            } catch (PackageParserException e) {
                                Slog.w(TAG, "failed to parse " + previousPkg.codePath, e);
                            }
                        }

                        // Static overlays cannot be updated.
                        if (ppkg != null && ppkg.isOverlayIsStatic()) {
                            throw new PackageManagerException("Overlay "
                                    + pkg.getPackageName()
                                    + " is static and cannot be upgraded.");
                        // Non-static overlays cannot be converted to static overlays.
                        } else if (pkg.isOverlayIsStatic()) {
                            throw new PackageManagerException("Overlay "
                                    + pkg.getPackageName()
                                    + " cannot be upgraded into a static overlay.");
                        }
                    }
                } else {
                    // The overlay is a non-system overlay. Non-system overlays cannot be static.
                    if (pkg.isOverlayIsStatic()) {
                        throw new PackageManagerException("Overlay "
                                + pkg.getPackageName()
                                + " is static but not pre-installed.");
                    }

                    // A non-preloaded overlay packages must have targetSdkVersion >= Q, or be
                    // signed with the platform certificate. Check this in increasing order of
                    // computational cost.
                    if (pkg.getTargetSdkVersion() < Build.VERSION_CODES.Q) {
                        final PackageSetting platformPkgSetting =
                                mSettings.getPackageLPr("android");
                        if ((platformPkgSetting.signatures.mSigningDetails
                                    != PackageParser.SigningDetails.UNKNOWN)
                                && (compareSignatures(
                                        platformPkgSetting.signatures.mSigningDetails.signatures,
                                pkg.getSigningDetails().signatures)
                                    != PackageManager.SIGNATURE_MATCH)) {
                            throw new PackageManagerException("Overlay "
                                    + pkg.getPackageName()
                                    + " must target Q or later, "
                                    + "or be signed with the platform certificate");
                        }
                    }

                    // A non-preloaded overlay package, without <overlay android:targetName>, will
                    // only be used if it is signed with the same certificate as its target. If the
                    // target is already installed, check this here to augment the last line of
                    // defence which is OMS.
                    if (pkg.getOverlayTargetName() == null) {
                        final PackageSetting targetPkgSetting =
                                mSettings.getPackageLPr(pkg.getOverlayTarget());
                        if (targetPkgSetting != null) {
                            if ((targetPkgSetting.signatures.mSigningDetails
                                        != PackageParser.SigningDetails.UNKNOWN)
                                    && (compareSignatures(
                                            targetPkgSetting.signatures.mSigningDetails.signatures,
                                    pkg.getSigningDetails().signatures)
                                        != PackageManager.SIGNATURE_MATCH)) {
                                throw new PackageManagerException("Overlay "
                                        + pkg.getPackageName() + " and target "
                                        + pkg.getOverlayTarget() + " signed with"
                                        + " different certificates, and the overlay lacks"
                                        + " <overlay android:targetName>");
                            }
                        }
                    }
                }
            }
        }
    }

    @GuardedBy("mLock")
    private boolean addBuiltInSharedLibraryLocked(String path, String name) {
        if (nonStaticSharedLibExistsLocked(name)) {
            return false;
        }

        SharedLibraryInfo libraryInfo = new SharedLibraryInfo(path, null, null, name,
                (long) SharedLibraryInfo.VERSION_UNDEFINED, SharedLibraryInfo.TYPE_BUILTIN,
                new VersionedPackage(PLATFORM_PACKAGE_NAME, (long) 0),
                null, null);

        commitSharedLibraryInfoLocked(libraryInfo);
        return true;
    }

    @GuardedBy("mLock")
    private boolean nonStaticSharedLibExistsLocked(String name) {
        return sharedLibExists(name, SharedLibraryInfo.VERSION_UNDEFINED, mSharedLibraries);
    }

    private static boolean sharedLibExists(final String name, final long version,
            Map<String, LongSparseArray<SharedLibraryInfo>> librarySource) {
        LongSparseArray<SharedLibraryInfo> versionedLib = librarySource.get(name);
        if (versionedLib != null && versionedLib.indexOfKey(version) >= 0) {
            return true;
        }
        return false;
    }

    @GuardedBy("mLock")
    private void commitSharedLibraryInfoLocked(SharedLibraryInfo libraryInfo) {
        final String name = libraryInfo.getName();
        LongSparseArray<SharedLibraryInfo> versionedLib = mSharedLibraries.get(name);
        if (versionedLib == null) {
            versionedLib = new LongSparseArray<>();
            mSharedLibraries.put(name, versionedLib);
        }
        final String declaringPackageName = libraryInfo.getDeclaringPackage().getPackageName();
        if (libraryInfo.getType() == SharedLibraryInfo.TYPE_STATIC) {
            mStaticLibsByDeclaringPackage.put(declaringPackageName, versionedLib);
        }
        versionedLib.put(libraryInfo.getLongVersion(), libraryInfo);
    }

    private boolean removeSharedLibraryLPw(String name, long version) {
        LongSparseArray<SharedLibraryInfo> versionedLib = mSharedLibraries.get(name);
        if (versionedLib == null) {
            return false;
        }
        final int libIdx = versionedLib.indexOfKey(version);
        if (libIdx < 0) {
            return false;
        }
        SharedLibraryInfo libraryInfo = versionedLib.valueAt(libIdx);
        versionedLib.remove(version);
        if (versionedLib.size() <= 0) {
            mSharedLibraries.remove(name);
            if (libraryInfo.getType() == SharedLibraryInfo.TYPE_STATIC) {
                mStaticLibsByDeclaringPackage.remove(libraryInfo.getDeclaringPackage()
                        .getPackageName());
            }
        }
        return true;
    }

    /**
     * Adds a scanned package to the system. When this method is finished, the package will
     * be available for query, resolution, etc...
     */
    private void commitPackageSettings(AndroidPackage pkg,
            @Nullable AndroidPackage oldPkg, PackageSetting pkgSetting,
            final @ScanFlags int scanFlags, boolean chatty, ReconciledPackage reconciledPkg) {
        final String pkgName = pkg.getPackageName();
        if (mCustomResolverComponentName != null &&
                mCustomResolverComponentName.getPackageName().equals(pkg.getPackageName())) {
            setUpCustomResolverActivity(pkg);
        }

        if (pkg.getPackageName().equals("android")) {
            synchronized (mLock) {
                // Set up information for our fall-back user intent resolution activity.
                mPlatformPackage = pkg;
                mAndroidApplication = pkg.toAppInfoWithoutState();
                if (!mResolverReplaced) {
                    mResolveActivity.applicationInfo = mAndroidApplication;
                    mResolveActivity.name = ResolverActivity.class.getName();
                    mResolveActivity.packageName = mAndroidApplication.packageName;
                    mResolveActivity.processName = "system:ui";
                    mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
                    mResolveActivity.documentLaunchMode = ActivityInfo.DOCUMENT_LAUNCH_NEVER;
                    mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS;
                    mResolveActivity.theme = R.style.Theme_Material_Dialog_Alert;
                    mResolveActivity.exported = true;
                    mResolveActivity.enabled = true;
                    mResolveActivity.resizeMode = ActivityInfo.RESIZE_MODE_RESIZEABLE;
                    mResolveActivity.configChanges = ActivityInfo.CONFIG_SCREEN_SIZE
                            | ActivityInfo.CONFIG_SMALLEST_SCREEN_SIZE
                            | ActivityInfo.CONFIG_SCREEN_LAYOUT
                            | ActivityInfo.CONFIG_ORIENTATION
                            | ActivityInfo.CONFIG_KEYBOARD
                            | ActivityInfo.CONFIG_KEYBOARD_HIDDEN;
                    mResolveInfo.activityInfo = mResolveActivity;
                    mResolveInfo.priority = 0;
                    mResolveInfo.preferredOrder = 0;
                    mResolveInfo.match = 0;
                    mResolveComponentName = new ComponentName(
                            mAndroidApplication.packageName, mResolveActivity.name);
                }
            }
        }

        ArrayList<AndroidPackage> clientLibPkgs = null;
        // writer
        synchronized (mLock) {
            if (!ArrayUtils.isEmpty(reconciledPkg.allowedSharedLibraryInfos)) {
                for (SharedLibraryInfo info : reconciledPkg.allowedSharedLibraryInfos) {
                    commitSharedLibraryInfoLocked(info);
                }
                final Map<String, AndroidPackage> combinedSigningDetails =
                        reconciledPkg.getCombinedAvailablePackages();
                try {
                    // Shared libraries for the package need to be updated.
                    updateSharedLibrariesLocked(pkg, null, combinedSigningDetails);
                } catch (PackageManagerException e) {
                    Slog.e(TAG, "updateSharedLibrariesLPr failed: ", e);
                }
                // Update all applications that use this library. Skip when booting
                // since this will be done after all packages are scaned.
                if ((scanFlags & SCAN_BOOTING) == 0) {
                    clientLibPkgs = updateAllSharedLibrariesLocked(pkg, combinedSigningDetails);
                }
            }
        }
        if (reconciledPkg.installResult != null) {
            reconciledPkg.installResult.libraryConsumers = clientLibPkgs;
        }

        if ((scanFlags & SCAN_BOOTING) != 0) {
            // No apps can run during boot scan, so they don't need to be frozen
        } else if ((scanFlags & SCAN_DONT_KILL_APP) != 0) {
            // Caller asked to not kill app, so it's probably not frozen
        } else if ((scanFlags & SCAN_IGNORE_FROZEN) != 0) {
            // Caller asked us to ignore frozen check for some reason; they
            // probably didn't know the package name
        } else {
            // We're doing major surgery on this package, so it better be frozen
            // right now to keep it from launching
            checkPackageFrozen(pkgName);
        }

        // Also need to kill any apps that are dependent on the library.
        if (clientLibPkgs != null) {
            for (int i=0; i<clientLibPkgs.size(); i++) {
                AndroidPackage clientPkg = clientLibPkgs.get(i);
                killApplication(clientPkg.getAppInfoPackageName(),
                        clientPkg.getUid(), "update lib");
            }
        }

        // writer
        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "updateSettings");

        synchronized (mLock) {
            // We don't expect installation to fail beyond this point

            // Add the new setting to mSettings
            mSettings.insertPackageSettingLPw(pkgSetting, pkg);
            // Add the new setting to mPackages
            mPackages.put(pkg.getAppInfoPackageName(), pkg);

            // Add the package's KeySets to the global KeySetManagerService
            KeySetManagerService ksms = mSettings.mKeySetManagerService;
            ksms.addScannedPackageLPw(pkg);

            mComponentResolver.addAllComponents(pkg, chatty);
            mAppsFilter.addPackage(pkgSetting, mSettings.mPackages);

            // Don't allow ephemeral applications to define new permissions groups.
            if ((scanFlags & SCAN_AS_INSTANT_APP) != 0) {
                Slog.w(TAG, "Permission groups from package " + pkg.getPackageName()
                        + " ignored: instant apps cannot define new permission groups.");
            } else {
                mPermissionManager.addAllPermissionGroups(pkg, chatty);
            }

            // Don't allow ephemeral applications to define new permissions.
            if ((scanFlags & SCAN_AS_INSTANT_APP) != 0) {
                Slog.w(TAG, "Permissions from package " + pkg.getPackageName()
                        + " ignored: instant apps cannot define new permissions.");
            } else {
                mPermissionManager.addAllPermissions(pkg, chatty);
            }

            int collectionSize = ArrayUtils.size(pkg.getInstrumentations());
            StringBuilder r = null;
            int i;
            for (i = 0; i < collectionSize; i++) {
                ParsedInstrumentation a = pkg.getInstrumentations().get(i);
                a.setPackageName(pkg.getPackageName());
                mInstrumentation.put(a.getComponentName(), a);
                if (chatty) {
                    if (r == null) {
                        r = new StringBuilder(256);
                    } else {
                        r.append(' ');
                    }
                    r.append(a.getName());
                }
            }
            if (r != null) {
                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Instrumentation: " + r);
            }

            if (pkg.getProtectedBroadcasts() != null) {
                synchronized (mProtectedBroadcasts) {
                    mProtectedBroadcasts.addAll(pkg.getProtectedBroadcasts());
                }
            }

            if (oldPkg != null) {
                // We need to call revokeRuntimePermissionsIfGroupChanged async as permission
                // revoke callbacks from this method might need to kill apps which need the
                // mPackages lock on a different thread. This would dead lock.
                //
                // Hence create a copy of all package names and pass it into
                // revokeRuntimePermissionsIfGroupChanged. Only for those permissions might get
                // revoked. If a new package is added before the async code runs the permission
                // won't be granted yet, hence new packages are no problem.
                final ArrayList<String> allPackageNames = new ArrayList<>(mPackages.keySet());

                AsyncTask.execute(() ->
                        mPermissionManager.revokeRuntimePermissionsIfGroupChanged(pkg, oldPkg,
                                allPackageNames));
            }
        }

        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
    }

    private void setUpCustomResolverActivity(AndroidPackage pkg) {
        synchronized (mLock) {
            mResolverReplaced = true;
            // Set up information for custom user intent resolution activity.
            mResolveActivity.applicationInfo = pkg.toAppInfoWithoutState();
            mResolveActivity.name = mCustomResolverComponentName.getClassName();
            mResolveActivity.packageName = pkg.getAppInfoPackageName();
            mResolveActivity.processName = pkg.getAppInfoProcessName();
            mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
            mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS |
                    ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS;
            mResolveActivity.theme = 0;
            mResolveActivity.exported = true;
            mResolveActivity.enabled = true;
            mResolveInfo.activityInfo = mResolveActivity;
            mResolveInfo.priority = 0;
            mResolveInfo.preferredOrder = 0;
            mResolveInfo.match = 0;
            mResolveComponentName = mCustomResolverComponentName;
            Slog.i(TAG, "Replacing default ResolverActivity with custom activity: " +
                    mResolveComponentName);
        }
    }

    private void setUpInstantAppInstallerActivityLP(ActivityInfo installerActivity) {
        if (installerActivity == null) {
            if (DEBUG_INSTANT) {
                Slog.d(TAG, "Clear ephemeral installer activity");
            }
            mInstantAppInstallerActivity = null;
            return;
        }

        if (DEBUG_INSTANT) {
            Slog.d(TAG, "Set ephemeral installer activity: "
                    + installerActivity.getComponentName());
        }
        // Set up information for ephemeral installer activity
        mInstantAppInstallerActivity = installerActivity;
        mInstantAppInstallerActivity.flags |= ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS
                | ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS;
        mInstantAppInstallerActivity.exported = true;
        mInstantAppInstallerActivity.enabled = true;
        mInstantAppInstallerInfo.activityInfo = mInstantAppInstallerActivity;
        mInstantAppInstallerInfo.priority = 1;
        mInstantAppInstallerInfo.preferredOrder = 1;
        mInstantAppInstallerInfo.isDefault = true;
        mInstantAppInstallerInfo.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
                | IntentFilter.MATCH_ADJUSTMENT_NORMAL;
    }

    private void killApplication(String pkgName, @AppIdInt int appId, String reason) {
        killApplication(pkgName, appId, UserHandle.USER_ALL, reason);
    }

    private void killApplication(String pkgName, @AppIdInt int appId,
            @UserIdInt int userId, String reason) {
        // Request the ActivityManager to kill the process(only for existing packages)
        // so that we do not end up in a confused state while the user is still using the older
        // version of the application while the new one gets installed.
        final long token = Binder.clearCallingIdentity();
        try {
            IActivityManager am = ActivityManager.getService();
            if (am != null) {
                try {
                    am.killApplication(pkgName, appId, userId, reason);
                } catch (RemoteException e) {
                }
            }
        } finally {
            Binder.restoreCallingIdentity(token);
        }
    }

    private void removePackageLI(AndroidPackage pkg, boolean chatty) {
        // Remove the parent package setting
        PackageSetting ps = getPackageSetting(pkg.getPackageName());
        if (ps != null) {
            removePackageLI(ps.name, chatty);
        } else if (DEBUG_REMOVE && chatty) {
            Log.d(TAG, "Not removing package " + pkg.getPackageName() + "; mExtras == null");
        }
    }

    void removePackageLI(String packageName, boolean chatty) {
        if (DEBUG_INSTALL) {
            if (chatty)
                Log.d(TAG, "Removing package " + packageName);
        }

        // writer
        synchronized (mLock) {
            final AndroidPackage removedPackage = mPackages.remove(packageName);
            if (removedPackage != null) {
                cleanPackageDataStructuresLILPw(removedPackage, chatty);
            }
        }
    }

    void cleanPackageDataStructuresLILPw(AndroidPackage pkg, boolean chatty) {
        mComponentResolver.removeAllComponents(pkg, chatty);
        mAppsFilter.removePackage(getPackageSetting(pkg.getPackageName()),
                mInjector.getUserManagerInternal().getUserIds(), mSettings.mPackages);
        mPermissionManager.removeAllPermissions(pkg, chatty);

        final int instrumentationSize = ArrayUtils.size(pkg.getInstrumentations());
        StringBuilder r = null;
        int i;
        for (i = 0; i < instrumentationSize; i++) {
            ParsedInstrumentation a = pkg.getInstrumentations().get(i);
            mInstrumentation.remove(a.getComponentName());
            if (DEBUG_REMOVE && chatty) {
                if (r == null) {
                    r = new StringBuilder(256);
                } else {
                    r.append(' ');
                }
                r.append(a.getName());
            }
        }
        if (r != null) {
            if (DEBUG_REMOVE) Log.d(TAG, "  Instrumentation: " + r);
        }

        r = null;
        if ((pkg.getFlags() & ApplicationInfo.FLAG_SYSTEM) != 0) {
            // Only system apps can hold shared libraries.
            if (pkg.getLibraryNames() != null) {
                final int libraryNamesSize = pkg.getLibraryNames().size();
                for (i = 0; i < libraryNamesSize; i++) {
                    String name = pkg.getLibraryNames().get(i);
                    if (removeSharedLibraryLPw(name, 0)) {
                        if (DEBUG_REMOVE && chatty) {
                            if (r == null) {
                                r = new StringBuilder(256);
                            } else {
                                r.append(' ');
                            }
                            r.append(name);
                        }
                    }
                }
            }
        }

        r = null;

        // Any package can hold static shared libraries.
        if (pkg.getStaticSharedLibName() != null) {
            if (removeSharedLibraryLPw(pkg.getStaticSharedLibName(),
                    pkg.getStaticSharedLibVersion())) {
                if (DEBUG_REMOVE && chatty) {
                    if (r == null) {
                        r = new StringBuilder(256);
                    } else {
                        r.append(' ');
                    }
                    r.append(pkg.getStaticSharedLibName());
                }
            }
        }

        if (r != null) {
            if (DEBUG_REMOVE) Log.d(TAG, "  Libraries: " + r);
        }
    }

    @Override
    public void sendPackageBroadcast(final String action, final String pkg, final Bundle extras,
            final int flags, final String targetPkg, final IIntentReceiver finishedReceiver,
            final int[] userIds, int[] instantUserIds) {
        mHandler.post(() -> {
            try {
                final IActivityManager am = ActivityManager.getService();
                if (am == null) return;
                final int[] resolvedUserIds;
                if (userIds == null) {
                    resolvedUserIds = am.getRunningUserIds();
                } else {
                    resolvedUserIds = userIds;
                }
                doSendBroadcast(am, action, pkg, extras, flags, targetPkg, finishedReceiver,
                        resolvedUserIds, false);
                if (instantUserIds != null && instantUserIds != EMPTY_INT_ARRAY) {
                    doSendBroadcast(am, action, pkg, extras, flags, targetPkg, finishedReceiver,
                            instantUserIds, true);
                }
            } catch (RemoteException ex) {
            }
        });
    }

    @Override
    public void notifyPackageAdded(String packageName, int uid) {
        final PackageListObserver[] observers;
        synchronized (mLock) {
            if (mPackageListObservers.size() == 0) {
                return;
            }
            final PackageListObserver[] observerArray =
                    new PackageListObserver[mPackageListObservers.size()];
            observers = mPackageListObservers.toArray(observerArray);
        }
        for (int i = observers.length - 1; i >= 0; --i) {
            observers[i].onPackageAdded(packageName, uid);
        }
    }

    @Override
    public void notifyPackageChanged(String packageName, int uid) {
        final PackageListObserver[] observers;
        synchronized (mLock) {
            if (mPackageListObservers.size() == 0) {
                return;
            }
            final PackageListObserver[] observerArray =
                    new PackageListObserver[mPackageListObservers.size()];
            observers = mPackageListObservers.toArray(observerArray);
        }
        for (int i = observers.length - 1; i >= 0; --i) {
            observers[i].onPackageChanged(packageName, uid);
        }
    }

    private static final Comparator<ProviderInfo> sProviderInitOrderSorter = (p1, p2) -> {
        final int v1 = p1.initOrder;
        final int v2 = p2.initOrder;
        return (v1 > v2) ? -1 : ((v1 < v2) ? 1 : 0);
    };

    @Override
    public void notifyPackageRemoved(String packageName, int uid) {
        final PackageListObserver[] observers;
        synchronized (mLock) {
            if (mPackageListObservers.size() == 0) {
                return;
            }
            final PackageListObserver[] observerArray =
                    new PackageListObserver[mPackageListObservers.size()];
            observers = mPackageListObservers.toArray(observerArray);
        }
        for (int i = observers.length - 1; i >= 0; --i) {
            observers[i].onPackageRemoved(packageName, uid);
        }
    }

    /**
     * Sends a broadcast for the given action.
     * <p>If {@code isInstantApp} is {@code true}, then the broadcast is protected with
     * the {@link android.Manifest.permission#ACCESS_INSTANT_APPS} permission. This allows
     * the system and applications allowed to see instant applications to receive package
     * lifecycle events for instant applications.
     */
    private void doSendBroadcast(IActivityManager am, String action, String pkg, Bundle extras,
            int flags, String targetPkg, IIntentReceiver finishedReceiver,
            int[] userIds, boolean isInstantApp)
                    throws RemoteException {
        for (int id : userIds) {
            final Intent intent = new Intent(action,
                    pkg != null ? Uri.fromParts(PACKAGE_SCHEME, pkg, null) : null);
            final String[] requiredPermissions =
                    isInstantApp ? INSTANT_APP_BROADCAST_PERMISSION : null;
            if (extras != null) {
                intent.putExtras(extras);
            }
            if (targetPkg != null) {
                intent.setPackage(targetPkg);
            }
            // Modify the UID when posting to other users
            int uid = intent.getIntExtra(Intent.EXTRA_UID, -1);
            if (uid > 0 && UserHandle.getUserId(uid) != id) {
                uid = UserHandle.getUid(id, UserHandle.getAppId(uid));
                intent.putExtra(Intent.EXTRA_UID, uid);
            }
            intent.putExtra(Intent.EXTRA_USER_HANDLE, id);
            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT | flags);
            if (DEBUG_BROADCASTS) {
                RuntimeException here = new RuntimeException("here");
                here.fillInStackTrace();
                Slog.d(TAG, "Sending to user " + id + ": "
                        + intent.toShortString(false, true, false, false)
                        + " " + intent.getExtras(), here);
            }
            am.broadcastIntent(null, intent, null, finishedReceiver,
                    0, null, null, requiredPermissions, android.app.AppOpsManager.OP_NONE,
                    null, finishedReceiver != null, false, id);
        }
    }

    /**
     * Check if the external storage media is available. This is true if there
     * is a mounted external storage medium or if the external storage is
     * emulated.
     */
    private boolean isExternalMediaAvailable() {
        return mMediaMounted || Environment.isExternalStorageEmulated();
    }

    /**
     * Ensure that the install reason matches what we know about the package installer (e.g. whether
     * it is acting on behalf on an enterprise or the user).
     *
     * Note that the ordering of the conditionals in this method is important. The checks we perform
     * are as follows, in this order:
     *
     * 1) If the install is being performed by a system app, we can trust the app to have set the
     *    install reason correctly. Thus, we pass through the install reason unchanged, no matter
     *    what it is.
     * 2) If the install is being performed by a device or profile owner app, the install reason
     *    should be enterprise policy. However, we cannot be sure that the device or profile owner
     *    set the install reason correctly. If the app targets an older SDK version where install
     *    reasons did not exist yet, or if the app author simply forgot, the install reason may be
     *    unset or wrong. Thus, we force the install reason to be enterprise policy.
     * 3) In all other cases, the install is being performed by a regular app that is neither part
     *    of the system nor a device or profile owner. We have no reason to believe that this app is
     *    acting on behalf of the enterprise admin. Thus, we check whether the install reason was
     *    set to enterprise policy and if so, change it to unknown instead.
     */
    private int fixUpInstallReason(String installerPackageName, int installerUid,
            int installReason) {
        if (checkUidPermission(android.Manifest.permission.INSTALL_PACKAGES, installerUid)
                == PERMISSION_GRANTED) {
            // If the install is being performed by a system app, we trust that app to have set the
            // install reason correctly.
            return installReason;
        }
        final String ownerPackage = mProtectedPackages.getDeviceOwnerOrProfileOwnerPackage(
                UserHandle.getUserId(installerUid));
        if (ownerPackage != null && ownerPackage.equals(installerPackageName)) {
            // If the install is being performed by a device or profile owner, the install
            // reason should be enterprise policy.
            return PackageManager.INSTALL_REASON_POLICY;
        }


        if (installReason == PackageManager.INSTALL_REASON_POLICY) {
            // If the install is being performed by a regular app (i.e. neither system app nor
            // device or profile owner), we have no reason to believe that the app is acting on
            // behalf of an enterprise. If the app set the install reason to enterprise policy,
            // change it to unknown instead.
            return PackageManager.INSTALL_REASON_UNKNOWN;
        }

        // If the install is being performed by a regular app and the install reason was set to any
        // value but enterprise policy, leave the install reason unchanged.
        return installReason;
    }

    void installStage(ActiveInstallSession activeInstallSession) {
        if (DEBUG_INSTANT) {
            if ((activeInstallSession.getSessionParams().installFlags
                    & PackageManager.INSTALL_INSTANT_APP) != 0) {
                Slog.d(TAG, "Ephemeral install of " + activeInstallSession.getPackageName());
            }
        }
        final Message msg = mHandler.obtainMessage(INIT_COPY);
        final InstallParams params = new InstallParams(activeInstallSession);
        params.setTraceMethod("installStage").setTraceCookie(System.identityHashCode(params));
        msg.obj = params;

        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "installStage",
                System.identityHashCode(msg.obj));
        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
                System.identityHashCode(msg.obj));

        mHandler.sendMessage(msg);
    }

    void installStage(List<ActiveInstallSession> children)
            throws PackageManagerException {
        final Message msg = mHandler.obtainMessage(INIT_COPY);
        final MultiPackageInstallParams params =
                new MultiPackageInstallParams(UserHandle.ALL, children);
        params.setTraceMethod("installStageMultiPackage")
                .setTraceCookie(System.identityHashCode(params));
        msg.obj = params;

        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "installStageMultiPackage",
                System.identityHashCode(msg.obj));
        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
                System.identityHashCode(msg.obj));
        mHandler.sendMessage(msg);
    }

    private void sendPackageAddedForUser(String packageName, PackageSetting pkgSetting,
            int userId) {
        final boolean isSystem = isSystemApp(pkgSetting) || isUpdatedSystemApp(pkgSetting);
        final boolean isInstantApp = pkgSetting.getInstantApp(userId);
        final int[] userIds = isInstantApp ? EMPTY_INT_ARRAY : new int[] { userId };
        final int[] instantUserIds = isInstantApp ? new int[] { userId } : EMPTY_INT_ARRAY;
        sendPackageAddedForNewUsers(packageName, isSystem /*sendBootCompleted*/,
                false /*startReceiver*/, pkgSetting.appId, userIds, instantUserIds);

        // Send a session commit broadcast
        final PackageInstaller.SessionInfo info = new PackageInstaller.SessionInfo();
        info.installReason = pkgSetting.getInstallReason(userId);
        info.appPackageName = packageName;
        sendSessionCommitBroadcast(info, userId);
    }

    @Override
    public void sendPackageAddedForNewUsers(String packageName, boolean sendBootCompleted,
            boolean includeStopped, @AppIdInt int appId, int[] userIds, int[] instantUserIds) {
        if (ArrayUtils.isEmpty(userIds) && ArrayUtils.isEmpty(instantUserIds)) {
            return;
        }
        Bundle extras = new Bundle(1);
        // Set to UID of the first user, EXTRA_UID is automatically updated in sendPackageBroadcast
        final int uid = UserHandle.getUid(
                (ArrayUtils.isEmpty(userIds) ? instantUserIds[0] : userIds[0]), appId);
        extras.putInt(Intent.EXTRA_UID, uid);

        sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
                packageName, extras, 0, null, null, userIds, instantUserIds);
        if (sendBootCompleted && !ArrayUtils.isEmpty(userIds)) {
            mHandler.post(() -> {
                        for (int userId : userIds) {
                            sendBootCompletedBroadcastToSystemApp(
                                    packageName, includeStopped, userId);
                        }
                    }
            );
        }
    }

    /**
     * The just-installed/enabled app is bundled on the system, so presumed to be able to run
     * automatically without needing an explicit launch.
     * Send it a LOCKED_BOOT_COMPLETED/BOOT_COMPLETED if it would ordinarily have gotten ones.
     */
    private void sendBootCompletedBroadcastToSystemApp(
            String packageName, boolean includeStopped, int userId) {
        // If user is not running, the app didn't miss any broadcast
        if (!mUserManager.isUserRunning(userId)) {
            return;
        }
        final IActivityManager am = ActivityManager.getService();
        try {
            // Deliver LOCKED_BOOT_COMPLETED first
            Intent lockedBcIntent = new Intent(Intent.ACTION_LOCKED_BOOT_COMPLETED)
                    .setPackage(packageName);
            if (includeStopped) {
                lockedBcIntent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
            }
            final String[] requiredPermissions = {Manifest.permission.RECEIVE_BOOT_COMPLETED};
            am.broadcastIntent(null, lockedBcIntent, null, null, 0, null, null, requiredPermissions,
                    android.app.AppOpsManager.OP_NONE, null, false, false, userId);

            // Deliver BOOT_COMPLETED only if user is unlocked
            if (mUserManager.isUserUnlockingOrUnlocked(userId)) {
                Intent bcIntent = new Intent(Intent.ACTION_BOOT_COMPLETED).setPackage(packageName);
                if (includeStopped) {
                    bcIntent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
                }
                am.broadcastIntent(null, bcIntent, null, null, 0, null, null, requiredPermissions,
                        android.app.AppOpsManager.OP_NONE, null, false, false, userId);
            }
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

    @Override
    public boolean setApplicationHiddenSettingAsUser(String packageName, boolean hidden,
            int userId) {
        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
        PackageSetting pkgSetting;
        final int callingUid = Binder.getCallingUid();
        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
                true /* requireFullPermission */, true /* checkShell */,
                "setApplicationHiddenSetting for user " + userId);

        if (hidden && isPackageDeviceAdmin(packageName, userId)) {
            Slog.w(TAG, "Not hiding package " + packageName + ": has active device admin");
            return false;
        }

        long callingId = Binder.clearCallingIdentity();
        try {
            boolean sendAdded = false;
            boolean sendRemoved = false;
            // writer
            synchronized (mLock) {
                pkgSetting = mSettings.mPackages.get(packageName);
                if (pkgSetting == null) {
                    return false;
                }
                if (shouldFilterApplicationLocked(pkgSetting, callingUid, userId)) {
                    return false;
                }
                // Do not allow "android" is being disabled
                if ("android".equals(packageName)) {
                    Slog.w(TAG, "Cannot hide package: android");
                    return false;
                }
                // Cannot hide static shared libs as they are considered
                // a part of the using app (emulating static linking). Also
                // static libs are installed always on internal storage.
                AndroidPackage pkg = mPackages.get(packageName);
                if (pkg != null && pkg.getStaticSharedLibName() != null) {
                    Slog.w(TAG, "Cannot hide package: " + packageName
                            + " providing static shared library: "
                            + pkg.getStaticSharedLibName());
                    return false;
                }
                // Only allow protected packages to hide themselves.
                if (hidden && !UserHandle.isSameApp(callingUid, pkgSetting.appId)
                        && mProtectedPackages.isPackageStateProtected(userId, packageName)) {
                    Slog.w(TAG, "Not hiding protected package: " + packageName);
                    return false;
                }

                if (pkgSetting.getHidden(userId) != hidden) {
                    pkgSetting.setHidden(hidden, userId);
                    mSettings.writePackageRestrictionsLPr(userId);
                    if (hidden) {
                        sendRemoved = true;
                    } else {
                        sendAdded = true;
                    }
                }
            }
            if (sendAdded) {
                sendPackageAddedForUser(packageName, pkgSetting, userId);
                return true;
            }
            if (sendRemoved) {
                killApplication(packageName, UserHandle.getUid(userId, pkgSetting.appId),
                        "hiding pkg");
                sendApplicationHiddenForUser(packageName, pkgSetting, userId);
                return true;
            }
        } finally {
            Binder.restoreCallingIdentity(callingId);
        }
        return false;
    }

    @Override
    public void setSystemAppHiddenUntilInstalled(String packageName, boolean hidden) {
        final int callingUid = Binder.getCallingUid();
        PackageManagerServiceUtils
                .enforceSystemOrPhoneCaller("setSystemAppHiddenUntilInstalled", callingUid);
        synchronized (mLock) {
            final PackageSetting pkgSetting = mSettings.mPackages.get(packageName);
            if (pkgSetting == null || !pkgSetting.isSystem()) {
                return;
            }
            AndroidPackage pkg = pkgSetting.pkg;
            if (pkg != null) {
                pkg.mutate().setHiddenUntilInstalled(hidden);
            }
            final PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(packageName);
            if (disabledPs == null) {
                return;
            }
            pkg = disabledPs.pkg;
            if (pkg != null) {
                pkg.mutate().setHiddenUntilInstalled(hidden);
            }
        }
    }

    @Override
    public boolean setSystemAppInstallState(String packageName, boolean installed, int userId) {
        final int callingUid = Binder.getCallingUid();
        PackageManagerServiceUtils
                .enforceSystemOrPhoneCaller("setSystemAppInstallState", callingUid);
        synchronized (mLock) {
            final PackageSetting pkgSetting = mSettings.mPackages.get(packageName);
            // The target app should always be in system
            if (pkgSetting == null || !pkgSetting.isSystem()) {
                return false;
            }
            // Check if the install state is the same
            if (pkgSetting.getInstalled(userId) == installed) {
                return false;
            }
        }

        final long callingId = Binder.clearCallingIdentity();
        try {
            if (installed) {
                // install the app from uninstalled state
                installExistingPackageAsUser(
                        packageName,
                        userId,
                        PackageManager.INSTALL_ALL_WHITELIST_RESTRICTED_PERMISSIONS,
                        PackageManager.INSTALL_REASON_DEVICE_SETUP,
                        null);
                return true;
            }

            // uninstall the app from installed state
            deletePackageVersioned(
                    new VersionedPackage(packageName, PackageManager.VERSION_CODE_HIGHEST),
                    new LegacyPackageDeleteObserver(null).getBinder(),
                    userId,
                    PackageManager.DELETE_SYSTEM_APP);
            return true;
        } finally {
            Binder.restoreCallingIdentity(callingId);
        }
    }

    private void sendApplicationHiddenForUser(String packageName, PackageSetting pkgSetting,
            int userId) {
        final PackageRemovedInfo info = new PackageRemovedInfo(this);
        info.removedPackage = packageName;
        info.installerPackageName = pkgSetting.installSource.installerPackageName;
        info.removedUsers = new int[] {userId};
        info.broadcastUsers = new int[] {userId};
        info.uid = UserHandle.getUid(userId, pkgSetting.appId);
        info.sendPackageRemovedBroadcasts(true /*killApp*/);
    }

    private void sendDistractingPackagesChanged(String[] pkgList, int[] uidList, int userId,
            int distractionFlags) {
        final Bundle extras = new Bundle(3);
        extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList);
        extras.putIntArray(Intent.EXTRA_CHANGED_UID_LIST, uidList);
        extras.putInt(Intent.EXTRA_DISTRACTION_RESTRICTIONS, distractionFlags);
        sendPackageBroadcast(Intent.ACTION_DISTRACTING_PACKAGES_CHANGED, null, extras,
                Intent.FLAG_RECEIVER_REGISTERED_ONLY, null, null, new int[]{userId}, null);
    }

    private void sendPackagesSuspendedForUser(String[] pkgList, int[] uidList, int userId,
            boolean suspended) {
        final Bundle extras = new Bundle(3);
        extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList);
        extras.putIntArray(Intent.EXTRA_CHANGED_UID_LIST, uidList);
        sendPackageBroadcast(
                suspended ? Intent.ACTION_PACKAGES_SUSPENDED
                        : Intent.ACTION_PACKAGES_UNSUSPENDED,
                null, extras, Intent.FLAG_RECEIVER_REGISTERED_ONLY, null, null,
                new int[] {userId}, null);
    }

    /**
     * Returns true if application is not found or there was an error. Otherwise it returns
     * the hidden state of the package for the given user.
     */
    @Override
    public boolean getApplicationHiddenSettingAsUser(String packageName, int userId) {
        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
        final int callingUid = Binder.getCallingUid();
        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
                true /* requireFullPermission */, false /* checkShell */,
                "getApplicationHidden for user " + userId);
        PackageSetting ps;
        long callingId = Binder.clearCallingIdentity();
        try {
            // writer
            synchronized (mLock) {
                ps = mSettings.mPackages.get(packageName);
                if (ps == null) {
                    return true;
                }
                if (shouldFilterApplicationLocked(ps, callingUid, userId)) {
                    return true;
                }
                return ps.getHidden(userId);
            }
        } finally {
            Binder.restoreCallingIdentity(callingId);
        }
    }

    /**
     * @hide
     */
    @Override
    public int installExistingPackageAsUser(String packageName, int userId, int installFlags,
            int installReason, List<String> whiteListedPermissions) {
        return installExistingPackageAsUser(packageName, userId, installFlags, installReason,
                whiteListedPermissions, null);
    }

    int installExistingPackageAsUser(@Nullable String packageName, @UserIdInt int userId,
            @PackageManager.InstallFlags int installFlags,
            @PackageManager.InstallReason int installReason,
            @Nullable List<String> whiteListedPermissions, @Nullable IntentSender intentSender) {
        if (DEBUG_INSTALL) {
            Log.v(TAG, "installExistingPackageAsUser package=" + packageName + " userId=" + userId
                    + " installFlags=" + installFlags + " installReason=" + installReason
                    + " whiteListedPermissions=" + whiteListedPermissions);
        }

        final int callingUid = Binder.getCallingUid();
        if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES)
                != PackageManager.PERMISSION_GRANTED
                && mContext.checkCallingOrSelfPermission(
                        android.Manifest.permission.INSTALL_EXISTING_PACKAGES)
                != PackageManager.PERMISSION_GRANTED) {
            throw new SecurityException("Neither user " + callingUid + " nor current process has "
                    + android.Manifest.permission.INSTALL_PACKAGES + ".");
        }
        PackageSetting pkgSetting;
        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
                true /* requireFullPermission */, true /* checkShell */,
                "installExistingPackage for user " + userId);
        if (isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) {
            return PackageManager.INSTALL_FAILED_USER_RESTRICTED;
        }

        long callingId = Binder.clearCallingIdentity();
        try {
            boolean installed = false;
            final boolean instantApp =
                    (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
            final boolean fullApp =
                    (installFlags & PackageManager.INSTALL_FULL_APP) != 0;

            // writer
            synchronized (mLock) {
                pkgSetting = mSettings.mPackages.get(packageName);
                if (pkgSetting == null) {
                    return PackageManager.INSTALL_FAILED_INVALID_URI;
                }
                if (!canViewInstantApps(callingUid, UserHandle.getUserId(callingUid))) {
                    // only allow the existing package to be used if it's installed as a full
                    // application for at least one user
                    boolean installAllowed = false;
                    for (int checkUserId : mUserManager.getUserIds()) {
                        installAllowed = !pkgSetting.getInstantApp(checkUserId);
                        if (installAllowed) {
                            break;
                        }
                    }
                    if (!installAllowed) {
                        return PackageManager.INSTALL_FAILED_INVALID_URI;
                    }
                }
                if (!pkgSetting.getInstalled(userId)) {
                    pkgSetting.setInstalled(true, userId);
                    pkgSetting.setHidden(false, userId);
                    pkgSetting.setInstallReason(installReason, userId);
                    mSettings.writePackageRestrictionsLPr(userId);
                    mSettings.writeKernelMappingLPr(pkgSetting);
                    installed = true;
                } else if (fullApp && pkgSetting.getInstantApp(userId)) {
                    // upgrade app from instant to full; we don't allow app downgrade
                    installed = true;
                }
                setInstantAppForUser(mInjector, pkgSetting, userId, instantApp, fullApp);
            }

            if (installed) {
                if ((installFlags & PackageManager.INSTALL_ALL_WHITELIST_RESTRICTED_PERMISSIONS)
                        != 0 && pkgSetting.pkg != null) {
                    whiteListedPermissions = pkgSetting.pkg.getRequestedPermissions();
                }
                mPermissionManager.setWhitelistedRestrictedPermissions(packageName,
                        whiteListedPermissions, FLAG_PERMISSION_WHITELIST_INSTALLER, userId);

                if (pkgSetting.pkg != null) {
                    synchronized (mInstallLock) {
                        // We don't need to freeze for a brand new install
                        prepareAppDataAfterInstallLIF(pkgSetting.pkg);
                    }
                }
                sendPackageAddedForUser(packageName, pkgSetting, userId);
                synchronized (mLock) {
                    updateSequenceNumberLP(pkgSetting, new int[]{ userId });
                }
                // start async restore with no post-install since we finish install here
                PackageInstalledInfo res =
                        createPackageInstalledInfo(PackageManager.INSTALL_SUCCEEDED);
                res.pkg = pkgSetting.pkg;
                res.newUsers = new int[]{ userId };
                PostInstallData postInstallData = intentSender == null ? null :
                        new PostInstallData(null, res, () -> onRestoreComplete(res.returnCode,
                              mContext, intentSender));
                restoreAndPostInstall(userId, res, postInstallData);
            }
        } finally {
            Binder.restoreCallingIdentity(callingId);
        }

        return PackageManager.INSTALL_SUCCEEDED;
    }

    static void onRestoreComplete(int returnCode, Context context, IntentSender target) {
        Intent fillIn = new Intent();
        fillIn.putExtra(PackageInstaller.EXTRA_STATUS,
                PackageManager.installStatusToPublicStatus(returnCode));
        try {
            target.sendIntent(context, 0, fillIn, null, null);
        } catch (SendIntentException ignored) {
        }
    }

    static void setInstantAppForUser(Injector injector, PackageSetting pkgSetting,
            int userId, boolean instantApp, boolean fullApp) {
        // no state specified; do nothing
        if (!instantApp && !fullApp) {
            return;
        }
        if (userId != UserHandle.USER_ALL) {
            if (instantApp && !pkgSetting.getInstantApp(userId)) {
                pkgSetting.setInstantApp(true /*instantApp*/, userId);
            } else if (fullApp && pkgSetting.getInstantApp(userId)) {
                pkgSetting.setInstantApp(false /*instantApp*/, userId);
            }
        } else {
            for (int currentUserId : injector.getUserManagerInternal().getUserIds()) {
                if (instantApp && !pkgSetting.getInstantApp(currentUserId)) {
                    pkgSetting.setInstantApp(true /*instantApp*/, currentUserId);
                } else if (fullApp && pkgSetting.getInstantApp(currentUserId)) {
                    pkgSetting.setInstantApp(false /*instantApp*/, currentUserId);
                }
            }
        }
    }

    boolean isUserRestricted(int userId, String restrictionKey) {
        Bundle restrictions = mUserManager.getUserRestrictions(userId);
        if (restrictions.getBoolean(restrictionKey, false)) {
            Log.w(TAG, "User is restricted: " + restrictionKey);
            return true;
        }
        return false;
    }

    @Override
    public String[] setDistractingPackageRestrictionsAsUser(String[] packageNames,
            int restrictionFlags, int userId) {
        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.SUSPEND_APPS,
                "setDistractingPackageRestrictionsAsUser");

        final int callingUid = Binder.getCallingUid();
        if (callingUid != Process.ROOT_UID && callingUid != Process.SYSTEM_UID
                && UserHandle.getUserId(callingUid) != userId) {
            throw new SecurityException("Calling uid " + callingUid + " cannot call for user "
                    + userId);
        }
        Preconditions.checkNotNull(packageNames, "packageNames cannot be null");

        final List<String> changedPackagesList = new ArrayList<>(packageNames.length);
        final IntArray changedUids = new IntArray(packageNames.length);
        final List<String> unactionedPackages = new ArrayList<>(packageNames.length);
        final boolean[] canRestrict = (restrictionFlags != 0) ? canSuspendPackageForUserInternal(
                packageNames, userId) : null;

        for (int i = 0; i < packageNames.length; i++) {
            final String packageName = packageNames[i];
            final PackageSetting pkgSetting;
            synchronized (mLock) {
                pkgSetting = mSettings.mPackages.get(packageName);
                if (pkgSetting == null
                        || shouldFilterApplicationLocked(pkgSetting, callingUid, userId)) {
                    Slog.w(TAG, "Could not find package setting for package: " + packageName
                            + ". Skipping...");
                    unactionedPackages.add(packageName);
                    continue;
                }
            }
            if (canRestrict != null && !canRestrict[i]) {
                unactionedPackages.add(packageName);
                continue;
            }
            synchronized (mLock) {
                final int oldDistractionFlags = pkgSetting.getDistractionFlags(userId);
                if (restrictionFlags != oldDistractionFlags) {
                    pkgSetting.setDistractionFlags(restrictionFlags, userId);
                    changedPackagesList.add(packageName);
                    changedUids.add(UserHandle.getUid(userId, pkgSetting.appId));
                }
            }
        }

        if (!changedPackagesList.isEmpty()) {
            final String[] changedPackages = changedPackagesList.toArray(
                    new String[changedPackagesList.size()]);
            sendDistractingPackagesChanged(changedPackages, changedUids.toArray(), userId,
                    restrictionFlags);
            synchronized (mLock) {
                scheduleWritePackageRestrictionsLocked(userId);
            }
        }
        return unactionedPackages.toArray(new String[0]);
    }

    private void enforceCanSetPackagesSuspendedAsUser(String callingPackage, int callingUid,
            int userId, String callingMethod) {
        if (callingUid == Process.ROOT_UID || callingUid == Process.SYSTEM_UID) {
            return;
        }

        final String ownerPackage = mProtectedPackages.getDeviceOwnerOrProfileOwnerPackage(userId);
        if (ownerPackage != null) {
            final int ownerUid = getPackageUid(ownerPackage, 0, userId);
            if (ownerUid == callingUid) {
                return;
            }
        }

        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.SUSPEND_APPS,
                callingMethod);

        final int packageUid = getPackageUid(callingPackage, 0, userId);
        final boolean allowedPackageUid = packageUid == callingUid;
        // TODO(b/139383163): remove special casing for shell and enforce INTERACT_ACROSS_USERS_FULL
        final boolean allowedShell = callingUid == SHELL_UID
                && UserHandle.isSameApp(packageUid, callingUid);

        if (!allowedShell && !allowedPackageUid) {
            throw new SecurityException("Calling package " + callingPackage + " in user "
                    + userId + " does not belong to calling uid " + callingUid);
        }
    }

    @Override
    public String[] setPackagesSuspendedAsUser(String[] packageNames, boolean suspended,
            PersistableBundle appExtras, PersistableBundle launcherExtras,
            SuspendDialogInfo dialogInfo, String callingPackage, int userId) {
        final int callingUid = Binder.getCallingUid();
        enforceCanSetPackagesSuspendedAsUser(callingPackage, callingUid, userId,
                "setPackagesSuspendedAsUser");

        if (ArrayUtils.isEmpty(packageNames)) {
            return packageNames;
        }

        final List<String> changedPackagesList = new ArrayList<>(packageNames.length);
        final IntArray changedUids = new IntArray(packageNames.length);
        final List<String> unactionedPackages = new ArrayList<>(packageNames.length);
        final boolean[] canSuspend = suspended ? canSuspendPackageForUserInternal(packageNames,
                userId) : null;

        for (int i = 0; i < packageNames.length; i++) {
            final String packageName = packageNames[i];
            if (callingPackage.equals(packageName)) {
                Slog.w(TAG, "Calling package: " + callingPackage + " trying to "
                        + (suspended ? "" : "un") + "suspend itself. Ignoring");
                unactionedPackages.add(packageName);
                continue;
            }
            final PackageSetting pkgSetting;
            synchronized (mLock) {
                pkgSetting = mSettings.mPackages.get(packageName);
                if (pkgSetting == null
                        || shouldFilterApplicationLocked(pkgSetting, callingUid, userId)) {
                    Slog.w(TAG, "Could not find package setting for package: " + packageName
                            + ". Skipping suspending/un-suspending.");
                    unactionedPackages.add(packageName);
                    continue;
                }
            }
            if (canSuspend != null && !canSuspend[i]) {
                unactionedPackages.add(packageName);
                continue;
            }
            boolean packageUnsuspended;
            synchronized (mLock) {
                if (suspended) {
                    pkgSetting.addOrUpdateSuspension(callingPackage, dialogInfo, appExtras,
                            launcherExtras, userId);
                } else {
                    pkgSetting.removeSuspension(callingPackage, userId);
                }
                packageUnsuspended = !suspended && !pkgSetting.getSuspended(userId);
            }
            if (suspended || packageUnsuspended) {
                changedPackagesList.add(packageName);
                changedUids.add(UserHandle.getUid(userId, pkgSetting.appId));
            }
        }

        if (!changedPackagesList.isEmpty()) {
            final String[] changedPackages = changedPackagesList.toArray(
                    new String[changedPackagesList.size()]);
            sendPackagesSuspendedForUser(changedPackages, changedUids.toArray(), userId, suspended);
            sendMyPackageSuspendedOrUnsuspended(changedPackages, suspended, userId);
            synchronized (mLock) {
                scheduleWritePackageRestrictionsLocked(userId);
            }
        }
        return unactionedPackages.toArray(new String[unactionedPackages.size()]);
    }

    @Override
    public Bundle getSuspendedPackageAppExtras(String packageName, int userId) {
        final int callingUid = Binder.getCallingUid();
        if (getPackageUid(packageName, 0, userId) != callingUid) {
            throw new SecurityException("Calling package " + packageName
                    + " does not belong to calling uid " + callingUid);
        }
        return getSuspendedPackageAppExtrasInternal(packageName, userId);
    }

    private Bundle getSuspendedPackageAppExtrasInternal(String packageName, int userId) {
        synchronized (mLock) {
            final PackageSetting ps = mSettings.mPackages.get(packageName);
            if (ps == null) {
                throw new IllegalArgumentException("Unknown target package: " + packageName);
            }
            final PackageUserState pus = ps.readUserState(userId);
            final Bundle allExtras = new Bundle();
            if (pus.suspended) {
                for (int i = 0; i < pus.suspendParams.size(); i++) {
                    final PackageUserState.SuspendParams params = pus.suspendParams.valueAt(i);
                    if (params != null && params.appExtras != null) {
                        allExtras.putAll(params.appExtras);
                    }
                }
            }
            return (allExtras.size() > 0) ? allExtras : null;
        }
    }

    private void sendMyPackageSuspendedOrUnsuspended(String[] affectedPackages, boolean suspended,
            int userId) {
        final String action = suspended
                ? Intent.ACTION_MY_PACKAGE_SUSPENDED
                : Intent.ACTION_MY_PACKAGE_UNSUSPENDED;
        mHandler.post(() -> {
            try {
                final IActivityManager am = ActivityManager.getService();
                if (am == null) {
                    Slog.wtf(TAG, "IActivityManager null. Cannot send MY_PACKAGE_ "
                            + (suspended ? "" : "UN") + "SUSPENDED broadcasts");
                    return;
                }
                final int[] targetUserIds = new int[] {userId};
                for (String packageName : affectedPackages) {
                    final Bundle appExtras = suspended
                            ? getSuspendedPackageAppExtrasInternal(packageName, userId)
                            : null;
                    final Bundle intentExtras;
                    if (appExtras != null) {
                        intentExtras = new Bundle(1);
                        intentExtras.putBundle(Intent.EXTRA_SUSPENDED_PACKAGE_EXTRAS, appExtras);
                    } else {
                        intentExtras = null;
                    }
                    doSendBroadcast(am, action, null, intentExtras,
                            Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND, packageName, null,
                            targetUserIds, false);
                }
            } catch (RemoteException ex) {
                // Shouldn't happen as AMS is in the same process.
            }
        });
    }

    @Override
    public boolean isPackageSuspendedForUser(String packageName, int userId) {
        final int callingUid = Binder.getCallingUid();
        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
                true /* requireFullPermission */, false /* checkShell */,
                "isPackageSuspendedForUser for user " + userId);
        synchronized (mLock) {
            final PackageSetting ps = mSettings.mPackages.get(packageName);
            if (ps == null || shouldFilterApplicationLocked(ps, callingUid, userId)) {
                throw new IllegalArgumentException("Unknown target package: " + packageName);
            }
            return ps.getSuspended(userId);
        }
    }

    /**
     * Immediately unsuspends any packages suspended by the given package. To be called
     * when such a package's data is cleared or it is removed from the device.
     *
     * <p><b>Should not be used on a frequent code path</b> as it flushes state to disk
     * synchronously
     *
     * @param suspendingPackage The suspending package
     * @param userId The user for which the changes are taking place.
     */
    private void unsuspendForSuspendingPackage(String suspendingPackage, int userId) {
        final List<String> unsuspendedPackages = new ArrayList<>();
        final IntArray unsuspendedUids = new IntArray();
        synchronized (mLock) {
            for (PackageSetting ps : mSettings.mPackages.values()) {
                final PackageUserState pus = ps.readUserState(userId);
                if (pus.suspended) {
                    ps.removeSuspension(suspendingPackage, userId);
                    if (!ps.getSuspended(userId)) {
                        unsuspendedPackages.add(ps.name);
                        unsuspendedUids.add(UserHandle.getUid(userId, ps.getAppId()));
                    }
                }
            }
        }
        if (!unsuspendedPackages.isEmpty()) {
            final String[] packageArray = unsuspendedPackages.toArray(
                    new String[unsuspendedPackages.size()]);
            sendMyPackageSuspendedOrUnsuspended(packageArray, false, userId);
            sendPackagesSuspendedForUser(packageArray, unsuspendedUids.toArray(), userId, false);
        }
        // Write package restrictions immediately to avoid an inconsistent state.
        mSettings.writePackageRestrictionsLPr(userId);
    }

    @Override
    public String[] getUnsuspendablePackagesForUser(String[] packageNames, int userId) {
        Preconditions.checkNotNull("packageNames cannot be null", packageNames);
        mContext.enforceCallingOrSelfPermission(Manifest.permission.SUSPEND_APPS,
                "getUnsuspendablePackagesForUser");
        final int callingUid = Binder.getCallingUid();
        if (UserHandle.getUserId(callingUid) != userId) {
            throw new SecurityException("Calling uid " + callingUid
                    + " cannot query getUnsuspendablePackagesForUser for user " + userId);
        }
        final ArraySet<String> unactionablePackages = new ArraySet<>();
        final boolean[] canSuspend = canSuspendPackageForUserInternal(packageNames, userId);
        for (int i = 0; i < packageNames.length; i++) {
            if (!canSuspend[i]) {
                unactionablePackages.add(packageNames[i]);
            }
        }
        return unactionablePackages.toArray(new String[unactionablePackages.size()]);
    }

    /**
     * Returns an array of booleans, such that the ith boolean denotes whether the ith package can
     * be suspended or not.
     *
     * @param packageNames  The package names to check suspendability for.
     * @param userId The user to check in
     * @return An array containing results of the checks
     */
    @NonNull
    private boolean[] canSuspendPackageForUserInternal(@NonNull String[] packageNames, int userId) {
        final boolean[] canSuspend = new boolean[packageNames.length];
        final long callingId = Binder.clearCallingIdentity();
        try {
            final String activeLauncherPackageName = getActiveLauncherPackageName(userId);
            final String dialerPackageName = mPermissionManager.getDefaultDialer(userId);
            for (int i = 0; i < packageNames.length; i++) {
                canSuspend[i] = false;
                final String packageName = packageNames[i];

                if (isPackageDeviceAdmin(packageName, userId)) {
                    Slog.w(TAG, "Cannot suspend package \"" + packageName
                            + "\": has an active device admin");
                    continue;
                }
                if (packageName.equals(activeLauncherPackageName)) {
                    Slog.w(TAG, "Cannot suspend package \"" + packageName
                            + "\": contains the active launcher");
                    continue;
                }
                if (packageName.equals(mRequiredInstallerPackage)) {
                    Slog.w(TAG, "Cannot suspend package \"" + packageName
                            + "\": required for package installation");
                    continue;
                }
                if (packageName.equals(mRequiredUninstallerPackage)) {
                    Slog.w(TAG, "Cannot suspend package \"" + packageName
                            + "\": required for package uninstallation");
                    continue;
                }
                if (packageName.equals(mRequiredVerifierPackage)) {
                    Slog.w(TAG, "Cannot suspend package \"" + packageName
                            + "\": required for package verification");
                    continue;
                }
                if (packageName.equals(dialerPackageName)) {
                    Slog.w(TAG, "Cannot suspend package \"" + packageName
                            + "\": is the default dialer");
                    continue;
                }
                if (packageName.equals(mRequiredPermissionControllerPackage)) {
                    Slog.w(TAG, "Cannot suspend package \"" + packageName
                            + "\": required for permissions management");
                    continue;
                }
                synchronized (mLock) {
                    if (mProtectedPackages.isPackageStateProtected(userId, packageName)) {
                        Slog.w(TAG, "Cannot suspend package \"" + packageName
                                + "\": protected package");
                        continue;
                    }

                    // Cannot suspend static shared libs as they are considered
                    // a part of the using app (emulating static linking). Also
                    // static libs are installed always on internal storage.
                    AndroidPackage pkg = mPackages.get(packageName);
                    if (pkg != null && pkg.isStaticSharedLibrary()) {
                        Slog.w(TAG, "Cannot suspend package: " + packageName
                                + " providing static shared library: "
                                + pkg.getStaticSharedLibName());
                        continue;
                    }
                }
                if (PLATFORM_PACKAGE_NAME.equals(packageName)) {
                    Slog.w(TAG, "Cannot suspend the platform package: " + packageName);
                    continue;
                }
                canSuspend[i] = true;
            }
        } finally {
            Binder.restoreCallingIdentity(callingId);
        }
        return canSuspend;
    }

    private String getActiveLauncherPackageName(int userId) {
        Intent intent = new Intent(Intent.ACTION_MAIN);
        intent.addCategory(Intent.CATEGORY_HOME);
        ResolveInfo resolveInfo = resolveIntent(
                intent,
                intent.resolveTypeIfNeeded(mContext.getContentResolver()),
                PackageManager.MATCH_DEFAULT_ONLY,
                userId);

        return resolveInfo == null ? null : resolveInfo.activityInfo.packageName;
    }

    @Override
    public void verifyPendingInstall(int id, int verificationCode) throws RemoteException {
        mContext.enforceCallingOrSelfPermission(
                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
                "Only package verification agents can verify applications");

        final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED);
        final PackageVerificationResponse response = new PackageVerificationResponse(
                verificationCode, Binder.getCallingUid());
        msg.arg1 = id;
        msg.obj = response;
        mHandler.sendMessage(msg);
    }

    @Override
    public void extendVerificationTimeout(int id, int verificationCodeAtTimeout,
            long millisecondsToDelay) {
        mContext.enforceCallingOrSelfPermission(
                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
                "Only package verification agents can extend verification timeouts");

        final PackageVerificationState state = mPendingVerification.get(id);
        final PackageVerificationResponse response = new PackageVerificationResponse(
                verificationCodeAtTimeout, Binder.getCallingUid());

        if (millisecondsToDelay > PackageManager.MAXIMUM_VERIFICATION_TIMEOUT) {
            millisecondsToDelay = PackageManager.MAXIMUM_VERIFICATION_TIMEOUT;
        }
        if (millisecondsToDelay < 0) {
            millisecondsToDelay = 0;
        }
        if ((verificationCodeAtTimeout != PackageManager.VERIFICATION_ALLOW)
                && (verificationCodeAtTimeout != PackageManager.VERIFICATION_REJECT)) {
            verificationCodeAtTimeout = PackageManager.VERIFICATION_REJECT;
        }

        if ((state != null) && !state.timeoutExtended()) {
            state.extendTimeout();

            final Message msg = mHandler.obtainMessage(PACKAGE_VERIFIED);
            msg.arg1 = id;
            msg.obj = response;
            mHandler.sendMessageDelayed(msg, millisecondsToDelay);
        }
    }

    private void broadcastPackageVerified(int verificationId, Uri packageUri,
            int verificationCode, UserHandle user) {
        final Intent intent = new Intent(Intent.ACTION_PACKAGE_VERIFIED);
        intent.setDataAndType(packageUri, PACKAGE_MIME_TYPE);
        intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
        intent.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId);
        intent.putExtra(PackageManager.EXTRA_VERIFICATION_RESULT, verificationCode);

        mContext.sendBroadcastAsUser(intent, user,
                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT);
    }

    private ComponentName matchComponentForVerifier(String packageName,
            List<ResolveInfo> receivers) {
        ActivityInfo targetReceiver = null;

        final int NR = receivers.size();
        for (int i = 0; i < NR; i++) {
            final ResolveInfo info = receivers.get(i);
            if (info.activityInfo == null) {
                continue;
            }

            if (packageName.equals(info.activityInfo.packageName)) {
                targetReceiver = info.activityInfo;
                break;
            }
        }

        if (targetReceiver == null) {
            return null;
        }

        return new ComponentName(targetReceiver.packageName, targetReceiver.name);
    }

    private List<ComponentName> matchVerifiers(PackageInfoLite pkgInfo,
            List<ResolveInfo> receivers, final PackageVerificationState verificationState) {
        if (pkgInfo.verifiers.length == 0) {
            return null;
        }

        final int N = pkgInfo.verifiers.length;
        final List<ComponentName> sufficientVerifiers = new ArrayList<>(N + 1);
        for (int i = 0; i < N; i++) {
            final VerifierInfo verifierInfo = pkgInfo.verifiers[i];

            final ComponentName comp = matchComponentForVerifier(verifierInfo.packageName,
                    receivers);
            if (comp == null) {
                continue;
            }

            final int verifierUid = getUidForVerifier(verifierInfo);
            if (verifierUid == -1) {
                continue;
            }

            if (DEBUG_VERIFY) {
                Slog.d(TAG, "Added sufficient verifier " + verifierInfo.packageName
                        + " with the correct signature");
            }
            sufficientVerifiers.add(comp);
            verificationState.addSufficientVerifier(verifierUid);
        }

        return sufficientVerifiers;
    }

    private int getUidForVerifier(VerifierInfo verifierInfo) {
        synchronized (mLock) {
            final AndroidPackage pkg = mPackages.get(verifierInfo.packageName);
            if (pkg == null) {
                return -1;
            } else if (pkg.getSigningDetails().signatures.length != 1) {
                Slog.i(TAG, "Verifier package " + verifierInfo.packageName
                        + " has more than one signature; ignoring");
                return -1;
            }

            /*
             * If the public key of the package's signature does not match
             * our expected public key, then this is a different package and
             * we should skip.
             */

            final byte[] expectedPublicKey;
            try {
                final Signature verifierSig = pkg.getSigningDetails().signatures[0];
                final PublicKey publicKey = verifierSig.getPublicKey();
                expectedPublicKey = publicKey.getEncoded();
            } catch (CertificateException e) {
                return -1;
            }

            final byte[] actualPublicKey = verifierInfo.publicKey.getEncoded();

            if (!Arrays.equals(actualPublicKey, expectedPublicKey)) {
                Slog.i(TAG, "Verifier package " + verifierInfo.packageName
                        + " does not have the expected public key; ignoring");
                return -1;
            }

            return pkg.getUid();
        }
    }

    private void setEnableRollbackCode(int token, int enableRollbackCode) {
        final Message msg = mHandler.obtainMessage(ENABLE_ROLLBACK_STATUS);
        msg.arg1 = token;
        msg.arg2 = enableRollbackCode;
        mHandler.sendMessage(msg);
    }

    @Override
    public void finishPackageInstall(int token, boolean didLaunch) {
        enforceSystemOrRoot("Only the system is allowed to finish installs");

        if (DEBUG_INSTALL) {
            Slog.v(TAG, "BM finishing package install for " + token);
        }
        Trace.asyncTraceEnd(TRACE_TAG_PACKAGE_MANAGER, "restore", token);

        final Message msg = mHandler.obtainMessage(POST_INSTALL, token, didLaunch ? 1 : 0);
        mHandler.sendMessage(msg);
    }

    /**
     * Get the verification agent timeout.  Used for both the APK verifier and the
     * intent filter verifier.
     *
     * @return verification timeout in milliseconds
     */
    private long getVerificationTimeout() {
        long timeout = Global.getLong(mContext.getContentResolver(),
                Global.PACKAGE_VERIFIER_TIMEOUT, DEFAULT_VERIFICATION_TIMEOUT);
        // The setting can be used to increase the timeout but not decrease it, since that is
        // equivalent to disabling the verifier.
        return Math.max(timeout, DEFAULT_VERIFICATION_TIMEOUT);
    }

    /**
     * Get the default verification agent response code.
     *
     * @return default verification response code
     */
    private int getDefaultVerificationResponse(UserHandle user) {
        if (mUserManager.hasUserRestriction(UserManager.ENSURE_VERIFY_APPS, user.getIdentifier())) {
            return PackageManager.VERIFICATION_REJECT;
        }
        return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
                android.provider.Settings.Global.PACKAGE_VERIFIER_DEFAULT_RESPONSE,
                DEFAULT_VERIFICATION_RESPONSE);
    }

    /**
     * Check whether or not package verification has been enabled.
     *
     * @return true if verification should be performed
     */
    private boolean isVerificationEnabled(int userId, int installFlags, int installerUid) {
        if (!DEFAULT_VERIFY_ENABLE) {
            return false;
        }

        if ((installFlags & PackageManager.INSTALL_DISABLE_VERIFICATION) != 0) {
            return false;
        }

        // Check if installing from ADB
        if ((installFlags & PackageManager.INSTALL_FROM_ADB) != 0) {
            if (isUserRestricted(userId, UserManager.ENSURE_VERIFY_APPS)) {
                return true;
            }
            // Check if the developer does not want package verification for ADB installs
            return Global.getInt(mContext.getContentResolver(),
                    Global.PACKAGE_VERIFIER_INCLUDE_ADB, 1) != 0;
        } else {
            // only when not installed from ADB, skip verification for instant apps when
            // the installer and verifier are the same.
            if ((installFlags & PackageManager.INSTALL_INSTANT_APP) != 0) {
                if (mInstantAppInstallerActivity != null
                        && mInstantAppInstallerActivity.packageName.equals(
                                mRequiredVerifierPackage)) {
                    try {
                        mInjector.getAppOpsManager()
                                .checkPackage(installerUid, mRequiredVerifierPackage);
                        if (DEBUG_VERIFY) {
                            Slog.i(TAG, "disable verification for instant app");
                        }
                        return false;
                    } catch (SecurityException ignore) { }
                }
            }
            return true;
        }
    }

    @Override
    public void verifyIntentFilter(int id, int verificationCode, List<String> failedDomains)
            throws RemoteException {
        mContext.enforceCallingOrSelfPermission(
                Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT,
                "Only intentfilter verification agents can verify applications");

        final Message msg = mHandler.obtainMessage(INTENT_FILTER_VERIFIED);
        final IntentFilterVerificationResponse response = new IntentFilterVerificationResponse(
                Binder.getCallingUid(), verificationCode, failedDomains);
        msg.arg1 = id;
        msg.obj = response;
        mHandler.sendMessage(msg);
    }

    @Override
    public int getIntentVerificationStatus(String packageName, int userId) {
        final int callingUid = Binder.getCallingUid();
        if (UserHandle.getUserId(callingUid) != userId) {
            mContext.enforceCallingOrSelfPermission(
                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
                    "getIntentVerificationStatus" + userId);
        }
        if (getInstantAppPackageName(callingUid) != null) {
            return INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
        }
        synchronized (mLock) {
            final PackageSetting ps = mSettings.mPackages.get(packageName);
            if (ps == null
                    || shouldFilterApplicationLocked(
                    ps, callingUid, UserHandle.getUserId(callingUid))) {
                return INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
            }
            return mSettings.getIntentFilterVerificationStatusLPr(packageName, userId);
        }
    }

    @Override
    public boolean updateIntentVerificationStatus(String packageName, int status, int userId) {
        mContext.enforceCallingOrSelfPermission(
                android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);

        boolean result = false;
        synchronized (mLock) {
            final PackageSetting ps = mSettings.mPackages.get(packageName);
            if (shouldFilterApplicationLocked(
                    ps, Binder.getCallingUid(), UserHandle.getCallingUserId())) {
                return false;
            }
            result = mSettings.updateIntentFilterVerificationStatusLPw(packageName, status, userId);
        }
        if (result) {
            scheduleWritePackageRestrictionsLocked(userId);
        }
        return result;
    }

    @Override
    public @NonNull ParceledListSlice<IntentFilterVerificationInfo> getIntentFilterVerifications(
            String packageName) {
        final int callingUid = Binder.getCallingUid();
        if (getInstantAppPackageName(callingUid) != null) {
            return ParceledListSlice.emptyList();
        }
        synchronized (mLock) {
            final PackageSetting ps = mSettings.mPackages.get(packageName);
            if (shouldFilterApplicationLocked(ps, callingUid, UserHandle.getUserId(callingUid))) {
                return ParceledListSlice.emptyList();
            }
            return new ParceledListSlice<>(mSettings.getIntentFilterVerificationsLPr(packageName));
        }
    }

    @Override
    public @NonNull ParceledListSlice<IntentFilter> getAllIntentFilters(String packageName) {
        if (TextUtils.isEmpty(packageName)) {
            return ParceledListSlice.emptyList();
        }
        final int callingUid = Binder.getCallingUid();
        final int callingUserId = UserHandle.getUserId(callingUid);
        synchronized (mLock) {
            AndroidPackage pkg = mPackages.get(packageName);
            if (pkg == null || ArrayUtils.isEmpty(pkg.getActivities())) {
                return ParceledListSlice.emptyList();
            }
            final PackageSetting ps = getPackageSetting(pkg.getPackageName());
            if (ps == null) {
                return ParceledListSlice.emptyList();
            }
            if (shouldFilterApplicationLocked(ps, callingUid, callingUserId)) {
                return ParceledListSlice.emptyList();
            }
            final int count = ArrayUtils.size(pkg.getActivities());
            ArrayList<IntentFilter> result = new ArrayList<>();
            for (int n=0; n<count; n++) {
                ParsedActivity activity = pkg.getActivities().get(n);
                if (activity.intents != null && activity.intents.size() > 0) {
                    result.addAll(activity.intents);
                }
            }
            return new ParceledListSlice<IntentFilter>(result) {
                @Override
                protected void writeElement(IntentFilter parcelable, Parcel dest, int callFlags) {
                    // IntentFilter has final Parcelable methods, so redirect to the subclass
                    ((ParsedActivityIntentInfo) parcelable).writeIntentInfoToParcel(dest,
                            callFlags);
                }
            };
        }
    }

    /**
     * Get the "allow unknown sources" setting.
     *
     * @return the current "allow unknown sources" setting
     */
    private int getUnknownSourcesSettings() {
        return android.provider.Settings.Secure.getInt(mContext.getContentResolver(),
                android.provider.Settings.Secure.INSTALL_NON_MARKET_APPS,
                -1);
    }

    @Override
    public void setInstallerPackageName(String targetPackage, String installerPackageName) {
        final int callingUid = Binder.getCallingUid();
        if (getInstantAppPackageName(callingUid) != null) {
            return;
        }
        // writer
        synchronized (mLock) {
            PackageSetting targetPackageSetting = mSettings.mPackages.get(targetPackage);
            if (targetPackageSetting == null
                    || shouldFilterApplicationLocked(
                            targetPackageSetting, callingUid, UserHandle.getUserId(callingUid))) {
                throw new IllegalArgumentException("Unknown target package: " + targetPackage);
            }

            PackageSetting installerPackageSetting;
            if (installerPackageName != null) {
                installerPackageSetting = mSettings.mPackages.get(installerPackageName);
                if (installerPackageSetting == null) {
                    throw new IllegalArgumentException("Unknown installer package: "
                            + installerPackageName);
                }
            } else {
                installerPackageSetting = null;
            }

            Signature[] callerSignature;
            final int appId = UserHandle.getAppId(callingUid);
            final Object obj = mSettings.getSettingLPr(appId);
            if (obj != null) {
                if (obj instanceof SharedUserSetting) {
                    callerSignature =
                            ((SharedUserSetting)obj).signatures.mSigningDetails.signatures;
                } else if (obj instanceof PackageSetting) {
                    callerSignature = ((PackageSetting)obj).signatures.mSigningDetails.signatures;
                } else {
                    throw new SecurityException("Bad object " + obj + " for uid " + callingUid);
                }
            } else {
                throw new SecurityException("Unknown calling UID: " + callingUid);
            }

            // Verify: can't set installerPackageName to a package that is
            // not signed with the same cert as the caller.
            if (installerPackageSetting != null) {
                if (compareSignatures(callerSignature,
                        installerPackageSetting.signatures.mSigningDetails.signatures)
                        != PackageManager.SIGNATURE_MATCH) {
                    throw new SecurityException(
                            "Caller does not have same cert as new installer package "
                            + installerPackageName);
                }
            }

            // Verify: if target already has an installer package, it must
            // be signed with the same cert as the caller.
            String targetInstallerPackageName =
                    targetPackageSetting.installSource.installerPackageName;
            if (targetInstallerPackageName != null) {
                PackageSetting setting = mSettings.mPackages.get(
                        targetInstallerPackageName);
                // If the currently set package isn't valid, then it's always
                // okay to change it.
                if (setting != null) {
                    if (compareSignatures(callerSignature,
                            setting.signatures.mSigningDetails.signatures)
                            != PackageManager.SIGNATURE_MATCH) {
                        throw new SecurityException(
                                "Caller does not have same cert as old installer package "
                                + targetInstallerPackageName);
                    }
                }
            }

            // Okay!
            targetPackageSetting.setInstallerPackageName(installerPackageName);
            if (installerPackageName != null) {
                mSettings.mInstallerPackages.add(installerPackageName);
            }
            scheduleWriteSettingsLocked();
        }
    }

    @Override
    public void setApplicationCategoryHint(String packageName, int categoryHint,
            String callerPackageName) {
        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
            throw new SecurityException("Instant applications don't have access to this method");
        }
        mInjector.getAppOpsManager().checkPackage(Binder.getCallingUid(),
                callerPackageName);
        synchronized (mLock) {
            PackageSetting ps = mSettings.mPackages.get(packageName);
            if (ps == null) {
                throw new IllegalArgumentException("Unknown target package " + packageName);
            }
            if (shouldFilterApplicationLocked(
                    ps, Binder.getCallingUid(), UserHandle.getCallingUserId())) {
                throw new IllegalArgumentException("Unknown target package " + packageName);
            }
            if (!Objects.equals(callerPackageName, ps.installSource.installerPackageName)) {
                throw new IllegalArgumentException("Calling package " + callerPackageName
                        + " is not installer for " + packageName);
            }

            if (ps.categoryHint != categoryHint) {
                ps.categoryHint = categoryHint;
                scheduleWriteSettingsLocked();
            }
        }
    }

    private void processPendingInstall(final InstallArgs args, final int currentStatus) {
        if (args.mMultiPackageInstallParams != null) {
            args.mMultiPackageInstallParams.tryProcessInstallRequest(args, currentStatus);
        } else {
            PackageInstalledInfo res = createPackageInstalledInfo(currentStatus);
            processInstallRequestsAsync(
                    res.returnCode == PackageManager.INSTALL_SUCCEEDED,
                    Collections.singletonList(new InstallRequest(args, res)));
        }
    }

    // Queue up an async operation since the package installation may take a little while.
    private void processInstallRequestsAsync(boolean success,
            List<InstallRequest> installRequests) {
        mHandler.post(() -> {
            if (success) {
                for (InstallRequest request : installRequests) {
                    request.args.doPreInstall(request.installResult.returnCode);
                }
                synchronized (mInstallLock) {
                    installPackagesTracedLI(installRequests);
                }
                for (InstallRequest request : installRequests) {
                    request.args.doPostInstall(
                            request.installResult.returnCode, request.installResult.uid);
                }
            }
            for (InstallRequest request : installRequests) {
                restoreAndPostInstall(request.args.user.getIdentifier(), request.installResult,
                        new PostInstallData(request.args, request.installResult, null));
            }
        });
    }

    private PackageInstalledInfo createPackageInstalledInfo(
            int currentStatus) {
        PackageInstalledInfo res = new PackageInstalledInfo();
        res.setReturnCode(currentStatus);
        res.uid = -1;
        res.pkg = null;
        res.removedInfo = null;
        return res;
    }

    /** @param data Post-install is performed only if this is non-null. */
    private void restoreAndPostInstall(
            int userId, PackageInstalledInfo res, @Nullable PostInstallData data) {
        if (DEBUG_INSTALL) {
            Log.v(TAG, "restoreAndPostInstall userId=" + userId + " package=" + res.pkg);
        }

        // A restore should be performed at this point if (a) the install
        // succeeded, (b) the operation is not an update, and (c) the new
        // package has not opted out of backup participation.
        final boolean update = res.removedInfo != null
                && res.removedInfo.removedPackage != null;
        final int flags = (res.pkg == null) ? 0 : res.pkg.getFlags();
        boolean doRestore = !update
                && ((flags & ApplicationInfo.FLAG_ALLOW_BACKUP) != 0);

        // Set up the post-install work request bookkeeping.  This will be used
        // and cleaned up by the post-install event handling regardless of whether
        // there's a restore pass performed.  Token values are >= 1.
        int token;
        if (mNextInstallToken < 0) mNextInstallToken = 1;
        token = mNextInstallToken++;
        if (data != null) {
            mRunningInstalls.put(token, data);
        } else if (DEBUG_INSTALL) {
            Log.v(TAG, "No post-install required for " + token);
        }

        if (DEBUG_INSTALL) Log.v(TAG, "+ starting restore round-trip " + token);

        if (res.returnCode == PackageManager.INSTALL_SUCCEEDED && doRestore) {
            // Pass responsibility to the Backup Manager.  It will perform a
            // restore if appropriate, then pass responsibility back to the
            // Package Manager to run the post-install observer callbacks
            // and broadcasts.
            if (res.freezer != null) {
                res.freezer.close();
            }
            doRestore = performBackupManagerRestore(userId, token, res);
        }

        // If this is an update to a package that might be potentially downgraded, then we
        // need to check with the rollback manager whether there's any userdata that might
        // need to be snapshotted or restored for the package.
        //
        // TODO(narayan): Get this working for cases where userId == UserHandle.USER_ALL.
        if (res.returnCode == PackageManager.INSTALL_SUCCEEDED && !doRestore && update) {
            doRestore = performRollbackManagerRestore(userId, token, res, data);
        }

        if (!doRestore) {
            // No restore possible, or the Backup Manager was mysteriously not
            // available -- just fire the post-install work request directly.
            if (DEBUG_INSTALL) Log.v(TAG, "No restore - queue post-install for " + token);

            Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "postInstall", token);

            Message msg = mHandler.obtainMessage(POST_INSTALL, token, 0);
            mHandler.sendMessage(msg);
        }
    }

    /**
     * Perform Backup Manager restore for a given {@link PackageInstalledInfo}.
     * Returns whether the restore successfully completed.
     */
    private boolean performBackupManagerRestore(int userId, int token, PackageInstalledInfo res) {
        IBackupManager bm = IBackupManager.Stub.asInterface(
                ServiceManager.getService(Context.BACKUP_SERVICE));
        if (bm != null) {
            // For backwards compatibility as USER_ALL previously routed directly to USER_SYSTEM
            // in the BackupManager. USER_ALL is used in compatibility tests.
            if (userId == UserHandle.USER_ALL) {
                userId = UserHandle.USER_SYSTEM;
            }
            if (DEBUG_INSTALL) {
                Log.v(TAG, "token " + token + " to BM for possible restore for user " + userId);
            }
            Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "restore", token);
            try {
                if (bm.isBackupServiceActive(userId)) {
                    bm.restoreAtInstallForUser(
                            userId, res.pkg.getAppInfoPackageName(), token);
                } else {
                    return false;
                }
            } catch (RemoteException e) {
                // can't happen; the backup manager is local
            } catch (Exception e) {
                Slog.e(TAG, "Exception trying to enqueue restore", e);
                return false;
            }
        } else {
            Slog.e(TAG, "Backup Manager not found!");
            return false;
        }
        return true;
    }

    /**
     * Perform Rollback Manager restore for a given {@link PackageInstalledInfo}.
     * Returns whether the restore successfully completed.
     */
    private boolean performRollbackManagerRestore(int userId, int token, PackageInstalledInfo res,
            PostInstallData data) {
        IRollbackManager rm = IRollbackManager.Stub.asInterface(
                ServiceManager.getService(Context.ROLLBACK_SERVICE));

        final String packageName = res.pkg.getAppInfoPackageName();
        final String seInfo = res.pkg.getSeInfo();
        final int[] allUsers = mUserManager.getUserIds();
        final int[] installedUsers;

        final PackageSetting ps;
        int appId = -1;
        long ceDataInode = -1;
        synchronized (mSettings) {
            ps = mSettings.getPackageLPr(packageName);
            if (ps != null) {
                appId = ps.appId;
                ceDataInode = ps.getCeDataInode(userId);
            }

            // NOTE: We ignore the user specified in the InstallParam because we know this is
            // an update, and hence need to restore data for all installed users.
            installedUsers = ps.queryInstalledUsers(allUsers, true);
        }

        boolean doSnapshotOrRestore = data != null && data.args != null
                && ((data.args.installFlags & PackageManager.INSTALL_ENABLE_ROLLBACK) != 0
                || (data.args.installFlags & PackageManager.INSTALL_REQUEST_DOWNGRADE) != 0);

        if (ps != null && doSnapshotOrRestore) {
            try {
                rm.snapshotAndRestoreUserData(packageName, installedUsers, appId, ceDataInode,
                        seInfo, token);
            } catch (RemoteException re) {
                Log.e(TAG, "Error snapshotting/restoring user data: " + re);
                return false;
            }
            return true;
        }
        return false;
    }

    /**
     * Callback from PackageSettings whenever an app is first transitioned out of the
     * 'stopped' state.  Normally we just issue the broadcast, but we can't do that if
     * the app was "launched" for a restoreAtInstall operation.  Therefore we check
     * here whether the app is the target of an ongoing install, and only send the
     * broadcast immediately if it is not in that state.  If it *is* undergoing a restore,
     * the first-launch broadcast will be sent implicitly on that basis in POST_INSTALL
     * handling.
     */
    void notifyFirstLaunch(final String packageName, final String installerPackage,
            final int userId) {
        // Serialize this with the rest of the install-process message chain.  In the
        // restore-at-install case, this Runnable will necessarily run before the
        // POST_INSTALL message is processed, so the contents of mRunningInstalls
        // are coherent.  In the non-restore case, the app has already completed install
        // and been launched through some other means, so it is not in a problematic
        // state for observers to see the FIRST_LAUNCH signal.
        mHandler.post(() -> {
            for (int i = 0; i < mRunningInstalls.size(); i++) {
                final PostInstallData data = mRunningInstalls.valueAt(i);
                if (data.res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
                    continue;
                }
                if (packageName.equals(data.res.pkg.getAppInfoPackageName())) {
                    // right package; but is it for the right user?
                    for (int uIndex = 0; uIndex < data.res.newUsers.length; uIndex++) {
                        if (userId == data.res.newUsers[uIndex]) {
                            if (DEBUG_BACKUP) {
                                Slog.i(TAG, "Package " + packageName
                                        + " being restored so deferring FIRST_LAUNCH");
                            }
                            return;
                        }
                    }
                }
            }
            // didn't find it, so not being restored
            if (DEBUG_BACKUP) {
                Slog.i(TAG, "Package " + packageName + " sending normal FIRST_LAUNCH");
            }
            final boolean isInstantApp = isInstantApp(packageName, userId);
            final int[] userIds = isInstantApp ? EMPTY_INT_ARRAY : new int[] { userId };
            final int[] instantUserIds = isInstantApp ? new int[] { userId } : EMPTY_INT_ARRAY;
            sendFirstLaunchBroadcast(packageName, installerPackage, userIds, instantUserIds);
        });
    }

    private void sendFirstLaunchBroadcast(String pkgName, String installerPkg,
            int[] userIds, int[] instantUserIds) {
        sendPackageBroadcast(Intent.ACTION_PACKAGE_FIRST_LAUNCH, pkgName, null, 0,
                installerPkg, null, userIds, instantUserIds);
    }

    private abstract class HandlerParams {
        /** User handle for the user requesting the information or installation. */
        private final UserHandle mUser;
        String traceMethod;
        int traceCookie;

        HandlerParams(UserHandle user) {
            mUser = user;
        }

        UserHandle getUser() {
            return mUser;
        }

        /**
         * Gets the user handle for the user that the rollback agent should
         * use to look up information about this installation when enabling
         * rollback.
         */
        UserHandle getRollbackUser() {
            // The session for packages installed for "all" users is
            // associated with the "system" user.
            if (mUser == UserHandle.ALL) {
                return UserHandle.SYSTEM;
            }
            return mUser;
        }

        HandlerParams setTraceMethod(String traceMethod) {
            this.traceMethod = traceMethod;
            return this;
        }

        HandlerParams setTraceCookie(int traceCookie) {
            this.traceCookie = traceCookie;
            return this;
        }

        final void startCopy() {
            if (DEBUG_INSTALL) Slog.i(TAG, "startCopy " + mUser + ": " + this);
            handleStartCopy();
            handleReturnCode();
        }

        abstract void handleStartCopy();
        abstract void handleReturnCode();
    }

    static class OriginInfo {
        /**
         * Location where install is coming from, before it has been
         * copied/renamed into place. This could be a single monolithic APK
         * file, or a cluster directory. This location may be untrusted.
         */
        final File file;

        /**
         * Flag indicating that {@link #file} has already been staged, meaning downstream users
         * don't need to defensively copy the contents.
         */
        final boolean staged;

        /**
         * Flag indicating that {@link #file} is an already installed app that is being moved.
         */
        final boolean existing;

        final String resolvedPath;
        final File resolvedFile;

        static OriginInfo fromNothing() {
            return new OriginInfo(null, false, false);
        }

        static OriginInfo fromUntrustedFile(File file) {
            return new OriginInfo(file, false, false);
        }

        static OriginInfo fromExistingFile(File file) {
            return new OriginInfo(file, false, true);
        }

        static OriginInfo fromStagedFile(File file) {
            return new OriginInfo(file, true, false);
        }

        private OriginInfo(File file, boolean staged, boolean existing) {
            this.file = file;
            this.staged = staged;
            this.existing = existing;

            if (file != null) {
                resolvedPath = file.getAbsolutePath();
                resolvedFile = file;
            } else {
                resolvedPath = null;
                resolvedFile = null;
            }
        }
    }

    static class MoveInfo {
        final int moveId;
        final String fromUuid;
        final String toUuid;
        final String packageName;
        final String dataAppName;
        final int appId;
        final String seinfo;
        final int targetSdkVersion;

        public MoveInfo(int moveId, String fromUuid, String toUuid, String packageName,
                String dataAppName, int appId, String seinfo, int targetSdkVersion) {
            this.moveId = moveId;
            this.fromUuid = fromUuid;
            this.toUuid = toUuid;
            this.packageName = packageName;
            this.dataAppName = dataAppName;
            this.appId = appId;
            this.seinfo = seinfo;
            this.targetSdkVersion = targetSdkVersion;
        }
    }

    static class VerificationInfo {
        /** A constant used to indicate that a uid value is not present. */
        public static final int NO_UID = -1;

        /** URI referencing where the package was downloaded from. */
        final Uri originatingUri;

        /** HTTP referrer URI associated with the originatingURI. */
        final Uri referrer;

        /** UID of the application that the install request originated from. */
        final int originatingUid;

        /** UID of application requesting the install */
        final int installerUid;

        VerificationInfo(Uri originatingUri, Uri referrer, int originatingUid, int installerUid) {
            this.originatingUri = originatingUri;
            this.referrer = referrer;
            this.originatingUid = originatingUid;
            this.installerUid = installerUid;
        }
    }

    /**
     * Container for a multi-package install which refers to all install sessions and args being
     * committed together.
     */
    class MultiPackageInstallParams extends HandlerParams {

        private int mRet = INSTALL_SUCCEEDED;
        @NonNull
        private final ArrayList<InstallParams> mChildParams;
        @NonNull
        private final Map<InstallArgs, Integer> mCurrentState;

        MultiPackageInstallParams(
                @NonNull UserHandle user,
                @NonNull List<ActiveInstallSession> activeInstallSessions)
                throws PackageManagerException {
            super(user);
            if (activeInstallSessions.size() == 0) {
                throw new PackageManagerException("No child sessions found!");
            }
            mChildParams = new ArrayList<>(activeInstallSessions.size());
            for (int i = 0; i < activeInstallSessions.size(); i++) {
                final InstallParams childParams = new InstallParams(activeInstallSessions.get(i));
                childParams.mParentInstallParams = this;
                this.mChildParams.add(childParams);
            }
            this.mCurrentState = new ArrayMap<>(mChildParams.size());
        }

        @Override
        void handleStartCopy() {
            for (InstallParams params : mChildParams) {
                params.handleStartCopy();
                if (params.mRet != INSTALL_SUCCEEDED) {
                    mRet = params.mRet;
                }
            }
        }

        @Override
        void handleReturnCode() {
            for (InstallParams params : mChildParams) {
                params.handleReturnCode();
                if (params.mRet != INSTALL_SUCCEEDED) {
                    mRet = params.mRet;
                }
            }
        }

        void tryProcessInstallRequest(InstallArgs args, int currentStatus) {
            mCurrentState.put(args, currentStatus);
            if (mCurrentState.size() != mChildParams.size()) {
                return;
            }
            int completeStatus = PackageManager.INSTALL_SUCCEEDED;
            for (Integer status : mCurrentState.values()) {
                if (status == PackageManager.INSTALL_UNKNOWN) {
                    return;
                } else if (status != PackageManager.INSTALL_SUCCEEDED) {
                    completeStatus = status;
                    break;
                }
            }
            final List<InstallRequest> installRequests = new ArrayList<>(mCurrentState.size());
            for (Map.Entry<InstallArgs, Integer> entry : mCurrentState.entrySet()) {
                installRequests.add(new InstallRequest(entry.getKey(),
                        createPackageInstalledInfo(completeStatus)));
            }
            processInstallRequestsAsync(
                    completeStatus == PackageManager.INSTALL_SUCCEEDED,
                    installRequests);
        }
    }

    class InstallParams extends HandlerParams {
        // TODO: see if we can collapse this into ActiveInstallSession

        final OriginInfo origin;
        final MoveInfo move;
        final IPackageInstallObserver2 observer;
        int installFlags;
        @NonNull final InstallSource installSource;
        final String volumeUuid;
        private boolean mVerificationCompleted;
        private boolean mEnableRollbackCompleted;
        private InstallArgs mArgs;
        int mRet;
        final String packageAbiOverride;
        final String[] grantedRuntimePermissions;
        final List<String> whitelistedRestrictedPermissions;
        final VerificationInfo verificationInfo;
        final PackageParser.SigningDetails signingDetails;
        final int installReason;
        @Nullable
        MultiPackageInstallParams mParentInstallParams;
        final long requiredInstalledVersionCode;

        InstallParams(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer,
                int installFlags, InstallSource installSource, String volumeUuid,
                VerificationInfo verificationInfo, UserHandle user, String packageAbiOverride,
                String[] grantedPermissions, List<String> whitelistedRestrictedPermissions,
                SigningDetails signingDetails, int installReason,
                long requiredInstalledVersionCode) {
            super(user);
            this.origin = origin;
            this.move = move;
            this.observer = observer;
            this.installFlags = installFlags;
            this.installSource = Preconditions.checkNotNull(installSource);
            this.volumeUuid = volumeUuid;
            this.verificationInfo = verificationInfo;
            this.packageAbiOverride = packageAbiOverride;
            this.grantedRuntimePermissions = grantedPermissions;
            this.whitelistedRestrictedPermissions = whitelistedRestrictedPermissions;
            this.signingDetails = signingDetails;
            this.installReason = installReason;
            this.requiredInstalledVersionCode = requiredInstalledVersionCode;
        }

        InstallParams(ActiveInstallSession activeInstallSession) {
            super(activeInstallSession.getUser());
            if (DEBUG_INSTANT) {
                if ((activeInstallSession.getSessionParams().installFlags
                        & PackageManager.INSTALL_INSTANT_APP) != 0) {
                    Slog.d(TAG, "Ephemeral install of " + activeInstallSession.getPackageName());
                }
            }
            verificationInfo = new VerificationInfo(
                    activeInstallSession.getSessionParams().originatingUri,
                    activeInstallSession.getSessionParams().referrerUri,
                    activeInstallSession.getSessionParams().originatingUid,
                    activeInstallSession.getInstallerUid());
            origin = OriginInfo.fromStagedFile(activeInstallSession.getStagedDir());
            move = null;
            installReason = fixUpInstallReason(
                    activeInstallSession.getInstallSource().installerPackageName,
                    activeInstallSession.getInstallerUid(),
                    activeInstallSession.getSessionParams().installReason);
            observer = activeInstallSession.getObserver();
            installFlags = activeInstallSession.getSessionParams().installFlags;
            installSource = activeInstallSession.getInstallSource();
            volumeUuid = activeInstallSession.getSessionParams().volumeUuid;
            packageAbiOverride = activeInstallSession.getSessionParams().abiOverride;
            grantedRuntimePermissions = activeInstallSession.getSessionParams()
                    .grantedRuntimePermissions;
            whitelistedRestrictedPermissions = activeInstallSession.getSessionParams()
                    .whitelistedRestrictedPermissions;
            signingDetails = activeInstallSession.getSigningDetails();
            requiredInstalledVersionCode = activeInstallSession.getSessionParams()
                    .requiredInstalledVersionCode;
        }

        @Override
        public String toString() {
            return "InstallParams{" + Integer.toHexString(System.identityHashCode(this))
                    + " file=" + origin.file + "}";
        }

        private int installLocationPolicy(PackageInfoLite pkgLite) {
            String packageName = pkgLite.packageName;
            int installLocation = pkgLite.installLocation;
            // reader
            synchronized (mLock) {
                // Currently installed package which the new package is attempting to replace or
                // null if no such package is installed.
                AndroidPackage installedPkg = mPackages.get(packageName);
                // Package which currently owns the data which the new package will own if installed.
                // If an app is unstalled while keeping data (e.g., adb uninstall -k), installedPkg
                // will be null whereas dataOwnerPkg will contain information about the package
                // which was uninstalled while keeping its data.
                AndroidPackage dataOwnerPkg = installedPkg;
                if (dataOwnerPkg  == null) {
                    PackageSetting ps = mSettings.mPackages.get(packageName);
                    if (ps != null) {
                        dataOwnerPkg = ps.pkg;
                    }
                }

                if (requiredInstalledVersionCode != PackageManager.VERSION_CODE_HIGHEST) {
                    if (dataOwnerPkg == null) {
                        Slog.w(TAG, "Required installed version code was "
                                + requiredInstalledVersionCode
                                + " but package is not installed");
                        return PackageHelper.RECOMMEND_FAILED_WRONG_INSTALLED_VERSION;
                    }

                    if (dataOwnerPkg.getLongVersionCode() != requiredInstalledVersionCode) {
                        Slog.w(TAG, "Required installed version code was "
                                + requiredInstalledVersionCode
                                + " but actual installed version is "
                                + dataOwnerPkg.getLongVersionCode());
                        return PackageHelper.RECOMMEND_FAILED_WRONG_INSTALLED_VERSION;
                    }
                }

                if (dataOwnerPkg != null) {
                    if (!PackageManagerServiceUtils.isDowngradePermitted(installFlags,
                            dataOwnerPkg.getFlags())) {
                        try {
                            checkDowngrade(dataOwnerPkg, pkgLite);
                        } catch (PackageManagerException e) {
                            Slog.w(TAG, "Downgrade detected: " + e.getMessage());
                            return PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE;
                        }
                    }
                }

                if (installedPkg != null) {
                    if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) {
                        // Check for updated system application.
                        if ((installedPkg.getFlags() & ApplicationInfo.FLAG_SYSTEM) != 0) {
                            return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
                        } else {
                            // If current upgrade specifies particular preference
                            if (installLocation == PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY) {
                                // Application explicitly specified internal.
                                return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
                            } else if (installLocation == PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL) {
                                // App explictly prefers external. Let policy decide
                            } else {
                                // Prefer previous location
                                if (isExternal(installedPkg)) {
                                    return PackageHelper.RECOMMEND_INSTALL_EXTERNAL;
                                }
                                return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
                            }
                        }
                    } else {
                        // Invalid install. Return error code
                        return PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS;
                    }
                }
            }
            return pkgLite.recommendedInstallLocation;
        }

        /*
         * Invoke remote method to get package information and install
         * location values. Override install location based on default
         * policy if needed and then create install arguments based
         * on the install location.
         */
        public void handleStartCopy() {
            int ret = PackageManager.INSTALL_SUCCEEDED;

            // If we're already staged, we've firmly committed to an install location
            if (origin.staged) {
                if (origin.file != null) {
                    installFlags |= PackageManager.INSTALL_INTERNAL;
                } else {
                    throw new IllegalStateException("Invalid stage location");
                }
            }

            final boolean onInt = (installFlags & PackageManager.INSTALL_INTERNAL) != 0;
            final boolean ephemeral = (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
            PackageInfoLite pkgLite = null;


            pkgLite = PackageManagerServiceUtils.getMinimalPackageInfo(mContext,
                    origin.resolvedPath, installFlags, packageAbiOverride);

            if (DEBUG_INSTANT && ephemeral) {
                Slog.v(TAG, "pkgLite for install: " + pkgLite);
            }

            /*
             * If we have too little free space, try to free cache
             * before giving up.
             */
            if (!origin.staged && pkgLite.recommendedInstallLocation
                    == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) {
                // TODO: focus freeing disk space on the target device
                final StorageManager storage = StorageManager.from(mContext);
                final long lowThreshold = storage.getStorageLowBytes(
                        Environment.getDataDirectory());

                final long sizeBytes = PackageManagerServiceUtils.calculateInstalledSize(
                        origin.resolvedPath, packageAbiOverride);
                if (sizeBytes >= 0) {
                    try {
                        mInstaller.freeCache(null, sizeBytes + lowThreshold, 0, 0);
                        pkgLite = PackageManagerServiceUtils.getMinimalPackageInfo(mContext,
                                origin.resolvedPath, installFlags, packageAbiOverride);
                    } catch (InstallerException e) {
                        Slog.w(TAG, "Failed to free cache", e);
                    }
                }

                /*
                 * The cache free must have deleted the file we downloaded to install.
                 *
                 * TODO: fix the "freeCache" call to not delete the file we care about.
                 */
                if (pkgLite.recommendedInstallLocation
                        == PackageHelper.RECOMMEND_FAILED_INVALID_URI) {
                    pkgLite.recommendedInstallLocation
                            = PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE;
                }
            }


            if (ret == PackageManager.INSTALL_SUCCEEDED) {
                int loc = pkgLite.recommendedInstallLocation;
                if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_LOCATION) {
                    ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION;
                } else if (loc == PackageHelper.RECOMMEND_FAILED_ALREADY_EXISTS) {
                    ret = PackageManager.INSTALL_FAILED_ALREADY_EXISTS;
                } else if (loc == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) {
                    ret = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
                } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_APK) {
                    ret = PackageManager.INSTALL_FAILED_INVALID_APK;
                } else if (loc == PackageHelper.RECOMMEND_FAILED_INVALID_URI) {
                    ret = PackageManager.INSTALL_FAILED_INVALID_URI;
                } else if (loc == PackageHelper.RECOMMEND_MEDIA_UNAVAILABLE) {
                    ret = PackageManager.INSTALL_FAILED_MEDIA_UNAVAILABLE;
                } else {
                    // Override with defaults if needed.
                    loc = installLocationPolicy(pkgLite);
                    if (loc == PackageHelper.RECOMMEND_FAILED_VERSION_DOWNGRADE) {
                        ret = PackageManager.INSTALL_FAILED_VERSION_DOWNGRADE;
                    } else if (loc == PackageHelper.RECOMMEND_FAILED_WRONG_INSTALLED_VERSION) {
                        ret = PackageManager.INSTALL_FAILED_WRONG_INSTALLED_VERSION;
                    } else if (!onInt) {
                        // Override install location with flags
                        if (loc == PackageHelper.RECOMMEND_INSTALL_EXTERNAL) {
                            // Set the flag to install on external media.
                            installFlags &= ~PackageManager.INSTALL_INTERNAL;
                        } else if (loc == PackageHelper.RECOMMEND_INSTALL_EPHEMERAL) {
                            if (DEBUG_INSTANT) {
                                Slog.v(TAG, "...setting INSTALL_EPHEMERAL install flag");
                            }
                            installFlags |= PackageManager.INSTALL_INSTANT_APP;
                            installFlags &= ~PackageManager.INSTALL_INTERNAL;
                        } else {
                            // Make sure the flag for installing on external
                            // media is unset
                            installFlags |= PackageManager.INSTALL_INTERNAL;
                        }
                    }
                }
            }

            final InstallArgs args = createInstallArgs(this);
            mVerificationCompleted = true;
            mEnableRollbackCompleted = true;
            mArgs = args;

            if (ret == PackageManager.INSTALL_SUCCEEDED) {
                // TODO: http://b/22976637
                // Apps installed for "all" users use the device owner to verify the app
                UserHandle verifierUser = getUser();
                if (verifierUser == UserHandle.ALL) {
                    verifierUser = UserHandle.SYSTEM;
                }

                /*
                 * Determine if we have any installed package verifiers. If we
                 * do, then we'll defer to them to verify the packages.
                 */
                final int requiredUid = mRequiredVerifierPackage == null ? -1
                        : getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING,
                                verifierUser.getIdentifier());
                final int installerUid =
                        verificationInfo == null ? -1 : verificationInfo.installerUid;
                if (!origin.existing && requiredUid != -1
                        && isVerificationEnabled(
                                verifierUser.getIdentifier(), installFlags, installerUid)) {
                    final Intent verification = new Intent(
                            Intent.ACTION_PACKAGE_NEEDS_VERIFICATION);
                    verification.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
                    verification.setDataAndType(Uri.fromFile(new File(origin.resolvedPath)),
                            PACKAGE_MIME_TYPE);
                    verification.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);

                    // Query all live verifiers based on current user state
                    final List<ResolveInfo> receivers = queryIntentReceiversInternal(verification,
                            PACKAGE_MIME_TYPE, 0, verifierUser.getIdentifier(),
                            false /*allowDynamicSplits*/);

                    if (DEBUG_VERIFY) {
                        Slog.d(TAG, "Found " + receivers.size() + " verifiers for intent "
                                + verification.toString() + " with " + pkgLite.verifiers.length
                                + " optional verifiers");
                    }

                    final int verificationId = mPendingVerificationToken++;

                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId);

                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_PACKAGE,
                            installSource.installerPackageName);

                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALL_FLAGS,
                            installFlags);

                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_PACKAGE_NAME,
                            pkgLite.packageName);

                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_VERSION_CODE,
                            pkgLite.versionCode);

                    verification.putExtra(PackageManager.EXTRA_VERIFICATION_LONG_VERSION_CODE,
                            pkgLite.getLongVersionCode());

                    if (verificationInfo != null) {
                        if (verificationInfo.originatingUri != null) {
                            verification.putExtra(Intent.EXTRA_ORIGINATING_URI,
                                    verificationInfo.originatingUri);
                        }
                        if (verificationInfo.referrer != null) {
                            verification.putExtra(Intent.EXTRA_REFERRER,
                                    verificationInfo.referrer);
                        }
                        if (verificationInfo.originatingUid >= 0) {
                            verification.putExtra(Intent.EXTRA_ORIGINATING_UID,
                                    verificationInfo.originatingUid);
                        }
                        if (verificationInfo.installerUid >= 0) {
                            verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_UID,
                                    verificationInfo.installerUid);
                        }
                    }

                    final PackageVerificationState verificationState = new PackageVerificationState(
                            requiredUid, this);

                    mPendingVerification.append(verificationId, verificationState);

                    final List<ComponentName> sufficientVerifiers = matchVerifiers(pkgLite,
                            receivers, verificationState);

                    DeviceIdleInternal idleController =
                            mInjector.getLocalDeviceIdleController();
                    final long idleDuration = getVerificationTimeout();

                    /*
                     * If any sufficient verifiers were listed in the package
                     * manifest, attempt to ask them.
                     */
                    if (sufficientVerifiers != null) {
                        final int N = sufficientVerifiers.size();
                        if (N == 0) {
                            Slog.i(TAG, "Additional verifiers required, but none installed.");
                            ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
                        } else {
                            for (int i = 0; i < N; i++) {
                                final ComponentName verifierComponent = sufficientVerifiers.get(i);
                                idleController.addPowerSaveTempWhitelistApp(Process.myUid(),
                                        verifierComponent.getPackageName(), idleDuration,
                                        verifierUser.getIdentifier(), false, "package verifier");

                                final Intent sufficientIntent = new Intent(verification);
                                sufficientIntent.setComponent(verifierComponent);
                                mContext.sendBroadcastAsUser(sufficientIntent, verifierUser);
                            }
                        }
                    }

                    final ComponentName requiredVerifierComponent = matchComponentForVerifier(
                            mRequiredVerifierPackage, receivers);
                    if (ret == PackageManager.INSTALL_SUCCEEDED
                            && mRequiredVerifierPackage != null) {
                        Trace.asyncTraceBegin(
                                TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId);
                        /*
                         * Send the intent to the required verification agent,
                         * but only start the verification timeout after the
                         * target BroadcastReceivers have run.
                         */
                        verification.setComponent(requiredVerifierComponent);
                        idleController.addPowerSaveTempWhitelistApp(Process.myUid(),
                                mRequiredVerifierPackage, idleDuration,
                                verifierUser.getIdentifier(), false, "package verifier");
                        mContext.sendOrderedBroadcastAsUser(verification, verifierUser,
                                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
                                new BroadcastReceiver() {
                                    @Override
                                    public void onReceive(Context context, Intent intent) {
                                        final Message msg = mHandler
                                                .obtainMessage(CHECK_PENDING_VERIFICATION);
                                        msg.arg1 = verificationId;
                                        mHandler.sendMessageDelayed(msg, getVerificationTimeout());
                                    }
                                }, null, 0, null, null);

                        /*
                         * We don't want the copy to proceed until verification
                         * succeeds.
                         */
                        mVerificationCompleted = false;
                    }
                }

                if ((installFlags & PackageManager.INSTALL_ENABLE_ROLLBACK) != 0) {
                    // TODO(ruhler) b/112431924: Don't do this in case of 'move'?
                    final int enableRollbackToken = mPendingEnableRollbackToken++;
                    Trace.asyncTraceBegin(
                            TRACE_TAG_PACKAGE_MANAGER, "enable_rollback", enableRollbackToken);
                    mPendingEnableRollback.append(enableRollbackToken, this);

                    Intent enableRollbackIntent = new Intent(Intent.ACTION_PACKAGE_ENABLE_ROLLBACK);
                    enableRollbackIntent.putExtra(
                            PackageManagerInternal.EXTRA_ENABLE_ROLLBACK_TOKEN,
                            enableRollbackToken);
                    enableRollbackIntent.putExtra(
                            PackageManagerInternal.EXTRA_ENABLE_ROLLBACK_INSTALL_FLAGS,
                            installFlags);
                    enableRollbackIntent.putExtra(
                            PackageManagerInternal.EXTRA_ENABLE_ROLLBACK_USER,
                            getRollbackUser().getIdentifier());
                    enableRollbackIntent.setDataAndType(Uri.fromFile(new File(origin.resolvedPath)),
                            PACKAGE_MIME_TYPE);
                    enableRollbackIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);

                    // Allow the broadcast to be sent before boot complete.
                    // This is needed when committing the apk part of a staged
                    // session in early boot. The rollback manager registers
                    // its receiver early enough during the boot process that
                    // it will not miss the broadcast.
                    enableRollbackIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);

                    mContext.sendOrderedBroadcastAsUser(enableRollbackIntent, UserHandle.SYSTEM,
                            android.Manifest.permission.PACKAGE_ROLLBACK_AGENT,
                            new BroadcastReceiver() {
                                @Override
                                public void onReceive(Context context, Intent intent) {
                                    // the duration to wait for rollback to be enabled, in millis
                                    long rollbackTimeout = DeviceConfig.getLong(
                                            DeviceConfig.NAMESPACE_ROLLBACK,
                                            PROPERTY_ENABLE_ROLLBACK_TIMEOUT_MILLIS,
                                            DEFAULT_ENABLE_ROLLBACK_TIMEOUT_MILLIS);
                                    if (rollbackTimeout < 0) {
                                        rollbackTimeout = DEFAULT_ENABLE_ROLLBACK_TIMEOUT_MILLIS;
                                    }
                                    final Message msg = mHandler.obtainMessage(
                                            ENABLE_ROLLBACK_TIMEOUT);
                                    msg.arg1 = enableRollbackToken;
                                    mHandler.sendMessageDelayed(msg, rollbackTimeout);
                                }
                            }, null, 0, null, null);

                    mEnableRollbackCompleted = false;
                }
            }

            mRet = ret;
        }

        void setReturnCode(int ret) {
            if (mRet == PackageManager.INSTALL_SUCCEEDED) {
                // Only update mRet if it was previously INSTALL_SUCCEEDED to
                // ensure we do not overwrite any previous failure results.
                mRet = ret;
            }
        }

        void handleVerificationFinished() {
            mVerificationCompleted = true;
            handleReturnCode();
        }

        void handleRollbackEnabled() {
            // TODO(ruhler) b/112431924: Consider halting the install if we
            // couldn't enable rollback.
            mEnableRollbackCompleted = true;
            handleReturnCode();
        }

        @Override
        void handleReturnCode() {
            if (mVerificationCompleted && mEnableRollbackCompleted) {
                if ((installFlags & PackageManager.INSTALL_DRY_RUN) != 0) {
                    String packageName = "";
                    try {
                        PackageLite packageInfo =
                                new PackageParser().parsePackageLite(origin.file, 0);
                        packageName = packageInfo.packageName;
                    } catch (PackageParserException e) {
                        Slog.e(TAG, "Can't parse package at " + origin.file.getAbsolutePath(), e);
                    }
                    try {
                        observer.onPackageInstalled(packageName, mRet, "Dry run", new Bundle());
                    } catch (RemoteException e) {
                        Slog.i(TAG, "Observer no longer exists.");
                    }
                    return;
                }
                if (mRet == PackageManager.INSTALL_SUCCEEDED) {
                    mRet = mArgs.copyApk();
                }
                processPendingInstall(mArgs, mRet);
            }
        }
    }

    private InstallArgs createInstallArgs(InstallParams params) {
        if (params.move != null) {
            return new MoveInstallArgs(params);
        } else {
            return new FileInstallArgs(params);
        }
    }

    /**
     * Create args that describe an existing installed package. Typically used
     * when cleaning up old installs, or used as a move source.
     */
    private InstallArgs createInstallArgsForExisting(String codePath,
            String resourcePath, String[] instructionSets) {
        return new FileInstallArgs(codePath, resourcePath, instructionSets);
    }

    static abstract class InstallArgs {
        /** @see InstallParams#origin */
        final OriginInfo origin;
        /** @see InstallParams#move */
        final MoveInfo move;

        final IPackageInstallObserver2 observer;
        // Always refers to PackageManager flags only
        final int installFlags;
        @NonNull final InstallSource installSource;
        final String volumeUuid;
        final UserHandle user;
        final String abiOverride;
        final String[] installGrantPermissions;
        final List<String> whitelistedRestrictedPermissions;
        /** If non-null, drop an async trace when the install completes */
        final String traceMethod;
        final int traceCookie;
        final PackageParser.SigningDetails signingDetails;
        final int installReason;
        @Nullable final MultiPackageInstallParams mMultiPackageInstallParams;

        // The list of instruction sets supported by this app. This is currently
        // only used during the rmdex() phase to clean up resources. We can get rid of this
        // if we move dex files under the common app path.
        /* nullable */ String[] instructionSets;

        InstallArgs(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer,
                int installFlags, InstallSource installSource, String volumeUuid,
                UserHandle user, String[] instructionSets,
                String abiOverride, String[] installGrantPermissions,
                List<String> whitelistedRestrictedPermissions,
                String traceMethod, int traceCookie, SigningDetails signingDetails,
                int installReason,
                MultiPackageInstallParams multiPackageInstallParams) {
            this.origin = origin;
            this.move = move;
            this.installFlags = installFlags;
            this.observer = observer;
            this.installSource = Preconditions.checkNotNull(installSource);
            this.volumeUuid = volumeUuid;
            this.user = user;
            this.instructionSets = instructionSets;
            this.abiOverride = abiOverride;
            this.installGrantPermissions = installGrantPermissions;
            this.whitelistedRestrictedPermissions = whitelistedRestrictedPermissions;
            this.traceMethod = traceMethod;
            this.traceCookie = traceCookie;
            this.signingDetails = signingDetails;
            this.installReason = installReason;
            this.mMultiPackageInstallParams = multiPackageInstallParams;
        }

        /** New install */
        InstallArgs(InstallParams params) {
            this(params.origin, params.move, params.observer, params.installFlags,
                    params.installSource, params.volumeUuid,
                    params.getUser(), null /*instructionSets*/, params.packageAbiOverride,
                    params.grantedRuntimePermissions, params.whitelistedRestrictedPermissions,
                    params.traceMethod, params.traceCookie, params.signingDetails,
                    params.installReason, params.mParentInstallParams);
        }

        abstract int copyApk();
        abstract int doPreInstall(int status);

        /**
         * Rename package into final resting place. All paths on the given
         * scanned package should be updated to reflect the rename.
         */
        abstract boolean doRename(int status, ParsedPackage parsedPackage);
        abstract int doPostInstall(int status, int uid);

        /** @see PackageSettingBase#codePathString */
        abstract String getCodePath();
        /** @see PackageSettingBase#resourcePathString */
        abstract String getResourcePath();

        // Need installer lock especially for dex file removal.
        abstract void cleanUpResourcesLI();
        abstract boolean doPostDeleteLI(boolean delete);

        /**
         * Called before the source arguments are copied. This is used mostly
         * for MoveParams when it needs to read the source file to put it in the
         * destination.
         */
        int doPreCopy() {
            return PackageManager.INSTALL_SUCCEEDED;
        }

        /**
         * Called after the source arguments are copied. This is used mostly for
         * MoveParams when it needs to read the source file to put it in the
         * destination.
         */
        int doPostCopy(int uid) {
            return PackageManager.INSTALL_SUCCEEDED;
        }

        protected boolean isEphemeral() {
            return (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
        }

        UserHandle getUser() {
            return user;
        }
    }

    void removeDexFiles(List<String> allCodePaths, String[] instructionSets) {
        if (!allCodePaths.isEmpty()) {
            if (instructionSets == null) {
                throw new IllegalStateException("instructionSet == null");
            }
            String[] dexCodeInstructionSets = getDexCodeInstructionSets(instructionSets);
            for (String codePath : allCodePaths) {
                for (String dexCodeInstructionSet : dexCodeInstructionSets) {
                    try {
                        mInstaller.rmdex(codePath, dexCodeInstructionSet);
                    } catch (InstallerException ignored) {
                    }
                }
            }
        }
    }

    /**
     * Logic to handle installation of new applications, including copying
     * and renaming logic.
     */
    class FileInstallArgs extends InstallArgs {
        private File codeFile;
        private File resourceFile;

        // Example topology:
        // /data/app/com.example/base.apk
        // /data/app/com.example/split_foo.apk
        // /data/app/com.example/lib/arm/libfoo.so
        // /data/app/com.example/lib/arm64/libfoo.so
        // /data/app/com.example/dalvik/arm/base.apk@classes.dex

        /** New install */
        FileInstallArgs(InstallParams params) {
            super(params);
        }

        /** Existing install */
        FileInstallArgs(String codePath, String resourcePath, String[] instructionSets) {
            super(OriginInfo.fromNothing(), null, null, 0, InstallSource.EMPTY,
                    null, null, instructionSets, null, null, null, null, 0,
                    PackageParser.SigningDetails.UNKNOWN,
                    PackageManager.INSTALL_REASON_UNKNOWN, null /* parent */);
            this.codeFile = (codePath != null) ? new File(codePath) : null;
            this.resourceFile = (resourcePath != null) ? new File(resourcePath) : null;
        }

        int copyApk() {
            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyApk");
            try {
                return doCopyApk();
            } finally {
                Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
            }
        }

        private int doCopyApk() {
            if (origin.staged) {
                if (DEBUG_INSTALL) Slog.d(TAG, origin.file + " already staged; skipping copy");
                codeFile = origin.file;
                resourceFile = origin.file;
                return PackageManager.INSTALL_SUCCEEDED;
            }

            try {
                final boolean isEphemeral = (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
                final File tempDir =
                        mInstallerService.allocateStageDirLegacy(volumeUuid, isEphemeral);
                codeFile = tempDir;
                resourceFile = tempDir;
            } catch (IOException e) {
                Slog.w(TAG, "Failed to create copy file: " + e);
                return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
            }

            int ret = PackageManagerServiceUtils.copyPackage(
                    origin.file.getAbsolutePath(), codeFile);
            if (ret != PackageManager.INSTALL_SUCCEEDED) {
                Slog.e(TAG, "Failed to copy package");
                return ret;
            }

            final File libraryRoot = new File(codeFile, LIB_DIR_NAME);
            NativeLibraryHelper.Handle handle = null;
            try {
                handle = NativeLibraryHelper.Handle.create(codeFile);
                ret = NativeLibraryHelper.copyNativeBinariesWithOverride(handle, libraryRoot,
                        abiOverride);
            } catch (IOException e) {
                Slog.e(TAG, "Copying native libraries failed", e);
                ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
            } finally {
                IoUtils.closeQuietly(handle);
            }

            return ret;
        }

        int doPreInstall(int status) {
            if (status != PackageManager.INSTALL_SUCCEEDED) {
                cleanUp();
            }
            return status;
        }

        @Override
        boolean doRename(int status, ParsedPackage parsedPackage) {
            if (status != PackageManager.INSTALL_SUCCEEDED) {
                cleanUp();
                return false;
            }

            final File targetDir = codeFile.getParentFile();
            final File beforeCodeFile = codeFile;
            final File afterCodeFile = getNextCodePath(targetDir, parsedPackage.getPackageName());

            if (DEBUG_INSTALL) Slog.d(TAG, "Renaming " + beforeCodeFile + " to " + afterCodeFile);
            final boolean onIncremental = mIncrementalManager != null
                    && isIncrementalPath(beforeCodeFile.getAbsolutePath());
            try {
                if (onIncremental) {
                    mIncrementalManager.rename(beforeCodeFile.getAbsolutePath(),
                            afterCodeFile.getAbsolutePath());
                } else {
                    Os.rename(beforeCodeFile.getAbsolutePath(), afterCodeFile.getAbsolutePath());
                }
            } catch (IOException | ErrnoException e) {
                Slog.w(TAG, "Failed to rename", e);
                return false;
            }

            if (!SELinux.restoreconRecursive(afterCodeFile)) {
                Slog.w(TAG, "Failed to restorecon");
                return false;
            }

            // Reflect the rename internally
            codeFile = afterCodeFile;
            resourceFile = afterCodeFile;

            // Reflect the rename in scanned details
            try {
                parsedPackage.setCodePath(afterCodeFile.getCanonicalPath());
            } catch (IOException e) {
                Slog.e(TAG, "Failed to get path: " + afterCodeFile, e);
                return false;
            }
            parsedPackage.setBaseCodePath(FileUtils.rewriteAfterRename(beforeCodeFile,
                    afterCodeFile, parsedPackage.getBaseCodePath()));
            parsedPackage.setSplitCodePaths(FileUtils.rewriteAfterRename(beforeCodeFile,
                    afterCodeFile, parsedPackage.getSplitCodePaths()));

            // Reflect the rename in app info
            // TODO(b/135203078): Remove all of these application info calls
            parsedPackage.setApplicationVolumeUuid(parsedPackage.getVolumeUuid())
                    .setApplicationInfoCodePath(parsedPackage.getCodePath())
                    .setApplicationInfoResourcePath(parsedPackage.getCodePath())
                    .setApplicationInfoBaseResourcePath(parsedPackage.getBaseCodePath())
                    .setApplicationInfoSplitResourcePaths(parsedPackage.getSplitCodePaths());

            return true;
        }

        int doPostInstall(int status, int uid) {
            if (status != PackageManager.INSTALL_SUCCEEDED) {
                cleanUp();
            }
            return status;
        }

        @Override
        String getCodePath() {
            return (codeFile != null) ? codeFile.getAbsolutePath() : null;
        }

        @Override
        String getResourcePath() {
            return (resourceFile != null) ? resourceFile.getAbsolutePath() : null;
        }

        private boolean cleanUp() {
            if (codeFile == null || !codeFile.exists()) {
                return false;
            }

            String codePath = codeFile.getAbsolutePath();
            if (mIncrementalManager != null && isIncrementalPath(codePath)) {
                mIncrementalManager.closeStorage(codePath);
            }

            removeCodePathLI(codeFile);

            if (resourceFile != null && !FileUtils.contains(codeFile, resourceFile)) {
                resourceFile.delete();
            }

            return true;
        }

        void cleanUpResourcesLI() {
            // Try enumerating all code paths before deleting
            List<String> allCodePaths = Collections.EMPTY_LIST;
            if (codeFile != null && codeFile.exists()) {
                try {
                    final PackageLite pkg = PackageParser.parsePackageLite(codeFile, 0);
                    allCodePaths = pkg.getAllCodePaths();
                } catch (PackageParserException e) {
                    // Ignored; we tried our best
                }
            }

            cleanUp();
            removeDexFiles(allCodePaths, instructionSets);
        }

        boolean doPostDeleteLI(boolean delete) {
            // XXX err, shouldn't we respect the delete flag?
            cleanUpResourcesLI();
            return true;
        }
    }

    /**
     * Logic to handle movement of existing installed applications.
     */
    class MoveInstallArgs extends InstallArgs {
        private File codeFile;
        private File resourceFile;

        /** New install */
        MoveInstallArgs(InstallParams params) {
            super(params);
        }

        int copyApk() {
            if (DEBUG_INSTALL) Slog.d(TAG, "Moving " + move.packageName + " from "
                    + move.fromUuid + " to " + move.toUuid);
            synchronized (mInstaller) {
                try {
                    mInstaller.moveCompleteApp(move.fromUuid, move.toUuid, move.packageName,
                            move.dataAppName, move.appId, move.seinfo, move.targetSdkVersion);
                } catch (InstallerException e) {
                    Slog.w(TAG, "Failed to move app", e);
                    return PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
                }
            }

            codeFile = new File(Environment.getDataAppDirectory(move.toUuid), move.dataAppName);
            resourceFile = codeFile;
            if (DEBUG_INSTALL) Slog.d(TAG, "codeFile after move is " + codeFile);

            return PackageManager.INSTALL_SUCCEEDED;
        }

        int doPreInstall(int status) {
            if (status != PackageManager.INSTALL_SUCCEEDED) {
                cleanUp(move.toUuid);
            }
            return status;
        }

        @Override
        boolean doRename(int status, ParsedPackage parsedPackage) {
            if (status != PackageManager.INSTALL_SUCCEEDED) {
                cleanUp(move.toUuid);
                return false;
            }

            // Reflect the move in app info
            // TODO(b/135203078): Remove all of these application info calls
            parsedPackage.setApplicationVolumeUuid(parsedPackage.getVolumeUuid())
                    .setApplicationInfoCodePath(parsedPackage.getCodePath())
                    .setApplicationInfoResourcePath(parsedPackage.getCodePath())
                    .setApplicationInfoBaseResourcePath(parsedPackage.getBaseCodePath())
                    .setApplicationInfoSplitResourcePaths(parsedPackage.getSplitCodePaths());

            return true;
        }

        int doPostInstall(int status, int uid) {
            if (status == PackageManager.INSTALL_SUCCEEDED) {
                cleanUp(move.fromUuid);
            } else {
                cleanUp(move.toUuid);
            }
            return status;
        }

        @Override
        String getCodePath() {
            return (codeFile != null) ? codeFile.getAbsolutePath() : null;
        }

        @Override
        String getResourcePath() {
            return (resourceFile != null) ? resourceFile.getAbsolutePath() : null;
        }

        private boolean cleanUp(String volumeUuid) {
            final File codeFile = new File(Environment.getDataAppDirectory(volumeUuid),
                    move.dataAppName);
            Slog.d(TAG, "Cleaning up " + move.packageName + " on " + volumeUuid);
            final int[] userIds = mUserManager.getUserIds();
            synchronized (mInstallLock) {
                // Clean up both app data and code
                // All package moves are frozen until finished

                // We purposefully exclude FLAG_STORAGE_EXTERNAL here, since
                // this task was only focused on moving data on internal storage.
                for (int userId : userIds) {
                    try {
                        mInstaller.destroyAppData(volumeUuid, move.packageName, userId,
                                StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE, 0);
                    } catch (InstallerException e) {
                        Slog.w(TAG, String.valueOf(e));
                    }
                }
                removeCodePathLI(codeFile);
            }
            return true;
        }

        void cleanUpResourcesLI() {
            throw new UnsupportedOperationException();
        }

        boolean doPostDeleteLI(boolean delete) {
            throw new UnsupportedOperationException();
        }
    }

    private File getNextCodePath(File targetDir, String packageName) {
        File result;
        SecureRandom random = new SecureRandom();
        byte[] bytes = new byte[16];
        do {
            random.nextBytes(bytes);
            String suffix = Base64.encodeToString(bytes, Base64.URL_SAFE | Base64.NO_WRAP);
            result = new File(targetDir, packageName + "-" + suffix);
        } while (result.exists());
        return result;
    }

    static class PackageInstalledInfo {
        String name;
        int uid;
        // The set of users that originally had this package installed.
        int[] origUsers;
        // The set of users that now have this package installed.
        int[] newUsers;
        AndroidPackage pkg;
        int returnCode;
        String returnMsg;
        String installerPackageName;
        PackageRemovedInfo removedInfo;
        ArrayMap<String, PackageInstalledInfo> addedChildPackages;
        // The set of packages consuming this shared library or null if no consumers exist.
        ArrayList<AndroidPackage> libraryConsumers;
        PackageFreezer freezer;

        public void setError(int code, String msg) {
            setReturnCode(code);
            setReturnMessage(msg);
            Slog.w(TAG, msg);
        }

        public void setError(String msg, PackageParserException e) {
            setReturnCode(e.error);
            setReturnMessage(ExceptionUtils.getCompleteMessage(msg, e));
            final int childCount = (addedChildPackages != null) ? addedChildPackages.size() : 0;
            for (int i = 0; i < childCount; i++) {
                addedChildPackages.valueAt(i).setError(msg, e);
            }
            Slog.w(TAG, msg, e);
        }

        public void setError(String msg, PackageManagerException e) {
            returnCode = e.error;
            setReturnMessage(ExceptionUtils.getCompleteMessage(msg, e));
            final int childCount = (addedChildPackages != null) ? addedChildPackages.size() : 0;
            for (int i = 0; i < childCount; i++) {
                addedChildPackages.valueAt(i).setError(msg, e);
            }
            Slog.w(TAG, msg, e);
        }

        public void setReturnCode(int returnCode) {
            this.returnCode = returnCode;
            final int childCount = (addedChildPackages != null) ? addedChildPackages.size() : 0;
            for (int i = 0; i < childCount; i++) {
                addedChildPackages.valueAt(i).returnCode = returnCode;
            }
        }

        private void setReturnMessage(String returnMsg) {
            this.returnMsg = returnMsg;
            final int childCount = (addedChildPackages != null) ? addedChildPackages.size() : 0;
            for (int i = 0; i < childCount; i++) {
                addedChildPackages.valueAt(i).returnMsg = returnMsg;
            }
        }

        // In some error cases we want to convey more info back to the observer
        String origPackage;
        String origPermission;
    }

    private static void updateDigest(MessageDigest digest, File file) throws IOException {
        try (DigestInputStream digestStream =
                new DigestInputStream(new FileInputStream(file), digest)) {
            while (digestStream.read() != -1) {} // nothing to do; just plow through the file
        }
    }

    private void removeNativeBinariesLI(PackageSetting ps) {
        if (ps != null) {
            NativeLibraryHelper.removeNativeBinariesLI(ps.legacyNativeLibraryPathString);
        }
    }

    @GuardedBy("mLock")
    private void enableSystemPackageLPw(AndroidPackage pkg) {
        mSettings.enableSystemPackageLPw(pkg.getPackageName());
    }

    @GuardedBy("mLock")
    private boolean disableSystemPackageLPw(AndroidPackage oldPkg) {
        return mSettings.disableSystemPackageLPw(oldPkg.getPackageName(), true);
    }

    private void updateSettingsLI(AndroidPackage newPackage, InstallArgs installArgs,
            int[] allUsers, PackageInstalledInfo res) {
        updateSettingsInternalLI(newPackage, installArgs, allUsers, res);
    }

    private void updateSettingsInternalLI(AndroidPackage pkg, InstallArgs installArgs,
            int[] allUsers, PackageInstalledInfo res) {
        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "updateSettings");

        final String pkgName = pkg.getPackageName();
        final String installerPackageName = installArgs.installSource.installerPackageName;
        final int[] installedForUsers = res.origUsers;
        final int installReason = installArgs.installReason;

        if (DEBUG_INSTALL) Slog.d(TAG, "New package installed in " + pkg.getCodePath());
        synchronized (mLock) {
// NOTE: This changes slightly to include UPDATE_PERMISSIONS_ALL regardless of the size of pkg.permissions
            mPermissionManager.updatePermissions(pkgName, pkg);
            // For system-bundled packages, we assume that installing an upgraded version
            // of the package implies that the user actually wants to run that new code,
            // so we enable the package.
            PackageSetting ps = mSettings.mPackages.get(pkgName);
            final int userId = installArgs.user.getIdentifier();
            if (ps != null) {
                if (isSystemApp(pkg)) {
                    if (DEBUG_INSTALL) {
                        Slog.d(TAG, "Implicitly enabling system package on upgrade: " + pkgName);
                    }
                    // Enable system package for requested users
                    if (res.origUsers != null) {
                        for (int origUserId : res.origUsers) {
                            if (userId == UserHandle.USER_ALL || userId == origUserId) {
                                ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT,
                                        origUserId, installerPackageName);
                            }
                        }
                    }
                    // Also convey the prior install/uninstall state
                    if (allUsers != null && installedForUsers != null) {
                        for (int currentUserId : allUsers) {
                            final boolean installed = ArrayUtils.contains(
                                    installedForUsers, currentUserId);
                            if (DEBUG_INSTALL) {
                                Slog.d(TAG, "    user " + currentUserId + " => " + installed);
                            }
                            ps.setInstalled(installed, currentUserId);
                        }
                        // these install state changes will be persisted in the
                        // upcoming call to mSettings.writeLPr().
                    }
                }
                // It's implied that when a user requests installation, they want the app to be
                // installed and enabled.
                if (userId != UserHandle.USER_ALL) {
                    ps.setInstalled(true, userId);
                    ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, userId, installerPackageName);
                }

                ps.setInstallSource(installArgs.installSource);


                // When replacing an existing package, preserve the original install reason for all
                // users that had the package installed before.
                final Set<Integer> previousUserIds = new ArraySet<>();
                if (res.removedInfo != null && res.removedInfo.installReasons != null) {
                    final int installReasonCount = res.removedInfo.installReasons.size();
                    for (int i = 0; i < installReasonCount; i++) {
                        final int previousUserId = res.removedInfo.installReasons.keyAt(i);
                        final int previousInstallReason = res.removedInfo.installReasons.valueAt(i);
                        ps.setInstallReason(previousInstallReason, previousUserId);
                        previousUserIds.add(previousUserId);
                    }
                }

                // Set install reason for users that are having the package newly installed.
                if (userId == UserHandle.USER_ALL) {
                    for (int currentUserId : mUserManager.getUserIds()) {
                        if (!previousUserIds.contains(currentUserId)) {
                            ps.setInstallReason(installReason, currentUserId);
                        }
                    }
                } else if (!previousUserIds.contains(userId)) {
                    ps.setInstallReason(installReason, userId);
                }
                mSettings.writeKernelMappingLPr(ps);
            }
            res.name = pkgName;
            res.uid = pkg.getUid();
            res.pkg = pkg;
            mSettings.setInstallerPackageName(pkgName, installerPackageName);
            res.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
            //to update install status
            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "writeSettings");
            mSettings.writeLPr();
            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
        }

        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
    }

    private static class InstallRequest {
        public final InstallArgs args;
        public final PackageInstalledInfo installResult;

        private InstallRequest(InstallArgs args, PackageInstalledInfo res) {
            this.args = args;
            this.installResult = res;
        }
    }

    @GuardedBy({"mInstallLock", "mLock"})
    private void installPackagesTracedLI(List<InstallRequest> requests) {
        try {
            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "installPackages");
            installPackagesLI(requests);
        } finally {
            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
        }
    }

    /**
     * Package state to commit to memory and disk after reconciliation has completed.
     */
    private static class CommitRequest {
        final Map<String, ReconciledPackage> reconciledPackages;
        final int[] mAllUsers;

        private CommitRequest(Map<String, ReconciledPackage> reconciledPackages, int[] allUsers) {
            this.reconciledPackages = reconciledPackages;
            this.mAllUsers = allUsers;
        }
    }

    /**
     * Package scan results and related request details used to reconcile the potential addition of
     * one or more packages to the system.
     *
     * Reconcile will take a set of package details that need to be committed to the system and make
     * sure that they are valid in the context of the system and the other installing apps. Any
     * invalid state or app will result in a failed reconciliation and thus whatever operation (such
     * as install) led to the request.
     */
    private static class ReconcileRequest {
        public final Map<String, ScanResult> scannedPackages;

        public final Map<String, AndroidPackage> allPackages;
        public final Map<String, LongSparseArray<SharedLibraryInfo>> sharedLibrarySource;
        public final Map<String, InstallArgs> installArgs;
        public final Map<String, PackageInstalledInfo> installResults;
        public final Map<String, PrepareResult> preparedPackages;
        public final Map<String, VersionInfo> versionInfos;
        public final Map<String, PackageSetting> lastStaticSharedLibSettings;

        private ReconcileRequest(Map<String, ScanResult> scannedPackages,
                Map<String, InstallArgs> installArgs,
                Map<String, PackageInstalledInfo> installResults,
                Map<String, PrepareResult> preparedPackages,
                Map<String, LongSparseArray<SharedLibraryInfo>> sharedLibrarySource,
                Map<String, AndroidPackage> allPackages,
                Map<String, VersionInfo> versionInfos,
                Map<String, PackageSetting> lastStaticSharedLibSettings) {
            this.scannedPackages = scannedPackages;
            this.installArgs = installArgs;
            this.installResults = installResults;
            this.preparedPackages = preparedPackages;
            this.sharedLibrarySource = sharedLibrarySource;
            this.allPackages = allPackages;
            this.versionInfos = versionInfos;
            this.lastStaticSharedLibSettings = lastStaticSharedLibSettings;
        }

        private ReconcileRequest(Map<String, ScanResult> scannedPackages,
                Map<String, LongSparseArray<SharedLibraryInfo>> sharedLibrarySource,
                Map<String, AndroidPackage> allPackages,
                Map<String, VersionInfo> versionInfos,
                Map<String, PackageSetting> lastStaticSharedLibSettings) {
            this(scannedPackages, Collections.emptyMap(), Collections.emptyMap(),
                    Collections.emptyMap(), sharedLibrarySource, allPackages, versionInfos,
                    lastStaticSharedLibSettings);
        }
    }
    private static class ReconcileFailure extends PackageManagerException {
        ReconcileFailure(String message) {
            super("Reconcile failed: " + message);
        }
        ReconcileFailure(int reason, String message) {
            super(reason, "Reconcile failed: " + message);
        }
        ReconcileFailure(PackageManagerException e) {
            this(e.error, e.getMessage());
        }
    }

    /**
     * A container of all data needed to commit a package to in-memory data structures and to disk.
     * TODO: move most of the data contained her into a PackageSetting for commit.
     */
    private static class ReconciledPackage {
        public final ReconcileRequest request;
        public final PackageSetting pkgSetting;
        public final ScanResult scanResult;
        // TODO: Remove install-specific details from the reconcile result
        public final PackageInstalledInfo installResult;
        @Nullable public final PrepareResult prepareResult;
        @Nullable public final InstallArgs installArgs;
        public final DeletePackageAction deletePackageAction;
        public final List<SharedLibraryInfo> allowedSharedLibraryInfos;
        public final SigningDetails signingDetails;
        public final boolean sharedUserSignaturesChanged;
        public ArrayList<SharedLibraryInfo> collectedSharedLibraryInfos;
        public final boolean removeAppKeySetData;

        private ReconciledPackage(ReconcileRequest request,
                InstallArgs installArgs,
                PackageSetting pkgSetting,
                PackageInstalledInfo installResult,
                PrepareResult prepareResult,
                ScanResult scanResult,
                DeletePackageAction deletePackageAction,
                List<SharedLibraryInfo> allowedSharedLibraryInfos,
                SigningDetails signingDetails,
                boolean sharedUserSignaturesChanged,
                boolean removeAppKeySetData) {
            this.request = request;
            this.installArgs = installArgs;
            this.pkgSetting = pkgSetting;
            this.installResult = installResult;
            this.prepareResult = prepareResult;
            this.scanResult = scanResult;
            this.deletePackageAction = deletePackageAction;
            this.allowedSharedLibraryInfos = allowedSharedLibraryInfos;
            this.signingDetails = signingDetails;
            this.sharedUserSignaturesChanged = sharedUserSignaturesChanged;
            this.removeAppKeySetData = removeAppKeySetData;
        }

        /**
         * Returns a combined set of packages containing the packages already installed combined
         * with the package(s) currently being installed. The to-be installed packages take
         * precedence and may shadow already installed packages.
         */
        private Map<String, AndroidPackage> getCombinedAvailablePackages() {
            final ArrayMap<String, AndroidPackage> combined =
                    new ArrayMap<>(request.allPackages.size() + request.scannedPackages.size());

            combined.putAll(request.allPackages);

            for (ScanResult scanResult : request.scannedPackages.values()) {
                combined.put(scanResult.pkgSetting.name, scanResult.request.parsedPackage);
            }

            return combined;
        }
    }

    @GuardedBy("mLock")
    private static Map<String, ReconciledPackage> reconcilePackagesLocked(
            final ReconcileRequest request, KeySetManagerService ksms)
            throws ReconcileFailure {
        final Map<String, ScanResult> scannedPackages = request.scannedPackages;

        final Map<String, ReconciledPackage> result = new ArrayMap<>(scannedPackages.size());

        // make a copy of the existing set of packages so we can combine them with incoming packages
        final ArrayMap<String, AndroidPackage> combinedPackages =
                new ArrayMap<>(request.allPackages.size() + scannedPackages.size());

        combinedPackages.putAll(request.allPackages);

        final Map<String, LongSparseArray<SharedLibraryInfo>> incomingSharedLibraries =
                new ArrayMap<>();

        for (String installPackageName : scannedPackages.keySet()) {
            final ScanResult scanResult = scannedPackages.get(installPackageName);

            // add / replace existing with incoming packages
            combinedPackages.put(scanResult.pkgSetting.name, scanResult.request.parsedPackage);

            // in the first pass, we'll build up the set of incoming shared libraries
            final List<SharedLibraryInfo> allowedSharedLibInfos =
                    getAllowedSharedLibInfos(scanResult, request.sharedLibrarySource);
            final SharedLibraryInfo staticLib = scanResult.staticSharedLibraryInfo;
            if (allowedSharedLibInfos != null) {
                for (SharedLibraryInfo info : allowedSharedLibInfos) {
                    if (!addSharedLibraryToPackageVersionMap(incomingSharedLibraries, info)) {
                        throw new ReconcileFailure("Static Shared Library " + staticLib.getName()
                                + " is being installed twice in this set!");
                    }
                }
            }

            // the following may be null if we're just reconciling on boot (and not during install)
            final InstallArgs installArgs = request.installArgs.get(installPackageName);
            final PackageInstalledInfo res = request.installResults.get(installPackageName);
            final PrepareResult prepareResult = request.preparedPackages.get(installPackageName);
            final boolean isInstall = installArgs != null;
            if (isInstall && (res == null || prepareResult == null)) {
                throw new ReconcileFailure("Reconcile arguments are not balanced for "
                        + installPackageName + "!");
            }

            final DeletePackageAction deletePackageAction;
            // we only want to try to delete for non system apps
            if (isInstall && prepareResult.replace && !prepareResult.system) {
                final boolean killApp = (scanResult.request.scanFlags & SCAN_DONT_KILL_APP) == 0;
                final int deleteFlags = PackageManager.DELETE_KEEP_DATA
                        | (killApp ? 0 : PackageManager.DELETE_DONT_KILL_APP);
                deletePackageAction = mayDeletePackageLocked(res.removedInfo,
                        prepareResult.originalPs, prepareResult.disabledPs,
                        deleteFlags, null /* all users */);
                if (deletePackageAction == null) {
                    throw new ReconcileFailure(
                            PackageManager.INSTALL_FAILED_REPLACE_COULDNT_DELETE,
                            "May not delete " + installPackageName + " to replace");
                }
            } else {
                deletePackageAction = null;
            }

            final int scanFlags = scanResult.request.scanFlags;
            final int parseFlags = scanResult.request.parseFlags;
            final ParsedPackage parsedPackage = scanResult.request.parsedPackage;

            final PackageSetting disabledPkgSetting = scanResult.request.disabledPkgSetting;
            final PackageSetting lastStaticSharedLibSetting =
                    request.lastStaticSharedLibSettings.get(installPackageName);
            final PackageSetting signatureCheckPs =
                    (prepareResult != null && lastStaticSharedLibSetting != null)
                            ? lastStaticSharedLibSetting
                            : scanResult.pkgSetting;
            boolean removeAppKeySetData = false;
            boolean sharedUserSignaturesChanged = false;
            SigningDetails signingDetails = null;
            if (ksms.shouldCheckUpgradeKeySetLocked(signatureCheckPs, scanFlags)) {
                if (ksms.checkUpgradeKeySetLocked(signatureCheckPs, parsedPackage)) {
                    // We just determined the app is signed correctly, so bring
                    // over the latest parsed certs.
                } else {
                    if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
                        throw new ReconcileFailure(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
                                "Package " + parsedPackage.getPackageName()
                                        + " upgrade keys do not match the previously installed"
                                        + " version");
                    } else {
                        String msg = "System package " + parsedPackage.getPackageName()
                                + " signature changed; retaining data.";
                        reportSettingsProblem(Log.WARN, msg);
                    }
                }
                signingDetails = parsedPackage.getSigningDetails();
            } else {
                try {
                    final VersionInfo versionInfo = request.versionInfos.get(installPackageName);
                    final boolean compareCompat = isCompatSignatureUpdateNeeded(versionInfo);
                    final boolean compareRecover = isRecoverSignatureUpdateNeeded(versionInfo);
                    final boolean compatMatch = verifySignatures(signatureCheckPs,
                            disabledPkgSetting, parsedPackage.getSigningDetails(), compareCompat,
                            compareRecover);
                    // The new KeySets will be re-added later in the scanning process.
                    if (compatMatch) {
                        removeAppKeySetData = true;
                    }
                    // We just determined the app is signed correctly, so bring
                    // over the latest parsed certs.
                    signingDetails = parsedPackage.getSigningDetails();


                    // if this is is a sharedUser, check to see if the new package is signed by a
                    // newer
                    // signing certificate than the existing one, and if so, copy over the new
                    // details
                    if (signatureCheckPs.sharedUser != null) {
                        if (parsedPackage.getSigningDetails().hasAncestor(
                                signatureCheckPs.sharedUser.signatures.mSigningDetails)) {
                            signatureCheckPs.sharedUser.signatures.mSigningDetails =
                                    parsedPackage.getSigningDetails();
                        }
                        if (signatureCheckPs.sharedUser.signaturesChanged == null) {
                            signatureCheckPs.sharedUser.signaturesChanged = Boolean.FALSE;
                        }
                    }
                } catch (PackageManagerException e) {
                    if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
                        throw new ReconcileFailure(e);
                    }
                    signingDetails = parsedPackage.getSigningDetails();

                    // If the system app is part of a shared user we allow that shared user to
                    // change
                    // signatures as well as part of an OTA. We still need to verify that the
                    // signatures
                    // are consistent within the shared user for a given boot, so only allow
                    // updating
                    // the signatures on the first package scanned for the shared user (i.e. if the
                    // signaturesChanged state hasn't been initialized yet in SharedUserSetting).
                    if (signatureCheckPs.sharedUser != null) {
                        final Signature[] sharedUserSignatures =
                                signatureCheckPs.sharedUser.signatures.mSigningDetails.signatures;
                        if (signatureCheckPs.sharedUser.signaturesChanged != null
                                && compareSignatures(sharedUserSignatures,
                                parsedPackage.getSigningDetails().signatures)
                                        != PackageManager.SIGNATURE_MATCH) {
                            if (SystemProperties.getInt("ro.product.first_api_level", 0) <= 29) {
                                // Mismatched signatures is an error and silently skipping system
                                // packages will likely break the device in unforeseen ways.
                                // However, we allow the device to boot anyway because, prior to Q,
                                // vendors were not expecting the platform to crash in this
                                // situation.
                                // This WILL be a hard failure on any new API levels after Q.
                                throw new ReconcileFailure(
                                        INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES,
                                        "Signature mismatch for shared user: "
                                                + scanResult.pkgSetting.sharedUser);
                            } else {
                                // Treat mismatched signatures on system packages using a shared
                                // UID as
                                // fatal for the system overall, rather than just failing to install
                                // whichever package happened to be scanned later.
                                throw new IllegalStateException(
                                        "Signature mismatch on system package "
                                                + parsedPackage.getPackageName()
                                                + " for shared user "
                                                + scanResult.pkgSetting.sharedUser);
                            }
                        }

                        sharedUserSignaturesChanged = true;
                        signatureCheckPs.sharedUser.signatures.mSigningDetails =
                                parsedPackage.getSigningDetails();
                        signatureCheckPs.sharedUser.signaturesChanged = Boolean.TRUE;
                    }
                    // File a report about this.
                    String msg = "System package " + parsedPackage.getPackageName()
                            + " signature changed; retaining data.";
                    reportSettingsProblem(Log.WARN, msg);
                } catch (IllegalArgumentException e) {
                    // should never happen: certs matched when checking, but not when comparing
                    // old to new for sharedUser
                    throw new RuntimeException(
                            "Signing certificates comparison made on incomparable signing details"
                                    + " but somehow passed verifySignatures!", e);
                }
            }

            result.put(installPackageName,
                    new ReconciledPackage(request, installArgs, scanResult.pkgSetting,
                            res, request.preparedPackages.get(installPackageName), scanResult,
                            deletePackageAction, allowedSharedLibInfos, signingDetails,
                            sharedUserSignaturesChanged, removeAppKeySetData));
        }

        for (String installPackageName : scannedPackages.keySet()) {
            // Check all shared libraries and map to their actual file path.
            // We only do this here for apps not on a system dir, because those
            // are the only ones that can fail an install due to this.  We
            // will take care of the system apps by updating all of their
            // library paths after the scan is done. Also during the initial
            // scan don't update any libs as we do this wholesale after all
            // apps are scanned to avoid dependency based scanning.
            final ScanResult scanResult = scannedPackages.get(installPackageName);
            if ((scanResult.request.scanFlags & SCAN_BOOTING) != 0
                    || (scanResult.request.parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0) {
                continue;
            }
            try {
                result.get(installPackageName).collectedSharedLibraryInfos =
                        collectSharedLibraryInfos(scanResult.request.parsedPackage,
                                combinedPackages, request.sharedLibrarySource,
                                incomingSharedLibraries);

            } catch (PackageManagerException e) {
                throw new ReconcileFailure(e.error, e.getMessage());
            }
        }

        return result;
    }

    /**
     * Compare the newly scanned package with current system state to see which of its declared
     * shared libraries should be allowed to be added to the system.
     */
    private static List<SharedLibraryInfo> getAllowedSharedLibInfos(
            ScanResult scanResult,
            Map<String, LongSparseArray<SharedLibraryInfo>> existingSharedLibraries) {
        // Let's used the parsed package as scanResult.pkgSetting may be null
        final ParsedPackage parsedPackage = scanResult.request.parsedPackage;
        if (scanResult.staticSharedLibraryInfo == null
                && scanResult.dynamicSharedLibraryInfos == null) {
            return null;
        }

        // Any app can add new static shared libraries
        if (scanResult.staticSharedLibraryInfo != null) {
            return Collections.singletonList(scanResult.staticSharedLibraryInfo);
        }
        final boolean hasDynamicLibraries =
                (parsedPackage.getFlags() & ApplicationInfo.FLAG_SYSTEM) != 0
                        && scanResult.dynamicSharedLibraryInfos != null;
        if (!hasDynamicLibraries) {
            return null;
        }
        final boolean isUpdatedSystemApp = parsedPackage.isUpdatedSystemApp();
        // We may not yet have disabled the updated package yet, so be sure to grab the
        // current setting if that's the case.
        final PackageSetting updatedSystemPs = isUpdatedSystemApp
                ? scanResult.request.disabledPkgSetting == null
                        ? scanResult.request.oldPkgSetting
                        : scanResult.request.disabledPkgSetting
                : null;
        if (isUpdatedSystemApp && (updatedSystemPs.pkg == null
                || updatedSystemPs.pkg.getLibraryNames() == null)) {
            Slog.w(TAG, "Package " + parsedPackage.getPackageName()
                    + " declares libraries that are not declared on the system image; skipping");
            return null;
        }
        final ArrayList<SharedLibraryInfo> infos =
                new ArrayList<>(scanResult.dynamicSharedLibraryInfos.size());
        for (SharedLibraryInfo info : scanResult.dynamicSharedLibraryInfos) {
            final String name = info.getName();
            if (isUpdatedSystemApp) {
                // New library entries can only be added through the
                // system image.  This is important to get rid of a lot
                // of nasty edge cases: for example if we allowed a non-
                // system update of the app to add a library, then uninstalling
                // the update would make the library go away, and assumptions
                // we made such as through app install filtering would now
                // have allowed apps on the device which aren't compatible
                // with it.  Better to just have the restriction here, be
                // conservative, and create many fewer cases that can negatively
                // impact the user experience.
                if (!updatedSystemPs.pkg.getLibraryNames().contains(name)) {
                    Slog.w(TAG, "Package " + parsedPackage.getPackageName()
                            + " declares library " + name
                            + " that is not declared on system image; skipping");
                    continue;
                }
            }
            if (sharedLibExists(
                    name, SharedLibraryInfo.VERSION_UNDEFINED, existingSharedLibraries)) {
                Slog.w(TAG, "Package " + parsedPackage.getPackageName() + " declares library "
                        + name + " that already exists; skipping");
                continue;
            }
            infos.add(info);
        }
        return infos;
    }

    /**
     * Returns false if the adding shared library already exists in the map and so could not be
     * added.
     */
    private static boolean addSharedLibraryToPackageVersionMap(
            Map<String, LongSparseArray<SharedLibraryInfo>> target,
            SharedLibraryInfo library) {
        final String name = library.getName();
        if (target.containsKey(name)) {
            if (library.getType() != SharedLibraryInfo.TYPE_STATIC) {
                // We've already added this non-version-specific library to the map.
                return false;
            } else if (target.get(name).indexOfKey(library.getLongVersion()) >= 0) {
                // We've already added this version of a version-specific library to the map.
                return false;
            }
        } else {
            target.put(name, new LongSparseArray<>());
        }
        target.get(name).put(library.getLongVersion(), library);
        return true;
    }

    @GuardedBy("mLock")
    private void commitPackagesLocked(final CommitRequest request) {
        // TODO: remove any expected failures from this method; this should only be able to fail due
        //       to unavoidable errors (I/O, etc.)
        for (ReconciledPackage reconciledPkg : request.reconciledPackages.values()) {
            final ScanResult scanResult = reconciledPkg.scanResult;
            final ScanRequest scanRequest = scanResult.request;
            final ParsedPackage parsedPackage = scanRequest.parsedPackage;
            final String packageName = parsedPackage.getPackageName();
            final PackageInstalledInfo res = reconciledPkg.installResult;

            if (reconciledPkg.prepareResult.replace) {
                AndroidPackage oldPackage = mPackages.get(packageName);

                // Set the update and install times
                PackageSetting deletedPkgSetting = getPackageSetting(oldPackage.getPackageName());
                reconciledPkg.pkgSetting.firstInstallTime = deletedPkgSetting.firstInstallTime;
                reconciledPkg.pkgSetting.lastUpdateTime = System.currentTimeMillis();

                if (reconciledPkg.prepareResult.system) {
                    // Remove existing system package
                    removePackageLI(oldPackage, true);
                    if (!disableSystemPackageLPw(oldPackage)) {
                        // We didn't need to disable the .apk as a current system package,
                        // which means we are replacing another update that is already
                        // installed.  We need to make sure to delete the older one's .apk.
                        res.removedInfo.args = createInstallArgsForExisting(
                                oldPackage.getAppInfoCodePath(),
                                oldPackage.getAppInfoResourcePath(),
                                getAppDexInstructionSets(oldPackage.getPrimaryCpuAbi(),
                                        oldPackage.getSecondaryCpuAbi()));
                    } else {
                        res.removedInfo.args = null;
                    }
                } else {
                    try {
                        // Settings will be written during the call to updateSettingsLI().
                        executeDeletePackageLIF(reconciledPkg.deletePackageAction, packageName,
                                true, request.mAllUsers, false, parsedPackage);
                    } catch (SystemDeleteException e) {
                        if (Build.IS_ENG) {
                            throw new RuntimeException("Unexpected failure", e);
                            // ignore; not possible for non-system app
                        }
                    }
                    // Successfully deleted the old package; proceed with replace.

                    // If deleted package lived in a container, give users a chance to
                    // relinquish resources before killing.
                    if (oldPackage.isForwardLocked() || isExternal(oldPackage)) {
                        if (DEBUG_INSTALL) {
                            Slog.i(TAG, "upgrading pkg " + oldPackage
                                    + " is ASEC-hosted -> UNAVAILABLE");
                        }
                        final int[] uidArray = new int[]{oldPackage.getUid()};
                        final ArrayList<String> pkgList = new ArrayList<>(1);
                        pkgList.add(oldPackage.getAppInfoPackageName());
                        sendResourcesChangedBroadcast(false, true, pkgList, uidArray, null);
                    }

                    // Update the in-memory copy of the previous code paths.
                    PackageSetting ps1 = mSettings.mPackages.get(
                            reconciledPkg.prepareResult.existingPackage.getPackageName());
                    if ((reconciledPkg.installArgs.installFlags & PackageManager.DONT_KILL_APP)
                            == 0) {
                        if (ps1.mOldCodePaths == null) {
                            ps1.mOldCodePaths = new ArraySet<>();
                        }
                        Collections.addAll(ps1.mOldCodePaths, oldPackage.getBaseCodePath());
                        if (oldPackage.getSplitCodePaths() != null) {
                            Collections.addAll(ps1.mOldCodePaths, oldPackage.getSplitCodePaths());
                        }
                    } else {
                        ps1.mOldCodePaths = null;
                    }

                    if (reconciledPkg.installResult.returnCode
                            == PackageManager.INSTALL_SUCCEEDED) {
                        PackageSetting ps2 = mSettings.getPackageLPr(
                                parsedPackage.getPackageName());
                        if (ps2 != null) {
                            res.removedInfo.removedForAllUsers = mPackages.get(ps2.name) == null;
                        }
                    }
                }
            }

            AndroidPackage pkg = commitReconciledScanResultLocked(reconciledPkg);
            updateSettingsLI(pkg, reconciledPkg.installArgs, request.mAllUsers, res);

            final PackageSetting ps = mSettings.mPackages.get(packageName);
            if (ps != null) {
                res.newUsers = ps.queryInstalledUsers(mUserManager.getUserIds(), true);
                ps.setUpdateAvailable(false /*updateAvailable*/);
            }
            if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
                updateSequenceNumberLP(ps, res.newUsers);
                updateInstantAppInstallerLocked(packageName);
            }
        }
    }

    /**
     * Installs one or more packages atomically. This operation is broken up into four phases:
     * <ul>
     *     <li><b>Prepare</b>
     *         <br/>Analyzes any current install state, parses the package and does initial
     *         validation on it.</li>
     *     <li><b>Scan</b>
     *         <br/>Interrogates the parsed packages given the context collected in prepare.</li>
     *     <li><b>Reconcile</b>
     *         <br/>Validates scanned packages in the context of each other and the current system
     *         state to ensure that the install will be successful.
     *     <li><b>Commit</b>
     *         <br/>Commits all scanned packages and updates system state. This is the only place
     *         that system state may be modified in the install flow and all predictable errors
     *         must be determined before this phase.</li>
     * </ul>
     *
     * Failure at any phase will result in a full failure to install all packages.
     */
    @GuardedBy("mInstallLock")
    private void installPackagesLI(List<InstallRequest> requests) {
        final Map<String, ScanResult> preparedScans = new ArrayMap<>(requests.size());
        final Map<String, InstallArgs> installArgs = new ArrayMap<>(requests.size());
        final Map<String, PackageInstalledInfo> installResults = new ArrayMap<>(requests.size());
        final Map<String, PrepareResult> prepareResults = new ArrayMap<>(requests.size());
        final Map<String, VersionInfo> versionInfos = new ArrayMap<>(requests.size());
        final Map<String, PackageSetting> lastStaticSharedLibSettings =
                new ArrayMap<>(requests.size());
        final Map<String, Boolean> createdAppId = new ArrayMap<>(requests.size());
        boolean success = false;
        try {
            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "installPackagesLI");
            for (InstallRequest request : requests) {
                // TODO(b/109941548): remove this once we've pulled everything from it and into
                //                    scan, reconcile or commit.
                final PrepareResult prepareResult;
                try {
                    Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "preparePackage");
                    prepareResult =
                            preparePackageLI(request.args, request.installResult);
                } catch (PrepareFailure prepareFailure) {
                    request.installResult.setError(prepareFailure.error,
                            prepareFailure.getMessage());
                    request.installResult.origPackage = prepareFailure.conflictingPackage;
                    request.installResult.origPermission = prepareFailure.conflictingPermission;
                    return;
                } finally {
                    Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
                }
                request.installResult.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
                request.installResult.installerPackageName =
                        request.args.installSource.installerPackageName;

                final String packageName = prepareResult.packageToScan.getPackageName();
                prepareResults.put(packageName, prepareResult);
                installResults.put(packageName, request.installResult);
                installArgs.put(packageName, request.args);
                try {
                    final ScanResult result = scanPackageTracedLI(
                            prepareResult.packageToScan, prepareResult.parseFlags,
                            prepareResult.scanFlags, System.currentTimeMillis(),
                            request.args.user);
                    if (null != preparedScans.put(result.pkgSetting.pkg.getPackageName(), result)) {
                        request.installResult.setError(
                                PackageManager.INSTALL_FAILED_DUPLICATE_PACKAGE,
                                "Duplicate package " + result.pkgSetting.pkg.getPackageName()
                                        + " in multi-package install request.");
                        return;
                    }
                    createdAppId.put(packageName, optimisticallyRegisterAppId(result));
                    versionInfos.put(result.pkgSetting.pkg.getPackageName(),
                            getSettingsVersionForPackage(result.pkgSetting.pkg));
                    if (result.staticSharedLibraryInfo != null) {
                        final PackageSetting sharedLibLatestVersionSetting =
                                getSharedLibLatestVersionSetting(result);
                        if (sharedLibLatestVersionSetting != null) {
                            lastStaticSharedLibSettings.put(result.pkgSetting.pkg.getPackageName(),
                                    sharedLibLatestVersionSetting);
                        }
                    }
                } catch (PackageManagerException e) {
                    request.installResult.setError("Scanning Failed.", e);
                    return;
                }
            }
            ReconcileRequest reconcileRequest = new ReconcileRequest(preparedScans, installArgs,
                    installResults,
                    prepareResults,
                    mSharedLibraries,
                    Collections.unmodifiableMap(mPackages), versionInfos,
                    lastStaticSharedLibSettings);
            CommitRequest commitRequest = null;
            synchronized (mLock) {
                Map<String, ReconciledPackage> reconciledPackages;
                try {
                    Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "reconcilePackages");
                    reconciledPackages = reconcilePackagesLocked(
                            reconcileRequest, mSettings.mKeySetManagerService);
                } catch (ReconcileFailure e) {
                    for (InstallRequest request : requests) {
                        request.installResult.setError("Reconciliation failed...", e);
                    }
                    return;
                } finally {
                    Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
                }
                try {
                    Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "commitPackages");
                    commitRequest = new CommitRequest(reconciledPackages,
                            mUserManager.getUserIds());
                    commitPackagesLocked(commitRequest);
                    success = true;
                } finally {
                    Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
                }
            }
            executePostCommitSteps(commitRequest);
        } finally {
            if (!success) {
                for (ScanResult result : preparedScans.values()) {
                    if (createdAppId.getOrDefault(result.request.parsedPackage.getPackageName(),
                            false)) {
                        cleanUpAppIdCreation(result);
                    }
                }
                // TODO(patb): create a more descriptive reason than unknown in future release
                // mark all non-failure installs as UNKNOWN so we do not treat them as success
                for (InstallRequest request : requests) {
                    request.installResult.freezer.close();
                    if (request.installResult.returnCode == PackageManager.INSTALL_SUCCEEDED) {
                        request.installResult.returnCode = PackageManager.INSTALL_UNKNOWN;
                    }
                }
            }
            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
        }
    }

    /**
     * On successful install, executes remaining steps after commit completes and the package lock
     * is released. These are typically more expensive or require calls to installd, which often
     * locks on {@link #mLock}.
     */
    private void executePostCommitSteps(CommitRequest commitRequest) {
        for (ReconciledPackage reconciledPkg : commitRequest.reconciledPackages.values()) {
            final boolean instantApp = ((reconciledPkg.scanResult.request.scanFlags
                            & PackageManagerService.SCAN_AS_INSTANT_APP) != 0);
            final AndroidPackage pkg = reconciledPkg.pkgSetting.pkg;
            final String packageName = pkg.getPackageName();
            final boolean onIncremental = mIncrementalManager != null
                    && isIncrementalPath(pkg.getCodePath());
            prepareAppDataAfterInstallLIF(pkg);
            if (reconciledPkg.prepareResult.clearCodeCache) {
                clearAppDataLIF(pkg, UserHandle.USER_ALL, FLAG_STORAGE_DE | FLAG_STORAGE_CE
                        | FLAG_STORAGE_EXTERNAL | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
            }
            if (reconciledPkg.prepareResult.replace) {
                mDexManager.notifyPackageUpdated(pkg.getPackageName(),
                        pkg.getBaseCodePath(), pkg.getSplitCodePaths());
            }

            // Prepare the application profiles for the new code paths.
            // This needs to be done before invoking dexopt so that any install-time profile
            // can be used for optimizations.
            mArtManagerService.prepareAppProfiles(
                    pkg,
                    resolveUserIds(reconciledPkg.installArgs.user.getIdentifier()),
                    /* updateReferenceProfileContent= */ true);

            // Check whether we need to dexopt the app.
            //
            // NOTE: it is IMPORTANT to call dexopt:
            //   - after doRename which will sync the package data from AndroidPackage and
            //     its corresponding ApplicationInfo.
            //   - after installNewPackageLIF or replacePackageLIF which will update result with the
            //     uid of the application (pkg.applicationInfo.uid).
            //     This update happens in place!
            //
            // We only need to dexopt if the package meets ALL of the following conditions:
            //   1) it is not an instant app or if it is then dexopt is enabled via gservices.
            //   2) it is not debuggable.
            //   3) it is not on Incremental File System.
            //
            // Note that we do not dexopt instant apps by default. dexopt can take some time to
            // complete, so we skip this step during installation. Instead, we'll take extra time
            // the first time the instant app starts. It's preferred to do it this way to provide
            // continuous progress to the useur instead of mysteriously blocking somewhere in the
            // middle of running an instant app. The default behaviour can be overridden
            // via gservices.
            final boolean performDexopt =
                    (!instantApp || Global.getInt(mContext.getContentResolver(),
                    Global.INSTANT_APP_DEXOPT_ENABLED, 0) != 0)
                    && ((pkg.getFlags() & ApplicationInfo.FLAG_DEBUGGABLE) == 0)
                    && (!onIncremental);

            if (performDexopt) {
                // Compile the layout resources.
                if (SystemProperties.getBoolean(PRECOMPILE_LAYOUTS, false)) {
                    Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "compileLayouts");
                    mViewCompiler.compileLayouts(pkg);
                    Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
                }

                Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
                // Do not run PackageDexOptimizer through the local performDexOpt
                // method because `pkg` may not be in `mPackages` yet.
                //
                // Also, don't fail application installs if the dexopt step fails.
                DexoptOptions dexoptOptions = new DexoptOptions(packageName,
                        REASON_INSTALL,
                        DexoptOptions.DEXOPT_BOOT_COMPLETE
                                | DexoptOptions.DEXOPT_INSTALL_WITH_DEX_METADATA_FILE);
                mPackageDexOptimizer.performDexOpt(pkg,
                        null /* instructionSets */,
                        getOrCreateCompilerPackageStats(pkg),
                        mDexManager.getPackageUseInfoOrDefault(packageName),
                        dexoptOptions);
                Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
            }

            // Notify BackgroundDexOptService that the package has been changed.
            // If this is an update of a package which used to fail to compile,
            // BackgroundDexOptService will remove it from its blacklist.
            // TODO: Layering violation
            BackgroundDexOptService.notifyPackageChanged(packageName);
        }
    }

    /**
     * The set of data needed to successfully install the prepared package. This includes data that
     * will be used to scan and reconcile the package.
     */
    private static class PrepareResult {
        public final boolean replace;
        public final int scanFlags;
        public final int parseFlags;
        @Nullable /* The original Package if it is being replaced, otherwise {@code null} */
        public final AndroidPackage existingPackage;
        public final ParsedPackage packageToScan;
        public final boolean clearCodeCache;
        public final boolean system;
        public final PackageSetting originalPs;
        public final PackageSetting disabledPs;

        private PrepareResult(boolean replace, int scanFlags,
                int parseFlags, AndroidPackage existingPackage,
                ParsedPackage packageToScan, boolean clearCodeCache, boolean system,
                PackageSetting originalPs, PackageSetting disabledPs) {
            this.replace = replace;
            this.scanFlags = scanFlags;
            this.parseFlags = parseFlags;
            this.existingPackage = existingPackage;
            this.packageToScan = packageToScan;
            this.clearCodeCache = clearCodeCache;
            this.system = system;
            this.originalPs = originalPs;
            this.disabledPs = disabledPs;
        }
    }

    private static class PrepareFailure extends PackageManagerException {

        public String conflictingPackage;
        public String conflictingPermission;

        PrepareFailure(int error) {
            super(error, "Failed to prepare for install.");
        }

        PrepareFailure(int error, String detailMessage) {
            super(error, detailMessage);
        }

        PrepareFailure(String message, Exception e) {
            super(e instanceof PackageParserException
                    ? ((PackageParserException) e).error
                    : ((PackageManagerException) e).error,
                    ExceptionUtils.getCompleteMessage(message, e));
        }

        PrepareFailure conflictsWithExistingPermission(String conflictingPermission,
                String conflictingPackage) {
            this.conflictingPermission = conflictingPermission;
            this.conflictingPackage = conflictingPackage;
            return this;
        }
    }

    @GuardedBy("mInstallLock")
    private PrepareResult preparePackageLI(InstallArgs args, PackageInstalledInfo res)
            throws PrepareFailure {
        final int installFlags = args.installFlags;
        final File tmpPackageFile = new File(args.getCodePath());
        final boolean onExternal = args.volumeUuid != null;
        final boolean instantApp = ((installFlags & PackageManager.INSTALL_INSTANT_APP) != 0);
        final boolean fullApp = ((installFlags & PackageManager.INSTALL_FULL_APP) != 0);
        final boolean virtualPreload =
                ((installFlags & PackageManager.INSTALL_VIRTUAL_PRELOAD) != 0);
        @ScanFlags int scanFlags = SCAN_NEW_INSTALL | SCAN_UPDATE_SIGNATURE;
        if (args.move != null) {
            // moving a complete application; perform an initial scan on the new install location
            scanFlags |= SCAN_INITIAL;
        }
        if ((installFlags & PackageManager.INSTALL_DONT_KILL_APP) != 0) {
            scanFlags |= SCAN_DONT_KILL_APP;
        }
        if (instantApp) {
            scanFlags |= SCAN_AS_INSTANT_APP;
        }
        if (fullApp) {
            scanFlags |= SCAN_AS_FULL_APP;
        }
        if (virtualPreload) {
            scanFlags |= SCAN_AS_VIRTUAL_PRELOAD;
        }

        if (DEBUG_INSTALL) Slog.d(TAG, "installPackageLI: path=" + tmpPackageFile);

        // Sanity check
        if (instantApp && onExternal) {
            Slog.i(TAG, "Incompatible ephemeral install; external=" + onExternal);
            throw new PrepareFailure(PackageManager.INSTALL_FAILED_INSTANT_APP_INVALID);
        }

        // Retrieve PackageSettings and parse package
        @ParseFlags final int parseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY
                | PackageParser.PARSE_ENFORCE_CODE
                | (onExternal ? PackageParser.PARSE_EXTERNAL_STORAGE : 0);

        PackageParser pp = new PackageParser();
        pp.setSeparateProcesses(mSeparateProcesses);
        pp.setDisplayMetrics(mMetrics);
        pp.setCallback(mPackageParserCallback);

        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "parsePackage");
        ParsedPackage parsedPackage;
        try {
            parsedPackage = pp.parseParsedPackage(tmpPackageFile, parseFlags, false);
            DexMetadataHelper.validatePackageDexMetadata(parsedPackage);
        } catch (PackageParserException e) {
            throw new PrepareFailure("Failed parse during installPackageLI", e);
        } finally {
            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
        }

        // Instant apps have several additional install-time checks.
        if (instantApp) {
            if (parsedPackage.getTargetSdkVersion() < Build.VERSION_CODES.O) {
                Slog.w(TAG, "Instant app package " + parsedPackage.getPackageName()
                                + " does not target at least O");
                throw new PrepareFailure(INSTALL_FAILED_INSTANT_APP_INVALID,
                        "Instant app package must target at least O");
            }
            if (parsedPackage.getSharedUserId() != null) {
                Slog.w(TAG, "Instant app package " + parsedPackage.getPackageName()
                        + " may not declare sharedUserId.");
                throw new PrepareFailure(INSTALL_FAILED_INSTANT_APP_INVALID,
                        "Instant app package may not declare a sharedUserId");
            }
        }

        if (parsedPackage.isStaticSharedLibrary()) {
            // Static shared libraries have synthetic package names
            renameStaticSharedLibraryPackage(parsedPackage);

            // No static shared libs on external storage
            if (onExternal) {
                Slog.i(TAG, "Static shared libs can only be installed on internal storage.");
                throw new PrepareFailure(INSTALL_FAILED_INVALID_INSTALL_LOCATION,
                        "Packages declaring static-shared libs cannot be updated");
            }
        }

        // If package doesn't declare API override, mark that we have an install
        // time CPU ABI override.
        // TODO(b/135203078): Isn't this always true because cpuAbiOverride isn't assigned during
        //  parsing?
        if (TextUtils.isEmpty(parsedPackage.getCpuAbiOverride())) {
            parsedPackage.setCpuAbiOverride(args.abiOverride);
        }

        String pkgName = res.name = parsedPackage.getPackageName();
        if ((parsedPackage.getFlags() & ApplicationInfo.FLAG_TEST_ONLY) != 0) {
            if ((installFlags & PackageManager.INSTALL_ALLOW_TEST) == 0) {
                throw new PrepareFailure(INSTALL_FAILED_TEST_ONLY, "installPackageLI");
            }
        }

        try {
            // either use what we've been given or parse directly from the APK
            if (args.signingDetails != PackageParser.SigningDetails.UNKNOWN) {
                parsedPackage.setSigningDetails(args.signingDetails);
            } else {
                // TODO(b/136132412): skip for Incremental installation
                ApkParseUtils.collectCertificates(parsedPackage, false /* skipVerify */);
            }
        } catch (PackageParserException e) {
            throw new PrepareFailure("Failed collect during installPackageLI", e);
        }

        if (instantApp && parsedPackage.getSigningDetails().signatureSchemeVersion
                < SignatureSchemeVersion.SIGNING_BLOCK_V2) {
            Slog.w(TAG, "Instant app package " + parsedPackage.getPackageName()
                    + " is not signed with at least APK Signature Scheme v2");
            throw new PrepareFailure(INSTALL_FAILED_INSTANT_APP_INVALID,
                    "Instant app package must be signed with APK Signature Scheme v2 or greater");
        }

        // Get rid of all references to package scan path via parser.
        pp = null;
        boolean systemApp = false;
        boolean replace = false;
        synchronized (mLock) {
            // Check if installing already existing package
            if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) {
                String oldName = mSettings.getRenamedPackageLPr(pkgName);
                if (parsedPackage.getOriginalPackages() != null
                        && parsedPackage.getOriginalPackages().contains(oldName)
                        && mPackages.containsKey(oldName)) {
                    // This package is derived from an original package,
                    // and this device has been updating from that original
                    // name.  We must continue using the original name, so
                    // rename the new package here.
                    parsedPackage.setPackageName(oldName);
                    pkgName = parsedPackage.getPackageName();
                    replace = true;
                    if (DEBUG_INSTALL) {
                        Slog.d(TAG, "Replacing existing renamed package: oldName="
                                + oldName + " pkgName=" + pkgName);
                    }
                } else if (mPackages.containsKey(pkgName)) {
                    // This package, under its official name, already exists
                    // on the device; we should replace it.
                    replace = true;
                    if (DEBUG_INSTALL) Slog.d(TAG, "Replace existing pacakge: " + pkgName);
                }

                if (replace) {
                    // Prevent apps opting out from runtime permissions
                    AndroidPackage oldPackage = mPackages.get(pkgName);
                    final int oldTargetSdk = oldPackage.getTargetSdkVersion();
                    final int newTargetSdk = parsedPackage.getTargetSdkVersion();
                    if (oldTargetSdk > Build.VERSION_CODES.LOLLIPOP_MR1
                            && newTargetSdk <= Build.VERSION_CODES.LOLLIPOP_MR1) {
                        throw new PrepareFailure(
                                PackageManager.INSTALL_FAILED_PERMISSION_MODEL_DOWNGRADE,
                                "Package " + parsedPackage.getPackageName()
                                        + " new target SDK " + newTargetSdk
                                        + " doesn't support runtime permissions but the old"
                                        + " target SDK " + oldTargetSdk + " does.");
                    }
                    // Prevent persistent apps from being updated
                    if (((oldPackage.getFlags() & ApplicationInfo.FLAG_PERSISTENT) != 0)
                            && ((installFlags & PackageManager.INSTALL_STAGED) == 0)) {
                        throw new PrepareFailure(PackageManager.INSTALL_FAILED_INVALID_APK,
                                "Package " + oldPackage.getPackageName() + " is a persistent app. "
                                        + "Persistent apps are not updateable.");
                    }
                }
            }

            PackageSetting ps = mSettings.mPackages.get(pkgName);
            if (ps != null) {
                if (DEBUG_INSTALL) Slog.d(TAG, "Existing package: " + ps);

                // Static shared libs have same package with different versions where
                // we internally use a synthetic package name to allow multiple versions
                // of the same package, therefore we need to compare signatures against
                // the package setting for the latest library version.
                PackageSetting signatureCheckPs = ps;
                if (parsedPackage.isStaticSharedLibrary()) {
                    SharedLibraryInfo libraryInfo = getLatestSharedLibraVersionLPr(parsedPackage);
                    if (libraryInfo != null) {
                        signatureCheckPs = mSettings.getPackageLPr(libraryInfo.getPackageName());
                    }
                }

                // Quick sanity check that we're signed correctly if updating;
                // we'll check this again later when scanning, but we want to
                // bail early here before tripping over redefined permissions.
                final KeySetManagerService ksms = mSettings.mKeySetManagerService;
                if (ksms.shouldCheckUpgradeKeySetLocked(signatureCheckPs, scanFlags)) {
                    if (!ksms.checkUpgradeKeySetLocked(signatureCheckPs, parsedPackage)) {
                        throw new PrepareFailure(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package "
                                + parsedPackage.getPackageName() + " upgrade keys do not match the "
                                + "previously installed version");
                    }
                } else {
                    try {
                        final boolean compareCompat = isCompatSignatureUpdateNeeded(parsedPackage);
                        final boolean compareRecover = isRecoverSignatureUpdateNeeded(
                                parsedPackage);
                        // We don't care about disabledPkgSetting on install for now.
                        final boolean compatMatch = verifySignatures(signatureCheckPs, null,
                                parsedPackage.getSigningDetails(), compareCompat, compareRecover);
                        // The new KeySets will be re-added later in the scanning process.
                        if (compatMatch) {
                            synchronized (mLock) {
                                ksms.removeAppKeySetDataLPw(parsedPackage.getPackageName());
                            }
                        }
                    } catch (PackageManagerException e) {
                        throw new PrepareFailure(e.error, e.getMessage());
                    }
                }

                if (ps.pkg != null) {
                    systemApp = (ps.pkg.getFlags() & ApplicationInfo.FLAG_SYSTEM) != 0;
                }
                res.origUsers = ps.queryInstalledUsers(mUserManager.getUserIds(), true);
            }


            int N = ArrayUtils.size(parsedPackage.getPermissions());
            for (int i = N - 1; i >= 0; i--) {
                final ParsedPermission perm = parsedPackage.getPermissions().get(i);
                final BasePermission bp = mPermissionManager.getPermissionTEMP(perm.getName());

                // Don't allow anyone but the system to define ephemeral permissions.
                if ((perm.protectionLevel & PermissionInfo.PROTECTION_FLAG_INSTANT) != 0
                        && !systemApp) {
                    Slog.w(TAG, "Non-System package " + parsedPackage.getPackageName()
                            + " attempting to delcare ephemeral permission "
                            + perm.getName() + "; Removing ephemeral.");
                    perm.protectionLevel &= ~PermissionInfo.PROTECTION_FLAG_INSTANT;
                }

                // Check whether the newly-scanned package wants to define an already-defined perm
                if (bp != null) {
                    // If the defining package is signed with our cert, it's okay.  This
                    // also includes the "updating the same package" case, of course.
                    // "updating same package" could also involve key-rotation.
                    final boolean sigsOk;
                    final String sourcePackageName = bp.getSourcePackageName();
                    final PackageSettingBase sourcePackageSetting = bp.getSourcePackageSetting();
                    final KeySetManagerService ksms = mSettings.mKeySetManagerService;
                    if (sourcePackageName.equals(parsedPackage.getPackageName())
                            && (ksms.shouldCheckUpgradeKeySetLocked(
                            sourcePackageSetting, scanFlags))) {
                        sigsOk = ksms.checkUpgradeKeySetLocked(sourcePackageSetting, parsedPackage);
                    } else {

                        // in the event of signing certificate rotation, we need to see if the
                        // package's certificate has rotated from the current one, or if it is an
                        // older certificate with which the current is ok with sharing permissions
                        if (sourcePackageSetting.signatures.mSigningDetails.checkCapability(
                                parsedPackage.getSigningDetails(),
                                PackageParser.SigningDetails.CertCapabilities.PERMISSION)) {
                            sigsOk = true;
                        } else if (parsedPackage.getSigningDetails().checkCapability(
                                sourcePackageSetting.signatures.mSigningDetails,
                                PackageParser.SigningDetails.CertCapabilities.PERMISSION)) {

                            // the scanned package checks out, has signing certificate rotation
                            // history, and is newer; bring it over
                            sourcePackageSetting.signatures.mSigningDetails =
                                    parsedPackage.getSigningDetails();
                            sigsOk = true;
                        } else {
                            sigsOk = false;
                        }
                    }
                    if (!sigsOk) {
                        // If the owning package is the system itself, we log but allow
                        // install to proceed; we fail the install on all other permission
                        // redefinitions.
                        if (!sourcePackageName.equals("android")) {
                            throw new PrepareFailure(INSTALL_FAILED_DUPLICATE_PERMISSION, "Package "
                                    + parsedPackage.getPackageName()
                                    + " attempting to redeclare permission "
                                    + perm.getName() + " already owned by "
                                    + sourcePackageName)
                                    .conflictsWithExistingPermission(perm.getName(),
                                            sourcePackageName);
                        } else {
                            Slog.w(TAG, "Package " + parsedPackage.getPackageName()
                                    + " attempting to redeclare system permission "
                                    + perm.getName() + "; ignoring new declaration");
                            parsedPackage.removePermission(i);
                        }
                    } else if (!PLATFORM_PACKAGE_NAME.equals(parsedPackage.getPackageName())) {
                        // Prevent apps to change protection level to dangerous from any other
                        // type as this would allow a privilege escalation where an app adds a
                        // normal/signature permission in other app's group and later redefines
                        // it as dangerous leading to the group auto-grant.
                        if ((perm.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE)
                                == PermissionInfo.PROTECTION_DANGEROUS) {
                            if (bp != null && !bp.isRuntime()) {
                                Slog.w(TAG, "Package " + parsedPackage.getPackageName()
                                        + " trying to change a non-runtime permission "
                                        + perm.getName()
                                        + " to runtime; keeping old protection level");
                                perm.protectionLevel = bp.getProtectionLevel();
                            }
                        }
                    }
                }
            }
        }

        if (systemApp) {
            if (onExternal) {
                // Abort update; system app can't be replaced with app on sdcard
                throw new PrepareFailure(INSTALL_FAILED_INVALID_INSTALL_LOCATION,
                        "Cannot install updates to system apps on sdcard");
            } else if (instantApp) {
                // Abort update; system app can't be replaced with an instant app
                throw new PrepareFailure(INSTALL_FAILED_INSTANT_APP_INVALID,
                        "Cannot update a system app with an instant app");
            }
        }

        if (args.move != null) {
            // We did an in-place move, so dex is ready to roll
            scanFlags |= SCAN_NO_DEX;
            scanFlags |= SCAN_MOVE;

            synchronized (mLock) {
                final PackageSetting ps = mSettings.mPackages.get(pkgName);
                if (ps == null) {
                    res.setError(INSTALL_FAILED_INTERNAL_ERROR,
                            "Missing settings for moved package " + pkgName);
                }

                // We moved the entire application as-is, so bring over the
                // previously derived ABI information.
                parsedPackage.setPrimaryCpuAbi(ps.primaryCpuAbiString)
                        .setSecondaryCpuAbi(ps.secondaryCpuAbiString);
            }

        } else {
            // Enable SCAN_NO_DEX flag to skip dexopt at a later stage
            scanFlags |= SCAN_NO_DEX;

            try {
                String abiOverride = (TextUtils.isEmpty(parsedPackage.getCpuAbiOverride())
                        ? args.abiOverride : parsedPackage.getCpuAbiOverride());
                final boolean extractNativeLibs = !parsedPackage.isLibrary();
                final Pair<PackageAbiHelper.Abis, PackageAbiHelper.NativeLibraryPaths>
                        derivedAbi = mInjector.getAbiHelper().derivePackageAbi(
                                parsedPackage, abiOverride, extractNativeLibs);
                derivedAbi.first.applyTo(parsedPackage);
                derivedAbi.second.applyTo(parsedPackage);
            } catch (PackageManagerException pme) {
                Slog.e(TAG, "Error deriving application ABI", pme);
                throw new PrepareFailure(INSTALL_FAILED_INTERNAL_ERROR,
                        "Error deriving application ABI");
            }
        }

        if (!args.doRename(res.returnCode, parsedPackage)) {
            throw new PrepareFailure(INSTALL_FAILED_INSUFFICIENT_STORAGE, "Failed rename");
        }

        try {
            setUpFsVerityIfPossible(parsedPackage);
        } catch (InstallerException | IOException | DigestException | NoSuchAlgorithmException e) {
            throw new PrepareFailure(INSTALL_FAILED_INTERNAL_ERROR,
                    "Failed to set up verity: " + e);
        }

        if (!instantApp) {
            startIntentFilterVerifications(args.user.getIdentifier(), replace, parsedPackage);
        } else {
            if (DEBUG_DOMAIN_VERIFICATION) {
                Slog.d(TAG, "Not verifying instant app install for app links: " + pkgName);
            }
        }
        final PackageFreezer freezer =
                freezePackageForInstall(pkgName, installFlags, "installPackageLI");
        boolean shouldCloseFreezerBeforeReturn = true;
        try {
            final AndroidPackage existingPackage;
            String renamedPackage = null;
            boolean sysPkg = false;
            int targetScanFlags = scanFlags;
            int targetParseFlags = parseFlags;
            final PackageSetting ps;
            final PackageSetting disabledPs;
            final PackageSetting[] childPackages;
            if (replace) {
                if (parsedPackage.isStaticSharedLibrary()) {
                    // Static libs have a synthetic package name containing the version
                    // and cannot be updated as an update would get a new package name,
                    // unless this is the exact same version code which is useful for
                    // development.
                    AndroidPackage existingPkg = mPackages.get(parsedPackage.getPackageName());
                    if (existingPkg != null
                            && existingPkg.getLongVersionCode()
                            != parsedPackage.getLongVersionCode()) {
                        throw new PrepareFailure(INSTALL_FAILED_DUPLICATE_PACKAGE,
                                "Packages declaring "
                                        + "static-shared libs cannot be updated");
                    }
                }

                final boolean isInstantApp = (scanFlags & SCAN_AS_INSTANT_APP) != 0;

                final AndroidPackage oldPackage;
                final String pkgName11 = parsedPackage.getPackageName();
                final int[] allUsers;
                final int[] installedUsers;

                synchronized (mLock) {
                    oldPackage = mPackages.get(pkgName11);
                    existingPackage = oldPackage;
                    if (DEBUG_INSTALL) {
                        // TODO(b/135203078): PackageImpl.toString()
                        Slog.d(TAG,
                                "replacePackageLI: new=" + parsedPackage + ", old=" + oldPackage);
                    }

                    ps = mSettings.mPackages.get(pkgName11);
                    disabledPs = mSettings.getDisabledSystemPkgLPr(ps);

                    // verify signatures are valid
                    final KeySetManagerService ksms = mSettings.mKeySetManagerService;
                    if (ksms.shouldCheckUpgradeKeySetLocked(ps, scanFlags)) {
                        if (!ksms.checkUpgradeKeySetLocked(ps, parsedPackage)) {
                            throw new PrepareFailure(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
                                    "New package not signed by keys specified by upgrade-keysets: "
                                            + pkgName11);
                        }
                    } else {
                        // default to original signature matching
                        if (!parsedPackage.getSigningDetails().checkCapability(
                                oldPackage.getSigningDetails(),
                                SigningDetails.CertCapabilities.INSTALLED_DATA)
                                && !oldPackage.getSigningDetails().checkCapability(
                                parsedPackage.getSigningDetails(),
                                SigningDetails.CertCapabilities.ROLLBACK)) {
                            throw new PrepareFailure(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
                                    "New package has a different signature: " + pkgName11);
                        }
                    }

                    // don't allow a system upgrade unless the upgrade hash matches
                    if (oldPackage.getRestrictUpdateHash() != null && oldPackage.isSystem()) {
                        final byte[] digestBytes;
                        try {
                            final MessageDigest digest = MessageDigest.getInstance("SHA-512");
                            updateDigest(digest, new File(parsedPackage.getBaseCodePath()));
                            if (!ArrayUtils.isEmpty(parsedPackage.getSplitCodePaths())) {
                                for (String path : parsedPackage.getSplitCodePaths()) {
                                    updateDigest(digest, new File(path));
                                }
                            }
                            digestBytes = digest.digest();
                        } catch (NoSuchAlgorithmException | IOException e) {
                            throw new PrepareFailure(INSTALL_FAILED_INVALID_APK,
                                    "Could not compute hash: " + pkgName11);
                        }
                        if (!Arrays.equals(oldPackage.getRestrictUpdateHash(), digestBytes)) {
                            throw new PrepareFailure(INSTALL_FAILED_INVALID_APK,
                                    "New package fails restrict-update check: " + pkgName11);
                        }
                        // retain upgrade restriction
                        parsedPackage.setRestrictUpdateHash(oldPackage.getRestrictUpdateHash());
                    }

                    // Check for shared user id changes
                    String invalidPackageName = null;
                    if (!Objects.equals(oldPackage.getSharedUserId(),
                            parsedPackage.getSharedUserId())) {
                        invalidPackageName = parsedPackage.getPackageName();
                    }

                    if (invalidPackageName != null) {
                        throw new PrepareFailure(INSTALL_FAILED_SHARED_USER_INCOMPATIBLE,
                                "Package " + invalidPackageName + " tried to change user "
                                        + oldPackage.getSharedUserId());
                    }

                    // In case of rollback, remember per-user/profile install state
                    allUsers = mUserManager.getUserIds();
                    installedUsers = ps.queryInstalledUsers(allUsers, true);


                    // don't allow an upgrade from full to ephemeral
                    if (isInstantApp) {
                        if (args.user == null || args.user.getIdentifier() == UserHandle.USER_ALL) {
                            for (int currentUser : allUsers) {
                                if (!ps.getInstantApp(currentUser)) {
                                    // can't downgrade from full to instant
                                    Slog.w(TAG,
                                            "Can't replace full app with instant app: " + pkgName11
                                                    + " for user: " + currentUser);
                                    throw new PrepareFailure(
                                            PackageManager.INSTALL_FAILED_INSTANT_APP_INVALID);
                                }
                            }
                        } else if (!ps.getInstantApp(args.user.getIdentifier())) {
                            // can't downgrade from full to instant
                            Slog.w(TAG, "Can't replace full app with instant app: " + pkgName11
                                    + " for user: " + args.user.getIdentifier());
                            throw new PrepareFailure(
                                    PackageManager.INSTALL_FAILED_INSTANT_APP_INVALID);
                        }
                    }
                }

                // Update what is removed
                res.removedInfo = new PackageRemovedInfo(this);
                res.removedInfo.uid = oldPackage.getUid();
                res.removedInfo.removedPackage = oldPackage.getPackageName();
                res.removedInfo.installerPackageName = ps.installSource.installerPackageName;
                res.removedInfo.isStaticSharedLib = parsedPackage.getStaticSharedLibName() != null;
                res.removedInfo.isUpdate = true;
                res.removedInfo.origUsers = installedUsers;
                res.removedInfo.installReasons = new SparseArray<>(installedUsers.length);
                for (int i = 0; i < installedUsers.length; i++) {
                    final int userId = installedUsers[i];
                    res.removedInfo.installReasons.put(userId, ps.getInstallReason(userId));
                }

                sysPkg = (isSystemApp(oldPackage));
                if (sysPkg) {
                    // Set the system/privileged/oem/vendor/product flags as needed
                    final boolean privileged = isPrivilegedApp(oldPackage);
                    final boolean oem = isOemApp(oldPackage);
                    final boolean vendor = isVendorApp(oldPackage);
                    final boolean product = isProductApp(oldPackage);
                    final boolean odm = isOdmApp(oldPackage);
                    final @ParseFlags int systemParseFlags = parseFlags;
                    final @ScanFlags int systemScanFlags = scanFlags
                            | SCAN_AS_SYSTEM
                            | (privileged ? SCAN_AS_PRIVILEGED : 0)
                            | (oem ? SCAN_AS_OEM : 0)
                            | (vendor ? SCAN_AS_VENDOR : 0)
                            | (product ? SCAN_AS_PRODUCT : 0)
                            | (odm ? SCAN_AS_ODM : 0);

                    if (DEBUG_INSTALL) {
                        Slog.d(TAG, "replaceSystemPackageLI: new=" + parsedPackage
                                + ", old=" + oldPackage);
                    }
                    res.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
                    parsedPackage.setUpdatedSystemApp(true);
                    targetParseFlags = systemParseFlags;
                    targetScanFlags = systemScanFlags;
                } else { // non system replace
                    replace = true;
                    if (DEBUG_INSTALL) {
                        Slog.d(TAG,
                                "replaceNonSystemPackageLI: new=" + parsedPackage + ", old="
                                        + oldPackage);
                    }
                }
            } else { // new package install
                ps = null;
                disabledPs = null;
                replace = false;
                existingPackage = null;
                // Remember this for later, in case we need to rollback this install
                String pkgName1 = parsedPackage.getPackageName();

                if (DEBUG_INSTALL) Slog.d(TAG, "installNewPackageLI: " + parsedPackage);

                // TODO(patb): MOVE TO RECONCILE
                synchronized (mLock) {
                    renamedPackage = mSettings.getRenamedPackageLPr(pkgName1);
                    if (renamedPackage != null) {
                        // A package with the same name is already installed, though
                        // it has been renamed to an older name.  The package we
                        // are trying to install should be installed as an update to
                        // the existing one, but that has not been requested, so bail.
                        throw new PrepareFailure(INSTALL_FAILED_ALREADY_EXISTS,
                                "Attempt to re-install " + pkgName1
                                        + " without first uninstalling package running as "
                                        + renamedPackage);
                    }
                    if (mPackages.containsKey(pkgName1)) {
                        // Don't allow installation over an existing package with the same name.
                        throw new PrepareFailure(INSTALL_FAILED_ALREADY_EXISTS,
                                "Attempt to re-install " + pkgName1
                                        + " without first uninstalling.");
                    }
                }
            }
            // we're passing the freezer back to be closed in a later phase of install
            shouldCloseFreezerBeforeReturn = false;

            return new PrepareResult(replace, targetScanFlags, targetParseFlags,
                    existingPackage, parsedPackage, replace /* clearCodeCache */, sysPkg,
                    ps, disabledPs);
        } finally {
            res.freezer = freezer;
            if (shouldCloseFreezerBeforeReturn) {
                freezer.close();
            }
        }
    }

    /**
     * Set up fs-verity for the given package if possible.  This requires a feature flag of system
     * property to be enabled only if the kernel supports fs-verity.
     *
     * <p>When the feature flag is set to legacy mode, only APK is supported (with some experimental
     * kernel patches). In normal mode, all file format can be supported.
     */
    private void setUpFsVerityIfPossible(AndroidPackage pkg) throws InstallerException,
            PrepareFailure, IOException, DigestException, NoSuchAlgorithmException {
        final boolean standardMode = PackageManagerServiceUtils.isApkVerityEnabled();
        final boolean legacyMode = PackageManagerServiceUtils.isLegacyApkVerityEnabled();
        if (!standardMode && !legacyMode) {
            return;
        }

        // Collect files we care for fs-verity setup.
        ArrayMap<String, String> fsverityCandidates = new ArrayMap<>();
        if (legacyMode) {
            synchronized (mLock) {
                final PackageSetting ps = mSettings.mPackages.get(pkg.getPackageName());
                if (ps != null && ps.isPrivileged()) {
                    fsverityCandidates.put(pkg.getBaseCodePath(), null);
                    if (pkg.getSplitCodePaths() != null) {
                        for (String splitPath : pkg.getSplitCodePaths()) {
                            fsverityCandidates.put(splitPath, null);
                        }
                    }
                }
            }
        } else {
            // NB: These files will become only accessible if the signing key is loaded in kernel's
            // .fs-verity keyring.
            fsverityCandidates.put(pkg.getBaseCodePath(),
                    VerityUtils.getFsveritySignatureFilePath(pkg.getBaseCodePath()));

            final String dmPath = DexMetadataHelper.buildDexMetadataPathForApk(
                    pkg.getBaseCodePath());
            if (new File(dmPath).exists()) {
                fsverityCandidates.put(dmPath, VerityUtils.getFsveritySignatureFilePath(dmPath));
            }

            if (pkg.getSplitCodePaths() != null) {
                for (String path : pkg.getSplitCodePaths()) {
                    fsverityCandidates.put(path, VerityUtils.getFsveritySignatureFilePath(path));

                    final String splitDmPath = DexMetadataHelper.buildDexMetadataPathForApk(path);
                    if (new File(splitDmPath).exists()) {
                        fsverityCandidates.put(splitDmPath,
                                VerityUtils.getFsveritySignatureFilePath(splitDmPath));
                    }
                }
            }
        }

        for (Map.Entry<String, String> entry : fsverityCandidates.entrySet()) {
            final String filePath = entry.getKey();
            final String signaturePath = entry.getValue();

            if (!legacyMode) {
                // fs-verity is optional for now.  Only set up if signature is provided.
                if (new File(signaturePath).exists() && !VerityUtils.hasFsverity(filePath)) {
                    try {
                        VerityUtils.setUpFsverity(filePath, signaturePath);
                    } catch (IOException e) {
                        throw new PrepareFailure(PackageManager.INSTALL_FAILED_BAD_SIGNATURE,
                                "Failed to enable fs-verity: " + e);
                    }
                }
                continue;
            }

            // In legacy mode, fs-verity can only be enabled by process with CAP_SYS_ADMIN.
            final VerityUtils.SetupResult result = VerityUtils.generateApkVeritySetupData(filePath);
            if (result.isOk()) {
                if (Build.IS_DEBUGGABLE) Slog.i(TAG, "Enabling verity to " + filePath);
                final FileDescriptor fd = result.getUnownedFileDescriptor();
                try {
                    final byte[] rootHash = VerityUtils.generateApkVerityRootHash(filePath);
                    try {
                        // A file may already have fs-verity, e.g. when reused during a split
                        // install. If the measurement succeeds, no need to attempt to set up.
                        mInstaller.assertFsverityRootHashMatches(filePath, rootHash);
                    } catch (InstallerException e) {
                        mInstaller.installApkVerity(filePath, fd, result.getContentSize());
                        mInstaller.assertFsverityRootHashMatches(filePath, rootHash);
                    }
                } finally {
                    IoUtils.closeQuietly(fd);
                }
            } else if (result.isFailed()) {
                throw new PrepareFailure(PackageManager.INSTALL_FAILED_BAD_SIGNATURE,
                        "Failed to generate verity");
            }
        }
    }

    private void startIntentFilterVerifications(int userId, boolean replacing, AndroidPackage pkg) {
        if (mIntentFilterVerifierComponent == null) {
            Slog.w(TAG, "No IntentFilter verification will not be done as "
                    + "there is no IntentFilterVerifier available!");
            return;
        }

        final int verifierUid = getPackageUid(
                mIntentFilterVerifierComponent.getPackageName(),
                MATCH_DEBUG_TRIAGED_MISSING,
                (userId == UserHandle.USER_ALL) ? UserHandle.USER_SYSTEM : userId);

        Message msg = mHandler.obtainMessage(START_INTENT_FILTER_VERIFICATIONS);
        msg.obj = new IFVerificationParams(
                pkg.getPackageName(),
                hasDomainURLs(pkg),
                pkg.getActivities(),
                replacing,
                userId,
                verifierUid
        );
        mHandler.sendMessage(msg);
    }

    private void verifyIntentFiltersIfNeeded(int userId, int verifierUid, boolean replacing,
            String packageName,
            boolean hasDomainUrls,
            List<ParsedActivity> activities) {
        int size = activities.size();
        if (size == 0) {
            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
                    "No activity, so no need to verify any IntentFilter!");
            return;
        }

        if (!hasDomainUrls) {
            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
                    "No domain URLs, so no need to verify any IntentFilter!");
            return;
        }

        if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Checking for userId:" + userId
                + " if any IntentFilter from the " + size
                + " Activities needs verification ...");

        int count = 0;

        synchronized (mLock) {
            // If this is a new install and we see that we've already run verification for this
            // package, we have nothing to do: it means the state was restored from backup.
            if (!replacing) {
                IntentFilterVerificationInfo ivi =
                        mSettings.getIntentFilterVerificationLPr(packageName);
                if (ivi != null) {
                    if (DEBUG_DOMAIN_VERIFICATION) {
                        Slog.i(TAG, "Package " + packageName+ " already verified: status="
                                + ivi.getStatusString());
                    }
                    return;
                }
            }

            // If any filters need to be verified, then all need to be.
            boolean needToVerify = false;
            for (ParsedActivity a : activities) {
                for (ParsedActivityIntentInfo filter : a.intents) {
                    if (filter.needsVerification() && needsNetworkVerificationLPr(filter)) {
                        if (DEBUG_DOMAIN_VERIFICATION) {
                            Slog.d(TAG,
                                    "Intent filter needs verification, so processing all filters");
                        }
                        needToVerify = true;
                        break;
                    }
                }
            }

            if (needToVerify) {
                final int verificationId = mIntentFilterVerificationToken++;
                for (ParsedActivity a : activities) {
                    for (ParsedActivityIntentInfo filter : a.intents) {
                        if (filter.handlesWebUris(true) && needsNetworkVerificationLPr(filter)) {
                            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
                                    "Verification needed for IntentFilter:" + filter.toString());
                            mIntentFilterVerifier.addOneIntentFilterVerification(
                                    verifierUid, userId, verificationId, filter, packageName);
                            count++;
                        }
                    }
                }
            }
        }

        if (count > 0) {
            if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Starting " + count
                    + " IntentFilter verification" + (count > 1 ? "s" : "")
                    +  " for userId:" + userId);
            mIntentFilterVerifier.startVerifications(userId);
        } else {
            if (DEBUG_DOMAIN_VERIFICATION) {
                Slog.d(TAG, "No filters or not all autoVerify for " + packageName);
            }
        }
    }

    @GuardedBy("mLock")
    private boolean needsNetworkVerificationLPr(ParsedActivityIntentInfo filter) {
        final String packageName = filter.getPackageName();

        IntentFilterVerificationInfo ivi = mSettings.getIntentFilterVerificationLPr(
                packageName);
        if (ivi == null) {
            return true;
        }
        int status = ivi.getStatus();
        switch (status) {
            case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED:
            case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS:
            case INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ASK:
                return true;

            default:
                // Nothing to do
                return false;
        }
    }

    private static boolean isExternal(AndroidPackage pkg) {
        return (pkg.getFlags() & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
    }

    private static boolean isExternal(PackageSetting ps) {
        return (ps.pkgFlags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
    }

    static boolean isSystemApp(AndroidPackage pkg) {
        return (pkg.getFlags() & ApplicationInfo.FLAG_SYSTEM) != 0;
    }

    private static boolean isPrivilegedApp(AndroidPackage pkg) {
        return (pkg.getPrivateFlags() & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0;
    }

    private static boolean isOemApp(AndroidPackage pkg) {
        return (pkg.getPrivateFlags() & ApplicationInfo.PRIVATE_FLAG_OEM) != 0;
    }

    private static boolean isVendorApp(AndroidPackage pkg) {
        return (pkg.getPrivateFlags() & ApplicationInfo.PRIVATE_FLAG_VENDOR) != 0;
    }

    private static boolean isProductApp(AndroidPackage pkg) {
        return (pkg.getPrivateFlags() & ApplicationInfo.PRIVATE_FLAG_PRODUCT) != 0;
    }

    private static boolean isSystemExtApp(AndroidPackage pkg) {
        return (pkg.getPrivateFlags()
                & ApplicationInfo.PRIVATE_FLAG_SYSTEM_EXT) != 0;
    }

    private static boolean isOdmApp(AndroidPackage pkg) {
        return (pkg.getPrivateFlags() & ApplicationInfo.PRIVATE_FLAG_ODM) != 0;
    }

    private static boolean hasDomainURLs(AndroidPackage pkg) {
        return (pkg.getPrivateFlags() & ApplicationInfo.PRIVATE_FLAG_HAS_DOMAIN_URLS) != 0;
    }

    private static boolean isSystemApp(PackageSetting ps) {
        return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0;
    }

    private static boolean isUpdatedSystemApp(PackageSetting ps) {
        return (ps.pkgFlags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0;
    }

    private VersionInfo getSettingsVersionForPackage(AndroidPackage pkg) {
        if (isExternal(pkg)) {
            if (TextUtils.isEmpty(pkg.getVolumeUuid())) {
                return mSettings.getExternalVersion();
            } else {
                return mSettings.findOrCreateVersion(pkg.getVolumeUuid());
            }
        } else {
            return mSettings.getInternalVersion();
        }
    }

    private void deleteTempPackageFiles() {
        // TODO: Is this used?
        final FilenameFilter filter =
                (dir, name) -> name.startsWith("vmdl") && name.endsWith(".tmp");
    }

    @Override
    public void deletePackageAsUser(String packageName, int versionCode,
            IPackageDeleteObserver observer, int userId, int flags) {
        deletePackageVersioned(new VersionedPackage(packageName, versionCode),
                new LegacyPackageDeleteObserver(observer).getBinder(), userId, flags);
    }

    @Override
    public void deletePackageVersioned(VersionedPackage versionedPackage,
            final IPackageDeleteObserver2 observer, final int userId, final int deleteFlags) {
        final int callingUid = Binder.getCallingUid();
        mContext.enforceCallingOrSelfPermission(
                android.Manifest.permission.DELETE_PACKAGES, null);
        final boolean canViewInstantApps = canViewInstantApps(callingUid, userId);
        Preconditions.checkNotNull(versionedPackage);
        Preconditions.checkNotNull(observer);
        Preconditions.checkArgumentInRange(versionedPackage.getLongVersionCode(),
                PackageManager.VERSION_CODE_HIGHEST,
                Long.MAX_VALUE, "versionCode must be >= -1");

        final String packageName = versionedPackage.getPackageName();
        final long versionCode = versionedPackage.getLongVersionCode();
        final String internalPackageName;
        synchronized (mLock) {
            // Normalize package name to handle renamed packages and static libs
            internalPackageName = resolveInternalPackageNameLPr(packageName, versionCode);
        }

        final int uid = Binder.getCallingUid();
        if (!isOrphaned(internalPackageName)
                && !isCallerAllowedToSilentlyUninstall(uid, internalPackageName)) {
            mHandler.post(() -> {
                try {
                    final Intent intent = new Intent(Intent.ACTION_UNINSTALL_PACKAGE);
                    intent.setData(Uri.fromParts(PACKAGE_SCHEME, packageName, null));
                    intent.putExtra(PackageInstaller.EXTRA_CALLBACK, observer.asBinder());
                    observer.onUserActionRequired(intent);
                } catch (RemoteException re) {
                }
            });
            return;
        }
        final boolean deleteAllUsers = (deleteFlags & PackageManager.DELETE_ALL_USERS) != 0;
        final int[] users = deleteAllUsers ? mUserManager.getUserIds() : new int[]{userId};
        if (UserHandle.getUserId(uid) != userId || (deleteAllUsers && users.length > 1)) {
            mContext.enforceCallingOrSelfPermission(
                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
                    "deletePackage for user " + userId);
        }

        if (isUserRestricted(userId, UserManager.DISALLOW_UNINSTALL_APPS)) {
            mHandler.post(() -> {
                try {
                    observer.onPackageDeleted(packageName,
                            PackageManager.DELETE_FAILED_USER_RESTRICTED, null);
                } catch (RemoteException re) {
                }
            });
            return;
        }

        if (!deleteAllUsers && getBlockUninstallForUser(internalPackageName, userId)) {
            mHandler.post(() -> {
                try {
                    observer.onPackageDeleted(packageName,
                            PackageManager.DELETE_FAILED_OWNER_BLOCKED, null);
                } catch (RemoteException re) {
                }
            });
            return;
        }

        if (DEBUG_REMOVE) {
            Slog.d(TAG, "deletePackageAsUser: pkg=" + internalPackageName + " user=" + userId
                    + " deleteAllUsers: " + deleteAllUsers + " version="
                    + (versionCode == PackageManager.VERSION_CODE_HIGHEST
                    ? "VERSION_CODE_HIGHEST" : versionCode));
        }
        // Queue up an async operation since the package deletion may take a little while.
        mHandler.post(() -> {
            int returnCode;
            final PackageSetting ps = mSettings.mPackages.get(internalPackageName);
            boolean doDeletePackage = true;
            if (ps != null) {
                final boolean targetIsInstantApp =
                        ps.getInstantApp(UserHandle.getUserId(callingUid));
                doDeletePackage = !targetIsInstantApp
                        || canViewInstantApps;
            }
            if (doDeletePackage) {
                if (!deleteAllUsers) {
                    returnCode = deletePackageX(internalPackageName, versionCode,
                            userId, deleteFlags);
                } else {
                    int[] blockUninstallUserIds = getBlockUninstallForUsers(
                            internalPackageName, users);
                    // If nobody is blocking uninstall, proceed with delete for all users
                    if (ArrayUtils.isEmpty(blockUninstallUserIds)) {
                        returnCode = deletePackageX(internalPackageName, versionCode,
                                userId, deleteFlags);
                    } else {
                        // Otherwise uninstall individually for users with blockUninstalls=false
                        final int userFlags = deleteFlags & ~PackageManager.DELETE_ALL_USERS;
                        for (int userId1 : users) {
                            if (!ArrayUtils.contains(blockUninstallUserIds, userId1)) {
                                returnCode = deletePackageX(internalPackageName, versionCode,
                                        userId1, userFlags);
                                if (returnCode != PackageManager.DELETE_SUCCEEDED) {
                                    Slog.w(TAG, "Package delete failed for user " + userId1
                                            + ", returnCode " + returnCode);
                                }
                            }
                        }
                        // The app has only been marked uninstalled for certain users.
                        // We still need to report that delete was blocked
                        returnCode = PackageManager.DELETE_FAILED_OWNER_BLOCKED;
                    }
                }
            } else {
                returnCode = PackageManager.DELETE_FAILED_INTERNAL_ERROR;
            }
            try {
                observer.onPackageDeleted(packageName, returnCode, null);
            } catch (RemoteException e) {
                Log.i(TAG, "Observer no longer exists.");
            } //end catch
        });
    }

    private String resolveExternalPackageNameLPr(AndroidPackage pkg) {
        if (pkg.getStaticSharedLibName() != null) {
            return pkg.getManifestPackageName();
        }
        return pkg.getPackageName();
    }

    @GuardedBy("mLock")
    private String resolveInternalPackageNameLPr(String packageName, long versionCode) {
        // Handle renamed packages
        String normalizedPackageName = mSettings.getRenamedPackageLPr(packageName);
        packageName = normalizedPackageName != null ? normalizedPackageName : packageName;

        // Is this a static library?
        LongSparseArray<SharedLibraryInfo> versionedLib =
                mStaticLibsByDeclaringPackage.get(packageName);
        if (versionedLib == null || versionedLib.size() <= 0) {
            return packageName;
        }

        // Figure out which lib versions the caller can see
        LongSparseLongArray versionsCallerCanSee = null;
        final int callingAppId = UserHandle.getAppId(Binder.getCallingUid());
        if (callingAppId != Process.SYSTEM_UID && callingAppId != Process.SHELL_UID
                && callingAppId != Process.ROOT_UID) {
            versionsCallerCanSee = new LongSparseLongArray();
            String libName = versionedLib.valueAt(0).getName();
            String[] uidPackages = getPackagesForUid(Binder.getCallingUid());
            if (uidPackages != null) {
                for (String uidPackage : uidPackages) {
                    PackageSetting ps = mSettings.getPackageLPr(uidPackage);
                    final int libIdx = ArrayUtils.indexOf(ps.usesStaticLibraries, libName);
                    if (libIdx >= 0) {
                        final long libVersion = ps.usesStaticLibrariesVersions[libIdx];
                        versionsCallerCanSee.append(libVersion, libVersion);
                    }
                }
            }
        }

        // Caller can see nothing - done
        if (versionsCallerCanSee != null && versionsCallerCanSee.size() <= 0) {
            return packageName;
        }

        // Find the version the caller can see and the app version code
        SharedLibraryInfo highestVersion = null;
        final int versionCount = versionedLib.size();
        for (int i = 0; i < versionCount; i++) {
            SharedLibraryInfo libraryInfo = versionedLib.valueAt(i);
            if (versionsCallerCanSee != null && versionsCallerCanSee.indexOfKey(
                    libraryInfo.getLongVersion()) < 0) {
                continue;
            }
            final long libVersionCode = libraryInfo.getDeclaringPackage().getLongVersionCode();
            if (versionCode != PackageManager.VERSION_CODE_HIGHEST) {
                if (libVersionCode == versionCode) {
                    return libraryInfo.getPackageName();
                }
            } else if (highestVersion == null) {
                highestVersion = libraryInfo;
            } else if (libVersionCode  > highestVersion
                    .getDeclaringPackage().getLongVersionCode()) {
                highestVersion = libraryInfo;
            }
        }

        if (highestVersion != null) {
            return highestVersion.getPackageName();
        }

        return packageName;
    }

    boolean isCallerVerifier(int callingUid) {
        final int callingUserId = UserHandle.getUserId(callingUid);
        return mRequiredVerifierPackage != null &&
                callingUid == getPackageUid(mRequiredVerifierPackage, 0, callingUserId);
    }

    private boolean isCallerAllowedToSilentlyUninstall(int callingUid, String pkgName) {
        if (callingUid == Process.SHELL_UID || callingUid == Process.ROOT_UID
              || UserHandle.getAppId(callingUid) == Process.SYSTEM_UID) {
            return true;
        }
        final int callingUserId = UserHandle.getUserId(callingUid);
        // If the caller installed the pkgName, then allow it to silently uninstall.
        if (callingUid == getPackageUid(getInstallerPackageName(pkgName), 0, callingUserId)) {
            return true;
        }

        // Allow package verifier to silently uninstall.
        if (mRequiredVerifierPackage != null &&
                callingUid == getPackageUid(mRequiredVerifierPackage, 0, callingUserId)) {
            return true;
        }

        // Allow package uninstaller to silently uninstall.
        if (mRequiredUninstallerPackage != null &&
                callingUid == getPackageUid(mRequiredUninstallerPackage, 0, callingUserId)) {
            return true;
        }

        // Allow storage manager to silently uninstall.
        if (mStorageManagerPackage != null &&
                callingUid == getPackageUid(mStorageManagerPackage, 0, callingUserId)) {
            return true;
        }

        // Allow caller having MANAGE_PROFILE_AND_DEVICE_OWNERS permission to silently
        // uninstall for device owner provisioning.
        if (checkUidPermission(MANAGE_PROFILE_AND_DEVICE_OWNERS, callingUid)
                == PERMISSION_GRANTED) {
            return true;
        }

        return false;
    }

    private int[] getBlockUninstallForUsers(String packageName, int[] userIds) {
        int[] result = EMPTY_INT_ARRAY;
        for (int userId : userIds) {
            if (getBlockUninstallForUser(packageName, userId)) {
                result = ArrayUtils.appendInt(result, userId);
            }
        }
        return result;
    }

    @Override
    public boolean isPackageDeviceAdminOnAnyUser(String packageName) {
        final int callingUid = Binder.getCallingUid();
        if (checkUidPermission(android.Manifest.permission.MANAGE_USERS, callingUid)
                != PERMISSION_GRANTED) {
            EventLog.writeEvent(0x534e4554, "128599183", -1, "");
            throw new SecurityException(android.Manifest.permission.MANAGE_USERS
                    + " permission is required to call this API");
        }
        if (getInstantAppPackageName(callingUid) != null
                && !isCallerSameApp(packageName, callingUid)) {
            return false;
        }
        return isPackageDeviceAdmin(packageName, UserHandle.USER_ALL);
    }

    private boolean isPackageDeviceAdmin(String packageName, int userId) {
        IDevicePolicyManager dpm = IDevicePolicyManager.Stub.asInterface(
                ServiceManager.getService(Context.DEVICE_POLICY_SERVICE));
        try {
            if (dpm != null) {
                final ComponentName deviceOwnerComponentName = dpm.getDeviceOwnerComponent(
                        /* callingUserOnly =*/ false);
                final String deviceOwnerPackageName = deviceOwnerComponentName == null ? null
                        : deviceOwnerComponentName.getPackageName();
                // Does the package contains the device owner?
                // TODO Do we have to do it even if userId != UserHandle.USER_ALL?  Otherwise,
                // this check is probably not needed, since DO should be registered as a device
                // admin on some user too. (Original bug for this: b/17657954)
                if (packageName.equals(deviceOwnerPackageName)) {
                    return true;
                }
                // Does it contain a device admin for any user?
                int[] users;
                if (userId == UserHandle.USER_ALL) {
                    users = mUserManager.getUserIds();
                } else {
                    users = new int[]{userId};
                }
                for (int i = 0; i < users.length; ++i) {
                    if (dpm.packageHasActiveAdmins(packageName, users[i])) {
                        return true;
                    }
                }
            }
        } catch (RemoteException e) {
        }
        return false;
    }

    private boolean shouldKeepUninstalledPackageLPr(String packageName) {
        return mKeepUninstalledPackages != null && mKeepUninstalledPackages.contains(packageName);
    }

    /**
     *  This method is an internal method that could be get invoked either
     *  to delete an installed package or to clean up a failed installation.
     *  After deleting an installed package, a broadcast is sent to notify any
     *  listeners that the package has been removed. For cleaning up a failed
     *  installation, the broadcast is not necessary since the package's
     *  installation wouldn't have sent the initial broadcast either
     *  The key steps in deleting a package are
     *  deleting the package information in internal structures like mPackages,
     *  deleting the packages base directories through installd
     *  updating mSettings to reflect current status
     *  persisting settings for later use
     *  sending a broadcast if necessary
     */
    int deletePackageX(String packageName, long versionCode, int userId, int deleteFlags) {
        final PackageRemovedInfo info = new PackageRemovedInfo(this);
        final boolean res;

        final int removeUser = (deleteFlags & PackageManager.DELETE_ALL_USERS) != 0
                ? UserHandle.USER_ALL : userId;

        if (isPackageDeviceAdmin(packageName, removeUser)) {
            Slog.w(TAG, "Not removing package " + packageName + ": has active device admin");
            return PackageManager.DELETE_FAILED_DEVICE_POLICY_MANAGER;
        }

        final PackageSetting uninstalledPs;
        final PackageSetting disabledSystemPs;
        final AndroidPackage pkg;

        // for the uninstall-updates case and restricted profiles, remember the per-
        // user handle installed state
        int[] allUsers;
        /** enabled state of the uninstalled application */
        final int origEnabledState;
        synchronized (mLock) {
            uninstalledPs = mSettings.mPackages.get(packageName);
            if (uninstalledPs == null) {
                Slog.w(TAG, "Not removing non-existent package " + packageName);
                return PackageManager.DELETE_FAILED_INTERNAL_ERROR;
            }

            if (versionCode != PackageManager.VERSION_CODE_HIGHEST
                    && uninstalledPs.versionCode != versionCode) {
                Slog.w(TAG, "Not removing package " + packageName + " with versionCode "
                        + uninstalledPs.versionCode + " != " + versionCode);
                return PackageManager.DELETE_FAILED_INTERNAL_ERROR;
            }

            disabledSystemPs = mSettings.getDisabledSystemPkgLPr(packageName);
            // Save the enabled state before we delete the package. When deleting a stub
            // application we always set the enabled state to 'disabled'.
            origEnabledState = uninstalledPs == null
                    ? COMPONENT_ENABLED_STATE_DEFAULT : uninstalledPs.getEnabled(userId);
            // Static shared libs can be declared by any package, so let us not
            // allow removing a package if it provides a lib others depend on.
            pkg = mPackages.get(packageName);

            allUsers = mUserManager.getUserIds();

            if (pkg != null && pkg.getStaticSharedLibName() != null) {
                SharedLibraryInfo libraryInfo = getSharedLibraryInfoLPr(
                        pkg.getStaticSharedLibName(), pkg.getStaticSharedLibVersion());
                if (libraryInfo != null) {
                    for (int currUserId : allUsers) {
                        if (removeUser != UserHandle.USER_ALL && removeUser != currUserId) {
                            continue;
                        }
                        List<VersionedPackage> libClientPackages = getPackagesUsingSharedLibraryLPr(
                                libraryInfo, MATCH_KNOWN_PACKAGES, currUserId);
                        if (!ArrayUtils.isEmpty(libClientPackages)) {
                            Slog.w(TAG, "Not removing package " + pkg.getManifestPackageName()
                                    + " hosting lib " + libraryInfo.getName() + " version "
                                    + libraryInfo.getLongVersion() + " used by " + libClientPackages
                                    + " for user " + currUserId);
                            return PackageManager.DELETE_FAILED_USED_SHARED_LIBRARY;
                        }
                    }
                }
            }

            info.origUsers = uninstalledPs.queryInstalledUsers(allUsers, true);
        }

        final int freezeUser;
        if (isUpdatedSystemApp(uninstalledPs)
                && ((deleteFlags & PackageManager.DELETE_SYSTEM_APP) == 0)) {
            // We're downgrading a system app, which will apply to all users, so
            // freeze them all during the downgrade
            freezeUser = UserHandle.USER_ALL;
        } else {
            freezeUser = removeUser;
        }

        synchronized (mInstallLock) {
            if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageX: pkg=" + packageName + " user=" + userId);
            try (PackageFreezer freezer = freezePackageForDelete(packageName, freezeUser,
                    deleteFlags, "deletePackageX")) {
                res = deletePackageLIF(packageName, UserHandle.of(removeUser), true, allUsers,
                        deleteFlags | PackageManager.DELETE_CHATTY, info, true, null);
            }
            synchronized (mLock) {
                if (res) {
                    if (pkg != null) {
                        mInstantAppRegistry.onPackageUninstalledLPw(pkg, info.removedUsers);
                    }
                    updateSequenceNumberLP(uninstalledPs, info.removedUsers);
                    updateInstantAppInstallerLocked(packageName);
                }
            }
        }

        if (res) {
            final boolean killApp = (deleteFlags & PackageManager.DELETE_DONT_KILL_APP) == 0;
            info.sendPackageRemovedBroadcasts(killApp);
            info.sendSystemPackageUpdatedBroadcasts();
            info.sendSystemPackageAppearedBroadcasts();
        }
        // Force a gc here.
        Runtime.getRuntime().gc();
        // Delete the resources here after sending the broadcast to let
        // other processes clean up before deleting resources.
        synchronized (mInstallLock) {
            if (info.args != null) {
                info.args.doPostDeleteLI(true);
            }
            final AndroidPackage stubPkg =
                    (disabledSystemPs == null) ? null : disabledSystemPs.pkg;
            if (stubPkg != null && stubPkg.isStub()) {
                synchronized (mLock) {
                    // restore the enabled state of the stub; the state is overwritten when
                    // the stub is uninstalled
                    final PackageSetting stubPs = mSettings.mPackages.get(stubPkg.getPackageName());
                    if (stubPs != null) {
                        stubPs.setEnabled(origEnabledState, userId, "android");
                    }
                }
                if (origEnabledState == COMPONENT_ENABLED_STATE_DEFAULT
                        || origEnabledState == COMPONENT_ENABLED_STATE_ENABLED) {
                    if (DEBUG_COMPRESSION) {
                        Slog.i(TAG, "Enabling system stub after removal; pkg: "
                                + stubPkg.getPackageName());
                    }
                    enableCompressedPackage(stubPkg);
                }
            }
        }

        return res ? PackageManager.DELETE_SUCCEEDED : PackageManager.DELETE_FAILED_INTERNAL_ERROR;
    }

    static class PackageRemovedInfo {
        final PackageSender packageSender;
        String removedPackage;
        String installerPackageName;
        int uid = -1;
        int removedAppId = -1;
        int[] origUsers;
        int[] removedUsers = null;
        int[] broadcastUsers = null;
        int[] instantUserIds = null;
        SparseArray<Integer> installReasons;
        boolean isRemovedPackageSystemUpdate = false;
        boolean isUpdate;
        boolean dataRemoved;
        boolean removedForAllUsers;
        boolean isStaticSharedLib;
        // Clean up resources deleted packages.
        InstallArgs args = null;
        ArrayMap<String, PackageInstalledInfo> appearedChildPackages;

        PackageRemovedInfo(PackageSender packageSender) {
            this.packageSender = packageSender;
        }

        void sendPackageRemovedBroadcasts(boolean killApp) {
            sendPackageRemovedBroadcastInternal(killApp);
        }

        void sendSystemPackageUpdatedBroadcasts() {
            if (isRemovedPackageSystemUpdate) {
                sendSystemPackageUpdatedBroadcastsInternal();
            }
        }

        void sendSystemPackageAppearedBroadcasts() {
            final int packageCount = (appearedChildPackages != null)
                    ? appearedChildPackages.size() : 0;
            for (int i = 0; i < packageCount; i++) {
                PackageInstalledInfo installedInfo = appearedChildPackages.valueAt(i);
                packageSender.sendPackageAddedForNewUsers(installedInfo.name,
                    true /*sendBootCompleted*/, false /*startReceiver*/,
                    UserHandle.getAppId(installedInfo.uid), installedInfo.newUsers, null);
            }
        }

        private void sendSystemPackageUpdatedBroadcastsInternal() {
            Bundle extras = new Bundle(2);
            extras.putInt(Intent.EXTRA_UID, removedAppId >= 0 ? removedAppId : uid);
            extras.putBoolean(Intent.EXTRA_REPLACING, true);
            packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
                removedPackage, extras, 0, null /*targetPackage*/, null, null, null);
            packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED,
                removedPackage, extras, 0, null /*targetPackage*/, null, null, null);
            packageSender.sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED,
                null, null, 0, removedPackage, null, null, null);
            if (installerPackageName != null) {
                packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
                        removedPackage, extras, 0 /*flags*/,
                        installerPackageName, null, null, null);
                packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED,
                        removedPackage, extras, 0 /*flags*/,
                        installerPackageName, null, null, null);
            }
        }

        private void sendPackageRemovedBroadcastInternal(boolean killApp) {
            // Don't send static shared library removal broadcasts as these
            // libs are visible only the the apps that depend on them an one
            // cannot remove the library if it has a dependency.
            if (isStaticSharedLib) {
                return;
            }
            Bundle extras = new Bundle(2);
            final int removedUid = removedAppId >= 0  ? removedAppId : uid;
            extras.putInt(Intent.EXTRA_UID, removedUid);
            extras.putBoolean(Intent.EXTRA_DATA_REMOVED, dataRemoved);
            extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, !killApp);
            if (isUpdate || isRemovedPackageSystemUpdate) {
                extras.putBoolean(Intent.EXTRA_REPLACING, true);
            }
            extras.putBoolean(Intent.EXTRA_REMOVED_FOR_ALL_USERS, removedForAllUsers);
            if (removedPackage != null) {
                packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED,
                    removedPackage, extras, 0, null /*targetPackage*/, null,
                    broadcastUsers, instantUserIds);
                if (installerPackageName != null) {
                    packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED,
                            removedPackage, extras, 0 /*flags*/,
                            installerPackageName, null, broadcastUsers, instantUserIds);
                }
                if (dataRemoved && !isRemovedPackageSystemUpdate) {
                    packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_FULLY_REMOVED,
                        removedPackage, extras,
                        Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND,
                        null, null, broadcastUsers, instantUserIds);
                    packageSender.notifyPackageRemoved(removedPackage, removedUid);
                }
            }
            if (removedAppId >= 0) {
                // If a system app's updates are uninstalled the UID is not actually removed. Some
                // services need to know the package name affected.
                if (extras.getBoolean(Intent.EXTRA_REPLACING, false)) {
                    extras.putString(Intent.EXTRA_PACKAGE_NAME, removedPackage);
                }

                packageSender.sendPackageBroadcast(Intent.ACTION_UID_REMOVED,
                        null, extras, Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND,
                    null, null, broadcastUsers, instantUserIds);
            }
        }

        void populateUsers(int[] userIds, PackageSetting deletedPackageSetting) {
            removedUsers = userIds;
            if (removedUsers == null) {
                broadcastUsers = null;
                return;
            }

            broadcastUsers = EMPTY_INT_ARRAY;
            instantUserIds = EMPTY_INT_ARRAY;
            for (int i = userIds.length - 1; i >= 0; --i) {
                final int userId = userIds[i];
                if (deletedPackageSetting.getInstantApp(userId)) {
                    instantUserIds = ArrayUtils.appendInt(instantUserIds, userId);
                } else {
                    broadcastUsers = ArrayUtils.appendInt(broadcastUsers, userId);
                }
            }
        }
    }

    /*
     * This method deletes the package from internal data structures. If the DONT_DELETE_DATA
     * flag is not set, the data directory is removed as well.
     * make sure this flag is set for partially installed apps. If not its meaningless to
     * delete a partially installed application.
     */
    private void removePackageDataLIF(final PackageSetting deletedPs, int[] allUserHandles,
            PackageRemovedInfo outInfo, int flags, boolean writeSettings) {
        String packageName = deletedPs.name;
        if (DEBUG_REMOVE) Slog.d(TAG, "removePackageDataLI: " + deletedPs);
        // Retrieve object to delete permissions for shared user later on
        final AndroidPackage deletedPkg = deletedPs.pkg;
        if (outInfo != null) {
            outInfo.removedPackage = packageName;
            outInfo.installerPackageName = deletedPs.installSource.installerPackageName;
            outInfo.isStaticSharedLib = deletedPkg != null
                    && deletedPkg.getStaticSharedLibName() != null;
            outInfo.populateUsers(deletedPs == null ? null
                    : deletedPs.queryInstalledUsers(mUserManager.getUserIds(), true), deletedPs);
        }

        removePackageLI(deletedPs.name, (flags & PackageManager.DELETE_CHATTY) != 0);

        if ((flags & PackageManager.DELETE_KEEP_DATA) == 0) {
            final AndroidPackage resolvedPkg;
            if (deletedPkg != null) {
                resolvedPkg = deletedPkg;
            } else {
                // We don't have a parsed package when it lives on an ejected
                // adopted storage device, so fake something together
                resolvedPkg = PackageImpl.buildFakeForDeletion(deletedPs.name,
                        deletedPs.volumeUuid);
            }
            destroyAppDataLIF(resolvedPkg, UserHandle.USER_ALL,
                    FLAG_STORAGE_DE | FLAG_STORAGE_CE | FLAG_STORAGE_EXTERNAL);
            destroyAppProfilesLIF(resolvedPkg);
            if (outInfo != null) {
                outInfo.dataRemoved = true;
            }
        }

        int removedAppId = -1;

        // writer
        boolean installedStateChanged = false;
        if (deletedPs != null) {
            if ((flags & PackageManager.DELETE_KEEP_DATA) == 0) {
                final SparseBooleanArray changedUsers = new SparseBooleanArray();
                synchronized (mLock) {
                    clearIntentFilterVerificationsLPw(deletedPs.name, UserHandle.USER_ALL);
                    clearDefaultBrowserIfNeeded(packageName);
                    mSettings.mKeySetManagerService.removeAppKeySetDataLPw(packageName);
                    removedAppId = mSettings.removePackageLPw(packageName);
                    if (outInfo != null) {
                        outInfo.removedAppId = removedAppId;
                    }
                    mPermissionManager.updatePermissions(deletedPs.name, null);
                    if (deletedPs.sharedUser != null) {
                        // Remove permissions associated with package. Since runtime
                        // permissions are per user we have to kill the removed package
                        // or packages running under the shared user of the removed
                        // package if revoking the permissions requested only by the removed
                        // package is successful and this causes a change in gids.
                        boolean shouldKill = false;
                        for (int userId : UserManagerService.getInstance().getUserIds()) {
                            final int userIdToKill = mSettings.updateSharedUserPermsLPw(deletedPs,
                                    userId);
                            shouldKill |= userIdToKill == UserHandle.USER_ALL
                                    || userIdToKill >= UserHandle.USER_SYSTEM;
                        }
                        // If gids changed, kill all affected packages.
                        if (shouldKill) {
                            mHandler.post(() -> {
                                // This has to happen with no lock held.
                                killApplication(deletedPs.name, deletedPs.appId,
                                        KILL_APP_REASON_GIDS_CHANGED);
                            });
                        }
                    }
                    clearPackagePreferredActivitiesLPw(
                            deletedPs.name, changedUsers, UserHandle.USER_ALL);
                }
                if (changedUsers.size() > 0) {
                    updateDefaultHomeNotLocked(changedUsers);
                    postPreferredActivityChangedBroadcast(UserHandle.USER_ALL);
                }
            }
            // make sure to preserve per-user disabled state if this removal was just
            // a downgrade of a system app to the factory package
            if (allUserHandles != null && outInfo != null && outInfo.origUsers != null) {
                if (DEBUG_REMOVE) {
                    Slog.d(TAG, "Propagating install state across downgrade");
                }
                for (int userId : allUserHandles) {
                    final boolean installed = ArrayUtils.contains(outInfo.origUsers, userId);
                    if (DEBUG_REMOVE) {
                        Slog.d(TAG, "    user " + userId + " => " + installed);
                    }
                    if (installed != deletedPs.getInstalled(userId)) {
                        installedStateChanged = true;
                    }
                    deletedPs.setInstalled(installed, userId);
                }
            }
        }
        synchronized (mLock) {
            // can downgrade to reader
            if (writeSettings) {
                // Save settings now
                mSettings.writeLPr();
            }
            if (installedStateChanged) {
                mSettings.writeKernelMappingLPr(deletedPs);
            }
        }
        if (removedAppId != -1) {
            // A user ID was deleted here. Go through all users and remove it
            // from KeyStore.
            removeKeystoreDataIfNeeded(
                    mInjector.getUserManagerInternal(), UserHandle.USER_ALL, removedAppId);
        }
    }

    private static @Nullable SystemPartition resolveApexToSystemPartition(
            ApexManager.ActiveApexInfo apexInfo) {
        for (int i = 0, size = SYSTEM_PARTITIONS.size(); i < size; i++) {
            SystemPartition sp = SYSTEM_PARTITIONS.get(i);
            if (apexInfo.preinstalledApexPath.getAbsolutePath().startsWith(
                    sp.folder.getAbsolutePath())) {
                return new SystemPartition(apexInfo.apexDirectory, sp.scanFlag,
                        false /* hasOverlays */);
            }
        }
        return null;
    }

    /*
     * Tries to delete system package.
     */
    private void deleteSystemPackageLIF(DeletePackageAction action, PackageSetting deletedPs,
            int[] allUserHandles, int flags, @Nullable PackageRemovedInfo outInfo,
            boolean writeSettings)
            throws SystemDeleteException {
        final boolean applyUserRestrictions =
                (allUserHandles != null) && outInfo != null && (outInfo.origUsers != null);
        final AndroidPackage deletedPkg = deletedPs.pkg;
        // Confirm if the system package has been updated
        // An updated system app can be deleted. This will also have to restore
        // the system pkg from system partition
        // reader
        final PackageSetting disabledPs = action.disabledPs;
        if (DEBUG_REMOVE) Slog.d(TAG, "deleteSystemPackageLI: newPs=" + deletedPkg.getPackageName()
                + " disabledPs=" + disabledPs);
        Slog.d(TAG, "Deleting system pkg from data partition");

        if (DEBUG_REMOVE) {
            if (applyUserRestrictions) {
                Slog.d(TAG, "Remembering install states:");
                for (int userId : allUserHandles) {
                    final boolean finstalled = ArrayUtils.contains(outInfo.origUsers, userId);
                    Slog.d(TAG, "   u=" + userId + " inst=" + finstalled);
                }
            }
        }

        if (outInfo != null) {
            // Delete the updated package
            outInfo.isRemovedPackageSystemUpdate = true;
        }

        if (disabledPs.versionCode < deletedPs.versionCode) {
            // Delete data for downgrades
            flags &= ~PackageManager.DELETE_KEEP_DATA;
        } else {
            // Preserve data by setting flag
            flags |= PackageManager.DELETE_KEEP_DATA;
        }

        deleteInstalledPackageLIF(deletedPs, true, flags, allUserHandles,
                outInfo, writeSettings);

        // writer
        synchronized (mLock) {
            // NOTE: The system package always needs to be enabled; even if it's for
            // a compressed stub. If we don't, installing the system package fails
            // during scan [scanning checks the disabled packages]. We will reverse
            // this later, after we've "installed" the stub.
            // Reinstate the old system package
            enableSystemPackageLPw(disabledPs.pkg);
            // Remove any native libraries from the upgraded package.
            removeNativeBinariesLI(deletedPs);
        }

        // Install the system package
        if (DEBUG_REMOVE) Slog.d(TAG, "Re-installing system package: " + disabledPs);
        try {
            installPackageFromSystemLIF(disabledPs.codePathString, allUserHandles,
                    outInfo == null ? null : outInfo.origUsers, deletedPs.getPermissionsState(),
                    writeSettings);
        } catch (PackageManagerException e) {
            Slog.w(TAG, "Failed to restore system package:" + deletedPkg.getPackageName() + ": "
                    + e.getMessage());
            // TODO(patb): can we avoid this; throw would come from scan...
            throw new SystemDeleteException(e);
        } finally {
            if (disabledPs.pkg.isStub()) {
                // We've re-installed the stub; make sure it's disabled here. If package was
                // originally enabled, we'll install the compressed version of the application
                // and re-enable it afterward.
                final PackageSetting stubPs = mSettings.mPackages.get(deletedPkg.getPackageName());
                if (stubPs != null) {
                    stubPs.setEnabled(
                            COMPONENT_ENABLED_STATE_DISABLED, UserHandle.USER_SYSTEM, "android");
                }
            }
        }
    }

    /**
     * Installs a package that's already on the system partition.
     */
    private AndroidPackage installPackageFromSystemLIF(@NonNull String codePathString,
            @Nullable int[] allUserHandles, @Nullable int[] origUserHandles,
            @Nullable PermissionsState origPermissionState, boolean writeSettings)
                    throws PackageManagerException {
        @ParseFlags int parseFlags =
                mDefParseFlags
                | PackageParser.PARSE_MUST_BE_APK
                | PackageParser.PARSE_IS_SYSTEM_DIR;
        @ScanFlags int scanFlags = SCAN_AS_SYSTEM;
        for (int i = 0, size = mDirsToScanAsSystem.size(); i < size; i++) {
            SystemPartition partition = mDirsToScanAsSystem.get(i);
            if (partition.containsPath(codePathString)) {
                scanFlags |= partition.scanFlag;
                if (partition.containsPrivPath(codePathString)) {
                    scanFlags |= SCAN_AS_PRIVILEGED;
                }
                break;
            }
        }

        final File codePath = new File(codePathString);
        final AndroidPackage pkg =
                scanPackageTracedLI(codePath, parseFlags, scanFlags, 0 /*currentTime*/, null);

        try {
            // update shared libraries for the newly re-installed system package
            updateSharedLibrariesLocked(pkg, null, Collections.unmodifiableMap(mPackages));
        } catch (PackageManagerException e) {
            Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
        }

        prepareAppDataAfterInstallLIF(pkg);

        // writer
        synchronized (mLock) {
            PackageSetting ps = mSettings.mPackages.get(pkg.getPackageName());

            // Propagate the permissions state as we do not want to drop on the floor
            // runtime permissions. The update permissions method below will take
            // care of removing obsolete permissions and grant install permissions.
            if (origPermissionState != null) {
                ps.getPermissionsState().copyFrom(origPermissionState);
            }
            mPermissionManager.updatePermissions(pkg.getPackageName(), pkg);

            final boolean applyUserRestrictions
                    = (allUserHandles != null) && (origUserHandles != null);
            if (applyUserRestrictions) {
                boolean installedStateChanged = false;
                if (DEBUG_REMOVE) {
                    Slog.d(TAG, "Propagating install state across reinstall");
                }
                for (int userId : allUserHandles) {
                    final boolean installed = ArrayUtils.contains(origUserHandles, userId);
                    if (DEBUG_REMOVE) {
                        Slog.d(TAG, "    user " + userId + " => " + installed);
                    }
                    if (installed != ps.getInstalled(userId)) {
                        installedStateChanged = true;
                    }
                    ps.setInstalled(installed, userId);

                    mSettings.writeRuntimePermissionsForUserLPr(userId, false);
                }
                // Regardless of writeSettings we need to ensure that this restriction
                // state propagation is persisted
                mSettings.writeAllUsersPackageRestrictionsLPr();
                if (installedStateChanged) {
                    mSettings.writeKernelMappingLPr(ps);
                }
            }
            // can downgrade to reader here
            if (writeSettings) {
                mSettings.writeLPr();
            }
        }
        return pkg;
    }

    private void deleteInstalledPackageLIF(PackageSetting ps,
            boolean deleteCodeAndResources, int flags, int[] allUserHandles,
            PackageRemovedInfo outInfo, boolean writeSettings) {
        synchronized (mLock) {
            if (outInfo != null) {
                outInfo.uid = ps.appId;
            }
        }

        // Delete package data from internal structures and also remove data if flag is set
        removePackageDataLIF(ps, allUserHandles, outInfo, flags, writeSettings);

        // Delete application code and resources only for parent packages
        if (deleteCodeAndResources && (outInfo != null)) {
            outInfo.args = createInstallArgsForExisting(
                    ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(
                            ps.primaryCpuAbiString, ps.secondaryCpuAbiString));
            if (DEBUG_SD_INSTALL) Slog.i(TAG, "args=" + outInfo.args);
        }
    }

    @Override
    public boolean setBlockUninstallForUser(String packageName, boolean blockUninstall,
            int userId) {
        mContext.enforceCallingOrSelfPermission(
                android.Manifest.permission.DELETE_PACKAGES, null);
        synchronized (mLock) {
            // Cannot block uninstall of static shared libs as they are
            // considered a part of the using app (emulating static linking).
            // Also static libs are installed always on internal storage.
            AndroidPackage pkg = mPackages.get(packageName);
            if (pkg != null && pkg.getStaticSharedLibName() != null) {
                Slog.w(TAG, "Cannot block uninstall of package: " + packageName
                        + " providing static shared library: " + pkg.getStaticSharedLibName());
                return false;
            }
            mSettings.setBlockUninstallLPw(userId, packageName, blockUninstall);
            mSettings.writePackageRestrictionsLPr(userId);
        }
        return true;
    }

    @Override
    public boolean getBlockUninstallForUser(String packageName, int userId) {
        synchronized (mLock) {
            final PackageSetting ps = mSettings.mPackages.get(packageName);
            if (ps == null || shouldFilterApplicationLocked(ps, Binder.getCallingUid(), userId)) {
                return false;
            }
            return mSettings.getBlockUninstallLPr(userId, packageName);
        }
    }

    @Override
    public boolean setRequiredForSystemUser(String packageName, boolean systemUserApp) {
        enforceSystemOrRoot("setRequiredForSystemUser can only be run by the system or root");
        synchronized (mLock) {
            PackageSetting ps = mSettings.mPackages.get(packageName);
            if (ps == null) {
                Log.w(TAG, "Package doesn't exist: " + packageName);
                return false;
            }
            if (systemUserApp) {
                ps.pkgPrivateFlags |= ApplicationInfo.PRIVATE_FLAG_REQUIRED_FOR_SYSTEM_USER;
            } else {
                ps.pkgPrivateFlags &= ~ApplicationInfo.PRIVATE_FLAG_REQUIRED_FOR_SYSTEM_USER;
            }
            mSettings.writeLPr();
        }
        return true;
    }

    private static class DeletePackageAction {
        public final PackageSetting deletingPs;
        public final PackageSetting disabledPs;
        public final PackageRemovedInfo outInfo;
        public final int flags;
        public final UserHandle user;

        private DeletePackageAction(PackageSetting deletingPs, PackageSetting disabledPs,
                PackageRemovedInfo outInfo, int flags, UserHandle user) {
            this.deletingPs = deletingPs;
            this.disabledPs = disabledPs;
            this.outInfo = outInfo;
            this.flags = flags;
            this.user = user;
        }
    }

    /**
     * @return a {@link DeletePackageAction} if the provided package and related state may be
     * deleted, {@code null} otherwise.
     */
    @Nullable
    @GuardedBy("mLock")
    private static DeletePackageAction mayDeletePackageLocked(
            PackageRemovedInfo outInfo, PackageSetting ps, @Nullable PackageSetting disabledPs,
            int flags, UserHandle user) {
        if (ps == null) {
            return null;
        }
        if (isSystemApp(ps)) {
            final boolean deleteSystem = (flags & PackageManager.DELETE_SYSTEM_APP) != 0;
            final boolean deleteAllUsers =
                    user == null || user.getIdentifier() == UserHandle.USER_ALL;
            if ((!deleteSystem || deleteAllUsers) && disabledPs == null) {
                Slog.w(TAG, "Attempt to delete unknown system package " + ps.pkg.getPackageName());
                return null;
            }
            // Confirmed if the system package has been updated
            // An updated system app can be deleted. This will also have to restore
            // the system pkg from system partition reader
        }
        return new DeletePackageAction(ps, disabledPs, outInfo, flags, user);
    }

    /*
     * This method handles package deletion in general
     */
    private boolean deletePackageLIF(@NonNull String packageName, UserHandle user,
            boolean deleteCodeAndResources, int[] allUserHandles, int flags,
            PackageRemovedInfo outInfo, boolean writeSettings,
            ParsedPackage replacingPackage) {
        final DeletePackageAction action;
        synchronized (mLock) {
            final PackageSetting ps = mSettings.mPackages.get(packageName);
            final PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(ps);
            action = mayDeletePackageLocked(outInfo, ps, disabledPs, flags, user);
        }
        if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageLI: " + packageName + " user " + user);
        if (null == action) {
            if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageLI: action was null");
            return false;
        }


        try {
            executeDeletePackageLIF(action, packageName, deleteCodeAndResources,
                    allUserHandles, writeSettings, replacingPackage);
        } catch (SystemDeleteException e) {
            if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageLI: system deletion failure", e);
            return false;
        }
        return true;
    }

    private static class SystemDeleteException extends Exception {
        public final PackageManagerException reason;

        private SystemDeleteException(PackageManagerException reason) {
            this.reason = reason;
        }
    }

    /** Deletes a package. Only throws when install of a disabled package fails. */
    private void executeDeletePackageLIF(DeletePackageAction action,
            String packageName, boolean deleteCodeAndResources,
            int[] allUserHandles, boolean writeSettings,
            ParsedPackage replacingPackage) throws SystemDeleteException {
        final PackageSetting ps = action.deletingPs;
        final PackageRemovedInfo outInfo = action.outInfo;
        final UserHandle user = action.user;
        final int flags = action.flags;
        final boolean systemApp = isSystemApp(ps);

        final int userId = user == null ? UserHandle.USER_ALL : user.getIdentifier();
        if (ps.getPermissionsState().hasPermission(Manifest.permission.SUSPEND_APPS, userId)) {
            unsuspendForSuspendingPackage(packageName, userId);
        }
        if ((!systemApp || (flags & PackageManager.DELETE_SYSTEM_APP) != 0)
                && userId != UserHandle.USER_ALL) {
            // The caller is asking that the package only be deleted for a single
            // user.  To do this, we just mark its uninstalled state and delete
            // its data. If this is a system app, we only allow this to happen if
            // they have set the special DELETE_SYSTEM_APP which requests different
            // semantics than normal for uninstalling system apps.
            final boolean clearPackageStateAndReturn;
            synchronized (mLock) {
                markPackageUninstalledForUserLPw(ps, user);
                if (!systemApp) {
                    // Do not uninstall the APK if an app should be cached
                    boolean keepUninstalledPackage = shouldKeepUninstalledPackageLPr(packageName);
                    if (ps.isAnyInstalled(mUserManager.getUserIds()) || keepUninstalledPackage) {
                        // Other users still have this package installed, so all
                        // we need to do is clear this user's data and save that
                        // it is uninstalled.
                        if (DEBUG_REMOVE) Slog.d(TAG, "Still installed by other users");
                        clearPackageStateAndReturn = true;
                    } else {
                        // We need to set it back to 'installed' so the uninstall
                        // broadcasts will be sent correctly.
                        if (DEBUG_REMOVE) Slog.d(TAG, "Not installed by other users, full delete");
                        ps.setInstalled(true, userId);
                        mSettings.writeKernelMappingLPr(ps);
                        clearPackageStateAndReturn = false;
                    }
                } else {
                    // This is a system app, so we assume that the
                    // other users still have this package installed, so all
                    // we need to do is clear this user's data and save that
                    // it is uninstalled.
                    if (DEBUG_REMOVE) Slog.d(TAG, "Deleting system app");
                    clearPackageStateAndReturn = true;
                }
            }
            if (clearPackageStateAndReturn) {
                clearPackageStateForUserLIF(ps, userId, outInfo, flags);
                synchronized (mLock) {
                    scheduleWritePackageRestrictionsLocked(user);
                }
                return;
            }
        }

        // TODO(b/109941548): break reasons for ret = false out into mayDelete method
        if (systemApp) {
            if (DEBUG_REMOVE) Slog.d(TAG, "Removing system package: " + ps.name);
            // When an updated system application is deleted we delete the existing resources
            // as well and fall back to existing code in system partition
            deleteSystemPackageLIF(action, ps, allUserHandles, flags, outInfo, writeSettings);
        } else {
            if (DEBUG_REMOVE) Slog.d(TAG, "Removing non-system package: " + ps.name);
            deleteInstalledPackageLIF(ps, deleteCodeAndResources, flags, allUserHandles,
                    outInfo, writeSettings);
        }

        // Take a note whether we deleted the package for all users
        if (outInfo != null) {
            outInfo.removedForAllUsers = mPackages.get(ps.name) == null;
        }
    }

    @GuardedBy("mLock")
    private void markPackageUninstalledForUserLPw(PackageSetting ps, UserHandle user) {
        final int[] userIds = (user == null || user.getIdentifier() == UserHandle.USER_ALL)
                ? mUserManager.getUserIds() : new int[] {user.getIdentifier()};
        for (int nextUserId : userIds) {
            if (DEBUG_REMOVE) {
                Slog.d(TAG, "Marking package:" + ps.name + " uninstalled for user:" + nextUserId);
            }
            ps.setUserState(nextUserId, 0, COMPONENT_ENABLED_STATE_DEFAULT,
                    false /*installed*/,
                    true /*stopped*/,
                    true /*notLaunched*/,
                    false /*hidden*/,
                    0 /*distractionFlags*/,
                    false /*suspended*/,
                    null /*suspendParams*/,
                    false /*instantApp*/,
                    false /*virtualPreload*/,
                    null /*lastDisableAppCaller*/,
                    null /*enabledComponents*/,
                    null /*disabledComponents*/,
                    ps.readUserState(nextUserId).domainVerificationStatus,
                    0, PackageManager.INSTALL_REASON_UNKNOWN,
                    null /*harmfulAppWarning*/);
        }
        mSettings.writeKernelMappingLPr(ps);
    }

    private void clearPackageStateForUserLIF(PackageSetting ps, int userId,
            PackageRemovedInfo outInfo, int flags) {
        final AndroidPackage pkg;
        synchronized (mLock) {
            pkg = mPackages.get(ps.name);
        }

        destroyAppProfilesLIF(pkg);

        final int[] userIds = (userId == UserHandle.USER_ALL) ? mUserManager.getUserIds()
                : new int[] {userId};
        for (int nextUserId : userIds) {
            if (DEBUG_REMOVE) {
                Slog.d(TAG, "Updating package:" + ps.name + " install state for user:"
                        + nextUserId);
            }

            destroyAppDataLIF(pkg, nextUserId,
                    FLAG_STORAGE_DE | FLAG_STORAGE_CE | FLAG_STORAGE_EXTERNAL);
            clearDefaultBrowserIfNeededForUser(ps.name, nextUserId);
            removeKeystoreDataIfNeeded(mInjector.getUserManagerInternal(), nextUserId, ps.appId);
            final SparseBooleanArray changedUsers = new SparseBooleanArray();
            clearPackagePreferredActivitiesLPw(ps.name, changedUsers, nextUserId);
            if (changedUsers.size() > 0) {
                updateDefaultHomeNotLocked(changedUsers);
                postPreferredActivityChangedBroadcast(nextUserId);
                synchronized (mLock) {
                    scheduleWritePackageRestrictionsLocked(nextUserId);
                }
            }
            mPermissionManager.resetRuntimePermissions(pkg, nextUserId);
            // Also delete contributed media, when requested
            if ((flags & PackageManager.DELETE_CONTRIBUTED_MEDIA) != 0) {
                try {
                    MediaStore.deleteContributedMedia(mContext, ps.name, UserHandle.of(nextUserId));
                } catch (IOException e) {
                    Slog.w(TAG, "Failed to delete contributed media for " + ps.name, e);
                }
            }
        }

        if (outInfo != null) {
            outInfo.removedPackage = ps.name;
            outInfo.installerPackageName = ps.installSource.installerPackageName;
            outInfo.isStaticSharedLib = pkg != null && pkg.getStaticSharedLibName() != null;
            outInfo.removedAppId = ps.appId;
            outInfo.removedUsers = userIds;
            outInfo.broadcastUsers = userIds;
        }
    }

    @Override
    public void clearApplicationProfileData(String packageName) {
        enforceSystemOrRoot("Only the system can clear all profile data");

        final AndroidPackage pkg;
        synchronized (mLock) {
            pkg = mPackages.get(packageName);
        }

        try (PackageFreezer freezer = freezePackage(packageName, "clearApplicationProfileData")) {
            synchronized (mInstallLock) {
                clearAppProfilesLIF(pkg, UserHandle.USER_ALL);
            }
        }
    }

    @Override
    public void clearApplicationUserData(final String packageName,
            final IPackageDataObserver observer, final int userId) {
        mContext.enforceCallingOrSelfPermission(
                android.Manifest.permission.CLEAR_APP_USER_DATA, null);

        final int callingUid = Binder.getCallingUid();
        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
                true /* requireFullPermission */, false /* checkShell */, "clear application data");

        final PackageSetting ps = mSettings.getPackageLPr(packageName);
        final boolean filterApp =
                (ps != null && shouldFilterApplicationLocked(ps, callingUid, userId));
        if (!filterApp && mProtectedPackages.isPackageDataProtected(userId, packageName)) {
            throw new SecurityException("Cannot clear data for a protected package: "
                    + packageName);
        }
        // Queue up an async operation since the package deletion may take a little while.
        mHandler.post(new Runnable() {
            public void run() {
                mHandler.removeCallbacks(this);
                final boolean succeeded;
                if (!filterApp) {
                    try (PackageFreezer freezer = freezePackage(packageName,
                            "clearApplicationUserData")) {
                        synchronized (mInstallLock) {
                            succeeded = clearApplicationUserDataLIF(packageName, userId);
                        }
                        synchronized (mLock) {
                            mInstantAppRegistry.deleteInstantApplicationMetadataLPw(
                                    packageName, userId);
                        }
                    }
                    if (succeeded) {
                        // invoke DeviceStorageMonitor's update method to clear any notifications
                        DeviceStorageMonitorInternal dsm = LocalServices
                                .getService(DeviceStorageMonitorInternal.class);
                        if (dsm != null) {
                            dsm.checkMemory();
                        }
                        if (checkPermission(Manifest.permission.SUSPEND_APPS, packageName, userId)
                                == PERMISSION_GRANTED) {
                            unsuspendForSuspendingPackage(packageName, userId);
                        }
                    }
                } else {
                    succeeded = false;
                }
                if (observer != null) {
                    try {
                        observer.onRemoveCompleted(packageName, succeeded);
                    } catch (RemoteException e) {
                        Log.i(TAG, "Observer no longer exists.");
                    }
                } //end if observer
            } //end run
        });
    }

    private boolean clearApplicationUserDataLIF(String packageName, int userId) {
        if (packageName == null) {
            Slog.w(TAG, "Attempt to delete null packageName.");
            return false;
        }

        // Try finding details about the requested package
        AndroidPackage pkg;
        synchronized (mLock) {
            pkg = mPackages.get(packageName);
            if (pkg == null) {
                final PackageSetting ps = mSettings.mPackages.get(packageName);
                if (ps != null) {
                    pkg = ps.pkg;
                }
            }
        }
        if (pkg == null) {
            Slog.w(TAG, "Package named '" + packageName + "' doesn't exist.");
            return false;
        }
        mPermissionManager.resetRuntimePermissions(pkg, userId);

        clearAppDataLIF(pkg, userId,
                FLAG_STORAGE_DE | FLAG_STORAGE_CE | FLAG_STORAGE_EXTERNAL);

        final int appId = UserHandle.getAppId(pkg.getUid());
        removeKeystoreDataIfNeeded(mInjector.getUserManagerInternal(), userId, appId);

        UserManagerInternal umInternal = mInjector.getUserManagerInternal();
        final int flags;
        if (umInternal.isUserUnlockingOrUnlocked(userId)) {
            flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
        } else if (umInternal.isUserRunning(userId)) {
            flags = StorageManager.FLAG_STORAGE_DE;
        } else {
            flags = 0;
        }
        prepareAppDataContentsLIF(pkg, userId, flags);

        return true;
    }

    private void resetNetworkPolicies(int userId) {
        mInjector.getNetworkPolicyManagerInternal().resetUserState(userId);
    }

    /**
     * Remove entries from the keystore daemon. Will only remove it if the
     * {@code appId} is valid.
     */
    private static void removeKeystoreDataIfNeeded(UserManagerInternal um, @UserIdInt int userId,
            @AppIdInt int appId) {
        if (appId < 0) {
            return;
        }

        final KeyStore keyStore = KeyStore.getInstance();
        if (keyStore != null) {
            if (userId == UserHandle.USER_ALL) {
                for (final int individual : um.getUserIds()) {
                    keyStore.clearUid(UserHandle.getUid(individual, appId));
                }
            } else {
                keyStore.clearUid(UserHandle.getUid(userId, appId));
            }
        } else {
            Slog.w(TAG, "Could not contact keystore to clear entries for app id " + appId);
        }
    }

    @Override
    public void deleteApplicationCacheFiles(final String packageName,
            final IPackageDataObserver observer) {
        final int userId = UserHandle.getCallingUserId();
        deleteApplicationCacheFilesAsUser(packageName, userId, observer);
    }

    @Override
    public void deleteApplicationCacheFilesAsUser(final String packageName, final int userId,
            final IPackageDataObserver observer) {
        final int callingUid = Binder.getCallingUid();
        if (mContext.checkCallingOrSelfPermission(
                android.Manifest.permission.INTERNAL_DELETE_CACHE_FILES)
                != PackageManager.PERMISSION_GRANTED) {
            // If the caller has the old delete cache permission, silently ignore.  Else throw.
            if (mContext.checkCallingOrSelfPermission(
                    android.Manifest.permission.DELETE_CACHE_FILES)
                    == PackageManager.PERMISSION_GRANTED) {
                Slog.w(TAG, "Calling uid " + callingUid + " does not have " +
                        android.Manifest.permission.INTERNAL_DELETE_CACHE_FILES +
                        ", silently ignoring");
                return;
            }
            mContext.enforceCallingOrSelfPermission(
                    android.Manifest.permission.INTERNAL_DELETE_CACHE_FILES, null);
        }
        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
                /* requireFullPermission= */ true, /* checkShell= */ false,
                "delete application cache files");
        final int hasAccessInstantApps = mContext.checkCallingOrSelfPermission(
                android.Manifest.permission.ACCESS_INSTANT_APPS);

        final AndroidPackage pkg;
        synchronized (mLock) {
            pkg = mPackages.get(packageName);
        }

        // Queue up an async operation since the package deletion may take a little while.
        mHandler.post(() -> {
            final PackageSetting ps = pkg == null ? null : getPackageSetting(pkg.getPackageName());
            boolean doClearData = true;
            if (ps != null) {
                final boolean targetIsInstantApp =
                        ps.getInstantApp(UserHandle.getUserId(callingUid));
                doClearData = !targetIsInstantApp
                        || hasAccessInstantApps == PackageManager.PERMISSION_GRANTED;
            }
            if (doClearData) {
                synchronized (mInstallLock) {
                    final int flags = FLAG_STORAGE_DE | FLAG_STORAGE_CE | FLAG_STORAGE_EXTERNAL;
                    // We're only clearing cache files, so we don't care if the
                    // app is unfrozen and still able to run
                    clearAppDataLIF(pkg, userId, flags | Installer.FLAG_CLEAR_CACHE_ONLY);
                    clearAppDataLIF(pkg, userId, flags | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
                }
            }
            if (observer != null) {
                try {
                    observer.onRemoveCompleted(packageName, true);
                } catch (RemoteException e) {
                    Log.i(TAG, "Observer no longer exists.");
                }
            }
        });
    }

    @Override
    public void getPackageSizeInfo(final String packageName, int userId,
            final IPackageStatsObserver observer) {
        throw new UnsupportedOperationException(
                "Shame on you for calling the hidden API getPackageSizeInfo(). Shame!");
    }

    @GuardedBy("mInstallLock")
    private boolean getPackageSizeInfoLI(String packageName, int userId, PackageStats stats) {
        final PackageSetting ps;
        synchronized (mLock) {
            ps = mSettings.mPackages.get(packageName);
            if (ps == null) {
                Slog.w(TAG, "Failed to find settings for " + packageName);
                return false;
            }
        }

        final String[] packageNames = { packageName };
        final long[] ceDataInodes = { ps.getCeDataInode(userId) };
        final String[] codePaths = { ps.codePathString };

        try {
            mInstaller.getAppSize(ps.volumeUuid, packageNames, userId, 0,
                    ps.appId, ceDataInodes, codePaths, stats);

            // For now, ignore code size of packages on system partition
            if (isSystemApp(ps) && !isUpdatedSystemApp(ps)) {
                stats.codeSize = 0;
            }

            // External clients expect these to be tracked separately
            stats.dataSize -= stats.cacheSize;

        } catch (InstallerException e) {
            Slog.w(TAG, String.valueOf(e));
            return false;
        }

        return true;
    }

    @GuardedBy("mLock")
    private int getUidTargetSdkVersionLockedLPr(int uid) {
        final int appId = UserHandle.getAppId(uid);
        final Object obj = mSettings.getSettingLPr(appId);
        if (obj instanceof SharedUserSetting) {
            final SharedUserSetting sus = (SharedUserSetting) obj;
            int vers = Build.VERSION_CODES.CUR_DEVELOPMENT;
            final Iterator<PackageSetting> it = sus.packages.iterator();
            while (it.hasNext()) {
                final PackageSetting ps = it.next();
                if (ps.pkg != null) {
                    int v = ps.pkg.getTargetSdkVersion();
                    if (v < vers) vers = v;
                }
            }
            return vers;
        } else if (obj instanceof PackageSetting) {
            final PackageSetting ps = (PackageSetting) obj;
            if (ps.pkg != null) {
                return ps.pkg.getTargetSdkVersion();
            }
        }
        return Build.VERSION_CODES.CUR_DEVELOPMENT;
    }

    @GuardedBy("mLock")
    private int getPackageTargetSdkVersionLockedLPr(String packageName) {
        final AndroidPackage p = mPackages.get(packageName);
        if (p != null) {
            return p.getTargetSdkVersion();
        }
        return Build.VERSION_CODES.CUR_DEVELOPMENT;
    }

    @Override
    public void addPreferredActivity(IntentFilter filter, int match,
            ComponentName[] set, ComponentName activity, int userId) {
        addPreferredActivityInternal(filter, match, set, activity, true, userId,
                "Adding preferred");
    }

    private void addPreferredActivityInternal(IntentFilter filter, int match,
            ComponentName[] set, ComponentName activity, boolean always, int userId,
            String opname) {
        // writer
        int callingUid = Binder.getCallingUid();
        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
                true /* requireFullPermission */, false /* checkShell */, "add preferred activity");
        if (mContext.checkCallingOrSelfPermission(
                android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
                != PackageManager.PERMISSION_GRANTED) {
            if (getUidTargetSdkVersionLockedLPr(callingUid)
                    < Build.VERSION_CODES.FROYO) {
                Slog.w(TAG, "Ignoring addPreferredActivity() from uid "
                        + callingUid);
                return;
            }
            mContext.enforceCallingOrSelfPermission(
                    android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
        }
        if (filter.countActions() == 0) {
            Slog.w(TAG, "Cannot set a preferred activity with no filter actions");
            return;
        }
        if (DEBUG_PREFERRED) {
            Slog.i(TAG, opname + " activity " + activity.flattenToShortString() + " for user "
                    + userId + ":");
            filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
        }
        synchronized (mLock) {
            final PreferredIntentResolver pir = mSettings.editPreferredActivitiesLPw(userId);
            pir.addFilter(new PreferredActivity(filter, match, set, activity, always));
            scheduleWritePackageRestrictionsLocked(userId);
        }
        if (!updateDefaultHomeNotLocked(userId)) {
            postPreferredActivityChangedBroadcast(userId);
        }
    }

    private void postPreferredActivityChangedBroadcast(int userId) {
        mHandler.post(() -> {
            final IActivityManager am = ActivityManager.getService();
            if (am == null) {
                return;
            }

            final Intent intent = new Intent(Intent.ACTION_PREFERRED_ACTIVITY_CHANGED);
            intent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
            try {
                am.broadcastIntent(null, intent, null, null,
                        0, null, null, null, android.app.AppOpsManager.OP_NONE,
                        null, false, false, userId);
            } catch (RemoteException e) {
            }
        });
    }

    @Override
    public void replacePreferredActivity(IntentFilter filter, int match,
            ComponentName[] set, ComponentName activity, int userId) {
        if (filter.countActions() != 1) {
            throw new IllegalArgumentException(
                    "replacePreferredActivity expects filter to have only 1 action.");
        }
        if (filter.countDataAuthorities() != 0
                || filter.countDataPaths() != 0
                || filter.countDataSchemes() > 1
                || filter.countDataTypes() != 0) {
            throw new IllegalArgumentException(
                    "replacePreferredActivity expects filter to have no data authorities, " +
                    "paths, or types; and at most one scheme.");
        }

        final int callingUid = Binder.getCallingUid();
        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
                true /* requireFullPermission */, false /* checkShell */,
                "replace preferred activity");
        if (mContext.checkCallingOrSelfPermission(
                android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
                != PackageManager.PERMISSION_GRANTED) {
            synchronized (mLock) {
                if (getUidTargetSdkVersionLockedLPr(callingUid)
                        < Build.VERSION_CODES.FROYO) {
                    Slog.w(TAG, "Ignoring replacePreferredActivity() from uid "
                            + Binder.getCallingUid());
                    return;
                }
            }
            mContext.enforceCallingOrSelfPermission(
                    android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
        }

        synchronized (mLock) {
            final PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
            if (pir != null) {
                // Get all of the existing entries that exactly match this filter.
                final ArrayList<PreferredActivity> existing = pir.findFilters(filter);
                if (existing != null && existing.size() == 1) {
                    final PreferredActivity cur = existing.get(0);
                    if (DEBUG_PREFERRED) {
                        Slog.i(TAG, "Checking replace of preferred:");
                        filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
                        if (!cur.mPref.mAlways) {
                            Slog.i(TAG, "  -- CUR; not mAlways!");
                        } else {
                            Slog.i(TAG, "  -- CUR: mMatch=" + cur.mPref.mMatch);
                            Slog.i(TAG, "  -- CUR: mSet="
                                    + Arrays.toString(cur.mPref.mSetComponents));
                            Slog.i(TAG, "  -- CUR: mComponent=" + cur.mPref.mShortComponent);
                            Slog.i(TAG, "  -- NEW: mMatch="
                                    + (match&IntentFilter.MATCH_CATEGORY_MASK));
                            Slog.i(TAG, "  -- CUR: mSet=" + Arrays.toString(set));
                            Slog.i(TAG, "  -- CUR: mComponent=" + activity.flattenToShortString());
                        }
                    }
                    if (cur.mPref.mAlways && cur.mPref.mComponent.equals(activity)
                            && cur.mPref.mMatch == (match&IntentFilter.MATCH_CATEGORY_MASK)
                            && cur.mPref.sameSet(set)) {
                        // Setting the preferred activity to what it happens to be already
                        if (DEBUG_PREFERRED) {
                            Slog.i(TAG, "Replacing with same preferred activity "
                                    + cur.mPref.mShortComponent + " for user "
                                    + userId + ":");
                            filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
                        }
                        return;
                    }
                }
                if (existing != null) {
                    if (DEBUG_PREFERRED) {
                        Slog.i(TAG, existing.size() + " existing preferred matches for:");
                        filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
                    }
                    for (int i = existing.size() - 1; i >= 0; --i) {
                        final PreferredActivity pa = existing.get(i);
                        if (DEBUG_PREFERRED) {
                            Slog.i(TAG, "Removing existing preferred activity "
                                    + pa.mPref.mComponent + ":");
                            pa.dump(new LogPrinter(Log.INFO, TAG), "  ");
                        }
                        pir.removeFilter(pa);
                    }
                }
            }
        }
        addPreferredActivityInternal(filter, match, set, activity, true, userId,
                "Replacing preferred");
    }

    @Override
    public void clearPackagePreferredActivities(String packageName) {
        final int callingUid = Binder.getCallingUid();
        if (getInstantAppPackageName(callingUid) != null) {
            return;
        }
        // writer
        synchronized (mLock) {
            AndroidPackage pkg = mPackages.get(packageName);
            if (pkg == null || !isCallerSameApp(packageName, callingUid)) {
                if (mContext.checkCallingOrSelfPermission(
                        android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
                        != PackageManager.PERMISSION_GRANTED) {
                    if (getUidTargetSdkVersionLockedLPr(callingUid)
                            < Build.VERSION_CODES.FROYO) {
                        Slog.w(TAG, "Ignoring clearPackagePreferredActivities() from uid "
                                + callingUid);
                        return;
                    }
                    mContext.enforceCallingOrSelfPermission(
                            android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
                }
            }
            final PackageSetting ps = mSettings.getPackageLPr(packageName);
            if (ps != null
                    && shouldFilterApplicationLocked(
                            ps, callingUid, UserHandle.getUserId(callingUid))) {
                return;
            }
        }
        int callingUserId = UserHandle.getCallingUserId();
        final SparseBooleanArray changedUsers = new SparseBooleanArray();
        clearPackagePreferredActivitiesLPw(packageName, changedUsers, callingUserId);
        if (changedUsers.size() > 0) {
            updateDefaultHomeNotLocked(changedUsers);
            postPreferredActivityChangedBroadcast(callingUserId);
            synchronized (mLock) {
                scheduleWritePackageRestrictionsLocked(callingUserId);
            }
        }
    }

    /** This method takes a specific user id as well as UserHandle.USER_ALL. */
    @GuardedBy("mLock")
    private void clearPackagePreferredActivitiesLPw(String packageName,
            @NonNull SparseBooleanArray outUserChanged, int userId) {
        ArrayList<PreferredActivity> removed = null;
        for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
            final int thisUserId = mSettings.mPreferredActivities.keyAt(i);
            PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
            if (userId != UserHandle.USER_ALL && userId != thisUserId) {
                continue;
            }
            Iterator<PreferredActivity> it = pir.filterIterator();
            while (it.hasNext()) {
                PreferredActivity pa = it.next();
                // Mark entry for removal only if it matches the package name
                // and the entry is of type "always".
                if (packageName == null ||
                        (pa.mPref.mComponent.getPackageName().equals(packageName)
                                && pa.mPref.mAlways)) {
                    if (removed == null) {
                        removed = new ArrayList<>();
                    }
                    removed.add(pa);
                }
            }
            if (removed != null) {
                for (int j=0; j<removed.size(); j++) {
                    PreferredActivity pa = removed.get(j);
                    pir.removeFilter(pa);
                }
                outUserChanged.put(thisUserId, true);
            }
        }
    }

    /** This method takes a specific user id as well as UserHandle.USER_ALL. */
    @GuardedBy("mLock")
    private void clearIntentFilterVerificationsLPw(int userId) {
        final int packageCount = mPackages.size();
        for (int i = 0; i < packageCount; i++) {
            AndroidPackage pkg = mPackages.valueAt(i);
            clearIntentFilterVerificationsLPw(pkg.getPackageName(), userId);
        }
    }

    /** This method takes a specific user id as well as UserHandle.USER_ALL. */
    @GuardedBy("mLock")
    void clearIntentFilterVerificationsLPw(String packageName, int userId) {
        if (userId == UserHandle.USER_ALL) {
            if (mSettings.removeIntentFilterVerificationLPw(packageName,
                    mUserManager.getUserIds())) {
                for (int oneUserId : mUserManager.getUserIds()) {
                    scheduleWritePackageRestrictionsLocked(oneUserId);
                }
            }
        } else {
            if (mSettings.removeIntentFilterVerificationLPw(packageName, userId)) {
                scheduleWritePackageRestrictionsLocked(userId);
            }
        }
    }

    /** Clears state for all users, and touches intent filter verification policy */
    void clearDefaultBrowserIfNeeded(String packageName) {
        for (int oneUserId : mUserManager.getUserIds()) {
            clearDefaultBrowserIfNeededForUser(packageName, oneUserId);
        }
    }

    private void clearDefaultBrowserIfNeededForUser(String packageName, int userId) {
        final String defaultBrowserPackageName = mPermissionManager.getDefaultBrowser(userId);
        if (!TextUtils.isEmpty(defaultBrowserPackageName)) {
            if (packageName.equals(defaultBrowserPackageName)) {
                mPermissionManager.setDefaultBrowser(null, true, true, userId);
            }
        }
    }

    @Override
    public void resetApplicationPreferences(int userId) {
        mContext.enforceCallingOrSelfPermission(
                android.Manifest.permission.SET_PREFERRED_APPLICATIONS, null);
        final long identity = Binder.clearCallingIdentity();
        // writer
        try {
            final SparseBooleanArray changedUsers = new SparseBooleanArray();
            clearPackagePreferredActivitiesLPw(null, changedUsers, userId);
            if (changedUsers.size() > 0) {
                postPreferredActivityChangedBroadcast(userId);
            }
            synchronized (mLock) {
                mSettings.applyDefaultPreferredAppsLPw(userId);
                clearIntentFilterVerificationsLPw(userId);
                primeDomainVerificationsLPw(userId);
            }
            mPermissionManager.resetAllRuntimePermissions(userId);
            updateDefaultHomeNotLocked(userId);
            // TODO: We have to reset the default SMS and Phone. This requires
            // significant refactoring to keep all default apps in the package
            // manager (cleaner but more work) or have the services provide
            // callbacks to the package manager to request a default app reset.
            mPermissionManager.setDefaultBrowser(null, true, true, userId);
            resetNetworkPolicies(userId);
            synchronized (mLock) {
                scheduleWritePackageRestrictionsLocked(userId);
            }
        } finally {
            Binder.restoreCallingIdentity(identity);
        }
    }

    @Override
    public int getPreferredActivities(List<IntentFilter> outFilters,
            List<ComponentName> outActivities, String packageName) {
        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
            return 0;
        }
        int num = 0;
        final int userId = UserHandle.getCallingUserId();
        // reader
        synchronized (mLock) {
            PreferredIntentResolver pir = mSettings.mPreferredActivities.get(userId);
            if (pir != null) {
                final Iterator<PreferredActivity> it = pir.filterIterator();
                while (it.hasNext()) {
                    final PreferredActivity pa = it.next();
                    if (packageName == null
                            || (pa.mPref.mComponent.getPackageName().equals(packageName)
                                    && pa.mPref.mAlways)) {
                        if (outFilters != null) {
                            outFilters.add(new IntentFilter(pa));
                        }
                        if (outActivities != null) {
                            outActivities.add(pa.mPref.mComponent);
                        }
                    }
                }
            }
        }

        return num;
    }

    @Override
    public void addPersistentPreferredActivity(IntentFilter filter, ComponentName activity,
            int userId) {
        int callingUid = Binder.getCallingUid();
        if (callingUid != Process.SYSTEM_UID) {
            throw new SecurityException(
                    "addPersistentPreferredActivity can only be run by the system");
        }
        if (filter.countActions() == 0) {
            Slog.w(TAG, "Cannot set a preferred activity with no filter actions");
            return;
        }
        if (DEBUG_PREFERRED) {
            Slog.i(TAG, "Adding persistent preferred activity " + activity
                    + " for user " + userId + ":");
            filter.dump(new LogPrinter(Log.INFO, TAG), "  ");
        }
        synchronized (mLock) {
            mSettings.editPersistentPreferredActivitiesLPw(userId).addFilter(
                    new PersistentPreferredActivity(filter, activity));
            scheduleWritePackageRestrictionsLocked(userId);
        }
        updateDefaultHomeNotLocked(userId);
        postPreferredActivityChangedBroadcast(userId);
    }

    @Override
    public void clearPackagePersistentPreferredActivities(String packageName, int userId) {
        int callingUid = Binder.getCallingUid();
        if (callingUid != Process.SYSTEM_UID) {
            throw new SecurityException(
                    "clearPackagePersistentPreferredActivities can only be run by the system");
        }
        ArrayList<PersistentPreferredActivity> removed = null;
        boolean changed = false;
        synchronized (mLock) {
            for (int i=0; i<mSettings.mPersistentPreferredActivities.size(); i++) {
                final int thisUserId = mSettings.mPersistentPreferredActivities.keyAt(i);
                PersistentPreferredIntentResolver ppir = mSettings.mPersistentPreferredActivities
                        .valueAt(i);
                if (userId != thisUserId) {
                    continue;
                }
                Iterator<PersistentPreferredActivity> it = ppir.filterIterator();
                while (it.hasNext()) {
                    PersistentPreferredActivity ppa = it.next();
                    // Mark entry for removal only if it matches the package name.
                    if (ppa.mComponent.getPackageName().equals(packageName)) {
                        if (removed == null) {
                            removed = new ArrayList<>();
                        }
                        removed.add(ppa);
                    }
                }
                if (removed != null) {
                    for (int j=0; j<removed.size(); j++) {
                        PersistentPreferredActivity ppa = removed.get(j);
                        ppir.removeFilter(ppa);
                    }
                    changed = true;
                }
            }
        }
        if (changed) {
            updateDefaultHomeNotLocked(userId);
            postPreferredActivityChangedBroadcast(userId);
            synchronized (mLock) {
                scheduleWritePackageRestrictionsLocked(userId);
            }
        }
    }

    /**
     * Common machinery for picking apart a restored XML blob and passing
     * it to a caller-supplied functor to be applied to the running system.
     */
    private void restoreFromXml(XmlPullParser parser, int userId,
            String expectedStartTag, BlobXmlRestorer functor)
            throws IOException, XmlPullParserException {
        int type;
        while ((type = parser.next()) != XmlPullParser.START_TAG
                && type != XmlPullParser.END_DOCUMENT) {
        }
        if (type != XmlPullParser.START_TAG) {
            // oops didn't find a start tag?!
            if (DEBUG_BACKUP) {
                Slog.e(TAG, "Didn't find start tag during restore");
            }
            return;
        }
        // this is supposed to be TAG_PREFERRED_BACKUP
        if (!expectedStartTag.equals(parser.getName())) {
            if (DEBUG_BACKUP) {
                Slog.e(TAG, "Found unexpected tag " + parser.getName());
            }
            return;
        }

        // skip interfering stuff, then we're aligned with the backing implementation
        while ((type = parser.next()) == XmlPullParser.TEXT) { }
        functor.apply(parser, userId);
    }

    private interface BlobXmlRestorer {
        void apply(XmlPullParser parser, int userId) throws IOException, XmlPullParserException;
    }

    /**
     * Non-Binder method, support for the backup/restore mechanism: write the
     * full set of preferred activities in its canonical XML format.  Returns the
     * XML output as a byte array, or null if there is none.
     */
    @Override
    public byte[] getPreferredActivityBackup(int userId) {
        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
            throw new SecurityException("Only the system may call getPreferredActivityBackup()");
        }

        ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
        try {
            final XmlSerializer serializer = new FastXmlSerializer();
            serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
            serializer.startDocument(null, true);
            serializer.startTag(null, TAG_PREFERRED_BACKUP);

            synchronized (mLock) {
                mSettings.writePreferredActivitiesLPr(serializer, userId, true);
            }

            serializer.endTag(null, TAG_PREFERRED_BACKUP);
            serializer.endDocument();
            serializer.flush();
        } catch (Exception e) {
            if (DEBUG_BACKUP) {
                Slog.e(TAG, "Unable to write preferred activities for backup", e);
            }
            return null;
        }

        return dataStream.toByteArray();
    }

    @Override
    public void restorePreferredActivities(byte[] backup, int userId) {
        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
            throw new SecurityException("Only the system may call restorePreferredActivities()");
        }

        try {
            final XmlPullParser parser = Xml.newPullParser();
            parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
            restoreFromXml(parser, userId, TAG_PREFERRED_BACKUP,
                    (readParser, readUserId) -> {
                        synchronized (mLock) {
                            mSettings.readPreferredActivitiesLPw(readParser, readUserId);
                        }
                        updateDefaultHomeNotLocked(readUserId);
                    });
        } catch (Exception e) {
            if (DEBUG_BACKUP) {
                Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage());
            }
        }
    }

    /**
     * Non-Binder method, support for the backup/restore mechanism: write the
     * default browser (etc) settings in its canonical XML format.  Returns the default
     * browser XML representation as a byte array, or null if there is none.
     */
    @Override
    public byte[] getDefaultAppsBackup(int userId) {
        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
            throw new SecurityException("Only the system may call getDefaultAppsBackup()");
        }

        ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
        try {
            final XmlSerializer serializer = new FastXmlSerializer();
            serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
            serializer.startDocument(null, true);
            serializer.startTag(null, TAG_DEFAULT_APPS);

            synchronized (mLock) {
                mSettings.writeDefaultAppsLPr(serializer, userId);
            }

            serializer.endTag(null, TAG_DEFAULT_APPS);
            serializer.endDocument();
            serializer.flush();
        } catch (Exception e) {
            if (DEBUG_BACKUP) {
                Slog.e(TAG, "Unable to write default apps for backup", e);
            }
            return null;
        }

        return dataStream.toByteArray();
    }

    @Override
    public void restoreDefaultApps(byte[] backup, int userId) {
        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
            throw new SecurityException("Only the system may call restoreDefaultApps()");
        }

        try {
            final XmlPullParser parser = Xml.newPullParser();
            parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
            restoreFromXml(parser, userId, TAG_DEFAULT_APPS,
                    (parser1, userId1) -> {
                        final String defaultBrowser;
                        synchronized (mLock) {
                            mSettings.readDefaultAppsLPw(parser1, userId1);
                            defaultBrowser = mSettings.removeDefaultBrowserPackageNameLPw(userId1);
                        }
                        if (defaultBrowser != null) {
                            mPermissionManager
                                    .setDefaultBrowser(defaultBrowser, false, false, userId1);
                        }
                    });
        } catch (Exception e) {
            if (DEBUG_BACKUP) {
                Slog.e(TAG, "Exception restoring default apps: " + e.getMessage());
            }
        }
    }

    @Override
    public byte[] getIntentFilterVerificationBackup(int userId) {
        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
            throw new SecurityException("Only the system may call getIntentFilterVerificationBackup()");
        }

        ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
        try {
            final XmlSerializer serializer = new FastXmlSerializer();
            serializer.setOutput(dataStream, StandardCharsets.UTF_8.name());
            serializer.startDocument(null, true);
            serializer.startTag(null, TAG_INTENT_FILTER_VERIFICATION);

            synchronized (mLock) {
                mSettings.writeAllDomainVerificationsLPr(serializer, userId);
            }

            serializer.endTag(null, TAG_INTENT_FILTER_VERIFICATION);
            serializer.endDocument();
            serializer.flush();
        } catch (Exception e) {
            if (DEBUG_BACKUP) {
                Slog.e(TAG, "Unable to write default apps for backup", e);
            }
            return null;
        }

        return dataStream.toByteArray();
    }

    @Override
    public void restoreIntentFilterVerification(byte[] backup, int userId) {
        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
            throw new SecurityException("Only the system may call restorePreferredActivities()");
        }

        try {
            final XmlPullParser parser = Xml.newPullParser();
            parser.setInput(new ByteArrayInputStream(backup), StandardCharsets.UTF_8.name());
            restoreFromXml(parser, userId, TAG_INTENT_FILTER_VERIFICATION,
                    (parser1, userId1) -> {
                        synchronized (mLock) {
                            mSettings.readAllDomainVerificationsLPr(parser1, userId1);
                            mSettings.writeLPr();
                        }
                    });
        } catch (Exception e) {
            if (DEBUG_BACKUP) {
                Slog.e(TAG, "Exception restoring preferred activities: " + e.getMessage());
            }
        }
    }

    @Override
    public void addCrossProfileIntentFilter(IntentFilter intentFilter, String ownerPackage,
            int sourceUserId, int targetUserId, int flags) {
        mContext.enforceCallingOrSelfPermission(
                        android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
        int callingUid = Binder.getCallingUid();
        enforceOwnerRights(ownerPackage, callingUid);
        PackageManagerServiceUtils.enforceShellRestriction(mInjector.getUserManagerInternal(),
                UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId);
        if (intentFilter.countActions() == 0) {
            Slog.w(TAG, "Cannot set a crossProfile intent filter with no filter actions");
            return;
        }
        synchronized (mLock) {
            CrossProfileIntentFilter newFilter = new CrossProfileIntentFilter(intentFilter,
                    ownerPackage, targetUserId, flags);
            CrossProfileIntentResolver resolver =
                    mSettings.editCrossProfileIntentResolverLPw(sourceUserId);
            ArrayList<CrossProfileIntentFilter> existing = resolver.findFilters(intentFilter);
            // We have all those whose filter is equal. Now checking if the rest is equal as well.
            if (existing != null) {
                int size = existing.size();
                for (int i = 0; i < size; i++) {
                    if (newFilter.equalsIgnoreFilter(existing.get(i))) {
                        return;
                    }
                }
            }
            resolver.addFilter(newFilter);
            scheduleWritePackageRestrictionsLocked(sourceUserId);
        }
    }

    @Override
    public void clearCrossProfileIntentFilters(int sourceUserId, String ownerPackage) {
        mContext.enforceCallingOrSelfPermission(
                        android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
        final int callingUid = Binder.getCallingUid();
        enforceOwnerRights(ownerPackage, callingUid);
        PackageManagerServiceUtils.enforceShellRestriction(mInjector.getUserManagerInternal(),
                UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, sourceUserId);
        synchronized (mLock) {
            CrossProfileIntentResolver resolver =
                    mSettings.editCrossProfileIntentResolverLPw(sourceUserId);
            ArraySet<CrossProfileIntentFilter> set =
                    new ArraySet<>(resolver.filterSet());
            for (CrossProfileIntentFilter filter : set) {
                if (filter.getOwnerPackage().equals(ownerPackage)) {
                    resolver.removeFilter(filter);
                }
            }
            scheduleWritePackageRestrictionsLocked(sourceUserId);
        }
    }

    // Enforcing that callingUid is owning pkg on userId
    private void enforceOwnerRights(String pkg, int callingUid) {
        // The system owns everything.
        if (UserHandle.getAppId(callingUid) == Process.SYSTEM_UID) {
            return;
        }
        final int callingUserId = UserHandle.getUserId(callingUid);
        PackageInfo pi = getPackageInfo(pkg, 0, callingUserId);
        if (pi == null) {
            throw new IllegalArgumentException("Unknown package " + pkg + " on user "
                    + callingUserId);
        }
        if (!UserHandle.isSameApp(pi.applicationInfo.uid, callingUid)) {
            throw new SecurityException("Calling uid " + callingUid
                    + " does not own package " + pkg);
        }
    }

    @Override
    public ComponentName getHomeActivities(List<ResolveInfo> allHomeCandidates) {
        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
            return null;
        }
        return getHomeActivitiesAsUser(allHomeCandidates, UserHandle.getCallingUserId());
    }

    /**
     * Send a {@code PackageInstaller.ACTION_SESSION_UPDATED} broadcast intent, containing
     * the {@code sessionInfo} in the extra field {@code PackageInstaller.EXTRA_SESSION}.
     */
    public void sendSessionUpdatedBroadcast(PackageInstaller.SessionInfo sessionInfo,
            int userId) {
        if (TextUtils.isEmpty(sessionInfo.installerPackageName)) {
            return;
        }
        Intent sessionUpdatedIntent = new Intent(PackageInstaller.ACTION_SESSION_UPDATED)
                .putExtra(PackageInstaller.EXTRA_SESSION, sessionInfo)
                .setPackage(sessionInfo.installerPackageName);
        mContext.sendBroadcastAsUser(sessionUpdatedIntent, UserHandle.of(userId));
    }

    public void sendSessionCommitBroadcast(PackageInstaller.SessionInfo sessionInfo, int userId) {
        UserManagerService ums = UserManagerService.getInstance();
        if (ums != null && !sessionInfo.isStaged()) {
            final UserInfo parent = ums.getProfileParent(userId);
            final int launcherUid = (parent != null) ? parent.id : userId;
            final ComponentName launcherComponent = getDefaultHomeActivity(launcherUid);
            if (launcherComponent != null) {
                Intent launcherIntent = new Intent(PackageInstaller.ACTION_SESSION_COMMITTED)
                        .putExtra(PackageInstaller.EXTRA_SESSION, sessionInfo)
                        .putExtra(Intent.EXTRA_USER, UserHandle.of(userId))
                        .setPackage(launcherComponent.getPackageName());
                mContext.sendBroadcastAsUser(launcherIntent, UserHandle.of(launcherUid));
            }
            // TODO(b/122900055) Change/Remove this and replace with new permission role.
            if (mAppPredictionServicePackage != null) {
                Intent predictorIntent = new Intent(PackageInstaller.ACTION_SESSION_COMMITTED)
                        .putExtra(PackageInstaller.EXTRA_SESSION, sessionInfo)
                        .putExtra(Intent.EXTRA_USER, UserHandle.of(userId))
                        .setPackage(mAppPredictionServicePackage);
                mContext.sendBroadcastAsUser(predictorIntent, UserHandle.of(launcherUid));
            }
        }
    }

    /**
     * Report the 'Home' activity which is currently set as "always use this one". If non is set
     * then reports the most likely home activity or null if there are more than one.
     */
    private ComponentName getDefaultHomeActivity(int userId) {
        List<ResolveInfo> allHomeCandidates = new ArrayList<>();
        ComponentName cn = getHomeActivitiesAsUser(allHomeCandidates, userId);
        if (cn != null) {
            return cn;
        }

        // Find the launcher with the highest priority and return that component if there are no
        // other home activity with the same priority.
        int lastPriority = Integer.MIN_VALUE;
        ComponentName lastComponent = null;
        final int size = allHomeCandidates.size();
        for (int i = 0; i < size; i++) {
            final ResolveInfo ri = allHomeCandidates.get(i);
            if (ri.priority > lastPriority) {
                lastComponent = ri.activityInfo.getComponentName();
                lastPriority = ri.priority;
            } else if (ri.priority == lastPriority) {
                // Two components found with same priority.
                lastComponent = null;
            }
        }
        return lastComponent;
    }

    private Intent getHomeIntent() {
        Intent intent = new Intent(Intent.ACTION_MAIN);
        intent.addCategory(Intent.CATEGORY_HOME);
        intent.addCategory(Intent.CATEGORY_DEFAULT);
        return intent;
    }

    private IntentFilter getHomeFilter() {
        IntentFilter filter = new IntentFilter(Intent.ACTION_MAIN);
        filter.addCategory(Intent.CATEGORY_HOME);
        filter.addCategory(Intent.CATEGORY_DEFAULT);
        return filter;
    }

    ComponentName getHomeActivitiesAsUser(List<ResolveInfo> allHomeCandidates,
            int userId) {
        Intent intent  = getHomeIntent();
        List<ResolveInfo> resolveInfos = queryIntentActivitiesInternal(intent, null,
                PackageManager.GET_META_DATA, userId);
        allHomeCandidates.clear();
        if (resolveInfos == null) {
            return null;
        }
        allHomeCandidates.addAll(resolveInfos);

        final String packageName = mPermissionManager.getDefaultHome(userId);
        if (packageName == null) {
            return null;
        }
        int resolveInfosSize = resolveInfos.size();
        for (int i = 0; i < resolveInfosSize; i++) {
            ResolveInfo resolveInfo = resolveInfos.get(i);

            if (resolveInfo.activityInfo != null && TextUtils.equals(
                    resolveInfo.activityInfo.packageName, packageName)) {
                return new ComponentName(resolveInfo.activityInfo.packageName,
                        resolveInfo.activityInfo.name);
            }
        }
        return null;
    }

    /** <b>must not hold {@link #mLock}</b> */
    private void updateDefaultHomeNotLocked(SparseBooleanArray userIds) {
        if (Thread.holdsLock(mLock)) {
            Slog.wtf(TAG, "Calling thread " + Thread.currentThread().getName()
                    + " is holding mLock", new Throwable());
        }
        for (int i = userIds.size() - 1; i >= 0; --i) {
            final int userId = userIds.keyAt(i);
            updateDefaultHomeNotLocked(userId);
        }
    }

    /**
     * <b>must not hold {@link #mLock}</b>
     *
     * @return Whether the ACTION_PREFERRED_ACTIVITY_CHANGED broadcast has been scheduled.
     */
    private boolean updateDefaultHomeNotLocked(int userId) {
        if (Thread.holdsLock(mLock)) {
            Slog.wtf(TAG, "Calling thread " + Thread.currentThread().getName()
                    + " is holding mLock", new Throwable());
        }
        if (!mSystemReady) {
            // We might get called before system is ready because of package changes etc, but
            // finding preferred activity depends on settings provider, so we ignore the update
            // before that.
            return false;
        }
        final Intent intent = getHomeIntent();
        final List<ResolveInfo> resolveInfos = queryIntentActivitiesInternal(intent, null,
                PackageManager.GET_META_DATA, userId);
        final ResolveInfo preferredResolveInfo = findPreferredActivityNotLocked(
                intent, null, 0, resolveInfos, 0, true, false, false, userId);
        final String packageName = preferredResolveInfo != null
                && preferredResolveInfo.activityInfo != null
                ? preferredResolveInfo.activityInfo.packageName : null;
        final String currentPackageName = mPermissionManager.getDefaultHome(userId);
        if (TextUtils.equals(currentPackageName, packageName)) {
            return false;
        }
        final String[] callingPackages = getPackagesForUid(Binder.getCallingUid());
        if (callingPackages != null && ArrayUtils.contains(callingPackages,
                mRequiredPermissionControllerPackage)) {
            // PermissionController manages default home directly.
            return false;
        }
        mPermissionManager.setDefaultHome(currentPackageName, userId, (successful) -> {
            if (successful) {
                postPreferredActivityChangedBroadcast(userId);
            }
        });
        return true;
    }

    @Override
    public void setHomeActivity(ComponentName comp, int userId) {
        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
            return;
        }
        ArrayList<ResolveInfo> homeActivities = new ArrayList<>();
        getHomeActivitiesAsUser(homeActivities, userId);

        boolean found = false;

        final int size = homeActivities.size();
        final ComponentName[] set = new ComponentName[size];
        for (int i = 0; i < size; i++) {
            final ResolveInfo candidate = homeActivities.get(i);
            final ActivityInfo info = candidate.activityInfo;
            final ComponentName activityName = new ComponentName(info.packageName, info.name);
            set[i] = activityName;
            if (!found && activityName.equals(comp)) {
                found = true;
            }
        }
        if (!found) {
            throw new IllegalArgumentException("Component " + comp + " cannot be home on user "
                    + userId);
        }
        replacePreferredActivity(getHomeFilter(), IntentFilter.MATCH_CATEGORY_EMPTY,
                set, comp, userId);
    }

    private @Nullable String getSetupWizardPackageNameImpl() {
        final Intent intent = new Intent(Intent.ACTION_MAIN);
        intent.addCategory(Intent.CATEGORY_SETUP_WIZARD);

        final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, null,
                MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE
                        | MATCH_DISABLED_COMPONENTS,
                UserHandle.myUserId());
        if (matches.size() == 1) {
            return matches.get(0).getComponentInfo().packageName;
        } else {
            Slog.e(TAG, "There should probably be exactly one setup wizard; found " + matches.size()
                    + ": matches=" + matches);
            return null;
        }
    }

    private @Nullable String getStorageManagerPackageName() {
        final Intent intent = new Intent(StorageManager.ACTION_MANAGE_STORAGE);

        final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, null,
                MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE
                        | MATCH_DISABLED_COMPONENTS,
                UserHandle.myUserId());
        if (matches.size() == 1) {
            return matches.get(0).getComponentInfo().packageName;
        } else {
            Slog.e(TAG, "There should probably be exactly one storage manager; found "
                    + matches.size() + ": matches=" + matches);
            return null;
        }
    }

    @Override
    public String getSystemTextClassifierPackageName() {
        return ensureSystemPackageName(mContext.getString(
                R.string.config_defaultTextClassifierPackage));
    }

    @Override
    public String[] getSystemTextClassifierPackages() {
        return ensureSystemPackageNames(mContext.getResources().getStringArray(
                R.array.config_defaultTextClassifierPackages));
    }

    @Override
    public @Nullable String getAttentionServicePackageName() {
        final String flattenedComponentName =
                mContext.getString(R.string.config_defaultAttentionService);
        if (flattenedComponentName != null) {
            ComponentName componentName = ComponentName.unflattenFromString(flattenedComponentName);
            if (componentName != null && componentName.getPackageName() != null) {
                return ensureSystemPackageName(componentName.getPackageName());
            }
        }
        return null;
    }

    private @Nullable String getDocumenterPackageName() {
        final Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
        intent.addCategory(Intent.CATEGORY_OPENABLE);
        intent.setType("*/*");
        final String resolvedType = intent.resolveTypeIfNeeded(mContext.getContentResolver());

        final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, resolvedType,
                MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE
                        | MATCH_DISABLED_COMPONENTS,
                UserHandle.myUserId());
        if (matches.size() == 1) {
            return matches.get(0).getComponentInfo().packageName;
        } else {
            Slog.e(TAG, "There should probably be exactly one documenter; found "
                    + matches.size() + ": matches=" + matches);
            return null;
        }
    }

    @Nullable
    private String getDeviceConfiguratorPackageName() {
        return ensureSystemPackageName(mContext.getString(
                R.string.config_deviceConfiguratorPackageName));
    }

    @Override
    public String getWellbeingPackageName() {
        return ensureSystemPackageName(mContext.getString(R.string.config_defaultWellbeingPackage));
    }

    @Override
    public String getAppPredictionServicePackageName() {
        String flattenedAppPredictionServiceComponentName =
                mContext.getString(R.string.config_defaultAppPredictionService);
        if (flattenedAppPredictionServiceComponentName == null) {
            return null;
        }
        ComponentName appPredictionServiceComponentName =
                ComponentName.unflattenFromString(flattenedAppPredictionServiceComponentName);
        if (appPredictionServiceComponentName == null) {
            return null;
        }
        return ensureSystemPackageName(appPredictionServiceComponentName.getPackageName());
    }

    @Override
    public String getSystemCaptionsServicePackageName() {
        String flattenedSystemCaptionsServiceComponentName =
                mContext.getString(R.string.config_defaultSystemCaptionsService);

        if (TextUtils.isEmpty(flattenedSystemCaptionsServiceComponentName)) {
            return null;
        }

        ComponentName systemCaptionsServiceComponentName =
                ComponentName.unflattenFromString(flattenedSystemCaptionsServiceComponentName);
        if (systemCaptionsServiceComponentName == null) {
            return null;
        }
        return ensureSystemPackageName(systemCaptionsServiceComponentName.getPackageName());
    }

    @Override
    public String getSetupWizardPackageName() {
        if (Binder.getCallingUid() != Process.SYSTEM_UID) {
            throw new SecurityException("Non-system caller");
        }
        return mPmInternal.getSetupWizardPackageName();
    }

    public String getIncidentReportApproverPackageName() {
        return ensureSystemPackageName(mContext.getString(
                R.string.config_incidentReportApproverPackage));
    }

    @Override
    public String[] getTelephonyPackageNames() {
        String names = mContext.getString(R.string.config_telephonyPackages);
        String[] telephonyPackageNames = null;
        if (!TextUtils.isEmpty(names)) {
            telephonyPackageNames = names.trim().split(",");
        }
        return ensureSystemPackageNames(telephonyPackageNames);
    }

    @Override
    public String getContentCaptureServicePackageName() {
        final String flattenedContentCaptureService =
                mContext.getString(R.string.config_defaultContentCaptureService);

        if (TextUtils.isEmpty(flattenedContentCaptureService)) {
            return null;
        }

        final ComponentName contentCaptureServiceComponentName =
                ComponentName.unflattenFromString(flattenedContentCaptureService);
        if (contentCaptureServiceComponentName == null) {
            return null;
        }
        return ensureSystemPackageName(contentCaptureServiceComponentName.getPackageName());
    }

    @Nullable
    private String ensureSystemPackageName(@Nullable String packageName) {
        if (packageName == null) {
            return null;
        }
        if (getPackageInfo(packageName, MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE
                        | MATCH_DIRECT_BOOT_UNAWARE | MATCH_DISABLED_COMPONENTS,
                UserHandle.getCallingUserId()) == null) {
            return null;
        }
        return packageName;
    }

    @Nullable
    private String[] ensureSystemPackageNames(@Nullable String[] packageNames) {
        if (packageNames == null) {
            return null;
        }
        final int packageNamesLength = packageNames.length;
        for (int i = 0; i < packageNamesLength; i++) {
            packageNames[i] = ensureSystemPackageName(packageNames[i]);
        }
        return ArrayUtils.filterNotNull(packageNames, String[]::new);
    }

    @Override
    public void setApplicationEnabledSetting(String appPackageName,
            int newState, int flags, int userId, String callingPackage) {
        if (!mUserManager.exists(userId)) return;
        if (callingPackage == null) {
            callingPackage = Integer.toString(Binder.getCallingUid());
        }
        setEnabledSetting(appPackageName, null, newState, flags, userId, callingPackage);
    }

    @Override
    public void setUpdateAvailable(String packageName, boolean updateAvailable) {
        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, null);
        synchronized (mLock) {
            final PackageSetting pkgSetting = mSettings.mPackages.get(packageName);
            if (pkgSetting != null) {
                pkgSetting.setUpdateAvailable(updateAvailable);
            }
        }
    }

    @Override
    public void setComponentEnabledSetting(ComponentName componentName,
            int newState, int flags, int userId) {
        if (!mUserManager.exists(userId)) return;
        setEnabledSetting(componentName.getPackageName(),
                componentName.getClassName(), newState, flags, userId, null);
    }

    private void setEnabledSetting(final String packageName, String className, int newState,
            final int flags, int userId, String callingPackage) {
        if (!(newState == COMPONENT_ENABLED_STATE_DEFAULT
              || newState == COMPONENT_ENABLED_STATE_ENABLED
              || newState == COMPONENT_ENABLED_STATE_DISABLED
              || newState == COMPONENT_ENABLED_STATE_DISABLED_USER
              || newState == COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED)) {
            throw new IllegalArgumentException("Invalid new component state: "
                    + newState);
        }
        PackageSetting pkgSetting;
        final int callingUid = Binder.getCallingUid();
        final int permission;
        if (callingUid == Process.SYSTEM_UID) {
            permission = PackageManager.PERMISSION_GRANTED;
        } else {
            permission = mContext.checkCallingOrSelfPermission(
                    android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);
        }
        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
                false /* requireFullPermission */, true /* checkShell */, "set enabled");
        final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED);
        boolean sendNow = false;
        boolean isApp = (className == null);
        final boolean isCallerInstantApp = (getInstantAppPackageName(callingUid) != null);
        String componentName = isApp ? packageName : className;
        ArrayList<String> components;

        // reader
        synchronized (mLock) {
            pkgSetting = mSettings.mPackages.get(packageName);
            if (pkgSetting == null) {
                if (!isCallerInstantApp) {
                    if (className == null) {
                        throw new IllegalArgumentException("Unknown package: " + packageName);
                    }
                    throw new IllegalArgumentException(
                            "Unknown component: " + packageName + "/" + className);
                } else {
                    // throw SecurityException to prevent leaking package information
                    throw new SecurityException(
                            "Attempt to change component state; "
                            + "pid=" + Binder.getCallingPid()
                            + ", uid=" + callingUid
                            + (className == null
                                    ? ", package=" + packageName
                                    : ", component=" + packageName + "/" + className));
                }
            }
        }

        // Limit who can change which apps
        if (!UserHandle.isSameApp(callingUid, pkgSetting.appId)) {
            // Don't allow apps that don't have permission to modify other apps
            if (!allowedByPermission
                    || shouldFilterApplicationLocked(pkgSetting, callingUid, userId)) {
                throw new SecurityException(
                        "Attempt to change component state; "
                        + "pid=" + Binder.getCallingPid()
                        + ", uid=" + callingUid
                        + (className == null
                                ? ", package=" + packageName
                                : ", component=" + packageName + "/" + className));
            }
            // Don't allow changing protected packages.
            if (mProtectedPackages.isPackageStateProtected(userId, packageName)) {
                throw new SecurityException("Cannot disable a protected package: " + packageName);
            }
        }
        // Only allow apps with CHANGE_COMPONENT_ENABLED_STATE permission to change hidden
        // app details activity
        if (PackageManager.APP_DETAILS_ACTIVITY_CLASS_NAME.equals(className)
                && !allowedByPermission) {
            throw new SecurityException("Cannot disable a system-generated component");
        }

        synchronized (mLock) {
            if (callingUid == Process.SHELL_UID
                    && (pkgSetting.pkgFlags & ApplicationInfo.FLAG_TEST_ONLY) == 0) {
                // Shell can only change whole packages between ENABLED and DISABLED_USER states
                // unless it is a test package.
                int oldState = pkgSetting.getEnabled(userId);
                if (className == null
                        &&
                        (oldState == COMPONENT_ENABLED_STATE_DISABLED_USER
                                || oldState == COMPONENT_ENABLED_STATE_DEFAULT
                                || oldState == COMPONENT_ENABLED_STATE_ENABLED)
                        &&
                        (newState == COMPONENT_ENABLED_STATE_DISABLED_USER
                                || newState == COMPONENT_ENABLED_STATE_DEFAULT
                                || newState == COMPONENT_ENABLED_STATE_ENABLED)) {
                    // ok
                } else {
                    throw new SecurityException(
                            "Shell cannot change component state for " + packageName + "/"
                                    + className + " to " + newState);
                }
            }
        }
        if (className == null) {
            // We're dealing with an application/package level state change
            synchronized (mLock) {
                if (pkgSetting.getEnabled(userId) == newState) {
                    // Nothing to do
                    return;
                }
            }
            // If we're enabling a system stub, there's a little more work to do.
            // Prior to enabling the package, we need to decompress the APK(s) to the
            // data partition and then replace the version on the system partition.
            final AndroidPackage deletedPkg = pkgSetting.pkg;
            final boolean isSystemStub = deletedPkg.isStub()
                    && deletedPkg.isSystem();
            if (isSystemStub
                    && (newState == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT
                            || newState == PackageManager.COMPONENT_ENABLED_STATE_ENABLED)) {
                if (!enableCompressedPackage(deletedPkg)) {
                    return;
                }
            }
            if (newState == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT
                || newState == PackageManager.COMPONENT_ENABLED_STATE_ENABLED) {
                // Don't care about who enables an app.
                callingPackage = null;
            }
            synchronized (mLock) {
                pkgSetting.setEnabled(newState, userId, callingPackage);
            }
        } else {
            synchronized (mLock) {
                // We're dealing with a component level state change
                // First, verify that this is a valid class name.
                AndroidPackage pkg = pkgSetting.pkg;
                if (pkg == null || !pkg.hasComponentClassName(className)) {
                    if (pkg != null &&
                            pkg.getTargetSdkVersion() >=
                                    Build.VERSION_CODES.JELLY_BEAN) {
                        throw new IllegalArgumentException("Component class " + className
                                + " does not exist in " + packageName);
                    } else {
                        Slog.w(TAG, "Failed setComponentEnabledSetting: component class "
                                + className + " does not exist in " + packageName);
                    }
                }
                switch (newState) {
                    case COMPONENT_ENABLED_STATE_ENABLED:
                        if (!pkgSetting.enableComponentLPw(className, userId)) {
                            return;
                        }
                        break;
                    case COMPONENT_ENABLED_STATE_DISABLED:
                        if (!pkgSetting.disableComponentLPw(className, userId)) {
                            return;
                        }
                        break;
                    case COMPONENT_ENABLED_STATE_DEFAULT:
                        if (!pkgSetting.restoreComponentLPw(className, userId)) {
                            return;
                        }
                        break;
                    default:
                        Slog.e(TAG, "Invalid new component state: " + newState);
                        return;
                }
            }
        }
        synchronized (mLock) {
            if ((flags & PackageManager.SYNCHRONOUS) != 0) {
                flushPackageRestrictionsAsUserInternalLocked(userId);
            } else {
                scheduleWritePackageRestrictionsLocked(userId);
            }
            updateSequenceNumberLP(pkgSetting, new int[] { userId });
            final long callingId = Binder.clearCallingIdentity();
            try {
                updateInstantAppInstallerLocked(packageName);
            } finally {
                Binder.restoreCallingIdentity(callingId);
            }
            components = mPendingBroadcasts.get(userId, packageName);
            final boolean newPackage = components == null;
            if (newPackage) {
                components = new ArrayList<>();
            }
            if (!components.contains(componentName)) {
                components.add(componentName);
            }
            if ((flags&PackageManager.DONT_KILL_APP) == 0) {
                sendNow = true;
                // Purge entry from pending broadcast list if another one exists already
                // since we are sending one right away.
                mPendingBroadcasts.remove(userId, packageName);
            } else {
                if (newPackage) {
                    mPendingBroadcasts.put(userId, packageName, components);
                }
                if (!mHandler.hasMessages(SEND_PENDING_BROADCAST)) {
                    // Schedule a message - if it has been a "reasonably long time" since the
                    // service started, send the broadcast with a delay of one second to avoid
                    // delayed reactions from the receiver, else keep the default ten second delay
                    // to avoid extreme thrashing on service startup.
                    final long broadcastDelay = SystemClock.uptimeMillis() > mServiceStartWithDelay
                                                ? BROADCAST_DELAY
                                                : BROADCAST_DELAY_DURING_STARTUP;
                    mHandler.sendEmptyMessageDelayed(SEND_PENDING_BROADCAST, broadcastDelay);
                }
            }
        }

        long callingId = Binder.clearCallingIdentity();
        try {
            if (sendNow) {
                int packageUid = UserHandle.getUid(userId, pkgSetting.appId);
                sendPackageChangedBroadcast(packageName,
                        (flags & PackageManager.DONT_KILL_APP) != 0, components, packageUid, null);
            }
        } finally {
            Binder.restoreCallingIdentity(callingId);
        }
    }

    @Override
    public void flushPackageRestrictionsAsUser(int userId) {
        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
            return;
        }
        if (!mUserManager.exists(userId)) {
            return;
        }
        mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId, false /* requireFullPermission*/,
                false /* checkShell */, "flushPackageRestrictions");
        synchronized (mLock) {
            flushPackageRestrictionsAsUserInternalLocked(userId);
        }
    }

    @GuardedBy("mLock")
    private void flushPackageRestrictionsAsUserInternalLocked(int userId) {
        mSettings.writePackageRestrictionsLPr(userId);
        mDirtyUsers.remove(userId);
        if (mDirtyUsers.isEmpty()) {
            mHandler.removeMessages(WRITE_PACKAGE_RESTRICTIONS);
        }
    }

    private void sendPackageChangedBroadcast(String packageName,
            boolean dontKillApp, ArrayList<String> componentNames, int packageUid,
            String reason) {
        if (DEBUG_INSTALL)
            Log.v(TAG, "Sending package changed: package=" + packageName + " components="
                    + componentNames);
        Bundle extras = new Bundle(4);
        extras.putString(Intent.EXTRA_CHANGED_COMPONENT_NAME, componentNames.get(0));
        String nameList[] = new String[componentNames.size()];
        componentNames.toArray(nameList);
        extras.putStringArray(Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST, nameList);
        extras.putBoolean(Intent.EXTRA_DONT_KILL_APP, dontKillApp);
        extras.putInt(Intent.EXTRA_UID, packageUid);
        if (reason != null) {
            extras.putString(Intent.EXTRA_REASON, reason);
        }
        // If this is not reporting a change of the overall package, then only send it
        // to registered receivers.  We don't want to launch a swath of apps for every
        // little component state change.
        final int flags = !componentNames.contains(packageName)
                ? Intent.FLAG_RECEIVER_REGISTERED_ONLY : 0;
        final int userId = UserHandle.getUserId(packageUid);
        final boolean isInstantApp = isInstantApp(packageName, userId);
        final int[] userIds = isInstantApp ? EMPTY_INT_ARRAY : new int[] { userId };
        final int[] instantUserIds = isInstantApp ? new int[] { userId } : EMPTY_INT_ARRAY;
        sendPackageBroadcast(Intent.ACTION_PACKAGE_CHANGED,  packageName, extras, flags, null, null,
                userIds, instantUserIds);
    }

    @Override
    public void setPackageStoppedState(String packageName, boolean stopped, int userId) {
        if (!mUserManager.exists(userId)) return;
        final int callingUid = Binder.getCallingUid();
        if (getInstantAppPackageName(callingUid) != null) {
            return;
        }
        final int permission = mContext.checkCallingOrSelfPermission(
                android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);
        final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED);
        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
                true /* requireFullPermission */, true /* checkShell */, "stop package");
        // writer
        synchronized (mLock) {
            final PackageSetting ps = mSettings.mPackages.get(packageName);
            if (!shouldFilterApplicationLocked(ps, callingUid, userId)
                    && mSettings.setPackageStoppedStateLPw(this, packageName, stopped,
                            allowedByPermission, callingUid, userId)) {
                scheduleWritePackageRestrictionsLocked(userId);
            }
        }
    }

    @Override
    public String getInstallerPackageName(String packageName) {
        final int callingUid = Binder.getCallingUid();
        synchronized (mLock) {
            final InstallSource installSource = getInstallSourceLocked(packageName, callingUid);
            if (installSource == null) {
                throw new IllegalArgumentException("Unknown package: " + packageName);
            }
            String installerPackageName = installSource.installerPackageName;
            if (installerPackageName != null) {
                final PackageSetting ps = mSettings.mPackages.get(installerPackageName);
                if (ps == null || shouldFilterApplicationLocked(ps, callingUid,
                        UserHandle.getUserId(callingUid))) {
                    installerPackageName = null;
                }
            }
            return installerPackageName;
        }
    }

    @Override
    @Nullable
    public InstallSourceInfo getInstallSourceInfo(String packageName) {
        final int callingUid = Binder.getCallingUid();
        final int userId = UserHandle.getUserId(callingUid);

        String installerPackageName;
        String initiatingPackageName;
        String originatingPackageName;

        synchronized (mLock) {
            final InstallSource installSource = getInstallSourceLocked(packageName, callingUid);
            if (installSource == null) {
                return null;
            }

            installerPackageName = installSource.installerPackageName;
            if (installerPackageName != null) {
                final PackageSetting ps = mSettings.mPackages.get(installerPackageName);
                if (ps == null || shouldFilterApplicationLocked(ps, callingUid, userId)) {
                    installerPackageName = null;
                }
            }

            // All installSource strings are interned, so == is ok here
            if (installSource.initiatingPackageName == installSource.installerPackageName) {
                // The installer and initiator will often be the same, and when they are
                // we can skip doing the same check again.
                initiatingPackageName = installerPackageName;
            } else {
                initiatingPackageName = installSource.initiatingPackageName;
                final PackageSetting ps = mSettings.mPackages.get(initiatingPackageName);
                if (ps == null || shouldFilterApplicationLocked(ps, callingUid, userId)) {
                    initiatingPackageName = null;
                }

            }
            originatingPackageName = installSource.originatingPackageName;
            if (originatingPackageName != null) {
                final PackageSetting ps = mSettings.mPackages.get(originatingPackageName);
                if (ps == null || shouldFilterApplicationLocked(ps, callingUid, userId)) {
                    originatingPackageName = null;
                }
            }
        }

        if (originatingPackageName != null && mContext.checkCallingOrSelfPermission(
                Manifest.permission.INSTALL_PACKAGES) != PackageManager.PERMISSION_GRANTED) {
            originatingPackageName = null;
        }

        return new InstallSourceInfo(initiatingPackageName, originatingPackageName,
                installerPackageName);
    }

    @GuardedBy("mLock")
    @Nullable
    private InstallSource getInstallSourceLocked(String packageName, int callingUid) {
        final PackageSetting ps = mSettings.mPackages.get(packageName);

        // Installer info for Apex is not stored in PackageManager
        if (ps == null && mApexManager.isApexPackage(packageName)) {
            return InstallSource.EMPTY;
        }

        if (ps == null || shouldFilterApplicationLocked(ps, callingUid,
                UserHandle.getUserId(callingUid))) {
            return null;
        }

        return ps.installSource;
    }

    public boolean isOrphaned(String packageName) {
        // reader
        synchronized (mLock) {
            if (!mPackages.containsKey(packageName)) {
                return false;
            }
            return mSettings.isOrphaned(packageName);
        }
    }

    @Override
    public int getApplicationEnabledSetting(String packageName, int userId) {
        if (!mUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED;
        int callingUid = Binder.getCallingUid();
        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
                false /* requireFullPermission */, false /* checkShell */, "get enabled");
        // reader
        synchronized (mLock) {
            if (shouldFilterApplicationLocked(
                    mSettings.getPackageLPr(packageName), callingUid, userId)) {
                return COMPONENT_ENABLED_STATE_DISABLED;
            }
            return mSettings.getApplicationEnabledSettingLPr(packageName, userId);
        }
    }

    @Override
    public int getComponentEnabledSetting(@NonNull ComponentName component, int userId) {
        if (component == null) return COMPONENT_ENABLED_STATE_DEFAULT;
        if (!mUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED;
        int callingUid = Binder.getCallingUid();
        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
                false /*requireFullPermission*/, false /*checkShell*/, "getComponentEnabled");
        synchronized (mLock) {
            if (shouldFilterApplicationLocked(
                    mSettings.getPackageLPr(component.getPackageName()), callingUid,
                    component, TYPE_UNKNOWN, userId)) {
                return COMPONENT_ENABLED_STATE_DISABLED;
            }
            return mSettings.getComponentEnabledSettingLPr(component, userId);
        }
    }

    @Override
    public void enterSafeMode() {
        enforceSystemOrRoot("Only the system can request entering safe mode");

        if (!mSystemReady) {
            mSafeMode = true;
        }
    }

    @Override
    public void systemReady() {
        enforceSystemOrRoot("Only the system can claim the system is ready");

        mSystemReady = true;
        final ContentResolver resolver = mContext.getContentResolver();
        ContentObserver co = new ContentObserver(mHandler) {
            @Override
            public void onChange(boolean selfChange) {
                final boolean ephemeralFeatureDisabled =
                        Global.getInt(resolver, Global.ENABLE_EPHEMERAL_FEATURE, 1) == 0;
                for (int userId : UserManagerService.getInstance().getUserIds()) {
                    final boolean instantAppsDisabledForUser =
                            ephemeralFeatureDisabled || Secure.getIntForUser(resolver,
                                    Secure.INSTANT_APPS_ENABLED, 1, userId) == 0;
                    mWebInstantAppsDisabled.put(userId, instantAppsDisabledForUser);
                }
            }
        };
        mContext.getContentResolver().registerContentObserver(android.provider.Settings.Global
                        .getUriFor(Global.ENABLE_EPHEMERAL_FEATURE),
                false, co, UserHandle.USER_ALL);
        mContext.getContentResolver().registerContentObserver(android.provider.Settings.Secure
                        .getUriFor(Secure.INSTANT_APPS_ENABLED), false, co, UserHandle.USER_ALL);
        co.onChange(true);

        mAppsFilter.onSystemReady();

        // Disable any carrier apps. We do this very early in boot to prevent the apps from being
        // disabled after already being started.
        CarrierAppUtils.disableCarrierAppsUntilPrivileged(mContext.getOpPackageName(), this,
                mPermissionManagerService, mContext.getContentResolver(),
                UserHandle.USER_SYSTEM);

        disableSkuSpecificApps();

        // Read the compatibilty setting when the system is ready.
        boolean compatibilityModeEnabled = android.provider.Settings.Global.getInt(
                mContext.getContentResolver(),
                android.provider.Settings.Global.COMPATIBILITY_MODE, 1) == 1;
        PackageParser.setCompatibilityModeEnabled(compatibilityModeEnabled);

        if (DEBUG_SETTINGS) {
            Log.d(TAG, "compatibility mode:" + compatibilityModeEnabled);
        }

        synchronized (mLock) {
            // Verify that all of the preferred activity components actually
            // exist.  It is possible for applications to be updated and at
            // that point remove a previously declared activity component that
            // had been set as a preferred activity.  We try to clean this up
            // the next time we encounter that preferred activity, but it is
            // possible for the user flow to never be able to return to that
            // situation so here we do a sanity check to make sure we haven't
            // left any junk around.
            ArrayList<PreferredActivity> removed = new ArrayList<>();
            for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
                PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
                removed.clear();
                for (PreferredActivity pa : pir.filterSet()) {
                    if (!mComponentResolver.isActivityDefined(pa.mPref.mComponent)) {
                        removed.add(pa);
                    }
                }
                if (removed.size() > 0) {
                    for (int r=0; r<removed.size(); r++) {
                        PreferredActivity pa = removed.get(r);
                        Slog.w(TAG, "Removing dangling preferred activity: "
                                + pa.mPref.mComponent);
                        pir.removeFilter(pa);
                    }
                    mSettings.writePackageRestrictionsLPr(
                            mSettings.mPreferredActivities.keyAt(i));
                }
            }
        }

        mUserManager.systemReady();

        // Now that we've scanned all packages, and granted any default
        // permissions, ensure permissions are updated. Beware of dragons if you
        // try optimizing this.
        synchronized (mLock) {
            mPermissionManager.updateAllPermissions(StorageManager.UUID_PRIVATE_INTERNAL, false);

            final PermissionPolicyInternal permissionPolicyInternal =
                    mInjector.getPermissionPolicyInternal();
            permissionPolicyInternal.setOnInitializedCallback(userId -> {
                // The SDK updated case is already handled when we run during the ctor.
                synchronized (mLock) {
                    mPermissionManager.updateAllPermissions(
                            StorageManager.UUID_PRIVATE_INTERNAL, false);
                }
            });
        }

        // Watch for external volumes that come and go over time
        final StorageManager storage = mInjector.getStorageManager();
        storage.registerListener(mStorageListener);

        mInstallerService.systemReady();
        mApexManager.systemReady(mContext);
        mPackageDexOptimizer.systemReady();

        mInjector.getStorageManagerInternal().addExternalStoragePolicy(
                new StorageManagerInternal.ExternalStorageMountPolicy() {
            @Override
            public int getMountMode(int uid, String packageName) {
                if (Process.isIsolated(uid)) {
                    return Zygote.MOUNT_EXTERNAL_NONE;
                }
                if (checkUidPermission(READ_EXTERNAL_STORAGE, uid) == PERMISSION_DENIED) {
                    return Zygote.MOUNT_EXTERNAL_DEFAULT;
                }
                if (checkUidPermission(WRITE_EXTERNAL_STORAGE, uid) == PERMISSION_DENIED) {
                    return Zygote.MOUNT_EXTERNAL_READ;
                }
                return Zygote.MOUNT_EXTERNAL_WRITE;
            }

            @Override
            public boolean hasExternalStorage(int uid, String packageName) {
                return true;
            }
        });

        // Now that we're mostly running, clean up stale users and apps
        mUserManager.reconcileUsers(StorageManager.UUID_PRIVATE_INTERNAL);
        reconcileApps(StorageManager.UUID_PRIVATE_INTERNAL);

        mPermissionManager.systemReady();

        if (mInstantAppResolverConnection != null) {
            mContext.registerReceiver(new BroadcastReceiver() {
                @Override
                public void onReceive(Context context, Intent intent) {
                    mInstantAppResolverConnection.optimisticBind();
                    mContext.unregisterReceiver(this);
                }
            }, new IntentFilter(Intent.ACTION_BOOT_COMPLETED));
        }

        IntentFilter overlayFilter = new IntentFilter(Intent.ACTION_OVERLAY_CHANGED);
        overlayFilter.addDataScheme("package");
        mContext.registerReceiver(new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                if (intent == null) {
                    return;
                }
                Uri data = intent.getData();
                if (data == null) {
                    return;
                }
                String packageName = data.getSchemeSpecificPart();
                if (packageName == null) {
                    return;
                }
                AndroidPackage pkg = mPackages.get(packageName);
                if (pkg == null) {
                    return;
                }
                sendPackageChangedBroadcast(pkg.getPackageName(),
                        true /* dontKillApp */,
                        new ArrayList<>(Collections.singletonList(pkg.getPackageName())),
                        pkg.getUid(),
                        Intent.ACTION_OVERLAY_CHANGED);
            }
        }, overlayFilter);

        mModuleInfoProvider.systemReady();

        // Installer service might attempt to install some packages that have been staged for
        // installation on reboot. Make sure this is the last component to be call since the
        // installation might require other components to be ready.
        mInstallerService.restoreAndApplyStagedSessionIfNeeded();
    }

    public void waitForAppDataPrepared() {
        if (mPrepareAppDataFuture == null) {
            return;
        }
        ConcurrentUtils.waitForFutureNoInterrupt(mPrepareAppDataFuture, "wait for prepareAppData");
        mPrepareAppDataFuture = null;
    }

    @Override
    public boolean isSafeMode() {
        // allow instant applications
        return mSafeMode;
    }

    @Override
    public boolean hasSystemUidErrors() {
        // allow instant applications
        return mHasSystemUidErrors;
    }

    static String arrayToString(int[] array) {
        StringBuilder stringBuilder = new StringBuilder(128);
        stringBuilder.append('[');
        if (array != null) {
            for (int i=0; i<array.length; i++) {
                if (i > 0) stringBuilder.append(", ");
                stringBuilder.append(array[i]);
            }
        }
        stringBuilder.append(']');
        return stringBuilder.toString();
    }

    @Override
    public void onShellCommand(FileDescriptor in, FileDescriptor out,
            FileDescriptor err, String[] args, ShellCallback callback,
            ResultReceiver resultReceiver) {
        (new PackageManagerShellCommand(this, mPermissionManagerService)).exec(
                this, in, out, err, args, callback, resultReceiver);
    }

    @SuppressWarnings("resource")
    @Override
    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
        if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, TAG, pw)) return;

        DumpState dumpState = new DumpState();
        boolean fullPreferred = false;
        boolean checkin = false;

        String packageName = null;
        ArraySet<String> permissionNames = null;

        int opti = 0;
        while (opti < args.length) {
            String opt = args[opti];
            if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
                break;
            }
            opti++;

            if ("-a".equals(opt)) {
                // Right now we only know how to print all.
            } else if ("-h".equals(opt)) {
                pw.println("Package manager dump options:");
                pw.println("  [-h] [-f] [--checkin] [--all-components] [cmd] ...");
                pw.println("    --checkin: dump for a checkin");
                pw.println("    -f: print details of intent filters");
                pw.println("    -h: print this help");
                pw.println("    --all-components: include all component names in package dump");
                pw.println("  cmd may be one of:");
                pw.println("    apex: list active APEXes and APEX session state");
                pw.println("    l[ibraries]: list known shared libraries");
                pw.println("    f[eatures]: list device features");
                pw.println("    k[eysets]: print known keysets");
                pw.println("    r[esolvers] [activity|service|receiver|content]: dump intent resolvers");
                pw.println("    perm[issions]: dump permissions");
                pw.println("    permission [name ...]: dump declaration and use of given permission");
                pw.println("    pref[erred]: print preferred package settings");
                pw.println("    preferred-xml [--full]: print preferred package settings as xml");
                pw.println("    prov[iders]: dump content providers");
                pw.println("    p[ackages]: dump installed packages");
                pw.println("    q[ueries]: dump app queryability calculations");
                pw.println("    s[hared-users]: dump shared user IDs");
                pw.println("    m[essages]: print collected runtime messages");
                pw.println("    v[erifiers]: print package verifier info");
                pw.println("    d[omain-preferred-apps]: print domains preferred apps");
                pw.println("    i[ntent-filter-verifiers]|ifv: print intent filter verifier info");
                pw.println("    version: print database version info");
                pw.println("    write: write current settings now");
                pw.println("    installs: details about install sessions");
                pw.println("    check-permission <permission> <package> [<user>]: does pkg hold perm?");
                pw.println("    dexopt: dump dexopt state");
                pw.println("    compiler-stats: dump compiler statistics");
                pw.println("    service-permissions: dump permissions required by services");
                pw.println("    <package.name>: info about given package");
                return;
            } else if ("--checkin".equals(opt)) {
                checkin = true;
            } else if ("--all-components".equals(opt)) {
                dumpState.setOptionEnabled(DumpState.OPTION_DUMP_ALL_COMPONENTS);
            } else if ("-f".equals(opt)) {
                dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS);
            } else if ("--proto".equals(opt)) {
                dumpProto(fd);
                return;
            } else {
                pw.println("Unknown argument: " + opt + "; use -h for help");
            }
        }

        // Is the caller requesting to dump a particular piece of data?
        if (opti < args.length) {
            String cmd = args[opti];
            opti++;
            // Is this a package name?
            if ("android".equals(cmd) || cmd.contains(".")) {
                packageName = cmd;
                // When dumping a single package, we always dump all of its
                // filter information since the amount of data will be reasonable.
                dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS);
            } else if ("check-permission".equals(cmd)) {
                if (opti >= args.length) {
                    pw.println("Error: check-permission missing permission argument");
                    return;
                }
                String perm = args[opti];
                opti++;
                if (opti >= args.length) {
                    pw.println("Error: check-permission missing package argument");
                    return;
                }

                String pkg = args[opti];
                opti++;
                int user = UserHandle.getUserId(Binder.getCallingUid());
                if (opti < args.length) {
                    try {
                        user = Integer.parseInt(args[opti]);
                    } catch (NumberFormatException e) {
                        pw.println("Error: check-permission user argument is not a number: "
                                + args[opti]);
                        return;
                    }
                }

                // Normalize package name to handle renamed packages and static libs
                pkg = resolveInternalPackageNameLPr(pkg, PackageManager.VERSION_CODE_HIGHEST);

                pw.println(checkPermission(perm, pkg, user));
                return;
            } else if ("l".equals(cmd) || "libraries".equals(cmd)) {
                dumpState.setDump(DumpState.DUMP_LIBS);
            } else if ("f".equals(cmd) || "features".equals(cmd)) {
                dumpState.setDump(DumpState.DUMP_FEATURES);
            } else if ("r".equals(cmd) || "resolvers".equals(cmd)) {
                if (opti >= args.length) {
                    dumpState.setDump(DumpState.DUMP_ACTIVITY_RESOLVERS
                            | DumpState.DUMP_SERVICE_RESOLVERS
                            | DumpState.DUMP_RECEIVER_RESOLVERS
                            | DumpState.DUMP_CONTENT_RESOLVERS);
                } else {
                    while (opti < args.length) {
                        String name = args[opti];
                        if ("a".equals(name) || "activity".equals(name)) {
                            dumpState.setDump(DumpState.DUMP_ACTIVITY_RESOLVERS);
                        } else if ("s".equals(name) || "service".equals(name)) {
                            dumpState.setDump(DumpState.DUMP_SERVICE_RESOLVERS);
                        } else if ("r".equals(name) || "receiver".equals(name)) {
                            dumpState.setDump(DumpState.DUMP_RECEIVER_RESOLVERS);
                        } else if ("c".equals(name) || "content".equals(name)) {
                            dumpState.setDump(DumpState.DUMP_CONTENT_RESOLVERS);
                        } else {
                            pw.println("Error: unknown resolver table type: " + name);
                            return;
                        }
                        opti++;
                    }
                }
            } else if ("perm".equals(cmd) || "permissions".equals(cmd)) {
                dumpState.setDump(DumpState.DUMP_PERMISSIONS);
            } else if ("permission".equals(cmd)) {
                if (opti >= args.length) {
                    pw.println("Error: permission requires permission name");
                    return;
                }
                permissionNames = new ArraySet<>();
                while (opti < args.length) {
                    permissionNames.add(args[opti]);
                    opti++;
                }
                dumpState.setDump(DumpState.DUMP_PERMISSIONS
                        | DumpState.DUMP_PACKAGES | DumpState.DUMP_SHARED_USERS);
            } else if ("pref".equals(cmd) || "preferred".equals(cmd)) {
                dumpState.setDump(DumpState.DUMP_PREFERRED);
            } else if ("preferred-xml".equals(cmd)) {
                dumpState.setDump(DumpState.DUMP_PREFERRED_XML);
                if (opti < args.length && "--full".equals(args[opti])) {
                    fullPreferred = true;
                    opti++;
                }
            } else if ("d".equals(cmd) || "domain-preferred-apps".equals(cmd)) {
                dumpState.setDump(DumpState.DUMP_DOMAIN_PREFERRED);
            } else if ("p".equals(cmd) || "packages".equals(cmd)) {
                dumpState.setDump(DumpState.DUMP_PACKAGES);
            } else if ("q".equals(cmd) || "queries".equals(cmd)) {
                dumpState.setDump(DumpState.DUMP_QUERIES);
            } else if ("s".equals(cmd) || "shared-users".equals(cmd)) {
                dumpState.setDump(DumpState.DUMP_SHARED_USERS);
                if (opti < args.length && "noperm".equals(args[opti])) {
                    dumpState.setOptionEnabled(DumpState.OPTION_SKIP_PERMISSIONS);
                }
            } else if ("prov".equals(cmd) || "providers".equals(cmd)) {
                dumpState.setDump(DumpState.DUMP_PROVIDERS);
            } else if ("m".equals(cmd) || "messages".equals(cmd)) {
                dumpState.setDump(DumpState.DUMP_MESSAGES);
            } else if ("v".equals(cmd) || "verifiers".equals(cmd)) {
                dumpState.setDump(DumpState.DUMP_VERIFIERS);
            } else if ("i".equals(cmd) || "ifv".equals(cmd)
                    || "intent-filter-verifiers".equals(cmd)) {
                dumpState.setDump(DumpState.DUMP_INTENT_FILTER_VERIFIERS);
            } else if ("version".equals(cmd)) {
                dumpState.setDump(DumpState.DUMP_VERSION);
            } else if ("k".equals(cmd) || "keysets".equals(cmd)) {
                dumpState.setDump(DumpState.DUMP_KEYSETS);
            } else if ("installs".equals(cmd)) {
                dumpState.setDump(DumpState.DUMP_INSTALLS);
            } else if ("frozen".equals(cmd)) {
                dumpState.setDump(DumpState.DUMP_FROZEN);
            } else if ("volumes".equals(cmd)) {
                dumpState.setDump(DumpState.DUMP_VOLUMES);
            } else if ("dexopt".equals(cmd)) {
                dumpState.setDump(DumpState.DUMP_DEXOPT);
            } else if ("compiler-stats".equals(cmd)) {
                dumpState.setDump(DumpState.DUMP_COMPILER_STATS);
            } else if ("changes".equals(cmd)) {
                dumpState.setDump(DumpState.DUMP_CHANGES);
            } else if ("service-permissions".equals(cmd)) {
                dumpState.setDump(DumpState.DUMP_SERVICE_PERMISSIONS);
            } else if ("write".equals(cmd)) {
                synchronized (mLock) {
                    mSettings.writeLPr();
                    pw.println("Settings written.");
                    return;
                }
            }
        }

        if (checkin) {
            pw.println("vers,1");
        }

        // reader
        synchronized (mLock) {
            if (dumpState.isDumping(DumpState.DUMP_VERSION) && packageName == null) {
                if (!checkin) {
                    if (dumpState.onTitlePrinted())
                        pw.println();
                    pw.println("Database versions:");
                    mSettings.dumpVersionLPr(new IndentingPrintWriter(pw, "  "));
                }
            }

            if (dumpState.isDumping(DumpState.DUMP_VERIFIERS) && packageName == null) {
                if (!checkin) {
                    if (dumpState.onTitlePrinted())
                        pw.println();
                    pw.println("Verifiers:");
                    pw.print("  Required: ");
                    pw.print(mRequiredVerifierPackage);
                    pw.print(" (uid=");
                    pw.print(getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING,
                            UserHandle.USER_SYSTEM));
                    pw.println(")");
                } else if (mRequiredVerifierPackage != null) {
                    pw.print("vrfy,"); pw.print(mRequiredVerifierPackage);
                    pw.print(",");
                    pw.println(getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING,
                            UserHandle.USER_SYSTEM));
                }
            }

            if (dumpState.isDumping(DumpState.DUMP_INTENT_FILTER_VERIFIERS) &&
                    packageName == null) {
                if (mIntentFilterVerifierComponent != null) {
                    String verifierPackageName = mIntentFilterVerifierComponent.getPackageName();
                    if (!checkin) {
                        if (dumpState.onTitlePrinted())
                            pw.println();
                        pw.println("Intent Filter Verifier:");
                        pw.print("  Using: ");
                        pw.print(verifierPackageName);
                        pw.print(" (uid=");
                        pw.print(getPackageUid(verifierPackageName, MATCH_DEBUG_TRIAGED_MISSING,
                                UserHandle.USER_SYSTEM));
                        pw.println(")");
                    } else if (verifierPackageName != null) {
                        pw.print("ifv,"); pw.print(verifierPackageName);
                        pw.print(",");
                        pw.println(getPackageUid(verifierPackageName, MATCH_DEBUG_TRIAGED_MISSING,
                                UserHandle.USER_SYSTEM));
                    }
                } else {
                    pw.println();
                    pw.println("No Intent Filter Verifier available!");
                }
            }

            if (dumpState.isDumping(DumpState.DUMP_LIBS) && packageName == null) {
                boolean printedHeader = false;
                final Iterator<String> it = mSharedLibraries.keySet().iterator();
                while (it.hasNext()) {
                    String libName = it.next();
                    LongSparseArray<SharedLibraryInfo> versionedLib
                            = mSharedLibraries.get(libName);
                    if (versionedLib == null) {
                        continue;
                    }
                    final int versionCount = versionedLib.size();
                    for (int i = 0; i < versionCount; i++) {
                        SharedLibraryInfo libraryInfo = versionedLib.valueAt(i);
                        if (!checkin) {
                            if (!printedHeader) {
                                if (dumpState.onTitlePrinted())
                                    pw.println();
                                pw.println("Libraries:");
                                printedHeader = true;
                            }
                            pw.print("  ");
                        } else {
                            pw.print("lib,");
                        }
                        pw.print(libraryInfo.getName());
                        if (libraryInfo.isStatic()) {
                            pw.print(" version=" + libraryInfo.getLongVersion());
                        }
                        if (!checkin) {
                            pw.print(" -> ");
                        }
                        if (libraryInfo.getPath() != null) {
                            pw.print(" (jar) ");
                            pw.print(libraryInfo.getPath());
                        } else {
                            pw.print(" (apk) ");
                            pw.print(libraryInfo.getPackageName());
                        }
                        pw.println();
                    }
                }
            }

            if (dumpState.isDumping(DumpState.DUMP_FEATURES) && packageName == null) {
                if (dumpState.onTitlePrinted())
                    pw.println();
                if (!checkin) {
                    pw.println("Features:");
                }

                synchronized (mAvailableFeatures) {
                    for (FeatureInfo feat : mAvailableFeatures.values()) {
                        if (checkin) {
                            pw.print("feat,");
                            pw.print(feat.name);
                            pw.print(",");
                            pw.println(feat.version);
                        } else {
                            pw.print("  ");
                            pw.print(feat.name);
                            if (feat.version > 0) {
                                pw.print(" version=");
                                pw.print(feat.version);
                            }
                            pw.println();
                        }
                    }
                }
            }

            if (!checkin && dumpState.isDumping(DumpState.DUMP_ACTIVITY_RESOLVERS)) {
                mComponentResolver.dumpActivityResolvers(pw, dumpState, packageName);
            }
            if (!checkin && dumpState.isDumping(DumpState.DUMP_RECEIVER_RESOLVERS)) {
                mComponentResolver.dumpReceiverResolvers(pw, dumpState, packageName);
            }
            if (!checkin && dumpState.isDumping(DumpState.DUMP_SERVICE_RESOLVERS)) {
                mComponentResolver.dumpServiceResolvers(pw, dumpState, packageName);
            }
            if (!checkin && dumpState.isDumping(DumpState.DUMP_CONTENT_RESOLVERS)) {
                mComponentResolver.dumpProviderResolvers(pw, dumpState, packageName);
            }

            if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED)) {
                for (int i=0; i<mSettings.mPreferredActivities.size(); i++) {
                    PreferredIntentResolver pir = mSettings.mPreferredActivities.valueAt(i);
                    int user = mSettings.mPreferredActivities.keyAt(i);
                    if (pir.dump(pw,
                            dumpState.getTitlePrinted()
                                ? "\nPreferred Activities User " + user + ":"
                                : "Preferred Activities User " + user + ":", "  ",
                            packageName, true, false)) {
                        dumpState.setTitlePrinted(true);
                    }
                }
            }

            if (!checkin && dumpState.isDumping(DumpState.DUMP_PREFERRED_XML)) {
                pw.flush();
                FileOutputStream fout = new FileOutputStream(fd);
                BufferedOutputStream str = new BufferedOutputStream(fout);
                XmlSerializer serializer = new FastXmlSerializer();
                try {
                    serializer.setOutput(str, StandardCharsets.UTF_8.name());
                    serializer.startDocument(null, true);
                    serializer.setFeature(
                            "http://xmlpull.org/v1/doc/features.html#indent-output", true);
                    mSettings.writePreferredActivitiesLPr(serializer, 0, fullPreferred);
                    serializer.endDocument();
                    serializer.flush();
                } catch (IllegalArgumentException e) {
                    pw.println("Failed writing: " + e);
                } catch (IllegalStateException e) {
                    pw.println("Failed writing: " + e);
                } catch (IOException e) {
                    pw.println("Failed writing: " + e);
                }
            }

            if (!checkin
                    && dumpState.isDumping(DumpState.DUMP_DOMAIN_PREFERRED)
                    && packageName == null) {
                pw.println();
                int count = mSettings.mPackages.size();
                if (count == 0) {
                    pw.println("No applications!");
                    pw.println();
                } else {
                    final String prefix = "  ";
                    Collection<PackageSetting> allPackageSettings = mSettings.mPackages.values();
                    if (allPackageSettings.size() == 0) {
                        pw.println("No domain preferred apps!");
                        pw.println();
                    } else {
                        pw.println("App verification status:");
                        pw.println();
                        count = 0;
                        for (PackageSetting ps : allPackageSettings) {
                            IntentFilterVerificationInfo ivi = ps.getIntentFilterVerificationInfo();
                            if (ivi == null || ivi.getPackageName() == null) continue;
                            pw.println(prefix + "Package: " + ivi.getPackageName());
                            pw.println(prefix + "Domains: " + ivi.getDomainsString());
                            pw.println(prefix + "Status:  " + ivi.getStatusString());
                            pw.println();
                            count++;
                        }
                        if (count == 0) {
                            pw.println(prefix + "No app verification established.");
                            pw.println();
                        }
                        for (int userId : mUserManager.getUserIds()) {
                            pw.println("App linkages for user " + userId + ":");
                            pw.println();
                            count = 0;
                            for (PackageSetting ps : allPackageSettings) {
                                final long status = ps.getDomainVerificationStatusForUser(userId);
                                if (status >> 32 == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED
                                        && !DEBUG_DOMAIN_VERIFICATION) {
                                    continue;
                                }
                                pw.println(prefix + "Package: " + ps.name);
                                pw.println(prefix + "Domains: " + dumpDomainString(ps.name));
                                String statusStr = IntentFilterVerificationInfo.
                                        getStatusStringFromValue(status);
                                pw.println(prefix + "Status:  " + statusStr);
                                pw.println();
                                count++;
                            }
                            if (count == 0) {
                                pw.println(prefix + "No configured app linkages.");
                                pw.println();
                            }
                        }
                    }
                }
            }

            if (!checkin && dumpState.isDumping(DumpState.DUMP_PERMISSIONS)) {
                mSettings.dumpPermissionsLPr(pw, packageName, permissionNames, dumpState);
            }

            if (!checkin && dumpState.isDumping(DumpState.DUMP_PROVIDERS)) {
                mComponentResolver.dumpContentProviders(pw, dumpState, packageName);
            }

            if (!checkin && dumpState.isDumping(DumpState.DUMP_KEYSETS)) {
                mSettings.mKeySetManagerService.dumpLPr(pw, packageName, dumpState);
            }

            if (dumpState.isDumping(DumpState.DUMP_PACKAGES)) {
                mSettings.dumpPackagesLPr(pw, packageName, permissionNames, dumpState, checkin);
            }

            if (dumpState.isDumping(DumpState.DUMP_QUERIES)) {
                final PackageSetting setting = mSettings.getPackageLPr(packageName);
                Integer filteringAppId = setting == null ? null : setting.appId;
                mAppsFilter.dumpQueries(
                        pw, this, filteringAppId, dumpState,
                        mUserManager.getUserIds());
            }

            if (dumpState.isDumping(DumpState.DUMP_SHARED_USERS)) {
                mSettings.dumpSharedUsersLPr(pw, packageName, permissionNames, dumpState, checkin);
            }

            if (dumpState.isDumping(DumpState.DUMP_CHANGES)) {
                if (dumpState.onTitlePrinted()) pw.println();
                pw.println("Package Changes:");
                pw.print("  Sequence number="); pw.println(mChangedPackagesSequenceNumber);
                final int K = mChangedPackages.size();
                for (int i = 0; i < K; i++) {
                    final SparseArray<String> changes = mChangedPackages.valueAt(i);
                    pw.print("  User "); pw.print(mChangedPackages.keyAt(i)); pw.println(":");
                    final int N = changes.size();
                    if (N == 0) {
                        pw.print("    "); pw.println("No packages changed");
                    } else {
                        for (int j = 0; j < N; j++) {
                            final String pkgName = changes.valueAt(j);
                            final int sequenceNumber = changes.keyAt(j);
                            pw.print("    ");
                            pw.print("seq=");
                            pw.print(sequenceNumber);
                            pw.print(", package=");
                            pw.println(pkgName);
                        }
                    }
                }
            }

            if (!checkin && dumpState.isDumping(DumpState.DUMP_FROZEN) && packageName == null) {
                // XXX should handle packageName != null by dumping only install data that
                // the given package is involved with.
                if (dumpState.onTitlePrinted()) pw.println();

                final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ", 120);
                ipw.println();
                ipw.println("Frozen packages:");
                ipw.increaseIndent();
                if (mFrozenPackages.size() == 0) {
                    ipw.println("(none)");
                } else {
                    for (int i = 0; i < mFrozenPackages.size(); i++) {
                        ipw.println(mFrozenPackages.valueAt(i));
                    }
                }
                ipw.decreaseIndent();
            }

            if (!checkin && dumpState.isDumping(DumpState.DUMP_VOLUMES) && packageName == null) {
                if (dumpState.onTitlePrinted()) pw.println();

                final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ", 120);
                ipw.println();
                ipw.println("Loaded volumes:");
                ipw.increaseIndent();
                if (mLoadedVolumes.size() == 0) {
                    ipw.println("(none)");
                } else {
                    for (int i = 0; i < mLoadedVolumes.size(); i++) {
                        ipw.println(mLoadedVolumes.valueAt(i));
                    }
                }
                ipw.decreaseIndent();
            }

            if (!checkin && dumpState.isDumping(DumpState.DUMP_SERVICE_PERMISSIONS)
                    && packageName == null) {
                mComponentResolver.dumpServicePermissions(pw, dumpState);
            }

            if (!checkin && dumpState.isDumping(DumpState.DUMP_DEXOPT)) {
                if (dumpState.onTitlePrinted()) pw.println();
                dumpDexoptStateLPr(pw, packageName);
            }

            if (!checkin && dumpState.isDumping(DumpState.DUMP_COMPILER_STATS)) {
                if (dumpState.onTitlePrinted()) pw.println();
                dumpCompilerStatsLPr(pw, packageName);
            }

            if (!checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES) && packageName == null) {
                if (dumpState.onTitlePrinted()) pw.println();
                mSettings.dumpReadMessagesLPr(pw, dumpState);

                pw.println();
                pw.println("Package warning messages:");
                dumpCriticalInfo(pw, null);
            }

            if (checkin && dumpState.isDumping(DumpState.DUMP_MESSAGES)) {
                dumpCriticalInfo(pw, "msg,");
            }
        }

        // PackageInstaller should be called outside of mPackages lock
        if (!checkin && dumpState.isDumping(DumpState.DUMP_INSTALLS) && packageName == null) {
            // XXX should handle packageName != null by dumping only install data that
            // the given package is involved with.
            if (dumpState.onTitlePrinted()) pw.println();
            mInstallerService.dump(new IndentingPrintWriter(pw, "  ", 120));
        }

        if (!checkin && dumpState.isDumping(DumpState.DUMP_APEX)) {
            mApexManager.dump(pw, packageName);
        }
    }

    //TODO: b/111402650
    private void disableSkuSpecificApps() {
        String apkList[] = mContext.getResources().getStringArray(
                R.array.config_disableApksUnlessMatchedSku_apk_list);
        String skuArray[] = mContext.getResources().getStringArray(
                R.array.config_disableApkUnlessMatchedSku_skus_list);
        if (ArrayUtils.isEmpty(apkList)) {
           return;
        }
        String sku = SystemProperties.get("ro.boot.hardware.sku");
        if (!TextUtils.isEmpty(sku) && ArrayUtils.contains(skuArray, sku)) {
            return;
        }
        for (String packageName : apkList) {
            setSystemAppHiddenUntilInstalled(packageName, true);
            for (UserInfo user : mUserManager.getUsers(false)) {
                setSystemAppInstallState(packageName, false, user.id);
            }
        }
    }

    private void dumpProto(FileDescriptor fd) {
        final ProtoOutputStream proto = new ProtoOutputStream(fd);

        synchronized (mLock) {
            final long requiredVerifierPackageToken =
                    proto.start(PackageServiceDumpProto.REQUIRED_VERIFIER_PACKAGE);
            proto.write(PackageServiceDumpProto.PackageShortProto.NAME, mRequiredVerifierPackage);
            proto.write(
                    PackageServiceDumpProto.PackageShortProto.UID,
                    getPackageUid(
                            mRequiredVerifierPackage,
                            MATCH_DEBUG_TRIAGED_MISSING,
                            UserHandle.USER_SYSTEM));
            proto.end(requiredVerifierPackageToken);

            if (mIntentFilterVerifierComponent != null) {
                String verifierPackageName = mIntentFilterVerifierComponent.getPackageName();
                final long verifierPackageToken =
                        proto.start(PackageServiceDumpProto.VERIFIER_PACKAGE);
                proto.write(PackageServiceDumpProto.PackageShortProto.NAME, verifierPackageName);
                proto.write(
                        PackageServiceDumpProto.PackageShortProto.UID,
                        getPackageUid(
                                verifierPackageName,
                                MATCH_DEBUG_TRIAGED_MISSING,
                                UserHandle.USER_SYSTEM));
                proto.end(verifierPackageToken);
            }

            dumpSharedLibrariesProto(proto);
            dumpFeaturesProto(proto);
            mSettings.dumpPackagesProto(proto);
            mSettings.dumpSharedUsersProto(proto);
            dumpCriticalInfo(proto);
        }
        proto.flush();
    }

    private void dumpFeaturesProto(ProtoOutputStream proto) {
        synchronized (mAvailableFeatures) {
            final int count = mAvailableFeatures.size();
            for (int i = 0; i < count; i++) {
                mAvailableFeatures.valueAt(i).dumpDebug(proto, PackageServiceDumpProto.FEATURES);
            }
        }
    }

    private void dumpSharedLibrariesProto(ProtoOutputStream proto) {
        final int count = mSharedLibraries.size();
        for (int i = 0; i < count; i++) {
            final String libName = mSharedLibraries.keyAt(i);
            LongSparseArray<SharedLibraryInfo> versionedLib = mSharedLibraries.get(libName);
            if (versionedLib == null) {
                continue;
            }
            final int versionCount = versionedLib.size();
            for (int j = 0; j < versionCount; j++) {
                final SharedLibraryInfo libraryInfo = versionedLib.valueAt(j);
                final long sharedLibraryToken =
                        proto.start(PackageServiceDumpProto.SHARED_LIBRARIES);
                proto.write(PackageServiceDumpProto.SharedLibraryProto.NAME, libraryInfo.getName());
                final boolean isJar = (libraryInfo.getPath() != null);
                proto.write(PackageServiceDumpProto.SharedLibraryProto.IS_JAR, isJar);
                if (isJar) {
                    proto.write(PackageServiceDumpProto.SharedLibraryProto.PATH,
                            libraryInfo.getPath());
                } else {
                    proto.write(PackageServiceDumpProto.SharedLibraryProto.APK,
                            libraryInfo.getPackageName());
                }
                proto.end(sharedLibraryToken);
            }
        }
    }

    @GuardedBy("mLock")
    @SuppressWarnings("resource")
    private void dumpDexoptStateLPr(PrintWriter pw, String packageName) {
        final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ");
        ipw.println();
        ipw.println("Dexopt state:");
        ipw.increaseIndent();
        Collection<AndroidPackage> packages;
        if (packageName != null) {
            AndroidPackage targetPackage = mPackages.get(packageName);
            if (targetPackage != null) {
                packages = Collections.singletonList(targetPackage);
            } else {
                ipw.println("Unable to find package: " + packageName);
                return;
            }
        } else {
            packages = mPackages.values();
        }

        for (AndroidPackage pkg : packages) {
            ipw.println("[" + pkg.getPackageName() + "]");
            ipw.increaseIndent();
            mPackageDexOptimizer.dumpDexoptState(ipw, pkg,
                    mDexManager.getPackageUseInfoOrDefault(pkg.getPackageName()));
            ipw.decreaseIndent();
        }
    }

    @GuardedBy("mLock")
    @SuppressWarnings("resource")
    private void dumpCompilerStatsLPr(PrintWriter pw, String packageName) {
        final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ");
        ipw.println();
        ipw.println("Compiler stats:");
        ipw.increaseIndent();
        Collection<AndroidPackage> packages;
        if (packageName != null) {
            AndroidPackage targetPackage = mPackages.get(packageName);
            if (targetPackage != null) {
                packages = Collections.singletonList(targetPackage);
            } else {
                ipw.println("Unable to find package: " + packageName);
                return;
            }
        } else {
            packages = mPackages.values();
        }

        for (AndroidPackage pkg : packages) {
            ipw.println("[" + pkg.getPackageName() + "]");
            ipw.increaseIndent();

            CompilerStats.PackageStats stats = getCompilerPackageStats(pkg.getPackageName());
            if (stats == null) {
                ipw.println("(No recorded stats)");
            } else {
                stats.dump(ipw);
            }
            ipw.decreaseIndent();
        }
    }

    private String dumpDomainString(String packageName) {
        List<IntentFilterVerificationInfo> iviList = getIntentFilterVerifications(packageName)
                .getList();
        List<IntentFilter> filters = getAllIntentFilters(packageName).getList();

        ArraySet<String> result = new ArraySet<>();
        if (iviList.size() > 0) {
            for (IntentFilterVerificationInfo ivi : iviList) {
                result.addAll(ivi.getDomains());
            }
        }
        if (filters != null && filters.size() > 0) {
            for (IntentFilter filter : filters) {
                if (filter.hasCategory(Intent.CATEGORY_BROWSABLE)
                        && (filter.hasDataScheme(IntentFilter.SCHEME_HTTP) ||
                                filter.hasDataScheme(IntentFilter.SCHEME_HTTPS))) {
                    result.addAll(filter.getHostsList());
                }
            }
        }

        StringBuilder sb = new StringBuilder(result.size() * 16);
        for (String domain : result) {
            if (sb.length() > 0) sb.append(" ");
            sb.append(domain);
        }
        return sb.toString();
    }

    // ------- apps on sdcard specific code -------
    static final boolean DEBUG_SD_INSTALL = false;

    private static final String SD_ENCRYPTION_KEYSTORE_NAME = "AppsOnSD";

    private static final String SD_ENCRYPTION_ALGORITHM = "AES";

    private boolean mMediaMounted = false;

    static String getEncryptKey() {
        try {
            String sdEncKey = SystemKeyStore.getInstance().retrieveKeyHexString(
                    SD_ENCRYPTION_KEYSTORE_NAME);
            if (sdEncKey == null) {
                sdEncKey = SystemKeyStore.getInstance().generateNewKeyHexString(128,
                        SD_ENCRYPTION_ALGORITHM, SD_ENCRYPTION_KEYSTORE_NAME);
                if (sdEncKey == null) {
                    Slog.e(TAG, "Failed to create encryption keys");
                    return null;
                }
            }
            return sdEncKey;
        } catch (NoSuchAlgorithmException nsae) {
            Slog.e(TAG, "Failed to create encryption keys with exception: " + nsae);
            return null;
        } catch (IOException ioe) {
            Slog.e(TAG, "Failed to retrieve encryption keys with exception: " + ioe);
            return null;
        }
    }

    private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing,
            ArrayList<AndroidPackage> packages, IIntentReceiver finishedReceiver) {
        final int size = packages.size();
        final String[] packageNames = new String[size];
        final int[] packageUids = new int[size];
        for (int i = 0; i < size; i++) {
            final AndroidPackage pkg = packages.get(i);
            packageNames[i] = pkg.getAppInfoPackageName();
            packageUids[i] = pkg.getUid();
        }
        sendResourcesChangedBroadcast(mediaStatus, replacing, packageNames, packageUids,
                finishedReceiver);
    }

    private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing,
            ArrayList<String> pkgList, int uidArr[], IIntentReceiver finishedReceiver) {
        sendResourcesChangedBroadcast(mediaStatus, replacing,
                pkgList.toArray(new String[pkgList.size()]), uidArr, finishedReceiver);
    }

    private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing,
            String[] pkgList, int uidArr[], IIntentReceiver finishedReceiver) {
        int size = pkgList.length;
        if (size > 0) {
            // Send broadcasts here
            Bundle extras = new Bundle();
            extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList);
            if (uidArr != null) {
                extras.putIntArray(Intent.EXTRA_CHANGED_UID_LIST, uidArr);
            }
            if (replacing) {
                extras.putBoolean(Intent.EXTRA_REPLACING, replacing);
            }
            String action = mediaStatus ? Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE
                    : Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE;
            sendPackageBroadcast(action, null, extras, 0, null, finishedReceiver, null, null);
        }
    }

    private void loadPrivatePackages(final VolumeInfo vol) {
        mHandler.post(() -> loadPrivatePackagesInner(vol));
    }

    private void loadPrivatePackagesInner(VolumeInfo vol) {
        final String volumeUuid = vol.fsUuid;
        if (TextUtils.isEmpty(volumeUuid)) {
            Slog.e(TAG, "Loading internal storage is probably a mistake; ignoring");
            return;
        }

        final ArrayList<PackageFreezer> freezers = new ArrayList<>();
        final ArrayList<AndroidPackage> loaded = new ArrayList<>();
        final int parseFlags = mDefParseFlags | PackageParser.PARSE_EXTERNAL_STORAGE;

        final VersionInfo ver;
        final List<PackageSetting> packages;
        synchronized (mLock) {
            ver = mSettings.findOrCreateVersion(volumeUuid);
            packages = mSettings.getVolumePackagesLPr(volumeUuid);
        }

        for (PackageSetting ps : packages) {
            freezers.add(freezePackage(ps.name, "loadPrivatePackagesInner"));
            synchronized (mInstallLock) {
                final AndroidPackage pkg;
                try {
                    pkg = scanPackageTracedLI(ps.codePath, parseFlags, SCAN_INITIAL, 0, null);
                    loaded.add(pkg);

                } catch (PackageManagerException e) {
                    Slog.w(TAG, "Failed to scan " + ps.codePath + ": " + e.getMessage());
                }

                if (!Build.FINGERPRINT.equals(ver.fingerprint)) {
                    clearAppDataLIF(ps.pkg, UserHandle.USER_ALL, FLAG_STORAGE_DE | FLAG_STORAGE_CE
                            | FLAG_STORAGE_EXTERNAL | Installer.FLAG_CLEAR_CODE_CACHE_ONLY
                            | Installer.FLAG_CLEAR_APP_DATA_KEEP_ART_PROFILES);
                }
            }
        }

        // Reconcile app data for all started/unlocked users
        final StorageManager sm = mInjector.getStorageManager();
        UserManagerInternal umInternal = mInjector.getUserManagerInternal();
        for (UserInfo user : mUserManager.getUsers(false /* includeDying */)) {
            final int flags;
            if (umInternal.isUserUnlockingOrUnlocked(user.id)) {
                flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
            } else if (umInternal.isUserRunning(user.id)) {
                flags = StorageManager.FLAG_STORAGE_DE;
            } else {
                continue;
            }

            try {
                sm.prepareUserStorage(volumeUuid, user.id, user.serialNumber, flags);
                synchronized (mInstallLock) {
                    reconcileAppsDataLI(volumeUuid, user.id, flags, true /* migrateAppData */);
                }
            } catch (IllegalStateException e) {
                // Device was probably ejected, and we'll process that event momentarily
                Slog.w(TAG, "Failed to prepare storage: " + e);
            }
        }

        synchronized (mLock) {
            final boolean sdkUpdated = (ver.sdkVersion != mSdkVersion);
            if (sdkUpdated) {
                logCriticalInfo(Log.INFO, "Platform changed from " + ver.sdkVersion + " to "
                        + mSdkVersion + "; regranting permissions for " + volumeUuid);
            }
            mPermissionManager.updateAllPermissions(volumeUuid, sdkUpdated);

            // Yay, everything is now upgraded
            ver.forceCurrent();

            mSettings.writeLPr();
        }

        for (PackageFreezer freezer : freezers) {
            freezer.close();
        }

        if (DEBUG_INSTALL) Slog.d(TAG, "Loaded packages " + loaded);
        sendResourcesChangedBroadcast(true, false, loaded, null);
        mLoadedVolumes.add(vol.getId());
    }

    private void unloadPrivatePackages(final VolumeInfo vol) {
        mHandler.post(() -> unloadPrivatePackagesInner(vol));
    }

    private void unloadPrivatePackagesInner(VolumeInfo vol) {
        final String volumeUuid = vol.fsUuid;
        if (TextUtils.isEmpty(volumeUuid)) {
            Slog.e(TAG, "Unloading internal storage is probably a mistake; ignoring");
            return;
        }

        final ArrayList<AndroidPackage> unloaded = new ArrayList<>();
        synchronized (mInstallLock) {
        synchronized (mLock) {
            final List<PackageSetting> packages = mSettings.getVolumePackagesLPr(volumeUuid);
            for (PackageSetting ps : packages) {
                if (ps.pkg == null) continue;

                final AndroidPackage pkg = ps.pkg;
                final int deleteFlags = PackageManager.DELETE_KEEP_DATA;
                final PackageRemovedInfo outInfo = new PackageRemovedInfo(this);

                try (PackageFreezer freezer = freezePackageForDelete(ps.name, deleteFlags,
                        "unloadPrivatePackagesInner")) {
                    if (deletePackageLIF(ps.name, null, false, null, deleteFlags, outInfo,
                            false, null)) {
                        unloaded.add(pkg);
                    } else {
                        Slog.w(TAG, "Failed to unload " + ps.codePath);
                    }
                }

                // Try very hard to release any references to this package
                // so we don't risk the system server being killed due to
                // open FDs
                AttributeCache.instance().removePackage(ps.name);
            }

            mSettings.writeLPr();
        }
        }

        if (DEBUG_INSTALL) Slog.d(TAG, "Unloaded packages " + unloaded);
        sendResourcesChangedBroadcast(false, false, unloaded, null);
        mLoadedVolumes.remove(vol.getId());

        // Try very hard to release any references to this path so we don't risk
        // the system server being killed due to open FDs
        ResourcesManager.getInstance().invalidatePath(vol.getPath().getAbsolutePath());

        for (int i = 0; i < 3; i++) {
            System.gc();
            System.runFinalization();
        }
    }

    private void assertPackageKnownAndInstalled(String volumeUuid, String packageName, int userId)
            throws PackageManagerException {
        synchronized (mLock) {
            // Normalize package name to handle renamed packages
            packageName = normalizePackageNameLPr(packageName);

            final PackageSetting ps = mSettings.mPackages.get(packageName);
            if (ps == null) {
                throw new PackageManagerException("Package " + packageName + " is unknown");
            } else if (!TextUtils.equals(volumeUuid, ps.volumeUuid)) {
                throw new PackageManagerException(
                        "Package " + packageName + " found on unknown volume " + volumeUuid
                                + "; expected volume " + ps.volumeUuid);
            } else if (!ps.getInstalled(userId)) {
                throw new PackageManagerException(
                        "Package " + packageName + " not installed for user " + userId);
            }
        }
    }

    private List<String> collectAbsoluteCodePaths() {
        synchronized (mLock) {
            List<String> codePaths = new ArrayList<>();
            final int packageCount = mSettings.mPackages.size();
            for (int i = 0; i < packageCount; i++) {
                final PackageSetting ps = mSettings.mPackages.valueAt(i);
                codePaths.add(ps.codePath.getAbsolutePath());
            }
            return codePaths;
        }
    }

    /**
     * Examine all apps present on given mounted volume, and destroy apps that
     * aren't expected, either due to uninstallation or reinstallation on
     * another volume.
     */
    private void reconcileApps(String volumeUuid) {
        List<String> absoluteCodePaths = collectAbsoluteCodePaths();
        List<File> filesToDelete = null;

        final File[] files = FileUtils.listFilesOrEmpty(
                Environment.getDataAppDirectory(volumeUuid));
        for (File file : files) {
            final boolean isPackage = (isApkFile(file) || file.isDirectory())
                    && !PackageInstallerService.isStageName(file.getName());
            if (!isPackage) {
                // Ignore entries which are not packages
                continue;
            }

            String absolutePath = file.getAbsolutePath();

            boolean pathValid = false;
            final int absoluteCodePathCount = absoluteCodePaths.size();
            for (int i = 0; i < absoluteCodePathCount; i++) {
                String absoluteCodePath = absoluteCodePaths.get(i);
                if (absolutePath.startsWith(absoluteCodePath)) {
                    pathValid = true;
                    break;
                }
            }

            if (!pathValid) {
                if (filesToDelete == null) {
                    filesToDelete = new ArrayList<>();
                }
                filesToDelete.add(file);
            }
        }

        if (filesToDelete != null) {
            final int fileToDeleteCount = filesToDelete.size();
            for (int i = 0; i < fileToDeleteCount; i++) {
                File fileToDelete = filesToDelete.get(i);
                logCriticalInfo(Log.WARN, "Destroying orphaned" + fileToDelete);
                synchronized (mInstallLock) {
                    removeCodePathLI(fileToDelete);
                }
            }
        }
    }

    /**
     * Reconcile all app data for the given user.
     * <p>
     * Verifies that directories exist and that ownership and labeling is
     * correct for all installed apps on all mounted volumes.
     */
    void reconcileAppsData(int userId, int flags, boolean migrateAppsData) {
        final StorageManager storage = mInjector.getStorageManager();
        for (VolumeInfo vol : storage.getWritablePrivateVolumes()) {
            final String volumeUuid = vol.getFsUuid();
            synchronized (mInstallLock) {
                reconcileAppsDataLI(volumeUuid, userId, flags, migrateAppsData);
            }
        }
    }

    @GuardedBy("mInstallLock")
    private void reconcileAppsDataLI(String volumeUuid, int userId, int flags,
            boolean migrateAppData) {
        reconcileAppsDataLI(volumeUuid, userId, flags, migrateAppData, false /* onlyCoreApps */);
    }

    /**
     * Reconcile all app data on given mounted volume.
     * <p>
     * Destroys app data that isn't expected, either due to uninstallation or
     * reinstallation on another volume.
     * <p>
     * Verifies that directories exist and that ownership and labeling is
     * correct for all installed apps.
     * @return list of skipped non-core packages (if {@code onlyCoreApps} is true)
     */
    @GuardedBy("mInstallLock")
    private List<String> reconcileAppsDataLI(String volumeUuid, int userId, int flags,
            boolean migrateAppData, boolean onlyCoreApps) {
        Slog.v(TAG, "reconcileAppsData for " + volumeUuid + " u" + userId + " 0x"
                + Integer.toHexString(flags) + " migrateAppData=" + migrateAppData);
        List<String> result = onlyCoreApps ? new ArrayList<>() : null;

        final File ceDir = Environment.getDataUserCeDirectory(volumeUuid, userId);
        final File deDir = Environment.getDataUserDeDirectory(volumeUuid, userId);

        // First look for stale data that doesn't belong, and check if things
        // have changed since we did our last restorecon
        if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) {
            if (StorageManager.isFileEncryptedNativeOrEmulated()
                    && !StorageManager.isUserKeyUnlocked(userId)) {
                throw new RuntimeException(
                        "Yikes, someone asked us to reconcile CE storage while " + userId
                                + " was still locked; this would have caused massive data loss!");
            }

            final File[] files = FileUtils.listFilesOrEmpty(ceDir);
            for (File file : files) {
                final String packageName = file.getName();
                try {
                    assertPackageKnownAndInstalled(volumeUuid, packageName, userId);
                } catch (PackageManagerException e) {
                    logCriticalInfo(Log.WARN, "Destroying " + file + " due to: " + e);
                    try {
                        mInstaller.destroyAppData(volumeUuid, packageName, userId,
                                StorageManager.FLAG_STORAGE_CE, 0);
                    } catch (InstallerException e2) {
                        logCriticalInfo(Log.WARN, "Failed to destroy: " + e2);
                    }
                }
            }
        }
        if ((flags & StorageManager.FLAG_STORAGE_DE) != 0) {
            final File[] files = FileUtils.listFilesOrEmpty(deDir);
            for (File file : files) {
                final String packageName = file.getName();
                try {
                    assertPackageKnownAndInstalled(volumeUuid, packageName, userId);
                } catch (PackageManagerException e) {
                    logCriticalInfo(Log.WARN, "Destroying " + file + " due to: " + e);
                    try {
                        mInstaller.destroyAppData(volumeUuid, packageName, userId,
                                StorageManager.FLAG_STORAGE_DE, 0);
                    } catch (InstallerException e2) {
                        logCriticalInfo(Log.WARN, "Failed to destroy: " + e2);
                    }
                }
            }
        }

        // Ensure that data directories are ready to roll for all packages
        // installed for this volume and user
        final List<PackageSetting> packages;
        synchronized (mLock) {
            packages = mSettings.getVolumePackagesLPr(volumeUuid);
        }
        int preparedCount = 0;
        for (PackageSetting ps : packages) {
            final String packageName = ps.name;
            if (ps.pkg == null) {
                Slog.w(TAG, "Odd, missing scanned package " + packageName);
                // TODO: might be due to legacy ASEC apps; we should circle back
                // and reconcile again once they're scanned
                continue;
            }
            // Skip non-core apps if requested
            if (onlyCoreApps && !ps.pkg.isCoreApp()) {
                result.add(packageName);
                continue;
            }

            if (ps.getInstalled(userId)) {
                prepareAppDataAndMigrateLIF(ps.pkg, userId, flags, migrateAppData);
                preparedCount++;
            }
        }

        Slog.v(TAG, "reconcileAppsData finished " + preparedCount + " packages");
        return result;
    }

    /**
     * Prepare app data for the given app just after it was installed or
     * upgraded. This method carefully only touches users that it's installed
     * for, and it forces a restorecon to handle any seinfo changes.
     * <p>
     * Verifies that directories exist and that ownership and labeling is
     * correct for all installed apps. If there is an ownership mismatch, it
     * will try recovering system apps by wiping data; third-party app data is
     * left intact.
     * <p>
     * <em>Note: To avoid a deadlock, do not call this method with {@code mLock} lock held</em>
     */
    private void prepareAppDataAfterInstallLIF(AndroidPackage pkg) {
        final PackageSetting ps;
        synchronized (mLock) {
            ps = mSettings.mPackages.get(pkg.getPackageName());
            mSettings.writeKernelMappingLPr(ps);
        }

        UserManagerInternal umInternal = mInjector.getUserManagerInternal();
        for (UserInfo user : mUserManager.getUsers(false /*excludeDying*/)) {
            final int flags;
            if (umInternal.isUserUnlockingOrUnlocked(user.id)) {
                flags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE;
            } else if (umInternal.isUserRunning(user.id)) {
                flags = StorageManager.FLAG_STORAGE_DE;
            } else {
                continue;
            }

            if (ps.getInstalled(user.id)) {
                // TODO: when user data is locked, mark that we're still dirty
                prepareAppDataLIF(pkg, user.id, flags);
            }
        }
    }

    /**
     * Prepare app data for the given app.
     * <p>
     * Verifies that directories exist and that ownership and labeling is
     * correct for all installed apps. If there is an ownership mismatch, this
     * will try recovering system apps by wiping data; third-party app data is
     * left intact.
     */
    private void prepareAppDataLIF(AndroidPackage pkg, int userId, int flags) {
        if (pkg == null) {
            Slog.wtf(TAG, "Package was null!", new Throwable());
            return;
        }
        prepareAppDataLeafLIF(pkg, userId, flags);
    }

    private void prepareAppDataAndMigrateLIF(AndroidPackage pkg, int userId, int flags,
            boolean maybeMigrateAppData) {
        prepareAppDataLIF(pkg, userId, flags);

        if (maybeMigrateAppData && maybeMigrateAppDataLIF(pkg, userId)) {
            // We may have just shuffled around app data directories, so
            // prepare them one more time
            prepareAppDataLIF(pkg, userId, flags);
        }
    }

    private void prepareAppDataLeafLIF(AndroidPackage pkg, int userId, int flags) {
        if (DEBUG_APP_DATA) {
            Slog.v(TAG, "prepareAppData for " + pkg.getPackageName() + " u" + userId + " 0x"
                    + Integer.toHexString(flags));
        }

        final PackageSetting ps;
        synchronized (mLock) {
            ps = mSettings.mPackages.get(pkg.getPackageName());
        }
        final String volumeUuid = pkg.getVolumeUuid();
        final String packageName = pkg.getPackageName();

        final int appId = UserHandle.getAppId(pkg.getUid());

        Preconditions.checkNotNull(pkg.getSeInfo());

        final String seInfo =
                pkg.getSeInfo() + (pkg.getSeInfoUser() != null ? pkg.getSeInfoUser() : "");
        long ceDataInode = -1;
        try {
            ceDataInode = mInstaller.createAppData(volumeUuid, packageName, userId, flags,
                    appId, seInfo, pkg.getTargetSdkVersion());
        } catch (InstallerException e) {
            if (pkg.isSystemApp()) {
                logCriticalInfo(Log.ERROR, "Failed to create app data for " + packageName
                        + ", but trying to recover: " + e);
                destroyAppDataLeafLIF(pkg, userId, flags);
                try {
                    ceDataInode = mInstaller.createAppData(volumeUuid, packageName, userId, flags,
                            appId, seInfo, pkg.getTargetSdkVersion());
                    logCriticalInfo(Log.DEBUG, "Recovery succeeded!");
                } catch (InstallerException e2) {
                    logCriticalInfo(Log.DEBUG, "Recovery failed!");
                }
            } else {
                Slog.e(TAG, "Failed to create app data for " + packageName + ": " + e);
            }
        }
        // Prepare the application profiles only for upgrades and first boot (so that we don't
        // repeat the same operation at each boot).
        // We only have to cover the upgrade and first boot here because for app installs we
        // prepare the profiles before invoking dexopt (in installPackageLI).
        //
        // We also have to cover non system users because we do not call the usual install package
        // methods for them.
        //
        // NOTE: in order to speed up first boot time we only create the current profile and do not
        // update the content of the reference profile. A system image should already be configured
        // with the right profile keys and the profiles for the speed-profile prebuilds should
        // already be copied. That's done in #performDexOptUpgrade.
        //
        // TODO(calin, mathieuc): We should use .dm files for prebuilds profiles instead of
        // manually copying them in #performDexOptUpgrade. When we do that we should have a more
        // granular check here and only update the existing profiles.
        if (mIsUpgrade || mFirstBoot || (userId != UserHandle.USER_SYSTEM)) {
            mArtManagerService.prepareAppProfiles(pkg, userId,
                /* updateReferenceProfileContent= */ false);
        }

        if ((flags & StorageManager.FLAG_STORAGE_CE) != 0 && ceDataInode != -1) {
            // TODO: mark this structure as dirty so we persist it!
            synchronized (mLock) {
                if (ps != null) {
                    ps.setCeDataInode(ceDataInode, userId);
                }
            }
        }

        prepareAppDataContentsLeafLIF(pkg, userId, flags);
    }

    private void prepareAppDataContentsLIF(AndroidPackage pkg, int userId, int flags) {
        if (pkg == null) {
            Slog.wtf(TAG, "Package was null!", new Throwable());
            return;
        }
        prepareAppDataContentsLeafLIF(pkg, userId, flags);
    }

    private void prepareAppDataContentsLeafLIF(AndroidPackage pkg, int userId, int flags) {
        final String volumeUuid = pkg.getVolumeUuid();
        final String packageName = pkg.getPackageName();

        if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) {
            // Create a native library symlink only if we have native libraries
            // and if the native libraries are 32 bit libraries. We do not provide
            // this symlink for 64 bit libraries.
            if (pkg.getPrimaryCpuAbi() != null && !VMRuntime.is64BitAbi(pkg.getPrimaryCpuAbi())) {
                final String nativeLibPath = pkg.getNativeLibraryDir();
                try {
                    mInstaller.linkNativeLibraryDirectory(volumeUuid, packageName,
                            nativeLibPath, userId);
                } catch (InstallerException e) {
                    Slog.e(TAG, "Failed to link native for " + packageName + ": " + e);
                }
            }
        }
    }

    /**
     * For system apps on non-FBE devices, this method migrates any existing
     * CE/DE data to match the {@code defaultToDeviceProtectedStorage} flag
     * requested by the app.
     */
    private boolean maybeMigrateAppDataLIF(AndroidPackage pkg, int userId) {
        if (pkg.isSystem() && !StorageManager.isFileEncryptedNativeOrEmulated()
                && PackageManager.APPLY_DEFAULT_TO_DEVICE_PROTECTED_STORAGE) {
            final int storageTarget = pkg.isDefaultToDeviceProtectedStorage()
                    ? StorageManager.FLAG_STORAGE_DE : StorageManager.FLAG_STORAGE_CE;
            try {
                mInstaller.migrateAppData(pkg.getVolumeUuid(), pkg.getPackageName(), userId,
                        storageTarget);
            } catch (InstallerException e) {
                logCriticalInfo(Log.WARN,
                        "Failed to migrate " + pkg.getPackageName() + ": " + e.getMessage());
            }
            return true;
        } else {
            return false;
        }
    }

    public PackageFreezer freezePackage(String packageName, String killReason) {
        return freezePackage(packageName, UserHandle.USER_ALL, killReason);
    }

    public PackageFreezer freezePackage(String packageName, int userId, String killReason) {
        return new PackageFreezer(packageName, userId, killReason);
    }

    public PackageFreezer freezePackageForInstall(String packageName, int installFlags,
            String killReason) {
        return freezePackageForInstall(packageName, UserHandle.USER_ALL, installFlags, killReason);
    }

    public PackageFreezer freezePackageForInstall(String packageName, int userId, int installFlags,
            String killReason) {
        if ((installFlags & PackageManager.INSTALL_DONT_KILL_APP) != 0) {
            return new PackageFreezer();
        } else {
            return freezePackage(packageName, userId, killReason);
        }
    }

    public PackageFreezer freezePackageForDelete(String packageName, int deleteFlags,
            String killReason) {
        return freezePackageForDelete(packageName, UserHandle.USER_ALL, deleteFlags, killReason);
    }

    public PackageFreezer freezePackageForDelete(String packageName, int userId, int deleteFlags,
            String killReason) {
        if ((deleteFlags & PackageManager.DELETE_DONT_KILL_APP) != 0) {
            return new PackageFreezer();
        } else {
            return freezePackage(packageName, userId, killReason);
        }
    }

    /**
     * Class that freezes and kills the given package upon creation, and
     * unfreezes it upon closing. This is typically used when doing surgery on
     * app code/data to prevent the app from running while you're working.
     */
    private class PackageFreezer implements AutoCloseable {
        private final String mPackageName;

        private final boolean mWeFroze;

        private final AtomicBoolean mClosed = new AtomicBoolean();
        private final CloseGuard mCloseGuard = CloseGuard.get();

        /**
         * Create and return a stub freezer that doesn't actually do anything,
         * typically used when someone requested
         * {@link PackageManager#INSTALL_DONT_KILL_APP} or
         * {@link PackageManager#DELETE_DONT_KILL_APP}.
         */
        public PackageFreezer() {
            mPackageName = null;
            mWeFroze = false;
            mCloseGuard.open("close");
        }

        public PackageFreezer(String packageName, int userId, String killReason) {
            synchronized (mLock) {
                mPackageName = packageName;
                mWeFroze = mFrozenPackages.add(mPackageName);

                final PackageSetting ps = mSettings.mPackages.get(mPackageName);
                if (ps != null) {
                    killApplication(ps.name, ps.appId, userId, killReason);
                }
            }
            mCloseGuard.open("close");
        }

        @Override
        protected void finalize() throws Throwable {
            try {
                mCloseGuard.warnIfOpen();
                close();
            } finally {
                super.finalize();
            }
        }

        @Override
        public void close() {
            mCloseGuard.close();
            if (mClosed.compareAndSet(false, true)) {
                synchronized (mLock) {
                    if (mWeFroze) {
                        mFrozenPackages.remove(mPackageName);
                    }
                }
            }
        }
    }

    /**
     * Verify that given package is currently frozen.
     */
    private void checkPackageFrozen(String packageName) {
        synchronized (mLock) {
            if (!mFrozenPackages.contains(packageName)) {
                Slog.wtf(TAG, "Expected " + packageName + " to be frozen!", new Throwable());
            }
        }
    }

    @Override
    public int movePackage(final String packageName, final String volumeUuid) {
        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null);

        final int callingUid = Binder.getCallingUid();
        final UserHandle user = new UserHandle(UserHandle.getUserId(callingUid));
        final int moveId = mNextMoveId.getAndIncrement();
        mHandler.post(() -> {
            try {
                movePackageInternal(packageName, volumeUuid, moveId, callingUid, user);
            } catch (PackageManagerException e) {
                Slog.w(TAG, "Failed to move " + packageName, e);
                mMoveCallbacks.notifyStatusChanged(moveId, e.error);
            }
        });
        return moveId;
    }

    private void movePackageInternal(final String packageName, final String volumeUuid,
            final int moveId, final int callingUid, UserHandle user)
                    throws PackageManagerException {
        final StorageManager storage = mInjector.getStorageManager();
        final PackageManager pm = mContext.getPackageManager();

        final String currentVolumeUuid;
        final File codeFile;
        final InstallSource installSource;
        final String packageAbiOverride;
        final int appId;
        final String seinfo;
        final String label;
        final int targetSdkVersion;
        final PackageFreezer freezer;
        final int[] installedUserIds;
        final boolean isCurrentLocationExternal;

        // reader
        synchronized (mLock) {
            final AndroidPackage pkg = mPackages.get(packageName);
            final PackageSetting ps = mSettings.mPackages.get(packageName);
            if (pkg == null
                    || ps == null
                    || shouldFilterApplicationLocked(ps, callingUid, user.getIdentifier())) {
                throw new PackageManagerException(MOVE_FAILED_DOESNT_EXIST, "Missing package");
            }
            if (pkg.isSystemApp()) {
                throw new PackageManagerException(MOVE_FAILED_SYSTEM_PACKAGE,
                        "Cannot move system application");
            }

            final boolean isInternalStorage = VolumeInfo.ID_PRIVATE_INTERNAL.equals(volumeUuid);
            final boolean allow3rdPartyOnInternal = mContext.getResources().getBoolean(
                    com.android.internal.R.bool.config_allow3rdPartyAppOnInternal);
            if (isInternalStorage && !allow3rdPartyOnInternal) {
                throw new PackageManagerException(MOVE_FAILED_3RD_PARTY_NOT_ALLOWED_ON_INTERNAL,
                        "3rd party apps are not allowed on internal storage");
            }

            currentVolumeUuid = ps.volumeUuid;

            final File probe = new File(pkg.getCodePath());
            final File probeOat = new File(probe, "oat");
            if (!probe.isDirectory() || !probeOat.isDirectory()) {
                throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
                        "Move only supported for modern cluster style installs");
            }

            if (Objects.equals(currentVolumeUuid, volumeUuid)) {
                throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
                        "Package already moved to " + volumeUuid);
            }
            if (pkg.isInternal() && isPackageDeviceAdminOnAnyUser(packageName)) {
                throw new PackageManagerException(MOVE_FAILED_DEVICE_ADMIN,
                        "Device admin cannot be moved");
            }

            if (mFrozenPackages.contains(packageName)) {
                throw new PackageManagerException(MOVE_FAILED_OPERATION_PENDING,
                        "Failed to move already frozen package");
            }

            isCurrentLocationExternal = isExternal(pkg);
            codeFile = new File(pkg.getCodePath());
            installSource = ps.installSource;
            packageAbiOverride = ps.cpuAbiOverrideString;
            appId = UserHandle.getAppId(pkg.getUid());
            seinfo = pkg.getSeInfo();
            label = String.valueOf(pm.getApplicationLabel(pkg.toAppInfoWithoutState()));
            targetSdkVersion = pkg.getTargetSdkVersion();
            freezer = freezePackage(packageName, "movePackageInternal");
            installedUserIds = ps.queryInstalledUsers(mUserManager.getUserIds(), true);
        }

        final Bundle extras = new Bundle();
        extras.putString(Intent.EXTRA_PACKAGE_NAME, packageName);
        extras.putString(Intent.EXTRA_TITLE, label);
        mMoveCallbacks.notifyCreated(moveId, extras);

        int installFlags;
        final boolean moveCompleteApp;
        final File measurePath;

        installFlags = INSTALL_INTERNAL;
        if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, volumeUuid)) {
            moveCompleteApp = true;
            measurePath = Environment.getDataAppDirectory(volumeUuid);
        } else if (Objects.equals(StorageManager.UUID_PRIMARY_PHYSICAL, volumeUuid)) {
            moveCompleteApp = false;
            measurePath = storage.getPrimaryPhysicalVolume().getPath();
        } else {
            final VolumeInfo volume = storage.findVolumeByUuid(volumeUuid);
            if (volume == null || volume.getType() != VolumeInfo.TYPE_PRIVATE
                    || !volume.isMountedWritable()) {
                freezer.close();
                throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
                        "Move location not mounted private volume");
            }

            moveCompleteApp = true;
            measurePath = Environment.getDataAppDirectory(volumeUuid);
        }

        // If we're moving app data around, we need all the users unlocked
        if (moveCompleteApp) {
            for (int userId : installedUserIds) {
                if (StorageManager.isFileEncryptedNativeOrEmulated()
                        && !StorageManager.isUserKeyUnlocked(userId)) {
                    throw new PackageManagerException(MOVE_FAILED_LOCKED_USER,
                            "User " + userId + " must be unlocked");
                }
            }
        }

        final PackageStats stats = new PackageStats(null, -1);
        synchronized (mInstaller) {
            for (int userId : installedUserIds) {
                if (!getPackageSizeInfoLI(packageName, userId, stats)) {
                    freezer.close();
                    throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
                            "Failed to measure package size");
                }
            }
        }

        if (DEBUG_INSTALL) Slog.d(TAG, "Measured code size " + stats.codeSize + ", data size "
                + stats.dataSize);

        final long startFreeBytes = measurePath.getUsableSpace();
        final long sizeBytes;
        if (moveCompleteApp) {
            sizeBytes = stats.codeSize + stats.dataSize;
        } else {
            sizeBytes = stats.codeSize;
        }

        if (sizeBytes > storage.getStorageBytesUntilLow(measurePath)) {
            freezer.close();
            throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
                    "Not enough free space to move");
        }

        mMoveCallbacks.notifyStatusChanged(moveId, 10);

        final CountDownLatch installedLatch = new CountDownLatch(1);
        final IPackageInstallObserver2 installObserver = new IPackageInstallObserver2.Stub() {
            @Override
            public void onUserActionRequired(Intent intent) throws RemoteException {
                throw new IllegalStateException();
            }

            @Override
            public void onPackageInstalled(String basePackageName, int returnCode, String msg,
                    Bundle extras) throws RemoteException {
                if (DEBUG_INSTALL) Slog.d(TAG, "Install result for move: "
                        + PackageManager.installStatusToString(returnCode, msg));

                installedLatch.countDown();
                freezer.close();

                final int status = PackageManager.installStatusToPublicStatus(returnCode);
                switch (status) {
                    case PackageInstaller.STATUS_SUCCESS:
                        mMoveCallbacks.notifyStatusChanged(moveId,
                                PackageManager.MOVE_SUCCEEDED);
                        logAppMovedStorage(packageName, isCurrentLocationExternal);
                        break;
                    case PackageInstaller.STATUS_FAILURE_STORAGE:
                        mMoveCallbacks.notifyStatusChanged(moveId,
                                PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE);
                        break;
                    default:
                        mMoveCallbacks.notifyStatusChanged(moveId,
                                PackageManager.MOVE_FAILED_INTERNAL_ERROR);
                        break;
                }
            }
        };

        final MoveInfo move;
        if (moveCompleteApp) {
            // Kick off a thread to report progress estimates
            new Thread(() -> {
                while (true) {
                    try {
                        if (installedLatch.await(1, TimeUnit.SECONDS)) {
                            break;
                        }
                    } catch (InterruptedException ignored) {
                    }

                    final long deltaFreeBytes = startFreeBytes - measurePath.getUsableSpace();
                    final int progress = 10 + (int) MathUtils.constrain(
                            ((deltaFreeBytes * 80) / sizeBytes), 0, 80);
                    mMoveCallbacks.notifyStatusChanged(moveId, progress);
                }
            }).start();

            final String dataAppName = codeFile.getName();
            move = new MoveInfo(moveId, currentVolumeUuid, volumeUuid, packageName,
                    dataAppName, appId, seinfo, targetSdkVersion);
        } else {
            move = null;
        }

        installFlags |= PackageManager.INSTALL_REPLACE_EXISTING;

        final Message msg = mHandler.obtainMessage(INIT_COPY);
        final OriginInfo origin = OriginInfo.fromExistingFile(codeFile);
        final InstallParams params = new InstallParams(origin, move, installObserver, installFlags,
                installSource, volumeUuid, null /*verificationInfo*/, user,
                packageAbiOverride, null /*grantedPermissions*/,
                null /*whitelistedRestrictedPermissions*/, PackageParser.SigningDetails.UNKNOWN,
                PackageManager.INSTALL_REASON_UNKNOWN, PackageManager.VERSION_CODE_HIGHEST);
        params.setTraceMethod("movePackage").setTraceCookie(System.identityHashCode(params));
        msg.obj = params;

        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "movePackage",
                System.identityHashCode(msg.obj));
        Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall",
                System.identityHashCode(msg.obj));

        mHandler.sendMessage(msg);
    }

    /**
     * Logs that an app has been moved from internal to external storage and vice versa.
     * @param packageName The package that was moved.
     */
    private void logAppMovedStorage(String packageName, boolean isPreviousLocationExternal) {
        final AndroidPackage pkg;
        synchronized (mLock) {
            pkg = mPackages.get(packageName);
        }
        if (pkg == null) {
            return;
        }

        final StorageManager storage = mInjector.getStorageManager();;
        VolumeInfo volume = storage.findVolumeByUuid(pkg.getStorageUuid().toString());
        int packageExternalStorageType = getPackageExternalStorageType(volume, isExternal(pkg));

        if (!isPreviousLocationExternal && isExternal(pkg)) {
            // Move from internal to external storage.
            StatsLog.write(StatsLog.APP_MOVED_STORAGE_REPORTED, packageExternalStorageType,
                    StatsLog.APP_MOVED_STORAGE_REPORTED__MOVE_TYPE__TO_EXTERNAL,
                    packageName);
        } else if (isPreviousLocationExternal && !isExternal(pkg)) {
            // Move from external to internal storage.
            StatsLog.write(StatsLog.APP_MOVED_STORAGE_REPORTED, packageExternalStorageType,
                    StatsLog.APP_MOVED_STORAGE_REPORTED__MOVE_TYPE__TO_INTERNAL,
                    packageName);
        }
    }

    @Override
    public int movePrimaryStorage(String volumeUuid) throws RemoteException {
        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MOVE_PACKAGE, null);

        final int realMoveId = mNextMoveId.getAndIncrement();
        final Bundle extras = new Bundle();
        extras.putString(VolumeRecord.EXTRA_FS_UUID, volumeUuid);
        mMoveCallbacks.notifyCreated(realMoveId, extras);

        final IPackageMoveObserver callback = new IPackageMoveObserver.Stub() {
            @Override
            public void onCreated(int moveId, Bundle extras) {
                // Ignored
            }

            @Override
            public void onStatusChanged(int moveId, int status, long estMillis) {
                mMoveCallbacks.notifyStatusChanged(realMoveId, status, estMillis);
            }
        };

        final StorageManager storage = mInjector.getStorageManager();
        storage.setPrimaryStorageUuid(volumeUuid, callback);
        return realMoveId;
    }

    @Override
    public int getMoveStatus(int moveId) {
        mContext.enforceCallingOrSelfPermission(
                android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
        return mMoveCallbacks.mLastStatus.get(moveId);
    }

    @Override
    public void registerMoveCallback(IPackageMoveObserver callback) {
        mContext.enforceCallingOrSelfPermission(
                android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
        mMoveCallbacks.register(callback);
    }

    @Override
    public void unregisterMoveCallback(IPackageMoveObserver callback) {
        mContext.enforceCallingOrSelfPermission(
                android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
        mMoveCallbacks.unregister(callback);
    }

    @Override
    public boolean setInstallLocation(int loc) {
        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS,
                null);
        if (getInstallLocation() == loc) {
            return true;
        }
        if (loc == PackageHelper.APP_INSTALL_AUTO || loc == PackageHelper.APP_INSTALL_INTERNAL
                || loc == PackageHelper.APP_INSTALL_EXTERNAL) {
            android.provider.Settings.Global.putInt(mContext.getContentResolver(),
                    android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION, loc);
            return true;
        }
        return false;
   }

    @Override
    public int getInstallLocation() {
        // allow instant app access
        return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
                android.provider.Settings.Global.DEFAULT_INSTALL_LOCATION,
                PackageHelper.APP_INSTALL_AUTO);
    }

    /** Called by UserManagerService */
    void cleanUpUser(UserManagerService userManager, @UserIdInt int userId) {
        synchronized (mLock) {
            mDirtyUsers.remove(userId);
            mUserNeedsBadging.delete(userId);
            mSettings.removeUserLPw(userId);
            mPendingBroadcasts.remove(userId);
            mInstantAppRegistry.onUserRemovedLPw(userId);
            removeUnusedPackagesLPw(userManager, userId);
        }
    }

    /**
     * We're removing userId and would like to remove any downloaded packages
     * that are no longer in use by any other user.
     * @param userId the user being removed
     */
    @GuardedBy("mLock")
    private void removeUnusedPackagesLPw(UserManagerService userManager, final int userId) {
        final boolean DEBUG_CLEAN_APKS = false;
        int [] users = userManager.getUserIds();
        Iterator<PackageSetting> psit = mSettings.mPackages.values().iterator();
        while (psit.hasNext()) {
            PackageSetting ps = psit.next();
            if (ps.pkg == null) {
                continue;
            }
            final String packageName = ps.pkg.getPackageName();
            // Skip over if system app or static shared library
            if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0
                    || !TextUtils.isEmpty(ps.pkg.getStaticSharedLibName())) {
                continue;
            }
            if (DEBUG_CLEAN_APKS) {
                Slog.i(TAG, "Checking package " + packageName);
            }
            boolean keep = shouldKeepUninstalledPackageLPr(packageName);
            if (keep) {
                if (DEBUG_CLEAN_APKS) {
                    Slog.i(TAG, "  Keeping package " + packageName + " - requested by DO");
                }
            } else {
                for (int i = 0; i < users.length; i++) {
                    if (users[i] != userId && ps.getInstalled(users[i])) {
                        keep = true;
                        if (DEBUG_CLEAN_APKS) {
                            Slog.i(TAG, "  Keeping package " + packageName + " for user "
                                    + users[i]);
                        }
                        break;
                    }
                }
            }
            if (!keep) {
                if (DEBUG_CLEAN_APKS) {
                    Slog.i(TAG, "  Removing package " + packageName);
                }
                //end run
                mHandler.post(() -> deletePackageX(packageName, PackageManager.VERSION_CODE_HIGHEST,
                        userId, 0));
            }
        }
    }

    /**
     * Called by UserManagerService.
     *
     * @param installablePackages system packages that should be initially installed for this user,
     *                            or {@code null} if all system packages should be installed
     * @param disallowedPackages packages that should not be initially installed. Takes precedence
     *                           over installablePackages.
     */
    void createNewUser(int userId, @Nullable Set<String> installablePackages,
            String[] disallowedPackages) {
        synchronized (mInstallLock) {
            mSettings.createNewUserLI(this, mInstaller, userId,
                    installablePackages, disallowedPackages);
        }
        synchronized (mLock) {
            scheduleWritePackageRestrictionsLocked(userId);
            scheduleWritePackageListLocked(userId);
            primeDomainVerificationsLPw(userId);
        }
    }

    void onNewUserCreated(final int userId) {
        mPermissionManager.onNewUserCreated(userId);
    }

    @Override
    public VerifierDeviceIdentity getVerifierDeviceIdentity() throws RemoteException {
        mContext.enforceCallingOrSelfPermission(
                android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
                "Only package verification agents can read the verifier device identity");

        synchronized (mLock) {
            return mSettings.getVerifierDeviceIdentityLPw();
        }
    }

    @Override
    public boolean isStorageLow() {
        // allow instant applications
        final long token = Binder.clearCallingIdentity();
        try {
            final DeviceStorageMonitorInternal
                    dsm = mInjector.getDeviceStorageMonitorInternal();
            if (dsm != null) {
                return dsm.isMemoryLow();
            } else {
                return false;
            }
        } finally {
            Binder.restoreCallingIdentity(token);
        }
    }

    @Override
    public IPackageInstaller getPackageInstaller() {
        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
            return null;
        }
        return mInstallerService;
    }

    @Override
    public IArtManager getArtManager() {
        return mArtManagerService;
    }

    private boolean userNeedsBadging(int userId) {
        int index = mUserNeedsBadging.indexOfKey(userId);
        if (index < 0) {
            final UserInfo userInfo;
            final long token = Binder.clearCallingIdentity();
            try {
                userInfo = mUserManager.getUserInfo(userId);
            } finally {
                Binder.restoreCallingIdentity(token);
            }
            final boolean b;
            if (userInfo != null && userInfo.isManagedProfile()) {
                b = true;
            } else {
                b = false;
            }
            mUserNeedsBadging.put(userId, b);
            return b;
        }
        return mUserNeedsBadging.valueAt(index);
    }

    @Override
    public KeySet getKeySetByAlias(String packageName, String alias) {
        if (packageName == null || alias == null) {
            return null;
        }
        synchronized(mLock) {
            final AndroidPackage pkg = mPackages.get(packageName);
            if (pkg == null) {
                Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
                throw new IllegalArgumentException("Unknown package: " + packageName);
            }
            final PackageSetting ps = getPackageSetting(pkg.getPackageName());
            if (shouldFilterApplicationLocked(
                    ps, Binder.getCallingUid(), UserHandle.getCallingUserId())) {
                Slog.w(TAG, "KeySet requested for filtered package: " + packageName);
                throw new IllegalArgumentException("Unknown package: " + packageName);
            }
            final KeySetManagerService ksms = mSettings.mKeySetManagerService;
            return new KeySet(ksms.getKeySetByAliasAndPackageNameLPr(packageName, alias));
        }
    }

    @Override
    public KeySet getSigningKeySet(String packageName) {
        if (packageName == null) {
            return null;
        }
        synchronized (mLock) {
            final int callingUid = Binder.getCallingUid();
            final int callingUserId = UserHandle.getUserId(callingUid);
            final AndroidPackage pkg = mPackages.get(packageName);
            if (pkg == null) {
                Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
                throw new IllegalArgumentException("Unknown package: " + packageName);
            }
            final PackageSetting ps = getPackageSetting(pkg.getPackageName());
            if (shouldFilterApplicationLocked(ps, callingUid, callingUserId)) {
                // filter and pretend the package doesn't exist
                Slog.w(TAG, "KeySet requested for filtered package: " + packageName
                        + ", uid:" + callingUid);
                throw new IllegalArgumentException("Unknown package: " + packageName);
            }
            if (pkg.getUid() != callingUid
                    && Process.SYSTEM_UID != callingUid) {
                throw new SecurityException("May not access signing KeySet of other apps.");
            }
            final KeySetManagerService ksms = mSettings.mKeySetManagerService;
            return new KeySet(ksms.getSigningKeySetByPackageNameLPr(packageName));
        }
    }

    @Override
    public boolean isPackageSignedByKeySet(String packageName, KeySet ks) {
        final int callingUid = Binder.getCallingUid();
        if (getInstantAppPackageName(callingUid) != null) {
            return false;
        }
        if (packageName == null || ks == null) {
            return false;
        }
        synchronized(mLock) {
            final AndroidPackage pkg = mPackages.get(packageName);
            if (pkg == null
                    || shouldFilterApplicationLocked(getPackageSetting(pkg.getPackageName()),
                    callingUid, UserHandle.getUserId(callingUid))) {
                Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
                throw new IllegalArgumentException("Unknown package: " + packageName);
            }
            IBinder ksh = ks.getToken();
            if (ksh instanceof KeySetHandle) {
                final KeySetManagerService ksms = mSettings.mKeySetManagerService;
                return ksms.packageIsSignedByLPr(packageName, (KeySetHandle) ksh);
            }
            return false;
        }
    }

    @Override
    public boolean isPackageSignedByKeySetExactly(String packageName, KeySet ks) {
        final int callingUid = Binder.getCallingUid();
        if (getInstantAppPackageName(callingUid) != null) {
            return false;
        }
        if (packageName == null || ks == null) {
            return false;
        }
        synchronized (mLock) {
            final AndroidPackage pkg = mPackages.get(packageName);
            if (pkg == null
                    || shouldFilterApplicationLocked(getPackageSetting(pkg.getPackageName()),
                    callingUid, UserHandle.getUserId(callingUid))) {
                Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
                throw new IllegalArgumentException("Unknown package: " + packageName);
            }
            IBinder ksh = ks.getToken();
            if (ksh instanceof KeySetHandle) {
                final KeySetManagerService ksms = mSettings.mKeySetManagerService;
                return ksms.packageIsSignedByExactlyLPr(packageName, (KeySetHandle) ksh);
            }
            return false;
        }
    }

    @GuardedBy("mLock")
    private void deletePackageIfUnusedLPr(final String packageName) {
        PackageSetting ps = mSettings.mPackages.get(packageName);
        if (ps == null) {
            return;
        }
        if (!ps.isAnyInstalled(mUserManager.getUserIds())) {
            // TODO Implement atomic delete if package is unused
            // It is currently possible that the package will be deleted even if it is installed
            // after this method returns.
            mHandler.post(() -> deletePackageX(packageName, PackageManager.VERSION_CODE_HIGHEST,
                    0, PackageManager.DELETE_ALL_USERS));
        }
    }

    /**
     * Check and throw if the given before/after packages would be considered a
     * downgrade.
     */
    private static void checkDowngrade(AndroidPackage before, PackageInfoLite after)
            throws PackageManagerException {
        if (after.getLongVersionCode() < before.getLongVersionCode()) {
            throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
                    "Update version code " + after.versionCode + " is older than current "
                    + before.getLongVersionCode());
        } else if (after.getLongVersionCode() == before.getLongVersionCode()) {
            if (after.baseRevisionCode < before.getBaseRevisionCode()) {
                throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
                        "Update base revision code " + after.baseRevisionCode
                        + " is older than current " + before.getBaseRevisionCode());
            }

            if (!ArrayUtils.isEmpty(after.splitNames)) {
                for (int i = 0; i < after.splitNames.length; i++) {
                    final String splitName = after.splitNames[i];
                    final int j = ArrayUtils.indexOf(before.getSplitNames(), splitName);
                    if (j != -1) {
                        if (after.splitRevisionCodes[i] < before.getSplitRevisionCodes()[j]) {
                            throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
                                    "Update split " + splitName + " revision code "
                                    + after.splitRevisionCodes[i] + " is older than current "
                                    + before.getSplitRevisionCodes()[j]);
                        }
                    }
                }
            }
        }
    }

    private static class MoveCallbacks extends Handler {
        private static final int MSG_CREATED = 1;
        private static final int MSG_STATUS_CHANGED = 2;

        private final RemoteCallbackList<IPackageMoveObserver>
                mCallbacks = new RemoteCallbackList<>();

        private final SparseIntArray mLastStatus = new SparseIntArray();

        public MoveCallbacks(Looper looper) {
            super(looper);
        }

        public void register(IPackageMoveObserver callback) {
            mCallbacks.register(callback);
        }

        public void unregister(IPackageMoveObserver callback) {
            mCallbacks.unregister(callback);
        }

        @Override
        public void handleMessage(Message msg) {
            final SomeArgs args = (SomeArgs) msg.obj;
            final int n = mCallbacks.beginBroadcast();
            for (int i = 0; i < n; i++) {
                final IPackageMoveObserver callback = mCallbacks.getBroadcastItem(i);
                try {
                    invokeCallback(callback, msg.what, args);
                } catch (RemoteException ignored) {
                }
            }
            mCallbacks.finishBroadcast();
            args.recycle();
        }

        private void invokeCallback(IPackageMoveObserver callback, int what, SomeArgs args)
                throws RemoteException {
            switch (what) {
                case MSG_CREATED: {
                    callback.onCreated(args.argi1, (Bundle) args.arg2);
                    break;
                }
                case MSG_STATUS_CHANGED: {
                    callback.onStatusChanged(args.argi1, args.argi2, (long) args.arg3);
                    break;
                }
            }
        }

        private void notifyCreated(int moveId, Bundle extras) {
            Slog.v(TAG, "Move " + moveId + " created " + extras.toString());

            final SomeArgs args = SomeArgs.obtain();
            args.argi1 = moveId;
            args.arg2 = extras;
            obtainMessage(MSG_CREATED, args).sendToTarget();
        }

        private void notifyStatusChanged(int moveId, int status) {
            notifyStatusChanged(moveId, status, -1);
        }

        private void notifyStatusChanged(int moveId, int status, long estMillis) {
            Slog.v(TAG, "Move " + moveId + " status " + status);

            final SomeArgs args = SomeArgs.obtain();
            args.argi1 = moveId;
            args.argi2 = status;
            args.arg3 = estMillis;
            obtainMessage(MSG_STATUS_CHANGED, args).sendToTarget();

            synchronized (mLastStatus) {
                mLastStatus.put(moveId, status);
            }
        }
    }

    private class PackageManagerNative extends IPackageManagerNative.Stub {
        @Override
        public String[] getNamesForUids(int[] uids) throws RemoteException {
            final String[] results = PackageManagerService.this.getNamesForUids(uids);
            // massage results so they can be parsed by the native binder
            for (int i = results.length - 1; i >= 0; --i) {
                if (results[i] == null) {
                    results[i] = "";
                }
            }
            return results;
        }

        // NB: this differentiates between preloads and sideloads
        @Override
        public String getInstallerForPackage(String packageName) throws RemoteException {
            final String installerName = getInstallerPackageName(packageName);
            if (!TextUtils.isEmpty(installerName)) {
                return installerName;
            }
            // differentiate between preload and sideload
            int callingUser = UserHandle.getUserId(Binder.getCallingUid());
            ApplicationInfo appInfo = getApplicationInfo(packageName,
                                    /*flags*/ 0,
                                    /*userId*/ callingUser);
            if (appInfo != null && (appInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
                return "preload";
            }
            return "";
        }

        @Override
        public long getVersionCodeForPackage(String packageName) throws RemoteException {
            try {
                int callingUser = UserHandle.getUserId(Binder.getCallingUid());
                PackageInfo pInfo = getPackageInfo(packageName, 0, callingUser);
                if (pInfo != null) {
                    return pInfo.getLongVersionCode();
                }
            } catch (Exception e) {
            }
            return 0;
        }

        @Override
        public int getTargetSdkVersionForPackage(String packageName)
                throws RemoteException {
            int callingUser = UserHandle.getUserId(Binder.getCallingUid());
            ApplicationInfo info = getApplicationInfo(packageName, 0, callingUser);
            if (info == null) {
                throw new RemoteException(
                        "Couldn't get ApplicationInfo for package " + packageName);
            }
            return info.targetSdkVersion;
        }

        @Override
        public boolean[] isAudioPlaybackCaptureAllowed(String[] packageNames)
                throws RemoteException {
            int callingUser = UserHandle.getUserId(Binder.getCallingUid());
            boolean[] results = new boolean[packageNames.length];
            for (int i = results.length - 1; i >= 0; --i) {
                ApplicationInfo appInfo = getApplicationInfo(packageNames[i], 0, callingUser);
                results[i] = appInfo == null ? false : appInfo.isAudioPlaybackCaptureAllowed();
            }
            return results;
        }

        @Override
        public int getLocationFlags(String packageName) throws RemoteException {
            int callingUser = UserHandle.getUserId(Binder.getCallingUid());
            ApplicationInfo appInfo = getApplicationInfo(packageName,
                    /*flags*/ 0,
                    /*userId*/ callingUser);
            if (appInfo == null) {
                throw new RemoteException(
                        "Couldn't get ApplicationInfo for package " + packageName);
            }
            return ((appInfo.isSystemApp() ? IPackageManagerNative.LOCATION_SYSTEM : 0)
                    | (appInfo.isVendor() ? IPackageManagerNative.LOCATION_VENDOR : 0)
                    | (appInfo.isProduct() ? IPackageManagerNative.LOCATION_PRODUCT : 0));
        }

        @Override
        public String getModuleMetadataPackageName() throws RemoteException {
            return PackageManagerService.this.mModuleInfoProvider.getPackageName();
        }
    }

    private class PackageManagerInternalImpl extends PackageManagerInternal {
        @Override
        public List<ApplicationInfo> getInstalledApplications(int flags, int userId,
                int callingUid) {
            return PackageManagerService.this.getInstalledApplicationsListInternal(flags, userId,
                    callingUid);
        }


        @Override
        public boolean isPlatformSigned(String packageName) {
            PackageSetting packageSetting = mSettings.mPackages.get(packageName);
            if (packageSetting == null) {
                return false;
            }
            AndroidPackage pkg = packageSetting.pkg;
            if (pkg == null) {
                // May happen if package in on a removable sd card
                return false;
            }
            return pkg.getSigningDetails().hasAncestorOrSelf(mPlatformPackage.getSigningDetails())
                    || mPlatformPackage.getSigningDetails().checkCapability(pkg.getSigningDetails(),
                    PackageParser.SigningDetails.CertCapabilities.PERMISSION);
        }

        @Override
        public boolean isDataRestoreSafe(byte[] restoringFromSigHash, String packageName) {
            SigningDetails sd = getSigningDetails(packageName);
            if (sd == null) {
                return false;
            }
            return sd.hasSha256Certificate(restoringFromSigHash,
                    SigningDetails.CertCapabilities.INSTALLED_DATA);
        }

        @Override
        public boolean isDataRestoreSafe(Signature restoringFromSig, String packageName) {
            SigningDetails sd = getSigningDetails(packageName);
            if (sd == null) {
                return false;
            }
            return sd.hasCertificate(restoringFromSig,
                    SigningDetails.CertCapabilities.INSTALLED_DATA);
        }

        @Override
        public boolean hasSignatureCapability(int serverUid, int clientUid,
                @SigningDetails.CertCapabilities int capability) {
            SigningDetails serverSigningDetails = getSigningDetails(serverUid);
            SigningDetails clientSigningDetails = getSigningDetails(clientUid);
            return serverSigningDetails.checkCapability(clientSigningDetails, capability)
                    || clientSigningDetails.hasAncestorOrSelf(serverSigningDetails);

        }

        private SigningDetails getSigningDetails(@NonNull String packageName) {
            synchronized (mLock) {
                AndroidPackage p = mPackages.get(packageName);
                if (p == null) {
                    return null;
                }
                return p.getSigningDetails();
            }
        }

        private SigningDetails getSigningDetails(int uid) {
            synchronized (mLock) {
                final int appId = UserHandle.getAppId(uid);
                final Object obj = mSettings.getSettingLPr(appId);
                if (obj != null) {
                    if (obj instanceof SharedUserSetting) {
                        return ((SharedUserSetting) obj).signatures.mSigningDetails;
                    } else if (obj instanceof PackageSetting) {
                        final PackageSetting ps = (PackageSetting) obj;
                        return ps.signatures.mSigningDetails;
                    }
                }
                return SigningDetails.UNKNOWN;
            }
        }

        @Override
        public boolean isInstantApp(String packageName, int userId) {
            return PackageManagerService.this.isInstantApp(packageName, userId);
        }

        @Override
        public String getInstantAppPackageName(int uid) {
            return PackageManagerService.this.getInstantAppPackageName(uid);
        }

        @Override
        public boolean filterAppAccess(AndroidPackage pkg, int callingUid, int userId) {
            synchronized (mLock) {
                PackageSetting ps = getPackageSetting(pkg.getPackageName());
                return PackageManagerService.this.shouldFilterApplicationLocked(ps, callingUid,
                        userId);
            }
        }

        @Override
        public boolean filterAppAccess(String packageName, int callingUid, int userId) {
            synchronized (mLock) {
                PackageSetting ps = getPackageSetting(packageName);
                return PackageManagerService.this.shouldFilterApplicationLocked(ps, callingUid,
                        userId);
            }
        }

        @Override
        public AndroidPackage getPackage(String packageName) {
            synchronized (mLock) {
                packageName = resolveInternalPackageNameLPr(
                        packageName, PackageManager.VERSION_CODE_HIGHEST);
                return mPackages.get(packageName);
            }
        }

        @Override
        public AndroidPackage getPackage(int uid) {
            synchronized (mLock) {
                final String[] packageNames = getPackagesForUid(uid);
                AndroidPackage pkg = null;
                final int numPackages = packageNames == null ? 0 : packageNames.length;
                for (int i = 0; pkg == null && i < numPackages; i++) {
                    pkg = mPackages.get(packageNames[i]);
                }
                return pkg;
            }
        }

        @Nullable
        @Override
        public PackageSetting getPackageSetting(String packageName) {
            return PackageManagerService.this.getPackageSetting(packageName);
        }

        @Override
        public PackageList getPackageList(PackageListObserver observer) {
            synchronized (mLock) {
                final int N = mPackages.size();
                final ArrayList<String> list = new ArrayList<>(N);
                for (int i = 0; i < N; i++) {
                    list.add(mPackages.keyAt(i));
                }
                final PackageList packageList = new PackageList(list, observer);
                if (observer != null) {
                    mPackageListObservers.add(packageList);
                }
                return packageList;
            }
        }

        @Override
        public void removePackageListObserver(PackageListObserver observer) {
            synchronized (mLock) {
                mPackageListObservers.remove(observer);
            }
        }

        @Override
        public Object getDisabledSystemPackage(@NonNull String packageName) {
            synchronized (mLock) {
                return mSettings.getDisabledSystemPkgLPr(packageName);
            }
        }

        @Override
        public @Nullable
        String getDisabledSystemPackageName(@NonNull String packageName) {
            PackageSetting disabledPkgSetting = (PackageSetting) getDisabledSystemPackage(
                    packageName);
            AndroidPackage disabledPkg = disabledPkgSetting == null ? null : disabledPkgSetting.pkg;
            return disabledPkg == null ? null : disabledPkg.getPackageName();
        }

        /**
         * Only keep package names that refer to {@link PackageParser.Package#isSystem system}
         * packages.
         *
         * @param pkgNames The packages to filter
         *
         * @return The filtered packages
         */
        private @NonNull String[] filterOnlySystemPackages(@Nullable String... pkgNames) {
            if (pkgNames == null) {
                return ArrayUtils.emptyArray(String.class);
            }

            ArrayList<String> systemPackageNames = new ArrayList<>(pkgNames.length);

            for (String pkgName: pkgNames) {
                synchronized (mPackages) {
                    if (pkgName == null) {
                        continue;
                    }

                    AndroidPackage pkg = getPackage(pkgName);
                    if (pkg == null) {
                        Log.w(TAG, "Could not find package " + pkgName);
                        continue;
                    }

                    if (!pkg.isSystem()) {
                        Log.w(TAG, pkgName + " is not system");
                        continue;
                    }

                    systemPackageNames.add(pkgName);
                }
            }

            return systemPackageNames.toArray(new String[]{});
        }

        @Override
        public @NonNull String[] getKnownPackageNames(int knownPackage, int userId) {
            switch (knownPackage) {
                case PackageManagerInternal.PACKAGE_BROWSER:
                    return new String[]{mPermissionManager.getDefaultBrowser(userId)};
                case PackageManagerInternal.PACKAGE_INSTALLER:
                    return filterOnlySystemPackages(mRequiredInstallerPackage);
                case PackageManagerInternal.PACKAGE_SETUP_WIZARD:
                    return filterOnlySystemPackages(mSetupWizardPackage);
                case PackageManagerInternal.PACKAGE_SYSTEM:
                    return new String[]{"android"};
                case PackageManagerInternal.PACKAGE_VERIFIER:
                    return filterOnlySystemPackages(mRequiredVerifierPackage);
                case PackageManagerInternal.PACKAGE_SYSTEM_TEXT_CLASSIFIER:
                    return filterOnlySystemPackages(mSystemTextClassifierPackage);
                case PackageManagerInternal.PACKAGE_PERMISSION_CONTROLLER:
                    return filterOnlySystemPackages(mRequiredPermissionControllerPackage);
                case PackageManagerInternal.PACKAGE_WELLBEING:
                    return filterOnlySystemPackages(mWellbeingPackage);
                case PackageManagerInternal.PACKAGE_DOCUMENTER:
                    return filterOnlySystemPackages(mDocumenterPackage);
                case PackageManagerInternal.PACKAGE_CONFIGURATOR:
                    return filterOnlySystemPackages(mConfiguratorPackage);
                case PackageManagerInternal.PACKAGE_INCIDENT_REPORT_APPROVER:
                    return filterOnlySystemPackages(mIncidentReportApproverPackage);
                case PackageManagerInternal.PACKAGE_APP_PREDICTOR:
                    return filterOnlySystemPackages(mAppPredictionServicePackage);
                case PackageManagerInternal.PACKAGE_TELEPHONY:
                    return filterOnlySystemPackages(mTelephonyPackages);
                default:
                    return ArrayUtils.emptyArray(String.class);
            }
        }

        @Override
        public boolean isResolveActivityComponent(ComponentInfo component) {
            return mResolveActivity.packageName.equals(component.packageName)
                    && mResolveActivity.name.equals(component.name);
        }

        @Override
        public void setKeepUninstalledPackages(final List<String> packageList) {
            Preconditions.checkNotNull(packageList);
            List<String> removedFromList = null;
            synchronized (mLock) {
                if (mKeepUninstalledPackages != null) {
                    final int packagesCount = mKeepUninstalledPackages.size();
                    for (int i = 0; i < packagesCount; i++) {
                        String oldPackage = mKeepUninstalledPackages.get(i);
                        if (packageList != null && packageList.contains(oldPackage)) {
                            continue;
                        }
                        if (removedFromList == null) {
                            removedFromList = new ArrayList<>();
                        }
                        removedFromList.add(oldPackage);
                    }
                }
                mKeepUninstalledPackages = new ArrayList<>(packageList);
                if (removedFromList != null) {
                    final int removedCount = removedFromList.size();
                    for (int i = 0; i < removedCount; i++) {
                        deletePackageIfUnusedLPr(removedFromList.get(i));
                    }
                }
            }
        }

        @Override
        public boolean isPermissionsReviewRequired(String packageName, int userId) {
            synchronized (mLock) {
                final AndroidPackage pkg = mPackages.get(packageName);
                if (pkg == null) {
                    return false;
                }

                return mPermissionManager.isPermissionsReviewRequired(pkg, userId);
            }
        }

        @Override
        public PackageInfo getPackageInfo(
                String packageName, int flags, int filterCallingUid, int userId) {
            return PackageManagerService.this
                    .getPackageInfoInternal(packageName, PackageManager.VERSION_CODE_HIGHEST,
                            flags, filterCallingUid, userId);
        }

        @Override
        public Bundle getSuspendedPackageLauncherExtras(String packageName, int userId) {
            synchronized (mLock) {
                final PackageSetting ps = mSettings.mPackages.get(packageName);
                final Bundle allExtras = new Bundle();
                if (ps != null) {
                    final PackageUserState pus = ps.readUserState(userId);
                    if (pus.suspended) {
                        for (int i = 0; i < pus.suspendParams.size(); i++) {
                            final PackageUserState.SuspendParams params =
                                    pus.suspendParams.valueAt(i);
                            if (params != null && params.launcherExtras != null) {
                                allExtras.putAll(params.launcherExtras);
                            }
                        }
                    }

                }
                return (allExtras.size() > 0) ? allExtras : null;
            }
        }

        @Override
        public boolean isPackageSuspended(String packageName, int userId) {
            synchronized (mLock) {
                final PackageSetting ps = mSettings.mPackages.get(packageName);
                return (ps != null) ? ps.getSuspended(userId) : false;
            }
        }

        @Override
        public String getSuspendingPackage(String suspendedPackage, int userId) {
            synchronized (mLock) {
                final PackageSetting ps = mSettings.mPackages.get(suspendedPackage);
                if (ps != null) {
                    final PackageUserState pus = ps.readUserState(userId);
                    if (pus.suspended) {
                        String suspendingPackage = null;
                        for (int i = 0; i < pus.suspendParams.size(); i++) {
                            suspendingPackage = pus.suspendParams.keyAt(i);
                            if (PLATFORM_PACKAGE_NAME.equals(suspendingPackage)) {
                                return suspendingPackage;
                            }
                        }
                        return suspendingPackage;
                    }
                }
                return null;
            }
        }

        @Override
        public SuspendDialogInfo getSuspendedDialogInfo(String suspendedPackage,
                String suspendingPackage, int userId) {
            synchronized (mLock) {
                final PackageSetting ps = mSettings.mPackages.get(suspendedPackage);
                if (ps != null) {
                    final PackageUserState pus = ps.readUserState(userId);
                    if (pus.suspended) {
                        final PackageUserState.SuspendParams suspendParams =
                                pus.suspendParams.get(suspendingPackage);
                        return (suspendParams != null) ? suspendParams.dialogInfo : null;
                    }
                }
            }
            return null;
        }

        @Override
        public int getDistractingPackageRestrictions(String packageName, int userId) {
            synchronized (mLock) {
                final PackageSetting ps = mSettings.mPackages.get(packageName);
                return (ps != null) ? ps.getDistractionFlags(userId) : RESTRICTION_NONE;
            }
        }

        @Override
        public int getPackageUid(String packageName, int flags, int userId) {
            return PackageManagerService.this
                    .getPackageUid(packageName, flags, userId);
        }

        @Override
        public ApplicationInfo getApplicationInfo(
                String packageName, int flags, int filterCallingUid, int userId) {
            return PackageManagerService.this
                    .getApplicationInfoInternal(packageName, flags, filterCallingUid, userId);
        }

        @Override
        public ActivityInfo getActivityInfo(
                ComponentName component, int flags, int filterCallingUid, int userId) {
            return PackageManagerService.this
                    .getActivityInfoInternal(component, flags, filterCallingUid, userId);
        }

        @Override
        public List<ResolveInfo> queryIntentActivities(
                Intent intent, String resolvedType, int flags, int filterCallingUid, int userId) {
            return PackageManagerService.this
                    .queryIntentActivitiesInternal(intent, resolvedType, flags, filterCallingUid,
                            userId, false /*resolveForStart*/, true /*allowDynamicSplits*/);
        }

        @Override
        public List<ResolveInfo> queryIntentServices(
                Intent intent, int flags, int callingUid, int userId) {
            final String resolvedType = intent.resolveTypeIfNeeded(mContext.getContentResolver());
            return PackageManagerService.this
                    .queryIntentServicesInternal(intent, resolvedType, flags, userId, callingUid,
                            false);
        }

        @Override
        public ComponentName getHomeActivitiesAsUser(List<ResolveInfo> allHomeCandidates,
                int userId) {
            return PackageManagerService.this.getHomeActivitiesAsUser(allHomeCandidates, userId);
        }

        @Override
        public ComponentName getDefaultHomeActivity(int userId) {
            return PackageManagerService.this.getDefaultHomeActivity(userId);
        }

        @Override
        public void setDeviceAndProfileOwnerPackages(
                int deviceOwnerUserId, String deviceOwnerPackage,
                SparseArray<String> profileOwnerPackages) {
            mProtectedPackages.setDeviceAndProfileOwnerPackages(
                    deviceOwnerUserId, deviceOwnerPackage, profileOwnerPackages);

            final ArraySet<Integer> usersWithPoOrDo = new ArraySet<>();
            if (deviceOwnerPackage != null) {
                usersWithPoOrDo.add(deviceOwnerUserId);
            }
            final int sz = profileOwnerPackages.size();
            for (int i = 0; i < sz; i++) {
                if (profileOwnerPackages.valueAt(i) != null) {
                    usersWithPoOrDo.add(profileOwnerPackages.keyAt(i));
                }
            }
        }

        @Override
        public boolean isPackageDataProtected(int userId, String packageName) {
            return mProtectedPackages.isPackageDataProtected(userId, packageName);
        }

        @Override
        public boolean isPackageStateProtected(String packageName, int userId) {
            return mProtectedPackages.isPackageStateProtected(userId, packageName);
        }

        @Override
        public boolean isPackageEphemeral(int userId, String packageName) {
            synchronized (mLock) {
                final PackageSetting ps = mSettings.mPackages.get(packageName);
                return ps != null ? ps.getInstantApp(userId) : false;
            }
        }

        @Override
        public boolean wasPackageEverLaunched(String packageName, int userId) {
            synchronized (mLock) {
                return mSettings.wasPackageEverLaunchedLPr(packageName, userId);
            }
        }

        @Override
        public boolean isEnabledAndMatches(ParsedComponent component, int flags, int userId) {
            synchronized (mLock) {
                AndroidPackage pkg = getPackage(component.getPackageName());
                return mSettings.isEnabledAndMatchLPr(pkg, component, flags, userId);
            }
        }

        @Override
        public boolean userNeedsBadging(int userId) {
            synchronized (mLock) {
                return PackageManagerService.this.userNeedsBadging(userId);
            }
        }

        @Override
        public String getNameForUid(int uid) {
            return PackageManagerService.this.getNameForUid(uid);
        }

        @Override
        public boolean setInstalled(AndroidPackage pkg, @UserIdInt int userId,
                boolean installed) {
            synchronized (mLock) {
                final PackageSetting ps = mSettings.mPackages.get(pkg.getPackageName());
                if (ps.getInstalled(userId) != installed) {
                    ps.setInstalled(installed, userId);
                    return true;
                }
                return false;
            }
        }

        @Override
        public void requestInstantAppResolutionPhaseTwo(AuxiliaryResolveInfo responseObj,
                Intent origIntent, String resolvedType, String callingPackage,
                Bundle verificationBundle, int userId) {
            PackageManagerService.this.requestInstantAppResolutionPhaseTwo(
                    responseObj, origIntent, resolvedType, callingPackage, verificationBundle,
                    userId);
        }

        @Override
        public void grantImplicitAccess(int userId, Intent intent,
                int callingUid, int targetAppId) {
            synchronized (mLock) {
                final AndroidPackage callingPackage = getPackage(callingUid);
                final int targetUid = UserHandle.getUid(userId, targetAppId);
                final AndroidPackage targetPackage = getPackage(targetUid);
                if (callingPackage == null || targetPackage == null) {
                    return;
                }

                final boolean instantApp = isInstantAppInternal(callingPackage.getPackageName(),
                        userId, callingUid);
                if (instantApp) {
                    mInstantAppRegistry.grantInstantAccessLPw(userId, intent,
                            UserHandle.getAppId(callingUid), targetAppId);
                } else {
                    mAppsFilter.grantImplicitAccess(callingUid, targetUid);
                }
            }
        }

        @Override
        public boolean isInstantAppInstallerComponent(ComponentName component) {
            synchronized (mLock) {
                return mInstantAppInstallerActivity != null
                        && mInstantAppInstallerActivity.getComponentName().equals(component);
            }
        }

        @Override
        public void pruneInstantApps() {
            mInstantAppRegistry.pruneInstantApps();
        }

        @Override
        public String getSetupWizardPackageName() {
            return mSetupWizardPackage;
        }

        public void setExternalSourcesPolicy(ExternalSourcesPolicy policy) {
            if (policy != null) {
                mExternalSourcesPolicy = policy;
            }
        }

        @Override
        public boolean isPackagePersistent(String packageName) {
            synchronized (mLock) {
                AndroidPackage pkg = mPackages.get(packageName);
                return pkg != null
                        ? ((pkg.getFlags() & (ApplicationInfo.FLAG_SYSTEM
                                        | ApplicationInfo.FLAG_PERSISTENT)) ==
                                (ApplicationInfo.FLAG_SYSTEM | ApplicationInfo.FLAG_PERSISTENT))
                        : false;
            }
        }

        @Override
        public boolean isLegacySystemApp(AndroidPackage pkg) {
            synchronized (mLock) {
                final PackageSetting ps = getPackageSetting(pkg.getPackageName());
                return mPromoteSystemApps
                        && ps.isSystem()
                        && mExistingSystemPackages.contains(ps.name);
            }
        }

        @Override
        public List<PackageInfo> getOverlayPackages(int userId) {
            final ArrayList<PackageInfo> overlayPackages = new ArrayList<PackageInfo>();
            synchronized (mLock) {
                for (AndroidPackage p : mPackages.values()) {
                    if (p.getOverlayTarget() != null) {
                        PackageInfo pkg = generatePackageInfo(getPackageSetting(p.getPackageName()),
                                0, userId);
                        if (pkg != null) {
                            overlayPackages.add(pkg);
                        }
                    }
                }
            }
            return overlayPackages;
        }

        @Override
        public List<String> getTargetPackageNames(int userId) {
            List<String> targetPackages = new ArrayList<>();
            synchronized (mLock) {
                for (AndroidPackage p : mPackages.values()) {
                    if (p.getOverlayTarget() == null) {
                        targetPackages.add(p.getPackageName());
                    }
                }
            }
            return targetPackages;
        }

        @Override
        public boolean setEnabledOverlayPackages(int userId, @NonNull String targetPackageName,
                @Nullable List<String> overlayPackageNames) {
            synchronized (mLock) {
                if (targetPackageName == null || mPackages.get(targetPackageName) == null) {
                    Slog.e(TAG, "failed to find package " + targetPackageName);
                    return false;
                }
                ArrayList<String> overlayPaths = null;
                if (overlayPackageNames != null && overlayPackageNames.size() > 0) {
                    final int N = overlayPackageNames.size();
                    overlayPaths = new ArrayList<>(N);
                    for (int i = 0; i < N; i++) {
                        final String packageName = overlayPackageNames.get(i);
                        final AndroidPackage pkg = mPackages.get(packageName);
                        if (pkg == null) {
                            Slog.e(TAG, "failed to find package " + packageName);
                            return false;
                        }
                        overlayPaths.add(pkg.getBaseCodePath());
                    }
                }

                final PackageSetting ps = mSettings.mPackages.get(targetPackageName);
                ps.setOverlayPaths(overlayPaths, userId);
                return true;
            }
        }

        @Override
        public ResolveInfo resolveIntent(Intent intent, String resolvedType,
                int flags, int userId, boolean resolveForStart, int filterCallingUid) {
            return resolveIntentInternal(
                    intent, resolvedType, flags, userId, resolveForStart, filterCallingUid);
        }

        @Override
        public ResolveInfo resolveService(Intent intent, String resolvedType,
                int flags, int userId, int callingUid) {
            return resolveServiceInternal(intent, resolvedType, flags, userId, callingUid);
        }

        @Override
        public ProviderInfo resolveContentProvider(String name, int flags, int userId) {
            return PackageManagerService.this.resolveContentProviderInternal(
                    name, flags, userId);
        }

        @Override
        public void addIsolatedUid(int isolatedUid, int ownerUid) {
            synchronized (mLock) {
                mIsolatedOwners.put(isolatedUid, ownerUid);
            }
        }

        @Override
        public void removeIsolatedUid(int isolatedUid) {
            synchronized (mLock) {
                mIsolatedOwners.delete(isolatedUid);
            }
        }

        @Override
        public int getUidTargetSdkVersion(int uid) {
            synchronized (mLock) {
                return getUidTargetSdkVersionLockedLPr(uid);
            }
        }

        @Override
        public int getPackageTargetSdkVersion(String packageName) {
            synchronized (mLock) {
                return getPackageTargetSdkVersionLockedLPr(packageName);
            }
        }

        @Override
        public boolean canAccessInstantApps(int callingUid, int userId) {
            return PackageManagerService.this.canViewInstantApps(callingUid, userId);
        }

        @Override
        public boolean canAccessComponent(int callingUid, ComponentName component, int userId) {
            synchronized (mLock) {
                final PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
                return ps != null && !PackageManagerService.this.shouldFilterApplicationLocked(
                        ps, callingUid, component, TYPE_UNKNOWN, userId);
            }
        }

        @Override
        public boolean hasInstantApplicationMetadata(String packageName, int userId) {
            synchronized (mLock) {
                return mInstantAppRegistry.hasInstantApplicationMetadataLPr(packageName, userId);
            }
        }

        @Override
        public void notifyPackageUse(String packageName, int reason) {
            synchronized (mLock) {
                PackageManagerService.this.notifyPackageUseLocked(packageName, reason);
            }
        }

        @Override
        public SparseArray<String> getAppsWithSharedUserIds() {
            synchronized (mLock) {
                return getAppsWithSharedUserIdsLocked();
            }
        }

        @Override
        public String getSharedUserIdForPackage(String packageName) {
            synchronized (mLock) {
                return getSharedUserIdForPackageLocked(packageName);
            }
        }

        @Override
        public String[] getPackagesForSharedUserId(String sharedUserId, int userId) {
            synchronized (mLock) {
                return getPackagesForSharedUserIdLocked(sharedUserId, userId);
            }
        }

        @Override
        public boolean isOnlyCoreApps() {
            return PackageManagerService.this.isOnlyCoreApps();
        }

        @Override
        public void freeStorage(String volumeUuid, long bytes, int storageFlags)
                throws IOException {
            PackageManagerService.this.freeStorage(volumeUuid, bytes, storageFlags);
        }

        @Override
        public void forEachPackage(Consumer<AndroidPackage> actionLocked) {
            PackageManagerService.this.forEachPackage(actionLocked);
        }

        @Override
        public void forEachInstalledPackage(@NonNull Consumer<AndroidPackage> actionLocked,
                @UserIdInt int userId) {
            PackageManagerService.this.forEachInstalledPackage(actionLocked, userId);
        }

        @Override
        public ArraySet<String> getEnabledComponents(String packageName, int userId) {
            synchronized (mLock) {
                PackageSetting setting = mSettings.getPackageLPr(packageName);
                if (setting == null) {
                    return new ArraySet<>();
                }
                return setting.getEnabledComponents(userId);
            }
        }

        @Override
        public ArraySet<String> getDisabledComponents(String packageName, int userId) {
            synchronized (mLock) {
                PackageSetting setting = mSettings.getPackageLPr(packageName);
                if (setting == null) {
                    return new ArraySet<>();
                }
                return setting.getDisabledComponents(userId);
            }
        }

        @Override
        public @PackageManager.EnabledState int getApplicationEnabledState(
                String packageName, int userId) {
            synchronized (mLock) {
                PackageSetting setting = mSettings.getPackageLPr(packageName);
                if (setting == null) {
                    return COMPONENT_ENABLED_STATE_DEFAULT;
                }
                return setting.getEnabled(userId);
            }
        }

        @Override
        public void setEnableRollbackCode(int token, int enableRollbackCode) {
            PackageManagerService.this.setEnableRollbackCode(token, enableRollbackCode);
        }

        /**
         * Ask the package manager to compile layouts in the given package.
         */
        @Override
        public boolean compileLayouts(String packageName) {
            AndroidPackage pkg;
            synchronized (mLock) {
                pkg = mPackages.get(packageName);
                if (pkg == null) {
                    return false;
                }
            }
            return mArtManagerService.compileLayouts(pkg);
        }

        @Override
        public void finishPackageInstall(int token, boolean didLaunch) {
            PackageManagerService.this.finishPackageInstall(token, didLaunch);
        }

        @Nullable
        @Override
        public String removeLegacyDefaultBrowserPackageName(int userId) {
            synchronized (mLock) {
                return mSettings.removeDefaultBrowserPackageNameLPw(userId);
            }
        }

        @Override
        public boolean isApexPackage(String packageName) {
            return PackageManagerService.this.mApexManager.isApexPackage(packageName);
        }

        @Override
        public void uninstallApex(String packageName, long versionCode, int userId,
                IntentSender intentSender, int flags) {
            final int callerUid = Binder.getCallingUid();
            if (callerUid != Process.ROOT_UID && callerUid != Process.SHELL_UID) {
                throw new SecurityException("Not allowed to uninstall apexes");
            }
            PackageInstallerService.PackageDeleteObserverAdapter adapter =
                    new PackageInstallerService.PackageDeleteObserverAdapter(
                            PackageManagerService.this.mContext, intentSender, packageName,
                            false, userId);
            if ((flags & PackageManager.DELETE_ALL_USERS) == 0) {
                adapter.onPackageDeleted(packageName, PackageManager.DELETE_FAILED_ABORTED,
                        "Can't uninstall an apex for a single user");
                return;
            }
            final ApexManager am = PackageManagerService.this.mApexManager;
            PackageInfo activePackage = am.getPackageInfo(packageName,
                    ApexManager.MATCH_ACTIVE_PACKAGE);
            if (activePackage == null) {
                adapter.onPackageDeleted(packageName, PackageManager.DELETE_FAILED_ABORTED,
                        packageName + " is not an apex package");
                return;
            }
            if (versionCode != PackageManager.VERSION_CODE_HIGHEST
                    && activePackage.getLongVersionCode() != versionCode) {
                adapter.onPackageDeleted(packageName, PackageManager.DELETE_FAILED_ABORTED,
                        "Active version " + activePackage.getLongVersionCode()
                                + " is not equal to " + versionCode + "]");
                return;
            }
            if (!am.uninstallApex(activePackage.applicationInfo.sourceDir)) {
                adapter.onPackageDeleted(packageName, PackageManager.DELETE_FAILED_ABORTED,
                        "Failed to uninstall apex " + packageName);
            } else {
                adapter.onPackageDeleted(packageName, PackageManager.DELETE_SUCCEEDED,
                        null);
            }
        }

        @Override
        public void setRuntimePermissionsFingerPrint(@NonNull String fingerPrint,
                @UserIdInt int userId) {
            synchronized (mLock) {
                mSettings.setRuntimePermissionsFingerPrintLPr(fingerPrint, userId);
            }
        }

        @Override
        public void migrateLegacyObbData() {
            try {
                mInstaller.migrateLegacyObbData();
            } catch (Exception e) {
                Slog.wtf(TAG, e);
            }
        }

        @Override
        public void writeSettings(boolean async) {
            synchronized (mLock) {
                if (async) {
                    scheduleWriteSettingsLocked();
                } else {
                    mSettings.writeLPr();
                }
            }
        }

        @Override
        public void writePermissionSettings(int[] userIds, boolean async) {
            synchronized (mLock) {
                for (int userId : userIds) {
                    mSettings.writeRuntimePermissionsForUserLPr(userId, !async);
                }
            }
        }

        @Override
        public boolean isCallerInstallerOfRecord(
                @NonNull AndroidPackage pkg, int callingUid) {
            synchronized (mLock) {
                if (pkg == null) {
                    return false;
                }
                final PackageSetting packageSetting = getPackageSetting(pkg.getPackageName());
                if (packageSetting == null) {
                    return false;
                }
                final PackageSetting installerPackageSetting =
                        mSettings.mPackages.get(packageSetting.installSource.installerPackageName);
                return installerPackageSetting != null
                        && UserHandle.isSameApp(installerPackageSetting.appId, callingUid);
            }
        }

        @Override
        public boolean areDefaultRuntimePermissionsGranted(int userId) {
            synchronized (mLock) {
                return mSettings.areDefaultRuntimePermissionsGrantedLPr(userId);
            }
        }

        @Override
        public void setReadExternalStorageEnforced(boolean enforced) {
            synchronized (mLock) {
                if (mSettings.mReadExternalStorageEnforced != null
                        && mSettings.mReadExternalStorageEnforced == enforced) {
                    return;
                }
                mSettings.mReadExternalStorageEnforced = enforced ? Boolean.TRUE : Boolean.FALSE;
                mSettings.writeLPr();
            }
        }

        @Override
        public void setIntegrityVerificationResult(int verificationId, int verificationResult) {
            final Message msg = mHandler.obtainMessage(INTEGRITY_VERIFICATION_COMPLETE);
            msg.arg1 = verificationId;
            msg.obj = verificationResult;
            mHandler.sendMessage(msg);
        }
    }

    @GuardedBy("mLock")
    private SparseArray<String> getAppsWithSharedUserIdsLocked() {
        final SparseArray<String> sharedUserIds = new SparseArray<>();
        synchronized (mLock) {
            for (SharedUserSetting setting : mSettings.getAllSharedUsersLPw()) {
                sharedUserIds.put(UserHandle.getAppId(setting.userId), setting.name);
            }
        }
        return sharedUserIds;
    }

    @GuardedBy("mLock")
    private String getSharedUserIdForPackageLocked(String packageName) {
        final PackageSetting ps = mSettings.mPackages.get(packageName);
        return (ps != null && ps.isSharedUser()) ? ps.sharedUser.name : null;
    }

    @GuardedBy("mLock")
    private String[] getPackagesForSharedUserIdLocked(String sharedUserId, int userId) {
        try {
            final SharedUserSetting sus = mSettings.getSharedUserLPw(
                    sharedUserId, 0, 0, false);
            if (sus == null) {
                return EmptyArray.STRING;
            }
            String[] res = new String[sus.packages.size()];
            final Iterator<PackageSetting> it = sus.packages.iterator();
            int i = 0;
            while (it.hasNext()) {
                PackageSetting ps = it.next();
                if (ps.getInstalled(userId)) {
                    res[i++] = ps.name;
                }
            }
            res = ArrayUtils.trimToSize(res, i);
            if (res != null) {
                return res;
            }
        } catch (PackageManagerException e) {
            // Should not happen
        }
        return EmptyArray.STRING;
    }

    @Override
    public int getRuntimePermissionsVersion(@UserIdInt int userId) {
        Preconditions.checkArgumentNonnegative(userId);
        mContext.enforceCallingOrSelfPermission(
                Manifest.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY,
                "setRuntimePermissionVersion");
        synchronized (mLock) {
            return mSettings.getDefaultRuntimePermissionsVersionLPr(userId);
        }
    }

    @Override
    public void setRuntimePermissionsVersion(int version, @UserIdInt int userId) {
        Preconditions.checkArgumentNonnegative(version);
        Preconditions.checkArgumentNonnegative(userId);
        mContext.enforceCallingOrSelfPermission(
                Manifest.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY,
                "setRuntimePermissionVersion");
        synchronized (mLock) {
            mSettings.setDefaultRuntimePermissionsVersionLPr(version, userId);
        }
    }

    @Nullable
    public PackageSetting getPackageSetting(String packageName) {
        synchronized (mPackages) {
            packageName = resolveInternalPackageNameLPr(
                    packageName, PackageManager.VERSION_CODE_HIGHEST);
            return mSettings.mPackages.get(packageName);
        }
    }

    void forEachPackage(Consumer<AndroidPackage> actionLocked) {
        synchronized (mLock) {
            int numPackages = mPackages.size();
            for (int i = 0; i < numPackages; i++) {
                actionLocked.accept(mPackages.valueAt(i));
            }
        }
    }

    void forEachInstalledPackage(@NonNull Consumer<AndroidPackage> actionLocked,
            @UserIdInt int userId) {
        synchronized (mLock) {
            int numPackages = mPackages.size();
            for (int i = 0; i < numPackages; i++) {
                AndroidPackage pkg = mPackages.valueAt(i);
                PackageSetting setting = mSettings.getPackageLPr(pkg.getPackageName());
                if (setting == null || !setting.getInstalled(userId)) {
                    continue;
                }
                actionLocked.accept(pkg);
            }
        }
    }

    boolean isHistoricalPackageUsageAvailable() {
        return mPackageUsage.isHistoricalPackageUsageAvailable();
    }

    /**
     * Return a <b>copy</b> of the collection of packages known to the package manager.
     * @return A copy of the values of mPackages.
     */
    Collection<AndroidPackage> getPackages() {
        synchronized (mLock) {
            return new ArrayList<>(mPackages.values());
        }
    }

    /**
     * Logs process start information (including base APK hash) to the security log.
     * @hide
     */
    @Override
    public void logAppProcessStartIfNeeded(String processName, int uid, String seinfo,
            String apkFile, int pid) {
        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
            return;
        }
        if (!SecurityLog.isLoggingEnabled()) {
            return;
        }
        Bundle data = new Bundle();
        data.putLong("startTimestamp", System.currentTimeMillis());
        data.putString("processName", processName);
        data.putInt("uid", uid);
        data.putString("seinfo", seinfo);
        data.putString("apkFile", apkFile);
        data.putInt("pid", pid);
        Message msg = mProcessLoggingHandler.obtainMessage(
                ProcessLoggingHandler.LOG_APP_PROCESS_START_MSG);
        msg.setData(data);
        mProcessLoggingHandler.sendMessage(msg);
    }

    public CompilerStats.PackageStats getCompilerPackageStats(String pkgName) {
        return mCompilerStats.getPackageStats(pkgName);
    }

    public CompilerStats.PackageStats getOrCreateCompilerPackageStats(AndroidPackage pkg) {
        return getOrCreateCompilerPackageStats(pkg.getPackageName());
    }

    public CompilerStats.PackageStats getOrCreateCompilerPackageStats(String pkgName) {
        return mCompilerStats.getOrCreatePackageStats(pkgName);
    }

    public void deleteCompilerPackageStats(String pkgName) {
        mCompilerStats.deletePackageStats(pkgName);
    }

    @Override
    public int getInstallReason(String packageName, int userId) {
        final int callingUid = Binder.getCallingUid();
        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
                true /* requireFullPermission */, false /* checkShell */,
                "get install reason");
        synchronized (mLock) {
            final PackageSetting ps = mSettings.mPackages.get(packageName);
            if (shouldFilterApplicationLocked(ps, callingUid, userId)) {
                return PackageManager.INSTALL_REASON_UNKNOWN;
            }
            if (ps != null) {
                return ps.getInstallReason(userId);
            }
        }
        return PackageManager.INSTALL_REASON_UNKNOWN;
    }

    @Override
    public boolean canRequestPackageInstalls(String packageName, int userId) {
        return canRequestPackageInstallsInternal(packageName, 0, userId,
                true /* throwIfPermNotDeclared*/);
    }

    private boolean canRequestPackageInstallsInternal(String packageName, int flags, int userId,
            boolean throwIfPermNotDeclared) {
        int callingUid = Binder.getCallingUid();
        int uid = getPackageUid(packageName, 0, userId);
        if (callingUid != uid && callingUid != Process.ROOT_UID
                && callingUid != Process.SYSTEM_UID) {
            throw new SecurityException(
                    "Caller uid " + callingUid + " does not own package " + packageName);
        }
        ApplicationInfo info = getApplicationInfo(packageName, flags, userId);
        if (info == null) {
            return false;
        }
        if (info.targetSdkVersion < Build.VERSION_CODES.O) {
            return false;
        }
        if (isInstantApp(packageName, userId)) {
            return false;
        }
        String appOpPermission = Manifest.permission.REQUEST_INSTALL_PACKAGES;
        String[] packagesDeclaringPermission =
                mPermissionManager.getAppOpPermissionPackages(appOpPermission, callingUid);
        if (!ArrayUtils.contains(packagesDeclaringPermission, packageName)) {
            if (throwIfPermNotDeclared) {
                throw new SecurityException("Need to declare " + appOpPermission
                        + " to call this api");
            } else {
                Slog.e(TAG, "Need to declare " + appOpPermission + " to call this api");
                return false;
            }
        }
        if (mUserManager.hasUserRestriction(UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES, userId)
                  || mUserManager.hasUserRestriction(
                        UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES_GLOBALLY, userId)) {
            return false;
        }
        if (mExternalSourcesPolicy != null) {
            int isTrusted = mExternalSourcesPolicy.getPackageTrustedToInstallApps(packageName, uid);
            return isTrusted == PackageManagerInternal.ExternalSourcesPolicy.USER_TRUSTED;
        }
        return false;
    }

    @Override
    public ComponentName getInstantAppResolverSettingsComponent() {
        return mInstantAppResolverSettingsComponent;
    }

    @Override
    public ComponentName getInstantAppInstallerComponent() {
        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
            return null;
        }
        return mInstantAppInstallerActivity == null
                ? null : mInstantAppInstallerActivity.getComponentName();
    }

    @Override
    public String getInstantAppAndroidId(String packageName, int userId) {
        mContext.enforceCallingOrSelfPermission(android.Manifest.permission.ACCESS_INSTANT_APPS,
                "getInstantAppAndroidId");
        mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId,
                true /* requireFullPermission */, false /* checkShell */,
                "getInstantAppAndroidId");
        // Make sure the target is an Instant App.
        if (!isInstantApp(packageName, userId)) {
            return null;
        }
        synchronized (mLock) {
            return mInstantAppRegistry.getInstantAppAndroidIdLPw(packageName, userId);
        }
    }

    boolean canHaveOatDir(String packageName) {
        synchronized (mLock) {
            AndroidPackage p = mPackages.get(packageName);
            if (p == null) {
                return false;
            }
            return p.canHaveOatDir();
        }
    }

    private String getOatDir(AndroidPackage pkg) {
        if (!pkg.canHaveOatDir()) {
            return null;
        }
        File codePath = new File(pkg.getCodePath());
        if (codePath.isDirectory()) {
            return PackageDexOptimizer.getOatDir(codePath).getAbsolutePath();
        }
        return null;
    }

    void deleteOatArtifactsOfPackage(String packageName) {
        final String[] instructionSets;
        final List<String> codePaths;
        final String oatDir;
        final AndroidPackage pkg;
        synchronized (mLock) {
            pkg = mPackages.get(packageName);
        }
        instructionSets = getAppDexInstructionSets(pkg.getPrimaryCpuAbi(),
                pkg.getSecondaryCpuAbi());
        codePaths = pkg.getAllCodePaths();
        oatDir = getOatDir(pkg);

        for (String codePath : codePaths) {
            for (String isa : instructionSets) {
                try {
                    mInstaller.deleteOdex(codePath, isa, oatDir);
                } catch (InstallerException e) {
                    Log.e(TAG, "Failed deleting oat files for " + codePath, e);
                }
            }
        }
    }

    Set<String> getUnusedPackages(long downgradeTimeThresholdMillis) {
        Set<String> unusedPackages = new HashSet<>();
        long currentTimeInMillis = System.currentTimeMillis();
        synchronized (mLock) {
            for (AndroidPackage pkg : mPackages.values()) {
                PackageSetting ps =  mSettings.mPackages.get(pkg.getPackageName());
                if (ps == null) {
                    continue;
                }
                PackageDexUsage.PackageUseInfo packageUseInfo =
                      getDexManager().getPackageUseInfoOrDefault(pkg.getPackageName());
                if (PackageManagerServiceUtils
                        .isUnusedSinceTimeInMillis(ps.firstInstallTime, currentTimeInMillis,
                                downgradeTimeThresholdMillis, packageUseInfo,
                                pkg.getLatestPackageUseTimeInMills(),
                                pkg.getLatestForegroundPackageUseTimeInMills())) {
                    unusedPackages.add(pkg.getPackageName());
                }
            }
        }
        return unusedPackages;
    }

    @Override
    public void setHarmfulAppWarning(@NonNull String packageName, @Nullable CharSequence warning,
            int userId) {
        final int callingUid = Binder.getCallingUid();
        final int callingAppId = UserHandle.getAppId(callingUid);

        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
                true /*requireFullPermission*/, true /*checkShell*/, "setHarmfulAppInfo");

        if (callingAppId != Process.SYSTEM_UID && callingAppId != Process.ROOT_UID &&
                checkUidPermission(SET_HARMFUL_APP_WARNINGS, callingUid) != PERMISSION_GRANTED) {
            throw new SecurityException("Caller must have the "
                    + SET_HARMFUL_APP_WARNINGS + " permission.");
        }

        synchronized (mLock) {
            mSettings.setHarmfulAppWarningLPw(packageName, warning, userId);
            scheduleWritePackageRestrictionsLocked(userId);
        }
    }

    @Nullable
    @Override
    public CharSequence getHarmfulAppWarning(@NonNull String packageName, int userId) {
        final int callingUid = Binder.getCallingUid();
        final int callingAppId = UserHandle.getAppId(callingUid);

        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
                true /*requireFullPermission*/, true /*checkShell*/, "getHarmfulAppInfo");

        if (callingAppId != Process.SYSTEM_UID && callingAppId != Process.ROOT_UID &&
                checkUidPermission(SET_HARMFUL_APP_WARNINGS, callingUid) != PERMISSION_GRANTED) {
            throw new SecurityException("Caller must have the "
                    + SET_HARMFUL_APP_WARNINGS + " permission.");
        }

        synchronized (mLock) {
            return mSettings.getHarmfulAppWarningLPr(packageName, userId);
        }
    }

    @Override
    public boolean isPackageStateProtected(@NonNull String packageName, @UserIdInt int userId) {
        final int callingUid = Binder.getCallingUid();
        final int callingAppId = UserHandle.getAppId(callingUid);

        mPermissionManager.enforceCrossUserPermission(callingUid, userId,
                false /*requireFullPermission*/, true /*checkShell*/, "isPackageStateProtected");

        if (callingAppId != Process.SYSTEM_UID && callingAppId != Process.ROOT_UID
                && checkUidPermission(MANAGE_DEVICE_ADMINS, callingUid) != PERMISSION_GRANTED) {
            throw new SecurityException("Caller must have the "
                    + MANAGE_DEVICE_ADMINS + " permission.");
        }

        return mProtectedPackages.isPackageStateProtected(userId, packageName);
    }

    @Override
    public void sendDeviceCustomizationReadyBroadcast() {
        mContext.enforceCallingPermission(Manifest.permission.SEND_DEVICE_CUSTOMIZATION_READY,
                "sendDeviceCustomizationReadyBroadcast");

        final long ident = Binder.clearCallingIdentity();
        try {
            final Intent intent = new Intent(Intent.ACTION_DEVICE_CUSTOMIZATION_READY);
            intent.setFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
            final IActivityManager am = ActivityManager.getService();
            final String[] requiredPermissions = {
                Manifest.permission.RECEIVE_DEVICE_CUSTOMIZATION_READY,
            };
            try {
                am.broadcastIntent(null, intent, null, null, 0, null, null, requiredPermissions,
                        android.app.AppOpsManager.OP_NONE, null, false, false, UserHandle.USER_ALL);
            } catch (RemoteException e) {
                throw e.rethrowFromSystemServer();
            }
        } finally {
            Binder.restoreCallingIdentity(ident);
        }
    }

    static class ActiveInstallSession {
        private final String mPackageName;
        private final File mStagedDir;
        private final IPackageInstallObserver2 mObserver;
        private final PackageInstaller.SessionParams mSessionParams;
        private final int mInstallerUid;
        @NonNull private final InstallSource mInstallSource;
        private final UserHandle mUser;
        private final SigningDetails mSigningDetails;

        ActiveInstallSession(String packageName, File stagedDir, IPackageInstallObserver2 observer,
                PackageInstaller.SessionParams sessionParams, int installerUid,
                InstallSource installSource, UserHandle user, SigningDetails signingDetails) {
            mPackageName = packageName;
            mStagedDir = stagedDir;
            mObserver = observer;
            mSessionParams = sessionParams;
            mInstallerUid = installerUid;
            mInstallSource = Preconditions.checkNotNull(installSource);
            mUser = user;
            mSigningDetails = signingDetails;
        }

        public String getPackageName() {
            return mPackageName;
        }

        public File getStagedDir() {
            return mStagedDir;
        }

        public IPackageInstallObserver2 getObserver() {
            return mObserver;
        }

        public PackageInstaller.SessionParams getSessionParams() {
            return mSessionParams;
        }

        public int getInstallerUid() {
            return mInstallerUid;
        }

        @NonNull
        public InstallSource getInstallSource() {
            return mInstallSource;
        }

        public UserHandle getUser() {
            return mUser;
        }

        public SigningDetails getSigningDetails() {
            return mSigningDetails;
        }
    }
}

interface PackageSender {
    /**
     * @param userIds User IDs where the action occurred on a full application
     * @param instantUserIds User IDs where the action occurred on an instant application
     */
    void sendPackageBroadcast(final String action, final String pkg,
        final Bundle extras, final int flags, final String targetPkg,
        final IIntentReceiver finishedReceiver, final int[] userIds, int[] instantUserIds);
    void sendPackageAddedForNewUsers(String packageName, boolean sendBootCompleted,
        boolean includeStopped, int appId, int[] userIds, int[] instantUserIds);
    void notifyPackageAdded(String packageName, int uid);
    void notifyPackageChanged(String packageName, int uid);
    void notifyPackageRemoved(String packageName, int uid);
}
