summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrian Carlstrom <bdc@google.com>2014-08-05 17:47:12 +0000
committerGerrit Code Review <noreply-gerritcodereview@google.com>2014-08-05 00:30:25 +0000
commit8b8c718cbb4ac8d2e6210567d9b6097f428be222 (patch)
tree77b651e58b9f7fc8cc6d64be3b1e53de5955e95a
parent20bac14e521dd551addd8541380f1d9b6c910bd2 (diff)
parent1995d12d26bbaced73fd47f91b767731d290972c (diff)
downloadbase-8b8c718cbb4ac8d2e6210567d9b6097f428be222.tar.gz
Merge "Make system use patchoat to relocate during runtime."
-rw-r--r--services/java/com/android/server/pm/Installer.java28
-rwxr-xr-xservices/java/com/android/server/pm/PackageManagerService.java46
2 files changed, 65 insertions, 9 deletions
diff --git a/services/java/com/android/server/pm/Installer.java b/services/java/com/android/server/pm/Installer.java
index 66615c9895c6..0f384b1c372e 100644
--- a/services/java/com/android/server/pm/Installer.java
+++ b/services/java/com/android/server/pm/Installer.java
@@ -202,6 +202,34 @@ public final class Installer {
return execute(builder.toString());
}
+ public int patchoat(String apkPath, int uid, boolean isPublic, String pkgName,
+ String instructionSet) {
+ StringBuilder builder = new StringBuilder("patchoat");
+ builder.append(' ');
+ builder.append(apkPath);
+ builder.append(' ');
+ builder.append(uid);
+ builder.append(isPublic ? " 1" : " 0");
+ builder.append(' ');
+ builder.append(pkgName);
+ builder.append(' ');
+ builder.append(instructionSet);
+ return execute(builder.toString());
+ }
+
+ public int patchoat(String apkPath, int uid, boolean isPublic, String instructionSet) {
+ StringBuilder builder = new StringBuilder("patchoat");
+ builder.append(' ');
+ builder.append(apkPath);
+ builder.append(' ');
+ builder.append(uid);
+ builder.append(isPublic ? " 1" : " 0");
+ builder.append(" *"); // No pkgName arg present
+ builder.append(' ');
+ builder.append(instructionSet);
+ return execute(builder.toString());
+ }
+
public int dexopt(String apkPath, int uid, boolean isPublic, String instructionSet) {
StringBuilder builder = new StringBuilder("dexopt");
builder.append(' ');
diff --git a/services/java/com/android/server/pm/PackageManagerService.java b/services/java/com/android/server/pm/PackageManagerService.java
index 0941adbf51d9..f076fa0199b8 100755
--- a/services/java/com/android/server/pm/PackageManagerService.java
+++ b/services/java/com/android/server/pm/PackageManagerService.java
@@ -1368,11 +1368,18 @@ public class PackageManagerService extends IPackageManager.Stub {
}
try {
- if (DexFile.isDexOptNeededInternal(lib, null, instructionSet, false)) {
+ byte dexoptRequired = DexFile.isDexOptNeededInternal(lib, null,
+ instructionSet,
+ false);
+ if (dexoptRequired != DexFile.UP_TO_DATE) {
alreadyDexOpted.add(lib);
// The list of "shared libraries" we have at this point is
- mInstaller.dexopt(lib, Process.SYSTEM_UID, true, instructionSet);
+ if (dexoptRequired == DexFile.DEXOPT_NEEDED) {
+ mInstaller.dexopt(lib, Process.SYSTEM_UID, true, instructionSet);
+ } else {
+ mInstaller.patchoat(lib, Process.SYSTEM_UID, true, instructionSet);
+ }
didDexOptLibraryOrTool = true;
}
} catch (FileNotFoundException e) {
@@ -1419,9 +1426,15 @@ public class PackageManagerService extends IPackageManager.Stub {
continue;
}
try {
- if (DexFile.isDexOptNeededInternal(path, null, instructionSet, false)) {
+ byte dexoptRequired = DexFile.isDexOptNeededInternal(path, null,
+ instructionSet,
+ false);
+ if (dexoptRequired == DexFile.DEXOPT_NEEDED) {
mInstaller.dexopt(path, Process.SYSTEM_UID, true, instructionSet);
didDexOptLibraryOrTool = true;
+ } else if (dexoptRequired == DexFile.PATCHOAT_NEEDED) {
+ mInstaller.patchoat(path, Process.SYSTEM_UID, true, instructionSet);
+ didDexOptLibraryOrTool = true;
}
} catch (FileNotFoundException e) {
Slog.w(TAG, "Jar not found: " + path);
@@ -4282,15 +4295,18 @@ public class PackageManagerService extends IPackageManager.Stub {
if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_HAS_CODE) != 0) {
String path = pkg.mScanPath;
try {
- boolean isDexOptNeededInternal = DexFile.isDexOptNeededInternal(path,
- pkg.packageName,
- instructionSet,
- defer);
+ // This will return DEXOPT_NEEDED if we either cannot find any odex file for this
+ // patckage or the one we find does not match the image checksum (i.e. it was
+ // compiled against an old image). It will return PATCHOAT_NEEDED if we can find a
+ // odex file and it matches the checksum of the image but not its base address,
+ // meaning we need to move it.
+ byte isDexOptNeededInternal = DexFile.isDexOptNeededInternal(path, pkg.packageName,
+ instructionSet, defer);
// There are three basic cases here:
// 1.) we need to dexopt, either because we are forced or it is needed
// 2.) we are defering a needed dexopt
// 3.) we are skipping an unneeded dexopt
- if (forceDex || (!defer && isDexOptNeededInternal)) {
+ if (forceDex || (!defer && isDexOptNeededInternal == DexFile.DEXOPT_NEEDED)) {
Log.i(TAG, "Running dexopt on: " + pkg.applicationInfo.packageName);
final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid);
int ret = mInstaller.dexopt(path, sharedGid, !isForwardLocked(pkg),
@@ -4302,8 +4318,20 @@ public class PackageManagerService extends IPackageManager.Stub {
return DEX_OPT_FAILED;
}
return DEX_OPT_PERFORMED;
+ } else if (!defer && isDexOptNeededInternal == DexFile.PATCHOAT_NEEDED) {
+ Log.i(TAG, "Running patchoat on: " + pkg.applicationInfo.packageName);
+ final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid);
+ int ret = mInstaller.patchoat(path, sharedGid, !isForwardLocked(pkg),
+ pkg.packageName, instructionSet);
+ // Note that we ran patchoat, since rerunning will
+ // probably just result in an error again.
+ pkg.mDexOptNeeded = false;
+ if (ret < 0) {
+ return DEX_OPT_FAILED;
+ }
+ return DEX_OPT_PERFORMED;
}
- if (defer && isDexOptNeededInternal) {
+ if (defer && isDexOptNeededInternal != DexFile.UP_TO_DATE) {
if (mDeferredDexOpt == null) {
mDeferredDexOpt = new HashSet<PackageParser.Package>();
}