From 55fe944f987bcbdea8bbec7ea411684f69623da4 Mon Sep 17 00:00:00 2001 From: Andreas Gampe Date: Mon, 21 Sep 2015 13:20:07 -0700 Subject: Frameworks/base: Propagate boot status to installd Propagate the boot status explicitly to installd so that we do not have to rely on dev.bootcomplete, which isn't meaningfully set when the device needs the decryption screen on boot. Bug: 23898216 (cherry picked from commit 06bb908b78e3c790d3db52fef9f2ab0a129e53cd) Change-Id: I9b34298caf70b1e5d40970cc0d04c469016a80a7 --- .../android/internal/os/InstallerConnection.java | 7 +++-- core/java/com/android/internal/os/ZygoteInit.java | 2 +- .../core/java/com/android/server/pm/Installer.java | 17 +++++++++-- .../com/android/server/pm/PackageDexOptimizer.java | 19 +++++++------ .../android/server/pm/PackageManagerService.java | 33 ++++++++++++++-------- 5 files changed, 51 insertions(+), 27 deletions(-) diff --git a/core/java/com/android/internal/os/InstallerConnection.java b/core/java/com/android/internal/os/InstallerConnection.java index 671bf2444acc..2190af505c06 100644 --- a/core/java/com/android/internal/os/InstallerConnection.java +++ b/core/java/com/android/internal/os/InstallerConnection.java @@ -91,14 +91,14 @@ public class InstallerConnection { } 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, - false, false, null); + false, false, null, bootComplete); } public int dexopt(String apkPath, int uid, boolean isPublic, String pkgName, String instructionSet, int dexoptNeeded, boolean vmSafeMode, - boolean debuggable, String outputPath) { + boolean debuggable, String outputPath, boolean bootComplete) { StringBuilder builder = new StringBuilder("dexopt"); builder.append(' '); builder.append(apkPath); @@ -115,6 +115,7 @@ public class InstallerConnection { builder.append(debuggable ? " 1" : " 0"); builder.append(' '); builder.append(outputPath != null ? outputPath : "!"); + builder.append(bootComplete ? " 1" : " 0"); return execute(builder.toString()); } diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java index 915c075558fe..768a55eb702b 100644 --- a/core/java/com/android/internal/os/ZygoteInit.java +++ b/core/java/com/android/internal/os/ZygoteInit.java @@ -484,7 +484,7 @@ public class ZygoteInit { classPathElement, "*", instructionSet, false /* defer */); if (dexoptNeeded != DexFile.NO_DEXOPT_NEEDED) { installer.dexopt(classPathElement, Process.SYSTEM_UID, false, - instructionSet, dexoptNeeded); + instructionSet, dexoptNeeded, false /* boot complete */); } } } 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 ce31f98a6f50..f052db8ffa54 100644 --- a/services/core/java/com/android/server/pm/Installer.java +++ b/services/core/java/com/android/server/pm/Installer.java @@ -74,24 +74,37 @@ public final class Installer extends SystemService { public int dexopt(String apkPath, int uid, boolean isPublic, 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)) { Slog.e(TAG, "Invalid instruction set: " + instructionSet); 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, String instructionSet, int dexoptNeeded, boolean vmSafeMode, 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)) { Slog.e(TAG, "Invalid instruction set: " + instructionSet); return -1; } return mInstaller.dexopt(apkPath, uid, isPublic, pkgName, instructionSet, dexoptNeeded, vmSafeMode, - debuggable, outputPath); + debuggable, outputPath, bootComplete); } public int idmap(String targetApkPath, String overlayApkPath, int uid) { diff --git a/services/core/java/com/android/server/pm/PackageDexOptimizer.java b/services/core/java/com/android/server/pm/PackageDexOptimizer.java index 955ea3480173..9081850acb17 100644 --- a/services/core/java/com/android/server/pm/PackageDexOptimizer.java +++ b/services/core/java/com/android/server/pm/PackageDexOptimizer.java @@ -63,7 +63,7 @@ final class PackageDexOptimizer { * {@link PackageManagerService#mInstallLock}. */ int performDexOpt(PackageParser.Package pkg, String[] instructionSets, - boolean forceDex, boolean defer, boolean inclDependencies) { + boolean forceDex, boolean defer, boolean inclDependencies, boolean bootComplete) { ArraySet done; if (inclDependencies && (pkg.usesLibraries != null || pkg.usesOptionalLibraries != null)) { done = new ArraySet(); @@ -72,23 +72,24 @@ final class PackageDexOptimizer { done = null; } synchronized (mPackageManagerService.mInstallLock) { - return performDexOptLI(pkg, instructionSets, forceDex, defer, done); + return performDexOptLI(pkg, instructionSets, forceDex, defer, bootComplete, done); } } private int performDexOptLI(PackageParser.Package pkg, String[] targetInstructionSets, - boolean forceDex, boolean defer, ArraySet done) { + boolean forceDex, boolean defer, boolean bootComplete, ArraySet done) { final String[] instructionSets = targetInstructionSets != null ? targetInstructionSets : getAppDexInstructionSets(pkg.applicationInfo); if (done != null) { done.add(pkg.packageName); if (pkg.usesLibraries != null) { - performDexOptLibsLI(pkg.usesLibraries, instructionSets, forceDex, defer, done); + performDexOptLibsLI(pkg.usesLibraries, instructionSets, forceDex, defer, + bootComplete, done); } if (pkg.usesOptionalLibraries != null) { performDexOptLibsLI(pkg.usesOptionalLibraries, instructionSets, forceDex, defer, - done); + bootComplete, done); } } @@ -145,11 +146,11 @@ final class PackageDexOptimizer { Log.i(TAG, "Running dexopt (" + dexoptType + ") on: " + path + " pkg=" + pkg.applicationInfo.packageName + " isa=" + dexCodeInstructionSet + " vmSafeMode=" + vmSafeMode + " debuggable=" + debuggable - + " oatDir = " + oatDir); + + " oatDir = " + oatDir + " bootComplete=" + bootComplete); final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid); final int ret = mPackageManagerService.mInstaller.dexopt(path, sharedGid, !pkg.isForwardLocked(), pkg.packageName, dexCodeInstructionSet, - dexoptNeeded, vmSafeMode, debuggable, oatDir); + dexoptNeeded, vmSafeMode, debuggable, oatDir, bootComplete); if (ret < 0) { return DEX_OPT_FAILED; } @@ -218,12 +219,12 @@ final class PackageDexOptimizer { } private void performDexOptLibsLI(ArrayList libs, String[] instructionSets, - boolean forceDex, boolean defer, ArraySet done) { + boolean forceDex, boolean defer, boolean bootComplete, ArraySet done) { for (String libName : libs) { PackageParser.Package libPkg = mPackageManagerService.findSharedNonSystemLibrary( libName); if (libPkg != null && !done.contains(libName)) { - performDexOptLI(libPkg, instructionSets, forceDex, defer, done); + performDexOptLI(libPkg, instructionSets, forceDex, defer, bootComplete, done); } } } diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 34ed88dcd42d..a02feba30da6 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -1460,7 +1460,7 @@ public class PackageManagerService extends IPackageManager.Stub { int dexoptNeeded = DexFile.getDexOptNeeded(lib, null, dexCodeInstructionSet, false); if (dexoptNeeded != DexFile.NO_DEXOPT_NEEDED) { 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) { Slog.w(TAG, "Library not found: " + lib); @@ -1508,7 +1508,7 @@ public class PackageManagerService extends IPackageManager.Stub { try { int dexoptNeeded = DexFile.getDexOptNeeded(path, null, dexCodeInstructionSet, false); 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) { Slog.w(TAG, "Jar not found: " + path); @@ -1719,7 +1719,8 @@ public class PackageManagerService extends IPackageManager.Stub { // the rest of the commands above) because there's precious little we // can do about it. A settings error is reported, though. 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, @@ -4754,7 +4755,8 @@ public class PackageManagerService extends IPackageManager.Stub { PackageParser.Package p = pkg; synchronized (mInstallLock) { 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 */); } } @@ -4796,7 +4798,8 @@ public class PackageManagerService extends IPackageManager.Stub { synchronized (mInstallLock) { final String[] instructionSets = new String[] { targetInstructionSet }; 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; } } @@ -4840,7 +4843,8 @@ public class PackageManagerService extends IPackageManager.Stub { final String[] instructionSets = new String[] { getPrimaryInstructionSet(pkg.applicationInfo) }; 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) { throw new IllegalStateException("Failed to dexopt: " + res); } @@ -5605,12 +5609,13 @@ public class PackageManagerService extends IPackageManager.Stub { // we can avoid redundant dexopts, and also to make sure we've got the // code and package path correct. 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) { 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) { throw new PackageManagerException(INSTALL_FAILED_DEXOPT, "scanPackageLI"); } @@ -5686,7 +5691,8 @@ public class PackageManagerService extends IPackageManager.Stub { PackageParser.Package clientPkg = clientLibPkgs.get(i); int result = mPackageDexOptimizer.performDexOpt(clientPkg, 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) { throw new PackageManagerException(INSTALL_FAILED_DEXOPT, "scanPackageLI failed to dexopt clientLibPkgs"); @@ -6231,7 +6237,8 @@ public class PackageManagerService extends IPackageManager.Stub { * adds unnecessary complexity. */ private void adjustCpuAbisForSharedUserLPw(Set packagesForUser, - PackageParser.Package scannedPackage, boolean forceDexOpt, boolean deferDexOpt) { + PackageParser.Package scannedPackage, boolean forceDexOpt, boolean deferDexOpt, + boolean bootComplete) { String requiredInstructionSet = null; if (scannedPackage != null && scannedPackage.applicationInfo.primaryCpuAbi != null) { requiredInstructionSet = VMRuntime.getInstructionSet( @@ -6295,7 +6302,8 @@ public class PackageManagerService extends IPackageManager.Stub { Slog.i(TAG, "Adjusting ABI for : " + ps.name + " to " + adjustedAbi); 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) { ps.primaryCpuAbiString = null; ps.pkg.applicationInfo.primaryCpuAbi = null; @@ -10479,7 +10487,8 @@ public class PackageManagerService extends IPackageManager.Stub { // Run dexopt before old package gets removed, to minimize time when app is unavailable int result = mPackageDexOptimizer .performDexOpt(pkg, null /* instruction sets */, true /* forceDex */, - false /* defer */, false /* inclDependencies */); + false /* defer */, false /* inclDependencies */, + true /* boot complete */); if (result == PackageDexOptimizer.DEX_OPT_FAILED) { res.setError(INSTALL_FAILED_DEXOPT, "Dexopt failed for " + pkg.codePath); return; -- cgit v1.2.3-59-g8ed1b