diff options
Diffstat (limited to 'services')
3 files changed, 51 insertions, 96 deletions
diff --git a/services/core/java/com/android/server/pm/Installer.java b/services/core/java/com/android/server/pm/Installer.java index b4a44a6..3215acb 100644 --- a/services/core/java/com/android/server/pm/Installer.java +++ b/services/core/java/com/android/server/pm/Installer.java @@ -55,43 +55,25 @@ public final class Installer extends SystemService { return mInstaller.execute(builder.toString()); } - public int patchoat(String apkPath, int uid, boolean isPublic, String pkgName, - String instructionSet) { + public int dexopt(String apkPath, int uid, boolean isPublic, + String instructionSet, int dexoptNeeded) { if (!isValidInstructionSet(instructionSet)) { Slog.e(TAG, "Invalid instruction set: " + instructionSet); return -1; } - return mInstaller.patchoat(apkPath, uid, isPublic, pkgName, instructionSet); - } - - public int patchoat(String apkPath, int uid, boolean isPublic, String instructionSet) { - if (!isValidInstructionSet(instructionSet)) { - Slog.e(TAG, "Invalid instruction set: " + instructionSet); - return -1; - } - - return mInstaller.patchoat(apkPath, uid, isPublic, instructionSet); - } - - public int dexopt(String apkPath, int uid, boolean isPublic, String instructionSet) { - if (!isValidInstructionSet(instructionSet)) { - Slog.e(TAG, "Invalid instruction set: " + instructionSet); - return -1; - } - - return mInstaller.dexopt(apkPath, uid, isPublic, instructionSet); + return mInstaller.dexopt(apkPath, uid, isPublic, instructionSet, dexoptNeeded); } public int dexopt(String apkPath, int uid, boolean isPublic, String pkgName, - String instructionSet, boolean vmSafeMode, boolean debuggable, - @Nullable String outputPath) { + String instructionSet, int dexoptNeeded, boolean vmSafeMode, + boolean debuggable, @Nullable String outputPath) { if (!isValidInstructionSet(instructionSet)) { Slog.e(TAG, "Invalid instruction set: " + instructionSet); return -1; } - - return mInstaller.dexopt(apkPath, uid, isPublic, pkgName, instructionSet, vmSafeMode, + return mInstaller.dexopt(apkPath, uid, isPublic, pkgName, + instructionSet, dexoptNeeded, vmSafeMode, debuggable, outputPath); } diff --git a/services/core/java/com/android/server/pm/PackageDexOptimizer.java b/services/core/java/com/android/server/pm/PackageDexOptimizer.java index 680ec4b..4c36fa6 100644 --- a/services/core/java/com/android/server/pm/PackageDexOptimizer.java +++ b/services/core/java/com/android/server/pm/PackageDexOptimizer.java @@ -113,64 +113,48 @@ final class PackageDexOptimizer { for (String path : paths) { try { - // This will return DEXOPT_NEEDED if we either cannot find any odex file for this - // package 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. - final byte isDexOptNeeded = DexFile.isDexOptNeededInternal(path, - pkg.packageName, dexCodeInstructionSet, defer); - if (forceDex || (!defer && isDexOptNeeded == DexFile.DEXOPT_NEEDED)) { - File oatDir = createOatDirIfSupported(pkg, dexCodeInstructionSet); - Log.i(TAG, "Running dexopt on: " + path + " pkg=" - + pkg.applicationInfo.packageName + " isa=" + dexCodeInstructionSet - + " vmSafeMode=" + vmSafeMode + " debuggable=" + debuggable - + " oatDir = " + oatDir); - final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid); + final int dexoptNeeded; + if (forceDex) { + dexoptNeeded = DexFile.DEX2OAT_NEEDED; + } else { + dexoptNeeded = DexFile.getDexOptNeeded(path, + pkg.packageName, dexCodeInstructionSet, defer); + } - if (oatDir != null) { - int ret = mPackageManagerService.mInstaller.dexopt( - path, sharedGid, !pkg.isForwardLocked(), pkg.packageName, - dexCodeInstructionSet, vmSafeMode, debuggable, - oatDir.getAbsolutePath()); - if (ret < 0) { - return DEX_OPT_FAILED; - } + if (!forceDex && defer && dexoptNeeded != DexFile.NO_DEXOPT_NEEDED) { + // We're deciding to defer a needed dexopt. Don't bother dexopting for other + // paths and instruction sets. We'll deal with them all together when we process + // our list of deferred dexopts. + addPackageForDeferredDexopt(pkg); + return DEX_OPT_DEFERRED; + } + + if (dexoptNeeded != DexFile.NO_DEXOPT_NEEDED) { + final String dexoptType; + String oatDir = null; + if (dexoptNeeded == DexFile.DEX2OAT_NEEDED) { + dexoptType = "dex2oat"; + oatDir = createOatDirIfSupported(pkg, dexCodeInstructionSet); + } else if (dexoptNeeded == DexFile.PATCHOAT_NEEDED) { + dexoptType = "patchoat"; + } else if (dexoptNeeded == DexFile.SELF_PATCHOAT_NEEDED) { + dexoptType = "self patchoat"; } else { - final int ret = mPackageManagerService.mInstaller - .dexopt(path, sharedGid, - !pkg.isForwardLocked(), pkg.packageName, - dexCodeInstructionSet, - vmSafeMode, debuggable, null); - if (ret < 0) { - return DEX_OPT_FAILED; - } + throw new IllegalStateException("Invalid dexopt needed: " + dexoptNeeded); } - - performedDexOpt = true; - } else if (!defer && isDexOptNeeded == DexFile.PATCHOAT_NEEDED) { - Log.i(TAG, "Running patchoat on: " + pkg.applicationInfo.packageName); + Log.i(TAG, "Running dexopt (" + dexoptType + ") on: " + path + " pkg=" + + pkg.applicationInfo.packageName + " isa=" + dexCodeInstructionSet + + " vmSafeMode=" + vmSafeMode + " debuggable=" + debuggable + + " oatDir = " + oatDir); final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid); - final int ret = mPackageManagerService.mInstaller.patchoat(path, sharedGid, - !pkg.isForwardLocked(), pkg.packageName, dexCodeInstructionSet); - + final int ret = mPackageManagerService.mInstaller.dexopt(path, sharedGid, + !pkg.isForwardLocked(), pkg.packageName, dexCodeInstructionSet, + dexoptNeeded, vmSafeMode, debuggable, oatDir); if (ret < 0) { - // Don't bother running patchoat again if we failed, it will probably - // just result in an error again. Also, don't bother dexopting for other - // paths & ISAs. return DEX_OPT_FAILED; } - performedDexOpt = true; } - - // We're deciding to defer a needed dexopt. Don't bother dexopting for other - // paths and instruction sets. We'll deal with them all together when we process - // our list of deferred dexopts. - if (defer && isDexOptNeeded != DexFile.UP_TO_DATE) { - addPackageForDeferredDexopt(pkg); - return DEX_OPT_DEFERRED; - } } catch (FileNotFoundException e) { Slog.w(TAG, "Apk not found for dexopt: " + path); return DEX_OPT_FAILED; @@ -187,7 +171,7 @@ final class PackageDexOptimizer { } // At this point we haven't failed dexopt and we haven't deferred dexopt. We must - // either have either succeeded dexopt, or have had isDexOptNeededInternal tell us + // either have either succeeded dexopt, or have had getDexOptNeeded tell us // it isn't required. We therefore mark that this package doesn't need dexopt unless // it's forced. performedDexOpt will tell us whether we performed dex-opt or skipped // it. @@ -209,10 +193,11 @@ final class PackageDexOptimizer { * <li>Package location is not a directory, i.e. monolithic install.</li> * </ul> * - * @return oat directory or null, if oat directory cannot be created. + * @return Absolute path to the oat directory or null, if oat directory + * cannot be created. */ @Nullable - private File createOatDirIfSupported(PackageParser.Package pkg, String dexInstructionSet) + private String createOatDirIfSupported(PackageParser.Package pkg, String dexInstructionSet) throws IOException { if (pkg.isSystemApp() && !pkg.isUpdatedSystemApp()) { return null; @@ -222,7 +207,7 @@ final class PackageDexOptimizer { File oatDir = getOatDir(codePath); mPackageManagerService.mInstaller.createOatDir(oatDir.getAbsolutePath(), dexInstructionSet); - return oatDir; + return oatDir.getAbsolutePath(); } return null; } diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index bb8a785..3f0e8b0 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -1457,18 +1457,10 @@ public class PackageManagerService extends IPackageManager.Stub { } try { - byte dexoptRequired = DexFile.isDexOptNeededInternal(lib, null, - dexCodeInstructionSet, - false); - if (dexoptRequired != DexFile.UP_TO_DATE) { + int dexoptNeeded = DexFile.getDexOptNeeded(lib, null, dexCodeInstructionSet, false); + if (dexoptNeeded != DexFile.NO_DEXOPT_NEEDED) { alreadyDexOpted.add(lib); - - // The list of "shared libraries" we have at this point is - if (dexoptRequired == DexFile.DEXOPT_NEEDED) { - mInstaller.dexopt(lib, Process.SYSTEM_UID, true, dexCodeInstructionSet); - } else { - mInstaller.patchoat(lib, Process.SYSTEM_UID, true, dexCodeInstructionSet); - } + mInstaller.dexopt(lib, Process.SYSTEM_UID, true, dexCodeInstructionSet, dexoptNeeded); } } catch (FileNotFoundException e) { Slog.w(TAG, "Library not found: " + lib); @@ -1514,13 +1506,9 @@ public class PackageManagerService extends IPackageManager.Stub { continue; } try { - byte dexoptRequired = DexFile.isDexOptNeededInternal(path, null, - dexCodeInstructionSet, - false); - if (dexoptRequired == DexFile.DEXOPT_NEEDED) { - mInstaller.dexopt(path, Process.SYSTEM_UID, true, dexCodeInstructionSet); - } else if (dexoptRequired == DexFile.PATCHOAT_NEEDED) { - mInstaller.patchoat(path, Process.SYSTEM_UID, true, dexCodeInstructionSet); + int dexoptNeeded = DexFile.getDexOptNeeded(path, null, dexCodeInstructionSet, false); + if (dexoptNeeded != DexFile.NO_DEXOPT_NEEDED) { + mInstaller.dexopt(path, Process.SYSTEM_UID, true, dexCodeInstructionSet, dexoptNeeded); } } catch (FileNotFoundException e) { Slog.w(TAG, "Jar not found: " + path); |