OSDN Git Service

Let ResourcesManager generate CompatResources
authorJason Monk <jmonk@google.com>
Thu, 2 Mar 2017 17:55:00 +0000 (12:55 -0500)
committerJason Monk <jmonk@google.com>
Thu, 2 Mar 2017 17:55:00 +0000 (12:55 -0500)
This will let the ResourcesImpl be updated and handle null cases
better.

Test: Select text while composing email.
Change-Id: Ia8aed22f02b040a202db9cbb2bc02687c693cfa1
Fixes: 34761805
Fixes: 35869547

core/java/android/app/ContextImpl.java
core/java/android/app/ResourcesManager.java
core/java/android/content/res/CompatResources.java
core/java/android/content/res/CompatibilityInfo.java

index 7ee93d0..0ab4b80 100644 (file)
@@ -2254,11 +2254,10 @@ class ContextImpl extends Context {
     }
 
     void setResources(Resources r) {
-        if (mPackageInfo.getTargetSdkVersion() < VERSION_CODES.O) {
-            mResources = new CompatResources(r, this);
-        } else {
-            mResources = r;
+        if (r instanceof CompatResources) {
+            ((CompatResources) r).setContext(this);
         }
+        mResources = r;
     }
 
     void installSystemApplicationInfo(ApplicationInfo info, ClassLoader classLoader) {
index 52ec045..b42df5e 100644 (file)
@@ -22,6 +22,7 @@ import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.content.pm.ActivityInfo;
 import android.content.res.AssetManager;
+import android.content.res.CompatResources;
 import android.content.res.CompatibilityInfo;
 import android.content.res.Configuration;
 import android.content.res.Resources;
@@ -447,7 +448,8 @@ public class ResourcesManager {
      * or the class loader is different.
      */
     private @NonNull Resources getOrCreateResourcesForActivityLocked(@NonNull IBinder activityToken,
-            @NonNull ClassLoader classLoader, @NonNull ResourcesImpl impl) {
+            @NonNull ClassLoader classLoader, @NonNull ResourcesImpl impl,
+            @NonNull CompatibilityInfo compatInfo) {
         final ActivityResources activityResources = getOrCreateActivityResourcesStructLocked(
                 activityToken);
 
@@ -466,7 +468,8 @@ public class ResourcesManager {
             }
         }
 
-        Resources resources = new Resources(classLoader);
+        Resources resources = compatInfo.needsCompatResources() ? new CompatResources(classLoader)
+                : new Resources(classLoader);
         resources.setImpl(impl);
         activityResources.activityResources.add(new WeakReference<>(resources));
         if (DEBUG) {
@@ -481,7 +484,7 @@ public class ResourcesManager {
      * otherwise creates a new Resources object.
      */
     private @NonNull Resources getOrCreateResourcesLocked(@NonNull ClassLoader classLoader,
-            @NonNull ResourcesImpl impl) {
+            @NonNull ResourcesImpl impl, @NonNull CompatibilityInfo compatInfo) {
         // Find an existing Resources that has this ResourcesImpl set.
         final int refCount = mResourceReferences.size();
         for (int i = 0; i < refCount; i++) {
@@ -498,7 +501,8 @@ public class ResourcesManager {
         }
 
         // Create a new Resources reference and use the existing ResourcesImpl object.
-        Resources resources = new Resources(classLoader);
+        Resources resources = compatInfo.needsCompatResources() ? new CompatResources(classLoader)
+                : new Resources(classLoader);
         resources.setImpl(impl);
         mResourceReferences.add(new WeakReference<>(resources));
         if (DEBUG) {
@@ -614,7 +618,7 @@ public class ResourcesManager {
                         Slog.d(TAG, "- using existing impl=" + resourcesImpl);
                     }
                     return getOrCreateResourcesForActivityLocked(activityToken, classLoader,
-                            resourcesImpl);
+                            resourcesImpl, key.mCompatInfo);
                 }
 
                 // We will create the ResourcesImpl object outside of holding this lock.
@@ -629,7 +633,7 @@ public class ResourcesManager {
                     if (DEBUG) {
                         Slog.d(TAG, "- using existing impl=" + resourcesImpl);
                     }
-                    return getOrCreateResourcesLocked(classLoader, resourcesImpl);
+                    return getOrCreateResourcesLocked(classLoader, resourcesImpl, key.mCompatInfo);
                 }
 
                 // We will create the ResourcesImpl object outside of holding this lock.
@@ -659,9 +663,9 @@ public class ResourcesManager {
             final Resources resources;
             if (activityToken != null) {
                 resources = getOrCreateResourcesForActivityLocked(activityToken, classLoader,
-                        resourcesImpl);
+                        resourcesImpl, key.mCompatInfo);
             } else {
-                resources = getOrCreateResourcesLocked(classLoader, resourcesImpl);
+                resources = getOrCreateResourcesLocked(classLoader, resourcesImpl, key.mCompatInfo);
             }
             return resources;
         }
index 15575fd..829b6b7 100644 (file)
@@ -27,11 +27,17 @@ import java.lang.ref.WeakReference;
  */
 public class CompatResources extends Resources {
 
-    private final WeakReference<Context> mContext;
+    private WeakReference<Context> mContext;
 
-    public CompatResources(Resources base, Context context) {
-        super(base.getClassLoader());
-        setImpl(base.getImpl());
+    public CompatResources(ClassLoader cls) {
+        super(cls);
+        mContext = new WeakReference<>(null);
+    }
+
+    /**
+     * @hide
+     */
+    public void setContext(Context context) {
         mContext = new WeakReference<>(context);
     }
 
index da35ee9..781e235 100644 (file)
@@ -21,6 +21,8 @@ import android.graphics.Canvas;
 import android.graphics.PointF;
 import android.graphics.Rect;
 import android.graphics.Region;
+import android.os.Build;
+import android.os.Build.VERSION_CODES;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.util.DisplayMetrics;
@@ -78,6 +80,11 @@ public class CompatibilityInfo implements Parcelable {
     private static final int NEEDS_SCREEN_COMPAT = 8;
 
     /**
+     * Set if the application needs to run in with compat resources.
+     */
+    private static final int NEEDS_COMPAT_RES = 16;
+
+    /**
      * The effective screen density we have selected for this application.
      */
     public final int applicationDensity;
@@ -96,6 +103,9 @@ public class CompatibilityInfo implements Parcelable {
             boolean forceCompat) {
         int compatFlags = 0;
 
+        if (appInfo.targetSdkVersion < VERSION_CODES.O) {
+            compatFlags |= NEEDS_COMPAT_RES;
+        }
         if (appInfo.requiresSmallestWidthDp != 0 || appInfo.compatibleWidthLimitDp != 0
                 || appInfo.largestWidthLimitDp != 0) {
             // New style screen requirements spec.
@@ -274,6 +284,10 @@ public class CompatibilityInfo implements Parcelable {
         return (mCompatibilityFlags&NEVER_NEEDS_COMPAT) != 0;
     }
 
+    public boolean needsCompatResources() {
+        return (mCompatibilityFlags&NEEDS_COMPAT_RES) != 0;
+    }
+
     /**
      * Returns the translator which translates the coordinates in compatibility mode.
      * @param params the window's parameter