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++) {