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

Commit 4903f64b authored by Narayan Kamath's avatar Narayan Kamath
Browse files

Persist the cpuAbiOverride setting.

If an app is installed with an ABI override (adb install -r --abi)
we should remember this so that we don't revert to the scan derived
ABI on the next reboot.

bug: 16476618

Change-Id: I6085bc0099eb613dd9d3b07113c7c13859780697
parent dd0b7d08
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -1703,6 +1703,10 @@ public final class Pm {
            throw new IllegalArgumentException("Missing ABI argument");
        }

        if ("-".equals(abi)) {
            return abi;
        }

        final String[] supportedAbis = Build.SUPPORTED_ABIS;
        for (String supportedAbi : supportedAbis) {
            if (supportedAbi.equals(abi)) {
+10 −0
Original line number Diff line number Diff line
@@ -4256,6 +4256,16 @@ public class PackageParser {
        public ArraySet<String> mUpgradeKeySets;
        public ArrayMap<String, ArraySet<PublicKey>> mKeySetMapping;

        /**
         * The install time abi override for this package, if any.
         *
         * TODO: This seems like a horrible place to put the abiOverride because
         * this isn't something the packageParser parsers. However, this fits in with
         * the rest of the PackageManager where package scanning randomly pushes
         * and prods fields out of {@code this.applicationInfo}.
         */
        public String cpuAbiOverride;

        public Package(String packageName) {
            this.packageName = packageName;
            applicationInfo.packageName = packageName;
+62 −37
Original line number Diff line number Diff line
@@ -253,6 +253,10 @@ public class PackageManagerService extends IPackageManager.Stub {
    // package apks to install directory.
    private static final String INSTALL_PACKAGE_SUFFIX = "-";
    // Special value for {@code PackageParser.Package#cpuAbiOverride} to indicate
    // that the cpuAbiOverride must be clear.
    private static final String CLEAR_ABI_OVERRIDE = "-";
    static final int SCAN_MONITOR = 1<<0;
    static final int SCAN_NO_DEX = 1<<1;
    static final int SCAN_FORCE_DEX = 1<<2;
@@ -4093,8 +4097,7 @@ public class PackageManagerService extends IPackageManager.Stub {
                continue;
            }
            try {
                scanPackageLI(file, flags | PackageParser.PARSE_MUST_BE_APK, scanMode, currentTime,
                        null, null);
                scanPackageLI(file, flags | PackageParser.PARSE_MUST_BE_APK, scanMode, currentTime, null);
            } catch (PackageManagerException e) {
                Slog.w(TAG, "Failed to parse " + file + ": " + e.getMessage());
@@ -4175,7 +4178,7 @@ public class PackageManagerService extends IPackageManager.Stub {
     *  Returns null in case of errors and the error code is stored in mLastScanError
     */
    private PackageParser.Package scanPackageLI(File scanFile, int parseFlags, int scanMode,
            long currentTime, UserHandle user, String abiOverride) throws PackageManagerException {
            long currentTime, UserHandle user) throws PackageManagerException {
        if (DEBUG_INSTALL) Slog.d(TAG, "Parsing: " + scanFile);
        parseFlags |= mDefParseFlags;
        PackageParser pp = new PackageParser();
@@ -4371,7 +4374,7 @@ public class PackageManagerService extends IPackageManager.Stub {
        // Note that we invoke the following method only if we are about to unpack an application
        PackageParser.Package scannedPkg = scanPackageLI(pkg, parseFlags, scanMode
                | SCAN_UPDATE_SIGNATURE, currentTime, user, abiOverride);
                | SCAN_UPDATE_SIGNATURE, currentTime, user);
        /*
         * If the system app should be overridden by a previously installed
@@ -4998,8 +5001,26 @@ public class PackageManagerService extends IPackageManager.Stub {
        return res;
    }
    /**
     * Derive the value of the {@code cpuAbiOverride} based on the provided
     * value and an optional stored value from the package settings.
     */
    private static String deriveAbiOverride(String abiOverride, PackageSetting settings) {
        String cpuAbiOverride = null;
        if (CLEAR_ABI_OVERRIDE.equals(abiOverride)) {
            cpuAbiOverride = null;
        } else if (abiOverride != null) {
            cpuAbiOverride = abiOverride;
        } else if (settings != null) {
            cpuAbiOverride = settings.cpuAbiOverrideString;
        }
        return cpuAbiOverride;
    }
    private PackageParser.Package scanPackageLI(PackageParser.Package pkg, int parseFlags,
            int scanMode, long currentTime, UserHandle user, String abiOverride)
            int scanMode, long currentTime, UserHandle user)
            throws PackageManagerException {
        final File scanFile = new File(pkg.codePath);
        if (pkg.applicationInfo.getCodePath() == null ||
@@ -5435,6 +5456,7 @@ public class PackageManagerService extends IPackageManager.Stub {
        final String path = scanFile.getPath();
        final String codePath = pkg.applicationInfo.getCodePath();
        final String cpuAbiOverride = deriveAbiOverride(pkg.cpuAbiOverride, pkgSetting);
        if (isSystemApp(pkg) && !isUpdatedSystemApp(pkg)) {
            setBundledAppAbisAndRoots(pkg, pkgSetting);
@@ -5490,7 +5512,7 @@ public class PackageManagerService extends IPackageManager.Stub {
                    // 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 (abiOverride != null) {
                    if (pkg.cpuAbiOverride != null && !CLEAR_ABI_OVERRIDE.equals(pkg.cpuAbiOverride)) {
                        Slog.w(TAG, "Ignoring abiOverride for multi arch application.");
                    }
@@ -5533,15 +5555,15 @@ public class PackageManagerService extends IPackageManager.Stub {
                        }
                    }
                } else {
                    String[] abiList = (abiOverride != null) ?
                            new String[] { abiOverride } : Build.SUPPORTED_ABIS;
                    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 && abiOverride == null &&
                    if (Build.SUPPORTED_64_BIT_ABIS.length > 0 && cpuAbiOverride == null &&
                            NativeLibraryHelper.hasRenderscriptBitcode(handle)) {
                        abiList = Build.SUPPORTED_32_BIT_ABIS;
                        needsRenderScriptOverride = true;
@@ -5562,8 +5584,8 @@ public class PackageManagerService extends IPackageManager.Stub {
                    if (copyRet >= 0) {
                        pkg.applicationInfo.primaryCpuAbi = abiList[copyRet];
                    } else if (copyRet == PackageManager.NO_NATIVE_LIBRARIES && abiOverride != null) {
                        pkg.applicationInfo.primaryCpuAbi = abiOverride;
                    } else if (copyRet == PackageManager.NO_NATIVE_LIBRARIES && cpuAbiOverride != null) {
                        pkg.applicationInfo.primaryCpuAbi = cpuAbiOverride;
                    } else if (needsRenderScriptOverride) {
                        pkg.applicationInfo.primaryCpuAbi = abiList[0];
                    }
@@ -5608,6 +5630,10 @@ public class PackageManagerService extends IPackageManager.Stub {
        pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi;
        pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi;
        pkgSetting.cpuAbiOverrideString = cpuAbiOverride;
        // Copy the derived override back to the parsed package, so that we can
        // update the package settings accordingly.
        pkg.cpuAbiOverride = cpuAbiOverride;
        Slog.d(TAG, "Resolved nativeLibraryRoot for " + pkg.applicationInfo.packageName
                + " to root=" + pkg.applicationInfo.nativeLibraryRootDir + ", isa="
@@ -9269,7 +9295,7 @@ public class PackageManagerService extends IPackageManager.Stub {
                    // 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 (abiOverride != null) {
                    if (abiOverride != null &&  !CLEAR_ABI_OVERRIDE.equals(abiOverride)) {
                        Slog.w(TAG, "Ignoring abiOverride for multi arch application.");
                    }
@@ -9286,10 +9312,11 @@ public class PackageManagerService extends IPackageManager.Stub {
                        maybeThrowExceptionForMultiArchCopy("Failure copying 64 bit native libraries", copyRet);
                    }
                } else {
                    String[] abiList = (abiOverride != null) ?
                            new String[] { abiOverride } : Build.SUPPORTED_ABIS;
                    final String cpuAbiOverride = deriveAbiOverride(this.abiOverride, null /* package setting */);
                    String[] abiList = (cpuAbiOverride != null) ?
                            new String[] { cpuAbiOverride } : Build.SUPPORTED_ABIS;
                    if (Build.SUPPORTED_64_BIT_ABIS.length > 0 && abiOverride == null &&
                    if (Build.SUPPORTED_64_BIT_ABIS.length > 0 && cpuAbiOverride == null &&
                            NativeLibraryHelper.hasRenderscriptBitcode(handle)) {
                        abiList = Build.SUPPORTED_32_BIT_ABIS;
                    }
@@ -9557,7 +9584,7 @@ public class PackageManagerService extends IPackageManager.Stub {
            final String newCachePath = imcs.copyPackageToContainer(
                    originFile.getAbsolutePath(), cid, getEncryptKey(), isExternal(),
                    isFwdLocked(), abiOverride);
                    isFwdLocked(), deriveAbiOverride(abiOverride, null /* settings */));
            if (newCachePath != null) {
                setCachePath(newCachePath);
@@ -9908,7 +9935,7 @@ public class PackageManagerService extends IPackageManager.Stub {
     */
    private void installNewPackageLI(PackageParser.Package pkg,
            int parseFlags, int scanMode, UserHandle user,
            String installerPackageName, PackageInstalledInfo res, String abiOverride) {
            String installerPackageName, PackageInstalledInfo res) {
        // Remember this for later, in case we need to rollback this install
        String pkgName = pkg.packageName;
@@ -9935,7 +9962,7 @@ public class PackageManagerService extends IPackageManager.Stub {
        try {
            PackageParser.Package newPackage = scanPackageLI(pkg, parseFlags, scanMode,
                    System.currentTimeMillis(), user, abiOverride);
                    System.currentTimeMillis(), user);
            updateSettingsLI(newPackage, installerPackageName, null, null, res);
            // delete the partially installed application. the data directory will have to be
@@ -9971,7 +9998,7 @@ public class PackageManagerService extends IPackageManager.Stub {
    private void replacePackageLI(PackageParser.Package pkg,
            int parseFlags, int scanMode, UserHandle user,
            String installerPackageName, PackageInstalledInfo res, String abiOverride) {
            String installerPackageName, PackageInstalledInfo res) {
        PackageParser.Package oldPackage;
        String pkgName = pkg.packageName;
        int[] allUsers;
@@ -10010,19 +10037,17 @@ public class PackageManagerService extends IPackageManager.Stub {
        boolean sysPkg = (isSystemApp(oldPackage));
        if (sysPkg) {
            replaceSystemPackageLI(oldPackage, pkg, parseFlags, scanMode,
                    user, allUsers, perUserInstalled, installerPackageName, res,
                    abiOverride);
                    user, allUsers, perUserInstalled, installerPackageName, res);
        } else {
            replaceNonSystemPackageLI(oldPackage, pkg, parseFlags, scanMode,
                    user, allUsers, perUserInstalled, installerPackageName, res,
                    abiOverride);
                    user, allUsers, perUserInstalled, installerPackageName, res);
        }
    }
    private void replaceNonSystemPackageLI(PackageParser.Package deletedPackage,
            PackageParser.Package pkg, int parseFlags, int scanMode, UserHandle user,
            int[] allUsers, boolean[] perUserInstalled,
            String installerPackageName, PackageInstalledInfo res, String abiOverride) {
            String installerPackageName, PackageInstalledInfo res) {
        String pkgName = deletedPackage.packageName;
        boolean deletedPkg = true;
        boolean updatedSettings = false;
@@ -10047,7 +10072,7 @@ public class PackageManagerService extends IPackageManager.Stub {
            deleteCodeCacheDirsLI(pkgName);
            try {
                final PackageParser.Package newPackage = scanPackageLI(pkg, parseFlags,
                        scanMode | SCAN_UPDATE_TIME, System.currentTimeMillis(), user, abiOverride);
                        scanMode | SCAN_UPDATE_TIME, System.currentTimeMillis(), user);
                updateSettingsLI(newPackage, installerPackageName, allUsers, perUserInstalled, res);
                updatedSettings = true;
            } catch (PackageManagerException e) {
@@ -10080,8 +10105,7 @@ public class PackageManagerService extends IPackageManager.Stub {
                int oldScanMode = (oldOnSd ? 0 : SCAN_MONITOR) | SCAN_UPDATE_SIGNATURE
                        | SCAN_UPDATE_TIME;
                try {
                    scanPackageLI(restoreFile, oldParseFlags, oldScanMode, origUpdateTime, null,
                            null);
                    scanPackageLI(restoreFile, oldParseFlags, oldScanMode, origUpdateTime, null);
                } catch (PackageManagerException e) {
                    Slog.e(TAG, "Failed to restore package : " + pkgName + " after failed upgrade: "
                            + e.getMessage());
@@ -10103,7 +10127,7 @@ public class PackageManagerService extends IPackageManager.Stub {
    private void replaceSystemPackageLI(PackageParser.Package deletedPackage,
            PackageParser.Package pkg, int parseFlags, int scanMode, UserHandle user,
            int[] allUsers, boolean[] perUserInstalled,
            String installerPackageName, PackageInstalledInfo res, String abiOverride) {
            String installerPackageName, PackageInstalledInfo res) {
        if (DEBUG_INSTALL) Slog.d(TAG, "replaceSystemPackageLI: new=" + pkg
                + ", old=" + deletedPackage);
        boolean updatedSettings = false;
@@ -10163,7 +10187,7 @@ public class PackageManagerService extends IPackageManager.Stub {
        PackageParser.Package newPackage = null;
        try {
            newPackage = scanPackageLI(pkg, parseFlags, scanMode, 0, user, abiOverride);
            newPackage = scanPackageLI(pkg, parseFlags, scanMode, 0, user);
            if (newPackage.mExtras != null) {
                final PackageSetting newPkgSetting = (PackageSetting) newPackage.mExtras;
                newPkgSetting.firstInstallTime = oldPkgSetting.firstInstallTime;
@@ -10195,8 +10219,7 @@ public class PackageManagerService extends IPackageManager.Stub {
            }
            // Add back the old system package
            try {
                scanPackageLI(oldPkg, parseFlags, SCAN_MONITOR | SCAN_UPDATE_SIGNATURE, 0, user,
                        null);
                scanPackageLI(oldPkg, parseFlags, SCAN_MONITOR | SCAN_UPDATE_SIGNATURE, 0, user);
            } catch (PackageManagerException e) {
                Slog.e(TAG, "Failed to restore original package: " + e.getMessage());
            }
@@ -10327,6 +10350,9 @@ public class PackageManagerService extends IPackageManager.Stub {
            return;
        }
        // Mark that we have an install time CPU ABI override.
        pkg.cpuAbiOverride = args.abiOverride;
        String pkgName = res.name = pkg.packageName;
        if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_TEST_ONLY) != 0) {
            if ((pFlags&PackageManager.INSTALL_ALLOW_TEST) == 0) {
@@ -10445,10 +10471,10 @@ public class PackageManagerService extends IPackageManager.Stub {
        if (replace) {
            replacePackageLI(pkg, parseFlags, scanMode, args.user,
                    installerPackageName, res, args.abiOverride);
                    installerPackageName, res);
        } else {
            installNewPackageLI(pkg, parseFlags, scanMode | SCAN_DELETE_DATA_ON_FAILURES, args.user,
                    installerPackageName, res, args.abiOverride);
                    installerPackageName, res);
        }
        synchronized (mPackages) {
            final PackageSetting ps = mSettings.mPackages.get(pkgName);
@@ -10884,8 +10910,7 @@ public class PackageManagerService extends IPackageManager.Stub {
        final PackageParser.Package newPkg;
        try {
            newPkg = scanPackageLI(disabledPs.codePath, parseFlags, SCAN_MONITOR | SCAN_NO_PATHS, 0,
                    null, null);
            newPkg = scanPackageLI(disabledPs.codePath, parseFlags, SCAN_MONITOR | SCAN_NO_PATHS, 0, null);
        } catch (PackageManagerException e) {
            Slog.w(TAG, "Failed to restore system package:" + newPs.name + ": " + e.getMessage());
            return false;
@@ -12843,7 +12868,7 @@ public class PackageManagerService extends IPackageManager.Stub {
                synchronized (mInstallLock) {
                    PackageParser.Package pkg = null;
                    try {
                        pkg = scanPackageLI(new File(codePath), parseFlags, 0, 0, null, null);
                        pkg = scanPackageLI(new File(codePath), parseFlags, 0, 0, null);
                    } catch (PackageManagerException e) {
                        Slog.w(TAG, "Failed to scan " + codePath + ": " + e.getMessage());
                    }
+4 −2
Original line number Diff line number Diff line
@@ -31,9 +31,11 @@ final class PackageSetting extends PackageSettingBase {

    PackageSetting(String name, String realName, File codePath, File resourcePath,
            String legacyNativeLibraryPathString, String primaryCpuAbiString,
            String secondaryCpuAbiString, int pVersionCode, int pkgFlags) {
            String secondaryCpuAbiString, String cpuAbiOverrideString,
            int pVersionCode, int pkgFlags) {
        super(name, realName, codePath, resourcePath, legacyNativeLibraryPathString,
                primaryCpuAbiString, secondaryCpuAbiString, pVersionCode, pkgFlags);
                primaryCpuAbiString, secondaryCpuAbiString, cpuAbiOverrideString,
                pVersionCode, pkgFlags);
    }

    /**
+25 −3
Original line number Diff line number Diff line
@@ -64,8 +64,25 @@ class PackageSettingBase extends GrantedPermissions {
    @Deprecated
    String legacyNativeLibraryPathString;

    /**
     * The primary CPU abi for this package. This value is regenerated at every
     * boot scan.
     */
    String primaryCpuAbiString;

    /**
     * The secondary CPU abi for this package. This value is regenerated at every
     * boot scan.
     */
    String secondaryCpuAbiString;

    /**
     * The install time CPU override, if any. This value is written at install time
     * and doesn't change during the life of an install. If non-null,
     * {@code primaryCpuAbiString} will contain the same value.
     */
    String cpuAbiOverrideString;

    long timeStamp;
    long firstInstallTime;
    long lastUpdateTime;
@@ -94,12 +111,13 @@ class PackageSettingBase extends GrantedPermissions {
    String installerPackageName;
    PackageSettingBase(String name, String realName, File codePath, File resourcePath,
            String legacyNativeLibraryPathString, String primaryCpuAbiString,
            String secondaryCpuAbiString, int pVersionCode, int pkgFlags) {
            String secondaryCpuAbiString, String cpuAbiOverrideString,
            int pVersionCode, int pkgFlags) {
        super(pkgFlags);
        this.name = name;
        this.realName = realName;
        init(codePath, resourcePath, legacyNativeLibraryPathString, primaryCpuAbiString,
                secondaryCpuAbiString, pVersionCode);
                secondaryCpuAbiString, cpuAbiOverrideString, pVersionCode);
    }

    /**
@@ -118,6 +136,7 @@ class PackageSettingBase extends GrantedPermissions {
        legacyNativeLibraryPathString = base.legacyNativeLibraryPathString;
        primaryCpuAbiString = base.primaryCpuAbiString;
        secondaryCpuAbiString = base.secondaryCpuAbiString;
        cpuAbiOverrideString = base.cpuAbiOverrideString;
        timeStamp = base.timeStamp;
        firstInstallTime = base.firstInstallTime;
        lastUpdateTime = base.lastUpdateTime;
@@ -145,7 +164,8 @@ class PackageSettingBase extends GrantedPermissions {
    }

    void init(File codePath, File resourcePath, String legacyNativeLibraryPathString,
              String primaryCpuAbiString, String secondaryCpuAbiString, int pVersionCode) {
              String primaryCpuAbiString, String secondaryCpuAbiString,
              String cpuAbiOverrideString, int pVersionCode) {
        this.codePath = codePath;
        this.codePathString = codePath.toString();
        this.resourcePath = resourcePath;
@@ -153,6 +173,7 @@ class PackageSettingBase extends GrantedPermissions {
        this.legacyNativeLibraryPathString = legacyNativeLibraryPathString;
        this.primaryCpuAbiString = primaryCpuAbiString;
        this.secondaryCpuAbiString = secondaryCpuAbiString;
        this.cpuAbiOverrideString = cpuAbiOverrideString;
        this.versionCode = pVersionCode;
    }

@@ -185,6 +206,7 @@ class PackageSettingBase extends GrantedPermissions {

        primaryCpuAbiString = base.primaryCpuAbiString;
        secondaryCpuAbiString = base.secondaryCpuAbiString;
        cpuAbiOverrideString = base.cpuAbiOverrideString;
        timeStamp = base.timeStamp;
        firstInstallTime = base.firstInstallTime;
        lastUpdateTime = base.lastUpdateTime;
Loading