1 /*
2  * Copyright (C) 2011 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.frameworkperf;
18 
19 import java.io.IOException;
20 
21 import org.xmlpull.v1.XmlPullParser;
22 import org.xmlpull.v1.XmlPullParserException;
23 
24 import android.content.Context;
25 import android.content.res.TypedArray;
26 import android.content.res.XmlResourceParser;
27 import android.util.AttributeSet;
28 import android.util.Xml;
29 import android.view.InflateException;
30 
31 public class SimpleInflater {
32     /** Menu tag name in XML. */
33     private static final String XML_MENU = "menu";
34 
35     /** Group tag name in XML. */
36     private static final String XML_GROUP = "group";
37 
38     /** Item tag name in XML. */
39     private static final String XML_ITEM = "item";
40 
41     private Context mContext;
42 
SimpleInflater(Context context)43     public SimpleInflater(Context context) {
44         mContext = context;
45     }
46 
inflate(int menuRes)47     public void inflate(int menuRes) {
48         XmlResourceParser parser = null;
49         try {
50             parser = mContext.getResources().getLayout(menuRes);
51             AttributeSet attrs = Xml.asAttributeSet(parser);
52 
53             parseMenu(parser, attrs);
54         } catch (XmlPullParserException e) {
55             throw new InflateException("Error inflating menu XML", e);
56         } catch (IOException e) {
57             throw new InflateException("Error inflating menu XML", e);
58         } finally {
59             if (parser != null) parser.close();
60         }
61     }
62 
parseMenu(XmlPullParser parser, AttributeSet attrs)63     private void parseMenu(XmlPullParser parser, AttributeSet attrs)
64             throws XmlPullParserException, IOException {
65         int eventType = parser.getEventType();
66         String tagName;
67         boolean lookingForEndOfUnknownTag = false;
68         String unknownTagName = null;
69 
70         // This loop will skip to the menu start tag
71         do {
72             if (eventType == XmlPullParser.START_TAG) {
73                 tagName = parser.getName();
74                 if (tagName.equals(XML_MENU)) {
75                     // Go to next tag
76                     eventType = parser.next();
77                     break;
78                 }
79 
80                 throw new RuntimeException("Expecting menu, got " + tagName);
81             }
82             eventType = parser.next();
83         } while (eventType != XmlPullParser.END_DOCUMENT);
84 
85         boolean reachedEndOfMenu = false;
86         while (!reachedEndOfMenu) {
87             switch (eventType) {
88                 case XmlPullParser.START_TAG:
89                     if (lookingForEndOfUnknownTag) {
90                         break;
91                     }
92 
93                     tagName = parser.getName();
94                     if (tagName.equals(XML_ITEM)) {
95                         readItem(attrs);
96                     } else if (tagName.equals(XML_MENU)) {
97                         parseMenu(parser, attrs);
98                     } else {
99                         lookingForEndOfUnknownTag = true;
100                         unknownTagName = tagName;
101                     }
102                     break;
103 
104                 case XmlPullParser.END_TAG:
105                     tagName = parser.getName();
106                     if (lookingForEndOfUnknownTag && tagName.equals(unknownTagName)) {
107                         lookingForEndOfUnknownTag = false;
108                         unknownTagName = null;
109                     } else if (tagName.equals(XML_ITEM)) {
110                     } else if (tagName.equals(XML_MENU)) {
111                         reachedEndOfMenu = true;
112                     }
113                     break;
114 
115                 case XmlPullParser.END_DOCUMENT:
116                     throw new RuntimeException("Unexpected end of document");
117             }
118 
119             eventType = parser.next();
120         }
121     }
122 
readItem(AttributeSet attrs)123     public void readItem(AttributeSet attrs) {
124         TypedArray a = mContext.obtainStyledAttributes(attrs,
125                 com.android.internal.R.styleable.MenuItem);
126 
127         // Inherit attributes from the group as default value
128         int itemId = a.getResourceId(R.styleable.MenuItem_android_id, 0);
129         final int category = a.getInt(R.styleable.MenuItem_android_menuCategory, 0);
130         final int order = a.getInt(R.styleable.MenuItem_android_orderInCategory, 0);
131         CharSequence itemTitle = a.getText(R.styleable.MenuItem_android_title);
132         CharSequence itemTitleCondensed = a.getText(R.styleable.MenuItem_android_titleCondensed);
133         int itemIconResId = a.getResourceId(R.styleable.MenuItem_android_icon, 0);
134         String itemAlphabeticShortcut = a.getString(R.styleable.MenuItem_android_alphabeticShortcut);
135         String itemNumericShortcut = a.getString(R.styleable.MenuItem_android_numericShortcut);
136         int itemCheckable = 0;
137         if (a.hasValue(R.styleable.MenuItem_android_checkable)) {
138             // Item has attribute checkable, use it
139             itemCheckable = a.getBoolean(R.styleable.MenuItem_android_checkable, false) ? 1 : 0;
140         }
141         boolean itemChecked = a.getBoolean(R.styleable.MenuItem_android_checked, false);
142         boolean itemVisible = a.getBoolean(R.styleable.MenuItem_android_visible, false);
143         boolean itemEnabled = a.getBoolean(R.styleable.MenuItem_android_enabled, false);
144 
145         a.recycle();
146     }
147 }
148