Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ec71fed0 authored by Brian Carlstrom's avatar Brian Carlstrom Committed by Gerrit Code Review
Browse files

Merge "Improve ABI handling for shared user ids."

parents 63bf04d8 b851c89d
Loading
Loading
Loading
Loading
+71 −26
Original line number Diff line number Diff line
@@ -5132,6 +5132,20 @@ public class PackageManagerService extends IPackageManager.Stub {
        }
        pkg.mScanPath = path;
        if ((scanMode&SCAN_BOOTING) == 0 && pkgSetting.sharedUser != null) {
            // We don't do this here during boot because we can do it all
            // at once after scanning all existing packages.
            //
            // We also do this *before* we perform dexopt on this package, so that
            // we can avoid redundant dexopts, and also to make sure we've got the
            // code and package path correct.
            if (!adjustCpuAbisForSharedUserLPw(pkgSetting.sharedUser.packages,
                    pkg, forceDex, (scanMode & SCAN_DEFER_DEX) != 0)) {
                mLastScanError = PackageManager.INSTALL_FAILED_CPU_ABI_INCOMPATIBLE;
                return null;
            }
        }
        if ((scanMode&SCAN_NO_DEX) == 0) {
            if (performDexOptLI(pkg, forceDex, (scanMode&SCAN_DEFER_DEX) != 0, false)
                    == DEX_OPT_FAILED) {
@@ -5251,16 +5265,6 @@ public class PackageManagerService extends IPackageManager.Stub {
        // writer
        synchronized (mPackages) {
            if ((scanMode&SCAN_BOOTING) == 0 && pkgSetting.sharedUser != null) {
                // We don't do this here during boot because we can do it all
                // at once after scanning all existing packages.
                if (!adjustCpuAbisForSharedUserLPw(pkgSetting.sharedUser.packages,
                        pkg.applicationInfo.cpuAbi,
                        forceDex, (scanMode & SCAN_DEFER_DEX) != 0)) {
                    mLastScanError = PackageManager.INSTALL_FAILED_CPU_ABI_INCOMPATIBLE;
                    return null;
                }
            }
            // We don't expect installation to fail beyond this point,
            if ((scanMode&SCAN_MONITOR) != 0) {
                mAppDirs.put(pkg.mPath, pkg);
@@ -5604,19 +5608,43 @@ public class PackageManagerService extends IPackageManager.Stub {
        return pkg;
    }
    /**
     * 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.
     */
    private boolean adjustCpuAbisForSharedUserLPw(Set<PackageSetting> packagesForUser,
            String requiredInstructionSet, boolean forceDexOpt, boolean deferDexOpt) {
            PackageParser.Package scannedPackage, boolean forceDexOpt, boolean deferDexOpt) {
        String requiredInstructionSet = null;
        if (scannedPackage != null && scannedPackage.applicationInfo.cpuAbi != null) {
            requiredInstructionSet = VMRuntime.getInstructionSet(
                     scannedPackage.applicationInfo.cpuAbi);
        }
        PackageSetting requirer = null;
        for (PackageSetting ps : packagesForUser) {
            if (ps.cpuAbiString != null) {
            // 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.cpuAbiString == null) {
                    continue;
                }
                final String instructionSet = VMRuntime.getInstructionSet(ps.cpuAbiString);
                if (requiredInstructionSet != null) {
                    if (!instructionSet.equals(requiredInstructionSet)) {
                        // We have a mismatch between instruction sets (say arm vs arm64).
                        // bail out.
                        String errorMessage = "Instruction set mismatch, "
                                + ((requirer == null) ? "[caller]" : requirer.pkg)
                                + " requires " + requiredInstructionSet + " whereas " + ps.pkg
                                + ((requirer == null) ? "[caller]" : requirer)
                                + " requires " + requiredInstructionSet + " whereas " + ps
                                + " requires " + instructionSet;
                        Slog.e(TAG, errorMessage);
@@ -5632,12 +5660,30 @@ public class PackageManagerService extends IPackageManager.Stub {
        }
        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.cpuAbiString;
                if (scannedPackage != null) {
                    scannedPackage.applicationInfo.cpuAbi = adjustedAbi;
                }
            } else {
                // requirer == null implies that we're updating all ABIs in the set to
                // match scannedPackage.
                adjustedAbi =  scannedPackage.applicationInfo.cpuAbi;
            }
            for (PackageSetting ps : packagesForUser) {
                if (ps.cpuAbiString == null) {
                    ps.cpuAbiString = requirer.cpuAbiString;
                    if (ps.pkg != null) {
                        ps.pkg.applicationInfo.cpuAbi = requirer.cpuAbiString;
                        Slog.i(TAG, "Adjusting ABI for : " + ps.name + " to " + ps.cpuAbiString);
                if (scannedPackage == null || ! scannedPackage.packageName.equals(ps.name)) {
                    if (ps.cpuAbiString != null) {
                        continue;
                    }
                    ps.cpuAbiString = adjustedAbi;
                    ps.pkg.applicationInfo.cpuAbi = adjustedAbi;
                    Slog.i(TAG, "Adjusting ABI for : " + ps.name + " to " + adjustedAbi);
                    if (performDexOptLI(ps.pkg, forceDexOpt, deferDexOpt, true) == DEX_OPT_FAILED) {
                        ps.cpuAbiString = null;
@@ -5649,7 +5695,6 @@ public class PackageManagerService extends IPackageManager.Stub {
                }
            }
        }
        }
        return true;
    }