Let ResourcesManager generate CompatResources

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
This commit is contained in:
Jason Monk
2017-03-02 12:55:00 -05:00
parent 00a5f2a658
commit bd60e5bf2e
4 changed files with 39 additions and 16 deletions

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

View 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;
}

View 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);
}

View 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;
@@ -77,6 +79,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.
*/
@@ -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