Fix issue #7196015: system_server deadlock during setup wizard
Can't aquire the providers lock while holding the main activity thead
lock, because we call into the activity manager with that lock held.
Change-Id: If27326a2caa46480d0f1b98608be9e8a862febe0
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 9b82f2a..bcfb7d1 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -3636,39 +3636,45 @@
}
}
- ArrayList<ComponentCallbacks2> collectComponentCallbacksLocked(
+ ArrayList<ComponentCallbacks2> collectComponentCallbacks(
boolean allActivities, Configuration newConfig) {
ArrayList<ComponentCallbacks2> callbacks
= new ArrayList<ComponentCallbacks2>();
- if (mActivities.size() > 0) {
- for (ActivityClientRecord ar : mActivities.values()) {
- Activity a = ar.activity;
- if (a != null) {
- Configuration thisConfig = applyConfigCompatMainThread(mCurDefaultDisplayDpi,
- newConfig, ar.packageInfo.mCompatibilityInfo.getIfNeeded());
- if (!ar.activity.mFinished && (allActivities || !ar.paused)) {
- // If the activity is currently resumed, its configuration
- // needs to change right now.
- callbacks.add(a);
- } else if (thisConfig != null) {
- // Otherwise, we will tell it about the change
- // the next time it is resumed or shown. Note that
- // the activity manager may, before then, decide the
- // activity needs to be destroyed to handle its new
- // configuration.
- if (DEBUG_CONFIGURATION) {
- Slog.v(TAG, "Setting activity "
- + ar.activityInfo.name + " newConfig=" + thisConfig);
+ synchronized (mPackages) {
+ final int N = mAllApplications.size();
+ for (int i=0; i<N; i++) {
+ callbacks.add(mAllApplications.get(i));
+ }
+ if (mActivities.size() > 0) {
+ for (ActivityClientRecord ar : mActivities.values()) {
+ Activity a = ar.activity;
+ if (a != null) {
+ Configuration thisConfig = applyConfigCompatMainThread(mCurDefaultDisplayDpi,
+ newConfig, ar.packageInfo.mCompatibilityInfo.getIfNeeded());
+ if (!ar.activity.mFinished && (allActivities || !ar.paused)) {
+ // If the activity is currently resumed, its configuration
+ // needs to change right now.
+ callbacks.add(a);
+ } else if (thisConfig != null) {
+ // Otherwise, we will tell it about the change
+ // the next time it is resumed or shown. Note that
+ // the activity manager may, before then, decide the
+ // activity needs to be destroyed to handle its new
+ // configuration.
+ if (DEBUG_CONFIGURATION) {
+ Slog.v(TAG, "Setting activity "
+ + ar.activityInfo.name + " newConfig=" + thisConfig);
+ }
+ ar.newConfig = thisConfig;
}
- ar.newConfig = thisConfig;
}
}
}
- }
- if (mServices.size() > 0) {
- for (Service service : mServices.values()) {
- callbacks.add(service);
+ if (mServices.size() > 0) {
+ for (Service service : mServices.values()) {
+ callbacks.add(service);
+ }
}
}
synchronized (mProviderMap) {
@@ -3678,10 +3684,6 @@
}
}
}
- final int N = mAllApplications.size();
- for (int i=0; i<N; i++) {
- callbacks.add(mAllApplications.get(i));
- }
return callbacks;
}
@@ -3842,7 +3844,6 @@
final void handleConfigurationChanged(Configuration config, CompatibilityInfo compat) {
- ArrayList<ComponentCallbacks2> callbacks = null;
int configDiff = 0;
synchronized (mPackages) {
@@ -3873,9 +3874,10 @@
configDiff = mConfiguration.diff(config);
mConfiguration.updateFrom(config);
config = applyCompatConfiguration(mCurDefaultDisplayDpi);
- callbacks = collectComponentCallbacksLocked(false, config);
}
-
+
+ ArrayList<ComponentCallbacks2> callbacks = collectComponentCallbacks(false, config);
+
// Cleanup hardware accelerated stuff
WindowManagerGlobal.getInstance().trimLocalMemory();
@@ -3988,11 +3990,7 @@
}
final void handleLowMemory() {
- ArrayList<ComponentCallbacks2> callbacks;
-
- synchronized (mPackages) {
- callbacks = collectComponentCallbacksLocked(true, null);
- }
+ ArrayList<ComponentCallbacks2> callbacks = collectComponentCallbacks(true, null);
final int N = callbacks.size();
for (int i=0; i<N; i++) {
@@ -4020,10 +4018,7 @@
final WindowManagerGlobal windowManager = WindowManagerGlobal.getInstance();
windowManager.startTrimMemory(level);
- ArrayList<ComponentCallbacks2> callbacks;
- synchronized (mPackages) {
- callbacks = collectComponentCallbacksLocked(true, null);
- }
+ ArrayList<ComponentCallbacks2> callbacks = collectComponentCallbacks(true, null);
final int N = callbacks.size();
for (int i = 0; i < N; i++) {