/*
 * 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.app.AppOpsManager.MODE_ALLOWED;
import static android.app.AppOpsManager.MODE_DEFAULT;
import static android.app.AppOpsManager.MODE_IGNORED;
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.Intent.EXTRA_LONG_VERSION_CODE;
import static android.content.Intent.EXTRA_PACKAGE_NAME;
import static android.content.Intent.EXTRA_VERSION_CODE;
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.EXTRA_VERIFICATION_ID;
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_PROCESS_NOT_DEFINED;
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_PARSE_FAILED_NO_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.PackageManager.UNINSTALL_REASON_UNKNOWN;
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.internal.util.ArrayUtils.emptyIfNull;
import static com.android.internal.util.ArrayUtils.filter;
import static com.android.internal.util.FrameworkStatsLog.BOOT_TIME_EVENT_DURATION__EVENT__OTA_PACKAGE_MANAGER_DATA_APP_AVG_SCAN_TIME;
import static com.android.internal.util.FrameworkStatsLog.BOOT_TIME_EVENT_DURATION__EVENT__OTA_PACKAGE_MANAGER_INIT_TIME;
import static com.android.internal.util.FrameworkStatsLog.BOOT_TIME_EVENT_DURATION__EVENT__OTA_PACKAGE_MANAGER_SYSTEM_APP_AVG_SCAN_TIME;
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.makeDirRecursive;
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.annotation.WorkerThread;
import android.app.ActivityManager;
import android.app.ActivityManagerInternal;
import android.app.AppOpsManager;
import android.app.ApplicationPackageManager;
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.DataLoaderType;
import android.content.pm.FallbackCategoryProvider;
import android.content.pm.FeatureInfo;
import android.content.pm.IDexModuleRegisterCallback;
import android.content.pm.IPackageChangeObserver;
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.InstantAppResolveInfo.InstantAppDigest;
import android.content.pm.InstrumentationInfo;
import android.content.pm.IntentFilterVerificationInfo;
import android.content.pm.KeySet;
import android.content.pm.ModuleInfo;
import android.content.pm.PackageChangeEvent;
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.PackageManagerInternal.PrivateResolveFlags;
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.PackagePartitions;
import android.content.pm.PackagePartitions.SystemPartition;
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.ProcessInfo;
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.SigningInfo;
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.ParsingPackageUtils;
import android.content.pm.parsing.component.ParsedActivity;
import android.content.pm.parsing.component.ParsedInstrumentation;
import android.content.pm.parsing.component.ParsedIntentInfo;
import android.content.pm.parsing.component.ParsedMainComponent;
import android.content.pm.parsing.component.ParsedPermission;
import android.content.pm.parsing.component.ParsedProcess;
import android.content.pm.parsing.component.ParsedProvider;
import android.content.pm.parsing.component.ParsedService;
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.incremental.IncrementalStorage;
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.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.TimingsTraceLog;
import android.util.Xml;
import android.util.apk.ApkSignatureVerifier;
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.content.om.OverlayConfig;
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.FrameworkStatsLog;
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.parsing.PackageInfoUtils;
import com.android.server.pm.parsing.PackageParser2;
import com.android.server.pm.parsing.library.PackageBackwardCompatibility;
import com.android.server.pm.parsing.pkg.AndroidPackage;
import com.android.server.pm.parsing.pkg.AndroidPackageUtils;
import com.android.server.pm.parsing.pkg.PackageImpl;
import com.android.server.pm.parsing.pkg.ParsedPackage;
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.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.UUID;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
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.function.Predicate;
import java.util.function.Supplier;

/**
 * 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;
    static final int SCAN_AS_APK_IN_APEX = 1 << 23;

    @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;

    /**
     * Whether integrity verification is enabled by default.
     */
    private static final boolean DEFAULT_INTEGRITY_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 };

    private static final String RANDOM_DIR_PREFIX = "~~";

    final ServiceThread mHandlerThread;

    final Handler 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 packages prior to receiving an OTA. Keys are package name.
     * Only non-null during an OTA, and even then it is nulled again once systemReady().
     */
    private @Nullable ArraySet<String> mExistingPackages = null;
    /**
     * 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<ScanPartition> SYSTEM_PARTITIONS = Collections.unmodifiableList(
            PackagePartitions.getOrderedPartitions(ScanPartition::new));

    private final List<ScanPartition> mDirsToScanAsSystem;

    private final OverlayConfig mOverlayConfig;

    @GuardedBy("itself")
    final private ArrayList<IPackageChangeObserver> mPackageChangeObservers =
        new ArrayList<>();

    /**
     * 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<ActivityManagerInternal> mActivityManagerInternalProducer;
        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<ActivityManagerInternal> activityManagerInternalProducer,
                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);
            mActivityManagerInternalProducer = new Singleton<>(activityManagerInternalProducer);
            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 ActivityManagerInternal getActivityManagerInternal() {
            return mActivityManagerInternalProducer.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);
        }
    }

    @VisibleForTesting(visibility = Visibility.PRIVATE)
    public static class TestParams {
        public ApexManager apexManager;
        public @Nullable String appPredictionServicePackage;
        public ArtManagerService artManagerService;
        public @Nullable String configuratorPackage;
        public int defParseFlags;
        public DexManager dexManager;
        public List<ScanPartition> dirsToScanAsSystem;
        public @Nullable String documenterPackage;
        public boolean factoryTest;
        public ArrayMap<String, FeatureInfo> availableFeatures;
        public Handler handler;
        public ServiceThread handlerThread;
        public @Nullable String incidentReportApproverPackage;
        public IncrementalManager incrementalManager;
        public PackageInstallerService installerService;
        public InstantAppRegistry instantAppRegistry;
        public InstantAppResolverConnection instantAppResolverConnection;
        public ComponentName instantAppResolverSettingsComponent;
        public @Nullable IntentFilterVerifier<ParsedIntentInfo> intentFilterVerifier;
        public @Nullable ComponentName intentFilterVerifierComponent;
        public boolean isPreNmr1Upgrade;
        public boolean isPreNupgrade;
        public boolean isPreQupgrade;
        public boolean isUpgrade;
        public DisplayMetrics Metrics;
        public ModuleInfoProvider moduleInfoProvider;
        public MoveCallbacks moveCallbacks;
        public boolean onlyCore;
        public OverlayConfig overlayConfig;
        public PackageDexOptimizer packageDexOptimizer;
        public PackageParser2.Callback packageParserCallback;
        public IPermissionManager permissionManagerService;
        public PendingPackageBroadcasts pendingPackageBroadcasts;
        public PackageManagerInternal pmInternal;
        public ProcessLoggingHandler processLoggingHandler;
        public ProtectedPackages protectedPackages;
        public @NonNull String requiredInstallerPackage;
        public @NonNull String requiredPermissionControllerPackage;
        public @NonNull String requiredUninstallerPackage;
        public @Nullable String requiredVerifierPackage;
        public String[] separateProcesses;
        public @NonNull String servicesExtensionPackageName;
        public @Nullable String setupWizardPackage;
        public @NonNull String sharedSystemSharedLibraryPackageName;
        public @Nullable String storageManagerPackage;
        public @Nullable String defaultTextClassifierPackage;
        public @Nullable String systemTextClassifierPackage;
        public ViewCompiler viewCompiler;
        public @Nullable String wellbeingPackage;
        public @Nullable String retailDemoPackage;
        public ComponentName resolveComponentName;
        public ArrayMap<String, AndroidPackage> packages;
    }

    private final AppsFilter mAppsFilter;

    final PackageParser2.Callback mPackageParserCallback;

    // 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<ParsedIntentInfo> 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<ParsedIntentInfo> {
        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<ParsedIntentInfo> filters = ivs.getFilters();
                final int filterCount = filters.size();
                ArraySet<String> domainsSet = new ArraySet<>();
                for (int m=0; m<filterCount; m++) {
                    ParsedIntentInfo 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<ParsedIntentInfo> 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++) {
                ParsedIntentInfo 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,
                ParsedIntentInfo 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(ParsedIntentInfo 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.
    @VisibleForTesting(visibility = Visibility.PACKAGE)
    public 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;

    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 CHECK_PENDING_INTEGRITY_VERIFICATION = 26;

    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 mDefaultTextClassifierPackage;
    final @Nullable String mSystemTextClassifierPackageName;
    final @Nullable String mWellbeingPackage;
    final @Nullable String mDocumenterPackage;
    final @Nullable String mConfiguratorPackage;
    final @Nullable String mAppPredictionServicePackage;
    final @Nullable String mIncidentReportApproverPackage;
    final @Nullable String mServicesExtensionPackageName;
    final @Nullable String mSharedSystemSharedLibraryPackageName;
    final @Nullable String mRetailDemoPackage;

    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;
                        int autoRevokePermissionsMode = args.autoRevokePermissionsMode;

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

                        // 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, autoRevokePermissionsMode,
                                    false /*didRestore*/,
                                    args.installSource.installerPackageName, args.observer,
                                    args.mDataLoaderType);
                        }

                        // 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.isVerificationComplete()
                            && !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);

                        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);
                            state.setVerifierResponse(Binder.getCallingUid(),
                                    PackageManager.VERIFICATION_REJECT);
                        }

                        if (state.areAllVerificationsComplete()) {
                            mPendingVerification.remove(verificationId);
                        }

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

                        params.handleVerificationFinished();

                    }
                    break;
                }
                case CHECK_PENDING_INTEGRITY_VERIFICATION: {
                    final int verificationId = msg.arg1;
                    final PackageVerificationState state = mPendingVerification.get(verificationId);

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

                        Slog.i(TAG, "Integrity verification timed out for " + originUri);

                        state.setIntegrityVerificationResult(
                                getDefaultIntegrityVerificationResponse());

                        if (getDefaultIntegrityVerificationResponse()
                                == PackageManagerInternal.INTEGRITY_VERIFICATION_ALLOW) {
                            Slog.i(TAG, "Integrity check times out, continuing with " + originUri);
                        } else {
                            params.setReturnCode(
                                    PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE);
                        }

                        if (state.areAllVerificationsComplete()) {
                            mPendingVerification.remove(verificationId);
                        }

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

                        params.handleIntegrityVerificationFinished();
                    }
                    break;
                }
                case PACKAGE_VERIFIED: {
                    final int verificationId = msg.arg1;

                    final PackageVerificationState state = mPendingVerification.get(verificationId);
                    if (state == null) {
                        Slog.w(TAG, "Verification with id " + verificationId
                                + " not found."
                                + " It may be invalid or overridden by integrity verification");
                        break;
                    }

                    final PackageVerificationResponse response = (PackageVerificationResponse) msg.obj;

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

                    if (state.isVerificationComplete()) {
                        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);
                        }

                        if (state.areAllVerificationsComplete()) {
                            mPendingVerification.remove(verificationId);
                        }

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

                        params.handleVerificationFinished();
                    }

                    break;
                }
                case INTEGRITY_VERIFICATION_COMPLETE: {
                    final int verificationId = msg.arg1;

                    final PackageVerificationState state = mPendingVerification.get(verificationId);
                    if (state == null) {
                        Slog.w(TAG, "Integrity verification with id " + verificationId
                                + " not found. It may be invalid or overridden by verifier");
                        break;
                    }

                    final int response = (Integer) msg.obj;

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

                    state.setIntegrityVerificationResult(response);

                    if (response == PackageManagerInternal.INTEGRITY_VERIFICATION_ALLOW) {
                        Slog.i(TAG, "Integrity check passed for " + originUri);
                    } else {
                        params.setReturnCode(
                                PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE);
                    }

                    if (state.areAllVerificationsComplete()) {
                        mPendingVerification.remove(verificationId);
                    }

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

                    params.handleIntegrityVerificationFinished();
                    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 int sessionId = msg.arg2;
                    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_SESSION_ID,
                                sessionId);
                        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,
            int autoRevokePermissionsMode,
            boolean launchedForRestore, String installerPackage,
            IPackageInstallObserver2 installObserver, int dataLoaderType) {
        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);
            }

            if (autoRevokePermissionsMode == MODE_ALLOWED || autoRevokePermissionsMode == MODE_IGNORED) {
                mPermissionManager.setAutoRevokeWhitelisted(res.pkg.getPackageName(),
                        autoRevokePermissionsMode == MODE_IGNORED, UserHandle.myUserId());
            }

            // 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.getPackageName();

            // 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.isSystem();
                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);
                }
                extras.putInt(PackageInstaller.EXTRA_DATA_LOADER_TYPE, dataLoaderType);
                // Send to all running apps.
                final SparseArray<int[]> newBroadcastWhitelist;

                synchronized (mLock) {
                    newBroadcastWhitelist = mAppsFilter.getVisibilityWhitelist(
                            getPackageSettingInternal(res.name, Process.SYSTEM_UID),
                            updateUserIds, mSettings.mPackages);
                }
                sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName,
                        extras, 0 /*flags*/,
                        null /*targetPackage*/, null /*finishedReceiver*/,
                        updateUserIds, instantUserIds, newBroadcastWhitelist);
                if (installerPackageName != null) {
                    // Send to the installer, even if it's not running.
                    sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED, packageName,
                            extras, 0 /*flags*/,
                            installerPackageName, null /*finishedReceiver*/,
                            updateUserIds, instantUserIds, null /* broadcastWhitelist */);
                }
                // 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, null /* broadcastWhitelist */);
                }
                // 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, null /* broadcastWhitelist */);
                }

                // 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, res.removedInfo.broadcastWhitelist);
                    if (installerPackageName != null) {
                        sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, packageName,
                                extras, 0 /*flags*/,
                                installerPackageName, null /*finishedReceiver*/,
                                updateUserIds, instantUserIds, null /*broadcastWhitelist*/);
                    }
                    if (notifyVerifier) {
                        sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, packageName,
                                extras, 0 /*flags*/,
                                mRequiredVerifierPackage, null /*finishedReceiver*/,
                                updateUserIds, instantUserIds, null /*broadcastWhitelist*/);
                    }
                    sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED,
                            null /*package*/, null /*extras*/, 0 /*flags*/,
                            packageName /*targetPackage*/,
                            null /*finishedReceiver*/, updateUserIds, instantUserIds,
                            null /*broadcastWhitelist*/);
                } else if (launchedForRestore && !res.pkg.isSystem()) {
                    // 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 (res.pkg.isExternalStorage()) {
                    if (!update) {
                        final StorageManager storage = mInjector.getStorageManager();
                        VolumeInfo volume =
                                storage.findVolumeByUuid(
                                        res.pkg.getStorageUuid().toString());
                        int packageExternalStorageType =
                                getPackageExternalStorageType(volume, res.pkg.isExternalStorage());
                        // If the package was installed externally, log it.
                        if (packageExternalStorageType != StorageEnums.UNKNOWN) {
                            FrameworkStatsLog.write(
                                    FrameworkStatsLog.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
                int[] allUsers = mInjector.getUserManagerService().getUserIds();
                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() {
        // We normally invalidate when we write settings, but in cases where we delay and
        // coalesce settings writes, this strategy would have us invalidate the cache too late.
        // Invalidating on schedule addresses this problem.
        PackageManager.invalidatePackageInfoCache();
        if (!mHandler.hasMessages(WRITE_SETTINGS)) {
            mHandler.sendEmptyMessageDelayed(WRITE_SETTINGS, WRITE_SETTINGS_DELAY);
        }
    }

    void scheduleWritePackageListLocked(int userId) {
        PackageManager.invalidatePackageInfoCache();
        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) {
        PackageManager.invalidatePackageInfoCache();
        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<>(ActivityManagerInternal.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(pm.mPmInternal, i),
                (i, pm) -> (PlatformCompat) ServiceManager.getService("platform_compat"));

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

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

                        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(oldSeInfo)) {
                            Slog.i(TAG, "Updating seInfo for package " + packageName + " from: "
                                    + oldSeInfo + " to: " + newSeInfo);
                            ps.getPkgState().setOverrideSeInfo(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(), mExistingPackages);
            if (scheduleWrite) {
                scheduleWritePackageRestrictionsLocked(UserHandle.USER_ALL);
                scheduleWriteSettingsLocked();
            }
        }
    }

    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
    public static class ScanPartition extends SystemPartition {
        @ScanFlags
        public final int scanFlag;

        public ScanPartition(@NonNull SystemPartition partition) {
            super(partition);
            scanFlag = scanFlagForPartition(partition);
        }

        /**
         * Creates a partition containing the same folders as the original partition but with a
         * different root folder. The new partition will include the scan flags of the original
         * partition along with any specified additional scan flags.
         */
        public ScanPartition(@NonNull File folder, @NonNull ScanPartition original,
                @ScanFlags int additionalScanFlag) {
            super(folder, original);
            this.scanFlag = original.scanFlag | additionalScanFlag;
        }

        private static int scanFlagForPartition(PackagePartitions.SystemPartition partition) {
            switch (partition.type) {
                case PackagePartitions.PARTITION_SYSTEM:
                    return 0;
                case PackagePartitions.PARTITION_VENDOR:
                    return SCAN_AS_VENDOR;
                case PackagePartitions.PARTITION_ODM:
                    return SCAN_AS_ODM;
                case PackagePartitions.PARTITION_OEM:
                    return SCAN_AS_OEM;
                case PackagePartitions.PARTITION_PRODUCT:
                    return SCAN_AS_PRODUCT;
                case PackagePartitions.PARTITION_SYSTEM_EXT:
                    return SCAN_AS_SYSTEM_EXT;
                default:
                    throw new IllegalStateException("Unable to determine scan flag for "
                            + partition.folder);
            }
        }

        @Override
        public String toString() {
            return folder.getAbsolutePath() + ":" + scanFlag;
        }
    }

    /**
     * A extremely minimal constructor designed to start up a PackageManagerService instance for
     * testing.
     *
     * It is assumed that all methods under test will mock the internal fields and thus
     * none of the initialization is needed.
     */
    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
    public PackageManagerService(@NonNull Injector injector, @NonNull TestParams testParams) {
        mInjector = injector;
        mInjector.bootstrap(this);
        mAppsFilter = injector.getAppsFilter();
        mComponentResolver = injector.getComponentResolver();
        mContext = injector.getContext();
        mInstaller = injector.getInstaller();
        mInstallLock = injector.getInstallLock();
        mLock = injector.getLock();
        mPermissionManager = injector.getPermissionManagerServiceInternal();
        mSettings = injector.getSettings();
        mUserManager = injector.getUserManagerService();

        mApexManager = testParams.apexManager;
        mArtManagerService = testParams.artManagerService;
        mAvailableFeatures = testParams.availableFeatures;
        mDefParseFlags = testParams.defParseFlags;
        mDexManager = testParams.dexManager;
        mDirsToScanAsSystem = testParams.dirsToScanAsSystem;
        mFactoryTest = testParams.factoryTest;
        mHandler = testParams.handler;
        mHandlerThread = testParams.handlerThread;
        mIncrementalManager = testParams.incrementalManager;
        mInstallerService = testParams.installerService;
        mInstantAppRegistry = testParams.instantAppRegistry;
        mInstantAppResolverConnection = testParams.instantAppResolverConnection;
        mInstantAppResolverSettingsComponent = testParams.instantAppResolverSettingsComponent;
        mIntentFilterVerifier = testParams.intentFilterVerifier;
        mIntentFilterVerifierComponent = testParams.intentFilterVerifierComponent;
        mIsPreNMR1Upgrade = testParams.isPreNmr1Upgrade;
        mIsPreNUpgrade = testParams.isPreNupgrade;
        mIsPreQUpgrade = testParams.isPreQupgrade;
        mIsUpgrade = testParams.isUpgrade;
        mMetrics = testParams.Metrics;
        mModuleInfoProvider = testParams.moduleInfoProvider;
        mMoveCallbacks = testParams.moveCallbacks;
        mOnlyCore = testParams.onlyCore;
        mOverlayConfig = testParams.overlayConfig;
        mPackageDexOptimizer = testParams.packageDexOptimizer;
        mPackageParserCallback = testParams.packageParserCallback;
        mPendingBroadcasts = testParams.pendingPackageBroadcasts;
        mPermissionManagerService = testParams.permissionManagerService;
        mPmInternal = testParams.pmInternal;
        mProcessLoggingHandler = testParams.processLoggingHandler;
        mProtectedPackages = testParams.protectedPackages;
        mSeparateProcesses = testParams.separateProcesses;
        mViewCompiler = testParams.viewCompiler;
        mRequiredVerifierPackage = testParams.requiredVerifierPackage;
        mRequiredInstallerPackage = testParams.requiredInstallerPackage;
        mRequiredUninstallerPackage = testParams.requiredUninstallerPackage;
        mRequiredPermissionControllerPackage = testParams.requiredPermissionControllerPackage;
        mSetupWizardPackage = testParams.setupWizardPackage;
        mStorageManagerPackage = testParams.storageManagerPackage;
        mDefaultTextClassifierPackage = testParams.defaultTextClassifierPackage;
        mSystemTextClassifierPackageName = testParams.systemTextClassifierPackage;
        mWellbeingPackage = testParams.wellbeingPackage;
        mRetailDemoPackage = testParams.retailDemoPackage;
        mDocumenterPackage = testParams.documenterPackage;
        mConfiguratorPackage = testParams.configuratorPackage;
        mAppPredictionServicePackage = testParams.appPredictionServicePackage;
        mIncidentReportApproverPackage = testParams.incidentReportApproverPackage;
        mServicesExtensionPackageName = testParams.servicesExtensionPackageName;
        mSharedSystemSharedLibraryPackageName = testParams.sharedSystemSharedLibraryPackageName;

        mResolveComponentName = testParams.resolveComponentName;
        mPackages.putAll(testParams.packages);
    }

    public PackageManagerService(Injector injector, boolean onlyCore, boolean factoryTest) {
        PackageManager.invalidatePackageInfoCache();
        PackageManager.disableApplicationInfoCache();
        PackageManager.disablePackageInfoCache();

        final TimingsTraceAndSlog t = new TimingsTraceAndSlog(TAG + "Timing",
                Trace.TRACE_TAG_PACKAGE_MANAGER);
        mPendingBroadcasts = new PendingPackageBroadcasts();

        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);
        PlatformCompat platformCompat = mInjector.getCompatibility();
        mPackageParserCallback = new PackageParser2.Callback() {
            @Override
            public boolean isChangeEnabled(long changeId, @NonNull ApplicationInfo appInfo) {
                return platformCompat.isChangeEnabled(changeId, appInfo);
            }

            @Override
            public boolean hasFeature(String feature) {
                return PackageManagerService.this.hasSystemFeature(feature, 0);
            }
        };

        // 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();
        ApplicationPackageManager.invalidateHasSystemFeatureCache();
        t.traceEnd();

        mProtectedPackages = new ProtectedPackages(mContext);

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

        final List<ScanPartition> scanPartitions = new ArrayList<>();
        final List<ApexManager.ActiveApexInfo> activeApexInfos = mApexManager.getActiveApexInfos();
        for (int i = 0; i < activeApexInfos.size(); i++) {
            final ScanPartition scanPartition = resolveApexToScanPartition(activeApexInfos.get(i));
            if (scanPartition != null) {
                scanPartitions.add(scanPartition);
            }
        }

        mDirsToScanAsSystem = new ArrayList<>();
        mDirsToScanAsSystem.addAll(SYSTEM_PARTITIONS);
        mDirsToScanAsSystem.addAll(scanPartitions);
        Slog.d(TAG, "Directories scanned as system partitions: " + mDirsToScanAsSystem);

        // 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 the names of pre-existing packages prior to scanning, so we can determine
            // which system packages are completely new due to an upgrade.
            if (isDeviceUpgrading()) {
                mExistingPackages = new ArraySet<>(mSettings.mPackages.size());
                for (PackageSetting ps : mSettings.mPackages.values()) {
                    mExistingPackages.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;
            }

            final int systemParseFlags = mDefParseFlags | PackageParser.PARSE_IS_SYSTEM_DIR;
            final int systemScanFlags = scanFlags | SCAN_AS_SYSTEM;

            PackageParser2 packageParser = new PackageParser2(mSeparateProcesses, mOnlyCore,
                    mMetrics, mCacheDir, mPackageParserCallback);

            ExecutorService executorService = ParallelPackageParser.makeExecutorService();
            // Prepare apex package info before scanning APKs, these information are needed when
            // scanning apk in apex.
            mApexManager.scanApexPackagesTraced(packageParser, executorService);
            // 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.
            for (int i = mDirsToScanAsSystem.size() - 1; i >= 0; i--) {
                final ScanPartition partition = mDirsToScanAsSystem.get(i);
                if (partition.getOverlayFolder() == null) {
                    continue;
                }
                scanDirTracedLI(partition.getOverlayFolder(), systemParseFlags,
                        systemScanFlags | partition.scanFlag, 0,
                        packageParser, executorService);
            }

            scanDirTracedLI(frameworkDir, systemParseFlags,
                    systemScanFlags | SCAN_NO_DEX | SCAN_AS_PRIVILEGED, 0,
                    packageParser, executorService);
            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 ScanPartition partition = mDirsToScanAsSystem.get(i);
                if (partition.getPrivAppFolder() != null) {
                    scanDirTracedLI(partition.getPrivAppFolder(), systemParseFlags,
                            systemScanFlags | SCAN_AS_PRIVILEGED | partition.scanFlag, 0,
                            packageParser, executorService);
                }
                scanDirTracedLI(partition.getAppFolder(), systemParseFlags,
                        systemScanFlags | partition.scanFlag, 0,
                        packageParser, executorService);
            }

            // Parse overlay configuration files to set default enable state, mutability, and
            // priority of system overlays.
            mOverlayConfig = OverlayConfig.initializeSystemInstance(
                    consumer -> mPmInternal.forEachPackage(
                            pkg -> consumer.accept(pkg, pkg.isSystem())));

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

            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) {
                //CHECKSTYLE:OFF IndentationCheck
                FrameworkStatsLog.write(FrameworkStatsLog.BOOT_TIME_EVENT_DURATION_REPORTED,
                    BOOT_TIME_EVENT_DURATION__EVENT__OTA_PACKAGE_MANAGER_SYSTEM_APP_AVG_SCAN_TIME,
                    systemScanTime / systemPackagesCount);
                //CHECKSTYLE:ON IndentationCheck
            }
            if (!mOnlyCore) {
                EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_DATA_SCAN_START,
                        SystemClock.uptimeMillis());
                scanDirTracedLI(sAppInstallDir, 0, scanFlags | SCAN_REQUIRE_KNOWN, 0,
                        packageParser, executorService);

            }

            packageParser.close();

            List<Runnable> unfinishedTasks = executorService.shutdownNow();
            if (!unfinishedTasks.isEmpty()) {
                throw new IllegalStateException("Not all tasks finished before calling close: "
                        + unfinishedTasks);
            }

            if (!mOnlyCore) {
                // 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.getCodePath());
                            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++) {
                            final ScanPartition 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) {
                    //CHECKSTYLE:OFF IndentationCheck
                    FrameworkStatsLog.write(
                        FrameworkStatsLog.BOOT_TIME_EVENT_DURATION_REPORTED,
                        BOOT_TIME_EVENT_DURATION__EVENT__OTA_PACKAGE_MANAGER_DATA_APP_AVG_SCAN_TIME,
                        dataScanTime / dataPackagesCount);
                    //CHECKSTYLE:OFF IndentationCheck
                }
            }
            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();

            mDefaultTextClassifierPackage = getDefaultTextClassifierPackageName();
            mSystemTextClassifierPackageName = getSystemTextClassifierPackageName();
            mWellbeingPackage = getWellbeingPackageName();
            mDocumenterPackage = getDocumenterPackageName();
            mConfiguratorPackage = getDeviceConfiguratorPackageName();
            mAppPredictionServicePackage = getAppPredictionServicePackageName();
            mIncidentReportApproverPackage = getIncidentReportApproverPackageName();
            mRetailDemoPackage = getRetailDemoPackageName();

            // Now that we know all of the shared libraries, update all clients to have
            // the correct library paths.
            updateAllSharedLibrariesLocked(null, 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();
                setting.updateProcesses();
            }

            // Now that we know all the packages we are keeping,
            // read and update their last usage times.
            mPackageUsage.read(mSettings.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
            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;
                }
                mServicesExtensionPackageName = getRequiredServicesExtensionPackageLPr();
                mSharedSystemSharedLibraryPackageName = getRequiredSharedLibraryLPr(
                        PackageManager.SYSTEM_SHARED_LIBRARY_SHARED,
                        SharedLibraryInfo.VERSION_UNDEFINED);
            } else {
                mRequiredVerifierPackage = null;
                mRequiredInstallerPackage = null;
                mRequiredUninstallerPackage = null;
                mIntentFilterVerifierComponent = null;
                mIntentFilterVerifier = null;
                mServicesExtensionPackageName = null;
                mSharedSystemSharedLibraryPackageName = null;
            }

            // PermissionController hosts default permission granting and role management, so it's a
            // critical part of the core system.
            mRequiredPermissionControllerPackage = getRequiredPermissionControllerLPr();

            mSettings.setPermissionControllerVersion(
                    getPackageInfo(mRequiredPermissionControllerPackage, 0,
                            UserHandle.USER_SYSTEM).getLongVersionCode());

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

            // Prepare a supplier of package parser for the staging manager to parse apex file
            // during the staging installation.
            final Supplier<PackageParser2> apexParserSupplier = () -> new PackageParser2(
                    mSeparateProcesses, mOnlyCore, mMetrics, mCacheDir, mPackageParserCallback);
            mInstallerService = new PackageInstallerService(mContext, this, apexParserSupplier);
            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) {
                FrameworkStatsLog.write(
                        FrameworkStatsLog.BOOT_TIME_EVENT_DURATION_REPORTED,
                        BOOT_TIME_EVENT_DURATION__EVENT__OTA_PACKAGE_MANAGER_INIT_TIME,
                        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,
            @NonNull PackageSetting stubPkgSetting) {
        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, stubPkgSetting, null, 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 {
            makeDirRecursive(dstCodePath, 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*/, false /*isIncremental*/);
            } 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;
        }
    }

    @NonNull
    private String getRequiredServicesExtensionPackageLPr() {
        String servicesExtensionPackage =
                ensureSystemPackageName(
                        mContext.getString(R.string.config_servicesExtensionPackage));
        if (TextUtils.isEmpty(servicesExtensionPackage)) {
            throw new RuntimeException(
                    "Required services extension package is missing, check "
                            + "config_servicesExtensionPackage.");
        }
        return servicesExtensionPackage;
    }

    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;
                for (ParsedActivity a : pkg.getActivities()) {
                    for (ParsedIntentInfo filter : a.getIntents()) {
                        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, ps);

            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 && !AndroidPackageUtils.isEncryptionAware(ps.pkg)) {
                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 && !p.isSystem()) {
                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.getFlags() & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0;
            final boolean explicitlyVisibleToInstantApp =
                    (activity.getFlags() & 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.getFlags() & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0;
            final boolean explicitlyVisibleToInstantApp =
                    (activity.getFlags() & 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.getFlags() & ServiceInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0;
        } else if (type == TYPE_PROVIDER) {
            final ParsedProvider provider = mComponentResolver.getProvider(component);
            return provider != null
                    && (provider.getFlags() & ProviderInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0;
        } 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");
        return getPackageUidInternal(packageName, flags, userId, callingUid);
    }

    private int getPackageUidInternal(String packageName, int flags, int userId, int callingUid) {
        // reader
        synchronized (mLock) {
            final AndroidPackage p = mPackages.get(packageName);
            if (p != null && AndroidPackageUtils.isMatchForSystemOnly(p, flags)) {
                PackageSetting ps = getPackageSettingInternal(p.getPackageName(), callingUid);
                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 && AndroidPackageUtils.isMatchForSystemOnly(p, 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, ps);
            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, ps);
                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,
            boolean matchSystemOnly) {
        return updateFlagsForResolve(flags, userId, callingUid,
                wantInstantApps, matchSystemOnly, false /*onlyExposedExplicitly*/);
    }

    int updateFlagsForResolve(int flags, int userId, int callingUid,
            boolean wantInstantApps, boolean onlyExposedExplicitly, boolean matchSystemOnly) {
        // Safe mode means we shouldn't match any third-party components
        if (mSafeMode || matchSystemOnly) {
            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.getPackageLPr(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, ps);
            }
            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.getIntents().size(); i++) {
                if (a.getIntents().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, ps);
            }
        }
        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.enforceCrossUserOrProfilePermission(
                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, ps);
            }
        }
        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);
                final ApplicationInfo appInfo = PackageInfoUtils.generateApplicationInfo(
                        pkg, flags, state, userId, ps);
                if (appInfo == null) {
                    return null;
                }
                return PackageInfoUtils.generateProviderInfo(
                        pkg, p, flags, state, appInfo, userId, ps);
            }
        }
        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 mServicesExtensionPackageName;
        }
    }

    @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) {
        return getPackagesForUidInternal(uid, Binder.getCallingUid());
    }

    private String[] getPackagesForUidInternal(int uid, int callingUid) {
        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, 0 /*privateResolveFlags*/,
                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,
            @PrivateResolveFlags int privateResolveFlags, 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,
                    intent.isImplicitImageCaptureIntent() /*matchSystemOnly*/);
            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, privateResolveFlags, filterCallingUid, userId, resolveForStart,
                    true /*allowDynamicSplits*/);
            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);

            final ResolveInfo bestChoice =
                    chooseBestActivity(
                            intent, resolvedType, flags, privateResolveFlags, 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*/,
                intent.isImplicitImageCaptureIntent() /*matchSystemOnly*/);
        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,
            @Nullable String callingFeatureId, boolean isRequesterInstantApp,
            Bundle verificationBundle, int userId) {
        final Message msg = mHandler.obtainMessage(INSTANT_APP_RESOLUTION_PHASE_TWO,
                new InstantAppRequest(responseObj, origIntent, resolvedType,
                        callingPackage, callingFeatureId, isRequesterInstantApp, userId, verificationBundle,
                        false /*resolveForStart*/, responseObj.hostDigestPrefixSecure,
                        responseObj.token));
        mHandler.sendMessage(msg);
    }

    private ResolveInfo chooseBestActivity(Intent intent, String resolvedType,
            int flags, int privateResolveFlags, 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;
                        }
                    }
                }
                if ((privateResolveFlags
                        & PackageManagerInternal.RESOLVE_NON_RESOLVER_ONLY) != 0) {
                    return null;
                }
                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.isImplicitImageCaptureIntent() /*matchSystemOnly*/);
        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);
            if (parent == null) {
                return false;
            }
            synchronized (mLock) {
                int flags = updateFlagsForResolve(0, parent.id, callingUid,
                        false /*includeInstantApps*/,
                        intent.isImplicitImageCaptureIntent() /*matchSystemOnly*/);
                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, 0 /*privateResolveFlags*/, Binder.getCallingUid(),
                userId, false /*resolveForStart*/, true /*allowDynamicSplits*/);
    }

    private @NonNull List<ResolveInfo> queryIntentActivitiesInternal(Intent intent,
            String resolvedType, int flags, @PrivateResolveFlags int privateResolveFlags,
            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*/,
                intent.isImplicitImageCaptureIntent() /*matchSystemOnly*/);
        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 blockInstantResolution =
                        !isTargetSameInstantApp
                        && ((!matchInstantApp && !isCallerInstantApp && isTargetInstantApp)
                                || (matchVisibleToInstantAppOnly && isCallerInstantApp
                                        && isTargetHiddenFromInstantApp));
                final boolean blockNormalResolution = !isTargetInstantApp && !isCallerInstantApp
                        && shouldFilterApplicationLocked(
                                getPackageSettingInternal(ai.applicationInfo.packageName,
                                        Process.SYSTEM_UID), filterCallingUid, userId);
                if (!blockInstantResolution && !blockNormalResolution) {
                    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, privateResolveFlags, 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) {
            String callingPkgName = getInstantAppPackageName(filterCallingUid);
            boolean isRequesterInstantApp = isInstantApp(callingPkgName, userId);
            result = maybeAddInstantAppInstaller(result, intent, resolvedType, flags, userId,
                    resolveForStart, isRequesterInstantApp);
        }
        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,
            boolean isRequesterInstantApp) {
        // 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,
                    0, 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");
                String token = UUID.randomUUID().toString();
                InstantAppDigest digest = InstantAppResolver.parseDigest(intent);
                final InstantAppRequest requestObject = new InstantAppRequest(null /*responseObj*/,
                        intent /*origIntent*/, resolvedType, null /*callingPackage*/,
                        null /*callingFeatureId*/, isRequesterInstantApp, userId,
                        null /*verificationBundle*/, resolveForStart,
                        digest.getDigestPrefixSecure(), token);
                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, 0, 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;
            }
            if (ephemeralPkgName == null) {
                // caller is a full app
                SettingBase callingSetting =
                        mSettings.getSettingLPr(UserHandle.getAppId(filterCallingUid));
                PackageSetting resolvedSetting =
                        getPackageSettingInternal(info.activityInfo.packageName, 0);
                if (resolveForStart
                        || !mAppsFilter.shouldFilterApplication(
                                filterCallingUid, callingSetting, resolvedSetting, userId)) {
                    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;
            } else if (((info.activityInfo.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0)
                    && !info.activityInfo.applicationInfo.isInstantApp()) {
                // allow activities that have been explicitly exposed to ephemeral apps
                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*/,
                0 /*privateResolveFlags*/, 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, 0, 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*/,
                intent.isImplicitImageCaptureIntent() /*matchSystemOnly*/);
        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*/,
                intent.isImplicitImageCaptureIntent() /*matchSystemOnly*/);
        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*/,
                false /* matchSystemOnly */);
        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.enforceCrossUserOrProfilePermission(callingUid,
                userId,
                false /*requireFullPermission*/,
                false /*checkShell*/,
                "query intent receivers");
        final String instantAppPkgName = getInstantAppPackageName(callingUid);
        flags = updateFlagsForResolve(flags, userId, callingUid, includeInstantApps,
                false /* matchSystemOnly */);
        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 blockInstantResolution =
                        !isTargetSameInstantApp
                        && ((!matchInstantApp && !isCallerInstantApp && isTargetInstantApp)
                                || (matchVisibleToInstantAppOnly && isCallerInstantApp
                                        && isTargetHiddenFromInstantApp));

                final boolean blockNormalResolution = !isTargetInstantApp && !isCallerInstantApp
                        && shouldFilterApplicationLocked(
                        getPackageSettingInternal(si.applicationInfo.packageName,
                                Process.SYSTEM_UID), callingUid, userId);
                if (!blockInstantResolution && !blockNormalResolution) {
                    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, userId, callingUid);
            }
            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, userId, callingUid);
            }
            return Collections.emptyList();
        }
    }

    private List<ResolveInfo> applyPostServiceResolutionFilter(List<ResolveInfo> resolveInfos,
            String instantAppPkgName, @UserIdInt int userId, int filterCallingUid) {
        for (int i = resolveInfos.size() - 1; i >= 0; i--) {
            final ResolveInfo info = resolveInfos.get(i);
            if (instantAppPkgName == null) {
                SettingBase callingSetting =
                        mSettings.getSettingLPr(UserHandle.getAppId(filterCallingUid));
                PackageSetting resolvedSetting =
                        getPackageSettingInternal(info.serviceInfo.packageName, 0);
                if (!mAppsFilter.shouldFilterApplication(
                        filterCallingUid, callingSetting, resolvedSetting, userId)) {
                    continue;
                }
            }
            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*/,
                false /* matchSystemOnly */);
        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));
                final boolean blockNormalResolution = !isTargetInstantApp && !isCallerInstantApp
                        && shouldFilterApplicationLocked(
                        getPackageSettingInternal(pi.applicationInfo.packageName,
                                Process.SYSTEM_UID), callingUid, userId);
                if (!blockResolution && !blockNormalResolution) {
                    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, userId, callingUid);
            }
            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, userId, callingUid);
            }
            return Collections.emptyList();
        }
    }

    private List<ResolveInfo> applyPostContentProviderResolutionFilter(
            List<ResolveInfo> resolveInfos, String instantAppPkgName,
            @UserIdInt int userId, int callingUid) {
        for (int i = resolveInfos.size() - 1; i >= 0; i--) {
            final ResolveInfo info = resolveInfos.get(i);

            if (instantAppPkgName == null) {
                SettingBase callingSetting =
                        mSettings.getSettingLPr(UserHandle.getAppId(callingUid));
                PackageSetting resolvedSetting =
                        getPackageSettingInternal(info.providerInfo.packageName, 0);
                if (!mAppsFilter.shouldFilterApplication(
                        callingUid, callingSetting, resolvedSetting, userId)) {
                    continue;
                }
            }

            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, ps);
                        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, ps);
                        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.isPersistent()
                        && (!mSafeMode || p.isSystem())
                        && (matchesUnaware || matchesAware)) {
                    PackageSetting ps = mSettings.mPackages.get(p.getPackageName());
                    if (ps != null) {
                        ApplicationInfo ai = PackageInfoUtils.generateApplicationInfo(p, flags,
                                ps.readUserState(userId), userId, ps);
                        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, callingUserId, ps);
        }
    }

    @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,
                callingUserId));
    }

    private @NonNull List<InstrumentationInfo> queryInstrumentationInternal(String targetPackage,
            int flags, int userId) {
        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())) {
                    String packageName = p.getPackageName();
                    AndroidPackage pkg = mPackages.get(packageName);
                    PackageSetting pkgSetting = getPackageSetting(packageName);
                    if (pkg != null) {
                        InstrumentationInfo ii = PackageInfoUtils.generateInstrumentationInfo(p,
                                pkg, flags, userId, pkgSetting);
                        if (ii != null) {
                            finalList.add(ii);
                        }
                    }
                }
            }
        }

        return finalList;
    }

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

    private void scanDirLI(File scanDir, int parseFlags, int scanFlags, long currentTime,
            PackageParser2 packageParser, ExecutorService executorService) {
        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));
        }

        ParallelPackageParser parallelPackageParser =
                new ParallelPackageParser(packageParser, executorService);

        // 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");
            parsedPackage.setSigningDetails(
                    ParsingPackageUtils.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);

        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "parsePackage");
        final ParsedPackage parsedPackage;
        try (PackageParser2 pp = new PackageParser2(mSeparateProcesses, mOnlyCore, mMetrics, null,
                mPackageParserCallback)) {
            parsedPackage = pp.parsePackage(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;

        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, null);
                    applyPolicy(parsedPackage, parseFlags, scanFlags, mPlatformPackage, true);
                    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, null);
        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<PackageSetting> pkgSettings;
        synchronized (mLock) {
            pkgSettings = PackageManagerServiceUtils.getPackagesForDexopt(
                    mSettings.mPackages.values(), this);
        }

        List<AndroidPackage> pkgs = new ArrayList<>(pkgSettings.size());
        for (int index = 0; index < pkgSettings.size(); index++) {
            pkgs.add(pkgSettings.get(index).pkg);
        }

        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()) && pkg.isSystem()) {
                // 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 PackageSetting pkgSetting = mSettings.getPackageLPr(packageName);
        if (pkgSetting == null) {
            return;
        }
        pkgSetting.getPkgState().setLastPackageUsageTimeInMills(reason, System.currentTimeMillis());
    }

    @Override
    public void notifyDexLoad(String loadingPackageName, Map<String, String> classLoaderContextMap,
            String loaderIsa) {
        if (PLATFORM_PACKAGE_NAME.equals(loadingPackageName)
                && Binder.getCallingUid() != Process.SYSTEM_UID) {
            Slog.w(TAG, "Non System Server process reporting dex loads as system server. uid="
                    + Binder.getCallingUid());
            // Do not record dex loads from processes pretending to be system server.
            // Only the system server should be assigned the package "android", so reject calls
            // that don't satisfy the constraint.
            //
            // notifyDexLoad is a PM API callable from the app process. So in theory, apps could
            // craft calls to this API and pretend to be system server. Doing so poses no particular
            // danger for dex load reporting or later dexopt, however it is a sensible check to do
            // in order to verify the expectations.
            return;
        }
        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, classLoaderContextMap, 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;
        PackageSetting pkgSetting;
        synchronized (mLock) {
            p = mPackages.get(options.getPackageName());
            pkgSetting = mSettings.getPackageLPr(options.getPackageName());
            if (p == null || pkgSetting == null) {
                // Package could not be found. Report failure.
                return PackageDexOptimizer.DEX_OPT_FAILED;
            }
            mPackageUsage.maybeWriteAsync(mSettings.mPackages);
            mCompilerStats.maybeWriteAsync();
        }
        long callingId = Binder.clearCallingIdentity();
        try {
            synchronized (mInstallLock) {
                return performDexOptInternalWithDependenciesLI(p, pkgSetting, 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,
            @NonNull PackageSetting pkgSetting, DexoptOptions options) {
        // System server gets a special path.
        if (PLATFORM_PACKAGE_NAME.equals(p.getPackageName())) {
            return mDexManager.dexoptSystemServer(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(pkgSetting);
        final String[] instructionSets = getAppDexInstructionSets(
                AndroidPackageUtils.getPrimaryCpuAbi(p, pkgSetting),
                AndroidPackageUtils.getSecondaryCpuAbi(p, pkgSetting));
        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;
                PackageSetting depPackageSetting = null;
                synchronized (mLock) {
                    depPackage = mPackages.get(info.getPackageName());
                    depPackageSetting = mSettings.getPackageLPr(info.getPackageName());
                }
                if (depPackage != null && depPackageSetting != null) {
                    // TODO: Analyze and investigate if we (should) profile libraries.
                    pdo.performDexOpt(depPackage, depPackageSetting, instructionSets,
                            getOrCreateCompilerPackageStats(depPackage),
                            mDexManager.getPackageUseInfoOrDefault(depPackage.getPackageName()),
                            libraryOptions);
                } else {
                    // TODO(ngeoffray): Support dexopting system shared libraries.
                }
            }
        }

        return pdo.performDexOpt(p, pkgSetting, 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(PackageSetting pkgSetting) {
        if (!pkgSetting.getPkgState().getUsesLibraryInfos().isEmpty()) {
            ArrayList<SharedLibraryInfo> retValue = new ArrayList<>();
            Set<String> collectedNames = new HashSet<>();
            for (SharedLibraryInfo info : pkgSetting.getPkgState().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<PackageSetting> findSharedNonSystemLibraries(PackageSetting pkgSetting) {
        List<SharedLibraryInfo> deps = findSharedLibraries(pkgSetting);
        if (!deps.isEmpty()) {
            List<PackageSetting> retValue = new ArrayList<>();
            synchronized (mLock) {
                for (SharedLibraryInfo info : deps) {
                    PackageSetting depPackageSetting =
                            mSettings.getPackageLPr(info.getPackageName());
                    if (depPackageSetting != null && depPackageSetting.pkg != null) {
                        retValue.add(depPackageSetting);
                    }
                }
            }
            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(mSettings.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;
        PackageSetting pkgSetting;
        synchronized (mLock) {
            pkg = mPackages.get(packageName);
            pkgSetting = mSettings.getPackageLPr(packageName);
            if (pkg == null || pkgSetting == 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, pkgSetting,
                    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()) {
            File codePathParent = codePath.getParentFile();
            try {
                mInstaller.rmPackageDir(codePath.getAbsolutePath());
                if (codePathParent.getName().startsWith(RANDOM_DIR_PREFIX)) {
                    mInstaller.rmPackageDir(codePathParent.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 (AndroidPackageUtils.isLibrary(pkg)) {
            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, @Nullable AndroidPackage changingLib,
            @Nullable PackageSetting changingLibSetting) {
        if (libInfo.getPath() != null) {
            usesLibraryFiles.add(libInfo.getPath());
            return;
        }
        AndroidPackage pkgForCodePaths = mPackages.get(libInfo.getPackageName());
        PackageSetting pkgSetting = mSettings.getPackageLPr(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 (pkgForCodePaths == null
                    || pkgForCodePaths.getPackageName().equals(changingLib.getPackageName())) {
                pkgForCodePaths = changingLib;
                pkgSetting = changingLibSetting;
            }
        }
        if (pkgForCodePaths != null) {
            usesLibraryFiles.addAll(AndroidPackageUtils.getAllCodePaths(pkgForCodePaths));
            // If the package provides libraries, add the dependency to them.
            applyDefiningSharedLibraryUpdateLocked(pkg, libInfo, SharedLibraryInfo::addDependency);
            if (pkgSetting != null) {
                usesLibraryFiles.addAll(pkgSetting.getPkgState().getUsesLibraryFiles());
            }
        }
    }

    @GuardedBy("mLock")
    private void updateSharedLibrariesLocked(AndroidPackage pkg, PackageSetting pkgSetting,
            @Nullable AndroidPackage changingLib, @Nullable PackageSetting changingLibSetting,
            Map<String, AndroidPackage> availablePackages)
            throws PackageManagerException {
        final ArrayList<SharedLibraryInfo> sharedLibraryInfos = collectSharedLibraryInfos(
                pkgSetting.pkg, availablePackages, mSharedLibraries, null);
        executeSharedLibrariesUpdateLPr(pkg, pkgSetting, changingLib, changingLibSetting,
                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().isEmpty()) {
            usesLibraryInfos = collectSharedLibraryInfos(pkg.getUsesLibraries(), null, null,
                    pkg.getPackageName(), true, pkg.getTargetSdkVersion(), null,
                    availablePackages, existingLibraries, newLibraries);
        }
        if (!pkg.getUsesStaticLibraries().isEmpty()) {
            usesLibraryInfos = collectSharedLibraryInfos(pkg.getUsesStaticLibraries(),
                    pkg.getUsesStaticLibrariesVersions(), pkg.getUsesStaticLibrariesCertDigests(),
                    pkg.getPackageName(), true, pkg.getTargetSdkVersion(), usesLibraryInfos,
                    availablePackages, existingLibraries, newLibraries);
        }
        if (!pkg.getUsesOptionalLibraries().isEmpty()) {
            usesLibraryInfos = collectSharedLibraryInfos(pkg.getUsesOptionalLibraries(),
                    null, null, pkg.getPackageName(), false, pkg.getTargetSdkVersion(),
                    usesLibraryInfos, availablePackages, existingLibraries, newLibraries);
        }
        return usesLibraryInfos;
    }

    private void executeSharedLibrariesUpdateLPr(AndroidPackage pkg,
            @NonNull PackageSetting pkgSetting, @Nullable AndroidPackage changingLib,
            @Nullable PackageSetting changingLibSetting,
            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) {
            pkgSetting.getPkgState().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,
                        changingLibSetting);
            }
            pkgSetting.getPkgState().setUsesLibraryFiles(new ArrayList<>(usesLibraryFiles));
        } else {
            pkgSetting.getPkgState().setUsesLibraryInfos(Collections.emptyList())
                    .setUsesLibraryFiles(Collections.emptyList());
        }
    }

    @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(
            @Nullable AndroidPackage updatedPkg, @Nullable PackageSetting updatedPkgSetting,
            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
        List<Pair<AndroidPackage, PackageSetting>> needsUpdating = null;
        if (updatedPkg != null && updatedPkgSetting != null) {
            needsUpdating = new ArrayList<>(1);
            needsUpdating.add(Pair.create(updatedPkg, updatedPkgSetting));
        }
        do {
            final Pair<AndroidPackage, PackageSetting> changingPkgPair =
                    (needsUpdating == null) ? null : needsUpdating.remove(0);
            final AndroidPackage changingPkg = changingPkgPair != null
                    ? changingPkgPair.first : null;
            final PackageSetting changingPkgSetting = changingPkgPair != null
                    ? changingPkgPair.second : null;
            for (int i = mPackages.size() - 1; i >= 0; --i) {
                final AndroidPackage pkg = mPackages.valueAt(i);
                final PackageSetting pkgSetting = mSettings.getPackageLPr(pkg.getPackageName());
                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(Pair.create(pkg, pkgSetting));
                    }
                }
                try {
                    updateSharedLibrariesLocked(pkg, pkgSetting, changingPkg,
                            changingPkgSetting, 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() || pkgSetting.getPkgState().isUpdatedSystemApp()) {
                        final int flags = pkgSetting.getPkgState().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, String cpuAbiOverride) throws PackageManagerException {
        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanPackage");
        try {
            return scanPackageNewLI(parsedPackage, parseFlags, scanFlags, currentTime, user,
                    cpuAbiOverride);
        } 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;
        /** Override value for package ABI if set during install */
        @Nullable
        public final String cpuAbiOverride;
        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,
                @Nullable String cpuAbiOverride) {
            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;
            this.cpuAbiOverride = cpuAbiOverride;
        }
    }

    /**
     * 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, String cpuAbiOverride) 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) {
            boolean isUpdatedSystemApp;
            if (pkgSetting != null) {
                isUpdatedSystemApp = pkgSetting.getPkgState().isUpdatedSystemApp();
            } else {
                isUpdatedSystemApp = disabledPkgSetting != null;
            }
            applyPolicy(parsedPackage, parseFlags, scanFlags, mPlatformPackage, isUpdatedSystemApp);
            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,
                    cpuAbiOverride);
            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);
        }
        if (reconciledPkg.installArgs != null && reconciledPkg.installArgs.forceQueryableOverride) {
            pkgSetting.forceQueryableOverride = true;
        }

        // 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, pkgSetting, null, 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().isEmpty()) {
            // 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().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().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) {
                    if (!TextUtils.equals(adjustedAbi,
                            AndroidPackageUtils.getRawPrimaryCpuAbi(ps.pkg))) {
                        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.
     *
     * TODO(b/135203078): Move this to package parsing
     **/
    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.getName());
            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.getName());
            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.getName());
            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.getName());
            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.getCodePath());
        final File destResourceFile = new File(parsedPackage.getCodePath());

        // 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().isEmpty()) {
            usesStaticLibraries = new String[parsedPackage.getUsesStaticLibraries().size()];
            parsedPackage.getUsesStaticLibraries().toArray(usesStaticLibraries);
        }
        // TODO(b/135203078): Remove appInfoFlag usage in favor of individually assigned booleans
        //  to avoid adding something that's unsupported due to lack of state, since it's called
        //  with null.
        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;

            // Flags contain system values stored in the server variant of AndroidPackage,
            // and so the server-side PackageInfoUtils is still called, even without a
            // PackageSetting to pass in.
            int pkgFlags = PackageInfoUtils.appInfoFlags(parsedPackage, null);
            int pkgPrivateFlags = PackageInfoUtils.appInfoPrivateFlags(parsedPackage, null);

            // REMOVE SharedUserSetting from method; update in a separate call
            pkgSetting = Settings.createNewSetting(parsedPackage.getPackageName(),
                    originalPkgSetting, disabledPkgSetting, realPkgName, sharedUserSetting,
                    destCodeFile, destResourceFile, parsedPackage.getNativeLibraryRootDir(),
                    AndroidPackageUtils.getRawPrimaryCpuAbi(parsedPackage),
                    AndroidPackageUtils.getRawSecondaryCpuAbi(parsedPackage),
                    parsedPackage.getVersionCode(), pkgFlags, pkgPrivateFlags, user,
                    true /*allowInstall*/, instantApp, virtualPreload,
                    UserManagerService.getInstance(), usesStaticLibraries,
                    parsedPackage.getUsesStaticLibrariesVersions(), parsedPackage.getMimeGroups());
        } else {
            // make a deep copy to avoid modifying any existing system state.
            pkgSetting = new PackageSetting(pkgSetting);
            pkgSetting.pkg = parsedPackage;

            // 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(),
                    AndroidPackageUtils.getPrimaryCpuAbi(parsedPackage, pkgSetting),
                    AndroidPackageUtils.getSecondaryCpuAbi(parsedPackage, pkgSetting),
                    PackageInfoUtils.appInfoFlags(parsedPackage, pkgSetting),
                    PackageInfoUtils.appInfoPrivateFlags(parsedPackage, pkgSetting),
                    UserManagerService.getInstance(),
                    usesStaticLibraries, parsedPackage.getUsesStaticLibrariesVersions(),
                    parsedPackage.getMimeGroups());
        }
        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())) {
            pkgSetting.getPkgState().setUpdatedSystemApp(true);
        }

        parsedPackage
                .setSeInfo(SELinuxMMAC.getSeInfo(parsedPackage, sharedUserSetting,
                        injector.getCompatibility()))
                .setSeInfoUser(SELinuxUtil.assignSeinfoUser(pkgSetting.readUserState(
                        userId == UserHandle.USER_ALL ? UserHandle.USER_SYSTEM : userId)));

        if (parsedPackage.isSystem()) {
            configurePackageComponents(parsedPackage);
        }

        final String cpuAbiOverride = deriveAbiOverride(request.cpuAbiOverride, pkgSetting);

        if ((scanFlags & SCAN_NEW_INSTALL) == 0) {
            if (needToDeriveAbi) {
                Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "derivePackageAbi");
                final boolean extractNativeLibs = !AndroidPackageUtils.isLibrary(parsedPackage);
                final Pair<PackageAbiHelper.Abis, PackageAbiHelper.NativeLibraryPaths> derivedAbi =
                        packageAbiHelper.derivePackageAbi(parsedPackage,
                                pkgSetting.getPkgState().isUpdatedSystemApp(), 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.

                String pkgRawPrimaryCpuAbi = AndroidPackageUtils.getRawPrimaryCpuAbi(parsedPackage);
                if (parsedPackage.isSystem() && !pkgSetting.getPkgState().isUpdatedSystemApp() &&
                        pkgRawPrimaryCpuAbi == null) {
                    final PackageAbiHelper.Abis abis = packageAbiHelper.getBundledAppAbis(
                            parsedPackage);
                    abis.applyTo(parsedPackage);
                    abis.applyTo(pkgSetting);
                    final PackageAbiHelper.NativeLibraryPaths nativeLibraryPaths =
                            packageAbiHelper.getNativeLibraryPaths(parsedPackage, pkgSetting,
                                    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,
                                pkgSetting, sAppLib32InstallDir);
                nativeLibraryPaths.applyTo(parsedPackage);

                if (DEBUG_ABI_SELECTION) {
                    Slog.i(TAG, "Using ABIS and native lib paths from settings : " +
                            parsedPackage.getPackageName() + " " +
                            AndroidPackageUtils.getRawPrimaryCpuAbi(parsedPackage)
                            + ", "
                            + AndroidPackageUtils.getRawSecondaryCpuAbi(parsedPackage));
                }
            }
        } 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, pkgSetting,
                            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) {
                Slog.w(TAG, "Ignoring persisted ABI override " + cpuAbiOverride +
                        " for package " + parsedPackage.getPackageName());
            }
        }

        pkgSetting.primaryCpuAbiString = AndroidPackageUtils.getRawPrimaryCpuAbi(parsedPackage);
        pkgSetting.secondaryCpuAbiString = AndroidPackageUtils.getRawSecondaryCpuAbi(parsedPackage);
        pkgSetting.cpuAbiOverrideString = 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=" + AndroidPackageUtils.getRawPrimaryCpuAbi(parsedPackage) +
                    " secondary=" + AndroidPackageUtils.getRawSecondaryCpuAbi(parsedPackage));
        }

        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
        pkgSetting.pkg = parsedPackage;
        pkgSetting.pkgFlags = PackageInfoUtils.appInfoFlags(parsedPackage, pkgSetting);
        pkgSetting.pkgPrivateFlags =
                PackageInfoUtils.appInfoPrivateFlags(parsedPackage, pkgSetting);
        if (parsedPackage.getLongVersionCode() != pkgSetting.versionCode) {
            pkgSetting.versionCode = parsedPackage.getLongVersionCode();
        }
        // Update volume if needed
        final String volumeUuid = parsedPackage.getVolumeUuid();
        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 =
                    AndroidPackageUtils.createSharedLibraryForStatic(parsedPackage);
        }
        List<SharedLibraryInfo> dynamicSharedLibraryInfos = null;
        if (!ArrayUtils.isEmpty(parsedPackage.getLibraryNames())) {
            dynamicSharedLibraryInfos = new ArrayList<>(parsedPackage.getLibraryNames().size());
            for (String name : parsedPackage.getLibraryNames()) {
                dynamicSharedLibraryInfos.add(
                        AndroidPackageUtils.createSharedLibraryForDynamic(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.isHasCode();
        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,
            boolean isUpdatedSystemApp) {
        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.setStub(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 (!parsedPackage.isSystem()) {
            // Only system apps can use these features.
            parsedPackage.clearOriginalPackages()
                    .setRealPackage(null)
                    .clearAdoptPermissions();
        }

        PackageBackwardCompatibility.modifySharedLibraries(parsedPackage, isUpdatedSystemApp);
    }

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

    private <T extends ParsedMainComponent>
            void assertPackageProcesses(AndroidPackage pkg, List<T> components,
            Map<String, ParsedProcess> procs, String compName)
            throws PackageManagerException {
        if (components == null) {
            return;
        }
        for (int i = components.size() - 1; i >= 0; i--) {
            final ParsedMainComponent component = components.get(i);
            if (!procs.containsKey(component.getProcessName())) {
                throw new PackageManagerException(
                        INSTALL_FAILED_PROCESS_NOT_DEFINED,
                        "Can't install because " + compName + " " + component.getClassName()
                                + "'s process attribute " + component.getProcessName()
                                + " (in package " + pkg.getPackageName()
                                + ") is not included in the <processes> list");
            }
        }
    }

    /**
     * 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.getCodePath() == 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().isEmpty()) {
                    throw new PackageManagerException(
                            "Static shared libs cannot declare activities");
                }

                // Static shared libs cannot declare services
                if (!pkg.getServices().isEmpty()) {
                    throw new PackageManagerException(
                            "Static shared libs cannot declare services");
                }

                // Static shared libs cannot declare providers
                if (!pkg.getProviders().isEmpty()) {
                    throw new PackageManagerException(
                            "Static shared libs cannot declare content providers");
                }

                // Static shared libs cannot declare receivers
                if (!pkg.getReceivers().isEmpty()) {
                    throw new PackageManagerException(
                            "Static shared libs cannot declare broadcast receivers");
                }

                // Static shared libs cannot declare permission groups
                if (!pkg.getPermissionGroups().isEmpty()) {
                    throw new PackageManagerException(
                            "Static shared libs cannot declare permission groups");
                }

                // Static shared libs cannot declare attributions
                if (!pkg.getAttributions().isEmpty()) {
                    throw new PackageManagerException(
                            "Static shared libs cannot declare features");
                }

                // Static shared libs cannot declare permissions
                if (!pkg.getPermissions().isEmpty()) {
                    throw new PackageManagerException(
                            "Static shared libs cannot declare permissions");
                }

                // Static shared libs cannot declare protected broadcasts
                if (!pkg.getProtectedBroadcasts().isEmpty()) {
                    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.getCodePath().equals(known.codePathString)
                                || !pkg.getCodePath().equals(known.resourcePathString)) {
                            throw new PackageManagerException(INSTALL_FAILED_PACKAGE_CHANGED,
                                    "Application package " + pkg.getPackageName()
                                    + " found at " + pkg.getCodePath()
                                    + " 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);
            }

            // If this package has defined explicit processes, then ensure that these are
            // the only processes used by its components.
            final Map<String, ParsedProcess> procs = pkg.getProcesses();
            if (!procs.isEmpty()) {
                if (!procs.containsKey(pkg.getProcessName())) {
                    throw new PackageManagerException(
                            INSTALL_FAILED_PROCESS_NOT_DEFINED,
                            "Can't install because application tag's process attribute "
                                    + pkg.getProcessName()
                                    + " (in package " + pkg.getPackageName()
                                    + ") is not included in the <processes> list");
                }
                assertPackageProcesses(pkg, pkg.getActivities(), procs, "activity");
                assertPackageProcesses(pkg, pkg.getServices(), procs, "service");
                assertPackageProcesses(pkg, pkg.getReceivers(), procs, "receiver");
                assertPackageProcesses(pkg, pkg.getProviders(), procs, "provider");
            }

            // 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. Immutable overlays cannot be
                        // upgraded.
                        Objects.requireNonNull(mOverlayConfig,
                                "Parsing non-system dir before overlay configs are initialized");
                        if (!mOverlayConfig.isMutable(pkg.getPackageName())) {
                            throw new PackageManagerException("Overlay "
                                    + pkg.getPackageName()
                                    + " is static and cannot be upgraded.");
                        }
                    }
                } else {
                    // 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>");
                            }
                        }
                    }
                }
            }

            // Ensure the package is signed with at least the minimum signature scheme version
            // required for its target SDK.
            int minSignatureSchemeVersion =
                    ApkSignatureVerifier.getMinimumSignatureSchemeVersionForTargetSdk(
                            pkg.getTargetSdkVersion());
            if (pkg.getSigningDetails().signatureSchemeVersion < minSignatureSchemeVersion) {
                throw new PackageManagerException(INSTALL_PARSE_FAILED_NO_CERTIFICATES,
                        "No signature found in package of version " + minSignatureSchemeVersion
                                + " or newer for package " + pkg.getPackageName());
            }
        }
    }

    @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);

        // Remove the shared library overlays from its dependent packages.
        for (int currentUserId : UserManagerService.getInstance().getUserIds()) {
            final List<VersionedPackage> dependents = getPackagesUsingSharedLibraryLPr(
                    libraryInfo, 0, currentUserId);
            if (dependents == null) {
                continue;
            }
            for (VersionedPackage dependentPackage : dependents) {
                final PackageSetting ps = mSettings.mPackages.get(
                        dependentPackage.getPackageName());
                if (ps != null) {
                    ps.setOverlayPathsForLibrary(libraryInfo.getName(), null, currentUserId);
                }
            }
        }

        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, pkgSetting);
        }

        if (pkg.getPackageName().equals("android")) {
            synchronized (mLock) {
                // Set up information for our fall-back user intent resolution activity.
                mPlatformPackage = pkg;

                // The instance stored in PackageManagerService is special cased to be non-user
                // specific, so initialize all the needed fields here.
                mAndroidApplication = pkg.toAppInfoWithoutState();
                mAndroidApplication.flags = PackageInfoUtils.appInfoFlags(pkg, pkgSetting);
                mAndroidApplication.privateFlags =
                        PackageInfoUtils.appInfoPrivateFlags(pkg, pkgSetting);
                mAndroidApplication.initForUser(UserHandle.USER_SYSTEM);

                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, pkgSetting, null, 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, pkgSetting,
                            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.getPackageName(),
                        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.getPackageName(), pkg);
            if ((scanFlags & SCAN_AS_APK_IN_APEX) != 0) {
                mApexManager.registerApkInApex(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().isEmpty()) {
                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, PackageSetting pkgSetting) {
        synchronized (mLock) {
            mResolverReplaced = true;

            // The instance created in PackageManagerService is special cased to be non-user
            // specific, so initialize all the needed fields here.
            ApplicationInfo appInfo = pkg.toAppInfoWithoutState();
            appInfo.flags = PackageInfoUtils.appInfoFlags(pkg, pkgSetting);
            appInfo.privateFlags =
                    PackageInfoUtils.appInfoPrivateFlags(pkg, pkgSetting);
            appInfo.initForUser(UserHandle.USER_SYSTEM);

            // Set up information for custom user intent resolution activity.
            mResolveActivity.applicationInfo = appInfo;
            mResolveActivity.name = mCustomResolverComponentName.getClassName();
            mResolveActivity.packageName = pkg.getPackageName();
            mResolveActivity.processName = pkg.getProcessName();
            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.isSystem()) {
            // Only system apps can hold shared libraries.
            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,
            @Nullable SparseArray<int[]> broadcastWhitelist) {
        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, broadcastWhitelist);
                if (instantUserIds != null && instantUserIds != EMPTY_INT_ARRAY) {
                    doSendBroadcast(am, action, pkg, extras, flags, targetPkg, finishedReceiver,
                            instantUserIds, true, null);
                }
            } 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, @Nullable SparseArray<int[]> broadcastWhitelist) {
        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);
            }
            mInjector.getActivityManagerInternal().broadcastIntent(
                    intent, finishedReceiver, requiredPermissions,
                    finishedReceiver != null, id,
                    broadcastWhitelist == null ? null : broadcastWhitelist.get(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,
                mAppsFilter.getVisibilityWhitelist(
                        getPackageSettingInternal(packageName, Process.SYSTEM_UID),
                        userIds, mSettings.mPackages));
        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.broadcastIntentWithFeature(null, 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.broadcastIntentWithFeature(null, 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;
            }
            pkgSetting.getPkgState().setHiddenUntilInstalled(hidden);
            final PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(packageName);
            if (disabledPs == null) {
                return;
            }
            disabledPs.getPkgState().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, 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, 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);
                    pkgSetting.setUninstallReason(PackageManager.UNINSTALL_REASON_UNKNOWN, 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);
        }
        Objects.requireNonNull(packageNames, "packageNames cannot be null");
        if (restrictionFlags != 0 && !isSuspendAllowedForUser(userId)) {
            Slog.w(TAG, "Cannot restrict packages due to restrictions on user " + userId);
            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[] 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;
        }
        if (suspended && !isSuspendAllowedForUser(userId)) {
            Slog.w(TAG, "Cannot suspend due to restrictions on user " + userId);
            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(() -> {
            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, null);
            }
        });
    }

    @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);
        }
    }

    void unsuspendForSuspendingPackage(String suspendingPackage, int userId) {
        final String[] allPackages;
        synchronized (mLock) {
            allPackages = mPackages.keySet().toArray(new String[mPackages.size()]);
        }
        removeSuspensionsBySuspendingPackage(allPackages, suspendingPackage::equals, userId);
    }

    /**
     * Removes any suspensions on given packages that were added by packages that pass the given
     * predicate.
     *
     * <p> Caller must flush package restrictions if it cares about immediate data consistency.
     *
     * @param packagesToChange The packages on which the suspension are to be removed.
     * @param suspendingPackagePredicate A predicate identifying the suspending packages whose
     *                                   suspensions will be removed.
     * @param userId The user for which the changes are taking place.
     */
    void removeSuspensionsBySuspendingPackage(String[] packagesToChange,
            Predicate<String> suspendingPackagePredicate, int userId) {
        final List<String> unsuspendedPackages = new ArrayList<>();
        final IntArray unsuspendedUids = new IntArray();
        synchronized (mLock) {
            for (String packageName : packagesToChange) {
                final PackageSetting ps = mSettings.mPackages.get(packageName);
                if (ps.getSuspended(userId)) {
                    ps.removeSuspension(suspendingPackagePredicate, userId);
                    if (!ps.getSuspended(userId)) {
                        unsuspendedPackages.add(ps.name);
                        unsuspendedUids.add(UserHandle.getUid(userId, ps.getAppId()));
                    }
                }
            }
            scheduleWritePackageRestrictionsLocked(userId);
        }
        if (!unsuspendedPackages.isEmpty()) {
            final String[] packageArray = unsuspendedPackages.toArray(
                    new String[unsuspendedPackages.size()]);
            sendMyPackageSuspendedOrUnsuspended(packageArray, false, userId);
            sendPackagesSuspendedForUser(packageArray, unsuspendedUids.toArray(), userId, false);
        }
    }

    void removeAllDistractingPackageRestrictions(int userId) {
        final String[] allPackages;
        synchronized (mLock) {
            allPackages = mPackages.keySet().toArray(new String[mPackages.size()]);
        }
        removeDistractingPackageRestrictions(allPackages, userId);
    }

    /**
     * Removes any {@link android.content.pm.PackageManager.DistractionRestriction restrictions}
     * set on given packages.
     *
     * <p> Caller must flush package restrictions if it cares about immediate data consistency.
     *
     * @param packagesToChange The packages on which restrictions are to be removed.
     * @param userId the user for which changes are taking place.
     */
    void removeDistractingPackageRestrictions(String[] packagesToChange, int userId) {
        final List<String> changedPackages = new ArrayList<>();
        final IntArray changedUids = new IntArray();
        synchronized (mLock) {
            for (String packageName : packagesToChange) {
                final PackageSetting ps = mSettings.mPackages.get(packageName);
                if (ps.getDistractionFlags(userId) != 0) {
                    ps.setDistractionFlags(0, userId);
                    changedPackages.add(ps.name);
                    changedUids.add(UserHandle.getUid(userId, ps.getAppId()));
                }
            }
            if (!changedPackages.isEmpty()) {
                final String[] packageArray = changedPackages.toArray(
                        new String[changedPackages.size()]);
                sendDistractingPackagesChanged(packageArray, changedUids.toArray(), userId, 0);
                scheduleWritePackageRestrictionsLocked(userId);
            }
        }
    }

    private boolean isCallerDeviceOrProfileOwner(int userId) {
        final int callingUid = Binder.getCallingUid();
        if (callingUid == Process.SYSTEM_UID) {
            return true;
        }
        final String ownerPackage = mProtectedPackages.getDeviceOwnerOrProfileOwnerPackage(userId);
        if (ownerPackage != null) {
            return callingUid == getPackageUidInternal(ownerPackage, 0, userId, callingUid);
        }
        return false;
    }

    private boolean isSuspendAllowedForUser(int userId) {
        return isCallerDeviceOrProfileOwner(userId)
                || (!mUserManager.hasUserRestriction(UserManager.DISALLOW_APPS_CONTROL, userId)
                && !mUserManager.hasUserRestriction(UserManager.DISALLOW_UNINSTALL_APPS, userId));
    }

    @Override
    public String[] getUnsuspendablePackagesForUser(String[] packageNames, int userId) {
        Objects.requireNonNull(packageNames, "packageNames cannot be null");
        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);
        }
        if (!isSuspendAllowedForUser(userId)) {
            Slog.w(TAG, "Cannot suspend due to restrictions on user " + userId);
            return packageNames;
        }
        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]);
                continue;
            }
            synchronized (mLock) {
                final PackageSetting ps = mSettings.mPackages.get(packageNames[i]);
                if (ps == null || shouldFilterApplicationLocked(ps, callingUid, userId)) {
                    Slog.w(TAG, "Could not find package setting for package: " + packageNames[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 boolean isCallerOwner = isCallerDeviceOrProfileOwner(userId);
        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;
                    }
                    if (!isCallerOwner && mSettings.getBlockUninstallLPr(userId, packageName)) {
                        Slog.w(TAG, "Cannot suspend package \"" + packageName
                                + "\": blocked by admin");
                        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);
    }

    /**
     * Get the default integrity verification response code.
     */
    private int getDefaultIntegrityVerificationResponse() {
        // We are not exposing this as a user-configurable setting because we don't want to provide
        // an easy way to get around the integrity check.
        return PackageManager.VERIFICATION_REJECT;
    }

    /**
     * Check whether or not package verification has been enabled.
     *
     * @return true if verification should be performed
     */
    private boolean isVerificationEnabled(
            PackageInfoLite pkgInfoLite, int userId, int installFlags, int installerUid) {
        if (!DEFAULT_VERIFY_ENABLE) {
            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 wants to skip verification for ADB installs
            if ((installFlags & PackageManager.INSTALL_DISABLE_VERIFICATION) != 0) {
                synchronized (mLock) {
                    if (mSettings.mPackages.get(pkgInfoLite.packageName) == null) {
                        // Always verify fresh install
                        return true;
                    }
                }
                // Only skip when apk is debuggable
                return !pkgInfoLite.debuggable;
            }
            return Global.getInt(mContext.getContentResolver(),
                    Global.PACKAGE_VERIFIER_INCLUDE_ADB, 1) != 0;
        }

        if ((installFlags & PackageManager.INSTALL_DISABLE_VERIFICATION) != 0) {
            return false;
        }

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

    /**
     * Check whether or not integrity verification has been enabled.
     */
    private boolean isIntegrityVerificationEnabled() {
        // We are not exposing this as a user-configurable setting because we don't want to provide
        // an easy way to get around the integrity check.
        return DEFAULT_INTEGRITY_VERIFY_ENABLE;
    }

    @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.getIntents() != null && activity.getIntents().size() > 0) {
                    result.addAll(activity.getIntents());
                }
            }
            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
                    ((ParsedIntentInfo) 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);
            mSettings.addInstallerPackageNames(targetPackageSetting.installSource);
            mAppsFilter.addPackage(targetPackageSetting, mSettings.mPackages);
            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;
        boolean allowBackup = res.pkg != null && res.pkg.isAllowBackup();
        boolean doRestore = !update && allowBackup;

        // 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.isUserReadyForBackup(userId)) {
                    bm.restoreAtInstallForUser(
                            userId, res.pkg.getPackageName(), token);
                } else {
                    Slog.w(TAG, "User " + userId + " is not ready. Restore at install "
                            + "didn't take place.");
                    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.getPackageName();
        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) {
            final String seInfo = AndroidPackageUtils.getSeInfo(res.pkg, ps);
            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.getPackageName())) {
                    // 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, null /* broadcastWhitelist */);
    }

    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 int appId;
        final String seinfo;
        final int targetSdkVersion;
        final String fromCodePath;

        public MoveInfo(int moveId, String fromUuid, String toUuid, String packageName,
                int appId, String seinfo, int targetSdkVersion,
                String fromCodePath) {
            this.moveId = moveId;
            this.fromUuid = fromUuid;
            this.toUuid = toUuid;
            this.packageName = packageName;
            this.appId = appId;
            this.seinfo = seinfo;
            this.targetSdkVersion = targetSdkVersion;
            this.fromCodePath = fromCodePath;
        }
    }

    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 mIntegrityVerificationCompleted;
        private boolean mEnableRollbackCompleted;
        private InstallArgs mArgs;
        int mRet;
        final String packageAbiOverride;
        final String[] grantedRuntimePermissions;
        final List<String> whitelistedRestrictedPermissions;
        final int autoRevokePermissionsMode;
        final VerificationInfo verificationInfo;
        final PackageParser.SigningDetails signingDetails;
        final int installReason;
        @Nullable
        MultiPackageInstallParams mParentInstallParams;
        final long requiredInstalledVersionCode;
        final boolean forceQueryableOverride;
        final int mDataLoaderType;
        final int mSessionId;

        InstallParams(OriginInfo origin, MoveInfo move, IPackageInstallObserver2 observer,
                int installFlags, InstallSource installSource, String volumeUuid,
                VerificationInfo verificationInfo, UserHandle user, String packageAbiOverride,
                String[] grantedPermissions, List<String> whitelistedRestrictedPermissions,
                int autoRevokePermissionsMode,
                SigningDetails signingDetails, int installReason,
                long requiredInstalledVersionCode, int dataLoaderType) {
            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.autoRevokePermissionsMode = autoRevokePermissionsMode;
            this.signingDetails = signingDetails;
            this.installReason = installReason;
            this.requiredInstalledVersionCode = requiredInstalledVersionCode;
            this.forceQueryableOverride = false;
            this.mDataLoaderType = dataLoaderType;
            this.mSessionId = -1;
        }

        InstallParams(ActiveInstallSession activeInstallSession) {
            super(activeInstallSession.getUser());
            final PackageInstaller.SessionParams sessionParams =
                    activeInstallSession.getSessionParams();
            if (DEBUG_INSTANT) {
                if ((sessionParams.installFlags
                        & PackageManager.INSTALL_INSTANT_APP) != 0) {
                    Slog.d(TAG, "Ephemeral install of " + activeInstallSession.getPackageName());
                }
            }
            verificationInfo = new VerificationInfo(
                    sessionParams.originatingUri,
                    sessionParams.referrerUri,
                    sessionParams.originatingUid,
                    activeInstallSession.getInstallerUid());
            origin = OriginInfo.fromStagedFile(activeInstallSession.getStagedDir());
            move = null;
            installReason = fixUpInstallReason(
                    activeInstallSession.getInstallSource().installerPackageName,
                    activeInstallSession.getInstallerUid(),
                    sessionParams.installReason);
            observer = activeInstallSession.getObserver();
            installFlags = sessionParams.installFlags;
            installSource = activeInstallSession.getInstallSource();
            volumeUuid = sessionParams.volumeUuid;
            packageAbiOverride = sessionParams.abiOverride;
            grantedRuntimePermissions = sessionParams.grantedRuntimePermissions;
            whitelistedRestrictedPermissions = sessionParams.whitelistedRestrictedPermissions;
            autoRevokePermissionsMode = sessionParams.autoRevokePermissionsMode;
            signingDetails = activeInstallSession.getSigningDetails();
            requiredInstalledVersionCode = sessionParams.requiredInstalledVersionCode;
            forceQueryableOverride = sessionParams.forceQueryableOverride;
            mDataLoaderType = (sessionParams.dataLoaderParams != null)
                    ? sessionParams.dataLoaderParams.getType() : DataLoaderType.NONE;
            mSessionId = activeInstallSession.getSessionId();
        }

        @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.isDebuggable())) {
                        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.isSystem()) {
                            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 (installedPkg.isExternalStorage()) {
                                    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;
            mIntegrityVerificationCompleted = true;
            mEnableRollbackCompleted = true;
            mArgs = args;

            if (ret == PackageManager.INSTALL_SUCCEEDED) {
                final int verificationId = mPendingVerificationToken++;

                // Perform package verification (unless we are simply moving the package).
                if (!origin.existing) {
                    PackageVerificationState verificationState =
                            new PackageVerificationState(this);
                    mPendingVerification.append(verificationId, verificationState);

                    sendIntegrityVerificationRequest(verificationId, pkgLite, verificationState);
                    ret = sendPackageVerificationRequest(
                            verificationId, pkgLite, verificationState);

                    // If both verifications are skipped, we should remove the state.
                    if (verificationState.areAllVerificationsComplete()) {
                        mPendingVerification.remove(verificationId);
                    }
                }


                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_SESSION_ID,
                            mSessionId);
                    enableRollbackIntent.setType(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;
                                    msg.arg2 = mSessionId;
                                    mHandler.sendMessageDelayed(msg, rollbackTimeout);
                                }
                            }, null, 0, null, null);

                    mEnableRollbackCompleted = false;
                }
            }

            mRet = ret;
        }

        /**
         * Send a request to check the integrity of the package.
         */
        void sendIntegrityVerificationRequest(
                int verificationId,
                PackageInfoLite pkgLite,
                PackageVerificationState verificationState) {
            if (!isIntegrityVerificationEnabled()) {
                // Consider the integrity check as passed.
                verificationState.setIntegrityVerificationResult(
                        PackageManagerInternal.INTEGRITY_VERIFICATION_ALLOW);
                return;
            }

            final Intent integrityVerification =
                    new Intent(Intent.ACTION_PACKAGE_NEEDS_INTEGRITY_VERIFICATION);

            integrityVerification.setDataAndType(Uri.fromFile(new File(origin.resolvedPath)),
                    PACKAGE_MIME_TYPE);

            final int flags = Intent.FLAG_GRANT_READ_URI_PERMISSION
                    | Intent.FLAG_RECEIVER_REGISTERED_ONLY
                    | Intent.FLAG_RECEIVER_FOREGROUND;
            integrityVerification.addFlags(flags);

            integrityVerification.putExtra(EXTRA_VERIFICATION_ID, verificationId);
            integrityVerification.putExtra(EXTRA_PACKAGE_NAME, pkgLite.packageName);
            integrityVerification.putExtra(EXTRA_VERSION_CODE, pkgLite.versionCode);
            integrityVerification.putExtra(EXTRA_LONG_VERSION_CODE, pkgLite.getLongVersionCode());
            populateInstallerExtras(integrityVerification);

            // send to integrity component only.
            integrityVerification.setPackage("android");

            DeviceIdleInternal idleController =
                    mInjector.getLocalDeviceIdleController();
            final long idleDuration = getVerificationTimeout();

            idleController.addPowerSaveTempWhitelistAppDirect(Process.myUid(),
                     idleDuration,
                    false, "integrity component");
            mContext.sendOrderedBroadcastAsUser(integrityVerification, UserHandle.SYSTEM,
                    /* receiverPermission= */ null,
                    new BroadcastReceiver() {
                        @Override
                        public void onReceive(Context context, Intent intent) {
                            final Message msg =
                                    mHandler.obtainMessage(CHECK_PENDING_INTEGRITY_VERIFICATION);
                            msg.arg1 = verificationId;
                            // TODO: do we want to use the same timeout?
                            mHandler.sendMessageDelayed(msg, getVerificationTimeout());
                        }
                    }, /* scheduler= */ null,
                    /* initialCode= */ 0,
                    /* initialData= */ null,
                    /* initialExtras= */ null);

            Trace.asyncTraceBegin(
                    TRACE_TAG_PACKAGE_MANAGER, "integrity_verification", verificationId);

            // stop the copy until verification succeeds.
            mIntegrityVerificationCompleted = false;
        }

        /**
         * Send a request to verifier(s) to verify the package if necessary, and return
         * {@link PackageManager#INSTALL_SUCCEEDED} if succeeded.
         */
        int sendPackageVerificationRequest(
                int verificationId,
                PackageInfoLite pkgLite,
                PackageVerificationState verificationState) {
            int ret = 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());
            verificationState.setRequiredVerifierUid(requiredUid);
            final int installerUid =
                    verificationInfo == null ? -1 : verificationInfo.installerUid;
            if (!origin.existing && isVerificationEnabled(pkgLite, 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");
                }

                verification.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId);

                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());

                populateInstallerExtras(verification);

                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);
                        }
                    }
                }

                if (mRequiredVerifierPackage != null) {
                    final ComponentName requiredVerifierComponent = matchComponentForVerifier(
                            mRequiredVerifierPackage, receivers);
                    /*
                     * 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);

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

                    /*
                     * We don't want the copy to proceed until verification
                     * succeeds.
                     */
                    mVerificationCompleted = false;
                }
            } else {
                verificationState.setVerifierResponse(
                        requiredUid, PackageManager.VERIFICATION_ALLOW);
            }
            return ret;
        }

        void populateInstallerExtras(Intent intent) {
            intent.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_PACKAGE,
                    installSource.initiatingPackageName);

            if (verificationInfo != null) {
                if (verificationInfo.originatingUri != null) {
                    intent.putExtra(Intent.EXTRA_ORIGINATING_URI,
                            verificationInfo.originatingUri);
                }
                if (verificationInfo.referrer != null) {
                    intent.putExtra(Intent.EXTRA_REFERRER,
                            verificationInfo.referrer);
                }
                if (verificationInfo.originatingUid >= 0) {
                    intent.putExtra(Intent.EXTRA_ORIGINATING_UID,
                            verificationInfo.originatingUid);
                }
                if (verificationInfo.installerUid >= 0) {
                    intent.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_UID,
                            verificationInfo.installerUid);
                }
            }
        }

        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() {
            if (!mVerificationCompleted) {
                mVerificationCompleted = true;
                if (mIntegrityVerificationCompleted) {
                    handleReturnCode();
                }
                // integrity verification still pending.
            }
        }

        void handleIntegrityVerificationFinished() {
            if (!mIntegrityVerificationCompleted) {
                mIntegrityVerificationCompleted = true;
                if (mVerificationCompleted) {
                    handleReturnCode();
                }
                // verifier still pending
            }
        }


        void handleRollbackEnabled() {
            // TODO(ruhler) b/112431924: Consider halting the install if we
            // couldn't enable rollback.
            mEnableRollbackCompleted = true;
            handleReturnCode();
        }

        @Override
        void handleReturnCode() {
            if (mVerificationCompleted
                    && mIntegrityVerificationCompleted && 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;
        final int autoRevokePermissionsMode;
        /** If non-null, drop an async trace when the install completes */
        final String traceMethod;
        final int traceCookie;
        final PackageParser.SigningDetails signingDetails;
        final int installReason;
        final boolean forceQueryableOverride;
        @Nullable final MultiPackageInstallParams mMultiPackageInstallParams;
        final int mDataLoaderType;

        // 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,
                int autoRevokePermissionsMode,
                String traceMethod, int traceCookie, SigningDetails signingDetails,
                int installReason, boolean forceQueryableOverride,
                MultiPackageInstallParams multiPackageInstallParams, int dataLoaderType) {
            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.autoRevokePermissionsMode = autoRevokePermissionsMode;
            this.traceMethod = traceMethod;
            this.traceCookie = traceCookie;
            this.signingDetails = signingDetails;
            this.installReason = installReason;
            this.forceQueryableOverride = forceQueryableOverride;
            this.mMultiPackageInstallParams = multiPackageInstallParams;
            this.mDataLoaderType = dataLoaderType;
        }

        /** 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.autoRevokePermissionsMode,
                    params.traceMethod, params.traceCookie, params.signingDetails,
                    params.installReason, params.forceQueryableOverride,
                    params.mParentInstallParams, params.mDataLoaderType);
        }

        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, MODE_DEFAULT, null, 0,
                    PackageParser.SigningDetails.UNKNOWN,
                    PackageManager.INSTALL_REASON_UNKNOWN, false, null /* parent */,
                    DataLoaderType.NONE);
            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 boolean isIncremental = isIncrementalPath(codeFile.getAbsolutePath());
            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, isIncremental);
            } 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 {
                makeDirRecursive(afterCodeFile.getParentFile(), 0775);
                if (onIncremental) {
                    mIncrementalManager.renameCodePath(beforeCodeFile, afterCodeFile);
                } else {
                    Os.rename(beforeCodeFile.getAbsolutePath(), afterCodeFile.getAbsolutePath());
                }
            } catch (IOException | ErrnoException e) {
                Slog.w(TAG, "Failed to rename", e);
                return false;
            }

            //TODO(b/136132412): enable selinux restorecon for incremental directories
            if (!onIncremental && !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()));

            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.appId, move.seinfo, move.targetSdkVersion,
                            move.fromCodePath);
                } catch (InstallerException e) {
                    Slog.w(TAG, "Failed to move app", e);
                    return PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
                }
            }

            final String toPathName = new File(move.fromCodePath).getName();
            codeFile = new File(Environment.getDataAppDirectory(move.toUuid), toPathName);
            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;
            }

            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 String toPathName = new File(move.fromCodePath).getName();
            final File codeFile = new File(Environment.getDataAppDirectory(volumeUuid),
                    toPathName);
            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.
                // We don't want ART profiles cleared, because they don't move,
                // so we would be deleting the only copy (b/149200535).
                final int flags = FLAG_STORAGE_DE | FLAG_STORAGE_CE
                        | Installer.FLAG_CLEAR_APP_DATA_KEEP_ART_PROFILES;
                for (int userId : userIds) {
                    try {
                        mInstaller.destroyAppData(volumeUuid, move.packageName, userId, flags, 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();
        }
    }

    /**
     * Given {@code targetDir}, returns {@code targetDir/~~[randomStrA]/[packageName]-[randomStrB].}
     * Makes sure that {@code targetDir/~~[randomStrA]} directory doesn't exist.
     * Notice that this method doesn't actually create any directory.
     *
     * @param targetDir Directory that is two-levels up from the result directory.
     * @param packageName Name of the package whose code files are to be installed under the result
     *                    directory.
     * @return File object for the directory that should hold the code files of {@code packageName}.
     */
    private File getNextCodePath(File targetDir, String packageName) {
        SecureRandom random = new SecureRandom();
        byte[] bytes = new byte[16];
        File firstLevelDir;
        do {
            random.nextBytes(bytes);
            String dirName = RANDOM_DIR_PREFIX
                    + Base64.encodeToString(bytes, Base64.URL_SAFE | Base64.NO_WRAP);
            firstLevelDir = new File(targetDir, dirName);
        } while (firstLevelDir.exists());
        random.nextBytes(bytes);
        String suffix = Base64.encodeToString(bytes, Base64.URL_SAFE | Base64.NO_WRAP);
        return new File(firstLevelDir, packageName + "-" + suffix);
    }

    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 int[] installedForUsers = res.origUsers;
        final int installReason = installArgs.installReason;
        InstallSource installSource = installArgs.installSource;
        final String installerPackageName = installSource.installerPackageName;

        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.
            final PackageSetting ps = mSettings.mPackages.get(pkgName);
            final int userId = installArgs.user.getIdentifier();
            if (ps != null) {
                if (pkg.isSystem()) {
                    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().
                    }

                    if (allUsers != null) {
                        for (int currentUserId : allUsers) {
                            ps.resetOverrideComponentLabelIcon(currentUserId);
                        }
                    }
                }

                // Retrieve the overlays for shared libraries of the package.
                if (!ps.getPkgState().getUsesLibraryInfos().isEmpty()) {
                    for (SharedLibraryInfo sharedLib : ps.getPkgState().getUsesLibraryInfos()) {
                        for (int currentUserId : UserManagerService.getInstance().getUserIds()) {
                            if (!sharedLib.isDynamic()) {
                                // TODO(146804378): Support overlaying static shared libraries
                                continue;
                            }
                            final PackageSetting libPs = mSettings.mPackages.get(
                                    sharedLib.getPackageName());
                            if (libPs == null) {
                                continue;
                            }
                            final String[] overlayPaths = libPs.getOverlayPaths(currentUserId);
                            if (overlayPaths != null) {
                                ps.setOverlayPathsForLibrary(sharedLib.getName(),
                                        Arrays.asList(overlayPaths), currentUserId);
                            }
                        }
                    }
                }

                // It's implied that when a user requests installation, they want the app to be
                // installed and enabled. (This does not apply to USER_ALL, which here means only
                // install on users for which the app is already installed).
                if (userId != UserHandle.USER_ALL) {
                    ps.setInstalled(true, userId);
                    ps.setEnabled(COMPONENT_ENABLED_STATE_DEFAULT, userId, installerPackageName);
                }

                if (installSource.initiatingPackageName != null) {
                    final PackageSetting ips = mSettings.mPackages.get(
                            installSource.initiatingPackageName);
                    if (ips != null) {
                        installSource = installSource.setInitiatingPackageSignatures(
                                ips.signatures);
                    }
                }
                ps.setInstallSource(installSource);
                mSettings.addInstallerPackageNames(installSource);

                // When replacing an existing package, preserve the original install reason for all
                // users that had the package installed before. Similarly for uninstall reasons.
                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);
                    }
                }
                if (res.removedInfo != null && res.removedInfo.uninstallReasons != null) {
                    for (int i = 0; i < res.removedInfo.uninstallReasons.size(); i++) {
                        final int previousUserId = res.removedInfo.uninstallReasons.keyAt(i);
                        final int previousReason = res.removedInfo.uninstallReasons.valueAt(i);
                        ps.setUninstallReason(previousReason, previousUserId);
                    }
                }

                // Set install reason for users that are having the package newly installed.
                final int[] allUsersList = mUserManager.getUserIds();
                if (userId == UserHandle.USER_ALL) {
                    // TODO(b/152629990): It appears that the package doesn't actually get newly
                    //  installed in this case, so the installReason shouldn't get modified?
                    for (int currentUserId : allUsersList) {
                        if (!previousUserIds.contains(currentUserId)) {
                            ps.setInstallReason(installReason, currentUserId);
                        }
                    }
                } else if (!previousUserIds.contains(userId)) {
                    ps.setInstallReason(installReason, userId);
                }
                // Ensure that the uninstall reason is UNKNOWN for users with the package installed.
                for (int currentUserId : allUsersList) {
                    if (ps.getInstalled(currentUserId)) {
                        ps.setUninstallReason(UNINSTALL_REASON_UNKNOWN, currentUserId);
                    }
                }
                mSettings.writeKernelMappingLPr(ps);
            }
            res.name = pkgName;
            res.uid = pkg.getUid();
            res.pkg = pkg;
            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.isSystem()
                        && scanResult.dynamicSharedLibraryInfos != null;
        if (!hasDynamicLibraries) {
            return null;
        }
        final boolean isUpdatedSystemApp = scanResult.pkgSetting.getPkgState()
                .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();

                res.removedInfo.broadcastWhitelist = mAppsFilter.getVisibilityWhitelist(
                                reconciledPkg.pkgSetting, request.mAllUsers, mSettings.mPackages);
                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.getCodePath(),
                                oldPackage.getCodePath(),
                                getAppDexInstructionSets(
                                        AndroidPackageUtils.getPrimaryCpuAbi(oldPackage,
                                                deletedPkgSetting),
                                        AndroidPackageUtils.getSecondaryCpuAbi(oldPackage,
                                                deletedPkgSetting)));
                    } 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.isExternalStorage()) {
                        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.getPackageName());
                        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, request.args.abiOverride);
                    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) {
                    if (request.installResult.freezer != null) {
                        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) {
        final ArraySet<IncrementalStorage> incrementalStorages = new ArraySet<>();
        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());
            if (onIncremental) {
                IncrementalStorage storage = mIncrementalManager.openStorage(pkg.getCodePath());
                if (storage == null) {
                    throw new IllegalArgumentException(
                            "Install: null storage for incremental package " + packageName);
                }
                incrementalStorages.add(storage);
            }
            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.isDebuggable()
                    && (!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);
                ScanResult result = reconciledPkg.scanResult;

                // This mirrors logic from commitReconciledScanResultLocked, where the library files
                // needed for dexopt are assigned.
                // TODO: Fix this to have 1 mutable PackageSetting for scan/install. If the previous
                //  setting needs to be passed to have a comparison, hide it behind an immutable
                //  interface. There's no good reason to have 3 different ways to access the real
                //  PackageSetting object, only one of which is actually correct.
                PackageSetting realPkgSetting = result.existingSettingCopied
                        ? result.request.pkgSetting : result.pkgSetting;
                if (realPkgSetting == null) {
                    realPkgSetting = reconciledPkg.pkgSetting;
                }

                // Unfortunately, the updated system app flag is only tracked on this PackageSetting
                boolean isUpdatedSystemApp = reconciledPkg.pkgSetting.getPkgState()
                        .isUpdatedSystemApp();

                realPkgSetting.getPkgState().setUpdatedSystemApp(isUpdatedSystemApp);

                mPackageDexOptimizer.performDexOpt(pkg, realPkgSetting,
                        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);

            notifyPackageChangeObserversOnUpdate(reconciledPkg);
        }
        NativeLibraryHelper.waitForNativeBinariesExtraction(incrementalStorages);
    }

    private void notifyPackageChangeObserversOnUpdate(ReconciledPackage reconciledPkg) {
      final PackageSetting pkgSetting = reconciledPkg.pkgSetting;
      final PackageInstalledInfo pkgInstalledInfo = reconciledPkg.installResult;
      final PackageRemovedInfo pkgRemovedInfo = pkgInstalledInfo.removedInfo;

      PackageChangeEvent pkgChangeEvent = new PackageChangeEvent();
      pkgChangeEvent.packageName = pkgSetting.pkg.getPackageName();
      pkgChangeEvent.version = pkgSetting.versionCode;
      pkgChangeEvent.lastUpdateTimeMillis = pkgSetting.lastUpdateTime;
      pkgChangeEvent.newInstalled = (pkgRemovedInfo == null || !pkgRemovedInfo.isUpdate);
      pkgChangeEvent.dataRemoved = (pkgRemovedInfo != null && pkgRemovedInfo.dataRemoved);
      pkgChangeEvent.isDeleted = false;

      notifyPackageChangeObservers(pkgChangeEvent);
    }

    private void notifyPackageChangeObserversOnDelete(String packageName, long version) {
      PackageChangeEvent pkgChangeEvent = new PackageChangeEvent();
      pkgChangeEvent.packageName = packageName;
      pkgChangeEvent.version = version;
      pkgChangeEvent.lastUpdateTimeMillis = 0L;
      pkgChangeEvent.newInstalled = false;
      pkgChangeEvent.dataRemoved = false;
      pkgChangeEvent.isDeleted = true;

      notifyPackageChangeObservers(pkgChangeEvent);
    }

    private void notifyPackageChangeObservers(PackageChangeEvent event) {
      try {
        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "notifyPackageChangeObservers");
        synchronized (mPackageChangeObservers) {
          for(IPackageChangeObserver observer : mPackageChangeObservers) {
            try {
              observer.onPackageChanged(event);
            } catch(RemoteException e) {
              Log.wtf(TAG, e);
            }
          }
        }
      } finally {
        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
      }
    }

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

        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "parsePackage");
        ParsedPackage parsedPackage;
        try (PackageParser2 pp = new PackageParser2(mSeparateProcesses, false, mMetrics, null,
                mPackageParserCallback)) {
            parsedPackage = pp.parsePackage(tmpPackageFile, parseFlags, false);
            AndroidPackageUtils.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");
            }
        }

        String pkgName = res.name = parsedPackage.getPackageName();
        if (parsedPackage.isTestOnly()) {
            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
                parsedPackage.setSigningDetails(
                        ParsingPackageUtils.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");
        }

        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().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.isPersistent()
                            && ((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.isSystem();
                }
                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.getProtectionLevel() & PermissionInfo.PROTECTION_FLAG_INSTANT) != 0
                        && !systemApp) {
                    Slog.w(TAG, "Non-System package " + parsedPackage.getPackageName()
                            + " attempting to delcare ephemeral permission "
                            + perm.getName() + "; Removing ephemeral.");
                    perm.setProtectionLevel(perm.getProtectionLevel() & ~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.getProtectionLevel() & 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.setProtectionLevel(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 {
                final boolean extractNativeLibs = !AndroidPackageUtils.isLibrary(parsedPackage);
                PackageSetting pkgSetting;
                synchronized (mLock) {
                    pkgSetting = mSettings.getPackageLPr(pkgName);
                }
                String abiOverride =
                        (pkgSetting == null || TextUtils.isEmpty(pkgSetting.cpuAbiOverrideString)
                        ? args.abiOverride : pkgSetting.cpuAbiOverrideString);
                boolean isUpdatedSystemAppFromExistingSetting = pkgSetting != null
                        && pkgSetting.getPkgState().isUpdatedSystemApp();
                AndroidPackage oldPackage = mPackages.get(pkgName);
                boolean isUpdatedSystemAppInferred = oldPackage != null && oldPackage.isSystem();
                final Pair<PackageAbiHelper.Abis, PackageAbiHelper.NativeLibraryPaths>
                        derivedAbi = mInjector.getAbiHelper().derivePackageAbi(parsedPackage,
                        isUpdatedSystemAppFromExistingSetting || isUpdatedSystemAppInferred,
                        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;
                final int[] uninstalledUsers;

                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);
                    uninstalledUsers = ps.queryInstalledUsers(allUsers, false);


                    // 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));
                }
                res.removedInfo.uninstallReasons = new SparseArray<>(uninstalledUsers.length);
                for (int i = 0; i < uninstalledUsers.length; i++) {
                    final int userId = uninstalledUsers[i];
                    res.removedInfo.uninstallReasons.put(userId, ps.getUninstallReason(userId));
                }

                sysPkg = oldPackage.isSystem();
                if (sysPkg) {
                    // Set the system/privileged/oem/vendor/product flags as needed
                    final boolean privileged = oldPackage.isPrivileged();
                    final boolean oem = oldPackage.isOem();
                    final boolean vendor = oldPackage.isVendor();
                    final boolean product = oldPackage.isProduct();
                    final boolean odm = oldPackage.isOdm();
                    final boolean systemExt = oldPackage.isSystemExt();
                    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)
                            | (systemExt ? SCAN_AS_SYSTEM_EXT : 0);

                    if (DEBUG_INSTALL) {
                        Slog.d(TAG, "replaceSystemPackageLI: new=" + parsedPackage
                                + ", old=" + oldPackage);
                    }
                    res.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
                    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(),
                pkg.isHasDomainUrls(),
                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 (ParsedIntentInfo filter : a.getIntents()) {
                    if (filter.needsVerification()
                            && needsNetworkVerificationLPr(a.getPackageName())) {
                        if (DEBUG_DOMAIN_VERIFICATION) {
                            Slog.d(TAG,
                                    "Intent filter needs verification, so processing all filters");
                        }
                        needToVerify = true;
                        break;
                    }
                }
            }

            if (needToVerify) {
                final boolean needsVerification = needsNetworkVerificationLPr(packageName);
                final int verificationId = mIntentFilterVerificationToken++;
                for (ParsedActivity a : activities) {
                    for (ParsedIntentInfo filter : a.getIntents()) {
                        // Run verification against hosts mentioned in any web-nav intent filter,
                        // even if the filter matches non-web schemes as well
                        if (needsVerification && filter.handlesWebUris(false)) {
                            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(String packageName) {
        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(PackageSetting ps) {
        return (ps.pkgFlags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 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 (pkg.isExternalStorage()) {
            if (TextUtils.isEmpty(pkg.getVolumeUuid())) {
                return mSettings.getExternalVersion();
            } else {
                return mSettings.findOrCreateVersion(pkg.getVolumeUuid());
            }
        } else {
            return mSettings.getInternalVersion();
        }
    }

    @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
            notifyPackageChangeObserversOnDelete(packageName, versionCode);
        });
    }

    private String resolveExternalPackageNameLPr(AndroidPackage pkg) {
        if (pkg.getStaticSharedLibName() != null) {
            return pkg.getManifestPackageName();
        }
        return pkg.getPackageName();
    }

    @GuardedBy("mLock")
    private String resolveInternalPackageNameLPr(String packageName, long versionCode) {
        final int callingUid = Binder.getCallingUid();
        return resolveInternalPackageNameInternalLocked(packageName, versionCode,
                callingUid);
    }

    private String resolveInternalPackageNameInternalLocked(
            String packageName, long versionCode, int callingUid) {
        // 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(callingUid);
        if (callingAppId != Process.SYSTEM_UID && callingAppId != Process.SHELL_UID
                && callingAppId != Process.ROOT_UID) {
            versionsCallerCanSee = new LongSparseLongArray();
            String libName = versionedLib.valueAt(0).getName();
            String[] uidPackages = getPackagesForUidInternal(callingUid, callingUid);
            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, uninstalledPs,
                                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()) {
                final PackageSetting stubPs;
                synchronized (mLock) {
                    // restore the enabled state of the stub; the state is overwritten when
                    // the stub is uninstalled
                    stubPs = mSettings.getPackageLPr(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, stubPs);
                }
            }
        }

        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;
        SparseArray<Integer> uninstallReasons;
        boolean isRemovedPackageSystemUpdate = false;
        boolean isUpdate;
        boolean dataRemoved;
        boolean removedForAllUsers;
        boolean isStaticSharedLib;
        // a two dimensional array mapping userId to the set of appIds that can receive notice
        // of package changes
        SparseArray<int[]> broadcastWhitelist;
        // 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, broadcastWhitelist);
            packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED, removedPackage,
                    extras, 0, null /*targetPackage*/, null, null, null, broadcastWhitelist);
            packageSender.sendPackageBroadcast(Intent.ACTION_MY_PACKAGE_REPLACED, null, null, 0,
                    removedPackage, null, null, null, null /* broadcastWhitelist */);
            if (installerPackageName != null) {
                packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_ADDED,
                        removedPackage, extras, 0 /*flags*/,
                        installerPackageName, null, null, null, null /* broadcastWhitelist */);
                packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_REPLACED,
                        removedPackage, extras, 0 /*flags*/,
                        installerPackageName, null, null, null, null /* broadcastWhitelist */);
            }
        }

        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, broadcastWhitelist);
                if (installerPackageName != null) {
                    packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_REMOVED,
                            removedPackage, extras, 0 /*flags*/,
                            installerPackageName, null, broadcastUsers, instantUserIds, null);
                }
                if (dataRemoved && !isRemovedPackageSystemUpdate) {
                    packageSender.sendPackageBroadcast(Intent.ACTION_PACKAGE_FULLY_REMOVED,
                            removedPackage, extras, Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND, null,
                            null, broadcastUsers, instantUserIds, broadcastWhitelist);
                    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, broadcastWhitelist);
            }
        }

        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 DELETE_KEEP_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);
                    if (installed) {
                        deletedPs.setUninstallReason(UNINSTALL_REASON_UNKNOWN, 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 ScanPartition resolveApexToScanPartition(
            ApexManager.ActiveApexInfo apexInfo) {
        for (int i = 0, size = SYSTEM_PARTITIONS.size(); i < size; i++) {
            ScanPartition sp = SYSTEM_PARTITIONS.get(i);
            if (apexInfo.preInstalledApexPath.getAbsolutePath().startsWith(
                    sp.folder.getAbsolutePath())) {
                return new ScanPartition(apexInfo.apexDirectory, sp, SCAN_AS_APK_IN_APEX);
            }
        }
        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++) {
            ScanPartition 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);

        PackageSetting pkgSetting = mSettings.getPackageLPr(pkg.getPackageName());

        try {
            // update shared libraries for the newly re-installed system package
            updateSharedLibrariesLocked(pkg, pkgSetting, null, 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);
                    if (installed) {
                        ps.setUninstallReason(UNINSTALL_REASON_UNKNOWN, 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 /*linkGeneration*/,
                    PackageManager.INSTALL_REASON_UNKNOWN,
                    PackageManager.UNINSTALL_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);
            }
            if ((flags & PackageManager.DELETE_KEEP_DATA) == 0) {
                destroyAppDataLIF(pkg, nextUserId,
                        FLAG_STORAGE_DE | FLAG_STORAGE_CE | FLAG_STORAGE_EXTERNAL);
            }
            clearDefaultBrowserIfNeededForUser(ps.name, nextUserId);
            removeKeystoreDataIfNeeded(mInjector.getUserManagerInternal(), nextUserId, ps.appId);
            clearPackagePreferredActivities(ps.name, nextUserId);
            mPermissionManager.resetRuntimePermissions(pkg, nextUserId);
        }

        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);
                            removeAllDistractingPackageRestrictions(userId);
                            flushPackageRestrictionsAsUserInternalLocked(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;
        PackageSetting ps;
        synchronized (mLock) {
            pkg = mPackages.get(packageName);
            ps = mSettings.mPackages.get(packageName);
            if (pkg == null) {
                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, ps, 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.broadcastIntentWithFeature(null, 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();
        clearPackagePreferredActivities(packageName, callingUserId);
    }

    /** This method takes a specific user id as well as UserHandle.USER_ALL. */
    private void clearPackagePreferredActivities(String packageName, int userId) {
        final SparseBooleanArray changedUsers = new SparseBooleanArray();

        clearPackagePreferredActivitiesLPw(packageName, changedUsers, userId);
        if (changedUsers.size() > 0) {
            updateDefaultHomeNotLocked(changedUsers);
            postPreferredActivityChangedBroadcast(userId);
            synchronized (mLock) {
                scheduleWritePackageRestrictionsLocked(userId);
            }
        }
    }

    /** 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(packageName, 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 getDefaultTextClassifierPackageName() {
        return ensureSystemPackageName(
                mContext.getString(R.string.config_servicesExtensionPackage));
    }

    @Override
    public String getSystemTextClassifierPackageName() {
        return ensureSystemPackageName(
                mContext.getString(R.string.config_defaultTextClassifierPackage));
    }

    @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());
    }

    private @NonNull String[] dropNonSystemPackages(@NonNull String[] pkgNames) {
        return emptyIfNull(filter(pkgNames, String[]::new, mIsSystemPackage), String.class);
    }

    private Predicate<String> mIsSystemPackage = (pkgName) -> {
        if ("android".equals(pkgName)) {
            return true;
        }
        AndroidPackage pkg = mPackages.get(pkgName);
        return pkg != null && pkg.isSystem();
    };

    @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 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 getRetailDemoPackageName() {
        final String predefinedPkgName = mContext.getString(R.string.config_retailDemoPackage);
        final String predefinedSignature = mContext.getString(
                R.string.config_retailDemoPackageSignature);

        if (TextUtils.isEmpty(predefinedPkgName) || TextUtils.isEmpty(predefinedSignature)) {
            return null;
        }

        final AndroidPackage androidPkg = mPackages.get(predefinedPkgName);
        if (androidPkg != null) {
            final SigningDetails signingDetail = androidPkg.getSigningDetails();
            if (signingDetail != null && signingDetail.signatures != null) {
                try {
                    final MessageDigest msgDigest = MessageDigest.getInstance("SHA-256");
                    for (Signature signature : signingDetail.signatures) {
                        if (TextUtils.equals(predefinedSignature,
                                HexEncoding.encodeToString(msgDigest.digest(
                                        signature.toByteArray()), false))) {
                            return predefinedPkgName;
                        }
                    }
                } catch (NoSuchAlgorithmException e) {
                    Slog.e(
                            TAG,
                            "Unable to verify signatures as getting the retail demo package name",
                            e);
                }
            }
        }

        return null;
    }

    @Nullable
    private String ensureSystemPackageName(@Nullable String packageName) {
        if (packageName == null) {
            return null;
        }
        long token = Binder.clearCallingIdentity();
        try {
            if (getPackageInfo(packageName, MATCH_FACTORY_ONLY, UserHandle.USER_SYSTEM) == null) {
                PackageInfo packageInfo = getPackageInfo(packageName, 0, UserHandle.USER_SYSTEM);
                if (packageInfo != null) {
                    EventLog.writeEvent(0x534e4554, "145981139", packageInfo.applicationInfo.uid,
                            "");
                }
                return null;
            }
        } finally {
            Binder.restoreCallingIdentity(token);
        }
        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 overrideLabelAndIcon(@NonNull ComponentName componentName,
            @NonNull String nonLocalizedLabel, int icon, int userId) {
        if (TextUtils.isEmpty(nonLocalizedLabel)) {
            throw new IllegalArgumentException("Override label should be a valid String");
        }
        updateComponentLabelIcon(componentName, nonLocalizedLabel, icon, userId);
    }

    @Override
    public void restoreLabelAndIcon(@NonNull ComponentName componentName, int userId) {
        updateComponentLabelIcon(componentName, null, null, userId);
    }

    @VisibleForTesting(visibility = Visibility.PRIVATE)
    public void updateComponentLabelIcon(/*@NonNull*/ ComponentName componentName,
            @Nullable String nonLocalizedLabel, @Nullable Integer icon, int userId) {
        if (componentName == null) {
            throw new IllegalArgumentException("Must specify a component");
        }

        boolean componentExists = mComponentResolver.componentExists(componentName);
        if (!componentExists) {
            throw new IllegalArgumentException("Component " + componentName + " not found");
        }

        int callingUid = Binder.getCallingUid();

        String componentPkgName = componentName.getPackageName();
        int componentUid = getPackageUid(componentPkgName, 0, userId);
        if (!UserHandle.isSameApp(callingUid, componentUid)) {
            throw new SecurityException("The calling UID (" + callingUid + ")"
                    + " does not match the target UID");
        }

        String allowedCallerPkg = mContext.getString(R.string.config_overrideComponentUiPackage);
        if (TextUtils.isEmpty(allowedCallerPkg)) {
            throw new SecurityException(
                    "There is no package defined as allowed to change a component's label or icon");
        }

        int allowedCallerUid = getPackageUid(allowedCallerPkg, PackageManager.MATCH_SYSTEM_ONLY,
                userId);
        if (allowedCallerUid == -1 || !UserHandle.isSameApp(callingUid, allowedCallerUid)) {
            throw new SecurityException("The calling UID (" + callingUid + ")"
                    + " is not allowed to change a component's label or icon");
        }

        synchronized (mLock) {
            AndroidPackage pkg = mPackages.get(componentPkgName);
            PackageSetting pkgSetting = getPackageSetting(componentPkgName);
            if (pkg == null || pkgSetting == null
                    || (!pkg.isSystem() && !pkgSetting.getPkgState().isUpdatedSystemApp())) {
                throw new SecurityException(
                        "Changing the label is not allowed for " + componentName);
            }

            if (!pkgSetting.overrideNonLocalizedLabelAndIcon(componentName, nonLocalizedLabel,
                    icon, userId)) {
                // Nothing changed
                return;
            }
        }

        ArrayList<String> components = mPendingBroadcasts.get(userId, componentPkgName);
        if (components == null) {
            components = new ArrayList<>();
            mPendingBroadcasts.put(userId, componentPkgName, components);
        }

        String className = componentName.getClassName();
        if (!components.contains(className)) {
            components.add(className);
        }

        if (!mHandler.hasMessages(SEND_PENDING_BROADCAST)) {
            mHandler.sendEmptyMessageDelayed(SEND_PENDING_BROADCAST, BROADCAST_DELAY);
        }
    }

    @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, pkgSetting)) {
                    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);
                if ((newState == COMPONENT_ENABLED_STATE_DISABLED_USER
                        || newState == COMPONENT_ENABLED_STATE_DISABLED)
                        && pkgSetting.getPermissionsState().hasPermission(
                                Manifest.permission.SUSPEND_APPS, userId)) {
                    // This app should not generally be allowed to get disabled by the UI, but if it
                    // ever does, we don't want to end up with some of the user's apps permanently
                    // suspended.
                    unsuspendForSuspendingPackage(packageName, userId);
                    removeAllDistractingPackageRestrictions(userId);
                }
            }
        } 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 || !AndroidPackageUtils.hasComponentClassName(pkg, 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);
        }
    }

    @WorkerThread
    @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) {
        // NOTE: this invokes synchronous disk access, so callers using this
        // method should consider running on a background thread
        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;
        final SparseArray<int[]> broadcastWhitelist;
        synchronized (mLock) {
            broadcastWhitelist = isInstantApp ? null : mAppsFilter.getVisibilityWhitelist(
                    getPackageSettingInternal(packageName, Process.SYSTEM_UID),
                    userIds, mSettings.mPackages);
        }
        sendPackageBroadcast(Intent.ACTION_PACKAGE_CHANGED,  packageName, extras, flags, null, null,
                userIds, instantUserIds, broadcastWhitelist);
    }

    @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;

        final InstallSource installSource;
        synchronized (mLock) {
            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;
                }
            }

            if (installSource.isInitiatingPackageUninstalled) {
                // We can't check visibility in the usual way, since the initiating package is no
                // longer present. So we apply simpler rules to whether to expose the info:
                // 1. Instant apps can't see it.
                // 2. Otherwise only the installed app itself can see it.
                final boolean isInstantApp = getInstantAppPackageName(callingUid) != null;
                if (!isInstantApp && isCallerSameApp(packageName, callingUid)) {
                    initiatingPackageName = installSource.initiatingPackageName;
                } else {
                    initiatingPackageName = null;
                }
            } else {
                // 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;
                }
            }
        }

        // Remaining work can safely be done outside the lock. (Note that installSource is
        // immutable so it's ok to carry on reading from it.)

        if (originatingPackageName != null && mContext.checkCallingOrSelfPermission(
                Manifest.permission.INSTALL_PACKAGES) != PackageManager.PERMISSION_GRANTED) {
            originatingPackageName = null;
        }

        // If you can see the initiatingPackageName, and we have valid signing info for it,
        // then we let you see that too.
        final SigningInfo initiatingPackageSigningInfo;
        final PackageSignatures signatures = installSource.initiatingPackageSignatures;
        if (initiatingPackageName != null && signatures != null
                && signatures.mSigningDetails != SigningDetails.UNKNOWN) {
            initiatingPackageSigningInfo = new SigningInfo(signatures.mSigningDetails);
        } else {
            initiatingPackageSigningInfo = null;
        }

        return new InstallSourceInfo(initiatingPackageName, initiatingPackageSigningInfo,
                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(), UserHandle.USER_SYSTEM, mContext);

        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();
        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();

        mExistingPackages = null;
    }

    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<PackageSetting> pkgSettings;
        if (packageName != null) {
            PackageSetting targetPkgSetting = mSettings.mPackages.get(packageName);
            if (targetPkgSetting != null) {
                pkgSettings = Collections.singletonList(targetPkgSetting);
            } else {
                ipw.println("Unable to find package: " + packageName);
                return;
            }
        } else {
            pkgSettings = mSettings.mPackages.values();
        }

        for (PackageSetting pkgSetting : pkgSettings) {
            if (pkgSetting.pkg == null) {
                continue;
            }
            ipw.println("[" + pkgSetting.name + "]");
            ipw.increaseIndent();
            mPackageDexOptimizer.dumpDexoptState(ipw, pkgSetting.pkg, pkgSetting,
                    mDexManager.getPackageUseInfoOrDefault(pkgSetting.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.getPackageName();
            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;
            // TODO: not sure how to handle this one.
            sendPackageBroadcast(action, null, extras, 0, null, finishedReceiver, null, 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 (absoluteCodePath.startsWith(absolutePath)) {
                    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();
        StorageManagerInternal smInternal = mInjector.getStorageManagerInternal();
        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);

                if (umInternal.isUserUnlockingOrUnlocked(user.id)) {
                    // Prepare app data on external storage; currently this is used to
                    // setup any OBB dirs that were created by the installer correctly.
                    int uid = UserHandle.getUid(user.id, UserHandle.getAppId(pkg.getUid()));
                    smInternal.prepareAppDataAfterInstall(pkg.getPackageName(), uid);
                }
            }
        }
    }

    /**
     * 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());

        String pkgSeInfo = AndroidPackageUtils.getSeInfo(pkg, ps);

        Preconditions.checkNotNull(pkgSeInfo);

        final String seInfo = pkgSeInfo + (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.isSystem()) {
                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, ps, userId, flags);
    }

    private void prepareAppDataContentsLIF(AndroidPackage pkg, @Nullable PackageSetting pkgSetting,
            int userId, int flags) {
        if (pkg == null) {
            Slog.wtf(TAG, "Package was null!", new Throwable());
            return;
        }
        prepareAppDataContentsLeafLIF(pkg, pkgSetting, userId, flags);
    }

    private void prepareAppDataContentsLeafLIF(AndroidPackage pkg,
            @Nullable PackageSetting pkgSetting, 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.
            String primaryCpuAbi = AndroidPackageUtils.getPrimaryCpuAbi(pkg, pkgSetting);
            if (primaryCpuAbi != null && !VMRuntime.is64BitAbi(primaryCpuAbi)) {
                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;
        final String fromCodePath;

        // 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.isSystem()) {
                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.isExternalStorage() && 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 = pkg.isExternalStorage();
            codeFile = new File(pkg.getCodePath());
            installSource = ps.installSource;
            packageAbiOverride = ps.cpuAbiOverrideString;
            appId = UserHandle.getAppId(pkg.getUid());
            seinfo = AndroidPackageUtils.getSeInfo(pkg, ps);
            label = String.valueOf(pm.getApplicationLabel(pkg.toAppInfoWithoutState()));
            targetSdkVersion = pkg.getTargetSdkVersion();
            freezer = freezePackage(packageName, "movePackageInternal");
            installedUserIds = ps.queryInstalledUsers(mUserManager.getUserIds(), true);
            if (codeFile.getParentFile().getName().startsWith(RANDOM_DIR_PREFIX)) {
                fromCodePath = codeFile.getParentFile().getAbsolutePath();
            } else {
                fromCodePath = codeFile.getAbsolutePath();
            }
        }

        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();

            move = new MoveInfo(moveId, currentVolumeUuid, volumeUuid, packageName,
                    appId, seinfo, targetSdkVersion, fromCodePath);
        } 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*/, MODE_DEFAULT /* autoRevokePermissions */,
                PackageParser.SigningDetails.UNKNOWN,
                PackageManager.INSTALL_REASON_UNKNOWN, PackageManager.VERSION_CODE_HIGHEST,
                DataLoaderType.NONE);
        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, pkg.isExternalStorage());

        if (!isPreviousLocationExternal && pkg.isExternalStorage()) {
            // Move from internal to external storage.
            FrameworkStatsLog.write(FrameworkStatsLog.APP_MOVED_STORAGE_REPORTED,
                    packageExternalStorageType,
                    FrameworkStatsLog.APP_MOVED_STORAGE_REPORTED__MOVE_TYPE__TO_EXTERNAL,
                    packageName);
        } else if (isPreviousLocationExternal && !pkg.isExternalStorage()) {
            // Move from external to internal storage.
            FrameworkStatsLog.write(FrameworkStatsLog.APP_MOVED_STORAGE_REPORTED,
                    packageExternalStorageType,
                    FrameworkStatsLog.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 userTypeInstallablePackages system packages that should be initially installed for
     *                                    this type of 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> userTypeInstallablePackages,
            String[] disallowedPackages) {
        synchronized (mInstallLock) {
            mSettings.createNewUserLI(this, mInstaller, userId,
                    userTypeInstallablePackages, disallowedPackages);
        }
        synchronized (mLock) {
            scheduleWritePackageRestrictionsLocked(userId);
            scheduleWritePackageListLocked(userId);
            primeDomainVerificationsLPw(userId);
        }
    }

    void onNewUserCreated(final int userId) {
        mPermissionManager.onNewUserCreated(userId);
    }

    boolean readPermissionStateForUser(@UserIdInt int userId) {
        synchronized (mPackages) {
            mSettings.readPermissionStateForUserSyncLPr(userId);
            return mPmInternal.isPermissionUpgradeNeeded(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 final class PackageChangeObserverDeathRecipient implements IBinder.DeathRecipient {
        private final IPackageChangeObserver mObserver;

        PackageChangeObserverDeathRecipient(IPackageChangeObserver observer) {
            mObserver = observer;
        }

        @Override
        public void binderDied() {
            synchronized (mPackageChangeObservers) {
                mPackageChangeObservers.remove(mObserver);
                Log.d(TAG, "Size of mPackageChangeObservers after removing dead observer is "
                    + mPackageChangeObservers.size());
            }
        }
    }

    private class PackageManagerNative extends IPackageManagerNative.Stub {
        @Override
        public void registerPackageChangeObserver(@NonNull IPackageChangeObserver observer) {
          synchronized (mPackageChangeObservers) {
            try {
                observer.asBinder().linkToDeath(
                    new PackageChangeObserverDeathRecipient(observer), 0);
            } catch (RemoteException e) {
              Log.e(TAG, e.getMessage());
            }
            mPackageChangeObservers.add(observer);
            Log.d(TAG, "Size of mPackageChangeObservers after registry is "
                + mPackageChangeObservers.size());
          }
        }

        @Override
        public void unregisterPackageChangeObserver(@NonNull IPackageChangeObserver observer) {
          synchronized (mPackageChangeObservers) {
            mPackageChangeObservers.remove(observer);
            Log.d(TAG, "Size of mPackageChangeObservers after unregistry is "
                + mPackageChangeObservers.size());
          }
        }

        @Override
        public String[] getAllPackages() {
            return PackageManagerService.this.getAllPackages().toArray(new String[0]);
        }

        @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 = getPackagesForUidInternal(uid, Process.SYSTEM_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 PackageSetting 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 (mLock) {
                    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) {
            return dropNonSystemPackages(getKnownPackageNamesInternal(knownPackage, userId));
        }

        private String[] getKnownPackageNamesInternal(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(
                            mDefaultTextClassifierPackage, mSystemTextClassifierPackageName);
                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_COMPANION:
                    return filterOnlySystemPackages("com.android.companiondevicemanager");
                case PackageManagerInternal.PACKAGE_RETAIL_DEMO:
                    return TextUtils.isEmpty(mRetailDemoPackage)
                            ? ArrayUtils.emptyArray(String.class)
                            : new String[] {mRetailDemoPackage};
                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 long getCeDataInode(String packageName, int userId) {
            synchronized (mLock) {
                final PackageSetting ps = mSettings.mPackages.get(packageName);
                if (ps != null) {
                    return ps.getCeDataInode(userId);
                }
                return 0;
            }
        }

        @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 void removeAllNonSystemPackageSuspensions(int userId) {
            final String[] allPackages;
            synchronized (mLock) {
                allPackages = mPackages.keySet().toArray(new String[mPackages.size()]);
            }
            PackageManagerService.this.removeSuspensionsBySuspendingPackage(allPackages,
                    (suspendingPackage) -> !PLATFORM_PACKAGE_NAME.equals(suspendingPackage),
                    userId);
        }

        @Override
        public void removeNonSystemPackageSuspensions(String packageName, int userId) {
            PackageManagerService.this.removeSuspensionsBySuspendingPackage(
                    new String[]{packageName},
                    (suspendingPackage) -> !PLATFORM_PACKAGE_NAME.equals(suspendingPackage),
                    userId);
        }

        @Override
        public void flushPackageRestrictions(int userId) {
            synchronized (mLock) {
                PackageManagerService.this.flushPackageRestrictionsAsUserInternalLocked(userId);
            }
        }

        @Override
        public void removeDistractingPackageRestrictions(String packageName, int userId) {
            PackageManagerService.this.removeDistractingPackageRestrictions(
                    new String[]{packageName}, userId);
        }

        @Override
        public void removeAllDistractingPackageRestrictions(int userId) {
            PackageManagerService.this.removeAllDistractingPackageRestrictions(userId);
        }

        @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 int getPackageUidInternal(String packageName, int flags, int userId) {
            return PackageManagerService.this
                    .getPackageUidInternal(packageName, flags, userId, Process.SYSTEM_UID);
        }

        @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, 0, 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 ComponentName getSystemUiServiceComponent() {
            return ComponentName.unflattenFromString(mContext.getResources().getString(
                    com.android.internal.R.string.config_systemUIServiceComponent));
        }

        @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 void setDeviceOwnerProtectedPackages(List<String> packageNames) {
            mProtectedPackages.setDeviceOwnerProtectedPackages(packageNames);
        }

        @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(ParsedMainComponent 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 void requestInstantAppResolutionPhaseTwo(AuxiliaryResolveInfo responseObj,
                Intent origIntent, String resolvedType, String callingPackage,
                @Nullable String callingFeatureId, boolean isRequesterInstantApp,
                Bundle verificationBundle, int userId) {
            PackageManagerService.this.requestInstantAppResolutionPhaseTwo(responseObj, origIntent,
                    resolvedType, callingPackage, callingFeatureId, isRequesterInstantApp,
                    verificationBundle, userId);
        }

        @Override
        public void grantImplicitAccess(int userId, Intent intent,
                int recipientAppId, int visibleUid, boolean direct) {
            synchronized (mLock) {
                final AndroidPackage visiblePackage = getPackage(visibleUid);
                final int recipientUid = UserHandle.getUid(userId, recipientAppId);
                if (visiblePackage == null || getPackage(recipientUid) == null) {
                    return;
                }

                final boolean instantApp =
                        isInstantAppInternal(visiblePackage.getPackageName(), userId, visibleUid);
                if (instantApp) {
                    if (!direct) {
                        // if the interaction that lead to this granting access to an instant app
                        // was indirect (i.e.: URI permission grant), do not actually execute the
                        // grant.
                        return;
                    }
                    mInstantAppRegistry.grantInstantAccessLPw(userId, intent,
                            recipientAppId, UserHandle.getAppId(visibleUid) /*instantAppId*/);
                } else {
                    mAppsFilter.grantImplicitAccess(recipientUid, visibleUid);
                }
            }
        }

        @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.isSystem() && pkg.isPersistent();
            }
        }

        @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,
                @NonNull Collection<String> outUpdatedPackageNames) {
            synchronized (mLock) {
                final AndroidPackage targetPkg = mPackages.get(targetPackageName);
                if (targetPackageName == null || targetPkg == 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());
                    }
                }

                ArraySet<String> updatedPackageNames = null;
                if (targetPkg.getLibraryNames() != null) {
                    // Set the overlay paths for dependencies of the shared library.
                    updatedPackageNames = new ArraySet<>();
                    for (String libName : targetPkg.getLibraryNames()) {
                        final SharedLibraryInfo info = getSharedLibraryInfoLPr(libName,
                                SharedLibraryInfo.VERSION_UNDEFINED);
                        if (info == null) {
                            continue;
                        }
                        final List<VersionedPackage> dependents = getPackagesUsingSharedLibraryLPr(
                                info, 0, userId);
                        if (dependents == null) {
                            continue;
                        }
                        for (VersionedPackage dependent : dependents) {
                            final PackageSetting ps = mSettings.mPackages.get(
                                    dependent.getPackageName());
                            if (ps == null) {
                                continue;
                            }
                            ps.setOverlayPathsForLibrary(libName, overlayPaths, userId);
                            updatedPackageNames.add(dependent.getPackageName());
                        }
                    }
                }

                final PackageSetting ps = mSettings.mPackages.get(targetPackageName);
                ps.setOverlayPaths(overlayPaths, userId);

                outUpdatedPackageNames.add(targetPackageName);
                if (updatedPackageNames != null) {
                    outUpdatedPackageNames.addAll(updatedPackageNames);
                }

                return true;
            }
        }

        @Override
        public ResolveInfo resolveIntent(Intent intent, String resolvedType,
                int flags, int privateResolveFlags, int userId, boolean resolveForStart,
                int filterCallingUid) {
            return resolveIntentInternal(
                    intent, resolvedType, flags, privateResolveFlags, 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
        @NonNull
        public String[] getSharedUserPackagesForPackage(String packageName, int userId) {
            synchronized (mLock) {
                return getSharedUserPackagesForPackageLocked(packageName, userId);
            }
        }

        @Override
        public ArrayMap<String, ProcessInfo> getProcessesForUid(int uid) {
            synchronized (mLock) {
                return getProcessesForUidLocked(uid);
            }
        }

        @Override
        public int[] getPermissionGids(String permissionName, int userId) {
            synchronized (mLock) {
                return getPermissionGidsLocked(permissionName, 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 forEachPackageSetting(Consumer<PackageSetting> actionLocked) {
            synchronized (mLock) {
                for (int index = 0; index < mSettings.mPackages.size(); index++) {
                    actionLocked.accept(mSettings.mPackages.valueAt(index));
                }
            }
        }

        @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 List<String> getApksInApex(String apexPackageName) {
            return PackageManagerService.this.mApexManager.getApksInApex(apexPackageName);
        }

        @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 updateRuntimePermissionsFingerprint(@UserIdInt int userId) {
            synchronized (mLock) {
                mSettings.updateRuntimePermissionsFingerprintLPr(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 isPermissionUpgradeNeeded(int userId) {
            synchronized (mLock) {
                return mSettings.isPermissionUpgradeNeededLPr(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);
        }

        @Override
        public List<String> getMimeGroup(String packageName, String mimeGroup) {
            return PackageManagerService.this.getMimeGroup(packageName, mimeGroup);
        }

        @Override
        public void setVisibilityLogging(String packageName, boolean enable) {
            final PackageSetting pkg;
            synchronized (mLock) {
                pkg = mSettings.getPackageLPr(packageName);
            }
            if (pkg == null) {
                throw new IllegalStateException("No package found for " + packageName);
            }
            mAppsFilter.getFeatureConfig().enableLogging(pkg.appId, enable);
        }

        @Override
        public boolean isSystemPackage(@NonNull String packageName) {
            return packageName.equals(
                    PackageManagerService.this.ensureSystemPackageName(packageName));
        }
    }

    @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")
    @NonNull
    private String[] getSharedUserPackagesForPackageLocked(String packageName, int userId) {
        final PackageSetting packageSetting = mSettings.mPackages.get(packageName);
        if (packageSetting == null || !packageSetting.isSharedUser()) {
            return EmptyArray.STRING;
        }

        ArraySet<PackageSetting> packages = packageSetting.sharedUser.packages;
        String[] res = new String[packages.size()];
        final Iterator<PackageSetting> it = 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);
        return res != null ? res : EmptyArray.STRING;
    }

    @GuardedBy("mLock")
    public ArrayMap<String, ProcessInfo> getProcessesForUidLocked(int uid) {
        final int appId = UserHandle.getAppId(uid);
        final SettingBase obj = mSettings.getSettingLPr(appId);
        if (obj instanceof SharedUserSetting) {
            final SharedUserSetting sus = (SharedUserSetting) obj;
            return PackageInfoUtils.generateProcessInfo(sus.processes, 0);
        } else if (obj instanceof PackageSetting) {
            final PackageSetting ps = (PackageSetting) obj;
            return PackageInfoUtils.generateProcessInfo(ps.pkg.getProcesses(), 0);
        }
        return null;
    }

    @GuardedBy("mLock")
    public int[] getPermissionGidsLocked(String permissionName, int userId) {
        BasePermission perm
                = mPermissionManager.getPermissionSettings().getPermission(permissionName);
        if (perm != null) {
            return perm.computeGids(userId);
        }
        return null;
    }

    @Override
    public int getRuntimePermissionsVersion(@UserIdInt int userId) {
        Preconditions.checkArgumentNonnegative(userId);
        enforceAdjustRuntimePermissionsPolicyOrUpgradeRuntimePermissions(
                "getRuntimePermissionVersion");
        synchronized (mLock) {
            return mSettings.getDefaultRuntimePermissionsVersionLPr(userId);
        }
    }

    @Override
    public void setRuntimePermissionsVersion(int version, @UserIdInt int userId) {
        Preconditions.checkArgumentNonnegative(version);
        Preconditions.checkArgumentNonnegative(userId);
        enforceAdjustRuntimePermissionsPolicyOrUpgradeRuntimePermissions(
                "setRuntimePermissionVersion");
        synchronized (mLock) {
            mSettings.setDefaultRuntimePermissionsVersionLPr(version, userId);
        }
    }

    private void enforceAdjustRuntimePermissionsPolicyOrUpgradeRuntimePermissions(
            @NonNull String message) {
        if (mContext.checkCallingOrSelfPermission(
                Manifest.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY)
                != PackageManager.PERMISSION_GRANTED
                && mContext.checkCallingOrSelfPermission(
                Manifest.permission.UPGRADE_RUNTIME_PERMISSIONS)
                != PackageManager.PERMISSION_GRANTED) {
            throw new SecurityException(message + " requires "
                    + Manifest.permission.ADJUST_RUNTIME_PERMISSIONS_POLICY + " or "
                    + Manifest.permission.UPGRADE_RUNTIME_PERMISSIONS);
        }
    }

    @Nullable
    public PackageSetting getPackageSetting(String packageName) {
        return getPackageSettingInternal(packageName, Binder.getCallingUid());
    }

    private PackageSetting getPackageSettingInternal(String packageName, int callingUid) {
        synchronized (mLock) {
            packageName = resolveInternalPackageNameInternalLocked(
                    packageName, PackageManager.VERSION_CODE_HIGHEST, callingUid);
            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 boolean isAutoRevokeWhitelisted(String packageName) {
        int mode = mInjector.getAppOpsManager().checkOpNoThrow(
                AppOpsManager.OP_AUTO_REVOKE_PERMISSIONS_IF_UNUSED,
                Binder.getCallingUid(), packageName);
        if (mode == MODE_ALLOWED) {
            return false;
        } else if (mode == MODE_IGNORED) {
            return true;
        } else {
            synchronized (mLock) {
                boolean manifestWhitelisted =
                        mPackages.get(packageName).getAutoRevokePermissions()
                                == ApplicationInfo.AUTO_REVOKE_DISALLOWED;
                return manifestWhitelisted;
            }
        }
    }

    @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);
            PackageSetting pkgSetting = mSettings.getPackageLPr(packageName);
            if (p == null || pkgSetting == null) {
                return false;
            }
            return AndroidPackageUtils.canHaveOatDir(p,
                    pkgSetting.getPkgState().isUpdatedSystemApp());
        }
    }

    private String getOatDir(AndroidPackage pkg, @NonNull PackageSetting pkgSetting) {
        if (!AndroidPackageUtils.canHaveOatDir(pkg,
                pkgSetting.getPkgState().isUpdatedSystemApp())) {
            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;
        final PackageSetting pkgSetting;
        synchronized (mLock) {
            pkg = mPackages.get(packageName);
            pkgSetting = mSettings.getPackageLPr(packageName);
        }
        instructionSets = getAppDexInstructionSets(
                AndroidPackageUtils.getPrimaryCpuAbi(pkg, pkgSetting),
                AndroidPackageUtils.getSecondaryCpuAbi(pkg, pkgSetting));
        codePaths = AndroidPackageUtils.getAllCodePaths(pkg);
        oatDir = getOatDir(pkg, pkgSetting);

        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,
                                ps.getPkgState().getLatestPackageUseTimeInMills(),
                                ps.getPkgState().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.broadcastIntentWithFeature(null, 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);
        }
    }

    private void applyMimeGroupChanges(String packageName, String mimeGroup) {
        if (mComponentResolver.updateMimeGroup(packageName, mimeGroup)) {
            clearPackagePreferredActivities(packageName, UserHandle.USER_ALL);
        }

        mPmInternal.writeSettings(false);
    }

    @Override
    public void setMimeGroup(String packageName, String mimeGroup, List<String> mimeTypes) {
        boolean changed = mSettings.mPackages.get(packageName)
                .setMimeGroup(mimeGroup, mimeTypes);

        if (changed) {
            applyMimeGroupChanges(packageName, mimeGroup);
        }
    }

    @Override
    public List<String> getMimeGroup(String packageName, String mimeGroup) {
        return mSettings.mPackages.get(packageName).getMimeGroup(mimeGroup);
    }

    static class ActiveInstallSession {
        private final String mPackageName;
        private final File mStagedDir;
        private final IPackageInstallObserver2 mObserver;
        private final int mSessionId;
        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,
                int sessionId, PackageInstaller.SessionParams sessionParams, int installerUid,
                InstallSource installSource, UserHandle user, SigningDetails signingDetails) {
            mPackageName = packageName;
            mStagedDir = stagedDir;
            mObserver = observer;
            mSessionId = sessionId;
            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 int getSessionId() {
            return mSessionId;
        }

        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,
        @Nullable SparseArray<int[]> broadcastWhitelist);
    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);
}
