Merge "Handle hybrid themes correctly in Drawable cache" into lmp-preview-dev
diff --git a/core/java/android/content/res/Resources.java b/core/java/android/content/res/Resources.java
index a78f8e2..3737638 100644
--- a/core/java/android/content/res/Resources.java
+++ b/core/java/android/content/res/Resources.java
@@ -31,11 +31,11 @@
import android.os.Bundle;
import android.os.IBinder;
import android.os.Trace;
+import android.util.ArrayMap;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.Log;
import android.util.Slog;
-import android.util.SparseArray;
import android.util.TypedValue;
import android.util.LongSparseArray;
@@ -104,10 +104,10 @@
// These are protected by mAccessLock.
private final Object mAccessLock = new Object();
private final Configuration mTmpConfig = new Configuration();
- private final ThemedCaches<ConstantState> mDrawableCache =
- new ThemedCaches<ConstantState>();
- private final ThemedCaches<ConstantState> mColorDrawableCache =
- new ThemedCaches<ConstantState>();
+ private final ArrayMap<String, LongSparseArray<WeakReference<ConstantState>>> mDrawableCache =
+ new ArrayMap<String, LongSparseArray<WeakReference<ConstantState>>>();
+ private final ArrayMap<String, LongSparseArray<WeakReference<ConstantState>>> mColorDrawableCache =
+ new ArrayMap<String, LongSparseArray<WeakReference<ConstantState>>>();
private final LongSparseArray<WeakReference<ColorStateList>> mColorStateListCache =
new LongSparseArray<WeakReference<ColorStateList>>();
@@ -1261,18 +1261,17 @@
* any of the style's attributes are already defined in the theme, the
* current values in the theme will be overwritten.
*
- * @param resid The resource ID of a style resource from which to
+ * @param resId The resource ID of a style resource from which to
* obtain attribute values.
* @param force If true, values in the style resource will always be
* used in the theme; otherwise, they will only be used
* if not already defined in the theme.
*/
- public void applyStyle(int resid, boolean force) {
- AssetManager.applyThemeStyle(mTheme, resid, force);
+ public void applyStyle(int resId, boolean force) {
+ AssetManager.applyThemeStyle(mTheme, resId, force);
- // TODO: In very rare cases, we may end up with a hybrid theme
- // that can't map to a single theme ID.
- mThemeResId = resid;
+ mThemeResId = resId;
+ mKey += Integer.toHexString(resId) + (force ? "! " : " ");
}
/**
@@ -1288,6 +1287,7 @@
AssetManager.copyTheme(mTheme, other.mTheme);
mThemeResId = other.mThemeResId;
+ mKey = other.mKey;
}
/**
@@ -1577,6 +1577,9 @@
/** Resource identifier for the theme. */
private int mThemeResId = 0;
+ /** Unique key for the series of styles applied to this theme. */
+ private String mKey = "";
+
// Needed by layoutlib.
/*package*/ long getNativeTheme() {
return mTheme;
@@ -1585,6 +1588,10 @@
/*package*/ int getAppliedStyleResId() {
return mThemeResId;
}
+
+ /*package*/ String getKey() {
+ return mKey;
+ }
}
/**
@@ -1740,7 +1747,8 @@
}
private void clearDrawableCachesLocked(
- ThemedCaches<ConstantState> caches, int configChanges) {
+ ArrayMap<String, LongSparseArray<WeakReference<ConstantState>>> caches,
+ int configChanges) {
final int N = caches.size();
for (int i = 0; i < N; i++) {
clearDrawableCacheLocked(caches.valueAt(i), configChanges);
@@ -1763,7 +1771,7 @@
configChanges, cs.getChangingConfigurations())) {
if (DEBUG_CONFIG) {
Log.d(TAG, "FLUSHING #0x"
- + Long.toHexString(mDrawableCache.keyAt(i))
+ + Long.toHexString(cache.keyAt(i))
+ " / " + cs + " with changes: 0x"
+ Integer.toHexString(cs.getChangingConfigurations()));
}
@@ -2205,7 +2213,7 @@
}
final boolean isColorDrawable;
- final ThemedCaches<ConstantState> caches;
+ final ArrayMap<String, LongSparseArray<WeakReference<ConstantState>>> caches;
final long key;
if (value.type >= TypedValue.TYPE_FIRST_COLOR_INT
&& value.type <= TypedValue.TYPE_LAST_COLOR_INT) {
@@ -2258,7 +2266,8 @@
}
private void cacheDrawable(TypedValue value, Theme theme, boolean isColorDrawable,
- ThemedCaches<ConstantState> caches, long key, Drawable dr) {
+ ArrayMap<String, LongSparseArray<WeakReference<ConstantState>>> caches,
+ long key, Drawable dr) {
final ConstantState cs = dr.getConstantState();
if (cs == null) {
return;
@@ -2287,8 +2296,12 @@
}
} else {
synchronized (mAccessLock) {
- final LongSparseArray<WeakReference<ConstantState>> themedCache;
- themedCache = caches.getOrCreate(theme == null ? 0 : theme.mThemeResId);
+ final String themeKey = theme == null ? "" : theme.mKey;
+ LongSparseArray<WeakReference<ConstantState>> themedCache = caches.get(themeKey);
+ if (themedCache == null) {
+ themedCache = new LongSparseArray<WeakReference<ConstantState>>(1);
+ caches.put(themeKey, themedCache);
+ }
themedCache.put(key, new WeakReference<ConstantState>(cs));
}
}
@@ -2347,7 +2360,9 @@
return dr;
}
- private Drawable getCachedDrawable(ThemedCaches<ConstantState> caches, long key, Theme theme) {
+ private Drawable getCachedDrawable(
+ ArrayMap<String, LongSparseArray<WeakReference<ConstantState>>> caches,
+ long key, Theme theme) {
synchronized (mAccessLock) {
final int themeKey = theme != null ? theme.mThemeResId : 0;
final LongSparseArray<WeakReference<ConstantState>> themedCache = caches.get(themeKey);
@@ -2584,21 +2599,4 @@
updateConfiguration(null, null);
mAssets.ensureStringBlocks();
}
-
- static class ThemedCaches<T> extends SparseArray<LongSparseArray<WeakReference<T>>> {
- /**
- * Returns the cache of drawables styled for the specified theme.
- * <p>
- * Drawables that have themeable attributes but were loaded without
- * specifying a theme are cached at themeResId = 0.
- */
- public LongSparseArray<WeakReference<T>> getOrCreate(int themeResId) {
- LongSparseArray<WeakReference<T>> result = get(themeResId);
- if (result == null) {
- result = new LongSparseArray<WeakReference<T>>(1);
- put(themeResId, result);
- }
- return result;
- }
- }
}