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