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 <T super String>, 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