Merge "Track generations in resource caches" into udc-dev

This commit is contained in:
Jeremy Meyer
2023-06-01 20:23:40 +00:00
committed by Android (Google) Code Review
6 changed files with 144 additions and 71 deletions

View File

@@ -111,19 +111,20 @@ public class AnimatorInflater {
float pathErrorScale) throws NotFoundException { float pathErrorScale) throws NotFoundException {
final ConfigurationBoundResourceCache<Animator> animatorCache = resources final ConfigurationBoundResourceCache<Animator> animatorCache = resources
.getAnimatorCache(); .getAnimatorCache();
Animator animator = animatorCache.getInstance(id, resources, theme); ConfigurationBoundResourceCache.Entry<Animator> animatorEntry =
if (animator != null) { animatorCache.getInstance(id, resources, theme);
if (animatorEntry.hasValue()) {
if (DBG_ANIMATOR_INFLATER) { if (DBG_ANIMATOR_INFLATER) {
Log.d(TAG, "loaded animator from cache, " + resources.getResourceName(id)); Log.d(TAG, "loaded animator from cache, " + resources.getResourceName(id));
} }
return animator; return animatorEntry.getValue();
} else if (DBG_ANIMATOR_INFLATER) { } else if (DBG_ANIMATOR_INFLATER) {
Log.d(TAG, "cache miss for animator " + resources.getResourceName(id)); Log.d(TAG, "cache miss for animator " + resources.getResourceName(id));
} }
XmlResourceParser parser = null; XmlResourceParser parser = null;
try { try {
parser = resources.getAnimation(id); parser = resources.getAnimation(id);
animator = createAnimatorFromXml(resources, theme, parser, pathErrorScale); Animator animator = createAnimatorFromXml(resources, theme, parser, pathErrorScale);
if (animator != null) { if (animator != null) {
animator.appendChangingConfigurations(getChangingConfigs(resources, id)); animator.appendChangingConfigurations(getChangingConfigs(resources, id));
final ConstantState<Animator> constantState = animator.createConstantState(); final ConstantState<Animator> constantState = animator.createConstantState();
@@ -131,7 +132,7 @@ public class AnimatorInflater {
if (DBG_ANIMATOR_INFLATER) { if (DBG_ANIMATOR_INFLATER) {
Log.d(TAG, "caching animator for res " + resources.getResourceName(id)); Log.d(TAG, "caching animator for res " + resources.getResourceName(id));
} }
animatorCache.put(id, theme, constantState); animatorCache.put(id, theme, constantState, animatorEntry.getGeneration());
// create a new animator so that cached version is never used by the user // create a new animator so that cached version is never used by the user
animator = constantState.newInstance(resources, theme); animator = constantState.newInstance(resources, theme);
} }
@@ -160,20 +161,22 @@ public class AnimatorInflater {
final ConfigurationBoundResourceCache<StateListAnimator> cache = resources final ConfigurationBoundResourceCache<StateListAnimator> cache = resources
.getStateListAnimatorCache(); .getStateListAnimatorCache();
final Theme theme = context.getTheme(); final Theme theme = context.getTheme();
StateListAnimator animator = cache.getInstance(id, resources, theme); ConfigurationBoundResourceCache.Entry<StateListAnimator> animatorEntry =
if (animator != null) { cache.getInstance(id, resources, theme);
return animator; if (animatorEntry.hasValue()) {
return animatorEntry.getValue();
} }
XmlResourceParser parser = null; XmlResourceParser parser = null;
try { try {
parser = resources.getAnimation(id); parser = resources.getAnimation(id);
animator = createStateListAnimatorFromXml(context, parser, Xml.asAttributeSet(parser)); StateListAnimator animator =
createStateListAnimatorFromXml(context, parser, Xml.asAttributeSet(parser));
if (animator != null) { if (animator != null) {
animator.appendChangingConfigurations(getChangingConfigs(resources, id)); animator.appendChangingConfigurations(getChangingConfigs(resources, id));
final ConstantState<StateListAnimator> constantState = animator final ConstantState<StateListAnimator> constantState = animator
.createConstantState(); .createConstantState();
if (constantState != null) { if (constantState != null) {
cache.put(id, theme, constantState); cache.put(id, theme, constantState, animatorEntry.getGeneration());
// return a clone so that the animator in constant state is never used. // return a clone so that the animator in constant state is never used.
animator = constantState.newInstance(resources, theme); animator = constantState.newInstance(resources, theme);
} }

View File

@@ -37,16 +37,16 @@ public class ConfigurationBoundResourceCache<T> extends ThemedResourceCache<Cons
* @param key a key that uniquely identifies the drawable resource * @param key a key that uniquely identifies the drawable resource
* @param resources a Resources object from which to create new instances. * @param resources a Resources object from which to create new instances.
* @param theme the theme where the resource will be used * @param theme the theme where the resource will be used
* @return a new instance of the resource, or {@code null} if not in * @return an Entry wrapping a new instance of the resource, or {@code null} if not in
* the cache * the cache
*/ */
public T getInstance(long key, Resources resources, Resources.Theme theme) { public Entry<T> getInstance(long key, Resources resources, Resources.Theme theme) {
final ConstantState<T> entry = get(key, theme); final Entry<ConstantState<T>> e = get(key, theme);
if (entry != null) { if (e.hasValue()) {
return entry.newInstance(resources, theme); return new Entry<>(e.getValue().newInstance(resources, theme), e.getGeneration());
} }
return null; return new Entry<>(null, e.getGeneration());
} }
@Override @Override

View File

@@ -40,14 +40,32 @@ class DrawableCache extends ThemedResourceCache<Drawable.ConstantState> {
*/ */
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
public Drawable getInstance(long key, Resources resources, Resources.Theme theme) { public Drawable getInstance(long key, Resources resources, Resources.Theme theme) {
final Drawable.ConstantState entry = get(key, theme); final Entry<Drawable.ConstantState> entry = get(key, theme);
if (entry != null) { if (entry.getValue() != null) {
return entry.newDrawable(resources, theme); return entry.getValue().newDrawable(resources, theme);
} }
return null; return null;
} }
/**
* If the resource is cached, creates and returns a new instance of it.
*
* @param key a key that uniquely identifies the drawable resource
* @param resources a Resources object from which to create new instances.
* @param theme the theme where the resource will be used
* @return an Entry wrapping a a new instance of the resource, or {@code null} if not in
* the cache
*/
public Entry<Drawable> getDrawable(long key, Resources resources, Resources.Theme theme) {
final Entry<Drawable.ConstantState> e = get(key, theme);
if (e.hasValue()) {
return new Entry<>(e.getValue().newDrawable(resources, theme), e.getGeneration());
}
return new Entry<>(null, e.getGeneration());
}
@Override @Override
public boolean shouldInvalidateEntry(Drawable.ConstantState entry, int configChanges) { public boolean shouldInvalidateEntry(Drawable.ConstantState entry, int configChanges) {
return Configuration.needNewResources(configChanges, entry.getChangingConfigurations()); return Configuration.needNewResources(configChanges, entry.getChangingConfigurations());

View File

@@ -650,15 +650,21 @@ public class ResourcesImpl {
key = (((long) value.assetCookie) << 32) | value.data; key = (((long) value.assetCookie) << 32) | value.data;
} }
int cacheGeneration;
// First, check whether we have a cached version of this drawable // First, check whether we have a cached version of this drawable
// that was inflated against the specified theme. Skip the cache if // that was inflated against the specified theme. Skip the cache if
// we're currently preloading or we're not using the cache. // we're currently preloading or we're not using the cache.
if (!mPreloading && useCache) { if (!mPreloading && useCache) {
final Drawable cachedDrawable = caches.getInstance(key, wrapper, theme); final ThemedResourceCache.Entry<Drawable> cachedDrawable =
if (cachedDrawable != null) { caches.getDrawable(key, wrapper, theme);
cachedDrawable.setChangingConfigurations(value.changingConfigurations); if (cachedDrawable.hasValue()) {
return cachedDrawable; cachedDrawable.getValue().setChangingConfigurations(
value.changingConfigurations);
return cachedDrawable.getValue();
} }
cacheGeneration = cachedDrawable.getGeneration();
} else {
cacheGeneration = ThemedResourceCache.UNDEFINED_GENERATION;
} }
// Next, check preloaded drawables. Preloaded drawables may contain // Next, check preloaded drawables. Preloaded drawables may contain
@@ -702,7 +708,8 @@ public class ResourcesImpl {
if (dr != null) { if (dr != null) {
dr.setChangingConfigurations(value.changingConfigurations); dr.setChangingConfigurations(value.changingConfigurations);
if (useCache) { if (useCache) {
cacheDrawable(value, isColorDrawable, caches, theme, canApplyTheme, key, dr); cacheDrawable(value, isColorDrawable, caches, theme, canApplyTheme, key, dr,
cacheGeneration);
if (needsNewDrawableAfterCache) { if (needsNewDrawableAfterCache) {
Drawable.ConstantState state = dr.getConstantState(); Drawable.ConstantState state = dr.getConstantState();
if (state != null) { if (state != null) {
@@ -733,7 +740,7 @@ public class ResourcesImpl {
} }
private void cacheDrawable(TypedValue value, boolean isColorDrawable, DrawableCache caches, private void cacheDrawable(TypedValue value, boolean isColorDrawable, DrawableCache caches,
Resources.Theme theme, boolean usesTheme, long key, Drawable dr) { Resources.Theme theme, boolean usesTheme, long key, Drawable dr, int cacheGeneration) {
final Drawable.ConstantState cs = dr.getConstantState(); final Drawable.ConstantState cs = dr.getConstantState();
if (cs == null) { if (cs == null) {
return; return;
@@ -761,7 +768,7 @@ public class ResourcesImpl {
} }
} else { } else {
synchronized (mAccessLock) { synchronized (mAccessLock) {
caches.put(key, theme, cs, usesTheme); caches.put(key, theme, cs, cacheGeneration, usesTheme);
} }
} }
} }
@@ -1002,14 +1009,16 @@ public class ResourcesImpl {
TypedValue value, int id) { TypedValue value, int id) {
final long key = (((long) value.assetCookie) << 32) | value.data; final long key = (((long) value.assetCookie) << 32) | value.data;
final ConfigurationBoundResourceCache<ComplexColor> cache = mComplexColorCache; final ConfigurationBoundResourceCache<ComplexColor> cache = mComplexColorCache;
ComplexColor complexColor = cache.getInstance(key, wrapper, theme); ThemedResourceCache.Entry<ComplexColor> complexColorEntry =
if (complexColor != null) { cache.getInstance(key, wrapper, theme);
return complexColor; if (complexColorEntry.hasValue()) {
return complexColorEntry.getValue();
} }
final android.content.res.ConstantState<ComplexColor> factory = final android.content.res.ConstantState<ComplexColor> factory =
sPreloadedComplexColors.get(key); sPreloadedComplexColors.get(key);
ComplexColor complexColor = null;
if (factory != null) { if (factory != null) {
complexColor = factory.newInstance(wrapper, theme); complexColor = factory.newInstance(wrapper, theme);
} }
@@ -1026,7 +1035,8 @@ public class ResourcesImpl {
sPreloadedComplexColors.put(key, complexColor.getConstantState()); sPreloadedComplexColors.put(key, complexColor.getConstantState());
} }
} else { } else {
cache.put(key, theme, complexColor.getConstantState()); cache.put(key, theme, complexColor.getConstantState(),
complexColorEntry.getGeneration());
} }
} }
return complexColor; return complexColor;

View File

@@ -33,11 +33,37 @@ import java.lang.ref.WeakReference;
* @param <T> type of data to cache * @param <T> type of data to cache
*/ */
abstract class ThemedResourceCache<T> { abstract class ThemedResourceCache<T> {
public static final int UNDEFINED_GENERATION = -1;
@UnsupportedAppUsage @UnsupportedAppUsage
private ArrayMap<ThemeKey, LongSparseArray<WeakReference<T>>> mThemedEntries; private ArrayMap<ThemeKey, LongSparseArray<WeakReference<T>>> mThemedEntries;
private LongSparseArray<WeakReference<T>> mUnthemedEntries; private LongSparseArray<WeakReference<T>> mUnthemedEntries;
private LongSparseArray<WeakReference<T>> mNullThemedEntries; private LongSparseArray<WeakReference<T>> mNullThemedEntries;
private int mGeneration;
public static class Entry<S> {
private S mValue;
private int mGeneration;
public S getValue() {
return mValue;
}
public boolean hasValue() {
return mValue != null;
}
public int getGeneration() {
return mGeneration;
}
Entry(S value, int generation) {
this.mValue = value;
this.mGeneration = generation;
}
}
/** /**
* Adds a new theme-dependent entry to the cache. * Adds a new theme-dependent entry to the cache.
* *
@@ -45,9 +71,10 @@ abstract class ThemedResourceCache<T> {
* @param theme the theme against which this entry was inflated, or * @param theme the theme against which this entry was inflated, or
* {@code null} if the entry has no theme applied * {@code null} if the entry has no theme applied
* @param entry the entry to cache * @param entry the entry to cache
* @param generation The generation of the cache to compare against before storing
*/ */
public void put(long key, @Nullable Theme theme, @NonNull T entry) { public void put(long key, @Nullable Theme theme, @NonNull T entry, int generation) {
put(key, theme, entry, true); put(key, theme, entry, generation, true);
} }
/** /**
@@ -57,10 +84,12 @@ abstract class ThemedResourceCache<T> {
* @param theme the theme against which this entry was inflated, or * @param theme the theme against which this entry was inflated, or
* {@code null} if the entry has no theme applied * {@code null} if the entry has no theme applied
* @param entry the entry to cache * @param entry the entry to cache
* @param generation The generation of the cache to compare against before storing
* @param usesTheme {@code true} if the entry is affected theme changes, * @param usesTheme {@code true} if the entry is affected theme changes,
* {@code false} otherwise * {@code false} otherwise
*/ */
public void put(long key, @Nullable Theme theme, @NonNull T entry, boolean usesTheme) { public void put(long key, @Nullable Theme theme, @NonNull T entry, int generation,
boolean usesTheme) {
if (entry == null) { if (entry == null) {
return; return;
} }
@@ -72,7 +101,8 @@ abstract class ThemedResourceCache<T> {
} else { } else {
entries = getThemedLocked(theme, true); entries = getThemedLocked(theme, true);
} }
if (entries != null) { if (entries != null
&& ((generation == mGeneration) || (generation == UNDEFINED_GENERATION))) {
entries.put(key, new WeakReference<>(entry)); entries.put(key, new WeakReference<>(entry));
} }
} }
@@ -86,7 +116,7 @@ abstract class ThemedResourceCache<T> {
* @return a cached entry, or {@code null} if not in the cache * @return a cached entry, or {@code null} if not in the cache
*/ */
@Nullable @Nullable
public T get(long key, @Nullable Theme theme) { public Entry get(long key, @Nullable Theme theme) {
// The themed (includes null-themed) and unthemed caches are mutually // The themed (includes null-themed) and unthemed caches are mutually
// exclusive, so we'll give priority to whichever one we think we'll // exclusive, so we'll give priority to whichever one we think we'll
// hit first. Since most of the framework drawables are themed, that's // hit first. Since most of the framework drawables are themed, that's
@@ -96,7 +126,7 @@ abstract class ThemedResourceCache<T> {
if (themedEntries != null) { if (themedEntries != null) {
final WeakReference<T> themedEntry = themedEntries.get(key); final WeakReference<T> themedEntry = themedEntries.get(key);
if (themedEntry != null) { if (themedEntry != null) {
return themedEntry.get(); return new Entry(themedEntry.get(), mGeneration);
} }
} }
@@ -104,12 +134,12 @@ abstract class ThemedResourceCache<T> {
if (unthemedEntries != null) { if (unthemedEntries != null) {
final WeakReference<T> unthemedEntry = unthemedEntries.get(key); final WeakReference<T> unthemedEntry = unthemedEntries.get(key);
if (unthemedEntry != null) { if (unthemedEntry != null) {
return unthemedEntry.get(); return new Entry(unthemedEntry.get(), mGeneration);
} }
} }
} }
return null; return new Entry(null, mGeneration);
} }
/** /**
@@ -121,6 +151,7 @@ abstract class ThemedResourceCache<T> {
@UnsupportedAppUsage @UnsupportedAppUsage
public void onConfigurationChange(@Config int configChanges) { public void onConfigurationChange(@Config int configChanges) {
prune(configChanges); prune(configChanges);
mGeneration++;
} }
/** /**

View File

@@ -45,36 +45,40 @@ public class ConfigurationBoundResourceCacheTest
@SmallTest @SmallTest
public void testGetEmpty() { public void testGetEmpty() {
final Resources res = getActivity().getResources(); final Resources res = getActivity().getResources();
assertNull(mCache.getInstance(-1, res, null)); assertNull(mCache.getInstance(-1, res, null).getValue());
} }
@SmallTest @SmallTest
public void testSetGet() { public void testSetGet() {
mCache.put(1, null, new DummyFloatConstantState(5f)); mCache.put(1, null, new DummyFloatConstantState(5f),
ThemedResourceCache.UNDEFINED_GENERATION);
final Resources res = getActivity().getResources(); final Resources res = getActivity().getResources();
assertEquals(5f, mCache.getInstance(1, res, null)); assertEquals(5f, mCache.getInstance(1, res, null).getValue());
assertNotSame(5f, mCache.getInstance(1, res, null)); assertNotSame(5f, mCache.getInstance(1, res, null).getValue());
assertEquals(null, mCache.getInstance(1, res, getActivity().getTheme())); assertEquals(false, mCache.getInstance(1, res, getActivity().getTheme()).hasValue());
} }
@SmallTest @SmallTest
public void testSetGetThemed() { public void testSetGetThemed() {
mCache.put(1, getActivity().getTheme(), new DummyFloatConstantState(5f)); mCache.put(1, getActivity().getTheme(), new DummyFloatConstantState(5f),
ThemedResourceCache.UNDEFINED_GENERATION);
final Resources res = getActivity().getResources(); final Resources res = getActivity().getResources();
assertEquals(null, mCache.getInstance(1, res, null)); assertEquals(false, mCache.getInstance(1, res, null).hasValue());
assertEquals(5f, mCache.getInstance(1, res, getActivity().getTheme())); assertEquals(5f, mCache.getInstance(1, res, getActivity().getTheme()).getValue());
assertNotSame(5f, mCache.getInstance(1, res, getActivity().getTheme())); assertNotSame(5f, mCache.getInstance(1, res, getActivity().getTheme()).getValue());
} }
@SmallTest @SmallTest
public void testMultiThreadPutGet() { public void testMultiThreadPutGet() {
mCache.put(1, getActivity().getTheme(), new DummyFloatConstantState(5f)); mCache.put(1, getActivity().getTheme(), new DummyFloatConstantState(5f),
mCache.put(1, null, new DummyFloatConstantState(10f)); ThemedResourceCache.UNDEFINED_GENERATION);
mCache.put(1, null, new DummyFloatConstantState(10f),
ThemedResourceCache.UNDEFINED_GENERATION);
final Resources res = getActivity().getResources(); final Resources res = getActivity().getResources();
assertEquals(10f, mCache.getInstance(1, res, null)); assertEquals(10f, mCache.getInstance(1, res, null).getValue());
assertNotSame(10f, mCache.getInstance(1, res, null)); assertNotSame(10f, mCache.getInstance(1, res, null).getValue());
assertEquals(5f, mCache.getInstance(1, res, getActivity().getTheme())); assertEquals(5f, mCache.getInstance(1, res, getActivity().getTheme()).getValue());
assertNotSame(5f, mCache.getInstance(1, res, getActivity().getTheme())); assertNotSame(5f, mCache.getInstance(1, res, getActivity().getTheme()).getValue());
} }
@SmallTest @SmallTest
@@ -86,16 +90,17 @@ public class ConfigurationBoundResourceCacheTest
res.getValue(R.dimen.resource_cache_test_generic, staticValue, true); res.getValue(R.dimen.resource_cache_test_generic, staticValue, true);
float staticDim = TypedValue.complexToDimension(staticValue.data, res.getDisplayMetrics()); float staticDim = TypedValue.complexToDimension(staticValue.data, res.getDisplayMetrics());
mCache.put(key, getActivity().getTheme(), mCache.put(key, getActivity().getTheme(),
new DummyFloatConstantState(staticDim, staticValue.changingConfigurations)); new DummyFloatConstantState(staticDim, staticValue.changingConfigurations),
ThemedResourceCache.UNDEFINED_GENERATION);
final Configuration cfg = res.getConfiguration(); final Configuration cfg = res.getConfiguration();
Configuration newCnf = new Configuration(cfg); Configuration newCnf = new Configuration(cfg);
newCnf.orientation = cfg.orientation == Configuration.ORIENTATION_LANDSCAPE ? newCnf.orientation = cfg.orientation == Configuration.ORIENTATION_LANDSCAPE ?
Configuration.ORIENTATION_PORTRAIT Configuration.ORIENTATION_PORTRAIT
: Configuration.ORIENTATION_LANDSCAPE; : Configuration.ORIENTATION_LANDSCAPE;
int changes = calcConfigChanges(res, newCnf); int changes = calcConfigChanges(res, newCnf);
assertEquals(staticDim, mCache.getInstance(key, res, getActivity().getTheme())); assertEquals(staticDim, mCache.getInstance(key, res, getActivity().getTheme()).getValue());
mCache.onConfigurationChange(changes); mCache.onConfigurationChange(changes);
assertEquals(staticDim, mCache.getInstance(key, res, getActivity().getTheme())); assertEquals(staticDim, mCache.getInstance(key, res, getActivity().getTheme()).getValue());
} }
@SmallTest @SmallTest
@@ -108,7 +113,8 @@ public class ConfigurationBoundResourceCacheTest
float changingDim = TypedValue.complexToDimension(changingValue.data, float changingDim = TypedValue.complexToDimension(changingValue.data,
res.getDisplayMetrics()); res.getDisplayMetrics());
mCache.put(key, getActivity().getTheme(), mCache.put(key, getActivity().getTheme(),
new DummyFloatConstantState(changingDim, changingValue.changingConfigurations)); new DummyFloatConstantState(changingDim, changingValue.changingConfigurations),
ThemedResourceCache.UNDEFINED_GENERATION);
final Configuration cfg = res.getConfiguration(); final Configuration cfg = res.getConfiguration();
Configuration newCnf = new Configuration(cfg); Configuration newCnf = new Configuration(cfg);
@@ -116,9 +122,10 @@ public class ConfigurationBoundResourceCacheTest
Configuration.ORIENTATION_PORTRAIT Configuration.ORIENTATION_PORTRAIT
: Configuration.ORIENTATION_LANDSCAPE; : Configuration.ORIENTATION_LANDSCAPE;
int changes = calcConfigChanges(res, newCnf); int changes = calcConfigChanges(res, newCnf);
assertEquals(changingDim, mCache.getInstance(key, res, getActivity().getTheme())); assertEquals(changingDim,
mCache.getInstance(key, res, getActivity().getTheme()).getValue());
mCache.onConfigurationChange(changes); mCache.onConfigurationChange(changes);
assertNull(mCache.get(key, getActivity().getTheme())); assertNull(mCache.get(key, getActivity().getTheme()).getValue());
} }
@SmallTest @SmallTest
@@ -133,9 +140,11 @@ public class ConfigurationBoundResourceCacheTest
float changingDim = TypedValue.complexToDimension(changingValue.data, float changingDim = TypedValue.complexToDimension(changingValue.data,
res.getDisplayMetrics()); res.getDisplayMetrics());
mCache.put(R.dimen.resource_cache_test_generic, getActivity().getTheme(), mCache.put(R.dimen.resource_cache_test_generic, getActivity().getTheme(),
new DummyFloatConstantState(staticDim, staticValue.changingConfigurations)); new DummyFloatConstantState(staticDim, staticValue.changingConfigurations),
ThemedResourceCache.UNDEFINED_GENERATION);
mCache.put(R.dimen.resource_cache_test_orientation_dependent, getActivity().getTheme(), mCache.put(R.dimen.resource_cache_test_orientation_dependent, getActivity().getTheme(),
new DummyFloatConstantState(changingDim, changingValue.changingConfigurations)); new DummyFloatConstantState(changingDim, changingValue.changingConfigurations),
ThemedResourceCache.UNDEFINED_GENERATION);
final Configuration cfg = res.getConfiguration(); final Configuration cfg = res.getConfiguration();
Configuration newCnf = new Configuration(cfg); Configuration newCnf = new Configuration(cfg);
newCnf.orientation = cfg.orientation == Configuration.ORIENTATION_LANDSCAPE ? newCnf.orientation = cfg.orientation == Configuration.ORIENTATION_LANDSCAPE ?
@@ -143,15 +152,15 @@ public class ConfigurationBoundResourceCacheTest
: Configuration.ORIENTATION_LANDSCAPE; : Configuration.ORIENTATION_LANDSCAPE;
int changes = calcConfigChanges(res, newCnf); int changes = calcConfigChanges(res, newCnf);
assertEquals(staticDim, mCache.getInstance(R.dimen.resource_cache_test_generic, res, assertEquals(staticDim, mCache.getInstance(R.dimen.resource_cache_test_generic, res,
getActivity().getTheme())); getActivity().getTheme()).getValue());
assertEquals(changingDim, assertEquals(changingDim,
mCache.getInstance(R.dimen.resource_cache_test_orientation_dependent, res, mCache.getInstance(R.dimen.resource_cache_test_orientation_dependent, res,
getActivity().getTheme())); getActivity().getTheme()).getValue());
mCache.onConfigurationChange(changes); mCache.onConfigurationChange(changes);
assertEquals(staticDim, mCache.getInstance(R.dimen.resource_cache_test_generic, res, assertEquals(staticDim, mCache.getInstance(R.dimen.resource_cache_test_generic, res,
getActivity().getTheme())); getActivity().getTheme()).getValue());
assertNull(mCache.getInstance(R.dimen.resource_cache_test_orientation_dependent, res, assertNull(mCache.getInstance(R.dimen.resource_cache_test_orientation_dependent, res,
getActivity().getTheme())); getActivity().getTheme()).getValue());
} }
@SmallTest @SmallTest
@@ -173,10 +182,12 @@ public class ConfigurationBoundResourceCacheTest
res.getDisplayMetrics()); res.getDisplayMetrics());
final Resources.Theme theme = i == 0 ? getActivity().getTheme() : null; final Resources.Theme theme = i == 0 ? getActivity().getTheme() : null;
mCache.put(R.dimen.resource_cache_test_generic, theme, mCache.put(R.dimen.resource_cache_test_generic, theme,
new DummyFloatConstantState(staticDim, staticValues[i].changingConfigurations)); new DummyFloatConstantState(staticDim, staticValues[i].changingConfigurations),
ThemedResourceCache.UNDEFINED_GENERATION);
mCache.put(R.dimen.resource_cache_test_orientation_dependent, theme, mCache.put(R.dimen.resource_cache_test_orientation_dependent, theme,
new DummyFloatConstantState(changingDim, new DummyFloatConstantState(changingDim,
changingValues[i].changingConfigurations)); changingValues[i].changingConfigurations),
ThemedResourceCache.UNDEFINED_GENERATION);
} }
final Configuration cfg = res.getConfiguration(); final Configuration cfg = res.getConfiguration();
Configuration newCnf = new Configuration(cfg); Configuration newCnf = new Configuration(cfg);
@@ -187,18 +198,18 @@ public class ConfigurationBoundResourceCacheTest
for (int i = 0; i < 2; i++) { for (int i = 0; i < 2; i++) {
final Resources.Theme theme = i == 0 ? getActivity().getTheme() : null; final Resources.Theme theme = i == 0 ? getActivity().getTheme() : null;
assertEquals(staticDim, assertEquals(staticDim,
mCache.getInstance(R.dimen.resource_cache_test_generic, res, theme)); mCache.getInstance(R.dimen.resource_cache_test_generic, res, theme).getValue());
assertEquals(changingDim, assertEquals(changingDim,
mCache.getInstance(R.dimen.resource_cache_test_orientation_dependent, res, mCache.getInstance(R.dimen.resource_cache_test_orientation_dependent, res,
theme)); theme).getValue());
} }
mCache.onConfigurationChange(changes); mCache.onConfigurationChange(changes);
for (int i = 0; i < 2; i++) { for (int i = 0; i < 2; i++) {
final Resources.Theme theme = i == 0 ? getActivity().getTheme() : null; final Resources.Theme theme = i == 0 ? getActivity().getTheme() : null;
assertEquals(staticDim, assertEquals(staticDim,
mCache.getInstance(R.dimen.resource_cache_test_generic, res, theme)); mCache.getInstance(R.dimen.resource_cache_test_generic, res, theme).getValue());
assertNull(mCache.getInstance(R.dimen.resource_cache_test_orientation_dependent, res, assertNull(mCache.getInstance(R.dimen.resource_cache_test_orientation_dependent, res,
theme)); theme).getValue());
} }
} }