Merge "Frameworks/base: Propagate boot status to installd" into mnc-dr-dev

This commit is contained in:
Andreas Gampe
2015-09-22 18:27:39 +00:00
committed by Android (Google) Code Review
5 changed files with 51 additions and 27 deletions

View File

@@ -92,14 +92,14 @@ public class InstallerConnection {
} }
public int dexopt(String apkPath, int uid, boolean isPublic, public int dexopt(String apkPath, int uid, boolean isPublic,
String instructionSet, int dexoptNeeded) { String instructionSet, int dexoptNeeded, boolean bootComplete) {
return dexopt(apkPath, uid, isPublic, "*", instructionSet, dexoptNeeded, return dexopt(apkPath, uid, isPublic, "*", instructionSet, dexoptNeeded,
false, false, null); false, false, null, bootComplete);
} }
public int dexopt(String apkPath, int uid, boolean isPublic, String pkgName, public int dexopt(String apkPath, int uid, boolean isPublic, String pkgName,
String instructionSet, int dexoptNeeded, boolean vmSafeMode, String instructionSet, int dexoptNeeded, boolean vmSafeMode,
boolean debuggable, String outputPath) { boolean debuggable, String outputPath, boolean bootComplete) {
StringBuilder builder = new StringBuilder("dexopt"); StringBuilder builder = new StringBuilder("dexopt");
builder.append(' '); builder.append(' ');
builder.append(apkPath); builder.append(apkPath);
@@ -116,6 +116,7 @@ public class InstallerConnection {
builder.append(debuggable ? " 1" : " 0"); builder.append(debuggable ? " 1" : " 0");
builder.append(' '); builder.append(' ');
builder.append(outputPath != null ? outputPath : "!"); builder.append(outputPath != null ? outputPath : "!");
builder.append(bootComplete ? " 1" : " 0");
return execute(builder.toString()); return execute(builder.toString());
} }

View File

@@ -477,7 +477,7 @@ public class ZygoteInit {
classPathElement, "*", instructionSet, false /* defer */); classPathElement, "*", instructionSet, false /* defer */);
if (dexoptNeeded != DexFile.NO_DEXOPT_NEEDED) { if (dexoptNeeded != DexFile.NO_DEXOPT_NEEDED) {
installer.dexopt(classPathElement, Process.SYSTEM_UID, false, installer.dexopt(classPathElement, Process.SYSTEM_UID, false,
instructionSet, dexoptNeeded); instructionSet, dexoptNeeded, false /* boot complete */);
} }
} }
} catch (IOException ioe) { } catch (IOException ioe) {

View File

@@ -77,24 +77,37 @@ public final class Installer extends SystemService {
public int dexopt(String apkPath, int uid, boolean isPublic, public int dexopt(String apkPath, int uid, boolean isPublic,
String instructionSet, int dexoptNeeded) { String instructionSet, int dexoptNeeded) {
return dexopt(apkPath, uid, isPublic, instructionSet, dexoptNeeded, true);
}
public int dexopt(String apkPath, int uid, boolean isPublic,
String instructionSet, int dexoptNeeded, boolean bootComplete) {
if (!isValidInstructionSet(instructionSet)) { if (!isValidInstructionSet(instructionSet)) {
Slog.e(TAG, "Invalid instruction set: " + instructionSet); Slog.e(TAG, "Invalid instruction set: " + instructionSet);
return -1; return -1;
} }
return mInstaller.dexopt(apkPath, uid, isPublic, instructionSet, dexoptNeeded); return mInstaller.dexopt(apkPath, uid, isPublic, instructionSet, dexoptNeeded,
bootComplete);
} }
public int dexopt(String apkPath, int uid, boolean isPublic, String pkgName, public int dexopt(String apkPath, int uid, boolean isPublic, String pkgName,
String instructionSet, int dexoptNeeded, boolean vmSafeMode, String instructionSet, int dexoptNeeded, boolean vmSafeMode,
boolean debuggable, @Nullable String outputPath) { boolean debuggable, @Nullable String outputPath) {
return dexopt(apkPath, uid, isPublic, pkgName, instructionSet, dexoptNeeded, vmSafeMode,
debuggable, outputPath, true);
}
public int dexopt(String apkPath, int uid, boolean isPublic, String pkgName,
String instructionSet, int dexoptNeeded, boolean vmSafeMode,
boolean debuggable, @Nullable String outputPath, boolean bootComplete) {
if (!isValidInstructionSet(instructionSet)) { if (!isValidInstructionSet(instructionSet)) {
Slog.e(TAG, "Invalid instruction set: " + instructionSet); Slog.e(TAG, "Invalid instruction set: " + instructionSet);
return -1; return -1;
} }
return mInstaller.dexopt(apkPath, uid, isPublic, pkgName, return mInstaller.dexopt(apkPath, uid, isPublic, pkgName,
instructionSet, dexoptNeeded, vmSafeMode, instructionSet, dexoptNeeded, vmSafeMode,
debuggable, outputPath); debuggable, outputPath, bootComplete);
} }
public int idmap(String targetApkPath, String overlayApkPath, int uid) { public int idmap(String targetApkPath, String overlayApkPath, int uid) {

View File

@@ -71,7 +71,7 @@ final class PackageDexOptimizer {
* {@link PackageManagerService#mInstallLock}. * {@link PackageManagerService#mInstallLock}.
*/ */
int performDexOpt(PackageParser.Package pkg, String[] instructionSets, int performDexOpt(PackageParser.Package pkg, String[] instructionSets,
boolean forceDex, boolean defer, boolean inclDependencies) { boolean forceDex, boolean defer, boolean inclDependencies, boolean bootComplete) {
ArraySet<String> done; ArraySet<String> done;
if (inclDependencies && (pkg.usesLibraries != null || pkg.usesOptionalLibraries != null)) { if (inclDependencies && (pkg.usesLibraries != null || pkg.usesOptionalLibraries != null)) {
done = new ArraySet<String>(); done = new ArraySet<String>();
@@ -86,7 +86,7 @@ final class PackageDexOptimizer {
mDexoptWakeLock.acquire(); mDexoptWakeLock.acquire();
} }
try { try {
return performDexOptLI(pkg, instructionSets, forceDex, defer, done); return performDexOptLI(pkg, instructionSets, forceDex, defer, bootComplete, done);
} finally { } finally {
if (useLock) { if (useLock) {
mDexoptWakeLock.release(); mDexoptWakeLock.release();
@@ -96,18 +96,19 @@ final class PackageDexOptimizer {
} }
private int performDexOptLI(PackageParser.Package pkg, String[] targetInstructionSets, private int performDexOptLI(PackageParser.Package pkg, String[] targetInstructionSets,
boolean forceDex, boolean defer, ArraySet<String> done) { boolean forceDex, boolean defer, boolean bootComplete, ArraySet<String> done) {
final String[] instructionSets = targetInstructionSets != null ? final String[] instructionSets = targetInstructionSets != null ?
targetInstructionSets : getAppDexInstructionSets(pkg.applicationInfo); targetInstructionSets : getAppDexInstructionSets(pkg.applicationInfo);
if (done != null) { if (done != null) {
done.add(pkg.packageName); done.add(pkg.packageName);
if (pkg.usesLibraries != null) { if (pkg.usesLibraries != null) {
performDexOptLibsLI(pkg.usesLibraries, instructionSets, forceDex, defer, done); performDexOptLibsLI(pkg.usesLibraries, instructionSets, forceDex, defer,
bootComplete, done);
} }
if (pkg.usesOptionalLibraries != null) { if (pkg.usesOptionalLibraries != null) {
performDexOptLibsLI(pkg.usesOptionalLibraries, instructionSets, forceDex, defer, performDexOptLibsLI(pkg.usesOptionalLibraries, instructionSets, forceDex, defer,
done); bootComplete, done);
} }
} }
@@ -174,11 +175,11 @@ final class PackageDexOptimizer {
Log.i(TAG, "Running dexopt (" + dexoptType + ") on: " + path + " pkg=" Log.i(TAG, "Running dexopt (" + dexoptType + ") on: " + path + " pkg="
+ pkg.applicationInfo.packageName + " isa=" + dexCodeInstructionSet + pkg.applicationInfo.packageName + " isa=" + dexCodeInstructionSet
+ " vmSafeMode=" + vmSafeMode + " debuggable=" + debuggable + " vmSafeMode=" + vmSafeMode + " debuggable=" + debuggable
+ " oatDir = " + oatDir); + " oatDir = " + oatDir + " bootComplete=" + bootComplete);
final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid); final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid);
final int ret = mPackageManagerService.mInstaller.dexopt(path, sharedGid, final int ret = mPackageManagerService.mInstaller.dexopt(path, sharedGid,
!pkg.isForwardLocked(), pkg.packageName, dexCodeInstructionSet, !pkg.isForwardLocked(), pkg.packageName, dexCodeInstructionSet,
dexoptNeeded, vmSafeMode, debuggable, oatDir); dexoptNeeded, vmSafeMode, debuggable, oatDir, bootComplete);
// Dex2oat might fail due to compiler / verifier errors. We soldier on // Dex2oat might fail due to compiler / verifier errors. We soldier on
// regardless, and attempt to interpret the app as a safety net. // regardless, and attempt to interpret the app as a safety net.
@@ -235,12 +236,12 @@ final class PackageDexOptimizer {
} }
private void performDexOptLibsLI(ArrayList<String> libs, String[] instructionSets, private void performDexOptLibsLI(ArrayList<String> libs, String[] instructionSets,
boolean forceDex, boolean defer, ArraySet<String> done) { boolean forceDex, boolean defer, boolean bootComplete, ArraySet<String> done) {
for (String libName : libs) { for (String libName : libs) {
PackageParser.Package libPkg = mPackageManagerService.findSharedNonSystemLibrary( PackageParser.Package libPkg = mPackageManagerService.findSharedNonSystemLibrary(
libName); libName);
if (libPkg != null && !done.contains(libName)) { if (libPkg != null && !done.contains(libName)) {
performDexOptLI(libPkg, instructionSets, forceDex, defer, done); performDexOptLI(libPkg, instructionSets, forceDex, defer, bootComplete, done);
} }
} }
} }

View File

@@ -1979,7 +1979,7 @@ public class PackageManagerService extends IPackageManager.Stub {
int dexoptNeeded = DexFile.getDexOptNeeded(lib, null, dexCodeInstructionSet, false); int dexoptNeeded = DexFile.getDexOptNeeded(lib, null, dexCodeInstructionSet, false);
if (dexoptNeeded != DexFile.NO_DEXOPT_NEEDED) { if (dexoptNeeded != DexFile.NO_DEXOPT_NEEDED) {
alreadyDexOpted.add(lib); alreadyDexOpted.add(lib);
mInstaller.dexopt(lib, Process.SYSTEM_UID, true, dexCodeInstructionSet, dexoptNeeded); mInstaller.dexopt(lib, Process.SYSTEM_UID, true, dexCodeInstructionSet, dexoptNeeded, false);
} }
} catch (FileNotFoundException e) { } catch (FileNotFoundException e) {
Slog.w(TAG, "Library not found: " + lib); Slog.w(TAG, "Library not found: " + lib);
@@ -2027,7 +2027,7 @@ public class PackageManagerService extends IPackageManager.Stub {
try { try {
int dexoptNeeded = DexFile.getDexOptNeeded(path, null, dexCodeInstructionSet, false); int dexoptNeeded = DexFile.getDexOptNeeded(path, null, dexCodeInstructionSet, false);
if (dexoptNeeded != DexFile.NO_DEXOPT_NEEDED) { if (dexoptNeeded != DexFile.NO_DEXOPT_NEEDED) {
mInstaller.dexopt(path, Process.SYSTEM_UID, true, dexCodeInstructionSet, dexoptNeeded); mInstaller.dexopt(path, Process.SYSTEM_UID, true, dexCodeInstructionSet, dexoptNeeded, false);
} }
} catch (FileNotFoundException e) { } catch (FileNotFoundException e) {
Slog.w(TAG, "Jar not found: " + path); Slog.w(TAG, "Jar not found: " + path);
@@ -2256,7 +2256,8 @@ public class PackageManagerService extends IPackageManager.Stub {
// the rest of the commands above) because there's precious little we // the rest of the commands above) because there's precious little we
// can do about it. A settings error is reported, though. // can do about it. A settings error is reported, though.
adjustCpuAbisForSharedUserLPw(setting.packages, null /* scanned package */, adjustCpuAbisForSharedUserLPw(setting.packages, null /* scanned package */,
false /* force dexopt */, false /* defer dexopt */); false /* force dexopt */, false /* defer dexopt */,
false /* boot complete */);
} }
// Now that we know all the packages we are keeping, // Now that we know all the packages we are keeping,
@@ -6208,7 +6209,8 @@ public class PackageManagerService extends IPackageManager.Stub {
PackageParser.Package p = pkg; PackageParser.Package p = pkg;
synchronized (mInstallLock) { synchronized (mInstallLock) {
mPackageDexOptimizer.performDexOpt(p, null /* instruction sets */, mPackageDexOptimizer.performDexOpt(p, null /* instruction sets */,
false /* force dex */, false /* defer */, true /* include dependencies */); false /* force dex */, false /* defer */, true /* include dependencies */,
false /* boot complete */);
} }
} }
@@ -6251,7 +6253,8 @@ public class PackageManagerService extends IPackageManager.Stub {
synchronized (mInstallLock) { synchronized (mInstallLock) {
final String[] instructionSets = new String[] { targetInstructionSet }; final String[] instructionSets = new String[] { targetInstructionSet };
int result = mPackageDexOptimizer.performDexOpt(p, instructionSets, int result = mPackageDexOptimizer.performDexOpt(p, instructionSets,
false /* forceDex */, false /* defer */, true /* inclDependencies */); false /* forceDex */, false /* defer */, true /* inclDependencies */,
true /* boot complete */);
return result == PackageDexOptimizer.DEX_OPT_PERFORMED; return result == PackageDexOptimizer.DEX_OPT_PERFORMED;
} }
} finally { } finally {
@@ -6298,7 +6301,8 @@ public class PackageManagerService extends IPackageManager.Stub {
final String[] instructionSets = new String[] { final String[] instructionSets = new String[] {
getPrimaryInstructionSet(pkg.applicationInfo) }; getPrimaryInstructionSet(pkg.applicationInfo) };
final int res = mPackageDexOptimizer.performDexOpt(pkg, instructionSets, final int res = mPackageDexOptimizer.performDexOpt(pkg, instructionSets,
true /*forceDex*/, false /* defer */, true /* inclDependencies */); true /*forceDex*/, false /* defer */, true /* inclDependencies */,
true /* boot complete */);
if (res != PackageDexOptimizer.DEX_OPT_PERFORMED) { if (res != PackageDexOptimizer.DEX_OPT_PERFORMED) {
throw new IllegalStateException("Failed to dexopt: " + res); throw new IllegalStateException("Failed to dexopt: " + res);
} }
@@ -7090,12 +7094,13 @@ public class PackageManagerService extends IPackageManager.Stub {
// we can avoid redundant dexopts, and also to make sure we've got the // we can avoid redundant dexopts, and also to make sure we've got the
// code and package path correct. // code and package path correct.
adjustCpuAbisForSharedUserLPw(pkgSetting.sharedUser.packages, adjustCpuAbisForSharedUserLPw(pkgSetting.sharedUser.packages,
pkg, forceDex, (scanFlags & SCAN_DEFER_DEX) != 0); pkg, forceDex, (scanFlags & SCAN_DEFER_DEX) != 0, true /* boot complete */);
} }
if ((scanFlags & SCAN_NO_DEX) == 0) { if ((scanFlags & SCAN_NO_DEX) == 0) {
int result = mPackageDexOptimizer.performDexOpt(pkg, null /* instruction sets */, int result = mPackageDexOptimizer.performDexOpt(pkg, null /* instruction sets */,
forceDex, (scanFlags & SCAN_DEFER_DEX) != 0, false /* inclDependencies */); forceDex, (scanFlags & SCAN_DEFER_DEX) != 0, false /* inclDependencies */,
(scanFlags & SCAN_BOOTING) == 0);
if (result == PackageDexOptimizer.DEX_OPT_FAILED) { if (result == PackageDexOptimizer.DEX_OPT_FAILED) {
throw new PackageManagerException(INSTALL_FAILED_DEXOPT, "scanPackageLI"); throw new PackageManagerException(INSTALL_FAILED_DEXOPT, "scanPackageLI");
} }
@@ -7171,7 +7176,8 @@ public class PackageManagerService extends IPackageManager.Stub {
PackageParser.Package clientPkg = clientLibPkgs.get(i); PackageParser.Package clientPkg = clientLibPkgs.get(i);
int result = mPackageDexOptimizer.performDexOpt(clientPkg, int result = mPackageDexOptimizer.performDexOpt(clientPkg,
null /* instruction sets */, forceDex, null /* instruction sets */, forceDex,
(scanFlags & SCAN_DEFER_DEX) != 0, false); (scanFlags & SCAN_DEFER_DEX) != 0, false,
(scanFlags & SCAN_BOOTING) == 0);
if (result == PackageDexOptimizer.DEX_OPT_FAILED) { if (result == PackageDexOptimizer.DEX_OPT_FAILED) {
throw new PackageManagerException(INSTALL_FAILED_DEXOPT, throw new PackageManagerException(INSTALL_FAILED_DEXOPT,
"scanPackageLI failed to dexopt clientLibPkgs"); "scanPackageLI failed to dexopt clientLibPkgs");
@@ -7712,7 +7718,8 @@ public class PackageManagerService extends IPackageManager.Stub {
* adds unnecessary complexity. * adds unnecessary complexity.
*/ */
private void adjustCpuAbisForSharedUserLPw(Set<PackageSetting> packagesForUser, private void adjustCpuAbisForSharedUserLPw(Set<PackageSetting> packagesForUser,
PackageParser.Package scannedPackage, boolean forceDexOpt, boolean deferDexOpt) { PackageParser.Package scannedPackage, boolean forceDexOpt, boolean deferDexOpt,
boolean bootComplete) {
String requiredInstructionSet = null; String requiredInstructionSet = null;
if (scannedPackage != null && scannedPackage.applicationInfo.primaryCpuAbi != null) { if (scannedPackage != null && scannedPackage.applicationInfo.primaryCpuAbi != null) {
requiredInstructionSet = VMRuntime.getInstructionSet( requiredInstructionSet = VMRuntime.getInstructionSet(
@@ -7776,7 +7783,8 @@ public class PackageManagerService extends IPackageManager.Stub {
Slog.i(TAG, "Adjusting ABI for : " + ps.name + " to " + adjustedAbi); Slog.i(TAG, "Adjusting ABI for : " + ps.name + " to " + adjustedAbi);
int result = mPackageDexOptimizer.performDexOpt(ps.pkg, int result = mPackageDexOptimizer.performDexOpt(ps.pkg,
null /* instruction sets */, forceDexOpt, deferDexOpt, true); null /* instruction sets */, forceDexOpt, deferDexOpt, true,
bootComplete);
if (result == PackageDexOptimizer.DEX_OPT_FAILED) { if (result == PackageDexOptimizer.DEX_OPT_FAILED) {
ps.primaryCpuAbiString = null; ps.primaryCpuAbiString = null;
ps.pkg.applicationInfo.primaryCpuAbi = null; ps.pkg.applicationInfo.primaryCpuAbi = null;
@@ -12376,7 +12384,8 @@ public class PackageManagerService extends IPackageManager.Stub {
// Run dexopt before old package gets removed, to minimize time when app is unavailable // Run dexopt before old package gets removed, to minimize time when app is unavailable
int result = mPackageDexOptimizer int result = mPackageDexOptimizer
.performDexOpt(pkg, null /* instruction sets */, false /* forceDex */, .performDexOpt(pkg, null /* instruction sets */, false /* forceDex */,
false /* defer */, false /* inclDependencies */); false /* defer */, false /* inclDependencies */,
true /* boot complete */);
if (result == PackageDexOptimizer.DEX_OPT_FAILED) { if (result == PackageDexOptimizer.DEX_OPT_FAILED) {
res.setError(INSTALL_FAILED_DEXOPT, "Dexopt failed for " + pkg.codePath); res.setError(INSTALL_FAILED_DEXOPT, "Dexopt failed for " + pkg.codePath);
return; return;