1282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski/*
2e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta * Copyright (C) 2016 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
19642cff50f8f7a67eed09eac1e56d7133b26a192cDeepanshu Guptaimport com.android.SdkConstants;
20642cff50f8f7a67eed09eac1e56d7133b26a192cDeepanshu Guptaimport com.android.ide.common.rendering.api.ArrayResourceValue;
21e5d3baf22f046d0a579128fc258f6b92e700ca02Deepanshu Guptaimport com.android.ide.common.rendering.api.DensityBasedResourceValue;
22282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport com.android.ide.common.rendering.api.LayoutLog;
2337dbb8b7f3c069196040eed3a03006647db7fa5bDeepanshu Guptaimport com.android.ide.common.rendering.api.LayoutlibCallback;
24618ca261f370c257723a3c7a5871bb6f6b4d7f3aDeepanshu Guptaimport com.android.ide.common.rendering.api.RenderResources;
25282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport com.android.ide.common.rendering.api.ResourceValue;
26282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport com.android.layoutlib.bridge.Bridge;
27282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport com.android.layoutlib.bridge.BridgeConstants;
28282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport com.android.layoutlib.bridge.android.BridgeContext;
29282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport com.android.layoutlib.bridge.android.BridgeXmlBlockParser;
30282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport com.android.layoutlib.bridge.impl.ParserFactory;
31282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport com.android.layoutlib.bridge.impl.ResourceHelper;
32e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Guptaimport com.android.layoutlib.bridge.util.NinePatchInputStream;
33282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport com.android.ninepatch.NinePatch;
34282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport com.android.resources.ResourceType;
35e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Guptaimport com.android.tools.layoutlib.annotations.LayoutlibDelegate;
36282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport com.android.util.Pair;
37282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
38282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport org.xmlpull.v1.XmlPullParser;
39282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport org.xmlpull.v1.XmlPullParserException;
40282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
41642cff50f8f7a67eed09eac1e56d7133b26a192cDeepanshu Guptaimport android.annotation.NonNull;
42642cff50f8f7a67eed09eac1e56d7133b26a192cDeepanshu Guptaimport android.annotation.Nullable;
43e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Guptaimport android.content.res.Resources.NotFoundException;
44e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Guptaimport android.content.res.Resources.Theme;
45282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport android.graphics.drawable.Drawable;
46282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport android.util.AttributeSet;
47282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport android.util.DisplayMetrics;
48282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport android.util.TypedValue;
49282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport android.view.ViewGroup.LayoutParams;
50282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
51282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport java.io.File;
52282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport java.io.FileInputStream;
53282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport java.io.FileNotFoundException;
54282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiimport java.io.InputStream;
55642cff50f8f7a67eed09eac1e56d7133b26a192cDeepanshu Guptaimport java.util.Iterator;
56282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
57491523d52cd8368ef9a92e95fb3e9332bf86a996Deepanshu Gupta@SuppressWarnings("deprecation")
58e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Guptapublic class Resources_Delegate {
59282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
60e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta    private static boolean[] mPlatformResourceFlag = new boolean[1];
61282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
62282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    public static Resources initSystem(BridgeContext context,
63282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            AssetManager assets,
64282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            DisplayMetrics metrics,
65282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            Configuration config,
6637dbb8b7f3c069196040eed3a03006647db7fa5bDeepanshu Gupta            LayoutlibCallback layoutlibCallback) {
67e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta        Resources resources = new Resources(assets, metrics, config);
68e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta        resources.mContext = context;
69e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta        resources.mLayoutlibCallback = layoutlibCallback;
70e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta        return Resources.mSystem = resources;
71282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
72282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
73282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    /**
74e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta     * Disposes the static {@link Resources#mSystem} to make sure we don't leave objects around that
75e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta     * would prevent us from unloading the library.
76282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski     */
77282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    public static void disposeSystem() {
78e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta        Resources.mSystem.mContext = null;
79e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta        Resources.mSystem.mLayoutlibCallback = null;
80282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        Resources.mSystem = null;
81282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
82282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
83e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta    public static BridgeTypedArray newTypeArray(Resources resources, int numEntries,
84e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta            boolean platformFile) {
85e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta        return new BridgeTypedArray(resources, resources.mContext, numEntries, platformFile);
86282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
87282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
88618ca261f370c257723a3c7a5871bb6f6b4d7f3aDeepanshu Gupta    private static Pair<ResourceType, String> getResourceInfo(Resources resources, int id,
89e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta            boolean[] platformResFlag_out) {
90282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        // first get the String related to this id in the framework
91282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        Pair<ResourceType, String> resourceInfo = Bridge.resolveResourceId(id);
92282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
93e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta        // Set the layoutlib callback and context for resources
94e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta        if (resources != Resources.mSystem && resources.mLayoutlibCallback == null) {
95e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta            resources.mLayoutlibCallback = Resources.mSystem.mLayoutlibCallback;
96e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta            resources.mContext = Resources.mSystem.mContext;
97e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta        }
98e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta
99282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (resourceInfo != null) {
100282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            platformResFlag_out[0] = true;
101618ca261f370c257723a3c7a5871bb6f6b4d7f3aDeepanshu Gupta            return resourceInfo;
102282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
103282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
104282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        // didn't find a match in the framework? look in the project.
105e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta        if (resources.mLayoutlibCallback != null) {
106e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta            resourceInfo = resources.mLayoutlibCallback.resolveResourceId(id);
107282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
108282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            if (resourceInfo != null) {
109282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                platformResFlag_out[0] = false;
110618ca261f370c257723a3c7a5871bb6f6b4d7f3aDeepanshu Gupta                return resourceInfo;
111282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            }
112282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
113618ca261f370c257723a3c7a5871bb6f6b4d7f3aDeepanshu Gupta        return null;
114618ca261f370c257723a3c7a5871bb6f6b4d7f3aDeepanshu Gupta    }
115618ca261f370c257723a3c7a5871bb6f6b4d7f3aDeepanshu Gupta
116618ca261f370c257723a3c7a5871bb6f6b4d7f3aDeepanshu Gupta    private static Pair<String, ResourceValue> getResourceValue(Resources resources, int id,
117618ca261f370c257723a3c7a5871bb6f6b4d7f3aDeepanshu Gupta            boolean[] platformResFlag_out) {
118618ca261f370c257723a3c7a5871bb6f6b4d7f3aDeepanshu Gupta        Pair<ResourceType, String> resourceInfo =
119618ca261f370c257723a3c7a5871bb6f6b4d7f3aDeepanshu Gupta                getResourceInfo(resources, id, platformResFlag_out);
120618ca261f370c257723a3c7a5871bb6f6b4d7f3aDeepanshu Gupta
121618ca261f370c257723a3c7a5871bb6f6b4d7f3aDeepanshu Gupta        if (resourceInfo != null) {
122618ca261f370c257723a3c7a5871bb6f6b4d7f3aDeepanshu Gupta            String attributeName = resourceInfo.getSecond();
123618ca261f370c257723a3c7a5871bb6f6b4d7f3aDeepanshu Gupta            RenderResources renderResources = resources.mContext.getRenderResources();
124618ca261f370c257723a3c7a5871bb6f6b4d7f3aDeepanshu Gupta            return Pair.of(attributeName, platformResFlag_out[0] ?
125618ca261f370c257723a3c7a5871bb6f6b4d7f3aDeepanshu Gupta                    renderResources.getFrameworkResource(resourceInfo.getFirst(), attributeName) :
126618ca261f370c257723a3c7a5871bb6f6b4d7f3aDeepanshu Gupta                    renderResources.getProjectResource(resourceInfo.getFirst(), attributeName));
127618ca261f370c257723a3c7a5871bb6f6b4d7f3aDeepanshu Gupta        }
128282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
129282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        return null;
130282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
131282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
132e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta    @LayoutlibDelegate
133e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta    static Drawable getDrawable(Resources resources, int id) {
134e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta        return getDrawable(resources, id, null);
135e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta    }
136e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta
137e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta    @LayoutlibDelegate
138e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta    static Drawable getDrawable(Resources resources, int id, Theme theme) {
139e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta        Pair<String, ResourceValue> value = getResourceValue(resources, id, mPlatformResourceFlag);
140282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
141282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (value != null) {
142e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta            return ResourceHelper.getDrawable(value.getSecond(), resources.mContext, theme);
143282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
144282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
145282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        // id was not found or not resolved. Throw a NotFoundException.
146e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta        throwException(resources, id);
147282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
148282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        // this is not used since the method above always throws
149282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        return null;
150282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
151282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
152e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta    @LayoutlibDelegate
153e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta    static int getColor(Resources resources, int id) {
154e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta        return getColor(resources, id, null);
155e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta    }
156e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta
157e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta    @LayoutlibDelegate
158e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta    static int getColor(Resources resources, int id, Theme theme) throws NotFoundException {
159e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta        Pair<String, ResourceValue> value = getResourceValue(resources, id, mPlatformResourceFlag);
160282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
161282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (value != null) {
16268501b87d2891ae9bf65d400f9cd755e197fda0cDeepanshu Gupta            ResourceValue resourceValue = value.getSecond();
163282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            try {
16468501b87d2891ae9bf65d400f9cd755e197fda0cDeepanshu Gupta                return ResourceHelper.getColor(resourceValue.getValue());
165282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            } catch (NumberFormatException e) {
16668501b87d2891ae9bf65d400f9cd755e197fda0cDeepanshu Gupta                // Check if the value passed is a file. If it is, mostly likely, user is referencing
16768501b87d2891ae9bf65d400f9cd755e197fda0cDeepanshu Gupta                // a color state list from a place where they should reference only a pure color.
16868501b87d2891ae9bf65d400f9cd755e197fda0cDeepanshu Gupta                String message;
16968501b87d2891ae9bf65d400f9cd755e197fda0cDeepanshu Gupta                if (new File(resourceValue.getValue()).isFile()) {
17068501b87d2891ae9bf65d400f9cd755e197fda0cDeepanshu Gupta                    String resource = (resourceValue.isFramework() ? "@android:" : "@") + "color/"
171e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta                            + resourceValue.getName();
17268501b87d2891ae9bf65d400f9cd755e197fda0cDeepanshu Gupta                    message = "Hexadecimal color expected, found Color State List for " + resource;
17368501b87d2891ae9bf65d400f9cd755e197fda0cDeepanshu Gupta                } else {
17468501b87d2891ae9bf65d400f9cd755e197fda0cDeepanshu Gupta                    message = e.getMessage();
17568501b87d2891ae9bf65d400f9cd755e197fda0cDeepanshu Gupta                }
17668501b87d2891ae9bf65d400f9cd755e197fda0cDeepanshu Gupta                Bridge.getLog().error(LayoutLog.TAG_RESOURCES_FORMAT, message, e, null);
177282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                return 0;
178282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            }
179282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
180282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
1814d8e078c7c9c9f8407ebc7e88673e53b67723e18Deepanshu Gupta        // Suppress possible NPE. getColorStateList will never return null, it will instead
1824d8e078c7c9c9f8407ebc7e88673e53b67723e18Deepanshu Gupta        // throw an exception, but intelliJ can't figure that out
1834d8e078c7c9c9f8407ebc7e88673e53b67723e18Deepanshu Gupta        //noinspection ConstantConditions
184e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta        return getColorStateList(resources, id, theme).getDefaultColor();
185282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
186282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
187e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta    @LayoutlibDelegate
188e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta    static ColorStateList getColorStateList(Resources resources, int id) throws NotFoundException {
189e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta        return getColorStateList(resources, id, null);
190e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta    }
191e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta
192e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta    @LayoutlibDelegate
193e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta    static ColorStateList getColorStateList(Resources resources, int id, Theme theme)
194e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta            throws NotFoundException {
195e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta        Pair<String, ResourceValue> resValue =
196e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta                getResourceValue(resources, id, mPlatformResourceFlag);
197282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
198282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (resValue != null) {
199282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            ColorStateList stateList = ResourceHelper.getColorStateList(resValue.getSecond(),
200e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta                    resources.mContext);
201282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            if (stateList != null) {
2024d8e078c7c9c9f8407ebc7e88673e53b67723e18Deepanshu Gupta                return stateList.obtainForTheme(theme);
203282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            }
204282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
205282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
206282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        // id was not found or not resolved. Throw a NotFoundException.
207e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta        throwException(resources, id);
208282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
209282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        // this is not used since the method above always throws
210282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        return null;
211282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
212282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
213e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta    @LayoutlibDelegate
214e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta    static CharSequence getText(Resources resources, int id, CharSequence def) {
215e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta        Pair<String, ResourceValue> value = getResourceValue(resources, id, mPlatformResourceFlag);
216e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta
217e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta        if (value != null) {
218e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta            ResourceValue resValue = value.getSecond();
219e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta
220e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta            assert resValue != null;
221e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta            if (resValue != null) {
222e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta                String v = resValue.getValue();
223e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta                if (v != null) {
224e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta                    return v;
225e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta                }
226e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta            }
227e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta        }
228e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta
229e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta        return def;
230e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta    }
231e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta
232e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta    @LayoutlibDelegate
233e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta    static CharSequence getText(Resources resources, int id) throws NotFoundException {
234e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta        Pair<String, ResourceValue> value = getResourceValue(resources, id, mPlatformResourceFlag);
235282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
236282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (value != null) {
237282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            ResourceValue resValue = value.getSecond();
238282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
239282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            assert resValue != null;
240282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            if (resValue != null) {
241282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                String v = resValue.getValue();
242282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                if (v != null) {
243282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    return v;
244282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                }
245282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            }
246282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
247282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
248282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        // id was not found or not resolved. Throw a NotFoundException.
249e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta        throwException(resources, id);
250282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
251282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        // this is not used since the method above always throws
252282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        return null;
253282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
254282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
255e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta    @LayoutlibDelegate
256e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta    static CharSequence[] getTextArray(Resources resources, int id) throws NotFoundException {
257e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta        ResourceValue resValue = getArrayResourceValue(resources, id);
258642cff50f8f7a67eed09eac1e56d7133b26a192cDeepanshu Gupta        if (resValue == null) {
259642cff50f8f7a67eed09eac1e56d7133b26a192cDeepanshu Gupta            // Error already logged by getArrayResourceValue.
260642cff50f8f7a67eed09eac1e56d7133b26a192cDeepanshu Gupta            return new CharSequence[0];
261642cff50f8f7a67eed09eac1e56d7133b26a192cDeepanshu Gupta        } else if (!(resValue instanceof ArrayResourceValue)) {
262642cff50f8f7a67eed09eac1e56d7133b26a192cDeepanshu Gupta            return new CharSequence[]{
263e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta                    resolveReference(resources, resValue.getValue(), resValue.isFramework())};
264642cff50f8f7a67eed09eac1e56d7133b26a192cDeepanshu Gupta        }
265642cff50f8f7a67eed09eac1e56d7133b26a192cDeepanshu Gupta        ArrayResourceValue arv = ((ArrayResourceValue) resValue);
266e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta        return fillValues(resources, arv, new CharSequence[arv.getElementCount()]);
267642cff50f8f7a67eed09eac1e56d7133b26a192cDeepanshu Gupta    }
268642cff50f8f7a67eed09eac1e56d7133b26a192cDeepanshu Gupta
269e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta    @LayoutlibDelegate
270e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta    static String[] getStringArray(Resources resources, int id) throws NotFoundException {
271e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta        ResourceValue resValue = getArrayResourceValue(resources, id);
272642cff50f8f7a67eed09eac1e56d7133b26a192cDeepanshu Gupta        if (resValue == null) {
273642cff50f8f7a67eed09eac1e56d7133b26a192cDeepanshu Gupta            // Error already logged by getArrayResourceValue.
274642cff50f8f7a67eed09eac1e56d7133b26a192cDeepanshu Gupta            return new String[0];
275642cff50f8f7a67eed09eac1e56d7133b26a192cDeepanshu Gupta        } else if (!(resValue instanceof ArrayResourceValue)) {
276642cff50f8f7a67eed09eac1e56d7133b26a192cDeepanshu Gupta            return new String[]{
277e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta                    resolveReference(resources, resValue.getValue(), resValue.isFramework())};
278642cff50f8f7a67eed09eac1e56d7133b26a192cDeepanshu Gupta        }
279642cff50f8f7a67eed09eac1e56d7133b26a192cDeepanshu Gupta        ArrayResourceValue arv = ((ArrayResourceValue) resValue);
280e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta        return fillValues(resources, arv, new String[arv.getElementCount()]);
281642cff50f8f7a67eed09eac1e56d7133b26a192cDeepanshu Gupta    }
282642cff50f8f7a67eed09eac1e56d7133b26a192cDeepanshu Gupta
283642cff50f8f7a67eed09eac1e56d7133b26a192cDeepanshu Gupta    /**
284642cff50f8f7a67eed09eac1e56d7133b26a192cDeepanshu Gupta     * Resolve each element in resValue and copy them to {@code values}. The values copied are
285642cff50f8f7a67eed09eac1e56d7133b26a192cDeepanshu Gupta     * always Strings. The ideal signature for the method should be &lt;T super String&gt;, but java
286642cff50f8f7a67eed09eac1e56d7133b26a192cDeepanshu Gupta     * generics don't support it.
287642cff50f8f7a67eed09eac1e56d7133b26a192cDeepanshu Gupta     */
288e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta    static <T extends CharSequence> T[] fillValues(Resources resources, ArrayResourceValue resValue,
289e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta            T[] values) {
290642cff50f8f7a67eed09eac1e56d7133b26a192cDeepanshu Gupta        int i = 0;
291642cff50f8f7a67eed09eac1e56d7133b26a192cDeepanshu Gupta        for (Iterator<String> iterator = resValue.iterator(); iterator.hasNext(); i++) {
292642cff50f8f7a67eed09eac1e56d7133b26a192cDeepanshu Gupta            @SuppressWarnings("unchecked")
293e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta            T s = (T) resolveReference(resources, iterator.next(), resValue.isFramework());
294642cff50f8f7a67eed09eac1e56d7133b26a192cDeepanshu Gupta            values[i] = s;
295642cff50f8f7a67eed09eac1e56d7133b26a192cDeepanshu Gupta        }
296642cff50f8f7a67eed09eac1e56d7133b26a192cDeepanshu Gupta        return values;
297642cff50f8f7a67eed09eac1e56d7133b26a192cDeepanshu Gupta    }
298642cff50f8f7a67eed09eac1e56d7133b26a192cDeepanshu Gupta
299e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta    @LayoutlibDelegate
300e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta    static int[] getIntArray(Resources resources, int id) throws NotFoundException {
301e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta        ResourceValue rv = getArrayResourceValue(resources, id);
302642cff50f8f7a67eed09eac1e56d7133b26a192cDeepanshu Gupta        if (rv == null) {
303642cff50f8f7a67eed09eac1e56d7133b26a192cDeepanshu Gupta            // Error already logged by getArrayResourceValue.
304642cff50f8f7a67eed09eac1e56d7133b26a192cDeepanshu Gupta            return new int[0];
305642cff50f8f7a67eed09eac1e56d7133b26a192cDeepanshu Gupta        } else if (!(rv instanceof ArrayResourceValue)) {
306642cff50f8f7a67eed09eac1e56d7133b26a192cDeepanshu Gupta            // This is an older IDE that can only give us the first element of the array.
307e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta            String firstValue = resolveReference(resources, rv.getValue(), rv.isFramework());
308642cff50f8f7a67eed09eac1e56d7133b26a192cDeepanshu Gupta            try {
309642cff50f8f7a67eed09eac1e56d7133b26a192cDeepanshu Gupta                return new int[]{getInt(firstValue)};
310642cff50f8f7a67eed09eac1e56d7133b26a192cDeepanshu Gupta            } catch (NumberFormatException e) {
311642cff50f8f7a67eed09eac1e56d7133b26a192cDeepanshu Gupta                Bridge.getLog().error(LayoutLog.TAG_RESOURCES_FORMAT,
312642cff50f8f7a67eed09eac1e56d7133b26a192cDeepanshu Gupta                        "Integer resource array contains non-integer value: " +
313642cff50f8f7a67eed09eac1e56d7133b26a192cDeepanshu Gupta                                firstValue, null);
314642cff50f8f7a67eed09eac1e56d7133b26a192cDeepanshu Gupta                return new int[1];
315642cff50f8f7a67eed09eac1e56d7133b26a192cDeepanshu Gupta            }
316642cff50f8f7a67eed09eac1e56d7133b26a192cDeepanshu Gupta        }
317642cff50f8f7a67eed09eac1e56d7133b26a192cDeepanshu Gupta        ArrayResourceValue resValue = ((ArrayResourceValue) rv);
318642cff50f8f7a67eed09eac1e56d7133b26a192cDeepanshu Gupta        int[] values = new int[resValue.getElementCount()];
319642cff50f8f7a67eed09eac1e56d7133b26a192cDeepanshu Gupta        int i = 0;
320642cff50f8f7a67eed09eac1e56d7133b26a192cDeepanshu Gupta        for (Iterator<String> iterator = resValue.iterator(); iterator.hasNext(); i++) {
321e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta            String element = resolveReference(resources, iterator.next(), resValue.isFramework());
322642cff50f8f7a67eed09eac1e56d7133b26a192cDeepanshu Gupta            try {
323642cff50f8f7a67eed09eac1e56d7133b26a192cDeepanshu Gupta                values[i] = getInt(element);
324642cff50f8f7a67eed09eac1e56d7133b26a192cDeepanshu Gupta            } catch (NumberFormatException e) {
325642cff50f8f7a67eed09eac1e56d7133b26a192cDeepanshu Gupta                Bridge.getLog().error(LayoutLog.TAG_RESOURCES_FORMAT,
326642cff50f8f7a67eed09eac1e56d7133b26a192cDeepanshu Gupta                        "Integer resource array contains non-integer value: " + element, null);
327642cff50f8f7a67eed09eac1e56d7133b26a192cDeepanshu Gupta            }
328642cff50f8f7a67eed09eac1e56d7133b26a192cDeepanshu Gupta        }
329642cff50f8f7a67eed09eac1e56d7133b26a192cDeepanshu Gupta        return values;
330642cff50f8f7a67eed09eac1e56d7133b26a192cDeepanshu Gupta    }
331642cff50f8f7a67eed09eac1e56d7133b26a192cDeepanshu Gupta
332642cff50f8f7a67eed09eac1e56d7133b26a192cDeepanshu Gupta    /**
333642cff50f8f7a67eed09eac1e56d7133b26a192cDeepanshu Gupta     * Try to find the ArrayResourceValue for the given id.
334642cff50f8f7a67eed09eac1e56d7133b26a192cDeepanshu Gupta     * <p/>
335642cff50f8f7a67eed09eac1e56d7133b26a192cDeepanshu Gupta     * If the ResourceValue found is not of type {@link ResourceType#ARRAY}, the method logs an
336642cff50f8f7a67eed09eac1e56d7133b26a192cDeepanshu Gupta     * error and return null. However, if the ResourceValue found has type {@code
337642cff50f8f7a67eed09eac1e56d7133b26a192cDeepanshu Gupta     * ResourceType.ARRAY}, but the value is not an instance of {@link ArrayResourceValue}, the
338642cff50f8f7a67eed09eac1e56d7133b26a192cDeepanshu Gupta     * method returns the ResourceValue. This happens on older versions of the IDE, which did not
339642cff50f8f7a67eed09eac1e56d7133b26a192cDeepanshu Gupta     * parse the array resources properly.
340642cff50f8f7a67eed09eac1e56d7133b26a192cDeepanshu Gupta     * <p/>
341e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta     *
342642cff50f8f7a67eed09eac1e56d7133b26a192cDeepanshu Gupta     * @throws NotFoundException if no resource if found
343642cff50f8f7a67eed09eac1e56d7133b26a192cDeepanshu Gupta     */
344642cff50f8f7a67eed09eac1e56d7133b26a192cDeepanshu Gupta    @Nullable
345e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta    private static ResourceValue getArrayResourceValue(Resources resources, int id)
346e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta            throws NotFoundException {
347e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta        Pair<String, ResourceValue> v = getResourceValue(resources, id, mPlatformResourceFlag);
348642cff50f8f7a67eed09eac1e56d7133b26a192cDeepanshu Gupta
349642cff50f8f7a67eed09eac1e56d7133b26a192cDeepanshu Gupta        if (v != null) {
350642cff50f8f7a67eed09eac1e56d7133b26a192cDeepanshu Gupta            ResourceValue resValue = v.getSecond();
351642cff50f8f7a67eed09eac1e56d7133b26a192cDeepanshu Gupta
352642cff50f8f7a67eed09eac1e56d7133b26a192cDeepanshu Gupta            assert resValue != null;
353642cff50f8f7a67eed09eac1e56d7133b26a192cDeepanshu Gupta            if (resValue != null) {
354642cff50f8f7a67eed09eac1e56d7133b26a192cDeepanshu Gupta                final ResourceType type = resValue.getResourceType();
355642cff50f8f7a67eed09eac1e56d7133b26a192cDeepanshu Gupta                if (type != ResourceType.ARRAY) {
356642cff50f8f7a67eed09eac1e56d7133b26a192cDeepanshu Gupta                    Bridge.getLog().error(LayoutLog.TAG_RESOURCES_RESOLVE,
357642cff50f8f7a67eed09eac1e56d7133b26a192cDeepanshu Gupta                            String.format(
358642cff50f8f7a67eed09eac1e56d7133b26a192cDeepanshu Gupta                                    "Resource with id 0x%1$X is not an array resource, but %2$s",
359642cff50f8f7a67eed09eac1e56d7133b26a192cDeepanshu Gupta                                    id, type == null ? "null" : type.getDisplayName()),
360642cff50f8f7a67eed09eac1e56d7133b26a192cDeepanshu Gupta                            null);
361642cff50f8f7a67eed09eac1e56d7133b26a192cDeepanshu Gupta                    return null;
362642cff50f8f7a67eed09eac1e56d7133b26a192cDeepanshu Gupta                }
363642cff50f8f7a67eed09eac1e56d7133b26a192cDeepanshu Gupta                if (!(resValue instanceof ArrayResourceValue)) {
364642cff50f8f7a67eed09eac1e56d7133b26a192cDeepanshu Gupta                    Bridge.getLog().warning(LayoutLog.TAG_UNSUPPORTED,
365642cff50f8f7a67eed09eac1e56d7133b26a192cDeepanshu Gupta                            "Obtaining resource arrays via getTextArray, getStringArray or getIntArray is not fully supported in this version of the IDE.",
366642cff50f8f7a67eed09eac1e56d7133b26a192cDeepanshu Gupta                            null);
367642cff50f8f7a67eed09eac1e56d7133b26a192cDeepanshu Gupta                }
368642cff50f8f7a67eed09eac1e56d7133b26a192cDeepanshu Gupta                return resValue;
369642cff50f8f7a67eed09eac1e56d7133b26a192cDeepanshu Gupta            }
370642cff50f8f7a67eed09eac1e56d7133b26a192cDeepanshu Gupta        }
371642cff50f8f7a67eed09eac1e56d7133b26a192cDeepanshu Gupta
372642cff50f8f7a67eed09eac1e56d7133b26a192cDeepanshu Gupta        // id was not found or not resolved. Throw a NotFoundException.
373e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta        throwException(resources, id);
374642cff50f8f7a67eed09eac1e56d7133b26a192cDeepanshu Gupta
375642cff50f8f7a67eed09eac1e56d7133b26a192cDeepanshu Gupta        // this is not used since the method above always throws
376642cff50f8f7a67eed09eac1e56d7133b26a192cDeepanshu Gupta        return null;
377642cff50f8f7a67eed09eac1e56d7133b26a192cDeepanshu Gupta    }
378642cff50f8f7a67eed09eac1e56d7133b26a192cDeepanshu Gupta
379642cff50f8f7a67eed09eac1e56d7133b26a192cDeepanshu Gupta    @NonNull
380e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta    private static String resolveReference(Resources resources, @NonNull String ref,
381e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta            boolean forceFrameworkOnly) {
382642cff50f8f7a67eed09eac1e56d7133b26a192cDeepanshu Gupta        if (ref.startsWith(SdkConstants.PREFIX_RESOURCE_REF) || ref.startsWith
383642cff50f8f7a67eed09eac1e56d7133b26a192cDeepanshu Gupta                (SdkConstants.PREFIX_THEME_REF)) {
384642cff50f8f7a67eed09eac1e56d7133b26a192cDeepanshu Gupta            ResourceValue rv =
385e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta                    resources.mContext.getRenderResources().findResValue(ref, forceFrameworkOnly);
386e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta            rv = resources.mContext.getRenderResources().resolveResValue(rv);
387642cff50f8f7a67eed09eac1e56d7133b26a192cDeepanshu Gupta            if (rv != null) {
388642cff50f8f7a67eed09eac1e56d7133b26a192cDeepanshu Gupta                return rv.getValue();
389642cff50f8f7a67eed09eac1e56d7133b26a192cDeepanshu Gupta            } else {
390642cff50f8f7a67eed09eac1e56d7133b26a192cDeepanshu Gupta                Bridge.getLog().error(LayoutLog.TAG_RESOURCES_RESOLVE,
391642cff50f8f7a67eed09eac1e56d7133b26a192cDeepanshu Gupta                        "Unable to resolve resource " + ref, null);
392642cff50f8f7a67eed09eac1e56d7133b26a192cDeepanshu Gupta            }
393642cff50f8f7a67eed09eac1e56d7133b26a192cDeepanshu Gupta        }
394642cff50f8f7a67eed09eac1e56d7133b26a192cDeepanshu Gupta        // Not a reference.
395642cff50f8f7a67eed09eac1e56d7133b26a192cDeepanshu Gupta        return ref;
396642cff50f8f7a67eed09eac1e56d7133b26a192cDeepanshu Gupta    }
397642cff50f8f7a67eed09eac1e56d7133b26a192cDeepanshu Gupta
398e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta    @LayoutlibDelegate
399e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta    static XmlResourceParser getLayout(Resources resources, int id) throws NotFoundException {
400e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta        Pair<String, ResourceValue> v = getResourceValue(resources, id, mPlatformResourceFlag);
401282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
402282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (v != null) {
403282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            ResourceValue value = v.getSecond();
404282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            XmlPullParser parser = null;
405282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
406282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            try {
407282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                // check if the current parser can provide us with a custom parser.
408e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta                if (!mPlatformResourceFlag[0]) {
409e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta                    parser = resources.mLayoutlibCallback.getParser(value);
410282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                }
411282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
412282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                // create a new one manually if needed.
413282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                if (parser == null) {
414282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    File xml = new File(value.getValue());
415282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    if (xml.isFile()) {
416282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                        // we need to create a pull parser around the layout XML file, and then
417282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                        // give that to our XmlBlockParser
418e91096c03dda225240b1487f019bf3d082854587Deepanshu Gupta                        parser = ParserFactory.create(xml, true);
419282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    }
420282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                }
421282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
422282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                if (parser != null) {
423e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta                    return new BridgeXmlBlockParser(parser, resources.mContext,
424e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta                            mPlatformResourceFlag[0]);
425282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                }
426282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            } catch (XmlPullParserException e) {
427282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                Bridge.getLog().error(LayoutLog.TAG_BROKEN,
428282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                        "Failed to configure parser for " + value.getValue(), e, null /*data*/);
429282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                // we'll return null below.
430282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            } catch (FileNotFoundException e) {
431282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                // this shouldn't happen since we check above.
432282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            }
433282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
434282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
435282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
436282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        // id was not found or not resolved. Throw a NotFoundException.
437e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta        throwException(resources, id);
438282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
439282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        // this is not used since the method above always throws
440282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        return null;
441282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
442282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
443e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta    @LayoutlibDelegate
444e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta    static XmlResourceParser getAnimation(Resources resources, int id) throws NotFoundException {
445e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta        Pair<String, ResourceValue> v = getResourceValue(resources, id, mPlatformResourceFlag);
446282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
447282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (v != null) {
448282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            ResourceValue value = v.getSecond();
449e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta            XmlPullParser parser;
450282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
451282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            try {
452282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                File xml = new File(value.getValue());
453282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                if (xml.isFile()) {
454282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    // we need to create a pull parser around the layout XML file, and then
455282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    // give that to our XmlBlockParser
456282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    parser = ParserFactory.create(xml);
457282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
458e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta                    return new BridgeXmlBlockParser(parser, resources.mContext,
459e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta                            mPlatformResourceFlag[0]);
460282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                }
461282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            } catch (XmlPullParserException e) {
462282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                Bridge.getLog().error(LayoutLog.TAG_BROKEN,
463282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                        "Failed to configure parser for " + value.getValue(), e, null /*data*/);
464282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                // we'll return null below.
465282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            } catch (FileNotFoundException e) {
466282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                // this shouldn't happen since we check above.
467282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            }
468282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
469282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
470282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
471282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        // id was not found or not resolved. Throw a NotFoundException.
472e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta        throwException(resources, id);
473282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
474282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        // this is not used since the method above always throws
475282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        return null;
476282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
477282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
478e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta    @LayoutlibDelegate
479e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta    static TypedArray obtainAttributes(Resources resources, AttributeSet set, int[] attrs) {
480e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta        return resources.mContext.obtainStyledAttributes(set, attrs);
481282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
482282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
483e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta    @LayoutlibDelegate
484e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta    static TypedArray obtainAttributes(Resources resources, Resources.Theme theme, AttributeSet
485e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta            set, int[] attrs) {
486e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta        return Resources.obtainAttributes_Original(resources, theme, set, attrs);
487282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
488282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
489e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta    @LayoutlibDelegate
490e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta    static TypedArray obtainTypedArray(Resources resources, int id) throws NotFoundException {
491e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta        throw new UnsupportedOperationException();
492e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta    }
493282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
494e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta    @LayoutlibDelegate
495e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta    static float getDimension(Resources resources, int id) throws NotFoundException {
496e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta        Pair<String, ResourceValue> value = getResourceValue(resources, id, mPlatformResourceFlag);
497282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
498282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (value != null) {
499282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            ResourceValue resValue = value.getSecond();
500282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
501282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            assert resValue != null;
502282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            if (resValue != null) {
503282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                String v = resValue.getValue();
504282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                if (v != null) {
505282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    if (v.equals(BridgeConstants.MATCH_PARENT) ||
506282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                            v.equals(BridgeConstants.FILL_PARENT)) {
507282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                        return LayoutParams.MATCH_PARENT;
508282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    } else if (v.equals(BridgeConstants.WRAP_CONTENT)) {
509282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                        return LayoutParams.WRAP_CONTENT;
510282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    }
511e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta                    TypedValue tmpValue = new TypedValue();
512282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    if (ResourceHelper.parseFloatAttribute(
513e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta                            value.getFirst(), v, tmpValue, true /*requireUnit*/) &&
514e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta                            tmpValue.type == TypedValue.TYPE_DIMENSION) {
515e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta                        return tmpValue.getDimension(resources.getDisplayMetrics());
516282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    }
517282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                }
518282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            }
519282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
520282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
521282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        // id was not found or not resolved. Throw a NotFoundException.
522e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta        throwException(resources, id);
523282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
524282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        // this is not used since the method above always throws
525282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        return 0;
526282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
527282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
528e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta    @LayoutlibDelegate
529e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta    static int getDimensionPixelOffset(Resources resources, int id) throws NotFoundException {
530e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta        Pair<String, ResourceValue> value = getResourceValue(resources, id, mPlatformResourceFlag);
531282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
532282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (value != null) {
533282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            ResourceValue resValue = value.getSecond();
534282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
535282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            assert resValue != null;
536282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            if (resValue != null) {
537282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                String v = resValue.getValue();
538282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                if (v != null) {
539e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta                    TypedValue tmpValue = new TypedValue();
540282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    if (ResourceHelper.parseFloatAttribute(
541e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta                            value.getFirst(), v, tmpValue, true /*requireUnit*/) &&
542e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta                            tmpValue.type == TypedValue.TYPE_DIMENSION) {
543e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta                        return TypedValue.complexToDimensionPixelOffset(tmpValue.data,
544e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta                                resources.getDisplayMetrics());
545282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    }
546282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                }
547282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            }
548282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
549282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
550282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        // id was not found or not resolved. Throw a NotFoundException.
551e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta        throwException(resources, id);
552282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
553282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        // this is not used since the method above always throws
554282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        return 0;
555282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
556282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
557e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta    @LayoutlibDelegate
558e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta    static int getDimensionPixelSize(Resources resources, int id) throws NotFoundException {
559e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta        Pair<String, ResourceValue> value = getResourceValue(resources, id, mPlatformResourceFlag);
560282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
561282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (value != null) {
562282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            ResourceValue resValue = value.getSecond();
563282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
564282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            assert resValue != null;
565282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            if (resValue != null) {
566282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                String v = resValue.getValue();
567282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                if (v != null) {
568e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta                    TypedValue tmpValue = new TypedValue();
569282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    if (ResourceHelper.parseFloatAttribute(
570e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta                            value.getFirst(), v, tmpValue, true /*requireUnit*/) &&
571e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta                            tmpValue.type == TypedValue.TYPE_DIMENSION) {
572e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta                        return TypedValue.complexToDimensionPixelSize(tmpValue.data,
573e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta                                resources.getDisplayMetrics());
574282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    }
575282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                }
576282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            }
577282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
578282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
579282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        // id was not found or not resolved. Throw a NotFoundException.
580e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta        throwException(resources, id);
581282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
582282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        // this is not used since the method above always throws
583282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        return 0;
584282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
585282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
586e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta    @LayoutlibDelegate
587e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta    static int getInteger(Resources resources, int id) throws NotFoundException {
588e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta        Pair<String, ResourceValue> value = getResourceValue(resources, id, mPlatformResourceFlag);
589282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
590282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (value != null) {
591282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            ResourceValue resValue = value.getSecond();
592282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
593282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            assert resValue != null;
594282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            if (resValue != null) {
595282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                String v = resValue.getValue();
596282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                if (v != null) {
597282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    try {
598642cff50f8f7a67eed09eac1e56d7133b26a192cDeepanshu Gupta                        return getInt(v);
599282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    } catch (NumberFormatException e) {
600282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                        // return exception below
601282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    }
602282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                }
603282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            }
604282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
605282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
606282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        // id was not found or not resolved. Throw a NotFoundException.
607e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta        throwException(resources, id);
608282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
609282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        // this is not used since the method above always throws
610282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        return 0;
611282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
612282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
613e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta    @LayoutlibDelegate
614e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta    static boolean getBoolean(Resources resources, int id) throws NotFoundException {
615e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta        Pair<String, ResourceValue> value = getResourceValue(resources, id, mPlatformResourceFlag);
616282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
617282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (value != null) {
618282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            ResourceValue resValue = value.getSecond();
619282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
620282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            if (resValue != null) {
621282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                String v = resValue.getValue();
622282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                if (v != null) {
623282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    return Boolean.parseBoolean(v);
624282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                }
625282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            }
626282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
627282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
628282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        // id was not found or not resolved. Throw a NotFoundException.
629e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta        throwException(resources, id);
630282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
631282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        // this is not used since the method above always throws
632282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        return false;
633282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
634282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
635e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta    @LayoutlibDelegate
636e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta    static String getResourceEntryName(Resources resources, int resid) throws NotFoundException {
637618ca261f370c257723a3c7a5871bb6f6b4d7f3aDeepanshu Gupta        Pair<ResourceType, String> resourceInfo = getResourceInfo(resources, resid, new boolean[1]);
638618ca261f370c257723a3c7a5871bb6f6b4d7f3aDeepanshu Gupta        if (resourceInfo != null) {
639618ca261f370c257723a3c7a5871bb6f6b4d7f3aDeepanshu Gupta            return resourceInfo.getSecond();
640618ca261f370c257723a3c7a5871bb6f6b4d7f3aDeepanshu Gupta        }
641618ca261f370c257723a3c7a5871bb6f6b4d7f3aDeepanshu Gupta        throwException(resid, null);
642618ca261f370c257723a3c7a5871bb6f6b4d7f3aDeepanshu Gupta        return null;
643618ca261f370c257723a3c7a5871bb6f6b4d7f3aDeepanshu Gupta
644282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
645282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
646e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta    @LayoutlibDelegate
647e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta    static String getResourceName(Resources resources, int resid) throws NotFoundException {
648618ca261f370c257723a3c7a5871bb6f6b4d7f3aDeepanshu Gupta        boolean[] platformOut = new boolean[1];
649618ca261f370c257723a3c7a5871bb6f6b4d7f3aDeepanshu Gupta        Pair<ResourceType, String> resourceInfo = getResourceInfo(resources, resid, platformOut);
650ceb1ab1d2a71c6d4e0cccf110a198ff83cb97e5aDeepanshu Gupta        String packageName;
651618ca261f370c257723a3c7a5871bb6f6b4d7f3aDeepanshu Gupta        if (resourceInfo != null) {
652618ca261f370c257723a3c7a5871bb6f6b4d7f3aDeepanshu Gupta            if (platformOut[0]) {
653ceb1ab1d2a71c6d4e0cccf110a198ff83cb97e5aDeepanshu Gupta                packageName = SdkConstants.ANDROID_NS_NAME;
654618ca261f370c257723a3c7a5871bb6f6b4d7f3aDeepanshu Gupta            } else {
655ceb1ab1d2a71c6d4e0cccf110a198ff83cb97e5aDeepanshu Gupta                packageName = resources.mContext.getPackageName();
656ceb1ab1d2a71c6d4e0cccf110a198ff83cb97e5aDeepanshu Gupta                packageName = packageName == null ? SdkConstants.APP_PREFIX : packageName;
657618ca261f370c257723a3c7a5871bb6f6b4d7f3aDeepanshu Gupta            }
658ceb1ab1d2a71c6d4e0cccf110a198ff83cb97e5aDeepanshu Gupta            return packageName + ':' + resourceInfo.getFirst().getName() + '/' +
659618ca261f370c257723a3c7a5871bb6f6b4d7f3aDeepanshu Gupta                    resourceInfo.getSecond();
660618ca261f370c257723a3c7a5871bb6f6b4d7f3aDeepanshu Gupta        }
661618ca261f370c257723a3c7a5871bb6f6b4d7f3aDeepanshu Gupta        throwException(resid, null);
662618ca261f370c257723a3c7a5871bb6f6b4d7f3aDeepanshu Gupta        return null;
663618ca261f370c257723a3c7a5871bb6f6b4d7f3aDeepanshu Gupta    }
664618ca261f370c257723a3c7a5871bb6f6b4d7f3aDeepanshu Gupta
665618ca261f370c257723a3c7a5871bb6f6b4d7f3aDeepanshu Gupta    @LayoutlibDelegate
666618ca261f370c257723a3c7a5871bb6f6b4d7f3aDeepanshu Gupta    static String getResourcePackageName(Resources resources, int resid) throws NotFoundException {
667618ca261f370c257723a3c7a5871bb6f6b4d7f3aDeepanshu Gupta        boolean[] platformOut = new boolean[1];
668618ca261f370c257723a3c7a5871bb6f6b4d7f3aDeepanshu Gupta        Pair<ResourceType, String> resourceInfo = getResourceInfo(resources, resid, platformOut);
669618ca261f370c257723a3c7a5871bb6f6b4d7f3aDeepanshu Gupta        if (resourceInfo != null) {
670618ca261f370c257723a3c7a5871bb6f6b4d7f3aDeepanshu Gupta            if (platformOut[0]) {
671618ca261f370c257723a3c7a5871bb6f6b4d7f3aDeepanshu Gupta                return SdkConstants.ANDROID_NS_NAME;
672618ca261f370c257723a3c7a5871bb6f6b4d7f3aDeepanshu Gupta            }
673618ca261f370c257723a3c7a5871bb6f6b4d7f3aDeepanshu Gupta            String packageName = resources.mContext.getPackageName();
674618ca261f370c257723a3c7a5871bb6f6b4d7f3aDeepanshu Gupta            return packageName == null ? SdkConstants.APP_PREFIX : packageName;
675618ca261f370c257723a3c7a5871bb6f6b4d7f3aDeepanshu Gupta        }
676618ca261f370c257723a3c7a5871bb6f6b4d7f3aDeepanshu Gupta        throwException(resid, null);
677618ca261f370c257723a3c7a5871bb6f6b4d7f3aDeepanshu Gupta        return null;
678282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
679282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
680e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta    @LayoutlibDelegate
681e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta    static String getResourceTypeName(Resources resources, int resid) throws NotFoundException {
682618ca261f370c257723a3c7a5871bb6f6b4d7f3aDeepanshu Gupta        Pair<ResourceType, String> resourceInfo = getResourceInfo(resources, resid, new boolean[1]);
683618ca261f370c257723a3c7a5871bb6f6b4d7f3aDeepanshu Gupta        if (resourceInfo != null) {
684618ca261f370c257723a3c7a5871bb6f6b4d7f3aDeepanshu Gupta            return resourceInfo.getFirst().getName();
685618ca261f370c257723a3c7a5871bb6f6b4d7f3aDeepanshu Gupta        }
686618ca261f370c257723a3c7a5871bb6f6b4d7f3aDeepanshu Gupta        throwException(resid, null);
687618ca261f370c257723a3c7a5871bb6f6b4d7f3aDeepanshu Gupta        return null;
688282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
689282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
690e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta    @LayoutlibDelegate
691e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta    static String getString(Resources resources, int id, Object... formatArgs)
692e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta            throws NotFoundException {
693e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta        String s = getString(resources, id);
694282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (s != null) {
695282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            return String.format(s, formatArgs);
696282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
697282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
698282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
699282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        // id was not found or not resolved. Throw a NotFoundException.
700e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta        throwException(resources, id);
701282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
702282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        // this is not used since the method above always throws
703282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        return null;
704282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
705282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
706e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta    @LayoutlibDelegate
707e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta    static String getString(Resources resources, int id) throws NotFoundException {
708e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta        Pair<String, ResourceValue> value = getResourceValue(resources, id, mPlatformResourceFlag);
709282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
710282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (value != null && value.getSecond().getValue() != null) {
711282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            return value.getSecond().getValue();
712282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
713282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
714282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        // id was not found or not resolved. Throw a NotFoundException.
715e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta        throwException(resources, id);
716282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
717282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        // this is not used since the method above always throws
718282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        return null;
719282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
720282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
721e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta    @LayoutlibDelegate
722e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta    static void getValue(Resources resources, int id, TypedValue outValue, boolean resolveRefs)
723282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            throws NotFoundException {
724e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta        Pair<String, ResourceValue> value = getResourceValue(resources, id, mPlatformResourceFlag);
725282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
726282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (value != null) {
727e5d3baf22f046d0a579128fc258f6b92e700ca02Deepanshu Gupta            ResourceValue resVal = value.getSecond();
728e5d3baf22f046d0a579128fc258f6b92e700ca02Deepanshu Gupta            String v = resVal.getValue();
729282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
730282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            if (v != null) {
731282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                if (ResourceHelper.parseFloatAttribute(value.getFirst(), v, outValue,
732282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                        false /*requireUnit*/)) {
733282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    return;
734282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                }
735e5d3baf22f046d0a579128fc258f6b92e700ca02Deepanshu Gupta                if (resVal instanceof DensityBasedResourceValue) {
736e5d3baf22f046d0a579128fc258f6b92e700ca02Deepanshu Gupta                    outValue.density =
737e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta                            ((DensityBasedResourceValue) resVal).getResourceDensity().getDpiValue();
738e5d3baf22f046d0a579128fc258f6b92e700ca02Deepanshu Gupta                }
739282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
740282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                // else it's a string
741282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                outValue.type = TypedValue.TYPE_STRING;
742282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                outValue.string = v;
743282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                return;
744282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            }
745282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
746282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
747282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        // id was not found or not resolved. Throw a NotFoundException.
748e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta        throwException(resources, id);
749282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
750282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
751e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta    @LayoutlibDelegate
752e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta    static void getValue(Resources resources, String name, TypedValue outValue, boolean resolveRefs)
753282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            throws NotFoundException {
754282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        throw new UnsupportedOperationException();
755282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
756282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
757e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta    @LayoutlibDelegate
758e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta    static XmlResourceParser getXml(Resources resources, int id) throws NotFoundException {
759e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta        Pair<String, ResourceValue> value = getResourceValue(resources, id, mPlatformResourceFlag);
760282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
761282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (value != null) {
762282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            String v = value.getSecond().getValue();
763282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
764282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            if (v != null) {
765282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                // check this is a file
766282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                File f = new File(v);
767282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                if (f.isFile()) {
768282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    try {
769282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                        XmlPullParser parser = ParserFactory.create(f);
770282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
771e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta                        return new BridgeXmlBlockParser(parser, resources.mContext,
772e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta                                mPlatformResourceFlag[0]);
773282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    } catch (XmlPullParserException e) {
774282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                        NotFoundException newE = new NotFoundException();
775282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                        newE.initCause(e);
776282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                        throw newE;
777282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    } catch (FileNotFoundException e) {
778282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                        NotFoundException newE = new NotFoundException();
779282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                        newE.initCause(e);
780282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                        throw newE;
781282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    }
782282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                }
783282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            }
784282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
785282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
786282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        // id was not found or not resolved. Throw a NotFoundException.
787e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta        throwException(resources, id);
788282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
789282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        // this is not used since the method above always throws
790282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        return null;
791282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
792282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
793e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta    @LayoutlibDelegate
794e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta    static XmlResourceParser loadXmlResourceParser(Resources resources, int id,
795e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta            String type) throws NotFoundException {
796e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta        return resources.loadXmlResourceParser_Original(id, type);
797e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta    }
798e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta
799e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta    @LayoutlibDelegate
800e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta    static XmlResourceParser loadXmlResourceParser(Resources resources, String file, int id,
801282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            int assetCookie, String type) throws NotFoundException {
802282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        // even though we know the XML file to load directly, we still need to resolve the
803282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        // id so that we can know if it's a platform or project resource.
804282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        // (mPlatformResouceFlag will get the result and will be used later).
805e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta        getResourceValue(resources, id, mPlatformResourceFlag);
806282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
807282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        File f = new File(file);
808282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        try {
809282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            XmlPullParser parser = ParserFactory.create(f);
810282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
811e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta            return new BridgeXmlBlockParser(parser, resources.mContext, mPlatformResourceFlag[0]);
812282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        } catch (XmlPullParserException e) {
813282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            NotFoundException newE = new NotFoundException();
814282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            newE.initCause(e);
815282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            throw newE;
816282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        } catch (FileNotFoundException e) {
817282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            NotFoundException newE = new NotFoundException();
818282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            newE.initCause(e);
819282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            throw newE;
820282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
821282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
822282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
823e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta    @LayoutlibDelegate
824e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta    static InputStream openRawResource(Resources resources, int id) throws NotFoundException {
825e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta        Pair<String, ResourceValue> value = getResourceValue(resources, id, mPlatformResourceFlag);
826282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
827282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (value != null) {
828282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            String path = value.getSecond().getValue();
829282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
830282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            if (path != null) {
831282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                // check this is a file
832282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                File f = new File(path);
833282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                if (f.isFile()) {
834282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    try {
835282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                        // if it's a nine-patch return a custom input stream so that
836282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                        // other methods (mainly bitmap factory) can detect it's a 9-patch
837282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                        // and actually load it as a 9-patch instead of a normal bitmap
838282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                        if (path.toLowerCase().endsWith(NinePatch.EXTENSION_9PATCH)) {
839282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                            return new NinePatchInputStream(f);
840282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                        }
841282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                        return new FileInputStream(f);
842282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    } catch (FileNotFoundException e) {
843282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                        NotFoundException newE = new NotFoundException();
844282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                        newE.initCause(e);
845282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                        throw newE;
846282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    }
847282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                }
848282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            }
849282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
850282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
851282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        // id was not found or not resolved. Throw a NotFoundException.
852e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta        throwException(resources, id);
853282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
854282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        // this is not used since the method above always throws
855282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        return null;
856282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
857282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
858e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta    @LayoutlibDelegate
859e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta    static InputStream openRawResource(Resources resources, int id, TypedValue value) throws
860e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta            NotFoundException {
861e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta        getValue(resources, id, value, true);
862282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
863282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        String path = value.string.toString();
864282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
865282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        File f = new File(path);
866282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (f.isFile()) {
867282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            try {
868282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                // if it's a nine-patch return a custom input stream so that
869282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                // other methods (mainly bitmap factory) can detect it's a 9-patch
870282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                // and actually load it as a 9-patch instead of a normal bitmap
871282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                if (path.toLowerCase().endsWith(NinePatch.EXTENSION_9PATCH)) {
872282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    return new NinePatchInputStream(f);
873282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                }
874282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                return new FileInputStream(f);
875282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            } catch (FileNotFoundException e) {
876282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                NotFoundException exception = new NotFoundException();
877282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                exception.initCause(e);
878282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                throw exception;
879282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            }
880282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
881282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
882282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        throw new NotFoundException();
883282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
884282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
885e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta    @LayoutlibDelegate
886e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta    static AssetFileDescriptor openRawResourceFd(Resources resources, int id) throws
887e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta            NotFoundException {
888282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        throw new UnsupportedOperationException();
889282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
890282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
891282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    /**
892e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta     * Builds and throws a {@link Resources.NotFoundException} based on a resource id and a resource
893e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta     * type.
894e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta     *
895282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski     * @param id the id of the resource
896e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta     *
897282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski     * @throws NotFoundException
898282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski     */
899e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta    private static void throwException(Resources resources, int id) throws NotFoundException {
900618ca261f370c257723a3c7a5871bb6f6b4d7f3aDeepanshu Gupta        throwException(id, getResourceInfo(resources, id, new boolean[1]));
901618ca261f370c257723a3c7a5871bb6f6b4d7f3aDeepanshu Gupta    }
902282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
903618ca261f370c257723a3c7a5871bb6f6b4d7f3aDeepanshu Gupta    private static void throwException(int id, @Nullable Pair<ResourceType, String> resourceInfo) {
904642cff50f8f7a67eed09eac1e56d7133b26a192cDeepanshu Gupta        String message;
905282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        if (resourceInfo != null) {
906282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski            message = String.format(
907282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    "Could not find %1$s resource matching value 0x%2$X (resolved name: %3$s) in current configuration.",
908282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski                    resourceInfo.getFirst(), id, resourceInfo.getSecond());
909282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        } else {
910618ca261f370c257723a3c7a5871bb6f6b4d7f3aDeepanshu Gupta            message = String.format("Could not resolve resource value: 0x%1$X.", id);
911282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        }
912282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
913282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        throw new NotFoundException(message);
914282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
915642cff50f8f7a67eed09eac1e56d7133b26a192cDeepanshu Gupta
916e05f1c4684fcc7e3f6a429ff01b210aa19f75304Deepanshu Gupta    private static int getInt(String v) throws NumberFormatException {
917642cff50f8f7a67eed09eac1e56d7133b26a192cDeepanshu Gupta        int radix = 10;
918642cff50f8f7a67eed09eac1e56d7133b26a192cDeepanshu Gupta        if (v.startsWith("0x")) {
919642cff50f8f7a67eed09eac1e56d7133b26a192cDeepanshu Gupta            v = v.substring(2);
920642cff50f8f7a67eed09eac1e56d7133b26a192cDeepanshu Gupta            radix = 16;
921642cff50f8f7a67eed09eac1e56d7133b26a192cDeepanshu Gupta        } else if (v.startsWith("0")) {
922642cff50f8f7a67eed09eac1e56d7133b26a192cDeepanshu Gupta            radix = 8;
923642cff50f8f7a67eed09eac1e56d7133b26a192cDeepanshu Gupta        }
924642cff50f8f7a67eed09eac1e56d7133b26a192cDeepanshu Gupta        return Integer.parseInt(v, radix);
925642cff50f8f7a67eed09eac1e56d7133b26a192cDeepanshu Gupta    }
926282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}
927