package androidx.appcompat.content.res; import android.annotation.SuppressLint; import android.content.Context; import android.content.res.ColorStateList; import android.content.res.Configuration; import android.content.res.Resources; import android.graphics.drawable.Drawable; import android.os.Build; import android.util.Log; import android.util.SparseArray; import android.util.TypedValue; import androidx.annotation.ColorRes; import androidx.annotation.DrawableRes; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.appcompat.widget.ResourceManagerInternal; import androidx.core.content.ContextCompat; import androidx.core.content.res.ColorStateListInflaterCompat; import java.util.WeakHashMap; @SuppressLint({"RestrictedAPI"}) public final class AppCompatResources { private static final String LOG_TAG = "AppCompatResources"; private static final ThreadLocal TL_TYPED_VALUE = new ThreadLocal<>(); private static final Object sColorStateCacheLock = new Object(); private static final WeakHashMap> sColorStateCaches = new WeakHashMap<>(0); public static class ColorStateListCacheEntry { public final Configuration configuration; public final ColorStateList value; public ColorStateListCacheEntry(@NonNull ColorStateList colorStateList, @NonNull Configuration configuration) { this.value = colorStateList; this.configuration = configuration; } } private AppCompatResources() { } private static void addColorStateListToCache(@NonNull Context context, @ColorRes int i, @NonNull ColorStateList colorStateList) { synchronized (sColorStateCacheLock) { WeakHashMap> weakHashMap = sColorStateCaches; SparseArray sparseArray = weakHashMap.get(context); if (sparseArray == null) { sparseArray = new SparseArray<>(); weakHashMap.put(context, sparseArray); } sparseArray.append(i, new ColorStateListCacheEntry(colorStateList, context.getResources().getConfiguration())); } } @Nullable private static ColorStateList getCachedColorStateList(@NonNull Context context, @ColorRes int i) { ColorStateListCacheEntry colorStateListCacheEntry; synchronized (sColorStateCacheLock) { SparseArray sparseArray = sColorStateCaches.get(context); if (!(sparseArray == null || sparseArray.size() <= 0 || (colorStateListCacheEntry = sparseArray.get(i)) == null)) { if (colorStateListCacheEntry.configuration.equals(context.getResources().getConfiguration())) { return colorStateListCacheEntry.value; } sparseArray.remove(i); } return null; } } public static ColorStateList getColorStateList(@NonNull Context context, @ColorRes int i) { if (Build.VERSION.SDK_INT >= 23) { return context.getColorStateList(i); } ColorStateList cachedColorStateList = getCachedColorStateList(context, i); if (cachedColorStateList != null) { return cachedColorStateList; } ColorStateList inflateColorStateList = inflateColorStateList(context, i); if (inflateColorStateList == null) { return ContextCompat.getColorStateList(context, i); } addColorStateListToCache(context, i, inflateColorStateList); return inflateColorStateList; } @Nullable public static Drawable getDrawable(@NonNull Context context, @DrawableRes int i) { return ResourceManagerInternal.get().getDrawable(context, i); } @NonNull private static TypedValue getTypedValue() { ThreadLocal threadLocal = TL_TYPED_VALUE; TypedValue typedValue = threadLocal.get(); if (typedValue != null) { return typedValue; } TypedValue typedValue2 = new TypedValue(); threadLocal.set(typedValue2); return typedValue2; } @Nullable private static ColorStateList inflateColorStateList(Context context, int i) { if (isColorInt(context, i)) { return null; } Resources resources = context.getResources(); try { return ColorStateListInflaterCompat.createFromXml(resources, resources.getXml(i), context.getTheme()); } catch (Exception e) { Log.e(LOG_TAG, "Failed to inflate ColorStateList, leaving it to the framework", e); return null; } } private static boolean isColorInt(@NonNull Context context, @ColorRes int i) { Resources resources = context.getResources(); TypedValue typedValue = getTypedValue(); resources.getValue(i, typedValue, true); int i2 = typedValue.type; return i2 >= 28 && i2 <= 31; } }