am 2e67a882: am 92c40bbd: am 8989290b: am 7b13c4d8: Merge "Always resolve enum when resolving resources." into lmp-dev
* commit '2e67a88214fa93a325a84a4b8e6ae122544c8edb': Always resolve enum when resolving resources.
This commit is contained in:
@@ -23,7 +23,6 @@ import com.android.ide.common.rendering.api.ResourceValue;
|
||||
import com.android.ide.common.rendering.api.StyleResourceValue;
|
||||
import com.android.internal.util.XmlUtils;
|
||||
import com.android.layoutlib.bridge.Bridge;
|
||||
import com.android.layoutlib.bridge.BridgeConstants;
|
||||
import com.android.layoutlib.bridge.android.BridgeContext;
|
||||
import com.android.layoutlib.bridge.android.BridgeXmlBlockParser;
|
||||
import com.android.layoutlib.bridge.impl.ParserFactory;
|
||||
@@ -142,16 +141,8 @@ public final class BridgeTypedArray extends TypedArray {
|
||||
*/
|
||||
@Override
|
||||
public CharSequence getText(int index) {
|
||||
if (index < 0 || index >= mResourceData.length) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (mResourceData[index] != null) {
|
||||
// FIXME: handle styled strings!
|
||||
return mResourceData[index].getValue();
|
||||
}
|
||||
|
||||
return null;
|
||||
// FIXME: handle styled strings!
|
||||
return getString(index);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -164,15 +155,14 @@ public final class BridgeTypedArray extends TypedArray {
|
||||
*/
|
||||
@Override
|
||||
public String getString(int index) {
|
||||
if (index < 0 || index >= mResourceData.length) {
|
||||
if (!hasValue(index)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (mResourceData[index] != null) {
|
||||
return mResourceData[index].getValue();
|
||||
}
|
||||
|
||||
return null;
|
||||
// As unfortunate as it is, it's possible to use enums with all attribute formats,
|
||||
// not just integers/enums. So, we need to search the enums always. In case,
|
||||
// enums are used, the returned value is an integer.
|
||||
Integer v = resolveEnumAttribute(index);
|
||||
return v == null ? mResourceData[index].getValue() : String.valueOf((int) v);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -185,20 +175,9 @@ public final class BridgeTypedArray extends TypedArray {
|
||||
*/
|
||||
@Override
|
||||
public boolean getBoolean(int index, boolean defValue) {
|
||||
if (index < 0 || index >= mResourceData.length) {
|
||||
return defValue;
|
||||
}
|
||||
String s = getString(index);
|
||||
return s == null ? defValue : XmlUtils.convertValueToBoolean(s, defValue);
|
||||
|
||||
if (mResourceData[index] == null) {
|
||||
return defValue;
|
||||
}
|
||||
|
||||
String s = mResourceData[index].getValue();
|
||||
if (s != null) {
|
||||
return XmlUtils.convertValueToBoolean(s, defValue);
|
||||
}
|
||||
|
||||
return defValue;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -211,75 +190,18 @@ public final class BridgeTypedArray extends TypedArray {
|
||||
*/
|
||||
@Override
|
||||
public int getInt(int index, int defValue) {
|
||||
if (index < 0 || index >= mResourceData.length) {
|
||||
return defValue;
|
||||
}
|
||||
|
||||
if (mResourceData[index] == null) {
|
||||
return defValue;
|
||||
}
|
||||
|
||||
String s = mResourceData[index].getValue();
|
||||
|
||||
if (s == null || s.length() == 0) {
|
||||
return defValue;
|
||||
}
|
||||
|
||||
String s = getString(index);
|
||||
try {
|
||||
return XmlUtils.convertValueToInt(s, defValue);
|
||||
if (s != null) {
|
||||
return XmlUtils.convertValueToInt(s, defValue);
|
||||
}
|
||||
} catch (NumberFormatException e) {
|
||||
// pass
|
||||
Bridge.getLog().warning(LayoutLog.TAG_RESOURCES_FORMAT,
|
||||
String.format("\"%s\" in attribute \"%2$s\" is not a valid integer",
|
||||
s, mNames[index]),
|
||||
null);
|
||||
return defValue;
|
||||
}
|
||||
|
||||
// Field is not null and is not an integer.
|
||||
// Check for possible constants and try to find them.
|
||||
return (int) resolveEnumAttribute(index, defValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Searches for the string in the attributes (flag or enums) and returns the integer.
|
||||
* If found, it will return an integer matching the value. However, if the value is not found,
|
||||
* it returns {@code defValue} which may be a float.
|
||||
*
|
||||
* @param index Index of attribute to retrieve.
|
||||
* @param defValue Value to return if the attribute is not found.
|
||||
*
|
||||
* @return Attribute int value, or defValue if not defined.
|
||||
*/
|
||||
private float resolveEnumAttribute(int index, float defValue) {
|
||||
// Get the map of attribute-constant -> IntegerValue
|
||||
Map<String, Integer> map = null;
|
||||
if (mIsFramework[index]) {
|
||||
map = Bridge.getEnumValues(mNames[index]);
|
||||
} else {
|
||||
// get the styleable matching the resolved name
|
||||
RenderResources res = mContext.getRenderResources();
|
||||
ResourceValue attr = res.getProjectResource(ResourceType.ATTR, mNames[index]);
|
||||
if (attr instanceof AttrResourceValue) {
|
||||
map = ((AttrResourceValue) attr).getAttributeValues();
|
||||
}
|
||||
}
|
||||
|
||||
if (map != null) {
|
||||
// accumulator to store the value of the 1+ constants.
|
||||
int result = 0;
|
||||
|
||||
// split the value in case this is a mix of several flags.
|
||||
String[] keywords = mResourceData[index].getValue().split("\\|");
|
||||
for (String keyword : keywords) {
|
||||
Integer i = map.get(keyword.trim());
|
||||
if (i != null) {
|
||||
result |= i;
|
||||
} else {
|
||||
Bridge.getLog().warning(LayoutLog.TAG_RESOURCES_FORMAT,
|
||||
String.format(
|
||||
"\"%s\" in attribute \"%2$s\" is not a valid value",
|
||||
keyword, mNames[index]), null);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
return defValue;
|
||||
}
|
||||
|
||||
@@ -292,27 +214,16 @@ public final class BridgeTypedArray extends TypedArray {
|
||||
*/
|
||||
@Override
|
||||
public float getFloat(int index, float defValue) {
|
||||
if (index < 0 || index >= mResourceData.length) {
|
||||
return defValue;
|
||||
}
|
||||
|
||||
if (mResourceData[index] == null) {
|
||||
return defValue;
|
||||
}
|
||||
|
||||
String s = mResourceData[index].getValue();
|
||||
|
||||
if (s != null) {
|
||||
try {
|
||||
return Float.parseFloat(s);
|
||||
} catch (NumberFormatException e) {
|
||||
Bridge.getLog().warning(LayoutLog.TAG_RESOURCES_FORMAT,
|
||||
String.format(
|
||||
"\"%s\" in attribute \"%2$s\" cannot be converted to float.",
|
||||
s, mNames[index]), null);
|
||||
|
||||
// we'll return the default value below.
|
||||
String s = getString(index);
|
||||
try {
|
||||
if (s != null) {
|
||||
return Float.parseFloat(s);
|
||||
}
|
||||
} catch (NumberFormatException e) {
|
||||
Bridge.getLog().warning(LayoutLog.TAG_RESOURCES_FORMAT,
|
||||
String.format("\"%s\" in attribute \"%2$s\" cannot be converted to float.",
|
||||
s, mNames[index]),
|
||||
null);
|
||||
}
|
||||
return defValue;
|
||||
}
|
||||
@@ -359,11 +270,7 @@ public final class BridgeTypedArray extends TypedArray {
|
||||
*/
|
||||
@Override
|
||||
public ColorStateList getColorStateList(int index) {
|
||||
if (index < 0 || index >= mResourceData.length) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (mResourceData[index] == null) {
|
||||
if (!hasValue(index)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -443,27 +350,25 @@ public final class BridgeTypedArray extends TypedArray {
|
||||
*/
|
||||
@Override
|
||||
public float getDimension(int index, float defValue) {
|
||||
if (index < 0 || index >= mResourceData.length) {
|
||||
return defValue;
|
||||
}
|
||||
|
||||
if (mResourceData[index] == null) {
|
||||
return defValue;
|
||||
}
|
||||
|
||||
String s = mResourceData[index].getValue();
|
||||
|
||||
String s = getString(index);
|
||||
if (s == null) {
|
||||
return defValue;
|
||||
}
|
||||
// Check if the value is a magic constant that doesn't require a unit.
|
||||
try {
|
||||
int i = Integer.parseInt(s);
|
||||
if (i == LayoutParams.MATCH_PARENT || i == LayoutParams.WRAP_CONTENT) {
|
||||
return i;
|
||||
}
|
||||
} catch (NumberFormatException ignored) {
|
||||
// pass
|
||||
}
|
||||
|
||||
if (ResourceHelper.parseFloatAttribute(mNames[index], s, mValue, true)) {
|
||||
return mValue.getDimension(mBridgeResources.getDisplayMetrics());
|
||||
}
|
||||
|
||||
// looks like we were unable to resolve the dimension value. Check if it is an attribute
|
||||
// constant.
|
||||
return resolveEnumAttribute(index, defValue);
|
||||
return defValue;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -511,16 +416,13 @@ public final class BridgeTypedArray extends TypedArray {
|
||||
try {
|
||||
return getDimension(index);
|
||||
} catch (RuntimeException e) {
|
||||
if (mResourceData[index] != null) {
|
||||
String s = mResourceData[index].getValue();
|
||||
String s = getString(index);
|
||||
|
||||
if (s != null) {
|
||||
// looks like we were unable to resolve the dimension value
|
||||
Bridge.getLog().warning(LayoutLog.TAG_RESOURCES_FORMAT,
|
||||
String.format(
|
||||
"\"%1$s\" in attribute \"%2$s\" is not a valid format.",
|
||||
if (s != null) {
|
||||
// looks like we were unable to resolve the dimension value
|
||||
Bridge.getLog().warning(LayoutLog.TAG_RESOURCES_FORMAT,
|
||||
String.format("\"%1$s\" in attribute \"%2$s\" is not a valid format.",
|
||||
s, mNames[index]), null);
|
||||
}
|
||||
}
|
||||
|
||||
return defValue;
|
||||
@@ -563,21 +465,19 @@ public final class BridgeTypedArray extends TypedArray {
|
||||
}
|
||||
|
||||
private int getDimension(int index) {
|
||||
if (mResourceData[index] == null) {
|
||||
throw new RuntimeException();
|
||||
}
|
||||
|
||||
String s = mResourceData[index].getValue();
|
||||
|
||||
String s = getString(index);
|
||||
if (s == null) {
|
||||
throw new RuntimeException();
|
||||
} else if (s.equals(BridgeConstants.MATCH_PARENT) ||
|
||||
s.equals(BridgeConstants.FILL_PARENT)) {
|
||||
return LayoutParams.MATCH_PARENT;
|
||||
} else if (s.equals(BridgeConstants.WRAP_CONTENT)) {
|
||||
return LayoutParams.WRAP_CONTENT;
|
||||
}
|
||||
|
||||
// Check if the value is a magic constant that doesn't require a unit.
|
||||
try {
|
||||
int i = Integer.parseInt(s);
|
||||
if (i == LayoutParams.MATCH_PARENT || i == LayoutParams.WRAP_CONTENT) {
|
||||
return i;
|
||||
}
|
||||
} catch (NumberFormatException ignored) {
|
||||
// pass
|
||||
}
|
||||
if (ResourceHelper.parseFloatAttribute(mNames[index], s, mValue, true)) {
|
||||
float f = mValue.getDimension(mBridgeResources.getDisplayMetrics());
|
||||
|
||||
@@ -607,15 +507,7 @@ public final class BridgeTypedArray extends TypedArray {
|
||||
*/
|
||||
@Override
|
||||
public float getFraction(int index, int base, int pbase, float defValue) {
|
||||
if (index < 0 || index >= mResourceData.length) {
|
||||
return defValue;
|
||||
}
|
||||
|
||||
if (mResourceData[index] == null) {
|
||||
return defValue;
|
||||
}
|
||||
|
||||
String value = mResourceData[index].getValue();
|
||||
String value = getString(index);
|
||||
if (value == null) {
|
||||
return defValue;
|
||||
}
|
||||
@@ -766,20 +658,11 @@ public final class BridgeTypedArray extends TypedArray {
|
||||
*/
|
||||
@Override
|
||||
public Drawable getDrawable(int index) {
|
||||
if (index < 0 || index >= mResourceData.length) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (mResourceData[index] == null) {
|
||||
if (!hasValue(index)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
ResourceValue value = mResourceData[index];
|
||||
String stringValue = value.getValue();
|
||||
if (stringValue == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return ResourceHelper.getDrawable(value, mContext);
|
||||
}
|
||||
|
||||
@@ -796,15 +679,7 @@ public final class BridgeTypedArray extends TypedArray {
|
||||
*/
|
||||
@Override
|
||||
public CharSequence[] getTextArray(int index) {
|
||||
if (index < 0 || index >= mResourceData.length) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (mResourceData[index] == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
String value = mResourceData[index].getValue();
|
||||
String value = getString(index);
|
||||
if (value != null) {
|
||||
return new CharSequence[] { value };
|
||||
}
|
||||
@@ -837,17 +712,8 @@ public final class BridgeTypedArray extends TypedArray {
|
||||
*/
|
||||
@Override
|
||||
public boolean getValue(int index, TypedValue outValue) {
|
||||
if (index < 0 || index >= mResourceData.length) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mResourceData[index] == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
String s = mResourceData[index].getValue();
|
||||
|
||||
return ResourceHelper.parseFloatAttribute(mNames[index], s, outValue, false);
|
||||
String s = getString(index);
|
||||
return s != null && ResourceHelper.parseFloatAttribute(mNames[index], s, outValue, false);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -859,12 +725,7 @@ public final class BridgeTypedArray extends TypedArray {
|
||||
*/
|
||||
@Override
|
||||
public boolean hasValue(int index) {
|
||||
//noinspection SimplifiableIfStatement
|
||||
if (index < 0 || index >= mResourceData.length) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return mResourceData[index] != null;
|
||||
return index >= 0 && index < mResourceData.length && mResourceData[index] != null;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -912,6 +773,52 @@ public final class BridgeTypedArray extends TypedArray {
|
||||
return Arrays.toString(mResourceData);
|
||||
}
|
||||
|
||||
/**
|
||||
* Searches for the string in the attributes (flag or enums) and returns the integer.
|
||||
* If found, it will return an integer matching the value.
|
||||
*
|
||||
* @param index Index of attribute to retrieve.
|
||||
*
|
||||
* @return Attribute int value, or null if not defined.
|
||||
*/
|
||||
private Integer resolveEnumAttribute(int index) {
|
||||
// Get the map of attribute-constant -> IntegerValue
|
||||
Map<String, Integer> map = null;
|
||||
if (mIsFramework[index]) {
|
||||
map = Bridge.getEnumValues(mNames[index]);
|
||||
} else {
|
||||
// get the styleable matching the resolved name
|
||||
RenderResources res = mContext.getRenderResources();
|
||||
ResourceValue attr = res.getProjectResource(ResourceType.ATTR, mNames[index]);
|
||||
if (attr instanceof AttrResourceValue) {
|
||||
map = ((AttrResourceValue) attr).getAttributeValues();
|
||||
}
|
||||
}
|
||||
|
||||
if (map != null) {
|
||||
// accumulator to store the value of the 1+ constants.
|
||||
int result = 0;
|
||||
boolean found = false;
|
||||
|
||||
// split the value in case this is a mix of several flags.
|
||||
String[] keywords = mResourceData[index].getValue().split("\\|");
|
||||
for (String keyword : keywords) {
|
||||
Integer i = map.get(keyword.trim());
|
||||
if (i != null) {
|
||||
result |= i;
|
||||
found = true;
|
||||
}
|
||||
// TODO: We should act smartly and log a warning for incorrect keywords. However,
|
||||
// this method is currently called even if the resourceValue is not an enum.
|
||||
}
|
||||
if (found) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
static TypedArray obtain(Resources res, int len) {
|
||||
return res instanceof BridgeResources ?
|
||||
new BridgeTypedArray(((BridgeResources) res), null, len, true) : null;
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package com.android.layoutlib.bridge.impl;
|
||||
|
||||
import com.android.annotations.NonNull;
|
||||
import com.android.ide.common.rendering.api.DensityBasedResourceValue;
|
||||
import com.android.ide.common.rendering.api.LayoutLog;
|
||||
import com.android.ide.common.rendering.api.RenderResources;
|
||||
@@ -358,7 +359,7 @@ public final class ResourceHelper {
|
||||
* @param requireUnit whether the value is expected to contain a unit.
|
||||
* @return true if success.
|
||||
*/
|
||||
public static boolean parseFloatAttribute(String attribute, String value,
|
||||
public static boolean parseFloatAttribute(String attribute, @NonNull String value,
|
||||
TypedValue outValue, boolean requireUnit) {
|
||||
assert !requireUnit || attribute != null;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user