You've already forked android_translation_layer
mirror of
https://gitlab.com/android_translation_layer/android_translation_layer.git
synced 2025-10-27 11:48:10 -07:00
borrow relevant parts of AOSP commit dbee9bb342cdfaa5155b1918f90262c05e2464cb
Our SVG-based VectorDrawable implementation still relies on `getDefaultColor` but exceptions are no longer thrown when parsing VectorDrawable xml files which use gradients as colors.
This commit is contained in:
@@ -817,8 +817,6 @@ public final class AssetManager {
|
||||
int defStyleRes, int[] inValues,
|
||||
int[] inAttrs, int[] outValues,
|
||||
int[] outIndices);
|
||||
/*package*/ native final boolean retrieveAttributes(int xmlParser, int[] inAttrs,
|
||||
int[] outValues, int[] outIndices);
|
||||
/*package*/ native final int getArraySize(int resource);
|
||||
/*package*/ native final int retrieveArray(int resource, int[] outValues);
|
||||
private native final int getStringBlockCount();
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
55
src/api-impl/android/content/res/ComplexColor.java
Normal file
55
src/api-impl/android/content/res/ComplexColor.java
Normal file
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright (C) 2016 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package android.content.res;
|
||||
|
||||
//import android.annotation.ColorInt;
|
||||
import android.content.res.Resources.Theme;
|
||||
import android.graphics.Color;
|
||||
|
||||
/**
|
||||
* Defines an abstract class for the complex color information, like
|
||||
* {@link android.content.res.ColorStateList} or {@link android.content.res.GradientColor}
|
||||
*/
|
||||
public abstract class ComplexColor {
|
||||
/**
|
||||
* @return {@code true} if this ComplexColor changes color based on state, {@code false}
|
||||
* otherwise.
|
||||
*/
|
||||
public boolean isStateful() { return false; }
|
||||
|
||||
/**
|
||||
* @return the default color.
|
||||
*/
|
||||
//@ColorInt
|
||||
public abstract int getDefaultColor();
|
||||
|
||||
/**
|
||||
* @hide only for resource preloading
|
||||
*
|
||||
*/
|
||||
public abstract ConstantState<ComplexColor> getConstantState();
|
||||
|
||||
/**
|
||||
* @hide only for resource preloading
|
||||
*/
|
||||
public abstract boolean canApplyTheme();
|
||||
|
||||
/**
|
||||
* @hide only for resource preloading
|
||||
*/
|
||||
public abstract ComplexColor obtainForTheme(Theme t);
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright (C) 2014 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package android.content.res;
|
||||
|
||||
/**
|
||||
* A Cache class which can be used to cache resource objects that are easy to clone but more
|
||||
* expensive to inflate.
|
||||
*
|
||||
* @hide For internal use only.
|
||||
*/
|
||||
public class ConfigurationBoundResourceCache<T> extends ThemedResourceCache<ConstantState<T>> {
|
||||
private final Resources mResources;
|
||||
|
||||
/**
|
||||
* Creates a cache for the given Resources instance.
|
||||
*
|
||||
* @param resources the resources to use when creating new instances
|
||||
*/
|
||||
public ConfigurationBoundResourceCache(Resources resources) {
|
||||
mResources = resources;
|
||||
}
|
||||
|
||||
/**
|
||||
* If the resource is cached, creates and returns a new instance of it.
|
||||
*
|
||||
* @param key a key that uniquely identifies the drawable resource
|
||||
* @param theme the theme where the resource will be used
|
||||
* @return a new instance of the resource, or {@code null} if not in
|
||||
* the cache
|
||||
*/
|
||||
public T getInstance(long key, Resources.Theme theme) {
|
||||
final ConstantState<T> entry = get(key, theme);
|
||||
if (entry != null) {
|
||||
return entry.newInstance(mResources, theme);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldInvalidateEntry(ConstantState<T> entry, int configChanges) {
|
||||
return Configuration.needNewResources(configChanges, entry.getChangingConfigurations());
|
||||
}
|
||||
}
|
||||
61
src/api-impl/android/content/res/ConstantState.java
Normal file
61
src/api-impl/android/content/res/ConstantState.java
Normal file
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright (C) 2014 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package android.content.res;
|
||||
|
||||
/**
|
||||
* A cache class that can provide new instances of a particular resource which may change
|
||||
* depending on the current {@link Resources.Theme} or {@link Configuration}.
|
||||
* <p>
|
||||
* A constant state should be able to return a bitmask of changing configurations, which
|
||||
* identifies the type of configuration changes that may invalidate this resource. These
|
||||
* configuration changes can be obtained from {@link android.util.TypedValue}. Entities such as
|
||||
* {@link android.animation.Animator} also provide a changing configuration method to include
|
||||
* their dependencies (e.g. An AnimatorSet's changing configuration is the union of the
|
||||
* changing configurations of each Animator in the set)
|
||||
* @hide
|
||||
*/
|
||||
abstract public class ConstantState<T> {
|
||||
|
||||
/**
|
||||
* Return a bit mask of configuration changes that will impact
|
||||
* this resource (and thus require completely reloading it).
|
||||
*/
|
||||
abstract public int getChangingConfigurations();
|
||||
|
||||
/**
|
||||
* Create a new instance without supplying resources the caller
|
||||
* is running in.
|
||||
*/
|
||||
public abstract T newInstance();
|
||||
|
||||
/**
|
||||
* Create a new instance from its constant state. This
|
||||
* must be implemented for resources that change based on the target
|
||||
* density of their caller (that is depending on whether it is
|
||||
* in compatibility mode).
|
||||
*/
|
||||
public T newInstance(Resources res) {
|
||||
return newInstance();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new instance from its constant state. This must be
|
||||
* implemented for resources that can have a theme applied.
|
||||
*/
|
||||
public T newInstance(Resources res, Resources.Theme theme) {
|
||||
return newInstance(res);
|
||||
}
|
||||
}
|
||||
512
src/api-impl/android/content/res/GradientColor.java
Normal file
512
src/api-impl/android/content/res/GradientColor.java
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
230
src/api-impl/android/content/res/ThemedResourceCache.java
Normal file
230
src/api-impl/android/content/res/ThemedResourceCache.java
Normal file
@@ -0,0 +1,230 @@
|
||||
/*
|
||||
* Copyright (C) 2015 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package android.content.res;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.content.res.Resources.Theme;
|
||||
import android.content.res.Resources.ThemeKey;
|
||||
import android.util.ArrayMap;
|
||||
import android.util.LongSparseArray;
|
||||
import java.lang.ref.WeakReference;
|
||||
|
||||
/**
|
||||
* Data structure used for caching data against themes.
|
||||
*
|
||||
* @param <T> type of data to cache
|
||||
*/
|
||||
abstract class ThemedResourceCache<T> {
|
||||
private ArrayMap<ThemeKey, LongSparseArray<WeakReference<T>>> mThemedEntries;
|
||||
private LongSparseArray<WeakReference<T>> mUnthemedEntries;
|
||||
private LongSparseArray<WeakReference<T>> mNullThemedEntries;
|
||||
|
||||
/**
|
||||
* Adds a new theme-dependent entry to the cache.
|
||||
*
|
||||
* @param key a key that uniquely identifies the entry
|
||||
* @param theme the theme against which this entry was inflated, or
|
||||
* {@code null} if the entry has no theme applied
|
||||
* @param entry the entry to cache
|
||||
*/
|
||||
public void put(long key, @Nullable Theme theme, @NonNull T entry) {
|
||||
put(key, theme, entry, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a new entry to the cache.
|
||||
*
|
||||
* @param key a key that uniquely identifies the entry
|
||||
* @param theme the theme against which this entry was inflated, or
|
||||
* {@code null} if the entry has no theme applied
|
||||
* @param entry the entry to cache
|
||||
* @param usesTheme {@code true} if the entry is affected theme changes,
|
||||
* {@code false} otherwise
|
||||
*/
|
||||
public void put(long key, @Nullable Theme theme, @NonNull T entry, boolean usesTheme) {
|
||||
if (entry == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
synchronized (this) {
|
||||
final LongSparseArray<WeakReference<T>> entries;
|
||||
if (!usesTheme) {
|
||||
entries = getUnthemedLocked(true);
|
||||
} else {
|
||||
entries = getThemedLocked(theme, true);
|
||||
}
|
||||
if (entries != null) {
|
||||
entries.put(key, new WeakReference<>(entry));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an entry from the cache.
|
||||
*
|
||||
* @param key a key that uniquely identifies the entry
|
||||
* @param theme the theme where the entry will be used
|
||||
* @return a cached entry, or {@code null} if not in the cache
|
||||
*/
|
||||
@Nullable
|
||||
public T get(long key, @Nullable Theme theme) {
|
||||
// The themed (includes null-themed) and unthemed caches are mutually
|
||||
// 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
|
||||
// probably going to be the themed cache.
|
||||
synchronized (this) {
|
||||
final LongSparseArray<WeakReference<T>> themedEntries = getThemedLocked(theme, false);
|
||||
if (themedEntries != null) {
|
||||
final WeakReference<T> themedEntry = themedEntries.get(key);
|
||||
if (themedEntry != null) {
|
||||
return themedEntry.get();
|
||||
}
|
||||
}
|
||||
|
||||
final LongSparseArray<WeakReference<T>> unthemedEntries = getUnthemedLocked(false);
|
||||
if (unthemedEntries != null) {
|
||||
final WeakReference<T> unthemedEntry = unthemedEntries.get(key);
|
||||
if (unthemedEntry != null) {
|
||||
return unthemedEntry.get();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prunes cache entries that have been invalidated by a configuration
|
||||
* change.
|
||||
*
|
||||
* @param configChanges a bitmask of configuration changes
|
||||
*/
|
||||
public void onConfigurationChange(int configChanges) {
|
||||
prune(configChanges);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether a cached entry has been invalidated by a configuration
|
||||
* change.
|
||||
*
|
||||
* @param entry a cached entry
|
||||
* @param configChanges a non-zero bitmask of configuration changes
|
||||
* @return {@code true} if the entry is invalid, {@code false} otherwise
|
||||
*/
|
||||
protected abstract boolean shouldInvalidateEntry(@NonNull T entry, int configChanges);
|
||||
|
||||
/**
|
||||
* Returns the cached data for the specified theme, optionally creating a
|
||||
* new entry if one does not already exist.
|
||||
*
|
||||
* @param t the theme for which to return cached data
|
||||
* @param create {@code true} to create an entry if one does not already
|
||||
* exist, {@code false} otherwise
|
||||
* @return the cached data for the theme, or {@code null} if the cache is
|
||||
* empty and {@code create} was {@code false}
|
||||
*/
|
||||
@Nullable
|
||||
private LongSparseArray<WeakReference<T>> getThemedLocked(@Nullable Theme t, boolean create) {
|
||||
if (t == null) {
|
||||
if (mNullThemedEntries == null && create) {
|
||||
mNullThemedEntries = new LongSparseArray<>(1);
|
||||
}
|
||||
return mNullThemedEntries;
|
||||
}
|
||||
|
||||
if (mThemedEntries == null) {
|
||||
if (create) {
|
||||
mThemedEntries = new ArrayMap<>(1);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
final ThemeKey key = t.getKey();
|
||||
LongSparseArray<WeakReference<T>> cache = mThemedEntries.get(key);
|
||||
if (cache == null && create) {
|
||||
cache = new LongSparseArray<>(1);
|
||||
|
||||
final ThemeKey keyClone = key.clone();
|
||||
mThemedEntries.put(keyClone, cache);
|
||||
}
|
||||
|
||||
return cache;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the theme-agnostic cached data.
|
||||
*
|
||||
* @param create {@code true} to create an entry if one does not already
|
||||
* exist, {@code false} otherwise
|
||||
* @return the theme-agnostic cached data, or {@code null} if the cache is
|
||||
* empty and {@code create} was {@code false}
|
||||
*/
|
||||
@Nullable
|
||||
private LongSparseArray<WeakReference<T>> getUnthemedLocked(boolean create) {
|
||||
if (mUnthemedEntries == null && create) {
|
||||
mUnthemedEntries = new LongSparseArray<>(1);
|
||||
}
|
||||
return mUnthemedEntries;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prunes cache entries affected by configuration changes or where weak
|
||||
* references have expired.
|
||||
*
|
||||
* @param configChanges a bitmask of configuration changes, or {@code 0} to
|
||||
* simply prune missing weak references
|
||||
* @return {@code true} if the cache is completely empty after pruning
|
||||
*/
|
||||
private boolean prune(int configChanges) {
|
||||
synchronized (this) {
|
||||
if (mThemedEntries != null) {
|
||||
for (int i = mThemedEntries.size() - 1; i >= 0; i--) {
|
||||
if (pruneEntriesLocked(mThemedEntries.valueAt(i), configChanges)) {
|
||||
mThemedEntries.removeAt(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pruneEntriesLocked(mNullThemedEntries, configChanges);
|
||||
pruneEntriesLocked(mUnthemedEntries, configChanges);
|
||||
|
||||
return mThemedEntries == null && mNullThemedEntries == null && mUnthemedEntries == null;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean pruneEntriesLocked(@Nullable LongSparseArray<WeakReference<T>> entries,
|
||||
int configChanges) {
|
||||
if (entries == null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
for (int i = entries.size() - 1; i >= 0; i--) {
|
||||
final WeakReference<T> ref = entries.valueAt(i);
|
||||
if (ref == null || pruneEntryLocked(ref.get(), configChanges)) {
|
||||
entries.removeAt(i);
|
||||
}
|
||||
}
|
||||
|
||||
return entries.size() == 0;
|
||||
}
|
||||
|
||||
private boolean pruneEntryLocked(@Nullable T entry, int configChanges) {
|
||||
return entry == null || (configChanges != 0 && shouldInvalidateEntry(entry, configChanges));
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user