Fix issue #2262563: 40 ANR reports from com.android.settings in dogfooding sholes running ERD43

Don't hold the global package log while instantiated an AssetManager+Resources, since
this is a fairly heavy-weight operation, and if done in the background can starve the
foreground.

Change-Id: I5ad37324fb7c27ffdbf28e1498ca0ad667479580
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index b116bf8..467812e 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -178,15 +178,16 @@
      * null.
      */
     Resources getTopLevelResources(String resDir, CompatibilityInfo compInfo) {
+        ResourcesKey key = new ResourcesKey(resDir, compInfo.applicationScale);
+        Resources r;
         synchronized (mPackages) {
             // Resources is app scale dependent.
-            ResourcesKey key = new ResourcesKey(resDir, compInfo.applicationScale);
             if (false) {
                 Log.w(TAG, "getTopLevelResources: " + resDir + " / "
                         + compInfo.applicationScale);
             }
             WeakReference<Resources> wr = mActiveResources.get(key);
-            Resources r = wr != null ? wr.get() : null;
+            r = wr != null ? wr.get() : null;
             if (r != null && r.getAssets().isUpToDate()) {
                 if (false) {
                     Log.w(TAG, "Returning cached resources " + r + " " + resDir
@@ -194,25 +195,37 @@
                 }
                 return r;
             }
+        }
 
-            //if (r != null) {
-            //    Log.w(TAG, "Throwing away out-of-date resources!!!! "
-            //            + r + " " + resDir);
-            //}
+        //if (r != null) {
+        //    Log.w(TAG, "Throwing away out-of-date resources!!!! "
+        //            + r + " " + resDir);
+        //}
 
-            AssetManager assets = new AssetManager();
-            if (assets.addAssetPath(resDir) == 0) {
-                return null;
+        AssetManager assets = new AssetManager();
+        if (assets.addAssetPath(resDir) == 0) {
+            return null;
+        }
+
+        //Log.i(TAG, "Resource: key=" + key + ", display metrics=" + metrics);
+        DisplayMetrics metrics = getDisplayMetricsLocked(false);
+        r = new Resources(assets, metrics, getConfiguration(), compInfo);
+        if (false) {
+            Log.i(TAG, "Created app resources " + resDir + " " + r + ": "
+                    + r.getConfiguration() + " appScale="
+                    + r.getCompatibilityInfo().applicationScale);
+        }
+        
+        synchronized (mPackages) {
+            WeakReference<Resources> wr = mActiveResources.get(key);
+            Resources existing = wr != null ? wr.get() : null;
+            if (existing != null && existing.getAssets().isUpToDate()) {
+                // Someone else already created the resources while we were
+                // unlocked; go ahead and use theirs.
+                r.getAssets().close();
+                return existing;
             }
-
-            //Log.i(TAG, "Resource: key=" + key + ", display metrics=" + metrics);
-            DisplayMetrics metrics = getDisplayMetricsLocked(false);
-            r = new Resources(assets, metrics, getConfiguration(), compInfo);
-            if (false) {
-                Log.i(TAG, "Created app resources " + resDir + " " + r + ": "
-                        + r.getConfiguration() + " appScale="
-                        + r.getCompatibilityInfo().applicationScale);
-            }
+            
             // XXX need to remove entries when weak references go away
             mActiveResources.put(key, new WeakReference<Resources>(r));
             return r;