diff options
author | Xavier Ducrohet <xav@android.com> | 2011-02-13 20:15:50 -0800 |
---|---|---|
committer | Xavier Ducrohet <xav@android.com> | 2011-02-14 09:42:19 -0800 |
commit | 02d2b5a4031c80bfe1012ce2f4f7b3695762abd9 (patch) | |
tree | f4d74330dbd29a475c7464c18fd32e8e76d2c2c1 /tools | |
parent | bbcf2079e9978ad6f75732070ce1dcc0dea3ea3f (diff) | |
download | frameworks_base-02d2b5a4031c80bfe1012ce2f4f7b3695762abd9.zip frameworks_base-02d2b5a4031c80bfe1012ce2f4f7b3695762abd9.tar.gz frameworks_base-02d2b5a4031c80bfe1012ce2f4f7b3695762abd9.tar.bz2 |
LayoutLib: When possible ensure parsers are popped from the stack.
Some parser consumers (seems to be mostly resource inflation)
don't use the pull parser up to the END_DOCUMENT tag, making
the parser not pop itself from the parser stack automatically.
This is likely due to the XML resources being very shallow (1-2 levels
max), and the inflater just reading the content that it expects instead
of parsing till the document is done.
This ensures that *some* parsers are pop'ed from the stack when
used. Some other parsers we don't really control and hope the
user will parse till END_DOCUMENT.
Change-Id: Ie1f5762983fed2b2ae97b896218ae12b493e7ad9
Diffstat (limited to 'tools')
5 files changed, 46 insertions, 21 deletions
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 15c4f44..734f5ad 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 @@ -294,7 +294,8 @@ public final class BridgeTypedArray extends TypedArray { return null; } - String value = mResourceData[index].getValue(); + ResourceValue resValue = mResourceData[index]; + String value = resValue.getValue(); if (value == null) { return null; @@ -308,11 +309,13 @@ public final class BridgeTypedArray extends TypedArray { parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true); parser.setInput(new FileReader(f)); - ColorStateList colorStateList = ColorStateList.createFromXml( - mContext.getResources(), - // FIXME: we need to know if this resource is platform or not - new BridgeXmlBlockParser(parser, mContext, false)); - return colorStateList; + BridgeXmlBlockParser blockParser = new BridgeXmlBlockParser( + parser, mContext, resValue.isFramework()); + try { + return ColorStateList.createFromXml(mContext.getResources(), blockParser); + } finally { + blockParser.ensurePopped(); + } } catch (XmlPullParserException e) { Bridge.getLog().error(LayoutLog.TAG_BROKEN, "Failed to configure parser for " + value, e, null /*data*/); 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 38800da..2f54ae6 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 @@ -45,6 +45,8 @@ public class BridgeXmlBlockParser implements XmlResourceParser { private boolean mStarted = false; private int mEventType = START_DOCUMENT; + private boolean mPopped = true; // default to true in case it's not pushed. + /** * Builds a {@link BridgeXmlBlockParser}. * @param parser The XmlPullParser to get the content from. @@ -59,6 +61,7 @@ public class BridgeXmlBlockParser implements XmlResourceParser { if (mContext != null) { mContext.pushParser(this); + mPopped = false; } } @@ -82,6 +85,13 @@ public class BridgeXmlBlockParser implements XmlResourceParser { return null; } + public void ensurePopped() { + if (mContext != null && mPopped == false) { + mContext.popParser(); + mPopped = true; + } + } + // ------- XmlResourceParser implementation public void setFeature(String name, boolean state) @@ -249,9 +259,9 @@ public class BridgeXmlBlockParser implements XmlResourceParser { } int ev = mParser.next(); - if (ev == END_TAG && mParser.getDepth() == 1 && mContext != null) { + if (ev == END_TAG && mParser.getDepth() == 1) { // done with parser remove it from the context stack. - mContext.popParser(); + ensurePopped(); } mEventType = ev; return ev; 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 771d89a..0c4b0d3 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 @@ -76,9 +76,13 @@ abstract class CustomBar extends LinearLayout { "UTF8"); BridgeXmlBlockParser bridgeParser = new BridgeXmlBlockParser( - parser, (BridgeContext) context, false); + parser, (BridgeContext) context, false /*platformFile*/); - inflater.inflate(bridgeParser, this, true); + try { + inflater.inflate(bridgeParser, this, true); + } finally { + bridgeParser.ensurePopped(); + } } private InputStream getIcon(String iconName, Density[] densityInOut, String[] pathOut, 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 136b205..fedd789 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 @@ -182,8 +182,8 @@ public class RenderSessionImpl extends RenderAction<SessionParams> { context.setBridgeInflater(mInflater); mInflater.setFactory2(context); - mBlockParser = new BridgeXmlBlockParser(params.getLayoutDescription(), - context, false /* platformResourceFlag */); + mBlockParser = new BridgeXmlBlockParser( + params.getLayoutDescription(), context, false /* platformResourceFlag */); return SUCCESS.createResult(); } @@ -562,13 +562,14 @@ public class RenderSessionImpl extends RenderAction<SessionParams> { BridgeContext context = getContext(); // create a block parser for the XML - BridgeXmlBlockParser blockParser = new BridgeXmlBlockParser(childXml, context, - false /* platformResourceFlag */); + BridgeXmlBlockParser blockParser = new BridgeXmlBlockParser( + childXml, context, false /* platformResourceFlag */); // inflate the child without adding it to the root since we want to control where it'll // get added. We do pass the parentView however to ensure that the layoutParams will // be created correctly. final View child = mInflater.inflate(blockParser, parentView, false /*attachToRoot*/); + blockParser.ensurePopped(); invalidateRenderingSize(); 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 19392a7..69f46e6 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 @@ -126,8 +126,13 @@ public final class ResourceHelper { parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true); parser.setInput(new FileReader(f)); - return ColorStateList.createFromXml(context.getResources(), - new BridgeXmlBlockParser(parser, context, resValue.isFramework())); + BridgeXmlBlockParser blockParser = new BridgeXmlBlockParser( + parser, context, resValue.isFramework()); + try { + return ColorStateList.createFromXml(context.getResources(), blockParser); + } finally { + blockParser.ensurePopped(); + } } catch (XmlPullParserException e) { Bridge.getLog().error(LayoutLog.TAG_BROKEN, "Failed to configure parser for " + value, e, null /*data*/); @@ -164,8 +169,6 @@ public final class ResourceHelper { * @param context the current context */ public static Drawable getDrawable(ResourceValue value, BridgeContext context) { - Drawable d = null; - String stringValue = value.getValue(); if (RenderResources.REFERENCE_NULL.equals(stringValue)) { return null; @@ -205,9 +208,13 @@ public final class ResourceHelper { parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true); parser.setInput(new FileReader(f)); - d = Drawable.createFromXml(context.getResources(), - new BridgeXmlBlockParser(parser, context, value.isFramework())); - return d; + BridgeXmlBlockParser blockParser = new BridgeXmlBlockParser( + parser, context, value.isFramework()); + try { + return Drawable.createFromXml(context.getResources(), blockParser); + } finally { + blockParser.ensurePopped(); + } } catch (Exception e) { // this is an error and not warning since the file existence is checked before // attempting to parse it. |