Merge "Run 32-bit app in multiArch APK."
diff --git a/api/system-current.txt b/api/system-current.txt
index 29b1e53..749ab0a 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -293,6 +293,7 @@
public static final class R.attr {
ctor public R.attr();
+ field public static final int abiOverride = 16844054; // 0x1010516
field public static final int absListViewStyle = 16842858; // 0x101006a
field public static final int accessibilityEventTypes = 16843648; // 0x1010380
field public static final int accessibilityFeedbackType = 16843650; // 0x1010382
diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java
index 220fb607..c071162 100644
--- a/core/java/android/app/ApplicationPackageManager.java
+++ b/core/java/android/app/ApplicationPackageManager.java
@@ -326,8 +326,7 @@
// This is a temporary hack. Callers must use
// createPackageContext(packageName).getApplicationInfo() to
// get the right paths.
- maybeAdjustApplicationInfo(ai);
- return ai;
+ return maybeAdjustApplicationInfo(ai);
}
} catch (RemoteException e) {
throw new RuntimeException("Package manager has died", e);
@@ -336,7 +335,7 @@
throw new NameNotFoundException(packageName);
}
- private static void maybeAdjustApplicationInfo(ApplicationInfo info) {
+ private static ApplicationInfo maybeAdjustApplicationInfo(ApplicationInfo info) {
// If we're dealing with a multi-arch application that has both
// 32 and 64 bit shared libraries, we might need to choose the secondary
// depending on what the current runtime's instruction set is.
@@ -353,9 +352,12 @@
// Everything will be set up correctly because info.nativeLibraryDir will
// correspond to the right ISA.
if (runtimeIsa.equals(secondaryIsa)) {
- info.nativeLibraryDir = info.secondaryNativeLibraryDir;
+ ApplicationInfo modified = new ApplicationInfo(info);
+ modified.nativeLibraryDir = info.secondaryNativeLibraryDir;
+ return modified;
}
}
+ return info;
}
@Override
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index 09b85c9..7b8f3d2 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -291,6 +291,7 @@
public final boolean coreApp;
public final boolean multiArch;
+ public final String abiOverride;
public final boolean extractNativeLibs;
public PackageLite(String codePath, ApkLite baseApk, String[] splitNames,
@@ -307,6 +308,7 @@
this.splitRevisionCodes = splitRevisionCodes;
this.coreApp = baseApk.coreApp;
this.multiArch = baseApk.multiArch;
+ this.abiOverride = baseApk.abiOverride;
this.extractNativeLibs = baseApk.extractNativeLibs;
}
@@ -334,11 +336,12 @@
public final Signature[] signatures;
public final boolean coreApp;
public final boolean multiArch;
+ public final String abiOverride;
public final boolean extractNativeLibs;
public ApkLite(String codePath, String packageName, String splitName, int versionCode,
int revisionCode, int installLocation, List<VerifierInfo> verifiers,
- Signature[] signatures, boolean coreApp, boolean multiArch,
+ Signature[] signatures, boolean coreApp, boolean multiArch, String abiOverride,
boolean extractNativeLibs) {
this.codePath = codePath;
this.packageName = packageName;
@@ -350,6 +353,7 @@
this.signatures = signatures;
this.coreApp = coreApp;
this.multiArch = multiArch;
+ this.abiOverride = abiOverride;
this.extractNativeLibs = extractNativeLibs;
}
}
@@ -793,6 +797,7 @@
}
pkg.codePath = packageDir.getAbsolutePath();
+ pkg.cpuAbiOverride = lite.abiOverride;
return pkg;
} finally {
IoUtils.closeQuietly(assets);
@@ -811,8 +816,8 @@
*/
@Deprecated
public Package parseMonolithicPackage(File apkFile, int flags) throws PackageParserException {
+ final PackageLite lite = parseMonolithicPackageLite(apkFile, flags);
if (mOnlyCoreApps) {
- final PackageLite lite = parseMonolithicPackageLite(apkFile, flags);
if (!lite.coreApp) {
throw new PackageParserException(INSTALL_PARSE_FAILED_MANIFEST_MALFORMED,
"Not a coreApp: " + apkFile);
@@ -823,6 +828,7 @@
try {
final Package pkg = parseBaseApk(apkFile, assets, flags);
pkg.codePath = apkFile.getAbsolutePath();
+ pkg.cpuAbiOverride = lite.abiOverride;
return pkg;
} finally {
IoUtils.closeQuietly(assets);
@@ -1316,6 +1322,7 @@
int revisionCode = 0;
boolean coreApp = false;
boolean multiArch = false;
+ String abiOverride = null;
boolean extractNativeLibs = true;
for (int i = 0; i < attrs.getAttributeCount(); i++) {
@@ -1356,6 +1363,9 @@
if ("multiArch".equals(attr)) {
multiArch = attrs.getAttributeBooleanValue(i, false);
}
+ if ("abiOverride".equals(attr)) {
+ abiOverride = attrs.getAttributeValue(i);
+ }
if ("extractNativeLibs".equals(attr)) {
extractNativeLibs = attrs.getAttributeBooleanValue(i, true);
}
@@ -1365,7 +1375,7 @@
return new ApkLite(codePath, packageSplit.first, packageSplit.second, versionCode,
revisionCode, installLocation, verifiers, signatures, coreApp, multiArch,
- extractNativeLibs);
+ abiOverride, extractNativeLibs);
}
/**
diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml
index c744bbd..15a4ad8 100644
--- a/core/res/res/values/attrs_manifest.xml
+++ b/core/res/res/values/attrs_manifest.xml
@@ -429,6 +429,12 @@
sets. -->
<attr name="multiArch" format ="boolean" />
+ <!-- Specify abiOverride for multiArch application.
+ @hide
+ @SystemApi
+ -->
+ <attr name="abiOverride" />
+
<!-- Specify whether a component is allowed to have multiple instances
of itself running in different processes. Use with the activity
and provider tags.
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index bbbb963..329e2e5 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -2696,6 +2696,7 @@
<public type="attr" name="endX" />
<public type="attr" name="endY" />
<public type="attr" name="offset" />
+ <public type="attr" name="abiOverride" />
<public type="style" name="Theme.Material.Light.DialogWhenLarge.DarkActionBar" />
<public type="style" name="Widget.Material.SeekBar.Discrete" />
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index b6905b4..d3b9187 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -7980,6 +7980,11 @@
pkg.applicationInfo.primaryCpuAbi = abi;
}
}
+ if (cpuAbiOverride != null &&
+ cpuAbiOverride.equals(pkg.applicationInfo.secondaryCpuAbi)) {
+ pkg.applicationInfo.secondaryCpuAbi = pkg.applicationInfo.primaryCpuAbi;
+ pkg.applicationInfo.primaryCpuAbi = cpuAbiOverride;
+ }
} else {
String[] abiList = (cpuAbiOverride != null) ?
new String[] { cpuAbiOverride } : Build.SUPPORTED_ABIS;
@@ -12842,8 +12847,11 @@
Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
}
- // Mark that we have an install time CPU ABI override.
- pkg.cpuAbiOverride = args.abiOverride;
+ // If package doesn't declare API override, mark that we have an install
+ // time CPU ABI override.
+ if (TextUtils.isEmpty(pkg.cpuAbiOverride)) {
+ pkg.cpuAbiOverride = args.abiOverride;
+ }
String pkgName = res.name = pkg.packageName;
if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_TEST_ONLY) != 0) {
@@ -13016,7 +13024,9 @@
scanFlags |= SCAN_NO_DEX;
try {
- derivePackageAbi(pkg, new File(pkg.codePath), args.abiOverride,
+ String abiOverride = (TextUtils.isEmpty(pkg.cpuAbiOverride) ?
+ args.abiOverride : pkg.cpuAbiOverride);
+ derivePackageAbi(pkg, new File(pkg.codePath), abiOverride,
true /* extract libs */);
} catch (PackageManagerException pme) {
Slog.e(TAG, "Error deriving application ABI", pme);