diff --git a/services/core/java/com/android/server/pm/InstructionSets.java b/services/core/java/com/android/server/pm/InstructionSets.java
index f326f1d..ec48713 100644
--- a/services/core/java/com/android/server/pm/InstructionSets.java
+++ b/services/core/java/com/android/server/pm/InstructionSets.java
@@ -22,11 +22,11 @@
 import android.text.TextUtils;
 import android.util.ArraySet;
 
+import dalvik.system.VMRuntime;
+
 import java.util.ArrayList;
 import java.util.List;
 
-import dalvik.system.VMRuntime;
-
 /**
  * Provides various methods for obtaining and converting of instruction sets.
  *
@@ -113,12 +113,15 @@
         return allInstructionSets;
     }
 
-    public static String getPrimaryInstructionSet(ApplicationInfo info) {
-        if (info.primaryCpuAbi == null) {
+    /**
+     * Calculates the primary instruction set based on the computed Abis of a given package.
+     */
+    public static String getPrimaryInstructionSet(PackageAbiHelper.Abis abis) {
+        if (abis.primary == null) {
             return getPreferredInstructionSet();
         }
 
-        return VMRuntime.getInstructionSet(info.primaryCpuAbi);
+        return VMRuntime.getInstructionSet(abis.primary);
     }
 
 }
diff --git a/services/core/java/com/android/server/pm/PackageAbiHelper.java b/services/core/java/com/android/server/pm/PackageAbiHelper.java
new file mode 100644
index 0000000..6f46564
--- /dev/null
+++ b/services/core/java/com/android/server/pm/PackageAbiHelper.java
@@ -0,0 +1,135 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.pm;
+
+import android.annotation.Nullable;
+import android.content.pm.PackageParser;
+import android.util.Pair;
+
+import com.android.internal.annotations.VisibleForTesting;
+
+import java.io.File;
+import java.util.Set;
+
+@VisibleForTesting
+interface PackageAbiHelper {
+    /**
+     * Derive and get the location of native libraries for the given package,
+     * which varies depending on where and how the package was installed.
+     */
+    NativeLibraryPaths getNativeLibraryPaths(
+            PackageParser.Package pkg, File appLib32InstallDir);
+
+    /**
+     * Calculate the abis for a bundled app. These can uniquely be determined from the contents of
+     * the system partition, i.e whether it contains 64 or 32 bit shared libraries etc. We do not
+     * validate any of this information, and instead assume that the system was built sensibly.
+     */
+    Abis getBundledAppAbis(PackageParser.Package pkg);
+
+    /**
+     * Derive the ABI of a non-system package located at {@code pkg}. This information
+     * is derived purely on the basis of the contents of {@code pkg} and {@code cpuAbiOverride}.
+     *
+     * If {@code extractLibs} is true, native libraries are extracted from the app if required.
+     */
+    Pair<Abis, NativeLibraryPaths> derivePackageAbi(
+            PackageParser.Package pkg, String cpuAbiOverride, boolean extractLibs)
+            throws PackageManagerException;
+
+    /**
+     * Calculates adjusted ABIs for a set of packages belonging to a shared user so that they all
+     * match. i.e, so that all packages can be run inside a single process if required.
+     *
+     * Optionally, callers can pass in a parsed package via {@code scannedPackage} in which case
+     * this function will either try and make the ABI for all packages in
+     * {@code packagesForUser} match {@code scannedPackage} or will update the ABI of
+     * {@code scannedPackage} to match the ABI selected for {@code packagesForUser}. This
+     * variant is used when installing or updating a package that belongs to a shared user.
+     *
+     * NOTE: We currently only match for the primary CPU abi string. Matching the secondary
+     * adds unnecessary complexity.
+     *
+     * @return the calculated primary abi that should be set for all non-specified packages
+     *         belonging to the shared user.
+     */
+    @Nullable
+    String getAdjustedAbiForSharedUser(
+            Set<PackageSetting> packagesForUser, PackageParser.Package scannedPackage);
+
+    /**
+     * The native library paths and related properties that should be set on a
+     * {@link android.content.pm.PackageParser.Package}.
+     */
+    final class NativeLibraryPaths {
+        public final String nativeLibraryRootDir;
+        public final boolean nativeLibraryRootRequiresIsa;
+        public final String nativeLibraryDir;
+        public final String secondaryNativeLibraryDir;
+
+        @VisibleForTesting
+        NativeLibraryPaths(String nativeLibraryRootDir,
+                boolean nativeLibraryRootRequiresIsa, String nativeLibraryDir,
+                String secondaryNativeLibraryDir) {
+            this.nativeLibraryRootDir = nativeLibraryRootDir;
+            this.nativeLibraryRootRequiresIsa = nativeLibraryRootRequiresIsa;
+            this.nativeLibraryDir = nativeLibraryDir;
+            this.secondaryNativeLibraryDir = secondaryNativeLibraryDir;
+        }
+
+        public void applyTo(PackageParser.Package pkg) {
+            pkg.applicationInfo.nativeLibraryRootDir = nativeLibraryRootDir;
+            pkg.applicationInfo.nativeLibraryRootRequiresIsa = nativeLibraryRootRequiresIsa;
+            pkg.applicationInfo.nativeLibraryDir = nativeLibraryDir;
+            pkg.applicationInfo.secondaryNativeLibraryDir = secondaryNativeLibraryDir;
+        }
+    }
+
+    /**
+     * The primary and secondary ABIs that should be set on a package and its package setting.
+     */
+    final class Abis {
+        public final String primary;
+        public final String secondary;
+
+        @VisibleForTesting
+        Abis(String primary, String secondary) {
+            this.primary = primary;
+            this.secondary = secondary;
+        }
+
+        Abis(PackageParser.Package pkg) {
+            this(pkg.applicationInfo.primaryCpuAbi, pkg.applicationInfo.secondaryCpuAbi);
+        }
+
+        public void applyTo(PackageParser.Package pkg) {
+            pkg.applicationInfo.primaryCpuAbi = primary;
+            pkg.applicationInfo.secondaryCpuAbi = secondary;
+        }
+        public void applyTo(PackageSetting pkgSetting) {
+            // pkgSetting might be null during rescan following uninstall of updates
+            // to a bundled app, so accommodate that possibility.  The settings in
+            // that case will be established later from the parsed package.
+            //
+            // If the settings aren't null, sync them up with what we've derived.
+            if (pkgSetting != null) {
+                pkgSetting.primaryCpuAbiString = primary;
+                pkgSetting.secondaryCpuAbiString = secondary;
+            }
+        }
+    }
+}
diff --git a/services/core/java/com/android/server/pm/PackageAbiHelperImpl.java b/services/core/java/com/android/server/pm/PackageAbiHelperImpl.java
new file mode 100644
index 0000000..1d3d24c
--- /dev/null
+++ b/services/core/java/com/android/server/pm/PackageAbiHelperImpl.java
@@ -0,0 +1,528 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.pm;
+
+import static android.content.pm.PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
+import static android.content.pm.PackageParser.isApkFile;
+import static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER;
+
+import static com.android.internal.content.NativeLibraryHelper.LIB64_DIR_NAME;
+import static com.android.internal.content.NativeLibraryHelper.LIB_DIR_NAME;
+import static com.android.server.pm.InstructionSets.getPreferredInstructionSet;
+import static com.android.server.pm.InstructionSets.getPrimaryInstructionSet;
+
+import android.annotation.Nullable;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.PackageParser;
+import android.os.Build;
+import android.os.Environment;
+import android.os.FileUtils;
+import android.os.Trace;
+import android.text.TextUtils;
+import android.util.Pair;
+import android.util.Slog;
+
+import com.android.internal.content.NativeLibraryHelper;
+import com.android.internal.util.ArrayUtils;
+
+import dalvik.system.VMRuntime;
+
+import libcore.io.IoUtils;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Set;
+
+final class PackageAbiHelperImpl implements PackageAbiHelper {
+
+    private static String calculateBundledApkRoot(final String codePathString) {
+        final File codePath = new File(codePathString);
+        final File codeRoot;
+        if (FileUtils.contains(Environment.getRootDirectory(), codePath)) {
+            codeRoot = Environment.getRootDirectory();
+        } else if (FileUtils.contains(Environment.getOemDirectory(), codePath)) {
+            codeRoot = Environment.getOemDirectory();
+        } else if (FileUtils.contains(Environment.getVendorDirectory(), codePath)) {
+            codeRoot = Environment.getVendorDirectory();
+        } else if (FileUtils.contains(Environment.getOdmDirectory(), codePath)) {
+            codeRoot = Environment.getOdmDirectory();
+        } else if (FileUtils.contains(Environment.getProductDirectory(), codePath)) {
+            codeRoot = Environment.getProductDirectory();
+        } else if (FileUtils.contains(Environment.getSystemExtDirectory(), codePath)) {
+            codeRoot = Environment.getSystemExtDirectory();
+        } else if (FileUtils.contains(Environment.getOdmDirectory(), codePath)) {
+            codeRoot = Environment.getOdmDirectory();
+        } else {
+            // Unrecognized code path; take its top real segment as the apk root:
+            // e.g. /something/app/blah.apk => /something
+            try {
+                File f = codePath.getCanonicalFile();
+                File parent = f.getParentFile();    // non-null because codePath is a file
+                File tmp;
+                while ((tmp = parent.getParentFile()) != null) {
+                    f = parent;
+                    parent = tmp;
+                }
+                codeRoot = f;
+                Slog.w(PackageManagerService.TAG, "Unrecognized code path "
+                        + codePath + " - using " + codeRoot);
+            } catch (IOException e) {
+                // Can't canonicalize the code path -- shenanigans?
+                Slog.w(PackageManagerService.TAG, "Can't canonicalize code path " + codePath);
+                return Environment.getRootDirectory().getPath();
+            }
+        }
+        return codeRoot.getPath();
+    }
+
+    // Utility method that returns the relative package path with respect
+    // to the installation directory. Like say for /data/data/com.test-1.apk
+    // string com.test-1 is returned.
+    private static String deriveCodePathName(String codePath) {
+        if (codePath == null) {
+            return null;
+        }
+        final File codeFile = new File(codePath);
+        final String name = codeFile.getName();
+        if (codeFile.isDirectory()) {
+            return name;
+        } else if (name.endsWith(".apk") || name.endsWith(".tmp")) {
+            final int lastDot = name.lastIndexOf('.');
+            return name.substring(0, lastDot);
+        } else {
+            Slog.w(PackageManagerService.TAG, "Odd, " + codePath + " doesn't look like an APK");
+            return null;
+        }
+    }
+
+    private static void maybeThrowExceptionForMultiArchCopy(String message, int copyRet) throws
+            PackageManagerException {
+        if (copyRet < 0) {
+            if (copyRet != PackageManager.NO_NATIVE_LIBRARIES
+                    && copyRet != PackageManager.INSTALL_FAILED_NO_MATCHING_ABIS) {
+                throw new PackageManagerException(copyRet, message);
+            }
+        }
+    }
+
+    @Override
+    public NativeLibraryPaths getNativeLibraryPaths(
+            PackageParser.Package pkg, File appLib32InstallDir) {
+        return getNativeLibraryPaths(new Abis(pkg), appLib32InstallDir, pkg.codePath,
+                pkg.applicationInfo.sourceDir, pkg.applicationInfo.isSystemApp(),
+                pkg.applicationInfo.isUpdatedSystemApp());
+    }
+
+    private static NativeLibraryPaths getNativeLibraryPaths(final Abis abis,
+            final File appLib32InstallDir, final String codePath, final String sourceDir,
+            final boolean isSystemApp, final boolean isUpdatedSystemApp) {
+        final File codeFile = new File(codePath);
+        final boolean bundledApp = isSystemApp && !isUpdatedSystemApp;
+
+        final String nativeLibraryRootDir;
+        final boolean nativeLibraryRootRequiresIsa;
+        final String nativeLibraryDir;
+        final String secondaryNativeLibraryDir;
+
+        if (isApkFile(codeFile)) {
+            // Monolithic install
+            if (bundledApp) {
+                // If "/system/lib64/apkname" exists, assume that is the per-package
+                // native library directory to use; otherwise use "/system/lib/apkname".
+                final String apkRoot = calculateBundledApkRoot(sourceDir);
+                final boolean is64Bit = VMRuntime.is64BitInstructionSet(
+                        getPrimaryInstructionSet(abis));
+
+                // This is a bundled system app so choose the path based on the ABI.
+                // if it's a 64 bit abi, use lib64 otherwise use lib32. Note that this
+                // is just the default path.
+                final String apkName = deriveCodePathName(codePath);
+                final String libDir = is64Bit ? LIB64_DIR_NAME : LIB_DIR_NAME;
+                nativeLibraryRootDir = Environment.buildPath(new File(apkRoot), libDir,
+                        apkName).getAbsolutePath();
+
+                if (abis.secondary != null) {
+                    final String secondaryLibDir = is64Bit ? LIB_DIR_NAME : LIB64_DIR_NAME;
+                    secondaryNativeLibraryDir = Environment.buildPath(new File(apkRoot),
+                            secondaryLibDir, apkName).getAbsolutePath();
+                } else {
+                    secondaryNativeLibraryDir = null;
+                }
+            } else {
+                final String apkName = deriveCodePathName(codePath);
+                nativeLibraryRootDir = new File(appLib32InstallDir, apkName)
+                        .getAbsolutePath();
+                secondaryNativeLibraryDir = null;
+            }
+
+            nativeLibraryRootRequiresIsa = false;
+            nativeLibraryDir = nativeLibraryRootDir;
+        } else {
+            // Cluster install
+            nativeLibraryRootDir = new File(codeFile, LIB_DIR_NAME).getAbsolutePath();
+            nativeLibraryRootRequiresIsa = true;
+
+            nativeLibraryDir = new File(nativeLibraryRootDir,
+                    getPrimaryInstructionSet(abis)).getAbsolutePath();
+
+            if (abis.secondary != null) {
+                secondaryNativeLibraryDir = new File(nativeLibraryRootDir,
+                        VMRuntime.getInstructionSet(abis.secondary)).getAbsolutePath();
+            } else {
+                secondaryNativeLibraryDir = null;
+            }
+        }
+        return new NativeLibraryPaths(nativeLibraryRootDir, nativeLibraryRootRequiresIsa,
+                nativeLibraryDir, secondaryNativeLibraryDir);
+    }
+
+    @Override
+    public Abis getBundledAppAbis(PackageParser.Package pkg) {
+        final String apkName = deriveCodePathName(pkg.applicationInfo.getCodePath());
+
+        // If "/system/lib64/apkname" exists, assume that is the per-package
+        // native library directory to use; otherwise use "/system/lib/apkname".
+        final String apkRoot = calculateBundledApkRoot(pkg.applicationInfo.sourceDir);
+        final Abis abis = getBundledAppAbi(pkg, apkRoot, apkName);
+        return abis;
+    }
+
+    /**
+     * Deduces the ABI of a bundled app and sets the relevant fields on the
+     * parsed pkg object.
+     *
+     * @param apkRoot the root of the installed apk, something like {@code /system} or
+     *                {@code /oem} under which system libraries are installed.
+     * @param apkName the name of the installed package.
+     */
+    private Abis getBundledAppAbi(PackageParser.Package pkg, String apkRoot, String apkName) {
+        final File codeFile = new File(pkg.codePath);
+
+        final boolean has64BitLibs;
+        final boolean has32BitLibs;
+
+        final String primaryCpuAbi;
+        final String secondaryCpuAbi;
+        if (isApkFile(codeFile)) {
+            // Monolithic install
+            has64BitLibs =
+                    (new File(apkRoot, new File(LIB64_DIR_NAME, apkName).getPath())).exists();
+            has32BitLibs = (new File(apkRoot, new File(LIB_DIR_NAME, apkName).getPath())).exists();
+        } else {
+            // Cluster install
+            final File rootDir = new File(codeFile, LIB_DIR_NAME);
+            if (!ArrayUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS)
+                    && !TextUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS[0])) {
+                final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_64_BIT_ABIS[0]);
+                has64BitLibs = (new File(rootDir, isa)).exists();
+            } else {
+                has64BitLibs = false;
+            }
+            if (!ArrayUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS)
+                    && !TextUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS[0])) {
+                final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_32_BIT_ABIS[0]);
+                has32BitLibs = (new File(rootDir, isa)).exists();
+            } else {
+                has32BitLibs = false;
+            }
+        }
+
+        if (has64BitLibs && !has32BitLibs) {
+            // The package has 64 bit libs, but not 32 bit libs. Its primary
+            // ABI should be 64 bit. We can safely assume here that the bundled
+            // native libraries correspond to the most preferred ABI in the list.
+
+            primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
+            secondaryCpuAbi = null;
+        } else if (has32BitLibs && !has64BitLibs) {
+            // The package has 32 bit libs but not 64 bit libs. Its primary
+            // ABI should be 32 bit.
+
+            primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
+            secondaryCpuAbi = null;
+        } else if (has32BitLibs && has64BitLibs) {
+            // The application has both 64 and 32 bit bundled libraries. We check
+            // here that the app declares multiArch support, and warn if it doesn't.
+            //
+            // We will be lenient here and record both ABIs. The primary will be the
+            // ABI that's higher on the list, i.e, a device that's configured to prefer
+            // 64 bit apps will see a 64 bit primary ABI,
+
+            if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_MULTIARCH) == 0) {
+                Slog.e(PackageManagerService.TAG,
+                        "Package " + pkg + " has multiple bundled libs, but is not multiarch.");
+            }
+
+            if (VMRuntime.is64BitInstructionSet(getPreferredInstructionSet())) {
+                primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
+                secondaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
+            } else {
+                primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
+                secondaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
+            }
+        } else {
+            primaryCpuAbi = null;
+            secondaryCpuAbi = null;
+        }
+        return new Abis(primaryCpuAbi, secondaryCpuAbi);
+    }
+
+    @Override
+    public Pair<Abis, NativeLibraryPaths> derivePackageAbi(
+            PackageParser.Package pkg, String cpuAbiOverride, boolean extractLibs)
+            throws PackageManagerException {
+        // Give ourselves some initial paths; we'll come back for another
+        // pass once we've determined ABI below.
+        final NativeLibraryPaths initialLibraryPaths = getNativeLibraryPaths(new Abis(pkg),
+                PackageManagerService.sAppLib32InstallDir, pkg.codePath,
+                pkg.applicationInfo.sourceDir, pkg.applicationInfo.isSystemApp(),
+                pkg.applicationInfo.isUpdatedSystemApp());
+
+        // We shouldn't attempt to extract libs from system app when it was not updated.
+        if (PackageManagerService.isSystemApp(pkg) && !pkg.isUpdatedSystemApp()) {
+            extractLibs = false;
+        }
+
+        final String nativeLibraryRootStr = initialLibraryPaths.nativeLibraryRootDir;
+        final boolean useIsaSpecificSubdirs = initialLibraryPaths.nativeLibraryRootRequiresIsa;
+
+        String primaryCpuAbi = null;
+        String secondaryCpuAbi = null;
+
+        NativeLibraryHelper.Handle handle = null;
+        try {
+            handle = NativeLibraryHelper.Handle.create(pkg);
+            // TODO(multiArch): This can be null for apps that didn't go through the
+            // usual installation process. We can calculate it again, like we
+            // do during install time.
+            //
+            // TODO(multiArch): Why do we need to rescan ASEC apps again ? It seems totally
+            // unnecessary.
+            final File nativeLibraryRoot = new File(nativeLibraryRootStr);
+
+            // Null out the abis so that they can be recalculated.
+            primaryCpuAbi = null;
+            secondaryCpuAbi = null;
+            if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_MULTIARCH) != 0) {
+                // Warn if we've set an abiOverride for multi-lib packages..
+                // By definition, we need to copy both 32 and 64 bit libraries for
+                // such packages.
+                if (pkg.cpuAbiOverride != null
+                        && !NativeLibraryHelper.CLEAR_ABI_OVERRIDE.equals(pkg.cpuAbiOverride)) {
+                    Slog.w(PackageManagerService.TAG,
+                            "Ignoring abiOverride for multi arch application.");
+                }
+
+                int abi32 = PackageManager.NO_NATIVE_LIBRARIES;
+                int abi64 = PackageManager.NO_NATIVE_LIBRARIES;
+                if (Build.SUPPORTED_32_BIT_ABIS.length > 0) {
+                    if (extractLibs) {
+                        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyNativeBinaries");
+                        abi32 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
+                                nativeLibraryRoot, Build.SUPPORTED_32_BIT_ABIS,
+                                useIsaSpecificSubdirs);
+                    } else {
+                        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "findSupportedAbi");
+                        abi32 = NativeLibraryHelper.findSupportedAbi(
+                                handle, Build.SUPPORTED_32_BIT_ABIS);
+                    }
+                    Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
+                }
+
+                // Shared library native code should be in the APK zip aligned
+                if (abi32 >= 0 && pkg.isLibrary() && extractLibs) {
+                    throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
+                            "Shared library native lib extraction not supported");
+                }
+
+                maybeThrowExceptionForMultiArchCopy(
+                        "Error unpackaging 32 bit native libs for multiarch app.", abi32);
+
+                if (Build.SUPPORTED_64_BIT_ABIS.length > 0) {
+                    if (extractLibs) {
+                        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyNativeBinaries");
+                        abi64 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
+                                nativeLibraryRoot, Build.SUPPORTED_64_BIT_ABIS,
+                                useIsaSpecificSubdirs);
+                    } else {
+                        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "findSupportedAbi");
+                        abi64 = NativeLibraryHelper.findSupportedAbi(
+                                handle, Build.SUPPORTED_64_BIT_ABIS);
+                    }
+                    Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
+                }
+
+                maybeThrowExceptionForMultiArchCopy(
+                        "Error unpackaging 64 bit native libs for multiarch app.", abi64);
+
+                if (abi64 >= 0) {
+                    // Shared library native libs should be in the APK zip aligned
+                    if (extractLibs && pkg.isLibrary()) {
+                        throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
+                                "Shared library native lib extraction not supported");
+                    }
+                    primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[abi64];
+                }
+
+                if (abi32 >= 0) {
+                    final String abi = Build.SUPPORTED_32_BIT_ABIS[abi32];
+                    if (abi64 >= 0) {
+                        if (pkg.use32bitAbi) {
+                            secondaryCpuAbi = primaryCpuAbi;
+                            primaryCpuAbi = abi;
+                        } else {
+                            secondaryCpuAbi = abi;
+                        }
+                    } else {
+                        primaryCpuAbi = abi;
+                    }
+                }
+            } else {
+                String[] abiList = (cpuAbiOverride != null)
+                        ? new String[]{cpuAbiOverride} : Build.SUPPORTED_ABIS;
+
+                // Enable gross and lame hacks for apps that are built with old
+                // SDK tools. We must scan their APKs for renderscript bitcode and
+                // not launch them if it's present. Don't bother checking on devices
+                // that don't have 64 bit support.
+                boolean needsRenderScriptOverride = false;
+                if (Build.SUPPORTED_64_BIT_ABIS.length > 0 && cpuAbiOverride == null
+                        && NativeLibraryHelper.hasRenderscriptBitcode(handle)) {
+                    abiList = Build.SUPPORTED_32_BIT_ABIS;
+                    needsRenderScriptOverride = true;
+                }
+
+                final int copyRet;
+                if (extractLibs) {
+                    Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyNativeBinaries");
+                    copyRet = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
+                            nativeLibraryRoot, abiList, useIsaSpecificSubdirs);
+                } else {
+                    Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "findSupportedAbi");
+                    copyRet = NativeLibraryHelper.findSupportedAbi(handle, abiList);
+                }
+                Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
+
+                if (copyRet < 0 && copyRet != PackageManager.NO_NATIVE_LIBRARIES) {
+                    throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
+                            "Error unpackaging native libs for app, errorCode=" + copyRet);
+                }
+
+                if (copyRet >= 0) {
+                    // Shared libraries that have native libs must be multi-architecture
+                    if (pkg.isLibrary()) {
+                        throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
+                                "Shared library with native libs must be multiarch");
+                    }
+                    primaryCpuAbi = abiList[copyRet];
+                } else if (copyRet == PackageManager.NO_NATIVE_LIBRARIES
+                        && cpuAbiOverride != null) {
+                    primaryCpuAbi = cpuAbiOverride;
+                } else if (needsRenderScriptOverride) {
+                    primaryCpuAbi = abiList[0];
+                }
+            }
+        } catch (IOException ioe) {
+            Slog.e(PackageManagerService.TAG, "Unable to get canonical file " + ioe.toString());
+        } finally {
+            IoUtils.closeQuietly(handle);
+        }
+
+        // Now that we've calculated the ABIs and determined if it's an internal app,
+        // we will go ahead and populate the nativeLibraryPath.
+
+        final Abis abis = new Abis(primaryCpuAbi, secondaryCpuAbi);
+        return new Pair<>(abis,
+                getNativeLibraryPaths(abis, PackageManagerService.sAppLib32InstallDir,
+                        pkg.codePath, pkg.applicationInfo.sourceDir,
+                        pkg.applicationInfo.isSystemApp(),
+                        pkg.applicationInfo.isUpdatedSystemApp()));
+    }
+
+    /**
+     * Adjusts ABIs for a set of packages belonging to a shared user so that they all match.
+     * i.e, so that all packages can be run inside a single process if required.
+     *
+     * Optionally, callers can pass in a parsed package via {@code newPackage} in which case
+     * this function will either try and make the ABI for all packages in
+     * {@code packagesForUser} match {@code scannedPackage} or will update the ABI of
+     * {@code scannedPackage} to match the ABI selected for {@code packagesForUser}. This
+     * variant is used when installing or updating a package that belongs to a shared user.
+     *
+     * NOTE: We currently only match for the primary CPU abi string. Matching the secondary
+     * adds unnecessary complexity.
+     */
+    @Override
+    @Nullable
+    public String getAdjustedAbiForSharedUser(
+            Set<PackageSetting> packagesForUser, PackageParser.Package scannedPackage) {
+        String requiredInstructionSet = null;
+        if (scannedPackage != null && scannedPackage.applicationInfo.primaryCpuAbi != null) {
+            requiredInstructionSet = VMRuntime.getInstructionSet(
+                    scannedPackage.applicationInfo.primaryCpuAbi);
+        }
+
+        PackageSetting requirer = null;
+        for (PackageSetting ps : packagesForUser) {
+            // If packagesForUser contains scannedPackage, we skip it. This will happen
+            // when scannedPackage is an update of an existing package. Without this check,
+            // we will never be able to change the ABI of any package belonging to a shared
+            // user, even if it's compatible with other packages.
+            if (scannedPackage != null && scannedPackage.packageName.equals(ps.name)) {
+                continue;
+            }
+            if (ps.primaryCpuAbiString == null) {
+                continue;
+            }
+
+            final String instructionSet =
+                    VMRuntime.getInstructionSet(ps.primaryCpuAbiString);
+            if (requiredInstructionSet != null && !requiredInstructionSet.equals(instructionSet)) {
+                // We have a mismatch between instruction sets (say arm vs arm64) warn about
+                // this but there's not much we can do.
+                String errorMessage = "Instruction set mismatch, "
+                        + ((requirer == null) ? "[caller]" : requirer)
+                        + " requires " + requiredInstructionSet + " whereas " + ps
+                        + " requires " + instructionSet;
+                Slog.w(PackageManagerService.TAG, errorMessage);
+            }
+
+            if (requiredInstructionSet == null) {
+                requiredInstructionSet = instructionSet;
+                requirer = ps;
+            }
+        }
+
+        if (requiredInstructionSet == null) {
+            return null;
+        }
+        final String adjustedAbi;
+        if (requirer != null) {
+            // requirer != null implies that either scannedPackage was null or that
+            // scannedPackage did not require an ABI, in which case we have to adjust
+            // scannedPackage to match the ABI of the set (which is the same as
+            // requirer's ABI)
+            adjustedAbi = requirer.primaryCpuAbiString;
+        } else {
+            // requirer == null implies that we're updating all ABIs in the set to
+            // match scannedPackage.
+            adjustedAbi = scannedPackage.applicationInfo.primaryCpuAbi;
+        }
+        return adjustedAbi;
+    }
+}
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 54051ba..a77b728 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -93,14 +93,12 @@
 
 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.LIB64_DIR_NAME;
 import static com.android.internal.content.NativeLibraryHelper.LIB_DIR_NAME;
 import static com.android.server.pm.ComponentResolver.RESOLVE_PRIORITY_SORTER;
 import static com.android.server.pm.InstructionSets.getAppDexInstructionSets;
 import static com.android.server.pm.InstructionSets.getDexCodeInstructionSet;
 import static com.android.server.pm.InstructionSets.getDexCodeInstructionSets;
 import static com.android.server.pm.InstructionSets.getPreferredInstructionSet;
-import static com.android.server.pm.InstructionSets.getPrimaryInstructionSet;
 import static com.android.server.pm.PackageManagerServiceCompilerMapping.getDefaultCompilerFilter;
 import static com.android.server.pm.PackageManagerServiceUtils.compareSignatures;
 import static com.android.server.pm.PackageManagerServiceUtils.compressedFileExists;
@@ -278,6 +276,7 @@
 
 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;
@@ -433,7 +432,7 @@
     // user, but by default initialize to this.
     public static final boolean DEBUG_DEXOPT = false;
 
-    private static final boolean DEBUG_ABI_SELECTION = 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;
 
@@ -663,7 +662,8 @@
     private static final File sAppInstallDir =
             new File(Environment.getDataDirectory(), "app");
     /** Directory where installed application's 32-bit native libraries are copied. */
-    private static final File sAppLib32InstallDir =
+    @VisibleForTesting
+    static final File sAppLib32InstallDir =
             new File(Environment.getDataDirectory(), "app-lib");
 
     // ----------------------------------------------------------------
@@ -754,6 +754,30 @@
 
     private final ApexManager mApexManager;
 
+    private final Injector mInjector;
+
+    /**
+     * Unit tests will instantiate and / or extend to mock dependencies / behaviors.
+     */
+    @VisibleForTesting
+    static class Injector {
+        private final UserManagerInternal mUserManager;
+        private final PackageAbiHelper mAbiHelper;
+
+        Injector(UserManagerInternal userManager, PackageAbiHelper abiHelper) {
+            mUserManager = userManager;
+            mAbiHelper = abiHelper;
+        }
+
+        public UserManagerInternal getUserManager() {
+            return mUserManager;
+        }
+
+        public PackageAbiHelper getAbiHelper() {
+            return mAbiHelper;
+        }
+    }
+
     class PackageParserCallback implements PackageParser.Callback {
         @Override public final boolean hasFeature(String feature) {
             return PackageManagerService.this.hasSystemFeature(feature, 0);
@@ -2093,8 +2117,8 @@
             // 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).
+                // 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);
                 }
@@ -2164,6 +2188,7 @@
      * external/removable/unprotected storage.
      * @return {@link StorageEnum#TYPE_UNKNOWN} if the package is not stored externally or the
      * corresponding {@link StorageEnum} storage type value if it is.
+     * corresponding {@link StorageEnum} storage type value if it is.
      */
     private static int getPackageExternalStorageType(VolumeInfo packageVolume,
             boolean packageIsExternal) {
@@ -2421,6 +2446,11 @@
                     mPermissionManager.getPermissionSettings(), mPackages);
         }
         }
+
+        // TODO(b/137961986): We should pass this via constructor, but would first need to create
+        // a packages lock that could also be passed in.
+        mInjector = new Injector(getUserManagerInternal(), new PackageAbiHelperImpl());
+
         mSettings.addSharedUserLPw("android.uid.system", Process.SYSTEM_UID,
                 ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
         mSettings.addSharedUserLPw("android.uid.phone", RADIO_UID,
@@ -3128,7 +3158,9 @@
                 // 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 =
-                        adjustCpuAbisForSharedUserLPw(setting.packages, null /*scannedPackage*/);
+                        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);
@@ -9397,7 +9429,8 @@
                             null /* originalPkgSetting */, null, parseFlags, scanFlags,
                             (pkg == mPlatformPackage), user);
                     applyPolicy(pkg, parseFlags, scanFlags, mPlatformPackage);
-                    final ScanResult scanResult = scanPackageOnlyLI(request, mFactoryTest, -1L);
+                    final ScanResult scanResult =
+                            scanPackageOnlyLI(request, mInjector, mFactoryTest, -1L);
                     if (scanResult.existingSettingCopied && scanResult.request.pkgSetting != null) {
                         scanResult.request.pkgSetting.updateFrom(scanResult.pkgSetting);
                     }
@@ -10759,7 +10792,8 @@
     }
 
     /** The result of a package scan. */
-    private static class ScanResult {
+    @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 */
@@ -10798,7 +10832,8 @@
     }
 
     /** A package to be scanned */
-    private static class ScanRequest {
+    @VisibleForTesting
+    static class ScanRequest {
         /** The parsed package */
         @NonNull public final PackageParser.Package pkg;
         /** The package this package replaces */
@@ -10991,7 +11026,7 @@
                     pkgSetting == null ? null : pkgSetting.pkg, pkgSetting, disabledPkgSetting,
                     originalPkgSetting, realPkgName, parseFlags, scanFlags,
                     (pkg == mPlatformPackage), user);
-            return scanPackageOnlyLI(request, mFactoryTest, currentTime);
+            return scanPackageOnlyLI(request, mInjector, mFactoryTest, currentTime);
         }
     }
 
@@ -11216,20 +11251,70 @@
     }
 
     /**
+     * Applies the adjusted ABI calculated by
+     * {@link PackageAbiHelper#getAdjustedAbiForSharedUser(Set, PackageParser.Package)} 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,
+            PackageParser.Package scannedPackage, String adjustedAbi) {
+        if (scannedPackage != null)  {
+            scannedPackage.applicationInfo.primaryCpuAbi = adjustedAbi;
+        }
+        List<String> changedAbiCodePath = null;
+        for (PackageSetting ps : sharedUserSetting.packages) {
+            if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) {
+                if (ps.primaryCpuAbiString != null) {
+                    continue;
+                }
+
+                ps.primaryCpuAbiString = adjustedAbi;
+                if (ps.pkg != null && ps.pkg.applicationInfo != null
+                        && !TextUtils.equals(
+                        adjustedAbi, ps.pkg.applicationInfo.primaryCpuAbi)) {
+                    ps.pkg.applicationInfo.primaryCpuAbi = adjustedAbi;
+                    if (DEBUG_ABI_SELECTION) {
+                        Slog.i(TAG,
+                                "Adjusting ABI for " + ps.name + " to " + adjustedAbi
+                                        + " (scannedPackage="
+                                        + (scannedPackage != null ? scannedPackage : "null")
+                                        + ")");
+                    }
+                    if (changedAbiCodePath == null) {
+                        changedAbiCodePath = new ArrayList<>();
+                    }
+                    changedAbiCodePath.add(ps.codePathString);
+                }
+            }
+        }
+        return changedAbiCodePath;
+    }
+
+
+    /**
      * 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")
-    private static @NonNull ScanResult scanPackageOnlyLI(@NonNull ScanRequest request,
+    @VisibleForTesting
+    @NonNull
+    static ScanResult scanPackageOnlyLI(@NonNull ScanRequest request,
+            Injector injector,
             boolean isUnderFactoryTest, long currentTime)
-                    throws PackageManagerException {
+            throws PackageManagerException {
+        final PackageAbiHelper packageAbiHelper = injector.getAbiHelper();
+        final UserManagerInternal userManager = injector.getUserManager();
         final PackageParser.Package pkg = request.pkg;
         PackageSetting pkgSetting = request.pkgSetting;
         final PackageSetting disabledPkgSetting = request.disabledPkgSetting;
@@ -11335,7 +11420,7 @@
         if (!createNewPackage) {
             final boolean instantApp = (scanFlags & SCAN_AS_INSTANT_APP) != 0;
             final boolean fullApp = (scanFlags & SCAN_AS_FULL_APP) != 0;
-            setInstantAppForUser(pkgSetting, userId, instantApp, fullApp);
+            setInstantAppForUser(userManager, pkgSetting, userId, instantApp, fullApp);
         }
         // TODO(patb): see if we can do away with disabled check here.
         if (disabledPkgSetting != null
@@ -11381,7 +11466,10 @@
             if (needToDeriveAbi) {
                 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "derivePackageAbi");
                 final boolean extractNativeLibs = !pkg.isLibrary();
-                derivePackageAbi(pkg, cpuAbiOverride, extractNativeLibs);
+                final Pair<PackageAbiHelper.Abis, PackageAbiHelper.NativeLibraryPaths> derivedAbi =
+                        packageAbiHelper.derivePackageAbi(pkg, cpuAbiOverride, extractNativeLibs);
+                derivedAbi.first.applyTo(pkg);
+                derivedAbi.second.applyTo(pkg);
                 Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
 
                 // Some system apps still use directory structure for native libraries
@@ -11389,8 +11477,13 @@
                 // structure. Try to detect abi based on directory structure.
                 if (isSystemApp(pkg) && !pkg.isUpdatedSystemApp() &&
                         pkg.applicationInfo.primaryCpuAbi == null) {
-                    setBundledAppAbisAndRoots(pkg, pkgSetting);
-                    setNativeLibraryPaths(pkg, sAppLib32InstallDir);
+                    final PackageAbiHelper.Abis abis = packageAbiHelper.getBundledAppAbis(
+                            pkg);
+                    abis.applyTo(pkg);
+                    abis.applyTo(pkgSetting);
+                    final PackageAbiHelper.NativeLibraryPaths nativeLibraryPaths =
+                            packageAbiHelper.getNativeLibraryPaths(pkg, sAppLib32InstallDir);
+                    nativeLibraryPaths.applyTo(pkg);
                 }
             } else {
                 // This is not a first boot or an upgrade, don't bother deriving the
@@ -11399,7 +11492,9 @@
                 pkg.applicationInfo.primaryCpuAbi = primaryCpuAbiFromSettings;
                 pkg.applicationInfo.secondaryCpuAbi = secondaryCpuAbiFromSettings;
 
-                setNativeLibraryPaths(pkg, sAppLib32InstallDir);
+                final PackageAbiHelper.NativeLibraryPaths nativeLibraryPaths =
+                        packageAbiHelper.getNativeLibraryPaths(pkg, sAppLib32InstallDir);
+                nativeLibraryPaths.applyTo(pkg);
 
                 if (DEBUG_ABI_SELECTION) {
                     Slog.i(TAG, "Using ABIS and native lib paths from settings : " +
@@ -11420,7 +11515,9 @@
             // 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).
-            setNativeLibraryPaths(pkg, sAppLib32InstallDir);
+            final PackageAbiHelper.NativeLibraryPaths nativeLibraryPaths =
+                    packageAbiHelper.getNativeLibraryPaths(pkg, sAppLib32InstallDir);
+            nativeLibraryPaths.applyTo(pkg);
         }
 
         // This is a special case for the "system" package, where the ABI is
@@ -11474,8 +11571,9 @@
             // 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 =
-                    adjustCpuAbisForSharedUserLPw(pkgSetting.sharedUser.packages, pkg);
+            changedAbiCodePath = applyAdjustedAbiToSharedUser(pkgSetting.sharedUser, pkg,
+                    packageAbiHelper.getAdjustedAbiForSharedUser(
+                            pkgSetting.sharedUser.packages, pkg));
         }
 
         if (isUnderFactoryTest && pkg.requestedPermissions.contains(
@@ -12325,264 +12423,6 @@
         Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
     }
 
-    /**
-     * Derive the ABI of a non-system package located at {@code scanFile}. This information
-     * is derived purely on the basis of the contents of {@code scanFile} and
-     * {@code cpuAbiOverride}.
-     *
-     * If {@code extractLibs} is true, native libraries are extracted from the app if required.
-     */
-    private static void derivePackageAbi(PackageParser.Package pkg, String cpuAbiOverride,
-            boolean extractLibs)
-                    throws PackageManagerException {
-        // Give ourselves some initial paths; we'll come back for another
-        // pass once we've determined ABI below.
-        setNativeLibraryPaths(pkg, sAppLib32InstallDir);
-
-        // We shouldn't attempt to extract libs from system app when it was not updated.
-        if (isSystemApp(pkg) && !pkg.isUpdatedSystemApp()) {
-            extractLibs = false;
-        }
-
-        final String nativeLibraryRootStr = pkg.applicationInfo.nativeLibraryRootDir;
-        final boolean useIsaSpecificSubdirs = pkg.applicationInfo.nativeLibraryRootRequiresIsa;
-
-        NativeLibraryHelper.Handle handle = null;
-        try {
-            handle = NativeLibraryHelper.Handle.create(pkg);
-            // TODO(multiArch): This can be null for apps that didn't go through the
-            // usual installation process. We can calculate it again, like we
-            // do during install time.
-            //
-            // TODO(multiArch): Why do we need to rescan ASEC apps again ? It seems totally
-            // unnecessary.
-            final File nativeLibraryRoot = new File(nativeLibraryRootStr);
-
-            // Null out the abis so that they can be recalculated.
-            pkg.applicationInfo.primaryCpuAbi = null;
-            pkg.applicationInfo.secondaryCpuAbi = null;
-            if (isMultiArch(pkg.applicationInfo)) {
-                // Warn if we've set an abiOverride for multi-lib packages..
-                // By definition, we need to copy both 32 and 64 bit libraries for
-                // such packages.
-                if (pkg.cpuAbiOverride != null
-                        && !NativeLibraryHelper.CLEAR_ABI_OVERRIDE.equals(pkg.cpuAbiOverride)) {
-                    Slog.w(TAG, "Ignoring abiOverride for multi arch application.");
-                }
-
-                int abi32 = PackageManager.NO_NATIVE_LIBRARIES;
-                int abi64 = PackageManager.NO_NATIVE_LIBRARIES;
-                if (Build.SUPPORTED_32_BIT_ABIS.length > 0) {
-                    if (extractLibs) {
-                        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyNativeBinaries");
-                        abi32 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
-                                nativeLibraryRoot, Build.SUPPORTED_32_BIT_ABIS,
-                                useIsaSpecificSubdirs);
-                    } else {
-                        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "findSupportedAbi");
-                        abi32 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_32_BIT_ABIS);
-                    }
-                    Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
-                }
-
-                // Shared library native code should be in the APK zip aligned
-                if (abi32 >= 0 && pkg.isLibrary() && extractLibs) {
-                    throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
-                            "Shared library native lib extraction not supported");
-                }
-
-                maybeThrowExceptionForMultiArchCopy(
-                        "Error unpackaging 32 bit native libs for multiarch app.", abi32);
-
-                if (Build.SUPPORTED_64_BIT_ABIS.length > 0) {
-                    if (extractLibs) {
-                        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyNativeBinaries");
-                        abi64 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
-                                nativeLibraryRoot, Build.SUPPORTED_64_BIT_ABIS,
-                                useIsaSpecificSubdirs);
-                    } else {
-                        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "findSupportedAbi");
-                        abi64 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_64_BIT_ABIS);
-                    }
-                    Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
-                }
-
-                maybeThrowExceptionForMultiArchCopy(
-                        "Error unpackaging 64 bit native libs for multiarch app.", abi64);
-
-                if (abi64 >= 0) {
-                    // Shared library native libs should be in the APK zip aligned
-                    if (extractLibs && pkg.isLibrary()) {
-                        throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
-                                "Shared library native lib extraction not supported");
-                    }
-                    pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[abi64];
-                }
-
-                if (abi32 >= 0) {
-                    final String abi = Build.SUPPORTED_32_BIT_ABIS[abi32];
-                    if (abi64 >= 0) {
-                        if (pkg.use32bitAbi) {
-                            pkg.applicationInfo.secondaryCpuAbi = pkg.applicationInfo.primaryCpuAbi;
-                            pkg.applicationInfo.primaryCpuAbi = abi;
-                        } else {
-                            pkg.applicationInfo.secondaryCpuAbi = abi;
-                        }
-                    } else {
-                        pkg.applicationInfo.primaryCpuAbi = abi;
-                    }
-                }
-            } else {
-                String[] abiList = (cpuAbiOverride != null) ?
-                        new String[] { cpuAbiOverride } : Build.SUPPORTED_ABIS;
-
-                // Enable gross and lame hacks for apps that are built with old
-                // SDK tools. We must scan their APKs for renderscript bitcode and
-                // not launch them if it's present. Don't bother checking on devices
-                // that don't have 64 bit support.
-                boolean needsRenderScriptOverride = false;
-                if (Build.SUPPORTED_64_BIT_ABIS.length > 0 && cpuAbiOverride == null &&
-                        NativeLibraryHelper.hasRenderscriptBitcode(handle)) {
-                    abiList = Build.SUPPORTED_32_BIT_ABIS;
-                    needsRenderScriptOverride = true;
-                }
-
-                final int copyRet;
-                if (extractLibs) {
-                    Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyNativeBinaries");
-                    copyRet = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
-                            nativeLibraryRoot, abiList, useIsaSpecificSubdirs);
-                } else {
-                    Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "findSupportedAbi");
-                    copyRet = NativeLibraryHelper.findSupportedAbi(handle, abiList);
-                }
-                Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
-
-                if (copyRet < 0 && copyRet != PackageManager.NO_NATIVE_LIBRARIES) {
-                    throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
-                            "Error unpackaging native libs for app, errorCode=" + copyRet);
-                }
-
-                if (copyRet >= 0) {
-                    // Shared libraries that have native libs must be multi-architecture
-                    if (pkg.isLibrary()) {
-                        throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
-                                "Shared library with native libs must be multiarch");
-                    }
-                    pkg.applicationInfo.primaryCpuAbi = abiList[copyRet];
-                } else if (copyRet == PackageManager.NO_NATIVE_LIBRARIES && cpuAbiOverride != null) {
-                    pkg.applicationInfo.primaryCpuAbi = cpuAbiOverride;
-                } else if (needsRenderScriptOverride) {
-                    pkg.applicationInfo.primaryCpuAbi = abiList[0];
-                }
-            }
-        } catch (IOException ioe) {
-            Slog.e(TAG, "Unable to get canonical file " + ioe.toString());
-        } finally {
-            IoUtils.closeQuietly(handle);
-        }
-
-        // Now that we've calculated the ABIs and determined if it's an internal app,
-        // we will go ahead and populate the nativeLibraryPath.
-        setNativeLibraryPaths(pkg, sAppLib32InstallDir);
-    }
-
-    /**
-     * Adjusts ABIs for a set of packages belonging to a shared user so that they all match.
-     * i.e, so that all packages can be run inside a single process if required.
-     *
-     * Optionally, callers can pass in a parsed package via {@code newPackage} in which case
-     * this function will either try and make the ABI for all packages in {@code packagesForUser}
-     * match {@code scannedPackage} or will update the ABI of {@code scannedPackage} to match
-     * the ABI selected for {@code packagesForUser}. This variant is used when installing or
-     * updating a package that belongs to a shared user.
-     *
-     * NOTE: We currently only match for the primary CPU abi string. Matching the secondary
-     * adds unnecessary complexity.
-     */
-    private static @Nullable List<String> adjustCpuAbisForSharedUserLPw(
-            Set<PackageSetting> packagesForUser, PackageParser.Package scannedPackage) {
-        List<String> changedAbiCodePath = null;
-        String requiredInstructionSet = null;
-        if (scannedPackage != null && scannedPackage.applicationInfo.primaryCpuAbi != null) {
-            requiredInstructionSet = VMRuntime.getInstructionSet(
-                     scannedPackage.applicationInfo.primaryCpuAbi);
-        }
-
-        PackageSetting requirer = null;
-        for (PackageSetting ps : packagesForUser) {
-            // If packagesForUser contains scannedPackage, we skip it. This will happen
-            // when scannedPackage is an update of an existing package. Without this check,
-            // we will never be able to change the ABI of any package belonging to a shared
-            // user, even if it's compatible with other packages.
-            if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) {
-                if (ps.primaryCpuAbiString == null) {
-                    continue;
-                }
-
-                final String instructionSet = VMRuntime.getInstructionSet(ps.primaryCpuAbiString);
-                if (requiredInstructionSet != null && !instructionSet.equals(requiredInstructionSet)) {
-                    // We have a mismatch between instruction sets (say arm vs arm64) warn about
-                    // this but there's not much we can do.
-                    String errorMessage = "Instruction set mismatch, "
-                            + ((requirer == null) ? "[caller]" : requirer)
-                            + " requires " + requiredInstructionSet + " whereas " + ps
-                            + " requires " + instructionSet;
-                    Slog.w(TAG, errorMessage);
-                }
-
-                if (requiredInstructionSet == null) {
-                    requiredInstructionSet = instructionSet;
-                    requirer = ps;
-                }
-            }
-        }
-
-        if (requiredInstructionSet != null) {
-            String adjustedAbi;
-            if (requirer != null) {
-                // requirer != null implies that either scannedPackage was null or that scannedPackage
-                // did not require an ABI, in which case we have to adjust scannedPackage to match
-                // the ABI of the set (which is the same as requirer's ABI)
-                adjustedAbi = requirer.primaryCpuAbiString;
-                if (scannedPackage != null) {
-                    scannedPackage.applicationInfo.primaryCpuAbi = adjustedAbi;
-                }
-            } else {
-                // requirer == null implies that we're updating all ABIs in the set to
-                // match scannedPackage.
-                adjustedAbi =  scannedPackage.applicationInfo.primaryCpuAbi;
-            }
-
-            for (PackageSetting ps : packagesForUser) {
-                if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) {
-                    if (ps.primaryCpuAbiString != null) {
-                        continue;
-                    }
-
-                    ps.primaryCpuAbiString = adjustedAbi;
-                    if (ps.pkg != null && ps.pkg.applicationInfo != null &&
-                            !TextUtils.equals(adjustedAbi, ps.pkg.applicationInfo.primaryCpuAbi)) {
-                        ps.pkg.applicationInfo.primaryCpuAbi = adjustedAbi;
-                        if (DEBUG_ABI_SELECTION) {
-                            Slog.i(TAG, "Adjusting ABI for " + ps.name + " to " + adjustedAbi
-                                    + " (requirer="
-                                    + (requirer != null ? requirer.pkg : "null")
-                                    + ", scannedPackage="
-                                    + (scannedPackage != null ? scannedPackage : "null")
-                                    + ")");
-                        }
-                        if (changedAbiCodePath == null) {
-                            changedAbiCodePath = new ArrayList<>();
-                        }
-                        changedAbiCodePath.add(ps.codePathString);
-                    }
-                }
-            }
-        }
-        return changedAbiCodePath;
-    }
-
     private void setUpCustomResolverActivity(PackageParser.Package pkg) {
         synchronized (mPackages) {
             mResolverReplaced = true;
@@ -12634,207 +12474,6 @@
                 | IntentFilter.MATCH_ADJUSTMENT_NORMAL;
     }
 
-    private static String calculateBundledApkRoot(final String codePathString) {
-        final File codePath = new File(codePathString);
-        final File codeRoot;
-        if (FileUtils.contains(Environment.getRootDirectory(), codePath)) {
-            codeRoot = Environment.getRootDirectory();
-        } else if (FileUtils.contains(Environment.getOemDirectory(), codePath)) {
-            codeRoot = Environment.getOemDirectory();
-        } else if (FileUtils.contains(Environment.getVendorDirectory(), codePath)) {
-            codeRoot = Environment.getVendorDirectory();
-        } else if (FileUtils.contains(Environment.getOdmDirectory(), codePath)) {
-            codeRoot = Environment.getOdmDirectory();
-        } else if (FileUtils.contains(Environment.getProductDirectory(), codePath)) {
-            codeRoot = Environment.getProductDirectory();
-        } else if (FileUtils.contains(Environment.getSystemExtDirectory(), codePath)) {
-            codeRoot = Environment.getSystemExtDirectory();
-        } else if (FileUtils.contains(Environment.getOdmDirectory(), codePath)) {
-            codeRoot = Environment.getOdmDirectory();
-        } else {
-            // Unrecognized code path; take its top real segment as the apk root:
-            // e.g. /something/app/blah.apk => /something
-            try {
-                File f = codePath.getCanonicalFile();
-                File parent = f.getParentFile();    // non-null because codePath is a file
-                File tmp;
-                while ((tmp = parent.getParentFile()) != null) {
-                    f = parent;
-                    parent = tmp;
-                }
-                codeRoot = f;
-                Slog.w(TAG, "Unrecognized code path "
-                        + codePath + " - using " + codeRoot);
-            } catch (IOException e) {
-                // Can't canonicalize the code path -- shenanigans?
-                Slog.w(TAG, "Can't canonicalize code path " + codePath);
-                return Environment.getRootDirectory().getPath();
-            }
-        }
-        return codeRoot.getPath();
-    }
-
-    /**
-     * Derive and set the location of native libraries for the given package,
-     * which varies depending on where and how the package was installed.
-     */
-    private static void setNativeLibraryPaths(PackageParser.Package pkg, File appLib32InstallDir) {
-        final ApplicationInfo info = pkg.applicationInfo;
-        final String codePath = pkg.codePath;
-        final File codeFile = new File(codePath);
-        final boolean bundledApp = info.isSystemApp() && !info.isUpdatedSystemApp();
-
-        info.nativeLibraryRootDir = null;
-        info.nativeLibraryRootRequiresIsa = false;
-        info.nativeLibraryDir = null;
-        info.secondaryNativeLibraryDir = null;
-
-        if (isApkFile(codeFile)) {
-            // Monolithic install
-            if (bundledApp) {
-                // If "/system/lib64/apkname" exists, assume that is the per-package
-                // native library directory to use; otherwise use "/system/lib/apkname".
-                final String apkRoot = calculateBundledApkRoot(info.sourceDir);
-                final boolean is64Bit = VMRuntime.is64BitInstructionSet(
-                        getPrimaryInstructionSet(info));
-
-                // This is a bundled system app so choose the path based on the ABI.
-                // if it's a 64 bit abi, use lib64 otherwise use lib32. Note that this
-                // is just the default path.
-                final String apkName = deriveCodePathName(codePath);
-                final String libDir = is64Bit ? LIB64_DIR_NAME : LIB_DIR_NAME;
-                info.nativeLibraryRootDir = Environment.buildPath(new File(apkRoot), libDir,
-                        apkName).getAbsolutePath();
-
-                if (info.secondaryCpuAbi != null) {
-                    final String secondaryLibDir = is64Bit ? LIB_DIR_NAME : LIB64_DIR_NAME;
-                    info.secondaryNativeLibraryDir = Environment.buildPath(new File(apkRoot),
-                            secondaryLibDir, apkName).getAbsolutePath();
-                }
-            } else {
-                final String apkName = deriveCodePathName(codePath);
-                info.nativeLibraryRootDir = new File(appLib32InstallDir, apkName)
-                        .getAbsolutePath();
-            }
-
-            info.nativeLibraryRootRequiresIsa = false;
-            info.nativeLibraryDir = info.nativeLibraryRootDir;
-        } else {
-            // Cluster install
-            info.nativeLibraryRootDir = new File(codeFile, LIB_DIR_NAME).getAbsolutePath();
-            info.nativeLibraryRootRequiresIsa = true;
-
-            info.nativeLibraryDir = new File(info.nativeLibraryRootDir,
-                    getPrimaryInstructionSet(info)).getAbsolutePath();
-
-            if (info.secondaryCpuAbi != null) {
-                info.secondaryNativeLibraryDir = new File(info.nativeLibraryRootDir,
-                        VMRuntime.getInstructionSet(info.secondaryCpuAbi)).getAbsolutePath();
-            }
-        }
-    }
-
-    /**
-     * Calculate the abis and roots for a bundled app. These can uniquely
-     * be determined from the contents of the system partition, i.e whether
-     * it contains 64 or 32 bit shared libraries etc. We do not validate any
-     * of this information, and instead assume that the system was built
-     * sensibly.
-     */
-    private static void setBundledAppAbisAndRoots(PackageParser.Package pkg,
-                                           PackageSetting pkgSetting) {
-        final String apkName = deriveCodePathName(pkg.applicationInfo.getCodePath());
-
-        // If "/system/lib64/apkname" exists, assume that is the per-package
-        // native library directory to use; otherwise use "/system/lib/apkname".
-        final String apkRoot = calculateBundledApkRoot(pkg.applicationInfo.sourceDir);
-        setBundledAppAbi(pkg, apkRoot, apkName);
-        // pkgSetting might be null during rescan following uninstall of updates
-        // to a bundled app, so accommodate that possibility.  The settings in
-        // that case will be established later from the parsed package.
-        //
-        // If the settings aren't null, sync them up with what we've just derived.
-        // note that apkRoot isn't stored in the package settings.
-        if (pkgSetting != null) {
-            pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi;
-            pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi;
-        }
-    }
-
-    /**
-     * Deduces the ABI of a bundled app and sets the relevant fields on the
-     * parsed pkg object.
-     *
-     * @param apkRoot the root of the installed apk, something like {@code /system} or {@code /oem}
-     *        under which system libraries are installed.
-     * @param apkName the name of the installed package.
-     */
-    private static void setBundledAppAbi(PackageParser.Package pkg, String apkRoot, String apkName) {
-        final File codeFile = new File(pkg.codePath);
-
-        final boolean has64BitLibs;
-        final boolean has32BitLibs;
-        if (isApkFile(codeFile)) {
-            // Monolithic install
-            has64BitLibs = (new File(apkRoot, new File(LIB64_DIR_NAME, apkName).getPath())).exists();
-            has32BitLibs = (new File(apkRoot, new File(LIB_DIR_NAME, apkName).getPath())).exists();
-        } else {
-            // Cluster install
-            final File rootDir = new File(codeFile, LIB_DIR_NAME);
-            if (!ArrayUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS)
-                    && !TextUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS[0])) {
-                final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_64_BIT_ABIS[0]);
-                has64BitLibs = (new File(rootDir, isa)).exists();
-            } else {
-                has64BitLibs = false;
-            }
-            if (!ArrayUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS)
-                    && !TextUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS[0])) {
-                final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_32_BIT_ABIS[0]);
-                has32BitLibs = (new File(rootDir, isa)).exists();
-            } else {
-                has32BitLibs = false;
-            }
-        }
-
-        if (has64BitLibs && !has32BitLibs) {
-            // The package has 64 bit libs, but not 32 bit libs. Its primary
-            // ABI should be 64 bit. We can safely assume here that the bundled
-            // native libraries correspond to the most preferred ABI in the list.
-
-            pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
-            pkg.applicationInfo.secondaryCpuAbi = null;
-        } else if (has32BitLibs && !has64BitLibs) {
-            // The package has 32 bit libs but not 64 bit libs. Its primary
-            // ABI should be 32 bit.
-
-            pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
-            pkg.applicationInfo.secondaryCpuAbi = null;
-        } else if (has32BitLibs && has64BitLibs) {
-            // The application has both 64 and 32 bit bundled libraries. We check
-            // here that the app declares multiArch support, and warn if it doesn't.
-            //
-            // We will be lenient here and record both ABIs. The primary will be the
-            // ABI that's higher on the list, i.e, a device that's configured to prefer
-            // 64 bit apps will see a 64 bit primary ABI,
-
-            if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_MULTIARCH) == 0) {
-                Slog.e(TAG, "Package " + pkg + " has multiple bundled libs, but is not multiarch.");
-            }
-
-            if (VMRuntime.is64BitInstructionSet(getPreferredInstructionSet())) {
-                pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
-                pkg.applicationInfo.secondaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
-            } else {
-                pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
-                pkg.applicationInfo.secondaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
-            }
-        } else {
-            pkg.applicationInfo.primaryCpuAbi = null;
-            pkg.applicationInfo.secondaryCpuAbi = null;
-        }
-    }
-
     private void killApplication(String pkgName, int appId, String reason) {
         killApplication(pkgName, appId, UserHandle.USER_ALL, reason);
     }
@@ -13556,7 +13195,8 @@
                     // upgrade app from instant to full; we don't allow app downgrade
                     installed = true;
                 }
-                setInstantAppForUser(pkgSetting, userId, instantApp, fullApp);
+                setInstantAppForUser(
+                        getUserManagerInternal(), pkgSetting, userId, instantApp, fullApp);
             }
 
             if (installed) {
@@ -13604,8 +13244,8 @@
         }
     }
 
-    static void setInstantAppForUser(PackageSetting pkgSetting, int userId,
-            boolean instantApp, boolean fullApp) {
+    static void setInstantAppForUser(UserManagerInternal userManager, PackageSetting pkgSetting,
+            int userId, boolean instantApp, boolean fullApp) {
         // no state specified; do nothing
         if (!instantApp && !fullApp) {
             return;
@@ -13617,7 +13257,7 @@
                 pkgSetting.setInstantApp(false /*instantApp*/, userId);
             }
         } else {
-            for (int currentUserId : sUserManager.getUserIds()) {
+            for (int currentUserId : userManager.getUserIds()) {
                 if (instantApp && !pkgSetting.getInstantApp(currentUserId)) {
                     pkgSetting.setInstantApp(true /*instantApp*/, currentUserId);
                 } else if (fullApp && pkgSetting.getInstantApp(currentUserId)) {
@@ -15891,16 +15531,6 @@
         }
     }
 
-    private static void maybeThrowExceptionForMultiArchCopy(String message, int copyRet) throws
-            PackageManagerException {
-        if (copyRet < 0) {
-            if (copyRet != PackageManager.NO_NATIVE_LIBRARIES &&
-                    copyRet != PackageManager.INSTALL_FAILED_NO_MATCHING_ABIS) {
-                throw new PackageManagerException(copyRet, message);
-            }
-        }
-    }
-
     /**
      * Logic to handle movement of existing installed applications.
      */
@@ -16027,26 +15657,6 @@
         return result;
     }
 
-    // Utility method that returns the relative package path with respect
-    // to the installation directory. Like say for /data/data/com.test-1.apk
-    // string com.test-1 is returned.
-    static String deriveCodePathName(String codePath) {
-        if (codePath == null) {
-            return null;
-        }
-        final File codeFile = new File(codePath);
-        final String name = codeFile.getName();
-        if (codeFile.isDirectory()) {
-            return name;
-        } else if (name.endsWith(".apk") || name.endsWith(".tmp")) {
-            final int lastDot = name.lastIndexOf('.');
-            return name.substring(0, lastDot);
-        } else {
-            Slog.w(TAG, "Odd, " + codePath + " doesn't look like an APK");
-            return null;
-        }
-    }
-
     static class PackageInstalledInfo {
         String name;
         int uid;
@@ -16979,7 +16589,8 @@
                 final PrepareResult prepareResult;
                 try {
                     Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "preparePackage");
-                    prepareResult = preparePackageLI(request.args, request.installResult);
+                    prepareResult =
+                            preparePackageLI(request.args, request.installResult);
                 } catch (PrepareFailure prepareFailure) {
                     request.installResult.setError(prepareFailure.error,
                             prepareFailure.getMessage());
@@ -17639,7 +17250,11 @@
                 String abiOverride = (TextUtils.isEmpty(pkg.cpuAbiOverride) ?
                         args.abiOverride : pkg.cpuAbiOverride);
                 final boolean extractNativeLibs = !pkg.isLibrary();
-                derivePackageAbi(pkg, abiOverride, extractNativeLibs);
+                final Pair<PackageAbiHelper.Abis, PackageAbiHelper.NativeLibraryPaths>
+                        derivedAbi = mInjector.getAbiHelper().derivePackageAbi(
+                                pkg, abiOverride, extractNativeLibs);
+                derivedAbi.first.applyTo(pkg);
+                derivedAbi.second.applyTo(pkg);
             } catch (PackageManagerException pme) {
                 Slog.e(TAG, "Error deriving application ABI", pme);
                 throw new PrepareFailure(INSTALL_FAILED_INTERNAL_ERROR,
@@ -18168,10 +17783,6 @@
         }
     }
 
-    private static boolean isMultiArch(ApplicationInfo info) {
-        return (info.flags & ApplicationInfo.FLAG_MULTIARCH) != 0;
-    }
-
     private static boolean isExternal(PackageParser.Package pkg) {
         return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
     }
@@ -18180,7 +17791,7 @@
         return (ps.pkgFlags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
     }
 
-    private static boolean isSystemApp(PackageParser.Package pkg) {
+    static boolean isSystemApp(PackageParser.Package pkg) {
         return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
     }
 
diff --git a/services/core/java/com/android/server/pm/PackageSettingBase.java b/services/core/java/com/android/server/pm/PackageSettingBase.java
index 58f262c..029673f 100644
--- a/services/core/java/com/android/server/pm/PackageSettingBase.java
+++ b/services/core/java/com/android/server/pm/PackageSettingBase.java
@@ -270,7 +270,8 @@
         updateAvailable = orig.updateAvailable;
     }
 
-    private PackageUserState modifyUserState(int userId) {
+    @VisibleForTesting
+    PackageUserState modifyUserState(int userId) {
         PackageUserState state = mUserState.get(userId);
         if (state == null) {
             state = new PackageUserState();
@@ -463,6 +464,18 @@
         state.harmfulAppWarning = harmfulAppWarning;
     }
 
+    void setUserState(int userId, PackageUserState otherState) {
+        setUserState(userId, otherState.ceDataInode, otherState.enabled, otherState.installed,
+                otherState.stopped, otherState.notLaunched, otherState.hidden,
+                otherState.distractionFlags, otherState.suspended, otherState.suspendingPackage,
+                otherState.dialogInfo, otherState.suspendedAppExtras,
+                otherState.suspendedLauncherExtras, otherState.instantApp,
+                otherState.virtualPreload, otherState.lastDisableAppCaller,
+                otherState.enabledComponents, otherState.disabledComponents,
+                otherState.domainVerificationStatus, otherState.appLinkGeneration,
+                otherState.installReason, otherState.harmfulAppWarning);
+    }
+
     ArraySet<String> getEnabledComponents(int userId) {
         return readUserState(userId).enabledComponents;
     }
diff --git a/services/core/java/com/android/server/pm/TEST_MAPPING b/services/core/java/com/android/server/pm/TEST_MAPPING
index 15dc6ae..0101366 100644
--- a/services/core/java/com/android/server/pm/TEST_MAPPING
+++ b/services/core/java/com/android/server/pm/TEST_MAPPING
@@ -8,6 +8,20 @@
     },
     {
       "name": "CtsCompilationTestCases"
+    },
+    {
+      "name": "FrameworksServicesTests",
+      "options": [
+        {
+          "include-filter": "com.android.server.pm."
+        },
+        {
+          "include-annotation": "android.platform.test.annotations.Presubmit"
+        },
+        {
+          "exclude-annotation": "androidx.test.filters.FlakyTest"
+        }
+      ]
     }
   ],
   "imports": [
diff --git a/services/tests/servicestests/src/com/android/server/pm/PackageBuilder.java b/services/tests/servicestests/src/com/android/server/pm/PackageBuilder.java
new file mode 100644
index 0000000..470d4fa
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/pm/PackageBuilder.java
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.pm;
+
+import android.content.pm.PackageParser;
+
+import com.android.internal.util.ArrayUtils;
+
+class PackageBuilder {
+    final PackageParser.Package mPkg;
+
+    PackageBuilder(String packageName) {
+        mPkg = new PackageParser.Package(packageName);
+    }
+
+    PackageBuilder setApplicationInfoCodePath(String codePath) {
+        mPkg.applicationInfo.setCodePath(codePath);
+        return this;
+    }
+
+    PackageBuilder setApplicationInfoResourcePath(String resourcePath) {
+        mPkg.applicationInfo.setResourcePath(resourcePath);
+        return this;
+    }
+
+    PackageBuilder setCodePath(String codePath) {
+        mPkg.codePath = codePath;
+        return this;
+    }
+
+    PackageBuilder setBaseCodePath(String baseCodePath) {
+        mPkg.baseCodePath = baseCodePath;
+        return this;
+    }
+
+    PackageBuilder addUsesStaticLibrary(String name, long version) {
+        mPkg.usesStaticLibraries = ArrayUtils.add(mPkg.usesStaticLibraries, name);
+        mPkg.usesStaticLibrariesVersions =
+                ArrayUtils.appendLong(mPkg.usesStaticLibrariesVersions, version);
+        return this;
+    }
+
+    PackageBuilder setApplicationInfoNativeLibraryRootDir(String dir) {
+        mPkg.applicationInfo.nativeLibraryRootDir = dir;
+        return this;
+    }
+
+    PackageBuilder setStaticSharedLib(String staticSharedLibName, long staticSharedLibVersion) {
+        mPkg.staticSharedLibVersion = staticSharedLibVersion;
+        mPkg.staticSharedLibName = staticSharedLibName;
+        return this;
+    }
+
+    PackageBuilder setManifestPackageName(String manifestPackageName) {
+        mPkg.manifestPackageName = manifestPackageName;
+        return this;
+    }
+
+    PackageBuilder setVersionCodeMajor(int versionCodeMajor) {
+        mPkg.mVersionCodeMajor = versionCodeMajor;
+        return this;
+    }
+
+    PackageBuilder setVersionCode(int versionCode) {
+        mPkg.mVersionCode = versionCode;
+        return this;
+    }
+
+    PackageBuilder addSplitCodePath(String splitCodePath) {
+        mPkg.splitCodePaths =
+                ArrayUtils.appendElement(String.class, mPkg.splitCodePaths, splitCodePath);
+        return this;
+    }
+
+    PackageBuilder setApplicationInfoVolumeUuid(String volumeUuid) {
+        mPkg.applicationInfo.volumeUuid = volumeUuid;
+        return this;
+    }
+
+    PackageBuilder addLibraryName(String libraryName) {
+        mPkg.libraryNames = ArrayUtils.add(mPkg.libraryNames, libraryName);
+        return this;
+    }
+
+    PackageBuilder setRealPackageName(String realPackageName) {
+        mPkg.mRealPackage = realPackageName;
+        return this;
+    }
+
+    PackageBuilder setCpuAbiOVerride(String cpuAbiOverride) {
+        mPkg.cpuAbiOverride = cpuAbiOverride;
+        return this;
+    }
+
+    PackageBuilder addPermissionRequest(String permissionName) {
+        mPkg.requestedPermissions.add(permissionName);
+        return this;
+    }
+
+    PackageParser.Package build() {
+        return mPkg;
+    }
+
+    public PackageBuilder addApplicationInfoFlag(int flag) {
+        mPkg.applicationInfo.flags |= flag;
+        return this;
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/pm/PackageSettingBuilder.java b/services/tests/servicestests/src/com/android/server/pm/PackageSettingBuilder.java
new file mode 100644
index 0000000..b42cfd8
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/pm/PackageSettingBuilder.java
@@ -0,0 +1,154 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.pm;
+
+import android.content.pm.PackageUserState;
+import android.util.SparseArray;
+
+import java.io.File;
+import java.util.List;
+
+class PackageSettingBuilder {
+    private String mName;
+    private String mRealName;
+    private String mCodePath;
+    private String mResourcePath;
+    private String mLegacyNativeLibraryPathString;
+    private String mPrimaryCpuAbiString;
+    private String mSecondaryCpuAbiString;
+    private String mCpuAbiOverrideString;
+    private long mPVersionCode;
+    private int mPkgFlags;
+    private int mPrivateFlags;
+    private String mParentPackageName;
+    private List<String> mChildPackageNames;
+    private int mSharedUserId;
+    private String[] mUsesStaticLibraries;
+    private long[] mUsesStaticLibrariesVersions;
+    private String mVolumeUuid;
+    private SparseArray<PackageUserState> mUserStates = new SparseArray<>();
+
+    public PackageSettingBuilder setName(String name) {
+        this.mName = name;
+        return this;
+    }
+
+    public PackageSettingBuilder setRealName(String realName) {
+        this.mRealName = realName;
+        return this;
+    }
+
+    public PackageSettingBuilder setCodePath(String codePath) {
+        this.mCodePath = codePath;
+        return this;
+    }
+
+    public PackageSettingBuilder setResourcePath(String resourcePath) {
+        this.mResourcePath = resourcePath;
+        return this;
+    }
+
+    public PackageSettingBuilder setLegacyNativeLibraryPathString(
+            String legacyNativeLibraryPathString) {
+        this.mLegacyNativeLibraryPathString = legacyNativeLibraryPathString;
+        return this;
+    }
+
+    public PackageSettingBuilder setPrimaryCpuAbiString(String primaryCpuAbiString) {
+        this.mPrimaryCpuAbiString = primaryCpuAbiString;
+        return this;
+    }
+
+    public PackageSettingBuilder setSecondaryCpuAbiString(String secondaryCpuAbiString) {
+        this.mSecondaryCpuAbiString = secondaryCpuAbiString;
+        return this;
+    }
+
+    public PackageSettingBuilder setCpuAbiOverrideString(String cpuAbiOverrideString) {
+        this.mCpuAbiOverrideString = cpuAbiOverrideString;
+        return this;
+    }
+
+    public PackageSettingBuilder setPVersionCode(long pVersionCode) {
+        this.mPVersionCode = pVersionCode;
+        return this;
+    }
+
+    public PackageSettingBuilder setPkgFlags(int pkgFlags) {
+        this.mPkgFlags = pkgFlags;
+        return this;
+    }
+
+    public PackageSettingBuilder setPrivateFlags(int privateFlags) {
+        this.mPrivateFlags = privateFlags;
+        return this;
+    }
+
+    public PackageSettingBuilder setParentPackageName(String parentPackageName) {
+        this.mParentPackageName = parentPackageName;
+        return this;
+    }
+
+    public PackageSettingBuilder setChildPackageNames(List<String> childPackageNames) {
+        this.mChildPackageNames = childPackageNames;
+        return this;
+    }
+
+    public PackageSettingBuilder setSharedUserId(int sharedUserId) {
+        this.mSharedUserId = sharedUserId;
+        return this;
+    }
+
+    public PackageSettingBuilder setUsesStaticLibraries(String[] usesStaticLibraries) {
+        this.mUsesStaticLibraries = usesStaticLibraries;
+        return this;
+    }
+
+    public PackageSettingBuilder setUsesStaticLibrariesVersions(
+            long[] usesStaticLibrariesVersions) {
+        this.mUsesStaticLibrariesVersions = usesStaticLibrariesVersions;
+        return this;
+    }
+
+    public PackageSettingBuilder setVolumeUuid(String volumeUuid) {
+        this.mVolumeUuid = volumeUuid;
+        return this;
+    }
+
+    public PackageSettingBuilder setInstantAppUserState(int userId, boolean isInstant) {
+        if (mUserStates.indexOfKey(userId) < 0) {
+            mUserStates.put(userId, new PackageUserState());
+        }
+        mUserStates.get(userId).instantApp = isInstant;
+        return this;
+    }
+
+    public PackageSetting build() {
+        final PackageSetting packageSetting = new PackageSetting(mName, mRealName,
+                new File(mCodePath), new File(mResourcePath),
+                mLegacyNativeLibraryPathString, mPrimaryCpuAbiString, mSecondaryCpuAbiString,
+                mCpuAbiOverrideString, mPVersionCode, mPkgFlags, mPrivateFlags, mParentPackageName,
+                mChildPackageNames, mSharedUserId, mUsesStaticLibraries,
+                mUsesStaticLibrariesVersions);
+        packageSetting.volumeUuid = this.mVolumeUuid;
+        for (int i = 0; i < mUserStates.size(); i++) {
+            packageSetting.setUserState(mUserStates.keyAt(i), mUserStates.valueAt(i));
+        }
+        return packageSetting;
+
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/pm/ScanRequestBuilder.java b/services/tests/servicestests/src/com/android/server/pm/ScanRequestBuilder.java
new file mode 100644
index 0000000..34a3f86
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/pm/ScanRequestBuilder.java
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.pm;
+
+import android.content.pm.PackageParser;
+import android.os.UserHandle;
+
+class ScanRequestBuilder {
+    private final PackageParser.Package mPkg;
+    private PackageParser.Package mOldPkg;
+    private SharedUserSetting mSharedUserSetting;
+    private PackageSetting mPkgSetting;
+    private PackageSetting mDisabledPkgSetting;
+    private PackageSetting mOriginalPkgSetting;
+    private String mRealPkgName;
+    private int mParseFlags;
+    private int mScanFlags;
+    private UserHandle mUser;
+    private boolean mIsPlatformPackage;
+
+    ScanRequestBuilder(PackageParser.Package pkg) {
+        this.mPkg = pkg;
+    }
+
+    public ScanRequestBuilder setOldPkg(PackageParser.Package oldPkg) {
+        this.mOldPkg = oldPkg;
+        return this;
+    }
+
+    public ScanRequestBuilder setSharedUserSetting(SharedUserSetting sharedUserSetting) {
+        this.mSharedUserSetting = sharedUserSetting;
+        return this;
+    }
+
+    public ScanRequestBuilder setPkgSetting(PackageSetting pkgSetting) {
+        this.mPkgSetting = pkgSetting;
+        return this;
+    }
+
+    public ScanRequestBuilder setDisabledPkgSetting(PackageSetting disabledPkgSetting) {
+        this.mDisabledPkgSetting = disabledPkgSetting;
+        return this;
+    }
+
+    public ScanRequestBuilder setOriginalPkgSetting(PackageSetting originalPkgSetting) {
+        this.mOriginalPkgSetting = originalPkgSetting;
+        return this;
+    }
+
+    public ScanRequestBuilder setRealPkgName(String realPkgName) {
+        this.mRealPkgName = realPkgName;
+        return this;
+    }
+
+    public ScanRequestBuilder setParseFlags(int parseFlags) {
+        this.mParseFlags = parseFlags;
+        return this;
+    }
+
+    public ScanRequestBuilder addParseFlag(int parseFlag) {
+        this.mParseFlags |= parseFlag;
+        return this;
+    }
+
+    public ScanRequestBuilder setScanFlags(int scanFlags) {
+        this.mScanFlags = scanFlags;
+        return this;
+    }
+
+    public ScanRequestBuilder addScanFlag(int scanFlag) {
+        this.mScanFlags |= scanFlag;
+        return this;
+    }
+
+    public ScanRequestBuilder setUser(UserHandle user) {
+        this.mUser = user;
+        return this;
+    }
+
+    public ScanRequestBuilder setIsPlatformPackage(boolean isPlatformPackage) {
+        this.mIsPlatformPackage = isPlatformPackage;
+        return this;
+    }
+
+    PackageManagerService.ScanRequest build() {
+        return new PackageManagerService.ScanRequest(
+                mPkg, mSharedUserSetting, mOldPkg, mPkgSetting, mDisabledPkgSetting,
+                mOriginalPkgSetting, mRealPkgName, mParseFlags, mScanFlags, mIsPlatformPackage,
+                mUser);
+    }
+}
diff --git a/services/tests/servicestests/src/com/android/server/pm/ScanTests.java b/services/tests/servicestests/src/com/android/server/pm/ScanTests.java
new file mode 100644
index 0000000..dd3d8b9
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/pm/ScanTests.java
@@ -0,0 +1,551 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.pm;
+
+import static android.content.pm.SharedLibraryInfo.TYPE_DYNAMIC;
+import static android.content.pm.SharedLibraryInfo.TYPE_STATIC;
+import static android.content.pm.SharedLibraryInfo.VERSION_UNDEFINED;
+
+import static com.android.server.pm.PackageManagerService.SCAN_AS_FULL_APP;
+import static com.android.server.pm.PackageManagerService.SCAN_AS_INSTANT_APP;
+import static com.android.server.pm.PackageManagerService.SCAN_FIRST_BOOT_OR_UPGRADE;
+import static com.android.server.pm.PackageManagerService.SCAN_NEW_INSTALL;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.empty;
+import static org.hamcrest.Matchers.hasItems;
+import static org.hamcrest.Matchers.nullValue;
+import static org.hamcrest.collection.IsArrayContainingInOrder.arrayContaining;
+import static org.hamcrest.core.Is.is;
+import static org.junit.Assert.assertNotSame;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.nullable;
+import static org.mockito.Mockito.when;
+
+import android.Manifest;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageParser;
+import android.content.pm.SharedLibraryInfo;
+import android.os.Environment;
+import android.os.UserHandle;
+import android.os.UserManagerInternal;
+import android.platform.test.annotations.Presubmit;
+import android.util.Pair;
+
+import org.hamcrest.BaseMatcher;
+import org.hamcrest.Description;
+import org.hamcrest.Matcher;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.junit.MockitoJUnitRunner;
+
+import java.io.File;
+
+@RunWith(MockitoJUnitRunner.class)
+@Presubmit
+// TODO: shared user tests
+public class ScanTests {
+
+    private static final String DUMMY_PACKAGE_NAME = "some.app.to.test";
+
+    @Mock
+    PackageAbiHelper mMockPackageAbiHelper;
+    @Mock
+    UserManagerInternal mMockUserManager;
+
+    @Before
+    public void setupDefaultUser() {
+        when(mMockUserManager.getUserIds()).thenReturn(new int[]{0});
+    }
+
+    @Before
+    public void setupDefaultAbiBehavior() throws Exception {
+        when(mMockPackageAbiHelper.derivePackageAbi(
+                any(PackageParser.Package.class), nullable(String.class), anyBoolean()))
+                .thenReturn(new Pair<>(
+                        new PackageAbiHelper.Abis("derivedPrimary", "derivedSecondary"),
+                        new PackageAbiHelper.NativeLibraryPaths(
+                                "derivedRootDir", true, "derivedNativeDir", "derivedNativeDir2")));
+        when(mMockPackageAbiHelper.getNativeLibraryPaths(
+                any(PackageParser.Package.class), any(File.class)))
+                .thenReturn(new PackageAbiHelper.NativeLibraryPaths(
+                        "getRootDir", true, "getNativeDir", "getNativeDir2"
+                ));
+        when(mMockPackageAbiHelper.getBundledAppAbis(
+                any(PackageParser.Package.class)))
+                .thenReturn(new PackageAbiHelper.Abis("bundledPrimary", "bundledSecondary"));
+    }
+
+    @Test
+    public void newInstallSimpleAllNominal() throws Exception {
+        final PackageManagerService.ScanRequest scanRequest =
+                createBasicScanRequestBuilder(createBasicPackage(DUMMY_PACKAGE_NAME).build())
+                        .addScanFlag(PackageManagerService.SCAN_NEW_INSTALL)
+                        .addScanFlag(PackageManagerService.SCAN_AS_FULL_APP)
+                        .build();
+
+        final PackageManagerService.ScanResult scanResult = executeScan(scanRequest);
+
+        assertBasicPackageScanResult(scanResult, DUMMY_PACKAGE_NAME, false /*isInstant*/);
+        assertThat(scanResult.existingSettingCopied, is(false));
+        assertPathsNotDerived(scanResult);
+    }
+
+    @Test
+    public void newInstallForAllUsers() throws Exception {
+        final int[] userIds = {0, 10, 11};
+        when(mMockUserManager.getUserIds()).thenReturn(userIds);
+
+        final PackageManagerService.ScanRequest scanRequest =
+                createBasicScanRequestBuilder(createBasicPackage(DUMMY_PACKAGE_NAME).build())
+                        .setRealPkgName(null)
+                        .addScanFlag(PackageManagerService.SCAN_NEW_INSTALL)
+                        .addScanFlag(PackageManagerService.SCAN_AS_FULL_APP)
+                        .build();
+        final PackageManagerService.ScanResult scanResult = executeScan(scanRequest);
+
+        for (int uid : userIds) {
+            assertThat(scanResult.pkgSetting.readUserState(uid).installed, is(true));
+        }
+    }
+
+    @Test
+    public void installRealPackageName() throws Exception {
+        final PackageManagerService.ScanRequest scanRequest =
+                createBasicScanRequestBuilder(createBasicPackage(DUMMY_PACKAGE_NAME).build())
+                        .setRealPkgName("com.package.real")
+                        .build();
+
+        final PackageManagerService.ScanResult scanResult = executeScan(scanRequest);
+
+        assertThat(scanResult.pkgSetting.realName, is("com.package.real"));
+
+        final PackageManagerService.ScanRequest scanRequestNoRealPkg =
+                createBasicScanRequestBuilder(
+                        createBasicPackage(DUMMY_PACKAGE_NAME)
+                                .setRealPackageName("com.package.real").build())
+                        .build();
+
+        final PackageManagerService.ScanResult scanResultNoReal = executeScan(scanRequestNoRealPkg);
+        assertThat(scanResultNoReal.pkgSetting.realName, nullValue());
+    }
+
+    @Test
+    public void updateSimpleNominal() throws Exception {
+        when(mMockUserManager.getUserIds()).thenReturn(new int[]{0});
+
+        final PackageSetting pkgSetting = createBasicPackageSettingBuilder(DUMMY_PACKAGE_NAME)
+                .setPrimaryCpuAbiString("primaryCpuAbi")
+                .setSecondaryCpuAbiString("secondaryCpuAbi")
+                .build();
+        final PackageManagerService.ScanRequest scanRequest =
+                createBasicScanRequestBuilder(createBasicPackage(DUMMY_PACKAGE_NAME).build())
+                        .addScanFlag(PackageManagerService.SCAN_AS_FULL_APP)
+                        .setPkgSetting(pkgSetting)
+                        .build();
+
+
+        final PackageManagerService.ScanResult scanResult = executeScan(scanRequest);
+
+        assertThat(scanResult.existingSettingCopied, is(true));
+
+        // ensure we don't overwrite the existing pkgSetting, in case something post-scan fails
+        assertNotSame(pkgSetting, scanResult.pkgSetting);
+
+        assertBasicPackageScanResult(scanResult, DUMMY_PACKAGE_NAME, false /*isInstant*/);
+
+        assertThat(scanResult.pkgSetting.primaryCpuAbiString, is("primaryCpuAbi"));
+        assertThat(scanResult.pkgSetting.secondaryCpuAbiString, is("secondaryCpuAbi"));
+        assertThat(scanResult.pkgSetting.cpuAbiOverrideString, nullValue());
+
+        assertPathsNotDerived(scanResult);
+    }
+
+    @Test
+    public void updateInstantSimpleNominal() throws Exception {
+        when(mMockUserManager.getUserIds()).thenReturn(new int[]{0});
+
+        final PackageSetting existingPkgSetting =
+                createBasicPackageSettingBuilder(DUMMY_PACKAGE_NAME)
+                        .setInstantAppUserState(0, true)
+                        .build();
+
+        final PackageManagerService.ScanRequest scanRequest =
+                createBasicScanRequestBuilder(createBasicPackage(DUMMY_PACKAGE_NAME).build())
+                        .setPkgSetting(existingPkgSetting)
+                        .build();
+
+
+        final PackageManagerService.ScanResult scanResult = executeScan(scanRequest);
+
+        assertBasicPackageScanResult(scanResult, DUMMY_PACKAGE_NAME, true /*isInstant*/);
+    }
+
+    @Test
+    public void installStaticSharedLibrary() throws Exception {
+        final PackageParser.Package pkg = createBasicPackage("static.lib.pkg.123")
+                .setStaticSharedLib("static.lib", 123L)
+                .setManifestPackageName("static.lib.pkg")
+                .setVersionCodeMajor(1)
+                .setVersionCode(234)
+                .setBaseCodePath("/some/path.apk")
+                .addSplitCodePath("/some/other/path.apk")
+                .build();
+
+        final PackageManagerService.ScanRequest scanRequest = new ScanRequestBuilder(
+                pkg).setUser(UserHandle.of(0)).build();
+
+
+        final PackageManagerService.ScanResult scanResult = executeScan(scanRequest);
+
+        assertThat(scanResult.staticSharedLibraryInfo.getPackageName(), is("static.lib.pkg.123"));
+        assertThat(scanResult.staticSharedLibraryInfo.getName(), is("static.lib"));
+        assertThat(scanResult.staticSharedLibraryInfo.getLongVersion(), is(123L));
+        assertThat(scanResult.staticSharedLibraryInfo.getType(), is(TYPE_STATIC));
+        assertThat(scanResult.staticSharedLibraryInfo.getDeclaringPackage().getPackageName(),
+                is("static.lib.pkg"));
+        assertThat(scanResult.staticSharedLibraryInfo.getDeclaringPackage().getLongVersionCode(),
+                is(pkg.getLongVersionCode()));
+        assertThat(scanResult.staticSharedLibraryInfo.getAllCodePaths(),
+                hasItems("/some/path.apk", "/some/other/path.apk"));
+        assertThat(scanResult.staticSharedLibraryInfo.getDependencies(), nullValue());
+        assertThat(scanResult.staticSharedLibraryInfo.getDependentPackages(), empty());
+    }
+
+    @Test
+    public void installDynamicLibraries() throws Exception {
+        final PackageParser.Package pkg = createBasicPackage("dynamic.lib.pkg")
+                .setManifestPackageName("dynamic.lib.pkg")
+                .addLibraryName("liba")
+                .addLibraryName("libb")
+                .setVersionCodeMajor(1)
+                .setVersionCode(234)
+                .setBaseCodePath("/some/path.apk")
+                .addSplitCodePath("/some/other/path.apk")
+                .build();
+
+        final PackageManagerService.ScanRequest scanRequest =
+                new ScanRequestBuilder(pkg).setUser(UserHandle.of(0)).build();
+
+
+        final PackageManagerService.ScanResult scanResult = executeScan(scanRequest);
+
+        final SharedLibraryInfo dynamicLib0 = scanResult.dynamicSharedLibraryInfos.get(0);
+        assertThat(dynamicLib0.getPackageName(), is("dynamic.lib.pkg"));
+        assertThat(dynamicLib0.getName(), is("liba"));
+        assertThat(dynamicLib0.getLongVersion(), is((long) VERSION_UNDEFINED));
+        assertThat(dynamicLib0.getType(), is(TYPE_DYNAMIC));
+        assertThat(dynamicLib0.getDeclaringPackage().getPackageName(), is("dynamic.lib.pkg"));
+        assertThat(dynamicLib0.getDeclaringPackage().getLongVersionCode(),
+                is(pkg.getLongVersionCode()));
+        assertThat(dynamicLib0.getAllCodePaths(),
+                hasItems("/some/path.apk", "/some/other/path.apk"));
+        assertThat(dynamicLib0.getDependencies(), nullValue());
+        assertThat(dynamicLib0.getDependentPackages(), empty());
+
+        final SharedLibraryInfo dynamicLib1 = scanResult.dynamicSharedLibraryInfos.get(1);
+        assertThat(dynamicLib1.getPackageName(), is("dynamic.lib.pkg"));
+        assertThat(dynamicLib1.getName(), is("libb"));
+        assertThat(dynamicLib1.getLongVersion(), is((long) VERSION_UNDEFINED));
+        assertThat(dynamicLib1.getType(), is(TYPE_DYNAMIC));
+        assertThat(dynamicLib1.getDeclaringPackage().getPackageName(), is("dynamic.lib.pkg"));
+        assertThat(dynamicLib1.getDeclaringPackage().getLongVersionCode(),
+                is(pkg.getLongVersionCode()));
+        assertThat(dynamicLib1.getAllCodePaths(),
+                hasItems("/some/path.apk", "/some/other/path.apk"));
+        assertThat(dynamicLib1.getDependencies(), nullValue());
+        assertThat(dynamicLib1.getDependentPackages(), empty());
+    }
+
+    @Test
+    public void volumeUuidChangesOnUpdate() throws Exception {
+        final PackageSetting pkgSetting =
+                createBasicPackageSettingBuilder(DUMMY_PACKAGE_NAME)
+                        .setVolumeUuid("someUuid")
+                        .build();
+
+        final PackageParser.Package basicPackage = createBasicPackage(DUMMY_PACKAGE_NAME)
+                .setApplicationInfoVolumeUuid("someNewUuid")
+                .build();
+
+
+        final PackageManagerService.ScanResult scanResult = executeScan(
+                new ScanRequestBuilder(basicPackage).setPkgSetting(pkgSetting).build());
+
+        assertThat(scanResult.pkgSetting.volumeUuid, is("someNewUuid"));
+    }
+
+    @Test
+    public void scanFirstBoot_derivesAbis() throws Exception {
+        final PackageSetting pkgSetting =
+                createBasicPackageSettingBuilder(DUMMY_PACKAGE_NAME).build();
+
+        final PackageParser.Package basicPackage =
+                createBasicPackage(DUMMY_PACKAGE_NAME)
+                        .setCpuAbiOVerride("testOverride")
+                        .build();
+
+
+        final PackageManagerService.ScanResult scanResult = executeScan(new ScanRequestBuilder(
+                basicPackage)
+                .setPkgSetting(pkgSetting)
+                .addScanFlag(SCAN_FIRST_BOOT_OR_UPGRADE)
+                .build());
+
+        assertAbiAndPathssDerived(scanResult);
+    }
+
+    @Test
+    public void scanWithOriginalPkgSetting_packageNameChanges() throws Exception {
+        final PackageSetting originalPkgSetting =
+                createBasicPackageSettingBuilder("original.package").build();
+
+        final PackageParser.Package basicPackage =
+                createBasicPackage(DUMMY_PACKAGE_NAME)
+                        .build();
+
+
+        final PackageManagerService.ScanResult result =
+                executeScan(new ScanRequestBuilder(basicPackage)
+                        .setOriginalPkgSetting(originalPkgSetting)
+                        .build());
+
+        assertThat(result.request.pkg.packageName, is("original.package"));
+    }
+
+    @Test
+    public void updateInstant_changeToFull() throws Exception {
+        when(mMockUserManager.getUserIds()).thenReturn(new int[]{0});
+
+        final PackageSetting existingPkgSetting =
+                createBasicPackageSettingBuilder(DUMMY_PACKAGE_NAME)
+                        .setInstantAppUserState(0, true)
+                        .build();
+
+        final PackageManagerService.ScanRequest scanRequest =
+                createBasicScanRequestBuilder(createBasicPackage(DUMMY_PACKAGE_NAME).build())
+                        .setPkgSetting(existingPkgSetting)
+                        .addScanFlag(SCAN_AS_FULL_APP)
+                        .build();
+
+
+        final PackageManagerService.ScanResult scanResult = executeScan(scanRequest);
+
+        assertBasicPackageScanResult(scanResult, DUMMY_PACKAGE_NAME, false /*isInstant*/);
+    }
+
+    @Test
+    public void updateFull_changeToInstant() throws Exception {
+        when(mMockUserManager.getUserIds()).thenReturn(new int[]{0});
+
+        final PackageSetting existingPkgSetting =
+                createBasicPackageSettingBuilder(DUMMY_PACKAGE_NAME)
+                        .setInstantAppUserState(0, false)
+                        .build();
+
+        final PackageManagerService.ScanRequest scanRequest =
+                createBasicScanRequestBuilder(createBasicPackage(DUMMY_PACKAGE_NAME).build())
+                        .setPkgSetting(existingPkgSetting)
+                        .addScanFlag(SCAN_AS_INSTANT_APP)
+                        .build();
+
+
+        final PackageManagerService.ScanResult scanResult = executeScan(scanRequest);
+
+        assertBasicPackageScanResult(scanResult, DUMMY_PACKAGE_NAME, true /*isInstant*/);
+    }
+
+    @Test
+    public void updateSystemApp_applicationInfoFlagSet() throws Exception {
+        final PackageSetting existingPkgSetting =
+                createBasicPackageSettingBuilder(DUMMY_PACKAGE_NAME)
+                        .setPkgFlags(ApplicationInfo.FLAG_SYSTEM)
+                        .build();
+
+        final PackageManagerService.ScanRequest scanRequest =
+                createBasicScanRequestBuilder(createBasicPackage(DUMMY_PACKAGE_NAME).build())
+                        .setPkgSetting(existingPkgSetting)
+                        .setDisabledPkgSetting(existingPkgSetting)
+                        .addScanFlag(SCAN_NEW_INSTALL)
+                        .build();
+
+        final PackageManagerService.ScanResult scanResult = executeScan(scanRequest);
+
+        assertThat(scanResult.request.pkg.applicationInfo.flags,
+                hasFlag(ApplicationInfo.FLAG_UPDATED_SYSTEM_APP));
+    }
+
+    @Test
+    public void factoryTestFlagSet() throws Exception {
+        final PackageParser.Package basicPackage = createBasicPackage(DUMMY_PACKAGE_NAME)
+                .addPermissionRequest(Manifest.permission.FACTORY_TEST)
+                .build();
+
+        final PackageManagerService.ScanResult scanResult = PackageManagerService.scanPackageOnlyLI(
+                createBasicScanRequestBuilder(basicPackage).build(),
+                new PackageManagerService.Injector(mMockUserManager, mMockPackageAbiHelper),
+                true /*isUnderFactoryTest*/,
+                System.currentTimeMillis());
+
+        assertThat(scanResult.request.pkg.applicationInfo.flags,
+                hasFlag(ApplicationInfo.FLAG_FACTORY_TEST));
+    }
+
+    @Test
+    public void scanSystemApp_isOrphanedTrue() throws Exception {
+        final PackageParser.Package pkg = createBasicPackage(DUMMY_PACKAGE_NAME)
+                .addApplicationInfoFlag(ApplicationInfo.FLAG_SYSTEM)
+                .build();
+
+        final PackageManagerService.ScanRequest scanRequest =
+                createBasicScanRequestBuilder(pkg)
+                        .build();
+
+        final PackageManagerService.ScanResult scanResult = executeScan(scanRequest);
+
+        assertThat(scanResult.pkgSetting.isOrphaned, is(true));
+    }
+
+    private static Matcher<Integer> hasFlag(final int flag) {
+        return new BaseMatcher<Integer>() {
+            @Override public void describeTo(Description description) {
+                description.appendText("flags ");
+            }
+
+            @Override public boolean matches(Object item) {
+                return ((int) item & flag) != 0;
+            }
+
+            @Override
+            public void describeMismatch(Object item, Description mismatchDescription) {
+                mismatchDescription
+                        .appendValue(item)
+                        .appendText(" does not contain flag ")
+                        .appendValue(flag);
+            }
+        };
+    }
+
+    private PackageManagerService.ScanResult executeScan(
+            PackageManagerService.ScanRequest scanRequest) throws PackageManagerException {
+        return PackageManagerService.scanPackageOnlyLI(
+                scanRequest,
+                new PackageManagerService.Injector(mMockUserManager, mMockPackageAbiHelper),
+                false /*isUnderFactoryTest*/,
+                System.currentTimeMillis());
+    }
+
+    private static String createResourcePath(String packageName) {
+        return "/data/app/" + packageName + "-randompath/base.apk";
+    }
+
+    private static String createCodePath(String packageName) {
+        return "/data/app/" + packageName + "-randompath";
+    }
+
+    private static PackageSettingBuilder createBasicPackageSettingBuilder(String packageName) {
+        return new PackageSettingBuilder()
+                .setName(packageName)
+                .setCodePath(createCodePath(packageName))
+                .setResourcePath(createResourcePath(packageName));
+    }
+
+    private static ScanRequestBuilder createBasicScanRequestBuilder(PackageParser.Package pkg) {
+        return new ScanRequestBuilder(pkg)
+                .setUser(UserHandle.of(0));
+    }
+
+
+    private static PackageBuilder createBasicPackage(String packageName) {
+        return new PackageBuilder(packageName)
+                .setCodePath("/data/tmp/randompath")
+                .setApplicationInfoCodePath(createCodePath(packageName))
+                .setApplicationInfoResourcePath(createResourcePath(packageName))
+                .setApplicationInfoVolumeUuid("volumeUuid")
+                .setBaseCodePath("/data/tmp/randompath/base.apk")
+                .addUsesStaticLibrary("some.static.library", 234L)
+                .addUsesStaticLibrary("some.other.static.library", 456L)
+                .setApplicationInfoNativeLibraryRootDir("/data/tmp/randompath/base.apk:/lib")
+                .setVersionCodeMajor(1)
+                .setVersionCode(2345);
+    }
+
+    private static void assertBasicPackageScanResult(
+            PackageManagerService.ScanResult scanResult, String packageName, boolean isInstant) {
+        assertThat(scanResult.success, is(true));
+
+        final PackageSetting pkgSetting = scanResult.pkgSetting;
+        assertBasicPackageSetting(scanResult, packageName, isInstant, pkgSetting);
+
+        final ApplicationInfo applicationInfo = pkgSetting.pkg.applicationInfo;
+        assertBasicApplicationInfo(scanResult, applicationInfo);
+
+    }
+
+    private static void assertBasicPackageSetting(PackageManagerService.ScanResult scanResult,
+            String packageName, boolean isInstant, PackageSetting pkgSetting) {
+        assertThat(pkgSetting.pkg.packageName, is(packageName));
+        assertThat(pkgSetting.getInstantApp(0), is(isInstant));
+        assertThat(pkgSetting.usesStaticLibraries,
+                arrayContaining("some.static.library", "some.other.static.library"));
+        assertThat(pkgSetting.usesStaticLibrariesVersions, is(new long[]{234L, 456L}));
+        assertThat(pkgSetting.pkg, is(scanResult.request.pkg));
+        assertThat(pkgSetting.pkg.mExtras, is(pkgSetting));
+        assertThat(pkgSetting.codePath, is(new File(createCodePath(packageName))));
+        assertThat(pkgSetting.resourcePath, is(new File(createResourcePath(packageName))));
+        assertThat(pkgSetting.versionCode, is(PackageInfo.composeLongVersionCode(1, 2345)));
+    }
+
+    private static void assertBasicApplicationInfo(PackageManagerService.ScanResult scanResult,
+            ApplicationInfo applicationInfo) {
+        assertThat(applicationInfo.processName, is(scanResult.request.pkg.packageName));
+
+        final int uid = applicationInfo.uid;
+        assertThat(UserHandle.getUserId(uid), is(UserHandle.USER_SYSTEM));
+
+        final String calculatedCredentialId = Environment.getDataUserCePackageDirectory(
+                applicationInfo.volumeUuid, UserHandle.USER_SYSTEM,
+                scanResult.request.pkg.packageName).getAbsolutePath();
+        assertThat(applicationInfo.credentialProtectedDataDir, is(calculatedCredentialId));
+        assertThat(applicationInfo.dataDir, is(applicationInfo.credentialProtectedDataDir));
+    }
+
+    private static void assertAbiAndPathssDerived(PackageManagerService.ScanResult scanResult) {
+        final ApplicationInfo applicationInfo = scanResult.pkgSetting.pkg.applicationInfo;
+        assertThat(applicationInfo.primaryCpuAbi, is("derivedPrimary"));
+        assertThat(applicationInfo.secondaryCpuAbi, is("derivedSecondary"));
+
+        assertThat(applicationInfo.nativeLibraryRootDir, is("derivedRootDir"));
+        assertThat(scanResult.pkgSetting.legacyNativeLibraryPathString, is("derivedRootDir"));
+        assertThat(applicationInfo.nativeLibraryRootRequiresIsa, is(true));
+        assertThat(applicationInfo.nativeLibraryDir, is("derivedNativeDir"));
+        assertThat(applicationInfo.secondaryNativeLibraryDir, is("derivedNativeDir2"));
+    }
+
+    private static void assertPathsNotDerived(PackageManagerService.ScanResult scanResult) {
+        final ApplicationInfo applicationInfo = scanResult.pkgSetting.pkg.applicationInfo;
+        assertThat(applicationInfo.nativeLibraryRootDir, is("getRootDir"));
+        assertThat(scanResult.pkgSetting.legacyNativeLibraryPathString, is("getRootDir"));
+        assertThat(applicationInfo.nativeLibraryRootRequiresIsa, is(true));
+        assertThat(applicationInfo.nativeLibraryDir, is("getNativeDir"));
+        assertThat(applicationInfo.secondaryNativeLibraryDir, is("getNativeDir2"));
+    }
+}
