Merge "Fix reintroduction of b/10845061" into mnc-dr-dev
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index 6ccdd08..e39bf607 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -8044,6 +8044,10 @@
* 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 @@
// 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 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 @@
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 @@
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 @@
} 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 @@
* 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 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) {
+ doubleTapInterval = event.getEventTime() - mLastPowerDown;
+ if (mCameraDoubleTapPowerEnabled
+ && doubleTapInterval < CAMERA_POWER_DOUBLE_TAP_TIME_MS) {
launched = true;
- intercept = true;
- } else if (event.getEventTime() - mLastPowerDownWhileInteractive
- < 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 @@
StatusBarManagerInternal service = LocalServices.getService(
StatusBarManagerInternal.class);
service.onCameraLaunchGestureDetected();
- MetricsLogger.action(mContext, logCategory);
return true;
}
@@ -339,8 +334,8 @@
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 @@
// 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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 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 @@
* {@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 @@
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 @@
}
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 @@
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 @@
}
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 @@
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 @@
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 @@
// 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 @@
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 @@
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 @@
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 @@
// 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 @@
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 @@
* 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 @@
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 @@
// 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 @@
}
}
- 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 @@
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 @@
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) {