diff options
9 files changed, 174 insertions, 68 deletions
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java index 6ccdd08..e39bf60 100644 --- a/core/java/com/android/internal/os/BatteryStatsImpl.java +++ b/core/java/com/android/internal/os/BatteryStatsImpl.java @@ -8044,6 +8044,10 @@ public final class BatteryStatsImpl extends BatteryStats { * wakelocks. If the screen is on, we just assign the actual cpu time an app used. */ public void updateCpuTimeLocked() { + if (mPowerProfile == null) { + return; + } + if (DEBUG_ENERGY_CPU) { Slog.d(TAG, "!Cpu updating!"); } @@ -8131,14 +8135,19 @@ public final class BatteryStatsImpl extends BatteryStats { // Add the cpu speeds to this UID. These are used as a ratio // for computing the power this UID used. - if (u.mCpuClusterSpeed == null) { - u.mCpuClusterSpeed = new LongSamplingCounter[clusterSpeeds.length][]; + final int numClusters = mPowerProfile.getNumCpuClusters(); + if (u.mCpuClusterSpeed == null || u.mCpuClusterSpeed.length != + numClusters) { + u.mCpuClusterSpeed = new LongSamplingCounter[numClusters][]; } for (int cluster = 0; cluster < clusterSpeeds.length; cluster++) { - if (u.mCpuClusterSpeed[cluster] == null) { + final int speedsInCluster = mPowerProfile.getNumSpeedStepsInCpuCluster( + cluster); + if (u.mCpuClusterSpeed[cluster] == null || speedsInCluster != + u.mCpuClusterSpeed[cluster].length) { u.mCpuClusterSpeed[cluster] = - new LongSamplingCounter[clusterSpeeds[cluster].length]; + new LongSamplingCounter[speedsInCluster]; } final LongSamplingCounter[] cpuSpeeds = u.mCpuClusterSpeed[cluster]; diff --git a/core/java/com/android/internal/os/InstallerConnection.java b/core/java/com/android/internal/os/InstallerConnection.java index dcc6a5e..db2b41f 100644 --- a/core/java/com/android/internal/os/InstallerConnection.java +++ b/core/java/com/android/internal/os/InstallerConnection.java @@ -92,14 +92,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); @@ -116,6 +116,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 06919e1..59283bb 100644 --- a/core/java/com/android/internal/os/ZygoteInit.java +++ b/core/java/com/android/internal/os/ZygoteInit.java @@ -477,7 +477,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/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java index 8a09b7c..055b5ef 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java +++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java @@ -920,9 +920,27 @@ public class KeyguardViewMediator extends SystemUI { } catch (RemoteException e) { Slog.w(TAG, "Failed to call onKeyguardExitResult(false)", e); } + } else if (!isSecure()) { + + // Keyguard is not secure, no need to do anything, and we don't need to reshow + // the Keyguard after the client releases the Keyguard lock. + mExternallyEnabled = true; + mNeedToReshowWhenReenabled = false; + updateInputRestricted(); + try { + callback.onKeyguardExitResult(true); + } catch (RemoteException e) { + Slog.w(TAG, "Failed to call onKeyguardExitResult(false)", e); + } } else { - mExitSecureCallback = callback; - verifyUnlockLocked(); + + // Since we prevent apps from hiding the Keyguard if we are secure, this should be + // a no-op as well. + try { + callback.onKeyguardExitResult(false); + } catch (RemoteException e) { + Slog.w(TAG, "Failed to call onKeyguardExitResult(false)", e); + } } } } diff --git a/services/core/java/com/android/server/GestureLauncherService.java b/services/core/java/com/android/server/GestureLauncherService.java index bd7d4b2..7c85001 100644 --- a/services/core/java/com/android/server/GestureLauncherService.java +++ b/services/core/java/com/android/server/GestureLauncherService.java @@ -101,8 +101,7 @@ public class GestureLauncherService extends SystemService { * Whether camera double tap power button gesture is currently enabled; */ private boolean mCameraDoubleTapPowerEnabled; - private long mLastPowerDownWhileNonInteractive; - private long mLastPowerDownWhileInteractive; + private long mLastPowerDown; public GestureLauncherService(Context context) { super(context); @@ -252,35 +251,32 @@ public class GestureLauncherService extends SystemService { public boolean interceptPowerKeyDown(KeyEvent event, boolean interactive) { boolean launched = false; boolean intercept = false; + long doubleTapInterval; synchronized (this) { - if (!mCameraDoubleTapPowerEnabled) { - mLastPowerDownWhileNonInteractive = 0; - mLastPowerDownWhileInteractive = 0; - return false; - } - if (event.getEventTime() - mLastPowerDownWhileNonInteractive - < CAMERA_POWER_DOUBLE_TAP_TIME_MS) { - launched = true; - intercept = true; - } else if (event.getEventTime() - mLastPowerDownWhileInteractive - < CAMERA_POWER_DOUBLE_TAP_TIME_MS) { + doubleTapInterval = event.getEventTime() - mLastPowerDown; + if (mCameraDoubleTapPowerEnabled + && doubleTapInterval < CAMERA_POWER_DOUBLE_TAP_TIME_MS) { launched = true; + intercept = interactive; } - mLastPowerDownWhileNonInteractive = interactive ? 0 : event.getEventTime(); - mLastPowerDownWhileInteractive = interactive ? event.getEventTime() : 0; + mLastPowerDown = event.getEventTime(); } if (launched) { Slog.i(TAG, "Power button double tap gesture detected, launching camera."); - launched = handleCameraLaunchGesture(false /* useWakelock */, - MetricsLogger.ACTION_DOUBLE_TAP_POWER_CAMERA_GESTURE); + launched = handleCameraLaunchGesture(false /* useWakelock */); + if (launched) { + MetricsLogger.action(mContext, MetricsLogger.ACTION_DOUBLE_TAP_POWER_CAMERA_GESTURE, + (int) doubleTapInterval); + } } + MetricsLogger.histogram(mContext, "power_double_tap_interval", (int) doubleTapInterval); return intercept && launched; } /** * @return true if camera was launched, false otherwise. */ - private boolean handleCameraLaunchGesture(boolean useWakelock, int logCategory) { + private boolean handleCameraLaunchGesture(boolean useWakelock) { boolean userSetupComplete = Settings.Secure.getInt(mContext.getContentResolver(), Settings.Secure.USER_SETUP_COMPLETE, 0) != 0; if (!userSetupComplete) { @@ -300,7 +296,6 @@ public class GestureLauncherService extends SystemService { StatusBarManagerInternal service = LocalServices.getService( StatusBarManagerInternal.class); service.onCameraLaunchGestureDetected(); - MetricsLogger.action(mContext, logCategory); return true; } @@ -339,8 +334,8 @@ public class GestureLauncherService extends SystemService { Slog.d(TAG, String.format("Received a camera launch event: " + "values=[%.4f, %.4f, %.4f].", values[0], values[1], values[2])); } - if (handleCameraLaunchGesture(true /* useWakelock */, - MetricsLogger.ACTION_WIGGLE_CAMERA_GESTURE)) { + if (handleCameraLaunchGesture(true /* useWakelock */)) { + MetricsLogger.action(mContext, MetricsLogger.ACTION_WIGGLE_CAMERA_GESTURE); trackCameraLaunchEvent(event); } return; diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 525aac7..e3b5651 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -316,6 +316,9 @@ public final class ActivityManagerService extends ActivityManagerNative // How long we wait for a launched process to attach to the activity manager // before we decide it's never going to come up for real. static final int PROC_START_TIMEOUT = 10*1000; + // How long we wait for an attached process to publish its content providers + // before we decide it must be hung. + static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10*1000; // How long we wait for a launched process to attach to the activity manager // before we decide it's never going to come up for real, when the process was @@ -1368,6 +1371,7 @@ public final class ActivityManagerService extends ActivityManagerNative static final int REPORT_USER_SWITCH_COMPLETE_MSG = 56; static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 57; static final int APP_BOOST_DEACTIVATE_MSG = 58; + static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 59; static final int FIRST_ACTIVITY_STACK_MSG = 100; static final int FIRST_BROADCAST_QUEUE_MSG = 200; @@ -1701,6 +1705,12 @@ public final class ActivityManagerService extends ActivityManagerNative processStartTimedOutLocked(app); } } break; + case CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG: { + ProcessRecord app = (ProcessRecord)msg.obj; + synchronized (ActivityManagerService.this) { + processContentProviderPublishTimedOutLocked(app); + } + } break; case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { synchronized (ActivityManagerService.this) { mStackSupervisor.doPendingActivityLaunchesLocked(true); @@ -5944,6 +5954,11 @@ public final class ActivityManagerService extends ActivityManagerNative return needRestart; } + private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) { + cleanupAppInLaunchingProvidersLocked(app, true); + removeProcessLocked(app, false, true, "timeout publishing content providers"); + } + private final void processStartTimedOutLocked(ProcessRecord app) { final int pid = app.pid; boolean gone = false; @@ -5970,7 +5985,7 @@ public final class ActivityManagerService extends ActivityManagerNative mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); } // Take care of any launching providers waiting for this process. - checkAppInLaunchingProvidersLocked(app, true); + cleanupAppInLaunchingProvidersLocked(app, true); // Take care of any services that are waiting for the process. mServices.processStartTimedOutLocked(app); app.kill("start timeout", true); @@ -6066,6 +6081,12 @@ public final class ActivityManagerService extends ActivityManagerNative boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null; + if (providers != null && checkAppInLaunchingProvidersLocked(app)) { + Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG); + msg.obj = app; + mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT); + } + if (!normalMode) { Slog.i(TAG, "Launching preboot mode app: " + app); } @@ -9897,7 +9918,7 @@ public final class ActivityManagerService extends ActivityManagerNative final long origId = Binder.clearCallingIdentity(); final int N = providers.size(); - for (int i=0; i<N; i++) { + for (int i = 0; i < N; i++) { ContentProviderHolder src = providers.get(i); if (src == null || src.info == null || src.provider == null) { continue; @@ -9912,15 +9933,20 @@ public final class ActivityManagerService extends ActivityManagerNative mProviderMap.putProviderByName(names[j], dst); } - int NL = mLaunchingProviders.size(); + int launchingCount = mLaunchingProviders.size(); int j; - for (j=0; j<NL; j++) { + boolean wasInLaunchingProviders = false; + for (j = 0; j < launchingCount; j++) { if (mLaunchingProviders.get(j) == dst) { mLaunchingProviders.remove(j); + wasInLaunchingProviders = true; j--; - NL--; + launchingCount--; } } + if (wasInLaunchingProviders) { + mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r); + } synchronized (dst) { dst.provider = src.provider; dst.proc = r; @@ -15531,7 +15557,7 @@ public final class ActivityManagerService extends ActivityManagerNative app.pubProviders.clear(); // Take care of any launching providers waiting for this process. - if (checkAppInLaunchingProvidersLocked(app, false)) { + if (cleanupAppInLaunchingProvidersLocked(app, false)) { restart = true; } @@ -15653,7 +15679,17 @@ public final class ActivityManagerService extends ActivityManagerNative return false; } - boolean checkAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { + boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) { + for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) { + ContentProviderRecord cpr = mLaunchingProviders.get(i); + if (cpr.launchingApp == app) { + return true; + } + } + return false; + } + + boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) { // Look through the content providers we are waiting to have launched, // and if any run in this process then either schedule a restart of // the process or kill the client waiting for it if this process has diff --git a/services/core/java/com/android/server/pm/Installer.java b/services/core/java/com/android/server/pm/Installer.java index b59b4b2..f292c9c 100644 --- a/services/core/java/com/android/server/pm/Installer.java +++ b/services/core/java/com/android/server/pm/Installer.java @@ -77,24 +77,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 8c23648..b692def 100644 --- a/services/core/java/com/android/server/pm/PackageDexOptimizer.java +++ b/services/core/java/com/android/server/pm/PackageDexOptimizer.java @@ -71,7 +71,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<String> done; if (inclDependencies && (pkg.usesLibraries != null || pkg.usesOptionalLibraries != null)) { done = new ArraySet<String>(); @@ -86,7 +86,7 @@ final class PackageDexOptimizer { mDexoptWakeLock.acquire(); } try { - return performDexOptLI(pkg, instructionSets, forceDex, defer, done); + return performDexOptLI(pkg, instructionSets, forceDex, defer, bootComplete, done); } finally { if (useLock) { mDexoptWakeLock.release(); @@ -96,18 +96,19 @@ final class PackageDexOptimizer { } 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 ? 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); } } @@ -174,11 +175,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); // Dex2oat might fail due to compiler / verifier errors. We soldier on // 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, - boolean forceDex, boolean defer, ArraySet<String> done) { + boolean forceDex, boolean defer, boolean bootComplete, ArraySet<String> 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 3330a50..8e6e688 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -1979,7 +1979,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); @@ -2027,7 +2027,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); @@ -2256,7 +2256,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, @@ -6208,7 +6209,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 */); } } @@ -6251,7 +6253,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; } } finally { @@ -6298,7 +6301,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); } @@ -7090,12 +7094,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"); } @@ -7171,7 +7176,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"); @@ -7712,7 +7718,8 @@ public class PackageManagerService extends IPackageManager.Stub { * adds unnecessary complexity. */ 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; if (scannedPackage != null && scannedPackage.applicationInfo.primaryCpuAbi != null) { requiredInstructionSet = VMRuntime.getInstructionSet( @@ -7776,7 +7783,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; @@ -12376,7 +12384,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 */, false /* 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; @@ -15678,14 +15687,28 @@ public class PackageManagerService extends IPackageManager.Stub { } } - private void loadPrivatePackages(VolumeInfo vol) { + private void loadPrivatePackages(final VolumeInfo vol) { + mHandler.post(new Runnable() { + @Override + public void run() { + loadPrivatePackagesInner(vol); + } + }); + } + + private void loadPrivatePackagesInner(VolumeInfo vol) { final ArrayList<ApplicationInfo> loaded = new ArrayList<>(); final int parseFlags = mDefParseFlags | PackageParser.PARSE_EXTERNAL_STORAGE; - synchronized (mInstallLock) { + + final VersionInfo ver; + final List<PackageSetting> packages; synchronized (mPackages) { - final VersionInfo ver = mSettings.findOrCreateVersion(vol.fsUuid); - final List<PackageSetting> packages = mSettings.getVolumePackagesLPr(vol.fsUuid); - for (PackageSetting ps : packages) { + ver = mSettings.findOrCreateVersion(vol.fsUuid); + packages = mSettings.getVolumePackagesLPr(vol.fsUuid); + } + + for (PackageSetting ps : packages) { + synchronized (mInstallLock) { final PackageParser.Package pkg; try { pkg = scanPackageLI(ps.codePath, parseFlags, SCAN_INITIAL, 0L, null); @@ -15698,7 +15721,9 @@ public class PackageManagerService extends IPackageManager.Stub { deleteCodeCacheDirsLI(ps.volumeUuid, ps.name); } } + } + synchronized (mPackages) { int updateFlags = UPDATE_PERMISSIONS_ALL; if (ver.sdkVersion != mSdkVersion) { logCriticalInfo(Log.INFO, "Platform changed from " + ver.sdkVersion + " to " @@ -15712,13 +15737,21 @@ public class PackageManagerService extends IPackageManager.Stub { mSettings.writeLPr(); } - } if (DEBUG_INSTALL) Slog.d(TAG, "Loaded packages " + loaded); sendResourcesChangedBroadcast(true, false, loaded, null); } - private void unloadPrivatePackages(VolumeInfo vol) { + private void unloadPrivatePackages(final VolumeInfo vol) { + mHandler.post(new Runnable() { + @Override + public void run() { + unloadPrivatePackagesInner(vol); + } + }); + } + + private void unloadPrivatePackagesInner(VolumeInfo vol) { final ArrayList<ApplicationInfo> unloaded = new ArrayList<>(); synchronized (mInstallLock) { synchronized (mPackages) { |