am f324d245: Merge "Reuse dexopt method for both dex2oat and patchoat."
* commit 'f324d245fdd07ac14ab312d1a5fa04a4e8dfcceb': Reuse dexopt method for both dex2oat and patchoat.
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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="
|
||||
final int dexoptNeeded;
|
||||
if (forceDex) {
|
||||
dexoptNeeded = DexFile.DEX2OAT_NEEDED;
|
||||
} else {
|
||||
dexoptNeeded = DexFile.getDexOptNeeded(path,
|
||||
pkg.packageName, dexCodeInstructionSet, defer);
|
||||
}
|
||||
|
||||
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 {
|
||||
throw new IllegalStateException("Invalid dexopt needed: " + dexoptNeeded);
|
||||
}
|
||||
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);
|
||||
|
||||
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;
|
||||
}
|
||||
} else {
|
||||
final int ret = mPackageManagerService.mInstaller
|
||||
.dexopt(path, sharedGid,
|
||||
!pkg.isForwardLocked(), pkg.packageName,
|
||||
dexCodeInstructionSet,
|
||||
vmSafeMode, debuggable, null);
|
||||
if (ret < 0) {
|
||||
return DEX_OPT_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
performedDexOpt = true;
|
||||
} else if (!defer && isDexOptNeeded == DexFile.PATCHOAT_NEEDED) {
|
||||
Log.i(TAG, "Running patchoat on: " + pkg.applicationInfo.packageName);
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -1458,18 +1458,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);
|
||||
@@ -1515,13 +1507,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);
|
||||
|
||||
Reference in New Issue
Block a user