From 116bdbd823b607d860b039ec334a1f985eed7a7f Mon Sep 17 00:00:00 2001 From: Narayan Kamath Date: Thu, 29 May 2014 11:51:59 +0100 Subject: [PATCH] Add an --abi argument to "pm install" This allows callers to force an install to a particular ABI. This is intended only for testing (and CTS) and is not meant for usage by the installer package. bug: 14453227 (cherry picked from commit 6431d11cd420536aaa9d93ae510a3151ccc4df1d) Change-Id: I85d4f8785deea02a6a4d3cb0b05e6ef8bf64826b --- cmds/pm/src/com/android/commands/pm/Pm.java | 30 +++- .../android/content/pm/IPackageManager.aidl | 7 + .../internal/app/IMediaContainerService.aidl | 10 +- .../defcontainer/DefaultContainerService.java | 46 ++--- .../server/pm/PackageManagerService.java | 166 +++++++++++------- 5 files changed, 169 insertions(+), 90 deletions(-) diff --git a/cmds/pm/src/com/android/commands/pm/Pm.java b/cmds/pm/src/com/android/commands/pm/Pm.java index b7c2c2229400f..47047b86a6ec0 100644 --- a/cmds/pm/src/com/android/commands/pm/Pm.java +++ b/cmds/pm/src/com/android/commands/pm/Pm.java @@ -39,6 +39,7 @@ import android.content.pm.VerificationParams; import android.content.res.AssetManager; import android.content.res.Resources; import android.net.Uri; +import android.os.Build; import android.os.Bundle; import android.os.IUserManager; import android.os.Process; @@ -57,7 +58,6 @@ import java.util.Collections; import java.util.Comparator; import java.util.List; import java.util.WeakHashMap; - import javax.crypto.SecretKey; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; @@ -823,6 +823,7 @@ public final class Pm { byte[] tag = null; String originatingUriString = null; String referrer = null; + String abi = null; while ((opt=nextOption()) != null) { if (opt.equals("-l")) { @@ -893,12 +894,34 @@ public final class Pm { System.err.println("Error: must supply argument for --referrer"); return; } + } else if (opt.equals("--abi")) { + abi = nextOptionData(); + if (abi == null) { + System.err.println("Error: must supply argument for --abi"); + return; + } } else { System.err.println("Error: Unknown option: " + opt); return; } } + if (abi != null) { + final String[] supportedAbis = Build.SUPPORTED_ABIS; + boolean matched = false; + for (String supportedAbi : supportedAbis) { + if (supportedAbi.equals(abi)) { + matched = true; + break; + } + } + + if (!matched) { + System.err.println("Error: abi " + abi + " not supported on this device."); + return; + } + } + final ContainerEncryptionParams encryptionParams; if (algo != null || iv != null || key != null || macAlgo != null || macKey != null || tag != null) { @@ -976,8 +999,9 @@ public final class Pm { VerificationParams verificationParams = new VerificationParams(verificationURI, originatingURI, referrerURI, VerificationParams.NO_UID, null); - mPm.installPackageWithVerificationAndEncryptionEtc(apkURI, null, obs, installFlags, - installerPackageName, verificationParams, encryptionParams); + mPm.installPackageWithVerificationEncryptionAndAbiOverrideEtc(apkURI, null, + obs, installFlags, installerPackageName, verificationParams, + encryptionParams, abi); synchronized (obs) { while (!obs.finished) { diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl index 44a6a5d12a5d6..70668e11d5d6f 100644 --- a/core/java/android/content/pm/IPackageManager.aidl +++ b/core/java/android/content/pm/IPackageManager.aidl @@ -433,6 +433,13 @@ interface IPackageManager { in VerificationParams verificationParams, in ContainerEncryptionParams encryptionParams); + void installPackageWithVerificationEncryptionAndAbiOverrideEtc(in Uri packageURI, + in IPackageInstallObserver observer, in IPackageInstallObserver2 observer2, + int flags, in String installerPackageName, + in VerificationParams verificationParams, + in ContainerEncryptionParams encryptionParams, + in String packageAbiOverride); + int installExistingPackageAsUser(String packageName, int userId); void verifyPendingInstall(int id, int verificationCode); diff --git a/core/java/com/android/internal/app/IMediaContainerService.aidl b/core/java/com/android/internal/app/IMediaContainerService.aidl index 03d3b226425e9..77f0dec00c711 100644 --- a/core/java/com/android/internal/app/IMediaContainerService.aidl +++ b/core/java/com/android/internal/app/IMediaContainerService.aidl @@ -25,16 +25,18 @@ import android.content.res.ObbInfo; interface IMediaContainerService { String copyResourceToContainer(in Uri packageURI, String containerId, String key, String resFileName, String publicResFileName, boolean isExternal, - boolean isForwardLocked); + boolean isForwardLocked, in String abiOverride); int copyResource(in Uri packageURI, in ContainerEncryptionParams encryptionParams, in ParcelFileDescriptor outStream); - PackageInfoLite getMinimalPackageInfo(in String packagePath, in int flags, in long threshold); + PackageInfoLite getMinimalPackageInfo(in String packagePath, in int flags, in long threshold, + in String abiOverride); boolean checkInternalFreeStorage(in Uri fileUri, boolean isForwardLocked, in long threshold); - boolean checkExternalFreeStorage(in Uri fileUri, boolean isForwardLocked); + boolean checkExternalFreeStorage(in Uri fileUri, boolean isForwardLocked, in String abiOverride); ObbInfo getObbInfo(in String filename); long calculateDirectorySize(in String directory); /** Return file system stats: [0] is total bytes, [1] is available bytes */ long[] getFileSystemStats(in String path); void clearDirectory(in String directory); - long calculateInstalledSize(in String packagePath, boolean isForwardLocked); + long calculateInstalledSize(in String packagePath, boolean isForwardLocked, + in String abiOverride); } diff --git a/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java b/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java index 36c1d5c704d28..b02aefc2ed5a6 100644 --- a/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java +++ b/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java @@ -101,13 +101,13 @@ public class DefaultContainerService extends IntentService { */ public String copyResourceToContainer(final Uri packageURI, final String cid, final String key, final String resFileName, final String publicResFileName, - boolean isExternal, boolean isForwardLocked) { + boolean isExternal, boolean isForwardLocked, String abiOverride) { if (packageURI == null || cid == null) { return null; } return copyResourceInner(packageURI, cid, key, resFileName, publicResFileName, - isExternal, isForwardLocked); + isExternal, isForwardLocked, abiOverride); } /** @@ -153,13 +153,12 @@ public class DefaultContainerService extends IntentService { /** * Determine the recommended install location for package * specified by file uri location. - * @param fileUri the uri of resource to be copied. Should be a - * file uri + * * @return Returns PackageInfoLite object containing * the package info and recommended app location. */ public PackageInfoLite getMinimalPackageInfo(final String packagePath, int flags, - long threshold) { + long threshold, String abiOverride) { PackageInfoLite ret = new PackageInfoLite(); if (packagePath == null) { @@ -191,7 +190,7 @@ public class DefaultContainerService extends IntentService { ret.verifiers = pkg.verifiers; ret.recommendedInstallLocation = recommendAppInstallLocation(pkg.installLocation, - packagePath, flags, threshold); + packagePath, flags, threshold, abiOverride); return ret; } @@ -208,11 +207,11 @@ public class DefaultContainerService extends IntentService { } @Override - public boolean checkExternalFreeStorage(Uri packageUri, boolean isForwardLocked) - throws RemoteException { + public boolean checkExternalFreeStorage(Uri packageUri, boolean isForwardLocked, + String abiOverride) throws RemoteException { final File apkFile = new File(packageUri.getPath()); try { - return isUnderExternalThreshold(apkFile, isForwardLocked); + return isUnderExternalThreshold(apkFile, isForwardLocked, abiOverride); } catch (IOException e) { return true; } @@ -265,11 +264,11 @@ public class DefaultContainerService extends IntentService { } @Override - public long calculateInstalledSize(String packagePath, boolean isForwardLocked) - throws RemoteException { + public long calculateInstalledSize(String packagePath, boolean isForwardLocked, + String abiOverride) throws RemoteException { final File packageFile = new File(packagePath); try { - return calculateContainerSize(packageFile, isForwardLocked) * 1024 * 1024; + return calculateContainerSize(packageFile, isForwardLocked, abiOverride) * 1024 * 1024; } catch (IOException e) { /* * Okay, something failed, so let's just estimate it to be 2x @@ -328,7 +327,8 @@ public class DefaultContainerService extends IntentService { } private String copyResourceInner(Uri packageURI, String newCid, String key, String resFileName, - String publicResFileName, boolean isExternal, boolean isForwardLocked) { + String publicResFileName, boolean isExternal, boolean isForwardLocked, + String abiOverride) { if (isExternal) { // Make sure the sdcard is mounted. @@ -342,8 +342,10 @@ public class DefaultContainerService extends IntentService { // The .apk file String codePath = packageURI.getPath(); File codeFile = new File(codePath); + String[] abiList = (abiOverride != null) ? new String[] { abiOverride } + : Build.SUPPORTED_ABIS; NativeLibraryHelper.ApkHandle handle = new NativeLibraryHelper.ApkHandle(codePath); - final int abi = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_ABIS); + final int abi = NativeLibraryHelper.findSupportedAbi(handle, abiList); // Calculate size of container needed to hold base APK. final int sizeMb; @@ -414,7 +416,7 @@ public class DefaultContainerService extends IntentService { int ret = PackageManager.INSTALL_SUCCEEDED; if (abi >= 0) { ret = NativeLibraryHelper.copyNativeBinariesIfNeededLI(handle, - sharedLibraryDir, Build.SUPPORTED_ABIS[abi]); + sharedLibraryDir, abiList[abi]); } else if (abi != PackageManager.NO_NATIVE_LIBRARIES) { ret = abi; } @@ -672,7 +674,7 @@ public class DefaultContainerService extends IntentService { private static final int PREFER_EXTERNAL = 2; private int recommendAppInstallLocation(int installLocation, String archiveFilePath, int flags, - long threshold) { + long threshold, String abiOverride) { int prefer; boolean checkBoth = false; @@ -741,7 +743,7 @@ public class DefaultContainerService extends IntentService { boolean fitsOnSd = false; if (!emulated && (checkBoth || prefer == PREFER_EXTERNAL)) { try { - fitsOnSd = isUnderExternalThreshold(apkFile, isForwardLocked); + fitsOnSd = isUnderExternalThreshold(apkFile, isForwardLocked, abiOverride); } catch (IOException e) { return PackageHelper.RECOMMEND_FAILED_INVALID_URI; } @@ -812,13 +814,13 @@ public class DefaultContainerService extends IntentService { * @return true if file fits * @throws IOException when file does not exist */ - private boolean isUnderExternalThreshold(File apkFile, boolean isForwardLocked) + private boolean isUnderExternalThreshold(File apkFile, boolean isForwardLocked, String abiOverride) throws IOException { if (Environment.isExternalStorageEmulated()) { return false; } - final int sizeMb = calculateContainerSize(apkFile, isForwardLocked); + final int sizeMb = calculateContainerSize(apkFile, isForwardLocked, abiOverride); final int availSdMb; if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) { @@ -832,9 +834,11 @@ public class DefaultContainerService extends IntentService { return availSdMb > sizeMb; } - private int calculateContainerSize(File apkFile, boolean forwardLocked) throws IOException { + private int calculateContainerSize(File apkFile, boolean forwardLocked, + String abiOverride) throws IOException { NativeLibraryHelper.ApkHandle handle = new NativeLibraryHelper.ApkHandle(apkFile); - final int abi = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_ABIS); + final int abi = NativeLibraryHelper.findSupportedAbi(handle, + (abiOverride != null) ? new String[] { abiOverride } : Build.SUPPORTED_ABIS); try { return calculateContainerSize(handle, apkFile, abi, forwardLocked); diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 13cc98c670415..dc608534b1b8d 100755 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -40,6 +40,7 @@ import com.android.internal.R; import com.android.internal.app.IMediaContainerService; import com.android.internal.app.ResolverActivity; import com.android.internal.content.NativeLibraryHelper; +import com.android.internal.content.NativeLibraryHelper.ApkHandle; import com.android.internal.content.PackageHelper; import com.android.internal.util.FastPrintWriter; import com.android.internal.util.FastXmlSerializer; @@ -4148,7 +4149,7 @@ public class PackageManagerService extends IPackageManager.Stub { continue; } PackageParser.Package pkg = scanPackageLI(file, - flags|PackageParser.PARSE_MUST_BE_APK, scanMode, currentTime, null); + flags|PackageParser.PARSE_MUST_BE_APK, scanMode, currentTime, null, null); // Don't mess around with apps in system partition. if (pkg == null && (flags & PackageParser.PARSE_IS_SYSTEM) == 0 && mLastScanError == PackageManager.INSTALL_FAILED_INVALID_APK) { @@ -4215,7 +4216,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) { + int parseFlags, int scanMode, long currentTime, UserHandle user, String abiOverride) { mLastScanError = PackageManager.INSTALL_SUCCEEDED; String scanPath = scanFile.getPath(); if (DEBUG_INSTALL) Slog.d(TAG, "Parsing: " + scanPath); @@ -4283,7 +4284,7 @@ public class PackageManagerService extends IPackageManager.Stub { mLastScanError = PackageManager.INSTALL_FAILED_DUPLICATE_PACKAGE; return null; } else { - // The current app on the system partion is better than + // The current app on the system partition is better than // what we have updated to on the data partition; switch // back to the system partition version. // At this point, its safely assumed that package installation for @@ -4402,7 +4403,7 @@ public class PackageManagerService extends IPackageManager.Stub { setApplicationInfoPaths(pkg, codePath, resPath); // 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); + | SCAN_UPDATE_SIGNATURE, currentTime, user, abiOverride); /* * If the system app should be overridden by a previously installed @@ -4945,7 +4946,7 @@ public class PackageManagerService extends IPackageManager.Stub { } private PackageParser.Package scanPackageLI(PackageParser.Package pkg, - int parseFlags, int scanMode, long currentTime, UserHandle user) { + int parseFlags, int scanMode, long currentTime, UserHandle user, String abiOverride) { File scanFile = new File(pkg.mScanPath); if (scanFile == null || pkg.applicationInfo.sourceDir == null || pkg.applicationInfo.publicSourceDir == null) { @@ -5395,10 +5396,14 @@ public class PackageManagerService extends IPackageManager.Stub { * only for non-system apps and system app upgrades. */ if (pkg.applicationInfo.nativeLibraryDir != null) { + final NativeLibraryHelper.ApkHandle handle = new NativeLibraryHelper.ApkHandle(scanFile); try { File nativeLibraryDir = new File(pkg.applicationInfo.nativeLibraryDir); final String dataPathString = dataPath.getCanonicalPath(); + final String[] abiList = (abiOverride != null) ? new String[] { abiOverride } : + Build.SUPPORTED_ABIS; + if (isSystemApp(pkg) && !isUpdatedSystemApp(pkg)) { /* * Upgrading from a previous version of the OS sometimes @@ -5411,8 +5416,11 @@ public class PackageManagerService extends IPackageManager.Stub { Log.i(TAG, "removed obsolete native libraries for system package " + path); } - - setInternalAppAbi(pkg, pkgSetting); + if (abiOverride != null) { + pkg.applicationInfo.cpuAbi = abiOverride; + } else { + setInternalAppAbi(pkg, pkgSetting); + } } else { if (!isForwardLocked(pkg) && !isExternal(pkg)) { /* @@ -5425,7 +5433,8 @@ public class PackageManagerService extends IPackageManager.Stub { } try { - int copyRet = copyNativeLibrariesForInternalApp(scanFile, nativeLibraryDir); + int copyRet = copyNativeLibrariesForInternalApp(handle, + nativeLibraryDir, abiList); if (copyRet < 0 && copyRet != PackageManager.NO_NATIVE_LIBRARIES) { Slog.e(TAG, "Unable to copy native libraries"); mLastScanError = PackageManager.INSTALL_FAILED_INTERNAL_ERROR; @@ -5435,7 +5444,9 @@ public class PackageManagerService extends IPackageManager.Stub { // We've successfully copied native libraries across, so we make a // note of what ABI we're using if (copyRet != PackageManager.NO_NATIVE_LIBRARIES) { - pkg.applicationInfo.cpuAbi = Build.SUPPORTED_ABIS[copyRet]; + pkg.applicationInfo.cpuAbi = abiList[copyRet]; + } else if (abiOverride != null) { + pkg.applicationInfo.cpuAbi = abiOverride; } else { pkg.applicationInfo.cpuAbi = null; } @@ -5452,20 +5463,22 @@ public class PackageManagerService extends IPackageManager.Stub { // to clean this up but we'll need to change the interface between this service // and IMediaContainerService (but doing so will spread this logic out, rather // than centralizing it). - final NativeLibraryHelper.ApkHandle handle = new NativeLibraryHelper.ApkHandle(scanFile); - final int abi = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_ABIS); + final int abi = NativeLibraryHelper.findSupportedAbi(handle, abiList); if (abi >= 0) { - pkg.applicationInfo.cpuAbi = Build.SUPPORTED_ABIS[abi]; + pkg.applicationInfo.cpuAbi = abiList[abi]; } else if (abi == PackageManager.NO_NATIVE_LIBRARIES) { // Note that (non upgraded) system apps will not have any native // libraries bundled in their APK, but we're guaranteed not to be // such an app at this point. - pkg.applicationInfo.cpuAbi = null; + if (abiOverride != null) { + pkg.applicationInfo.cpuAbi = abiOverride; + } else { + pkg.applicationInfo.cpuAbi = null; + } } else { mLastScanError = PackageManager.INSTALL_FAILED_INTERNAL_ERROR; return null; } - handle.close(); } if (DEBUG_INSTALL) Slog.i(TAG, "Linking native library dir for " + path); @@ -5482,8 +5495,12 @@ public class PackageManagerService extends IPackageManager.Stub { } } } + + pkgSetting.cpuAbiString = pkg.applicationInfo.cpuAbi; } catch (IOException ioe) { Slog.e(TAG, "Unable to get canonical file " + ioe.toString()); + } finally { + handle.close(); } } pkg.mScanPath = path; @@ -6175,8 +6192,8 @@ public class PackageManagerService extends IPackageManager.Stub { } } - private static int copyNativeLibrariesForInternalApp(File scanFile, final File nativeLibraryDir) - throws IOException { + private static int copyNativeLibrariesForInternalApp(ApkHandle handle, + final File nativeLibraryDir, String[] abiList) throws IOException { if (!nativeLibraryDir.isDirectory()) { nativeLibraryDir.delete(); @@ -6198,21 +6215,16 @@ public class PackageManagerService extends IPackageManager.Stub { * If this is an internal application or our nativeLibraryPath points to * the app-lib directory, unpack the libraries if necessary. */ - final NativeLibraryHelper.ApkHandle handle = new NativeLibraryHelper.ApkHandle(scanFile); - try { - int abi = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_ABIS); - if (abi >= 0) { - int copyRet = NativeLibraryHelper.copyNativeBinariesIfNeededLI(handle, - nativeLibraryDir, Build.SUPPORTED_ABIS[abi]); - if (copyRet != PackageManager.INSTALL_SUCCEEDED) { - return copyRet; - } + int abi = NativeLibraryHelper.findSupportedAbi(handle, abiList); + if (abi >= 0) { + int copyRet = NativeLibraryHelper.copyNativeBinariesIfNeededLI(handle, + nativeLibraryDir, Build.SUPPORTED_ABIS[abi]); + if (copyRet != PackageManager.INSTALL_SUCCEEDED) { + return copyRet; } - - return abi; - } finally { - handle.close(); } + + return abi; } private void killApplication(String pkgName, int appId, String reason) { @@ -7536,7 +7548,7 @@ public class PackageManagerService extends IPackageManager.Stub { } p = scanPackageLI(fullPath, flags, SCAN_MONITOR | SCAN_NO_PATHS | SCAN_UPDATE_TIME, - System.currentTimeMillis(), UserHandle.ALL); + System.currentTimeMillis(), UserHandle.ALL, null); if (p != null) { /* * TODO this seems dangerous as the package may have @@ -7657,6 +7669,16 @@ public class PackageManagerService extends IPackageManager.Stub { if (observer == null && observer2 == null) { throw new IllegalArgumentException("No install observer supplied"); } + installPackageWithVerificationEncryptionAndAbiOverrideEtc(packageURI, observer, observer2, + flags, installerPackageName, verificationParams, encryptionParams, null); + } + + @Override + public void installPackageWithVerificationEncryptionAndAbiOverrideEtc(Uri packageURI, + IPackageInstallObserver observer, IPackageInstallObserver2 observer2, + int flags, String installerPackageName, + VerificationParams verificationParams, ContainerEncryptionParams encryptionParams, + String packageAbiOverride) { mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, null); @@ -7696,7 +7718,8 @@ public class PackageManagerService extends IPackageManager.Stub { final Message msg = mHandler.obtainMessage(INIT_COPY); msg.obj = new InstallParams(packageURI, observer, observer2, filteredFlags, - installerPackageName, verificationParams, encryptionParams, user); + installerPackageName, verificationParams, encryptionParams, user, + packageAbiOverride); mHandler.sendMessage(msg); } @@ -8405,11 +8428,14 @@ public class PackageManagerService extends IPackageManager.Stub { private int mRet; private File mTempPackage; final ContainerEncryptionParams encryptionParams; + final String packageAbiOverride; + final String packageInstructionSetOverride; InstallParams(Uri packageURI, IPackageInstallObserver observer, IPackageInstallObserver2 observer2, int flags, String installerPackageName, VerificationParams verificationParams, - ContainerEncryptionParams encryptionParams, UserHandle user) { + ContainerEncryptionParams encryptionParams, UserHandle user, + String packageAbiOverride) { super(user); this.mPackageURI = packageURI; this.flags = flags; @@ -8418,6 +8444,9 @@ public class PackageManagerService extends IPackageManager.Stub { this.installerPackageName = installerPackageName; this.verificationParams = verificationParams; this.encryptionParams = encryptionParams; + this.packageAbiOverride = packageAbiOverride; + this.packageInstructionSetOverride = (packageAbiOverride == null) ? + packageAbiOverride : VMRuntime.getInstructionSet(packageAbiOverride); } @Override @@ -8563,7 +8592,7 @@ public class PackageManagerService extends IPackageManager.Stub { // Remote call to find out default install location final String packageFilePath = packageFile.getAbsolutePath(); pkgLite = mContainerService.getMinimalPackageInfo(packageFilePath, flags, - lowThreshold); + lowThreshold, packageAbiOverride); /* * If we have too little free space, try to free cache @@ -8572,10 +8601,10 @@ public class PackageManagerService extends IPackageManager.Stub { if (pkgLite.recommendedInstallLocation == PackageHelper.RECOMMEND_FAILED_INSUFFICIENT_STORAGE) { final long size = mContainerService.calculateInstalledSize( - packageFilePath, isForwardLocked()); + packageFilePath, isForwardLocked(), packageAbiOverride); if (mInstaller.freeCache(size + lowThreshold) >= 0) { pkgLite = mContainerService.getMinimalPackageInfo(packageFilePath, - flags, lowThreshold); + flags, lowThreshold, packageAbiOverride); } /* * The cache free must have deleted the file we @@ -8995,11 +9024,12 @@ public class PackageManagerService extends IPackageManager.Stub { final ManifestDigest manifestDigest; final UserHandle user; final String instructionSet; + final String abiOverride; InstallArgs(Uri packageURI, IPackageInstallObserver observer, IPackageInstallObserver2 observer2, int flags, String installerPackageName, ManifestDigest manifestDigest, - UserHandle user, String instructionSet) { + UserHandle user, String instructionSet, String abiOverride) { this.packageURI = packageURI; this.flags = flags; this.observer = observer; @@ -9008,6 +9038,7 @@ public class PackageManagerService extends IPackageManager.Stub { this.manifestDigest = manifestDigest; this.user = user; this.instructionSet = instructionSet; + this.abiOverride = abiOverride; } abstract void createCopyFile(); @@ -9063,12 +9094,13 @@ public class PackageManagerService extends IPackageManager.Stub { FileInstallArgs(InstallParams params) { super(params.getPackageUri(), params.observer, params.observer2, params.flags, params.installerPackageName, params.getManifestDigest(), - params.getUser(), null /* instruction set */); + params.getUser(), params.packageInstructionSetOverride, + params.packageAbiOverride); } FileInstallArgs(String fullCodePath, String fullResourcePath, String nativeLibraryPath, String instructionSet) { - super(null, null, null, 0, null, null, null, instructionSet); + super(null, null, null, 0, null, null, null, instructionSet, null); File codeFile = new File(fullCodePath); installDir = codeFile.getParentFile(); codeFileName = fullCodePath; @@ -9077,7 +9109,7 @@ public class PackageManagerService extends IPackageManager.Stub { } FileInstallArgs(Uri packageURI, String pkgName, String dataDir, String instructionSet) { - super(packageURI, null, null, 0, null, null, null, instructionSet); + super(packageURI, null, null, 0, null, null, null, instructionSet, null); installDir = isFwdLocked() ? mDrmAppPrivateInstallDir : mAppInstallDir; String apkName = getNextCodePath(null, pkgName, ".apk"); codeFileName = new File(installDir, apkName + ".apk").getPath(); @@ -9181,14 +9213,20 @@ public class PackageManagerService extends IPackageManager.Stub { NativeLibraryHelper.removeNativeBinariesFromDirLI(nativeLibraryFile); nativeLibraryFile.delete(); } + + final NativeLibraryHelper.ApkHandle handle = new NativeLibraryHelper.ApkHandle(codeFile); + final String[] abiList = (abiOverride != null) ? + new String[] { abiOverride } : Build.SUPPORTED_ABIS; try { - int copyRet = copyNativeLibrariesForInternalApp(codeFile, nativeLibraryFile); + int copyRet = copyNativeLibrariesForInternalApp(handle, nativeLibraryFile, abiList); if (copyRet < 0 && copyRet != PackageManager.NO_NATIVE_LIBRARIES) { return copyRet; } } catch (IOException e) { Slog.e(TAG, "Copying native libraries failed", e); ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR; + } finally { + handle.close(); } return ret; @@ -9403,14 +9441,15 @@ public class PackageManagerService extends IPackageManager.Stub { AsecInstallArgs(InstallParams params) { super(params.getPackageUri(), params.observer, params.observer2, params.flags, params.installerPackageName, params.getManifestDigest(), - params.getUser(), null /* instruction set */); + params.getUser(), params.packageInstructionSetOverride, + params.packageAbiOverride); } AsecInstallArgs(String fullCodePath, String fullResourcePath, String nativeLibraryPath, String instructionSet, boolean isExternal, boolean isForwardLocked) { super(null, null, null, (isExternal ? PackageManager.INSTALL_EXTERNAL : 0) | (isForwardLocked ? PackageManager.INSTALL_FORWARD_LOCK : 0), - null, null, null, instructionSet); + null, null, null, instructionSet, null); // Extract cid from fullCodePath int eidx = fullCodePath.lastIndexOf("/"); String subStr1 = fullCodePath.substring(0, eidx); @@ -9422,7 +9461,7 @@ public class PackageManagerService extends IPackageManager.Stub { AsecInstallArgs(String cid, String instructionSet, boolean isForwardLocked) { super(null, null, null, (isAsecExternal(cid) ? PackageManager.INSTALL_EXTERNAL : 0) | (isForwardLocked ? PackageManager.INSTALL_FORWARD_LOCK : 0), - null, null, null, instructionSet); + null, null, null, instructionSet, null); this.cid = cid; setCachePath(PackageHelper.getSdDir(cid)); } @@ -9431,7 +9470,7 @@ public class PackageManagerService extends IPackageManager.Stub { boolean isExternal, boolean isForwardLocked) { super(packageURI, null, null, (isExternal ? PackageManager.INSTALL_EXTERNAL : 0) | (isForwardLocked ? PackageManager.INSTALL_FORWARD_LOCK : 0), - null, null, null, instructionSet); + null, null, null, instructionSet, null); this.cid = cid; } @@ -9443,7 +9482,7 @@ public class PackageManagerService extends IPackageManager.Stub { try { mContext.grantUriPermission(DEFAULT_CONTAINER_PACKAGE, packageURI, Intent.FLAG_GRANT_READ_URI_PERMISSION); - return imcs.checkExternalFreeStorage(packageURI, isFwdLocked()); + return imcs.checkExternalFreeStorage(packageURI, isFwdLocked(), abiOverride); } finally { mContext.revokeUriPermission(packageURI, Intent.FLAG_GRANT_READ_URI_PERMISSION); } @@ -9469,7 +9508,8 @@ public class PackageManagerService extends IPackageManager.Stub { mContext.grantUriPermission(DEFAULT_CONTAINER_PACKAGE, packageURI, Intent.FLAG_GRANT_READ_URI_PERMISSION); newCachePath = imcs.copyResourceToContainer(packageURI, cid, getEncryptKey(), - RES_FILE_NAME, PUBLIC_RES_FILE_NAME, isExternal(), isFwdLocked()); + RES_FILE_NAME, PUBLIC_RES_FILE_NAME, isExternal(), isFwdLocked(), + abiOverride); } finally { mContext.revokeUriPermission(packageURI, Intent.FLAG_GRANT_READ_URI_PERMISSION); } @@ -9777,7 +9817,7 @@ public class PackageManagerService extends IPackageManager.Stub { */ private void installNewPackageLI(PackageParser.Package pkg, int parseFlags, int scanMode, UserHandle user, - String installerPackageName, PackageInstalledInfo res) { + String installerPackageName, PackageInstalledInfo res, String abiOverride) { // Remember this for later, in case we need to rollback this install String pkgName = pkg.packageName; @@ -9805,7 +9845,7 @@ public class PackageManagerService extends IPackageManager.Stub { } mLastScanError = PackageManager.INSTALL_SUCCEEDED; PackageParser.Package newPackage = scanPackageLI(pkg, parseFlags, scanMode, - System.currentTimeMillis(), user); + System.currentTimeMillis(), user, abiOverride); if (newPackage == null) { Slog.w(TAG, "Package couldn't be installed in " + pkg.mPath); if ((res.returnCode=mLastScanError) == PackageManager.INSTALL_SUCCEEDED) { @@ -9832,7 +9872,7 @@ public class PackageManagerService extends IPackageManager.Stub { private void replacePackageLI(PackageParser.Package pkg, int parseFlags, int scanMode, UserHandle user, - String installerPackageName, PackageInstalledInfo res) { + String installerPackageName, PackageInstalledInfo res, String abiOverride) { PackageParser.Package oldPackage; String pkgName = pkg.packageName; @@ -9861,17 +9901,19 @@ public class PackageManagerService extends IPackageManager.Stub { boolean sysPkg = (isSystemApp(oldPackage)); if (sysPkg) { replaceSystemPackageLI(oldPackage, pkg, parseFlags, scanMode, - user, allUsers, perUserInstalled, installerPackageName, res); + user, allUsers, perUserInstalled, installerPackageName, res, + abiOverride); } else { replaceNonSystemPackageLI(oldPackage, pkg, parseFlags, scanMode, - user, allUsers, perUserInstalled, installerPackageName, res); + user, allUsers, perUserInstalled, installerPackageName, res, + abiOverride); } } private void replaceNonSystemPackageLI(PackageParser.Package deletedPackage, PackageParser.Package pkg, int parseFlags, int scanMode, UserHandle user, int[] allUsers, boolean[] perUserInstalled, - String installerPackageName, PackageInstalledInfo res) { + String installerPackageName, PackageInstalledInfo res, String abiOverride) { PackageParser.Package newPackage = null; String pkgName = deletedPackage.packageName; boolean deletedPkg = true; @@ -9896,7 +9938,7 @@ public class PackageManagerService extends IPackageManager.Stub { // Successfully deleted the old package. Now proceed with re-installation mLastScanError = PackageManager.INSTALL_SUCCEEDED; newPackage = scanPackageLI(pkg, parseFlags, scanMode | SCAN_UPDATE_TIME, - System.currentTimeMillis(), user); + System.currentTimeMillis(), user, abiOverride); if (newPackage == null) { Slog.w(TAG, "Package couldn't be installed in " + pkg.mPath); if ((res.returnCode=mLastScanError) == PackageManager.INSTALL_SUCCEEDED) { @@ -9925,7 +9967,7 @@ public class PackageManagerService extends IPackageManager.Stub { } // Since we failed to install the new package we need to restore the old // package that we deleted. - if(deletedPkg) { + if (deletedPkg) { if (DEBUG_INSTALL) Slog.d(TAG, "Install failed, reinstalling: " + deletedPackage); File restoreFile = new File(deletedPackage.mPath); // Parse old package @@ -9936,7 +9978,7 @@ public class PackageManagerService extends IPackageManager.Stub { int oldScanMode = (oldOnSd ? 0 : SCAN_MONITOR) | SCAN_UPDATE_SIGNATURE | SCAN_UPDATE_TIME; if (scanPackageLI(restoreFile, oldParseFlags, oldScanMode, - origUpdateTime, null) == null) { + origUpdateTime, null, null) == null) { Slog.e(TAG, "Failed to restore package : " + pkgName + " after failed upgrade"); return; } @@ -9956,7 +9998,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 installerPackageName, PackageInstalledInfo res, String abiOverride) { if (DEBUG_INSTALL) Slog.d(TAG, "replaceSystemPackageLI: new=" + pkg + ", old=" + deletedPackage); PackageParser.Package newPackage = null; @@ -10010,7 +10052,7 @@ public class PackageManagerService extends IPackageManager.Stub { // Successfully disabled the old package. Now proceed with re-installation res.returnCode = mLastScanError = PackageManager.INSTALL_SUCCEEDED; pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP; - newPackage = scanPackageLI(pkg, parseFlags, scanMode, 0, user); + newPackage = scanPackageLI(pkg, parseFlags, scanMode, 0, user, abiOverride); if (newPackage == null) { Slog.w(TAG, "Package couldn't be installed in " + pkg.mPath); if ((res.returnCode=mLastScanError) == PackageManager.INSTALL_SUCCEEDED) { @@ -10044,7 +10086,7 @@ public class PackageManagerService extends IPackageManager.Stub { removeInstalledPackageLI(newPackage, true); } // Add back the old system package - scanPackageLI(oldPkg, parseFlags, SCAN_MONITOR | SCAN_UPDATE_SIGNATURE, 0, user); + scanPackageLI(oldPkg, parseFlags, SCAN_MONITOR | SCAN_UPDATE_SIGNATURE, 0, user, null); // Restore the old system information in Settings synchronized(mPackages) { if (updatedSettings) { @@ -10278,10 +10320,10 @@ public class PackageManagerService extends IPackageManager.Stub { pkg.applicationInfo.nativeLibraryDir = args.getNativeLibraryPath(); if (replace) { replacePackageLI(pkg, parseFlags, scanMode, args.user, - installerPackageName, res); + installerPackageName, res, args.abiOverride); } else { installNewPackageLI(pkg, parseFlags, scanMode | SCAN_DELETE_DATA_ON_FAILURES, args.user, - installerPackageName, res); + installerPackageName, res, args.abiOverride); } synchronized (mPackages) { final PackageSetting ps = mSettings.mPackages.get(pkgName); @@ -10698,7 +10740,7 @@ public class PackageManagerService extends IPackageManager.Stub { parseFlags |= PackageParser.PARSE_IS_PRIVILEGED; } PackageParser.Package newPkg = scanPackageLI(disabledPs.codePath, - parseFlags, SCAN_MONITOR | SCAN_NO_PATHS, 0, null); + parseFlags, SCAN_MONITOR | SCAN_NO_PATHS, 0, null, null); if (newPkg == null) { Slog.w(TAG, "Failed to restore system package:" + newPs.name @@ -12511,7 +12553,7 @@ public class PackageManagerService extends IPackageManager.Stub { doGc = true; synchronized (mInstallLock) { final PackageParser.Package pkg = scanPackageLI(new File(codePath), parseFlags, - 0, 0, null); + 0, 0, null, null); // Scan the package if (pkg != null) { /*