summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Richard Uhler <ruhler@google.com> 2015-03-25 16:25:57 -0700
committer Richard Uhler <ruhler@google.com> 2015-04-03 13:53:03 -0700
commit7b08b35bde3df58816b171b88712bcc6d21dcbe8 (patch)
tree7a18c33bf24a81b592ecbfd252252ffd494bfc6a
parent6aed9ec1b85ff1a8a39c4ec091a017f79413ead0 (diff)
Reuse dexopt method for both dex2oat and patchoat.
Change-Id: Ib9a6373f98474f1242367b5285086251a9d580e5
-rw-r--r--core/java/com/android/internal/os/InstallerConnection.java30
-rw-r--r--core/java/com/android/internal/os/ZygoteInit.java11
-rw-r--r--services/core/java/com/android/server/pm/Installer.java32
-rw-r--r--services/core/java/com/android/server/pm/PackageDexOptimizer.java91
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerService.java24
5 files changed, 64 insertions, 124 deletions
diff --git a/core/java/com/android/internal/os/InstallerConnection.java b/core/java/com/android/internal/os/InstallerConnection.java
index a4cdf194189f..671bf2444acc 100644
--- a/core/java/com/android/internal/os/InstallerConnection.java
+++ b/core/java/com/android/internal/os/InstallerConnection.java
@@ -90,12 +90,15 @@ public class InstallerConnection {
}
}
- public int dexopt(String apkPath, int uid, boolean isPublic, String instructionSet) {
- return dexopt(apkPath, uid, isPublic, "*", instructionSet, false, false, null);
+ public int dexopt(String apkPath, int uid, boolean isPublic,
+ String instructionSet, int dexoptNeeded) {
+ return dexopt(apkPath, uid, isPublic, "*", instructionSet, dexoptNeeded,
+ false, false, null);
}
public int dexopt(String apkPath, int uid, boolean isPublic, String pkgName,
- String instructionSet, boolean vmSafeMode, boolean debuggable, String outputPath) {
+ String instructionSet, int dexoptNeeded, boolean vmSafeMode,
+ boolean debuggable, String outputPath) {
StringBuilder builder = new StringBuilder("dexopt");
builder.append(' ');
builder.append(apkPath);
@@ -106,6 +109,8 @@ public class InstallerConnection {
builder.append(pkgName);
builder.append(' ');
builder.append(instructionSet);
+ builder.append(' ');
+ builder.append(dexoptNeeded);
builder.append(vmSafeMode ? " 1" : " 0");
builder.append(debuggable ? " 1" : " 0");
builder.append(' ');
@@ -113,25 +118,6 @@ public class InstallerConnection {
return execute(builder.toString());
}
- public int patchoat(String apkPath, int uid, boolean isPublic, String instructionSet) {
- return patchoat(apkPath, uid, isPublic, "*", instructionSet);
- }
-
- 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());
- }
-
private boolean connect() {
if (mSocket != null) {
return true;
diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java
index 98638ed2cf75..50ddbd16ba39 100644
--- a/core/java/com/android/internal/os/ZygoteInit.java
+++ b/core/java/com/android/internal/os/ZygoteInit.java
@@ -465,12 +465,11 @@ public class ZygoteInit {
try {
for (String classPathElement : classPathElements) {
- final byte dexopt = DexFile.isDexOptNeededInternal(classPathElement, "*", instructionSet,
- false /* defer */);
- if (dexopt == DexFile.DEXOPT_NEEDED) {
- installer.dexopt(classPathElement, Process.SYSTEM_UID, false, instructionSet);
- } else if (dexopt == DexFile.PATCHOAT_NEEDED) {
- installer.patchoat(classPathElement, Process.SYSTEM_UID, false, instructionSet);
+ final int dexoptNeeded = DexFile.getDexOptNeeded(
+ classPathElement, "*", instructionSet, false /* defer */);
+ if (dexoptNeeded != DexFile.NO_DEXOPT_NEEDED) {
+ installer.dexopt(classPathElement, Process.SYSTEM_UID, false,
+ instructionSet, dexoptNeeded);
}
}
} catch (IOException ioe) {
diff --git a/services/core/java/com/android/server/pm/Installer.java b/services/core/java/com/android/server/pm/Installer.java
index b4a44a646551..3215acb9240c 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 680ec4b4bb87..4c36fa6eea65 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 67d3cbea2d3e..231b0f090288 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);