summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java42
-rw-r--r--tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeInflater.java7
-rw-r--r--tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeResources.java109
-rw-r--r--tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeTypedArray.java42
-rw-r--r--tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeXmlBlockParser.java54
-rw-r--r--tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/CustomBar.java14
-rw-r--r--tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/PhoneSystemBar.java2
-rw-r--r--tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/TitleBar.java2
-rw-r--r--tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/ParserFactory.java77
-rw-r--r--tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java6
-rw-r--r--tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/ResourceHelper.java144
-rw-r--r--tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/android/BridgeXmlBlockParserTest.java15
12 files changed, 322 insertions, 192 deletions
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
index 904f7a3c42ff..8c93c31241e3 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
@@ -25,11 +25,11 @@ import com.android.ide.common.rendering.api.ResourceValue;
import com.android.ide.common.rendering.api.StyleResourceValue;
import com.android.layoutlib.bridge.Bridge;
import com.android.layoutlib.bridge.BridgeConstants;
+import com.android.layoutlib.bridge.impl.ParserFactory;
import com.android.layoutlib.bridge.impl.Stack;
import com.android.resources.ResourceType;
import com.android.util.Pair;
-import org.kxml2.io.KXmlParser;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
@@ -201,6 +201,9 @@ public final class BridgeContext extends Activity {
* @param parser the parser to add.
*/
public void pushParser(BridgeXmlBlockParser parser) {
+ if (ParserFactory.LOG_PARSER) {
+ System.out.println("PUSH " + parser.getParser().toString());
+ }
mParserStack.push(parser);
}
@@ -208,7 +211,10 @@ public final class BridgeContext extends Activity {
* Removes the parser at the top of the stack
*/
public void popParser() {
- mParserStack.pop();
+ BridgeXmlBlockParser parser = mParserStack.pop();
+ if (ParserFactory.LOG_PARSER) {
+ System.out.println("POPD " + parser.getParser().toString());
+ }
}
/**
@@ -341,9 +347,7 @@ public final class BridgeContext extends Activity {
// we need to create a pull parser around the layout XML file, and then
// give that to our XmlBlockParser
try {
- KXmlParser parser = new KXmlParser();
- parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true);
- parser.setInput(new FileInputStream(xml), "UTF-8"); //$NON-NLS-1$);
+ XmlPullParser parser = ParserFactory.create(xml);
// set the resource ref to have correct view cookies
mBridgeInflater.setResourceReference(resource);
@@ -682,25 +686,25 @@ public final class BridgeContext extends Activity {
*/
private BridgeTypedArray createStyleBasedTypedArray(StyleResourceValue style, int[] attrs)
throws Resources.NotFoundException {
- AtomicBoolean frameworkAttributes = new AtomicBoolean();
- AtomicReference<String> attrName = new AtomicReference<String>();
- TreeMap<Integer, String> styleNameMap = searchAttrs(attrs, frameworkAttributes, attrName);
BridgeTypedArray ta = ((BridgeResources) mSystemResources).newTypeArray(attrs.length,
- style.isFramework(), frameworkAttributes.get(), attrName.get());
-
- // loop through all the values in the style map, and init the TypedArray with
- // the style we got from the dynamic id
- for (Entry<Integer, String> styleAttribute : styleNameMap.entrySet()) {
- int index = styleAttribute.getKey().intValue();
+ false, true, null);
- String name = styleAttribute.getValue();
+ // for each attribute, get its name so that we can search it in the style
+ for (int i = 0 ; i < attrs.length ; i++) {
+ Pair<ResourceType, String> resolvedResource = Bridge.resolveResourceId(attrs[i]);
+ if (resolvedResource != null) {
+ String attrName = resolvedResource.getSecond();
+ // look for the value in the given style
+ ResourceValue resValue = mRenderResources.findItemInStyle(style, attrName);
- // get the value from the style, or its parent styles.
- ResourceValue resValue = mRenderResources.findItemInStyle(style, name);
+ if (resValue != null) {
+ // resolve it to make sure there are no references left.
+ ta.bridgeSetValue(i, attrName, mRenderResources.resolveResValue(resValue));
- // resolve it to make sure there are no references left.
- ta.bridgeSetValue(index, name, mRenderResources.resolveResValue(resValue));
+ resValue = mRenderResources.resolveResValue(resValue);
+ }
+ }
}
ta.sealArray();
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeInflater.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeInflater.java
index edfe83e2a745..df30c0da78c8 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeInflater.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeInflater.java
@@ -22,10 +22,10 @@ import com.android.ide.common.rendering.api.MergeCookie;
import com.android.ide.common.rendering.api.ResourceReference;
import com.android.ide.common.rendering.api.ResourceValue;
import com.android.layoutlib.bridge.Bridge;
+import com.android.layoutlib.bridge.impl.ParserFactory;
import com.android.resources.ResourceType;
import com.android.util.Pair;
-import org.kxml2.io.KXmlParser;
import org.xmlpull.v1.XmlPullParser;
import android.content.Context;
@@ -36,7 +36,6 @@ import android.view.View;
import android.view.ViewGroup;
import java.io.File;
-import java.io.FileInputStream;
/**
* Custom implementation of {@link LayoutInflater} to handle custom views.
@@ -175,9 +174,7 @@ public final class BridgeInflater extends LayoutInflater {
File f = new File(value.getValue());
if (f.isFile()) {
try {
- KXmlParser parser = new KXmlParser();
- parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true);
- parser.setInput(new FileInputStream(f), "UTF-8"); //$NON-NLS-1$
+ XmlPullParser parser = ParserFactory.create(f);
BridgeXmlBlockParser bridgeParser = new BridgeXmlBlockParser(
parser, bridgeContext, false);
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeResources.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeResources.java
index d0b90fb25af8..1756496fcada 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeResources.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeResources.java
@@ -21,12 +21,12 @@ import com.android.ide.common.rendering.api.LayoutLog;
import com.android.ide.common.rendering.api.ResourceValue;
import com.android.layoutlib.bridge.Bridge;
import com.android.layoutlib.bridge.BridgeConstants;
+import com.android.layoutlib.bridge.impl.ParserFactory;
import com.android.layoutlib.bridge.impl.ResourceHelper;
import com.android.ninepatch.NinePatch;
import com.android.resources.ResourceType;
import com.android.util.Pair;
-import org.kxml2.io.KXmlParser;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
@@ -131,14 +131,16 @@ public final class BridgeResources extends Resources {
platformStyleable, styleableName);
}
- private ResourceValue getResourceValue(int id, boolean[] platformResFlag_out) {
+ private Pair<String, ResourceValue> getResourceValue(int id, boolean[] platformResFlag_out) {
// first get the String related to this id in the framework
Pair<ResourceType, String> resourceInfo = Bridge.resolveResourceId(id);
if (resourceInfo != null) {
platformResFlag_out[0] = true;
- return mContext.getRenderResources().getFrameworkResource(
- resourceInfo.getFirst(), resourceInfo.getSecond());
+ String attributeName = resourceInfo.getSecond();
+
+ return Pair.of(attributeName, mContext.getRenderResources().getFrameworkResource(
+ resourceInfo.getFirst(), attributeName));
}
// didn't find a match in the framework? look in the project.
@@ -147,8 +149,10 @@ public final class BridgeResources extends Resources {
if (resourceInfo != null) {
platformResFlag_out[0] = false;
- return mContext.getRenderResources().getProjectResource(
- resourceInfo.getFirst(), resourceInfo.getSecond());
+ String attributeName = resourceInfo.getSecond();
+
+ return Pair.of(attributeName, mContext.getRenderResources().getProjectResource(
+ resourceInfo.getFirst(), attributeName));
}
}
@@ -157,10 +161,10 @@ public final class BridgeResources extends Resources {
@Override
public Drawable getDrawable(int id) throws NotFoundException {
- ResourceValue value = getResourceValue(id, mPlatformResourceFlag);
+ Pair<String, ResourceValue> value = getResourceValue(id, mPlatformResourceFlag);
if (value != null) {
- return ResourceHelper.getDrawable(value, mContext);
+ return ResourceHelper.getDrawable(value.getSecond(), mContext);
}
// id was not found or not resolved. Throw a NotFoundException.
@@ -172,11 +176,11 @@ public final class BridgeResources extends Resources {
@Override
public int getColor(int id) throws NotFoundException {
- ResourceValue value = getResourceValue(id, mPlatformResourceFlag);
+ Pair<String, ResourceValue> value = getResourceValue(id, mPlatformResourceFlag);
if (value != null) {
try {
- return ResourceHelper.getColor(value.getValue());
+ return ResourceHelper.getColor(value.getSecond().getValue());
} catch (NumberFormatException e) {
Bridge.getLog().error(LayoutLog.TAG_RESOURCES_FORMAT, e.getMessage(), e,
null /*data*/);
@@ -193,10 +197,11 @@ public final class BridgeResources extends Resources {
@Override
public ColorStateList getColorStateList(int id) throws NotFoundException {
- ResourceValue resValue = getResourceValue(id, mPlatformResourceFlag);
+ Pair<String, ResourceValue> resValue = getResourceValue(id, mPlatformResourceFlag);
if (resValue != null) {
- ColorStateList stateList = ResourceHelper.getColorStateList(resValue, mContext);
+ ColorStateList stateList = ResourceHelper.getColorStateList(resValue.getSecond(),
+ mContext);
if (stateList != null) {
return stateList;
}
@@ -211,10 +216,10 @@ public final class BridgeResources extends Resources {
@Override
public CharSequence getText(int id) throws NotFoundException {
- ResourceValue value = getResourceValue(id, mPlatformResourceFlag);
+ Pair<String, ResourceValue> value = getResourceValue(id, mPlatformResourceFlag);
if (value != null) {
- return value.getValue();
+ return value.getSecond().getValue();
}
// id was not found or not resolved. Throw a NotFoundException.
@@ -226,9 +231,10 @@ public final class BridgeResources extends Resources {
@Override
public XmlResourceParser getLayout(int id) throws NotFoundException {
- ResourceValue value = getResourceValue(id, mPlatformResourceFlag);
+ Pair<String, ResourceValue> v = getResourceValue(id, mPlatformResourceFlag);
- if (value != null) {
+ if (v != null) {
+ ResourceValue value = v.getSecond();
XmlPullParser parser = null;
try {
@@ -243,9 +249,7 @@ public final class BridgeResources extends Resources {
if (xml.isFile()) {
// we need to create a pull parser around the layout XML file, and then
// give that to our XmlBlockParser
- parser = new KXmlParser();
- parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true);
- parser.setInput(new FileInputStream(xml), "UTF-8"); //$NON-NLS-1$);
+ parser = ParserFactory.create(xml);
}
}
@@ -271,9 +275,10 @@ public final class BridgeResources extends Resources {
@Override
public XmlResourceParser getAnimation(int id) throws NotFoundException {
- ResourceValue value = getResourceValue(id, mPlatformResourceFlag);
+ Pair<String, ResourceValue> v = getResourceValue(id, mPlatformResourceFlag);
- if (value != null) {
+ if (v != null) {
+ ResourceValue value = v.getSecond();
XmlPullParser parser = null;
try {
@@ -281,9 +286,7 @@ public final class BridgeResources extends Resources {
if (xml.isFile()) {
// we need to create a pull parser around the layout XML file, and then
// give that to our XmlBlockParser
- parser = new KXmlParser();
- parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true);
- parser.setInput(new FileInputStream(xml), "UTF-8"); //$NON-NLS-1$);
+ parser = ParserFactory.create(xml);
return new BridgeXmlBlockParser(parser, mContext, mPlatformResourceFlag[0]);
}
@@ -317,10 +320,10 @@ public final class BridgeResources extends Resources {
@Override
public float getDimension(int id) throws NotFoundException {
- ResourceValue value = getResourceValue(id, mPlatformResourceFlag);
+ Pair<String, ResourceValue> value = getResourceValue(id, mPlatformResourceFlag);
if (value != null) {
- String v = value.getValue();
+ String v = value.getSecond().getValue();
if (v != null) {
if (v.equals(BridgeConstants.MATCH_PARENT) ||
@@ -330,7 +333,8 @@ public final class BridgeResources extends Resources {
return LayoutParams.WRAP_CONTENT;
}
- if (ResourceHelper.stringToFloat(v, mTmpValue) &&
+ if (ResourceHelper.parseFloatAttribute(
+ value.getFirst(), v, mTmpValue, true /*requireUnit*/) &&
mTmpValue.type == TypedValue.TYPE_DIMENSION) {
return mTmpValue.getDimension(mMetrics);
}
@@ -346,13 +350,14 @@ public final class BridgeResources extends Resources {
@Override
public int getDimensionPixelOffset(int id) throws NotFoundException {
- ResourceValue value = getResourceValue(id, mPlatformResourceFlag);
+ Pair<String, ResourceValue> value = getResourceValue(id, mPlatformResourceFlag);
if (value != null) {
- String v = value.getValue();
+ String v = value.getSecond().getValue();
if (v != null) {
- if (ResourceHelper.stringToFloat(v, mTmpValue) &&
+ if (ResourceHelper.parseFloatAttribute(
+ value.getFirst(), v, mTmpValue, true /*requireUnit*/) &&
mTmpValue.type == TypedValue.TYPE_DIMENSION) {
return TypedValue.complexToDimensionPixelOffset(mTmpValue.data, mMetrics);
}
@@ -368,13 +373,14 @@ public final class BridgeResources extends Resources {
@Override
public int getDimensionPixelSize(int id) throws NotFoundException {
- ResourceValue value = getResourceValue(id, mPlatformResourceFlag);
+ Pair<String, ResourceValue> value = getResourceValue(id, mPlatformResourceFlag);
if (value != null) {
- String v = value.getValue();
+ String v = value.getSecond().getValue();
if (v != null) {
- if (ResourceHelper.stringToFloat(v, mTmpValue) &&
+ if (ResourceHelper.parseFloatAttribute(
+ value.getFirst(), v, mTmpValue, true /*requireUnit*/) &&
mTmpValue.type == TypedValue.TYPE_DIMENSION) {
return TypedValue.complexToDimensionPixelSize(mTmpValue.data, mMetrics);
}
@@ -390,10 +396,10 @@ public final class BridgeResources extends Resources {
@Override
public int getInteger(int id) throws NotFoundException {
- ResourceValue value = getResourceValue(id, mPlatformResourceFlag);
+ Pair<String, ResourceValue> value = getResourceValue(id, mPlatformResourceFlag);
- if (value != null && value.getValue() != null) {
- String v = value.getValue();
+ if (value != null && value.getSecond().getValue() != null) {
+ String v = value.getSecond().getValue();
int radix = 10;
if (v.startsWith("0x")) {
v = v.substring(2);
@@ -445,10 +451,10 @@ public final class BridgeResources extends Resources {
@Override
public String getString(int id) throws NotFoundException {
- ResourceValue value = getResourceValue(id, mPlatformResourceFlag);
+ Pair<String, ResourceValue> value = getResourceValue(id, mPlatformResourceFlag);
- if (value != null && value.getValue() != null) {
- return value.getValue();
+ if (value != null && value.getSecond().getValue() != null) {
+ return value.getSecond().getValue();
}
// id was not found or not resolved. Throw a NotFoundException.
@@ -461,13 +467,14 @@ public final class BridgeResources extends Resources {
@Override
public void getValue(int id, TypedValue outValue, boolean resolveRefs)
throws NotFoundException {
- ResourceValue value = getResourceValue(id, mPlatformResourceFlag);
+ Pair<String, ResourceValue> value = getResourceValue(id, mPlatformResourceFlag);
if (value != null) {
- String v = value.getValue();
+ String v = value.getSecond().getValue();
if (v != null) {
- if (ResourceHelper.stringToFloat(v, outValue)) {
+ if (ResourceHelper.parseFloatAttribute(value.getFirst(), v, outValue,
+ false /*requireUnit*/)) {
return;
}
@@ -490,19 +497,17 @@ public final class BridgeResources extends Resources {
@Override
public XmlResourceParser getXml(int id) throws NotFoundException {
- ResourceValue value = getResourceValue(id, mPlatformResourceFlag);
+ Pair<String, ResourceValue> value = getResourceValue(id, mPlatformResourceFlag);
if (value != null) {
- String v = value.getValue();
+ String v = value.getSecond().getValue();
if (v != null) {
// check this is a file
- File f = new File(value.getValue());
+ File f = new File(v);
if (f.isFile()) {
try {
- KXmlParser parser = new KXmlParser();
- parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true);
- parser.setInput(new FileInputStream(f), "UTF-8"); //$NON-NLS-1$);
+ XmlPullParser parser = ParserFactory.create(f);
return new BridgeXmlBlockParser(parser, mContext, mPlatformResourceFlag[0]);
} catch (XmlPullParserException e) {
@@ -535,9 +540,7 @@ public final class BridgeResources extends Resources {
File f = new File(file);
try {
- KXmlParser parser = new KXmlParser();
- parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true);
- parser.setInput(new FileInputStream(f), "UTF-8"); //$NON-NLS-1$);
+ XmlPullParser parser = ParserFactory.create(f);
return new BridgeXmlBlockParser(parser, mContext, mPlatformResourceFlag[0]);
} catch (XmlPullParserException e) {
@@ -554,10 +557,10 @@ public final class BridgeResources extends Resources {
@Override
public InputStream openRawResource(int id) throws NotFoundException {
- ResourceValue value = getResourceValue(id, mPlatformResourceFlag);
+ Pair<String, ResourceValue> value = getResourceValue(id, mPlatformResourceFlag);
if (value != null) {
- String path = value.getValue();
+ String path = value.getSecond().getValue();
if (path != null) {
// check this is a file
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeTypedArray.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeTypedArray.java
index b1fbf08f592f..260cdc8c24ce 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeTypedArray.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeTypedArray.java
@@ -24,10 +24,10 @@ 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.impl.ParserFactory;
import com.android.layoutlib.bridge.impl.ResourceHelper;
import com.android.resources.ResourceType;
-import org.kxml2.io.KXmlParser;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
@@ -41,7 +41,6 @@ import android.view.LayoutInflater_Delegate;
import android.view.ViewGroup.LayoutParams;
import java.io.File;
-import java.io.FileInputStream;
import java.util.Arrays;
import java.util.Map;
@@ -211,7 +210,7 @@ public final class BridgeTypedArray extends TypedArray {
Map<String, Integer> map = null;
if (mPlatformStyleable) {
map = Bridge.getEnumValues(mNames[index]);
- } else {
+ } else if (mStyleableName != null) {
// get the styleable matching the resolved name
RenderResources res = mContext.getRenderResources();
ResourceValue styleable = res.getProjectResource(ResourceType.DECLARE_STYLEABLE,
@@ -331,9 +330,7 @@ public final class BridgeTypedArray extends TypedArray {
File f = new File(value);
if (f.isFile()) {
try {
- KXmlParser parser = new KXmlParser();
- parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true);
- parser.setInput(new FileInputStream(f), "UTF-8"); //$NON-NLS-1$);
+ XmlPullParser parser = ParserFactory.create(f);
BridgeXmlBlockParser blockParser = new BridgeXmlBlockParser(
parser, mContext, resValue.isFramework());
@@ -377,26 +374,7 @@ public final class BridgeTypedArray extends TypedArray {
*/
@Override
public int getInteger(int index, int defValue) {
- if (mResourceData[index] == null) {
- return defValue;
- }
-
- String s = mResourceData[index].getValue();
-
- if (s != null) {
- try {
- return Integer.parseInt(s);
- } catch (NumberFormatException e) {
- Bridge.getLog().warning(LayoutLog.TAG_RESOURCES_FORMAT,
- String.format(
- "\"%s\" in attribute \"%2$s\" cannont be converted to an integer.",
- s, mNames[index]), null /*data*/);
-
- // The default value is returned below.
- }
- }
-
- return defValue;
+ return getInt(index, defValue);
}
/**
@@ -434,7 +412,7 @@ public final class BridgeTypedArray extends TypedArray {
return defValue;
}
- if (ResourceHelper.stringToFloat(s, mValue)) {
+ if (ResourceHelper.parseFloatAttribute(mNames[index], s, mValue, true /*requireUnit*/)) {
return mValue.getDimension(mBridgeResources.mMetrics);
}
@@ -561,7 +539,7 @@ public final class BridgeTypedArray extends TypedArray {
throw new RuntimeException();
}
- if (ResourceHelper.stringToFloat(s, mValue)) {
+ if (ResourceHelper.parseFloatAttribute(mNames[index], s, mValue, true /*requireUnit*/)) {
float f = mValue.getDimension(mBridgeResources.mMetrics);
final int res = (int)(f+0.5f);
@@ -599,14 +577,15 @@ public final class BridgeTypedArray extends TypedArray {
return defValue;
}
- if (ResourceHelper.stringToFloat(value, mValue)) {
+ if (ResourceHelper.parseFloatAttribute(mNames[index], value, mValue,
+ false /*requireUnit*/)) {
return mValue.getFraction(base, pbase);
}
// looks like we were unable to resolve the fraction value
Bridge.getLog().warning(LayoutLog.TAG_RESOURCES_FORMAT,
String.format(
- "\"%1$s\" in attribute \"%2$s\" cannont be converted to a fraction.",
+ "\"%1$s\" in attribute \"%2$s\" cannot be converted to a fraction.",
value, mNames[index]), null /*data*/);
return defValue;
@@ -803,7 +782,8 @@ public final class BridgeTypedArray extends TypedArray {
String s = mResourceData[index].getValue();
- return ResourceHelper.stringToFloat(s, outValue);
+ return ResourceHelper.parseFloatAttribute(mNames[index], s, outValue,
+ false /*requireUnit*/);
}
/**
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeXmlBlockParser.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeXmlBlockParser.java
index 70dbaa4d895d..1016b3271744 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeXmlBlockParser.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeXmlBlockParser.java
@@ -18,6 +18,7 @@ package com.android.layoutlib.bridge.android;
import com.android.ide.common.rendering.api.ILayoutPullParser;
+import com.android.layoutlib.bridge.impl.ParserFactory;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
@@ -54,6 +55,10 @@ public class BridgeXmlBlockParser implements XmlResourceParser {
* @param platformFile Indicates whether the the file is a platform file or not.
*/
public BridgeXmlBlockParser(XmlPullParser parser, BridgeContext context, boolean platformFile) {
+ if (ParserFactory.LOG_PARSER) {
+ System.out.println("CRTE " + parser.toString());
+ }
+
mParser = parser;
mContext = context;
mPlatformFile = platformFile;
@@ -65,6 +70,10 @@ public class BridgeXmlBlockParser implements XmlResourceParser {
}
}
+ public XmlPullParser getParser() {
+ return mParser;
+ }
+
public boolean isPlatformFile() {
return mPlatformFile;
}
@@ -247,18 +256,63 @@ public class BridgeXmlBlockParser implements XmlResourceParser {
public int next() throws XmlPullParserException, IOException {
if (!mStarted) {
mStarted = true;
+
+ if (ParserFactory.LOG_PARSER) {
+ System.out.println("STRT " + mParser.toString());
+ }
+
return START_DOCUMENT;
}
+
int ev = mParser.next();
+ if (ParserFactory.LOG_PARSER) {
+ System.out.println("NEXT " + mParser.toString() + " " +
+ eventTypeToString(mEventType) + " -> " + eventTypeToString(ev));
+ }
+
if (ev == END_TAG && mParser.getDepth() == 1) {
// done with parser remove it from the context stack.
ensurePopped();
+
+ if (ParserFactory.LOG_PARSER) {
+ System.out.println("");
+ }
}
+
mEventType = ev;
return ev;
}
+ public static String eventTypeToString(int eventType) {
+ switch (eventType) {
+ case START_DOCUMENT:
+ return "START_DOC";
+ case END_DOCUMENT:
+ return "END_DOC";
+ case START_TAG:
+ return "START_TAG";
+ case END_TAG:
+ return "END_TAG";
+ case TEXT:
+ return "TEXT";
+ case CDSECT:
+ return "CDSECT";
+ case ENTITY_REF:
+ return "ENTITY_REF";
+ case IGNORABLE_WHITESPACE:
+ return "IGNORABLE_WHITESPACE";
+ case PROCESSING_INSTRUCTION:
+ return "PROCESSING_INSTRUCTION";
+ case COMMENT:
+ return "COMMENT";
+ case DOCDECL:
+ return "DOCDECL";
+ }
+
+ return "????";
+ }
+
public void require(int type, String namespace, String name)
throws XmlPullParserException {
if (type != getEventType()
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/CustomBar.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/CustomBar.java
index 060e6ee077bb..df701d57cd0a 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/CustomBar.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/CustomBar.java
@@ -22,11 +22,11 @@ import com.android.ide.common.rendering.api.StyleResourceValue;
import com.android.layoutlib.bridge.Bridge;
import com.android.layoutlib.bridge.android.BridgeContext;
import com.android.layoutlib.bridge.android.BridgeXmlBlockParser;
+import com.android.layoutlib.bridge.impl.ParserFactory;
import com.android.layoutlib.bridge.impl.ResourceHelper;
import com.android.resources.Density;
import com.android.resources.ResourceType;
-import org.kxml2.io.KXmlParser;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
@@ -60,7 +60,7 @@ abstract class CustomBar extends LinearLayout {
protected abstract TextView getStyleableTextView();
- protected CustomBar(Context context, Density density, String layoutPath)
+ protected CustomBar(Context context, Density density, String layoutPath, String name)
throws XmlPullParserException {
super(context);
setOrientation(LinearLayout.HORIZONTAL);
@@ -69,11 +69,8 @@ abstract class CustomBar extends LinearLayout {
LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(
Context.LAYOUT_INFLATER_SERVICE);
- KXmlParser parser = new KXmlParser();
- parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true);
- parser.setInput(
- getClass().getResourceAsStream(layoutPath),
- "UTF8"); //$NON-NLS-1$
+ XmlPullParser parser = ParserFactory.create(getClass().getResourceAsStream(layoutPath),
+ name);
BridgeXmlBlockParser bridgeParser = new BridgeXmlBlockParser(
parser, (BridgeContext) context, false /*platformFile*/);
@@ -230,7 +227,8 @@ abstract class CustomBar extends LinearLayout {
if (textSize != null) {
TypedValue out = new TypedValue();
- if (ResourceHelper.stringToFloat(textSize.getValue(), out)) {
+ if (ResourceHelper.parseFloatAttribute("textSize", textSize.getValue(), out,
+ true /*requireUnit*/)) {
textView.setTextSize(
out.getDimension(bridgeContext.getResources().mMetrics));
}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/PhoneSystemBar.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/PhoneSystemBar.java
index 80217bcdba2f..eaf4efe7d440 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/PhoneSystemBar.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/PhoneSystemBar.java
@@ -30,7 +30,7 @@ import android.widget.TextView;
public class PhoneSystemBar extends CustomBar {
public PhoneSystemBar(Context context, Density density) throws XmlPullParserException {
- super(context, density, "/bars/phone_system_bar.xml");
+ super(context, density, "/bars/phone_system_bar.xml", "phone_system_bar.xml");
setGravity(mGravity | Gravity.RIGHT);
setBackgroundColor(0xFFFFFFFF);
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/TitleBar.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/TitleBar.java
index d7401d960128..5f5ebc48d9f4 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/TitleBar.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/TitleBar.java
@@ -29,7 +29,7 @@ public class TitleBar extends CustomBar {
public TitleBar(Context context, Density density, String label)
throws XmlPullParserException {
- super(context, density, "/bars/title_bar.xml");
+ super(context, density, "/bars/title_bar.xml", "title_bar.xml");
// Cannot access the inside items through id because no R.id values have been
// created for them.
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/ParserFactory.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/ParserFactory.java
new file mode 100644
index 000000000000..a235ec3b9850
--- /dev/null
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/ParserFactory.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2011 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 com.android.layoutlib.bridge.impl;
+
+
+import org.kxml2.io.KXmlParser;
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.InputStream;
+
+/**
+ * A factory for {@link XmlPullParser}.
+ *
+ */
+public class ParserFactory {
+
+ private final static String ENCODING = "UTF-8"; //$NON-NLS-1$
+
+ public final static boolean LOG_PARSER = false;
+
+ public static XmlPullParser create(File f)
+ throws XmlPullParserException, FileNotFoundException {
+ KXmlParser parser = instantiateParser(f.getName());
+ parser.setInput(new FileInputStream(f), ENCODING);
+ return parser;
+ }
+
+ public static XmlPullParser create(InputStream stream, String name)
+ throws XmlPullParserException {
+ KXmlParser parser = instantiateParser(name);
+ parser.setInput(stream, ENCODING);
+ return parser;
+ }
+
+ private static KXmlParser instantiateParser(String name) throws XmlPullParserException {
+ KXmlParser parser;
+ if (name != null) {
+ parser = new CustomParser(name);
+ } else {
+ parser = new KXmlParser();
+ }
+ parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true);
+ return parser;
+ }
+
+ private static class CustomParser extends KXmlParser {
+ private final String mName;
+
+ CustomParser(String name) {
+ super();
+ mName = name;
+ }
+
+ @Override
+ public String toString() {
+ return mName;
+ }
+ }
+}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java
index f29a9d08413c..9332105c9699 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java
@@ -820,7 +820,8 @@ public class RenderSessionImpl extends RenderAction<SessionParams> {
"status_bar_height");
if (value != null) {
- TypedValue typedValue = ResourceHelper.getValue(value.getValue());
+ TypedValue typedValue = ResourceHelper.getValue("status_bar_height",
+ value.getValue(), true /*requireUnit*/);
if (typedValue != null) {
// compute the pixel value based on the display metrics
mStatusBarSize = (int)typedValue.getDimension(metrics);
@@ -850,7 +851,8 @@ public class RenderSessionImpl extends RenderAction<SessionParams> {
if (value != null) {
// get the numerical value, if available
- TypedValue typedValue = ResourceHelper.getValue(value.getValue());
+ TypedValue typedValue = ResourceHelper.getValue("actionBarSize", value.getValue(),
+ true /*requireUnit*/);
if (typedValue != null) {
// compute the pixel value based on the display metrics
mTitleBarSize = (int)typedValue.getDimension(metrics);
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/ResourceHelper.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/ResourceHelper.java
index e5efa4e55424..6dcb69393bd4 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/ResourceHelper.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/ResourceHelper.java
@@ -27,7 +27,6 @@ import com.android.ninepatch.NinePatch;
import com.android.ninepatch.NinePatchChunk;
import com.android.resources.Density;
-import org.kxml2.io.KXmlParser;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
@@ -121,9 +120,7 @@ public final class ResourceHelper {
try {
// let the framework inflate the ColorStateList from the XML file, by
// providing an XmlPullParser
- KXmlParser parser = new KXmlParser();
- parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true);
- parser.setInput(new FileInputStream(f), "UTF-8"); //$NON-NLS-1$);
+ XmlPullParser parser = ParserFactory.create(f);
BridgeXmlBlockParser blockParser = new BridgeXmlBlockParser(
parser, context, resValue.isFramework());
@@ -203,9 +200,7 @@ public final class ResourceHelper {
if (f.isFile()) {
try {
// let the framework inflate the Drawable from the XML file.
- KXmlParser parser = new KXmlParser();
- parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true);
- parser.setInput(new FileInputStream(f), "UTF-8"); //$NON-NLS-1$);
+ XmlPullParser parser = ParserFactory.create(f);
BridgeXmlBlockParser blockParser = new BridgeXmlBlockParser(
parser, context, value.isFramework());
@@ -341,11 +336,11 @@ public final class ResourceHelper {
};
/**
- * Returns the raw value from the given string.
+ * Returns the raw value from the given attribute float-type value string.
* This object is only valid until the next call on to {@link ResourceHelper}.
*/
- public static TypedValue getValue(String s) {
- if (stringToFloat(s, mValue)) {
+ public static TypedValue getValue(String attribute, String value, boolean requireUnit) {
+ if (parseFloatAttribute(attribute, value, mValue, requireUnit)) {
return mValue;
}
@@ -353,22 +348,27 @@ public final class ResourceHelper {
}
/**
- * Convert the string into a {@link TypedValue}.
- * @param s
- * @param outValue
+ * Parse a float attribute and return the parsed value into a given TypedValue.
+ * @param attribute the name of the attribute. Can be null if <var>requireUnit</var> is false.
+ * @param value the string value of the attribute
+ * @param outValue the TypedValue to receive the parsed value
+ * @param requireUnit whether the value is expected to contain a unit.
* @return true if success.
*/
- public static boolean stringToFloat(String s, TypedValue outValue) {
+ public static boolean parseFloatAttribute(String attribute, String value,
+ TypedValue outValue, boolean requireUnit) {
+ assert requireUnit == false || attribute != null;
+
// remove the space before and after
- s = s.trim();
- int len = s.length();
+ value = value.trim();
+ int len = value.length();
if (len <= 0) {
return false;
}
// check that there's no non ascii characters.
- char[] buf = s.toCharArray();
+ char[] buf = value.toCharArray();
for (int i = 0 ; i < len ; i++) {
if (buf[i] > 255) {
return false;
@@ -381,7 +381,7 @@ public final class ResourceHelper {
}
// now look for the string that is after the float...
- Matcher m = sFloatPattern.matcher(s);
+ Matcher m = sFloatPattern.matcher(value);
if (m.matches()) {
String f_str = m.group(1);
String end = m.group(2);
@@ -397,45 +397,7 @@ public final class ResourceHelper {
if (end.length() > 0 && end.charAt(0) != ' ') {
// Might be a unit...
if (parseUnit(end, outValue, sFloatOut)) {
-
- f *= sFloatOut[0];
- boolean neg = f < 0;
- if (neg) {
- f = -f;
- }
- long bits = (long)(f*(1<<23)+.5f);
- int radix;
- int shift;
- if ((bits&0x7fffff) == 0) {
- // Always use 23p0 if there is no fraction, just to make
- // things easier to read.
- radix = TypedValue.COMPLEX_RADIX_23p0;
- shift = 23;
- } else if ((bits&0xffffffffff800000L) == 0) {
- // Magnitude is zero -- can fit in 0 bits of precision.
- radix = TypedValue.COMPLEX_RADIX_0p23;
- shift = 0;
- } else if ((bits&0xffffffff80000000L) == 0) {
- // Magnitude can fit in 8 bits of precision.
- radix = TypedValue.COMPLEX_RADIX_8p15;
- shift = 8;
- } else if ((bits&0xffffff8000000000L) == 0) {
- // Magnitude can fit in 16 bits of precision.
- radix = TypedValue.COMPLEX_RADIX_16p7;
- shift = 16;
- } else {
- // Magnitude needs entire range, so no fractional part.
- radix = TypedValue.COMPLEX_RADIX_23p0;
- shift = 23;
- }
- int mantissa = (int)(
- (bits>>shift) & TypedValue.COMPLEX_MANTISSA_MASK);
- if (neg) {
- mantissa = (-mantissa) & TypedValue.COMPLEX_MANTISSA_MASK;
- }
- outValue.data |=
- (radix<<TypedValue.COMPLEX_RADIX_SHIFT)
- | (mantissa<<TypedValue.COMPLEX_MANTISSA_SHIFT);
+ computeTypedValue(outValue, f, sFloatOut[0]);
return true;
}
return false;
@@ -446,8 +408,20 @@ public final class ResourceHelper {
if (end.length() == 0) {
if (outValue != null) {
- outValue.type = TypedValue.TYPE_FLOAT;
- outValue.data = Float.floatToIntBits(f);
+ if (requireUnit == false) {
+ outValue.type = TypedValue.TYPE_FLOAT;
+ outValue.data = Float.floatToIntBits(f);
+ } else {
+ // no unit when required? Use dp and out an error.
+ applyUnit(sUnitNames[1], outValue, sFloatOut);
+ computeTypedValue(outValue, f, sFloatOut[0]);
+
+ Bridge.getLog().error(LayoutLog.TAG_RESOURCES_RESOLVE,
+ String.format(
+ "Dimension \"%1$s\" in attribute \"%2$s\" is missing unit!",
+ value, attribute),
+ null);
+ }
return true;
}
}
@@ -456,20 +430,64 @@ public final class ResourceHelper {
return false;
}
+ private static void computeTypedValue(TypedValue outValue, float value, float scale) {
+ value *= scale;
+ boolean neg = value < 0;
+ if (neg) {
+ value = -value;
+ }
+ long bits = (long)(value*(1<<23)+.5f);
+ int radix;
+ int shift;
+ if ((bits&0x7fffff) == 0) {
+ // Always use 23p0 if there is no fraction, just to make
+ // things easier to read.
+ radix = TypedValue.COMPLEX_RADIX_23p0;
+ shift = 23;
+ } else if ((bits&0xffffffffff800000L) == 0) {
+ // Magnitude is zero -- can fit in 0 bits of precision.
+ radix = TypedValue.COMPLEX_RADIX_0p23;
+ shift = 0;
+ } else if ((bits&0xffffffff80000000L) == 0) {
+ // Magnitude can fit in 8 bits of precision.
+ radix = TypedValue.COMPLEX_RADIX_8p15;
+ shift = 8;
+ } else if ((bits&0xffffff8000000000L) == 0) {
+ // Magnitude can fit in 16 bits of precision.
+ radix = TypedValue.COMPLEX_RADIX_16p7;
+ shift = 16;
+ } else {
+ // Magnitude needs entire range, so no fractional part.
+ radix = TypedValue.COMPLEX_RADIX_23p0;
+ shift = 23;
+ }
+ int mantissa = (int)(
+ (bits>>shift) & TypedValue.COMPLEX_MANTISSA_MASK);
+ if (neg) {
+ mantissa = (-mantissa) & TypedValue.COMPLEX_MANTISSA_MASK;
+ }
+ outValue.data |=
+ (radix<<TypedValue.COMPLEX_RADIX_SHIFT)
+ | (mantissa<<TypedValue.COMPLEX_MANTISSA_SHIFT);
+ }
+
private static boolean parseUnit(String str, TypedValue outValue, float[] outScale) {
str = str.trim();
for (UnitEntry unit : sUnitNames) {
if (unit.name.equals(str)) {
- outValue.type = unit.type;
- outValue.data = unit.unit << TypedValue.COMPLEX_UNIT_SHIFT;
- outScale[0] = unit.scale;
-
+ applyUnit(unit, outValue, outScale);
return true;
}
}
return false;
}
+
+ private static void applyUnit(UnitEntry unit, TypedValue outValue, float[] outScale) {
+ outValue.type = unit.type;
+ outValue.data = unit.unit << TypedValue.COMPLEX_UNIT_SHIFT;
+ outScale[0] = unit.scale;
+ }
}
diff --git a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/android/BridgeXmlBlockParserTest.java b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/android/BridgeXmlBlockParserTest.java
index 70d5446265e5..96436fed0d76 100644
--- a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/android/BridgeXmlBlockParserTest.java
+++ b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/android/BridgeXmlBlockParserTest.java
@@ -16,14 +16,11 @@
package com.android.layoutlib.bridge.android;
-import com.android.layoutlib.bridge.android.BridgeXmlBlockParser;
+import com.android.layoutlib.bridge.impl.ParserFactory;
-import org.kxml2.io.KXmlParser;
import org.w3c.dom.Node;
import org.xmlpull.v1.XmlPullParser;
-import java.io.InputStream;
-
import junit.framework.TestCase;
public class BridgeXmlBlockParserTest extends TestCase {
@@ -39,12 +36,12 @@ public class BridgeXmlBlockParserTest extends TestCase {
}
public void testXmlBlockParser() throws Exception {
- XmlPullParser parser = new KXmlParser();
- parser = new BridgeXmlBlockParser(parser, null, false /* platformResourceFlag */);
- InputStream input = this.getClass().getClassLoader().getResourceAsStream(
- "com/android/layoutlib/testdata/layout1.xml");
- parser.setInput(input, "UTF-8"); //$NON-NLS-1$
+ XmlPullParser parser = ParserFactory.create(
+ getClass().getResourceAsStream("com/android/layoutlib/testdata/layout1.xml"),
+ "layout1.xml");
+
+ parser = new BridgeXmlBlockParser(parser, null, false /* platformResourceFlag */);
assertEquals(XmlPullParser.START_DOCUMENT, parser.next());