Merge "Add properties from textAppearance to property map" into nyc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
bad02b0ec9
@@ -110,13 +110,13 @@ import static com.android.layoutlib.bridge.android.RenderParamsFlags.FLAG_KEY_AP
|
|||||||
public final class BridgeContext extends Context {
|
public final class BridgeContext extends Context {
|
||||||
|
|
||||||
/** The map adds cookies to each view so that IDE can link xml tags to views. */
|
/** The map adds cookies to each view so that IDE can link xml tags to views. */
|
||||||
private final HashMap<View, Object> mViewKeyMap = new HashMap<View, Object>();
|
private final HashMap<View, Object> mViewKeyMap = new HashMap<>();
|
||||||
/**
|
/**
|
||||||
* In some cases, when inflating an xml, some objects are created. Then later, the objects are
|
* In some cases, when inflating an xml, some objects are created. Then later, the objects are
|
||||||
* converted to views. This map stores the mapping from objects to cookies which can then be
|
* converted to views. This map stores the mapping from objects to cookies which can then be
|
||||||
* used to populate the mViewKeyMap.
|
* used to populate the mViewKeyMap.
|
||||||
*/
|
*/
|
||||||
private final HashMap<Object, Object> mViewKeyHelpMap = new HashMap<Object, Object>();
|
private final HashMap<Object, Object> mViewKeyHelpMap = new HashMap<>();
|
||||||
private final BridgeAssetManager mAssets;
|
private final BridgeAssetManager mAssets;
|
||||||
private Resources mSystemResources;
|
private Resources mSystemResources;
|
||||||
private final Object mProjectKey;
|
private final Object mProjectKey;
|
||||||
@@ -132,8 +132,7 @@ public final class BridgeContext extends Context {
|
|||||||
|
|
||||||
private Resources.Theme mTheme;
|
private Resources.Theme mTheme;
|
||||||
|
|
||||||
private final Map<Object, Map<String, String>> mDefaultPropMaps =
|
private final Map<Object, PropertiesMap> mDefaultPropMaps = new IdentityHashMap<>();
|
||||||
new IdentityHashMap<Object, Map<String,String>>();
|
|
||||||
|
|
||||||
// maps for dynamically generated id representing style objects (StyleResourceValue)
|
// maps for dynamically generated id representing style objects (StyleResourceValue)
|
||||||
@Nullable
|
@Nullable
|
||||||
@@ -142,13 +141,12 @@ public final class BridgeContext extends Context {
|
|||||||
private int mDynamicIdGenerator = 0x02030000; // Base id for R.style in custom namespace
|
private int mDynamicIdGenerator = 0x02030000; // Base id for R.style in custom namespace
|
||||||
|
|
||||||
// cache for TypedArray generated from StyleResourceValue object
|
// cache for TypedArray generated from StyleResourceValue object
|
||||||
private Map<int[], Map<List<StyleResourceValue>, Map<Integer, BridgeTypedArray>>>
|
private TypedArrayCache mTypedArrayCache;
|
||||||
mTypedArrayCache;
|
|
||||||
private BridgeInflater mBridgeInflater;
|
private BridgeInflater mBridgeInflater;
|
||||||
|
|
||||||
private BridgeContentResolver mContentResolver;
|
private BridgeContentResolver mContentResolver;
|
||||||
|
|
||||||
private final Stack<BridgeXmlBlockParser> mParserStack = new Stack<BridgeXmlBlockParser>();
|
private final Stack<BridgeXmlBlockParser> mParserStack = new Stack<>();
|
||||||
private SharedPreferences mSharedPreferences;
|
private SharedPreferences mSharedPreferences;
|
||||||
private ClassLoader mClassLoader;
|
private ClassLoader mClassLoader;
|
||||||
private IBinder mBinder;
|
private IBinder mBinder;
|
||||||
@@ -162,7 +160,7 @@ public final class BridgeContext extends Context {
|
|||||||
* This a map from value to attribute name. Warning for missing references shouldn't be logged
|
* This a map from value to attribute name. Warning for missing references shouldn't be logged
|
||||||
* if value and attr name pair is the same as an entry in this map.
|
* if value and attr name pair is the same as an entry in this map.
|
||||||
*/
|
*/
|
||||||
private static Map<String, String> RTL_ATTRS = new HashMap<String, String>(10);
|
private static Map<String, String> RTL_ATTRS = new HashMap<>(10);
|
||||||
|
|
||||||
static {
|
static {
|
||||||
RTL_ATTRS.put("?android:attr/paddingLeft", "paddingStart");
|
RTL_ATTRS.put("?android:attr/paddingLeft", "paddingStart");
|
||||||
@@ -325,11 +323,11 @@ public final class BridgeContext extends Context {
|
|||||||
return mParserStack.get(mParserStack.size() - 2);
|
return mParserStack.get(mParserStack.size() - 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean resolveThemeAttribute(int resid, TypedValue outValue, boolean resolveRefs) {
|
public boolean resolveThemeAttribute(int resId, TypedValue outValue, boolean resolveRefs) {
|
||||||
Pair<ResourceType, String> resourceInfo = Bridge.resolveResourceId(resid);
|
Pair<ResourceType, String> resourceInfo = Bridge.resolveResourceId(resId);
|
||||||
boolean isFrameworkRes = true;
|
boolean isFrameworkRes = true;
|
||||||
if (resourceInfo == null) {
|
if (resourceInfo == null) {
|
||||||
resourceInfo = mLayoutlibCallback.resolveResourceId(resid);
|
resourceInfo = mLayoutlibCallback.resolveResourceId(resId);
|
||||||
isFrameworkRes = false;
|
isFrameworkRes = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -602,23 +600,20 @@ public final class BridgeContext extends Context {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final BridgeTypedArray obtainStyledAttributes(int[] attrs) {
|
public final BridgeTypedArray obtainStyledAttributes(int[] attrs) {
|
||||||
// No style is specified here, so create the typed array based on the default theme
|
return obtainStyledAttributes(0, attrs);
|
||||||
// and the styles already applied to it. A null value of style indicates that the default
|
|
||||||
// theme should be used.
|
|
||||||
return createStyleBasedTypedArray(null, attrs);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final BridgeTypedArray obtainStyledAttributes(int resid, int[] attrs)
|
public final BridgeTypedArray obtainStyledAttributes(int resId, int[] attrs)
|
||||||
throws Resources.NotFoundException {
|
throws Resources.NotFoundException {
|
||||||
StyleResourceValue style = null;
|
StyleResourceValue style = null;
|
||||||
// get the StyleResourceValue based on the resId;
|
// get the StyleResourceValue based on the resId;
|
||||||
if (resid != 0) {
|
if (resId != 0) {
|
||||||
style = getStyleByDynamicId(resid);
|
style = getStyleByDynamicId(resId);
|
||||||
|
|
||||||
if (style == null) {
|
if (style == null) {
|
||||||
// In some cases, style may not be a dynamic id, so we do a full search.
|
// In some cases, style may not be a dynamic id, so we do a full search.
|
||||||
ResourceReference ref = resolveId(resid);
|
ResourceReference ref = resolveId(resId);
|
||||||
if (ref != null) {
|
if (ref != null) {
|
||||||
style = mRenderResources.getStyle(ref.getName(), ref.isFramework());
|
style = mRenderResources.getStyle(ref.getName(), ref.isFramework());
|
||||||
}
|
}
|
||||||
@@ -629,41 +624,33 @@ public final class BridgeContext extends Context {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// The map is from
|
|
||||||
// attrs (int[]) -> context's current themes (List<StyleRV>) -> resid (int) -> typed array.
|
|
||||||
if (mTypedArrayCache == null) {
|
if (mTypedArrayCache == null) {
|
||||||
mTypedArrayCache = new IdentityHashMap<int[],
|
mTypedArrayCache = new TypedArrayCache();
|
||||||
Map<List<StyleResourceValue>, Map<Integer, BridgeTypedArray>>>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// get the 2nd map
|
|
||||||
Map<List<StyleResourceValue>, Map<Integer, BridgeTypedArray>> map2 =
|
|
||||||
mTypedArrayCache.get(attrs);
|
|
||||||
if (map2 == null) {
|
|
||||||
map2 = new HashMap<List<StyleResourceValue>, Map<Integer, BridgeTypedArray>>();
|
|
||||||
mTypedArrayCache.put(attrs, map2);
|
|
||||||
}
|
|
||||||
|
|
||||||
// get the 3rd map
|
|
||||||
List<StyleResourceValue> currentThemes = mRenderResources.getAllThemes();
|
List<StyleResourceValue> currentThemes = mRenderResources.getAllThemes();
|
||||||
Map<Integer, BridgeTypedArray> map3 = map2.get(currentThemes);
|
|
||||||
if (map3 == null) {
|
Pair<BridgeTypedArray, PropertiesMap> typeArrayAndPropertiesPair =
|
||||||
map3 = new HashMap<Integer, BridgeTypedArray>();
|
mTypedArrayCache.get(attrs, currentThemes, resId);
|
||||||
// Create a copy of the list before adding it to the map. This allows reusing the
|
|
||||||
// existing list.
|
if (typeArrayAndPropertiesPair == null) {
|
||||||
currentThemes = new ArrayList<StyleResourceValue>(currentThemes);
|
typeArrayAndPropertiesPair = createStyleBasedTypedArray(style, attrs);
|
||||||
map2.put(currentThemes, map3);
|
mTypedArrayCache.put(attrs, currentThemes, resId, typeArrayAndPropertiesPair);
|
||||||
}
|
}
|
||||||
|
// Add value to defaultPropsMap if needed
|
||||||
// get the array from the 3rd map
|
if (typeArrayAndPropertiesPair.getSecond() != null) {
|
||||||
BridgeTypedArray ta = map3.get(resid);
|
Object key = getCurrentParser().getViewCookie();
|
||||||
|
if (key != null) {
|
||||||
if (ta == null) {
|
PropertiesMap defaultPropMap = mDefaultPropMaps.get(key);
|
||||||
ta = createStyleBasedTypedArray(style, attrs);
|
if (defaultPropMap == null) {
|
||||||
map3.put(resid, ta);
|
defaultPropMap = typeArrayAndPropertiesPair.getSecond();
|
||||||
|
mDefaultPropMaps.put(key, defaultPropMap);
|
||||||
|
} else {
|
||||||
|
defaultPropMap.putAll(typeArrayAndPropertiesPair.getSecond());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
return typeArrayAndPropertiesPair.getFirst();
|
||||||
return ta;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -675,7 +662,7 @@ public final class BridgeContext extends Context {
|
|||||||
public BridgeTypedArray obtainStyledAttributes(AttributeSet set, int[] attrs,
|
public BridgeTypedArray obtainStyledAttributes(AttributeSet set, int[] attrs,
|
||||||
int defStyleAttr, int defStyleRes) {
|
int defStyleAttr, int defStyleRes) {
|
||||||
|
|
||||||
Map<String, String> defaultPropMap = null;
|
PropertiesMap defaultPropMap = null;
|
||||||
boolean isPlatformFile = true;
|
boolean isPlatformFile = true;
|
||||||
|
|
||||||
// Hint: for XmlPullParser, attach source //DEVICE_SRC/dalvik/libcore/xml/src/java
|
// Hint: for XmlPullParser, attach source //DEVICE_SRC/dalvik/libcore/xml/src/java
|
||||||
@@ -689,7 +676,7 @@ public final class BridgeContext extends Context {
|
|||||||
if (key != null) {
|
if (key != null) {
|
||||||
defaultPropMap = mDefaultPropMaps.get(key);
|
defaultPropMap = mDefaultPropMaps.get(key);
|
||||||
if (defaultPropMap == null) {
|
if (defaultPropMap == null) {
|
||||||
defaultPropMap = new HashMap<String, String>();
|
defaultPropMap = new PropertiesMap();
|
||||||
mDefaultPropMaps.put(key, defaultPropMap);
|
mDefaultPropMaps.put(key, defaultPropMap);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -937,32 +924,33 @@ public final class BridgeContext extends Context {
|
|||||||
*
|
*
|
||||||
* @see #obtainStyledAttributes(int, int[])
|
* @see #obtainStyledAttributes(int, int[])
|
||||||
*/
|
*/
|
||||||
private BridgeTypedArray createStyleBasedTypedArray(@Nullable StyleResourceValue style,
|
private Pair<BridgeTypedArray, PropertiesMap> createStyleBasedTypedArray(
|
||||||
int[] attrs) throws Resources.NotFoundException {
|
@Nullable StyleResourceValue style, int[] attrs) throws Resources.NotFoundException {
|
||||||
|
|
||||||
List<Pair<String, Boolean>> attributes = searchAttrs(attrs);
|
List<Pair<String, Boolean>> attributes = searchAttrs(attrs);
|
||||||
|
|
||||||
BridgeTypedArray ta = Resources_Delegate.newTypeArray(mSystemResources, attrs.length,
|
BridgeTypedArray ta = Resources_Delegate.newTypeArray(mSystemResources, attrs.length, false);
|
||||||
false);
|
|
||||||
|
|
||||||
|
PropertiesMap defaultPropMap = new PropertiesMap();
|
||||||
// for each attribute, get its name so that we can search it in the style
|
// for each attribute, get its name so that we can search it in the style
|
||||||
for (int i = 0 ; i < attrs.length ; i++) {
|
for (int i = 0; i < attrs.length; i++) {
|
||||||
Pair<String, Boolean> attribute = attributes.get(i);
|
Pair<String, Boolean> attribute = attributes.get(i);
|
||||||
|
|
||||||
if (attribute != null) {
|
if (attribute != null) {
|
||||||
// look for the value in the given style
|
// look for the value in the given style
|
||||||
ResourceValue resValue;
|
ResourceValue resValue;
|
||||||
|
String attrName = attribute.getFirst();
|
||||||
if (style != null) {
|
if (style != null) {
|
||||||
resValue = mRenderResources.findItemInStyle(style, attribute.getFirst(),
|
resValue = mRenderResources.findItemInStyle(style, attrName,
|
||||||
attribute.getSecond());
|
attribute.getSecond());
|
||||||
} else {
|
} else {
|
||||||
resValue = mRenderResources.findItemInTheme(attribute.getFirst(),
|
resValue = mRenderResources.findItemInTheme(attrName, attribute.getSecond());
|
||||||
attribute.getSecond());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (resValue != null) {
|
if (resValue != null) {
|
||||||
|
// Add it to defaultPropMap before resolving
|
||||||
|
defaultPropMap.put(attrName, resValue.getValue());
|
||||||
// resolve it to make sure there are no references left.
|
// resolve it to make sure there are no references left.
|
||||||
ta.bridgeSetValue(i, attribute.getFirst(), attribute.getSecond(),
|
ta.bridgeSetValue(i, attrName, attribute.getSecond(),
|
||||||
mRenderResources.resolveResValue(resValue));
|
mRenderResources.resolveResValue(resValue));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -970,7 +958,7 @@ public final class BridgeContext extends Context {
|
|||||||
|
|
||||||
ta.sealArray();
|
ta.sealArray();
|
||||||
|
|
||||||
return ta;
|
return Pair.of(ta, defaultPropMap);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -982,7 +970,7 @@ public final class BridgeContext extends Context {
|
|||||||
* @return List of attribute information.
|
* @return List of attribute information.
|
||||||
*/
|
*/
|
||||||
private List<Pair<String, Boolean>> searchAttrs(int[] attrs) {
|
private List<Pair<String, Boolean>> searchAttrs(int[] attrs) {
|
||||||
List<Pair<String, Boolean>> results = new ArrayList<Pair<String, Boolean>>(attrs.length);
|
List<Pair<String, Boolean>> results = new ArrayList<>(attrs.length);
|
||||||
|
|
||||||
// for each attribute, get its name so that we can search it in the style
|
// for each attribute, get its name so that we can search it in the style
|
||||||
for (int attr : attrs) {
|
for (int attr : attrs) {
|
||||||
@@ -1011,7 +999,7 @@ public final class BridgeContext extends Context {
|
|||||||
* @return A (name, isFramework) pair describing the attribute if found. Returns null
|
* @return A (name, isFramework) pair describing the attribute if found. Returns null
|
||||||
* if nothing is found.
|
* if nothing is found.
|
||||||
*/
|
*/
|
||||||
public Pair<String, Boolean> searchAttr(int attr) {
|
private Pair<String, Boolean> searchAttr(int attr) {
|
||||||
Pair<ResourceType, String> info = Bridge.resolveResourceId(attr);
|
Pair<ResourceType, String> info = Bridge.resolveResourceId(attr);
|
||||||
if (info != null) {
|
if (info != null) {
|
||||||
return Pair.of(info.getSecond(), Boolean.TRUE);
|
return Pair.of(info.getSecond(), Boolean.TRUE);
|
||||||
@@ -1028,8 +1016,8 @@ public final class BridgeContext extends Context {
|
|||||||
public int getDynamicIdByStyle(StyleResourceValue resValue) {
|
public int getDynamicIdByStyle(StyleResourceValue resValue) {
|
||||||
if (mDynamicIdToStyleMap == null) {
|
if (mDynamicIdToStyleMap == null) {
|
||||||
// create the maps.
|
// create the maps.
|
||||||
mDynamicIdToStyleMap = new HashMap<Integer, StyleResourceValue>();
|
mDynamicIdToStyleMap = new HashMap<>();
|
||||||
mStyleToDynamicIdMap = new HashMap<StyleResourceValue, Integer>();
|
mStyleToDynamicIdMap = new HashMap<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
// look for an existing id
|
// look for an existing id
|
||||||
@@ -1868,4 +1856,69 @@ public final class BridgeContext extends Context {
|
|||||||
public boolean isCredentialProtectedStorage() {
|
public boolean isCredentialProtectedStorage() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The cached value depends on
|
||||||
|
* <ol>
|
||||||
|
* <li>{@code int[]}: the attributes for which TypedArray is created </li>
|
||||||
|
* <li>{@code List<StyleResourceValue>}: the themes set on the context at the time of
|
||||||
|
* creation of the TypedArray</li>
|
||||||
|
* <li>{@code Integer}: the default style used at the time of creation</li>
|
||||||
|
* </ol>
|
||||||
|
*
|
||||||
|
* The class is created by using nested maps resolving one dependency at a time.
|
||||||
|
* <p/>
|
||||||
|
* The final value of the nested maps is a pair of the typed array and a map of properties
|
||||||
|
* that should be added to {@link #mDefaultPropMaps}, if needed.
|
||||||
|
*/
|
||||||
|
private static class TypedArrayCache {
|
||||||
|
|
||||||
|
private Map<int[],
|
||||||
|
Map<List<StyleResourceValue>,
|
||||||
|
Map<Integer, Pair<BridgeTypedArray, PropertiesMap>>>> mCache;
|
||||||
|
|
||||||
|
public TypedArrayCache() {
|
||||||
|
mCache = new IdentityHashMap<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Pair<BridgeTypedArray, PropertiesMap> get(int[] attrs,
|
||||||
|
List<StyleResourceValue> themes, int resId) {
|
||||||
|
Map<List<StyleResourceValue>, Map<Integer, Pair<BridgeTypedArray, PropertiesMap>>>
|
||||||
|
cacheFromThemes = mCache.get(attrs);
|
||||||
|
if (cacheFromThemes != null) {
|
||||||
|
Map<Integer, Pair<BridgeTypedArray, PropertiesMap>> cacheFromResId =
|
||||||
|
cacheFromThemes.get(themes);
|
||||||
|
if (cacheFromResId != null) {
|
||||||
|
return cacheFromResId.get(resId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void put(int[] attrs, List<StyleResourceValue> themes, int resId,
|
||||||
|
Pair<BridgeTypedArray, PropertiesMap> value) {
|
||||||
|
Map<List<StyleResourceValue>, Map<Integer, Pair<BridgeTypedArray, PropertiesMap>>>
|
||||||
|
cacheFromThemes = mCache.get(attrs);
|
||||||
|
if (cacheFromThemes == null) {
|
||||||
|
cacheFromThemes = new HashMap<>();
|
||||||
|
mCache.put(attrs, cacheFromThemes);
|
||||||
|
}
|
||||||
|
Map<Integer, Pair<BridgeTypedArray, PropertiesMap>> cacheFromResId =
|
||||||
|
cacheFromThemes.get(themes);
|
||||||
|
if (cacheFromResId == null) {
|
||||||
|
cacheFromResId = new HashMap<>();
|
||||||
|
cacheFromThemes.put(themes, cacheFromResId);
|
||||||
|
}
|
||||||
|
cacheFromResId.put(resId, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An alias used for the value in {@code {@link #mDefaultPropMaps}}
|
||||||
|
*/
|
||||||
|
private static class PropertiesMap extends HashMap<String, String> {
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user