diff options
author | Alex Light <allight@google.com> | 2014-07-18 16:34:38 -0700 |
---|---|---|
committer | Alex Light <allight@google.com> | 2014-08-05 10:22:10 -0700 |
commit | 1995d12d26bbaced73fd47f91b767731d290972c (patch) | |
tree | 77b651e58b9f7fc8cc6d64be3b1e53de5955e95a | |
parent | 20bac14e521dd551addd8541380f1d9b6c910bd2 (diff) | |
download | base-1995d12d26bbaced73fd47f91b767731d290972c.tar.gz |
Make system use patchoat to relocate during runtime.
Make PackageManagerService aware of patchoat and make it use it when
appropriate.
Bug: 15358152
Change-Id: Ibe92d8b55a24bbf718b0416a21b76e5df7a2de26
-rw-r--r-- | services/java/com/android/server/pm/Installer.java | 28 | ||||
-rwxr-xr-x | services/java/com/android/server/pm/PackageManagerService.java | 46 |
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>(); } |