Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit bf4564f0 authored by The Android Open Source Project's avatar The Android Open Source Project Committed by Android Git Automerger
Browse files

am 5adfe6c5: merge from open-source master

Merge commit '5adfe6c5'

* commit '5adfe6c5':
  Fix the problem that color drawable cache key conflicts another drawable one.
parents a5086683 5adfe6c5
Loading
Loading
Loading
Loading
+69 −38
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@ import org.xmlpull.v1.XmlPullParserException;
import android.graphics.Movie;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable.ConstantState;
import android.os.Build;
import android.os.Bundle;
import android.os.SystemProperties;
@@ -69,6 +70,8 @@ public class Resources {
            = new LongSparseArray<Drawable.ConstantState>();
    private static final SparseArray<ColorStateList> mPreloadedColorStateLists
            = new SparseArray<ColorStateList>();
    private static final LongSparseArray<Drawable.ConstantState> sPreloadedColorDrawables
            = new LongSparseArray<Drawable.ConstantState>();
    private static boolean mPreloaded;

    /*package*/ final TypedValue mTmpValue = new TypedValue();
@@ -78,6 +81,8 @@ public class Resources {
            = new LongSparseArray<WeakReference<Drawable.ConstantState> >();
    private final SparseArray<WeakReference<ColorStateList> > mColorStateListCache
            = new SparseArray<WeakReference<ColorStateList> >();
    private final LongSparseArray<WeakReference<Drawable.ConstantState> > mColorDrawableCache
            = new LongSparseArray<WeakReference<Drawable.ConstantState> >();
    private boolean mPreloading;

    /*package*/ TypedArray mCachedStyledAttributes = null;
@@ -1339,13 +1344,32 @@ public class Resources {
                    (int)(mMetrics.density*160), mConfiguration.keyboard,
                    keyboardHidden, mConfiguration.navigation, width, height,
                    mConfiguration.screenLayout, mConfiguration.uiMode, sSdkVersion);
            int N = mDrawableCache.size();

            drawableCacheClear(mDrawableCache, configChanges);
            drawableCacheClear(mColorDrawableCache, configChanges);

            mColorStateListCache.clear();


            flushLayoutCache();
        }
        synchronized (mSync) {
            if (mPluralRule != null) {
                mPluralRule = NativePluralRules.forLocale(config.locale);
            }
        }
    }

    private void drawableCacheClear(
            LongSparseArray<WeakReference<ConstantState>> cache,
            int configChanges) {
        int N = cache.size();
        if (DEBUG_CONFIG) {
            Log.d(TAG, "Cleaning up drawables config changes: 0x"
                    + Integer.toHexString(configChanges));
        }
        for (int i=0; i<N; i++) {
                WeakReference<Drawable.ConstantState> ref = mDrawableCache.valueAt(i);
            WeakReference<Drawable.ConstantState> ref = cache.valueAt(i);
            if (ref != null) {
                Drawable.ConstantState cs = ref.get();
                if (cs != null) {
@@ -1357,10 +1381,10 @@ public class Resources {
                                    + " / " + cs + " with changes: 0x"
                                    + Integer.toHexString(cs.getChangingConfigurations()));
                        }
                            mDrawableCache.setValueAt(i, null);
                        cache.setValueAt(i, null);
                    } else if (DEBUG_CONFIG) {
                        Log.d(TAG, "(Keeping #0x"
                                    + Long.toHexString(mDrawableCache.keyAt(i))
                                + Long.toHexString(cache.keyAt(i))
                                + " / " + cs + " with changes: 0x"
                                + Integer.toHexString(cs.getChangingConfigurations())
                                + ")");
@@ -1368,15 +1392,7 @@ public class Resources {
                }
            }
        }
            mDrawableCache.clear();
            mColorStateListCache.clear();
            flushLayoutCache();
        }
        synchronized (mSync) {
            if (mPluralRule != null) {
                mPluralRule = NativePluralRules.forLocale(config.locale);
            }
        }
        cache.clear();
    }

    /**
@@ -1701,13 +1717,18 @@ public class Resources {
        }

        final long key = (((long) value.assetCookie) << 32) | value.data;
        Drawable dr = getCachedDrawable(key);
        boolean isColorDrawable = false;
        if (value.type >= TypedValue.TYPE_FIRST_COLOR_INT &&
                value.type <= TypedValue.TYPE_LAST_COLOR_INT) {
            isColorDrawable = true;
        }
        Drawable dr = getCachedDrawable(isColorDrawable ? mColorDrawableCache : mDrawableCache, key);

        if (dr != null) {
            return dr;
        }

        Drawable.ConstantState cs = sPreloadedDrawables.get(key);
        Drawable.ConstantState cs = isColorDrawable ? sPreloadedColorDrawables.get(key) : sPreloadedDrawables.get(key);
        if (cs != null) {
            dr = cs.newDrawable(this);
        } else {
@@ -1766,34 +1787,44 @@ public class Resources {
            cs = dr.getConstantState();
            if (cs != null) {
                if (mPreloading) {
                    if (isColorDrawable) {
                        sPreloadedColorDrawables.put(key, cs);
                    } else {
                        sPreloadedDrawables.put(key, cs);
                    }
                } else {
                    synchronized (mTmpValue) {
                        //Log.i(TAG, "Saving cached drawable @ #" +
                        //        Integer.toHexString(key.intValue())
                        //        + " in " + this + ": " + cs);
                        if (isColorDrawable) {
                            mColorDrawableCache.put(key, new WeakReference<Drawable.ConstantState>(cs));
                        } else {
                            mDrawableCache.put(key, new WeakReference<Drawable.ConstantState>(cs));
                        }
                    }
                }
            }
        }

        return dr;
    }

    private Drawable getCachedDrawable(long key) {
    private Drawable getCachedDrawable(
            LongSparseArray<WeakReference<ConstantState>> drawableCache,
            long key) {
        synchronized (mTmpValue) {
            WeakReference<Drawable.ConstantState> wr = mDrawableCache.get(key);
            WeakReference<Drawable.ConstantState> wr = drawableCache.get(key);
            if (wr != null) {   // we have the key
                Drawable.ConstantState entry = wr.get();
                if (entry != null) {
                    //Log.i(TAG, "Returning cached drawable @ #" +
                    //        Integer.toHexString(((Integer)key).intValue())
                    //        + " in " + this + ": " + entry);
                    return entry.newDrawable(this);
                    return entry.newDrawable();
                }
                else {  // our entry has been purged
                    mDrawableCache.delete(key);
                    drawableCache.delete(key);
                }
            }
        }