Merge "System services detect and register app CPU ABIs"
diff --git a/core/java/android/content/pm/ApplicationInfo.java b/core/java/android/content/pm/ApplicationInfo.java
index 9c46d96..1a1610d 100644
--- a/core/java/android/content/pm/ApplicationInfo.java
+++ b/core/java/android/content/pm/ApplicationInfo.java
@@ -441,6 +441,15 @@
public String nativeLibraryDir;
/**
+ * The ABI that this application requires, This is inferred from the ABIs
+ * of the native JNI libraries the application bundles. Will be {@code null}
+ * if this application does not require any particular ABI.
+ *
+ * {@hide}
+ */
+ public String requiredCpuAbi;
+
+ /**
* The kernel user-ID that has been assigned to this application;
* currently this is not a unique ID (multiple applications can have
* the same uid).
@@ -570,6 +579,7 @@
sourceDir = orig.sourceDir;
publicSourceDir = orig.publicSourceDir;
nativeLibraryDir = orig.nativeLibraryDir;
+ requiredCpuAbi = orig.requiredCpuAbi;
resourceDirs = orig.resourceDirs;
seinfo = orig.seinfo;
sharedLibraryFiles = orig.sharedLibraryFiles;
@@ -610,6 +620,7 @@
dest.writeString(sourceDir);
dest.writeString(publicSourceDir);
dest.writeString(nativeLibraryDir);
+ dest.writeString(requiredCpuAbi);
dest.writeStringArray(resourceDirs);
dest.writeString(seinfo);
dest.writeStringArray(sharedLibraryFiles);
@@ -649,6 +660,7 @@
sourceDir = source.readString();
publicSourceDir = source.readString();
nativeLibraryDir = source.readString();
+ requiredCpuAbi = source.readString();
resourceDirs = source.readStringArray();
seinfo = source.readString();
sharedLibraryFiles = source.readStringArray();
diff --git a/core/java/android/os/Process.java b/core/java/android/os/Process.java
index 7d2d051..10ff27e 100644
--- a/core/java/android/os/Process.java
+++ b/core/java/android/os/Process.java
@@ -466,6 +466,7 @@
* @param debugFlags Additional flags.
* @param targetSdkVersion The target SDK version for the app.
* @param seInfo null-ok SELinux information for the new process.
+ * @param abi non-null the ABI this app should be started with.
* @param zygoteArgs Additional arguments to supply to the zygote process.
*
* @return An object that describes the result of the attempt to start the process.
@@ -479,12 +480,12 @@
int debugFlags, int mountExternal,
int targetSdkVersion,
String seInfo,
+ String abi,
String[] zygoteArgs) {
try {
return startViaZygote(processClass, niceName, uid, gid, gids,
debugFlags, mountExternal, targetSdkVersion, seInfo,
- null, /* zygoteAbi TODO: Replace this with the real ABI */
- zygoteArgs);
+ abi, zygoteArgs);
} catch (ZygoteStartFailedEx ex) {
Log.e(LOG_TAG,
"Starting VM process through Zygote failed");
@@ -702,13 +703,6 @@
primaryZygoteState = ZygoteState.connect(ZYGOTE_SOCKET, getNumTries(primaryZygoteState));
}
- // TODO: Revert this temporary change. This is required to test
- // and submit this change ahead of the package manager changes
- // that supply this abi.
- if (abi == null) {
- return primaryZygoteState;
- }
-
if (primaryZygoteState.matches(abi)) {
return primaryZygoteState;
}
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index 2b0c0c9..16b9963 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -2780,11 +2780,16 @@
debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
}
+ String requiredAbi = app.info.requiredCpuAbi;
+ if (requiredAbi == null) {
+ requiredAbi = Build.SUPPORTED_ABIS[0];
+ }
+
// Start the process. It will either succeed and return a result containing
// the PID of the new process, or else throw a RuntimeException.
Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
app.processName, uid, uid, gids, debugFlags, mountExternal,
- app.info.targetSdkVersion, app.info.seinfo, null);
+ app.info.targetSdkVersion, app.info.seinfo, requiredAbi, null);
BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
synchronized (bs) {
diff --git a/services/java/com/android/server/pm/PackageManagerService.java b/services/java/com/android/server/pm/PackageManagerService.java
index 7d13caa..44765a5 100755
--- a/services/java/com/android/server/pm/PackageManagerService.java
+++ b/services/java/com/android/server/pm/PackageManagerService.java
@@ -2005,6 +2005,7 @@
pkg.applicationInfo.dataDir =
getDataPathForPackage(packageName, 0).getPath();
pkg.applicationInfo.nativeLibraryDir = ps.nativeLibraryPathString;
+ pkg.applicationInfo.requiredCpuAbi = ps.requiredCpuAbiString;
}
return generatePackageInfo(pkg, flags, userId);
}
@@ -3823,6 +3824,8 @@
codePath = pkg.mScanPath;
// Set application objects path explicitly.
setApplicationInfoPaths(pkg, codePath, resPath);
+ // Applications can run with the primary Cpu Abi unless otherwise is specified
+ pkg.applicationInfo.requiredCpuAbi = null;
// 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);
@@ -4395,6 +4398,7 @@
// the PkgSetting exists already and doesn't have to be created.
pkgSetting = mSettings.getPackageLPw(pkg, origPackage, realName, suid, destCodeFile,
destResourceFile, pkg.applicationInfo.nativeLibraryDir,
+ pkg.applicationInfo.requiredCpuAbi,
pkg.applicationInfo.flags, user, false);
if (pkgSetting == null) {
Slog.w(TAG, "Creating application package " + pkg.packageName + " failed");
@@ -4706,6 +4710,14 @@
mLastScanError = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
return null;
}
+
+ // 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.requiredCpuAbi = Build.SUPPORTED_ABIS[copyRet];
+ } else {
+ pkg.applicationInfo.requiredCpuAbi = null;
+ }
} catch (IOException e) {
Slog.e(TAG, "Unable to copy native libraries", e);
mLastScanError = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
diff --git a/services/java/com/android/server/pm/PackageSetting.java b/services/java/com/android/server/pm/PackageSetting.java
index b447861..15df3d2 100644
--- a/services/java/com/android/server/pm/PackageSetting.java
+++ b/services/java/com/android/server/pm/PackageSetting.java
@@ -30,8 +30,8 @@
SharedUserSetting sharedUser;
PackageSetting(String name, String realName, File codePath, File resourcePath,
- String nativeLibraryPathString, int pVersionCode, int pkgFlags) {
- super(name, realName, codePath, resourcePath, nativeLibraryPathString, pVersionCode,
+ String nativeLibraryPathString, String requiredCpuAbiString, int pVersionCode, int pkgFlags) {
+ super(name, realName, codePath, resourcePath, nativeLibraryPathString, requiredCpuAbiString, pVersionCode,
pkgFlags);
}
diff --git a/services/java/com/android/server/pm/PackageSettingBase.java b/services/java/com/android/server/pm/PackageSettingBase.java
index 7747c8f..ba95b9a 100644
--- a/services/java/com/android/server/pm/PackageSettingBase.java
+++ b/services/java/com/android/server/pm/PackageSettingBase.java
@@ -53,6 +53,7 @@
File resourcePath;
String resourcePathString;
String nativeLibraryPathString;
+ String requiredCpuAbiString;
long timeStamp;
long firstInstallTime;
long lastUpdateTime;
@@ -80,11 +81,11 @@
/* package name of the app that installed this package */
String installerPackageName;
PackageSettingBase(String name, String realName, File codePath, File resourcePath,
- String nativeLibraryPathString, int pVersionCode, int pkgFlags) {
+ String nativeLibraryPathString, String requiredCpuAbiString, int pVersionCode, int pkgFlags) {
super(pkgFlags);
this.name = name;
this.realName = realName;
- init(codePath, resourcePath, nativeLibraryPathString, pVersionCode);
+ init(codePath, resourcePath, nativeLibraryPathString, requiredCpuAbiString, pVersionCode);
}
/**
@@ -101,6 +102,7 @@
resourcePath = base.resourcePath;
resourcePathString = base.resourcePathString;
nativeLibraryPathString = base.nativeLibraryPathString;
+ requiredCpuAbiString = base.requiredCpuAbiString;
timeStamp = base.timeStamp;
firstInstallTime = base.firstInstallTime;
lastUpdateTime = base.lastUpdateTime;
@@ -128,12 +130,13 @@
}
void init(File codePath, File resourcePath, String nativeLibraryPathString,
- int pVersionCode) {
+ String requiredCpuAbiString, int pVersionCode) {
this.codePath = codePath;
this.codePathString = codePath.toString();
this.resourcePath = resourcePath;
this.resourcePathString = resourcePath.toString();
this.nativeLibraryPathString = nativeLibraryPathString;
+ this.requiredCpuAbiString = requiredCpuAbiString;
this.versionCode = pVersionCode;
}
@@ -164,6 +167,7 @@
grantedPermissions = base.grantedPermissions;
gids = base.gids;
+ requiredCpuAbiString = base.requiredCpuAbiString;
timeStamp = base.timeStamp;
firstInstallTime = base.firstInstallTime;
lastUpdateTime = base.lastUpdateTime;
diff --git a/services/java/com/android/server/pm/PendingPackage.java b/services/java/com/android/server/pm/PendingPackage.java
index c17cc46..36c3a34 100644
--- a/services/java/com/android/server/pm/PendingPackage.java
+++ b/services/java/com/android/server/pm/PendingPackage.java
@@ -22,8 +22,8 @@
final int sharedId;
PendingPackage(String name, String realName, File codePath, File resourcePath,
- String nativeLibraryPathString, int sharedId, int pVersionCode, int pkgFlags) {
- super(name, realName, codePath, resourcePath, nativeLibraryPathString, pVersionCode,
+ String nativeLibraryPathString, String requiredCpuAbiString, int sharedId, int pVersionCode, int pkgFlags) {
+ super(name, realName, codePath, resourcePath, nativeLibraryPathString, requiredCpuAbiString, pVersionCode,
pkgFlags);
this.sharedId = sharedId;
}
diff --git a/services/java/com/android/server/pm/Settings.java b/services/java/com/android/server/pm/Settings.java
index ed025e1..a50c689 100644
--- a/services/java/com/android/server/pm/Settings.java
+++ b/services/java/com/android/server/pm/Settings.java
@@ -213,10 +213,10 @@
PackageSetting getPackageLPw(PackageParser.Package pkg, PackageSetting origPackage,
String realName, SharedUserSetting sharedUser, File codePath, File resourcePath,
- String nativeLibraryPathString, int pkgFlags, UserHandle user, boolean add) {
+ String nativeLibraryPathString, String requiredCpuAbiString, int pkgFlags, UserHandle user, boolean add) {
final String name = pkg.packageName;
PackageSetting p = getPackageLPw(name, origPackage, realName, sharedUser, codePath,
- resourcePath, nativeLibraryPathString, pkg.mVersionCode, pkgFlags,
+ resourcePath, nativeLibraryPathString, requiredCpuAbiString, pkg.mVersionCode, pkgFlags,
user, add, true /* allowInstall */);
return p;
}
@@ -298,7 +298,7 @@
p.pkg.applicationInfo.flags &= ~ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
}
PackageSetting ret = addPackageLPw(name, p.realName, p.codePath, p.resourcePath,
- p.nativeLibraryPathString, p.appId, p.versionCode, p.pkgFlags);
+ p.nativeLibraryPathString, p.requiredCpuAbiString, p.appId, p.versionCode, p.pkgFlags);
mDisabledSysPackages.remove(name);
return ret;
}
@@ -312,7 +312,7 @@
}
PackageSetting addPackageLPw(String name, String realName, File codePath, File resourcePath,
- String nativeLibraryPathString, int uid, int vc, int pkgFlags) {
+ String nativeLibraryPathString, String requiredCpuAbiString, int uid, int vc, int pkgFlags) {
PackageSetting p = mPackages.get(name);
if (p != null) {
if (p.appId == uid) {
@@ -322,7 +322,7 @@
"Adding duplicate package, keeping first: " + name);
return null;
}
- p = new PackageSetting(name, realName, codePath, resourcePath, nativeLibraryPathString,
+ p = new PackageSetting(name, realName, codePath, resourcePath, nativeLibraryPathString, requiredCpuAbiString,
vc, pkgFlags);
p.appId = uid;
if (addUserIdLPw(uid, p, name)) {
@@ -391,10 +391,11 @@
private PackageSetting getPackageLPw(String name, PackageSetting origPackage,
String realName, SharedUserSetting sharedUser, File codePath, File resourcePath,
- String nativeLibraryPathString, int vc, int pkgFlags,
+ String nativeLibraryPathString, String requiredCpuAbiString, int vc, int pkgFlags,
UserHandle installUser, boolean add, boolean allowInstall) {
PackageSetting p = mPackages.get(name);
if (p != null) {
+ p.requiredCpuAbiString = requiredCpuAbiString;
if (!p.codePath.equals(codePath)) {
// Check to see if its a disabled system app
if ((p.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0) {
@@ -438,7 +439,7 @@
if (origPackage != null) {
// We are consuming the data from an existing package.
p = new PackageSetting(origPackage.name, name, codePath, resourcePath,
- nativeLibraryPathString, vc, pkgFlags);
+ nativeLibraryPathString, requiredCpuAbiString, vc, pkgFlags);
if (PackageManagerService.DEBUG_UPGRADE) Log.v(PackageManagerService.TAG, "Package "
+ name + " is adopting original package " + origPackage.name);
// Note that we will retain the new package's signature so
@@ -455,7 +456,7 @@
p.setTimeStamp(codePath.lastModified());
} else {
p = new PackageSetting(name, realName, codePath, resourcePath,
- nativeLibraryPathString, vc, pkgFlags);
+ nativeLibraryPathString, requiredCpuAbiString, vc, pkgFlags);
p.setTimeStamp(codePath.lastModified());
p.sharedUser = sharedUser;
// If this is not a system app, it starts out stopped.
@@ -581,6 +582,8 @@
&& !nativeLibraryPath.equalsIgnoreCase(p.nativeLibraryPathString)) {
p.nativeLibraryPathString = nativeLibraryPath;
}
+ // Update the required Cpu Abi
+ p.requiredCpuAbiString = pkg.applicationInfo.requiredCpuAbi;
// Update version code if needed
if (pkg.mVersionCode != p.versionCode) {
p.versionCode = pkg.mVersionCode;
@@ -1498,6 +1501,9 @@
if (pkg.nativeLibraryPathString != null) {
serializer.attribute(null, "nativeLibraryPath", pkg.nativeLibraryPathString);
}
+ if (pkg.requiredCpuAbiString != null) {
+ serializer.attribute(null, "requiredCpuAbi", pkg.requiredCpuAbiString);
+ }
if (pkg.sharedUser == null) {
serializer.attribute(null, "userId", Integer.toString(pkg.appId));
} else {
@@ -1540,6 +1546,9 @@
if (pkg.nativeLibraryPathString != null) {
serializer.attribute(null, "nativeLibraryPath", pkg.nativeLibraryPathString);
}
+ if (pkg.requiredCpuAbiString != null) {
+ serializer.attribute(null, "requiredCpuAbi", pkg.requiredCpuAbiString);
+ }
serializer.attribute(null, "flags", Integer.toString(pkg.pkgFlags));
serializer.attribute(null, "ft", Long.toHexString(pkg.timeStamp));
serializer.attribute(null, "it", Long.toHexString(pkg.firstInstallTime));
@@ -1804,7 +1813,7 @@
if (idObj != null && idObj instanceof SharedUserSetting) {
PackageSetting p = getPackageLPw(pp.name, null, pp.realName,
(SharedUserSetting) idObj, pp.codePath, pp.resourcePath,
- pp.nativeLibraryPathString, pp.versionCode, pp.pkgFlags,
+ pp.nativeLibraryPathString, pp.requiredCpuAbiString, pp.versionCode, pp.pkgFlags,
null, true /* add */, false /* allowInstall */);
if (p == null) {
PackageManagerService.reportSettingsProblem(Log.WARN,
@@ -2224,6 +2233,8 @@
String codePathStr = parser.getAttributeValue(null, "codePath");
String resourcePathStr = parser.getAttributeValue(null, "resourcePath");
String nativeLibraryPathStr = parser.getAttributeValue(null, "nativeLibraryPath");
+ String requiredCpuAbiString = parser.getAttributeValue(null, "requiredCpuAbi");
+
if (resourcePathStr == null) {
resourcePathStr = codePathStr;
}
@@ -2243,7 +2254,7 @@
pkgFlags |= ApplicationInfo.FLAG_PRIVILEGED;
}
PackageSetting ps = new PackageSetting(name, realName, codePathFile,
- new File(resourcePathStr), nativeLibraryPathStr, versionCode, pkgFlags);
+ new File(resourcePathStr), nativeLibraryPathStr, requiredCpuAbiString, versionCode, pkgFlags);
String timeStampStr = parser.getAttributeValue(null, "ft");
if (timeStampStr != null) {
try {
@@ -2310,6 +2321,7 @@
String codePathStr = null;
String resourcePathStr = null;
String nativeLibraryPathStr = null;
+ String requiredCpuAbiString = null;
String systemStr = null;
String installerPackageName = null;
String uidError = null;
@@ -2329,6 +2341,8 @@
codePathStr = parser.getAttributeValue(null, "codePath");
resourcePathStr = parser.getAttributeValue(null, "resourcePath");
nativeLibraryPathStr = parser.getAttributeValue(null, "nativeLibraryPath");
+ requiredCpuAbiString = parser.getAttributeValue(null, "requiredCpuAbi");
+
version = parser.getAttributeValue(null, "version");
if (version != null) {
try {
@@ -2405,7 +2419,7 @@
+ parser.getPositionDescription());
} else if (userId > 0) {
packageSetting = addPackageLPw(name.intern(), realName, new File(codePathStr),
- new File(resourcePathStr), nativeLibraryPathStr, userId, versionCode,
+ new File(resourcePathStr), nativeLibraryPathStr, requiredCpuAbiString, userId, versionCode,
pkgFlags);
if (PackageManagerService.DEBUG_SETTINGS)
Log.i(PackageManagerService.TAG, "Reading package " + name + ": userId="
@@ -2423,7 +2437,7 @@
userId = sharedIdStr != null ? Integer.parseInt(sharedIdStr) : 0;
if (userId > 0) {
packageSetting = new PendingPackage(name.intern(), realName, new File(
- codePathStr), new File(resourcePathStr), nativeLibraryPathStr, userId,
+ codePathStr), new File(resourcePathStr), nativeLibraryPathStr, requiredCpuAbiString, userId,
versionCode, pkgFlags);
packageSetting.setTimeStamp(timeStamp);
packageSetting.firstInstallTime = firstInstallTime;
@@ -2452,6 +2466,7 @@
packageSetting.uidError = "true".equals(uidError);
packageSetting.installerPackageName = installerPackageName;
packageSetting.nativeLibraryPathString = nativeLibraryPathStr;
+ packageSetting.requiredCpuAbiString = requiredCpuAbiString;
// Handle legacy string here for single-user mode
final String enabledStr = parser.getAttributeValue(null, ATTR_ENABLED);
if (enabledStr != null) {
@@ -2915,6 +2930,7 @@
pw.print(prefix); pw.print(" codePath="); pw.println(ps.codePathString);
pw.print(prefix); pw.print(" resourcePath="); pw.println(ps.resourcePathString);
pw.print(prefix); pw.print(" nativeLibraryPath="); pw.println(ps.nativeLibraryPathString);
+ pw.print(prefix); pw.print(" requiredCpuAbi="); pw.println(ps.requiredCpuAbiString);
pw.print(prefix); pw.print(" versionCode="); pw.print(ps.versionCode);
if (ps.pkg != null) {
pw.print(" targetSdk="); pw.print(ps.pkg.applicationInfo.targetSdkVersion);