Fix BridgeTypedArray.getType() [DO NOT MERGE]

Also includes some fixes for BridgeTypedArray.getInt() - when value is a
color, when value is an octal int, when value is true/false.

Bug: http://b.android.com/162438
Change-Id: I0b985ea3437be8018d0e116e7a599843cc7aacd6
(cherry picked from commit 5779ad71ea)
This commit is contained in:
Deepanshu Gupta
2015-05-27 16:57:10 -07:00
parent e481e713f2
commit e698bb27f3

View File

@@ -45,7 +45,24 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.Map;
import static com.android.ide.common.rendering.api.RenderResources.*;
import static android.util.TypedValue.TYPE_ATTRIBUTE;
import static android.util.TypedValue.TYPE_DIMENSION;
import static android.util.TypedValue.TYPE_FLOAT;
import static android.util.TypedValue.TYPE_INT_BOOLEAN;
import static android.util.TypedValue.TYPE_INT_COLOR_ARGB4;
import static android.util.TypedValue.TYPE_INT_COLOR_ARGB8;
import static android.util.TypedValue.TYPE_INT_COLOR_RGB4;
import static android.util.TypedValue.TYPE_INT_COLOR_RGB8;
import static android.util.TypedValue.TYPE_INT_DEC;
import static android.util.TypedValue.TYPE_INT_HEX;
import static android.util.TypedValue.TYPE_NULL;
import static android.util.TypedValue.TYPE_REFERENCE;
import static android.util.TypedValue.TYPE_STRING;
import static com.android.SdkConstants.PREFIX_RESOURCE_REF;
import static com.android.SdkConstants.PREFIX_THEME_REF;
import static com.android.ide.common.rendering.api.RenderResources.REFERENCE_EMPTY;
import static com.android.ide.common.rendering.api.RenderResources.REFERENCE_NULL;
import static com.android.ide.common.rendering.api.RenderResources.REFERENCE_UNDEFINED;
/**
* Custom implementation of TypedArray to handle non compiled resources.
@@ -223,7 +240,7 @@ public final class BridgeTypedArray extends TypedArray {
String s = getString(index);
try {
if (s != null) {
return XmlUtils.convertValueToInt(s, defValue);
return convertValueToInt(s, defValue);
}
} catch (NumberFormatException e) {
Bridge.getLog().warning(LayoutLog.TAG_RESOURCES_FORMAT,
@@ -762,6 +779,60 @@ public final class BridgeTypedArray extends TypedArray {
return s != null && ResourceHelper.parseFloatAttribute(mNames[index], s, outValue, false);
}
@Override
@SuppressWarnings("ResultOfMethodCallIgnored")
public int getType(int index) {
String value = getString(index);
if (value == null) {
return TYPE_NULL;
}
if (value.startsWith(PREFIX_RESOURCE_REF)) {
return TYPE_REFERENCE;
}
if (value.startsWith(PREFIX_THEME_REF)) {
return TYPE_ATTRIBUTE;
}
try {
// Don't care about the value. Only called to check if an exception is thrown.
convertValueToInt(value, 0);
if (value.startsWith("0x") || value.startsWith("0X")) {
return TYPE_INT_HEX;
}
// is it a color?
if (value.startsWith("#")) {
int length = value.length() - 1;
if (length == 3) { // rgb
return TYPE_INT_COLOR_RGB4;
}
if (length == 4) { // argb
return TYPE_INT_COLOR_ARGB4;
}
if (length == 6) { // rrggbb
return TYPE_INT_COLOR_RGB8;
}
if (length == 8) { // aarrggbb
return TYPE_INT_COLOR_ARGB8;
}
}
if (value.equalsIgnoreCase("true") || value.equalsIgnoreCase("false")) {
return TYPE_INT_BOOLEAN;
}
return TYPE_INT_DEC;
} catch (NumberFormatException ignored) {
try {
Float.parseFloat(value);
return TYPE_FLOAT;
} catch (NumberFormatException ignore) {
}
// Might be a dimension.
if (ResourceHelper.parseFloatAttribute(null, value, new TypedValue(), false)) {
return TYPE_DIMENSION;
}
}
// TODO: handle fractions.
return TYPE_STRING;
}
/**
* Determines whether there is an attribute at <var>index</var>.
*
@@ -871,6 +942,52 @@ public final class BridgeTypedArray extends TypedArray {
return null;
}
/**
* Copied from {@link XmlUtils#convertValueToInt(CharSequence, int)}, but adapted to account
* for aapt, and the fact that host Java VM's Integer.parseInt("XXXXXXXX", 16) cannot handle
* "XXXXXXXX" > 80000000.
*/
private static int convertValueToInt(@Nullable String charSeq, int defValue) {
if (null == charSeq)
return defValue;
int sign = 1;
int index = 0;
int len = charSeq.length();
int base = 10;
if ('-' == charSeq.charAt(0)) {
sign = -1;
index++;
}
if ('0' == charSeq.charAt(index)) {
// Quick check for a zero by itself
if (index == (len - 1))
return 0;
char c = charSeq.charAt(index + 1);
if ('x' == c || 'X' == c) {
index += 2;
base = 16;
} else {
index++;
// Leave the base as 10. aapt removes the preceding zero, and thus when framework
// sees the value, it only gets the decimal value.
}
} else if ('#' == charSeq.charAt(index)) {
return ResourceHelper.getColor(charSeq) * sign;
} else if ("true".equals(charSeq) || "TRUE".equals(charSeq)) {
return -1;
} else if ("false".equals(charSeq) || "FALSE".equals(charSeq)) {
return 0;
}
// Use Long, since we want to handle hex ints > 80000000.
return ((int)Long.parseLong(charSeq.substring(index), base)) * sign;
}
static TypedArray obtain(Resources res, int len) {
return res instanceof BridgeResources ?
new BridgeTypedArray(((BridgeResources) res), null, len, true) : null;