Do not make strong reference to Resources.

This CL removes the strong reference added for mapping display ids
and Resources to Displays. Instead, the key pair is now the display
id and ResourcesKey, and the mapping is pruned when key is
invalidated.

Change-Id: I60d767b52de7bbf769f6761f5a3301dd7aff6ddf
Fixes: 36625868
Test: make -j32 cts; cts-tradefed; run cts --module CtsAppTestCases --test android.app.cts.DisplayTest#testRotation
(cherry picked from commit 2d2315a66d81d29896e6a0ffedbfbbed3981b9ed)
diff --git a/core/java/android/app/ResourcesManager.java b/core/java/android/app/ResourcesManager.java
index d620a81..3191eec 100644
--- a/core/java/android/app/ResourcesManager.java
+++ b/core/java/android/app/ResourcesManager.java
@@ -44,6 +44,8 @@
 
 import java.lang.ref.WeakReference;
 import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.Map;
 import java.util.Objects;
 import java.util.WeakHashMap;
 import java.util.function.Predicate;
@@ -114,7 +116,7 @@
      * A cache of DisplayId, Resources to Display. These display adjustments associated with these
      * {@link Display}s will change as the resources change.
      */
-    private final ArrayMap<Pair<Integer, Resources>, WeakReference<Display>> mResourceDisplays =
+    private final ArrayMap<Pair<Integer, ResourcesKey>, WeakReference<Display>> mResourceDisplays =
         new ArrayMap<>();
 
     public static ResourcesManager getInstance() {
@@ -137,10 +139,7 @@
             for (int i = 0; i < mResourceImpls.size();) {
                 final ResourcesKey key = mResourceImpls.keyAt(i);
                 if (key.isPathReferenced(path)) {
-                    final ResourcesImpl res = mResourceImpls.removeAt(i).get();
-                    if (res != null) {
-                        res.flushLayoutCache();
-                    }
+                    cleanupResourceImpl(key);
                     count++;
                 } else {
                     i++;
@@ -251,8 +250,14 @@
      * @param resources The {@link Resources} backing the display adjustments.
      */
     public Display getAdjustedDisplay(final int displayId, Resources resources) {
-        final Pair<Integer, Resources> key = Pair.create(displayId, resources);
         synchronized (this) {
+            // Note that the ResourcesKey might be {@code null} in the case that the
+            // {@link Resources} is actually from {@link Resources#getSystem}. In this case, it is
+            // not managed by {@link ResourcesManager}, but we still want to cache the display
+            // object.
+            final Pair<Integer, ResourcesKey> key = Pair.create(displayId,
+                    findKeyForResourceImplLocked(resources.getImpl()));
+
             WeakReference<Display> wd = mResourceDisplays.get(key);
             if (wd != null) {
                 final Display display = wd.get();
@@ -273,6 +278,32 @@
         }
     }
 
+    private void cleanupResourceImpl(ResourcesKey removedKey) {
+        // Remove any resource to display mapping based on this key.
+        final Iterator<Map.Entry<Pair<Integer, ResourcesKey>, WeakReference<Display>>> iter =
+                mResourceDisplays.entrySet().iterator();
+        while (iter.hasNext()) {
+            final Map.Entry<Pair<Integer, ResourcesKey>, WeakReference<Display>> entry =
+                    iter.next();
+            final ResourcesKey key = entry.getKey().second;
+
+            // Do not touch system resource displays (indicated by a {@code null} key) or
+            // non-matching keys.
+            if (key == null || !key.equals(removedKey)) {
+                continue;
+            }
+
+            iter.remove();
+        }
+
+        // Remove resource key to resource impl mapping and flush cache
+        final ResourcesImpl res = mResourceImpls.remove(removedKey).get();
+
+        if (res != null) {
+            res.flushLayoutCache();
+        }
+    }
+
     /**
      * Creates an AssetManager from the paths within the ResourcesKey.
      *