1282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski/*
2282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Copyright (C) 2008 The Android Open Source Project
3282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski *
4282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Licensed under the Apache License, Version 2.0 (the "License");
5282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * you may not use this file except in compliance with the License.
6282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * You may obtain a copy of the License at
7282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski *
8282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski *      http://www.apache.org/licenses/LICENSE-2.0
9282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski *
10282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Unless required by applicable law or agreed to in writing, software
11282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * distributed under the License is distributed on an "AS IS" BASIS,
12282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * See the License for the specific language governing permissions and
14282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * limitations under the License.
15282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */
16282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
17282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskipackage android.content.res;
18282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
19282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport com.android.ide.common.rendering.api.IProjectCallback;
20282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport com.android.ide.common.rendering.api.LayoutLog;
21282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport com.android.ide.common.rendering.api.ResourceValue;
22282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport com.android.layoutlib.bridge.Bridge;
23282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport com.android.layoutlib.bridge.BridgeConstants;
24282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport com.android.layoutlib.bridge.android.BridgeContext;
25282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport com.android.layoutlib.bridge.android.BridgeXmlBlockParser;
26282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport com.android.layoutlib.bridge.impl.ParserFactory;
27282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport com.android.layoutlib.bridge.impl.ResourceHelper;
28282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport com.android.ninepatch.NinePatch;
29282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport com.android.resources.ResourceType;
30282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport com.android.util.Pair;
31282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
32282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport org.xmlpull.v1.XmlPullParser;
33282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport org.xmlpull.v1.XmlPullParserException;
34282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
35282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport android.graphics.drawable.Drawable;
36282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport android.util.AttributeSet;
37282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport android.util.DisplayMetrics;
38282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport android.util.TypedValue;
39282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport android.view.ViewGroup.LayoutParams;
40282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
41282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport java.io.File;
42282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport java.io.FileInputStream;
43282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport java.io.FileNotFoundException;
44282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport java.io.InputStream;
45282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
46282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski/**
47282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski *
48282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */
49282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskipublic final class BridgeResources extends Resources {
50282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
51282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    private BridgeContext mContext;
52282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    private IProjectCallback mProjectCallback;
53282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    private boolean[] mPlatformResourceFlag = new boolean[1];
54edc4664d60af1f124d05f0a2b6ba58b837630f51Alan Viverette    private TypedValue mTmpValue = new TypedValue();
55282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
56282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    /**
57282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski     * Simpler wrapper around FileInputStream. This is used when the input stream represent
58282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski     * not a normal bitmap but a nine patch.
59282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski     * This is useful when the InputStream is created in a method but used in another that needs
60282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski     * to know whether this is 9-patch or not, such as BitmapFactory.
61282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski     */
62282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    public class NinePatchInputStream extends FileInputStream {
63282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        private boolean mFakeMarkSupport = true;
64282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        public NinePatchInputStream(File file) throws FileNotFoundException {
65282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            super(file);
66282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
67282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
68282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        @Override
69282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        public boolean markSupported() {
70282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            if (mFakeMarkSupport) {
71282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                // this is needed so that BitmapFactory doesn't wrap this in a BufferedInputStream.
72282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                return true;
73282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            }
74282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
75282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            return super.markSupported();
76282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
77282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
78282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        public void disableFakeMarkSupport() {
79282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            // disable fake mark support so that in case codec actually try to use them
80282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            // we don't lie to them.
81282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            mFakeMarkSupport = false;
82282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
83282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
84282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
85282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    /**
86282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski     * This initializes the static field {@link Resources#mSystem} which is used
87282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski     * by methods who get global resources using {@link Resources#getSystem()}.
88282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski     * <p/>
89282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski     * They will end up using our bridge resources.
90282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski     * <p/>
91282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski     * {@link Bridge} calls this method after setting up a new bridge.
92282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski     */
93282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    public static Resources initSystem(BridgeContext context,
94282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            AssetManager assets,
95282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            DisplayMetrics metrics,
96282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            Configuration config,
97282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            IProjectCallback projectCallback) {
98282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        return Resources.mSystem = new BridgeResources(context,
99282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                assets,
100282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                metrics,
101282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                config,
102282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                projectCallback);
103282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
104282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
105282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    /**
106282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski     * Disposes the static {@link Resources#mSystem} to make sure we don't leave objects
107282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski     * around that would prevent us from unloading the library.
108282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski     */
109282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    public static void disposeSystem() {
110282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (Resources.mSystem instanceof BridgeResources) {
111282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            ((BridgeResources)(Resources.mSystem)).mContext = null;
112282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            ((BridgeResources)(Resources.mSystem)).mProjectCallback = null;
113282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
114282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        Resources.mSystem = null;
115282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
116282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
117282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    private BridgeResources(BridgeContext context, AssetManager assets, DisplayMetrics metrics,
118282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            Configuration config, IProjectCallback projectCallback) {
119282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        super(assets, metrics, config);
120282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        mContext = context;
121282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        mProjectCallback = projectCallback;
122282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
123282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
124282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    public BridgeTypedArray newTypeArray(int numEntries, boolean platformFile) {
125282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        return new BridgeTypedArray(this, mContext, numEntries, platformFile);
126282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
127282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
128282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    private Pair<String, ResourceValue> getResourceValue(int id, boolean[] platformResFlag_out) {
129282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        // first get the String related to this id in the framework
130282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        Pair<ResourceType, String> resourceInfo = Bridge.resolveResourceId(id);
131282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
132282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (resourceInfo != null) {
133282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            platformResFlag_out[0] = true;
134282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            String attributeName = resourceInfo.getSecond();
135282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
136282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            return Pair.of(attributeName, mContext.getRenderResources().getFrameworkResource(
137282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    resourceInfo.getFirst(), attributeName));
138282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
139282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
140282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        // didn't find a match in the framework? look in the project.
141282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (mProjectCallback != null) {
142282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            resourceInfo = mProjectCallback.resolveResourceId(id);
143282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
144282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            if (resourceInfo != null) {
145282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                platformResFlag_out[0] = false;
146282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                String attributeName = resourceInfo.getSecond();
147282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
148282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                return Pair.of(attributeName, mContext.getRenderResources().getProjectResource(
149282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                        resourceInfo.getFirst(), attributeName));
150282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            }
151282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
152282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
153282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        return null;
154282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
155282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
156282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    @Override
157282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    public Drawable getDrawable(int id) throws NotFoundException {
1588250a825c39a2f1f63920669cf233db3d8944b51Deepanshu Gupta        return getDrawable(id, null);
1598250a825c39a2f1f63920669cf233db3d8944b51Deepanshu Gupta    }
1608250a825c39a2f1f63920669cf233db3d8944b51Deepanshu Gupta
1618250a825c39a2f1f63920669cf233db3d8944b51Deepanshu Gupta    @Override
1628250a825c39a2f1f63920669cf233db3d8944b51Deepanshu Gupta    public Drawable getDrawable(int id, Theme theme) {
163282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        Pair<String, ResourceValue> value = getResourceValue(id, mPlatformResourceFlag);
164282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
165282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (value != null) {
1664a605c6fa0027ee116beb29fbc9625721f0441f0Deepanshu Gupta            return ResourceHelper.getDrawable(value.getSecond(), mContext, theme);
167282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
168282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
169282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        // id was not found or not resolved. Throw a NotFoundException.
170282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        throwException(id);
171282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
172282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        // this is not used since the method above always throws
173282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        return null;
174282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
175282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
176282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    @Override
177282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    public int getColor(int id) throws NotFoundException {
178282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        Pair<String, ResourceValue> value = getResourceValue(id, mPlatformResourceFlag);
179282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
180282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (value != null) {
181282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            try {
182282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                return ResourceHelper.getColor(value.getSecond().getValue());
183282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            } catch (NumberFormatException e) {
184282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                Bridge.getLog().error(LayoutLog.TAG_RESOURCES_FORMAT, e.getMessage(), e,
185282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                        null /*data*/);
186282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                return 0;
187282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            }
188282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
189282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
190282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        // id was not found or not resolved. Throw a NotFoundException.
191282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        throwException(id);
192282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
193282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        // this is not used since the method above always throws
194282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        return 0;
195282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
196282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
197282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    @Override
198282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    public ColorStateList getColorStateList(int id) throws NotFoundException {
199282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        Pair<String, ResourceValue> resValue = getResourceValue(id, mPlatformResourceFlag);
200282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
201282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (resValue != null) {
202282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            ColorStateList stateList = ResourceHelper.getColorStateList(resValue.getSecond(),
203282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    mContext);
204282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            if (stateList != null) {
205282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                return stateList;
206282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            }
207282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
208282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
209282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        // id was not found or not resolved. Throw a NotFoundException.
210282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        throwException(id);
211282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
212282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        // this is not used since the method above always throws
213282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        return null;
214282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
215282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
216282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    @Override
217282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    public CharSequence getText(int id) throws NotFoundException {
218282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        Pair<String, ResourceValue> value = getResourceValue(id, mPlatformResourceFlag);
219282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
220282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (value != null) {
221282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            ResourceValue resValue = value.getSecond();
222282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
223282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            assert resValue != null;
224282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            if (resValue != null) {
225282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                String v = resValue.getValue();
226282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                if (v != null) {
227282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    return v;
228282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                }
229282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            }
230282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
231282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
232282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        // id was not found or not resolved. Throw a NotFoundException.
233282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        throwException(id);
234282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
235282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        // this is not used since the method above always throws
236282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        return null;
237282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
238282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
239282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    @Override
240282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    public XmlResourceParser getLayout(int id) throws NotFoundException {
241282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        Pair<String, ResourceValue> v = getResourceValue(id, mPlatformResourceFlag);
242282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
243282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (v != null) {
244282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            ResourceValue value = v.getSecond();
245282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            XmlPullParser parser = null;
246282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
247282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            try {
248282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                // check if the current parser can provide us with a custom parser.
249282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                if (mPlatformResourceFlag[0] == false) {
250282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    parser = mProjectCallback.getParser(value);
251282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                }
252282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
253282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                // create a new one manually if needed.
254282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                if (parser == null) {
255282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    File xml = new File(value.getValue());
256282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    if (xml.isFile()) {
257282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                        // we need to create a pull parser around the layout XML file, and then
258282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                        // give that to our XmlBlockParser
259282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                        parser = ParserFactory.create(xml);
260282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    }
261282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                }
262282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
263282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                if (parser != null) {
264282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    return new BridgeXmlBlockParser(parser, mContext, mPlatformResourceFlag[0]);
265282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                }
266282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            } catch (XmlPullParserException e) {
267282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                Bridge.getLog().error(LayoutLog.TAG_BROKEN,
268282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                        "Failed to configure parser for " + value.getValue(), e, null /*data*/);
269282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                // we'll return null below.
270282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            } catch (FileNotFoundException e) {
271282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                // this shouldn't happen since we check above.
272282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            }
273282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
274282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
275282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
276282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        // id was not found or not resolved. Throw a NotFoundException.
277282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        throwException(id);
278282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
279282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        // this is not used since the method above always throws
280282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        return null;
281282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
282282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
283282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    @Override
284282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    public XmlResourceParser getAnimation(int id) throws NotFoundException {
285282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        Pair<String, ResourceValue> v = getResourceValue(id, mPlatformResourceFlag);
286282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
287282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (v != null) {
288282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            ResourceValue value = v.getSecond();
289282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            XmlPullParser parser = null;
290282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
291282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            try {
292282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                File xml = new File(value.getValue());
293282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                if (xml.isFile()) {
294282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    // we need to create a pull parser around the layout XML file, and then
295282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    // give that to our XmlBlockParser
296282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    parser = ParserFactory.create(xml);
297282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
298282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    return new BridgeXmlBlockParser(parser, mContext, mPlatformResourceFlag[0]);
299282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                }
300282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            } catch (XmlPullParserException e) {
301282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                Bridge.getLog().error(LayoutLog.TAG_BROKEN,
302282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                        "Failed to configure parser for " + value.getValue(), e, null /*data*/);
303282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                // we'll return null below.
304282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            } catch (FileNotFoundException e) {
305282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                // this shouldn't happen since we check above.
306282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            }
307282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
308282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
309282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
310282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        // id was not found or not resolved. Throw a NotFoundException.
311282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        throwException(id);
312282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
313282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        // this is not used since the method above always throws
314282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        return null;
315282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
316282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
317282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    @Override
318282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    public TypedArray obtainAttributes(AttributeSet set, int[] attrs) {
319282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        return mContext.obtainStyledAttributes(set, attrs);
320282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
321282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
322282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    @Override
323282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    public TypedArray obtainTypedArray(int id) throws NotFoundException {
324282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        throw new UnsupportedOperationException();
325282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
326282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
327282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
328282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    @Override
329282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    public float getDimension(int id) throws NotFoundException {
330282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        Pair<String, ResourceValue> value = getResourceValue(id, mPlatformResourceFlag);
331282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
332282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (value != null) {
333282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            ResourceValue resValue = value.getSecond();
334282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
335282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            assert resValue != null;
336282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            if (resValue != null) {
337282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                String v = resValue.getValue();
338282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                if (v != null) {
339282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    if (v.equals(BridgeConstants.MATCH_PARENT) ||
340282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                            v.equals(BridgeConstants.FILL_PARENT)) {
341282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                        return LayoutParams.MATCH_PARENT;
342282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    } else if (v.equals(BridgeConstants.WRAP_CONTENT)) {
343282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                        return LayoutParams.WRAP_CONTENT;
344282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    }
345282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
346282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    if (ResourceHelper.parseFloatAttribute(
347282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                            value.getFirst(), v, mTmpValue, true /*requireUnit*/) &&
348282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                            mTmpValue.type == TypedValue.TYPE_DIMENSION) {
349282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                        return mTmpValue.getDimension(getDisplayMetrics());
350282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    }
351282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                }
352282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            }
353282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
354282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
355282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        // id was not found or not resolved. Throw a NotFoundException.
356282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        throwException(id);
357282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
358282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        // this is not used since the method above always throws
359282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        return 0;
360282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
361282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
362282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    @Override
363282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    public int getDimensionPixelOffset(int id) throws NotFoundException {
364282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        Pair<String, ResourceValue> value = getResourceValue(id, mPlatformResourceFlag);
365282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
366282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (value != null) {
367282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            ResourceValue resValue = value.getSecond();
368282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
369282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            assert resValue != null;
370282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            if (resValue != null) {
371282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                String v = resValue.getValue();
372282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                if (v != null) {
373282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    if (ResourceHelper.parseFloatAttribute(
374282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                            value.getFirst(), v, mTmpValue, true /*requireUnit*/) &&
375282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                            mTmpValue.type == TypedValue.TYPE_DIMENSION) {
376282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                        return TypedValue.complexToDimensionPixelOffset(mTmpValue.data,
377282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                                getDisplayMetrics());
378282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    }
379282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                }
380282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            }
381282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
382282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
383282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        // id was not found or not resolved. Throw a NotFoundException.
384282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        throwException(id);
385282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
386282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        // this is not used since the method above always throws
387282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        return 0;
388282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
389282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
390282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    @Override
391282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    public int getDimensionPixelSize(int id) throws NotFoundException {
392282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        Pair<String, ResourceValue> value = getResourceValue(id, mPlatformResourceFlag);
393282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
394282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (value != null) {
395282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            ResourceValue resValue = value.getSecond();
396282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
397282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            assert resValue != null;
398282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            if (resValue != null) {
399282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                String v = resValue.getValue();
400282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                if (v != null) {
401282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    if (ResourceHelper.parseFloatAttribute(
402282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                            value.getFirst(), v, mTmpValue, true /*requireUnit*/) &&
403282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                            mTmpValue.type == TypedValue.TYPE_DIMENSION) {
404282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                        return TypedValue.complexToDimensionPixelSize(mTmpValue.data,
405282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                                getDisplayMetrics());
406282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    }
407282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                }
408282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            }
409282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
410282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
411282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        // id was not found or not resolved. Throw a NotFoundException.
412282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        throwException(id);
413282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
414282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        // this is not used since the method above always throws
415282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        return 0;
416282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
417282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
418282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    @Override
419282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    public int getInteger(int id) throws NotFoundException {
420282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        Pair<String, ResourceValue> value = getResourceValue(id, mPlatformResourceFlag);
421282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
422282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (value != null) {
423282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            ResourceValue resValue = value.getSecond();
424282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
425282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            assert resValue != null;
426282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            if (resValue != null) {
427282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                String v = resValue.getValue();
428282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                if (v != null) {
429282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    int radix = 10;
430282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    if (v.startsWith("0x")) {
431282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                        v = v.substring(2);
432282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                        radix = 16;
433282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    }
434282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    try {
435282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                        return Integer.parseInt(v, radix);
436282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    } catch (NumberFormatException e) {
437282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                        // return exception below
438282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    }
439282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                }
440282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            }
441282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
442282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
443282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        // id was not found or not resolved. Throw a NotFoundException.
444282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        throwException(id);
445282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
446282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        // this is not used since the method above always throws
447282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        return 0;
448282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
449282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
450282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    @Override
451282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    public boolean getBoolean(int id) throws NotFoundException {
452282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        Pair<String, ResourceValue> value = getResourceValue(id, mPlatformResourceFlag);
453282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
454282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (value != null) {
455282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            ResourceValue resValue = value.getSecond();
456282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
457282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            assert resValue != null;
458282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            if (resValue != null) {
459282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                String v = resValue.getValue();
460282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                if (v != null) {
461282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    return Boolean.parseBoolean(v);
462282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                }
463282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            }
464282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
465282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
466282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        // id was not found or not resolved. Throw a NotFoundException.
467282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        throwException(id);
468282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
469282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        // this is not used since the method above always throws
470282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        return false;
471282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
472282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
473282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    @Override
474282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    public String getResourceEntryName(int resid) throws NotFoundException {
475282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        throw new UnsupportedOperationException();
476282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
477282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
478282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    @Override
479282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    public String getResourceName(int resid) throws NotFoundException {
480282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        throw new UnsupportedOperationException();
481282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
482282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
483282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    @Override
484282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    public String getResourceTypeName(int resid) throws NotFoundException {
485282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        throw new UnsupportedOperationException();
486282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
487282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
488282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    @Override
489282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    public String getString(int id, Object... formatArgs) throws NotFoundException {
490282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        String s = getString(id);
491282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (s != null) {
492282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            return String.format(s, formatArgs);
493282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
494282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
495282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
496282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        // id was not found or not resolved. Throw a NotFoundException.
497282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        throwException(id);
498282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
499282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        // this is not used since the method above always throws
500282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        return null;
501282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
502282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
503282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    @Override
504282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    public String getString(int id) throws NotFoundException {
505282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        Pair<String, ResourceValue> value = getResourceValue(id, mPlatformResourceFlag);
506282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
507282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (value != null && value.getSecond().getValue() != null) {
508282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            return value.getSecond().getValue();
509282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
510282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
511282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        // id was not found or not resolved. Throw a NotFoundException.
512282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        throwException(id);
513282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
514282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        // this is not used since the method above always throws
515282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        return null;
516282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
517282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
518282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    @Override
519282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    public void getValue(int id, TypedValue outValue, boolean resolveRefs)
520282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            throws NotFoundException {
521282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        Pair<String, ResourceValue> value = getResourceValue(id, mPlatformResourceFlag);
522282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
523282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (value != null) {
524282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            String v = value.getSecond().getValue();
525282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
526282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            if (v != null) {
527282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                if (ResourceHelper.parseFloatAttribute(value.getFirst(), v, outValue,
528282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                        false /*requireUnit*/)) {
529282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    return;
530282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                }
531282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
532282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                // else it's a string
533282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                outValue.type = TypedValue.TYPE_STRING;
534282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                outValue.string = v;
535282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                return;
536282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            }
537282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
538282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
539282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        // id was not found or not resolved. Throw a NotFoundException.
540282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        throwException(id);
541282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
542282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
543282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    @Override
544282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    public void getValue(String name, TypedValue outValue, boolean resolveRefs)
545282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            throws NotFoundException {
546282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        throw new UnsupportedOperationException();
547282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
548282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
549282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    @Override
550282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    public XmlResourceParser getXml(int id) throws NotFoundException {
551282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        Pair<String, ResourceValue> value = getResourceValue(id, mPlatformResourceFlag);
552282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
553282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (value != null) {
554282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            String v = value.getSecond().getValue();
555282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
556282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            if (v != null) {
557282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                // check this is a file
558282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                File f = new File(v);
559282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                if (f.isFile()) {
560282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    try {
561282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                        XmlPullParser parser = ParserFactory.create(f);
562282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
563282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                        return new BridgeXmlBlockParser(parser, mContext, mPlatformResourceFlag[0]);
564282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    } catch (XmlPullParserException e) {
565282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                        NotFoundException newE = new NotFoundException();
566282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                        newE.initCause(e);
567282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                        throw newE;
568282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    } catch (FileNotFoundException e) {
569282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                        NotFoundException newE = new NotFoundException();
570282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                        newE.initCause(e);
571282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                        throw newE;
572282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    }
573282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                }
574282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            }
575282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
576282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
577282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        // id was not found or not resolved. Throw a NotFoundException.
578282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        throwException(id);
579282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
580282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        // this is not used since the method above always throws
581282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        return null;
582282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
583282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
584282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    @Override
585282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    public XmlResourceParser loadXmlResourceParser(String file, int id,
586282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            int assetCookie, String type) throws NotFoundException {
587282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        // even though we know the XML file to load directly, we still need to resolve the
588282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        // id so that we can know if it's a platform or project resource.
589282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        // (mPlatformResouceFlag will get the result and will be used later).
590282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        getResourceValue(id, mPlatformResourceFlag);
591282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
592282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        File f = new File(file);
593282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        try {
594282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            XmlPullParser parser = ParserFactory.create(f);
595282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
596282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            return new BridgeXmlBlockParser(parser, mContext, mPlatformResourceFlag[0]);
597282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        } catch (XmlPullParserException e) {
598282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            NotFoundException newE = new NotFoundException();
599282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            newE.initCause(e);
600282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            throw newE;
601282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        } catch (FileNotFoundException e) {
602282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            NotFoundException newE = new NotFoundException();
603282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            newE.initCause(e);
604282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            throw newE;
605282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
606282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
607282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
608282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
609282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    @Override
610282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    public InputStream openRawResource(int id) throws NotFoundException {
611282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        Pair<String, ResourceValue> value = getResourceValue(id, mPlatformResourceFlag);
612282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
613282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (value != null) {
614282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            String path = value.getSecond().getValue();
615282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
616282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            if (path != null) {
617282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                // check this is a file
618282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                File f = new File(path);
619282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                if (f.isFile()) {
620282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    try {
621282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                        // if it's a nine-patch return a custom input stream so that
622282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                        // other methods (mainly bitmap factory) can detect it's a 9-patch
623282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                        // and actually load it as a 9-patch instead of a normal bitmap
624282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                        if (path.toLowerCase().endsWith(NinePatch.EXTENSION_9PATCH)) {
625282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                            return new NinePatchInputStream(f);
626282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                        }
627282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                        return new FileInputStream(f);
628282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    } catch (FileNotFoundException e) {
629282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                        NotFoundException newE = new NotFoundException();
630282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                        newE.initCause(e);
631282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                        throw newE;
632282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    }
633282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                }
634282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            }
635282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
636282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
637282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        // id was not found or not resolved. Throw a NotFoundException.
638282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        throwException(id);
639282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
640282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        // this is not used since the method above always throws
641282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        return null;
642282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
643282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
644282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    @Override
645282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    public InputStream openRawResource(int id, TypedValue value) throws NotFoundException {
646282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        getValue(id, value, true);
647282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
648282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        String path = value.string.toString();
649282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
650282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        File f = new File(path);
651282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (f.isFile()) {
652282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            try {
653282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                // if it's a nine-patch return a custom input stream so that
654282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                // other methods (mainly bitmap factory) can detect it's a 9-patch
655282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                // and actually load it as a 9-patch instead of a normal bitmap
656282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                if (path.toLowerCase().endsWith(NinePatch.EXTENSION_9PATCH)) {
657282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    return new NinePatchInputStream(f);
658282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                }
659282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                return new FileInputStream(f);
660282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            } catch (FileNotFoundException e) {
661282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                NotFoundException exception = new NotFoundException();
662282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                exception.initCause(e);
663282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                throw exception;
664282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            }
665282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
666282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
667282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        throw new NotFoundException();
668282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
669282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
670282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    @Override
671282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    public AssetFileDescriptor openRawResourceFd(int id) throws NotFoundException {
672282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        throw new UnsupportedOperationException();
673282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
674282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
675282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    /**
676282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski     * Builds and throws a {@link Resources.NotFoundException} based on a resource id and a resource type.
677282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski     * @param id the id of the resource
678282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski     * @throws NotFoundException
679282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski     */
680282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    private void throwException(int id) throws NotFoundException {
681282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        // first get the String related to this id in the framework
682282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        Pair<ResourceType, String> resourceInfo = Bridge.resolveResourceId(id);
683282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
684282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        // if the name is unknown in the framework, get it from the custom view loader.
685282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (resourceInfo == null && mProjectCallback != null) {
686282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            resourceInfo = mProjectCallback.resolveResourceId(id);
687282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
688282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
689282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        String message = null;
690282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (resourceInfo != null) {
691282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            message = String.format(
692282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    "Could not find %1$s resource matching value 0x%2$X (resolved name: %3$s) in current configuration.",
693282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    resourceInfo.getFirst(), id, resourceInfo.getSecond());
694282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        } else {
695282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            message = String.format(
696282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    "Could not resolve resource value: 0x%1$X.", id);
697282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
698282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
699282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        throw new NotFoundException(message);
700282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
701282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}
702