19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*
29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2008 The Android Open Source Project
39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License.
69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at
79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *
109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and
149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License.
159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage com.android.layoutlib.bridge;
189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1919a021038f2f4683dddef651543d7298f5bd7218Xavier Ducrohetimport static com.android.ide.common.rendering.api.Result.Status.ERROR_UNKNOWN;
2019a021038f2f4683dddef651543d7298f5bd7218Xavier Ducrohetimport static com.android.ide.common.rendering.api.Result.Status.SUCCESS;
2119a021038f2f4683dddef651543d7298f5bd7218Xavier Ducrohet
2219a021038f2f4683dddef651543d7298f5bd7218Xavier Ducrohetimport com.android.ide.common.rendering.api.Capability;
23fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohetimport com.android.ide.common.rendering.api.DrawableParams;
2419a021038f2f4683dddef651543d7298f5bd7218Xavier Ducrohetimport com.android.ide.common.rendering.api.LayoutLog;
2519a021038f2f4683dddef651543d7298f5bd7218Xavier Ducrohetimport com.android.ide.common.rendering.api.RenderSession;
2619a021038f2f4683dddef651543d7298f5bd7218Xavier Ducrohetimport com.android.ide.common.rendering.api.Result;
272fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohetimport com.android.ide.common.rendering.api.Result.Status;
28c3f979f6fecb8b46e9315fddb2a1f344bf1f1447Xavier Ducrohetimport com.android.ide.common.rendering.api.SessionParams;
29c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohetimport com.android.layoutlib.bridge.impl.FontLoader;
30fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohetimport com.android.layoutlib.bridge.impl.RenderDrawable;
3119a021038f2f4683dddef651543d7298f5bd7218Xavier Ducrohetimport com.android.layoutlib.bridge.impl.RenderSessionImpl;
32a421f6c0ba8c354e2a81830e6402654bbf732780Xavier Ducrohetimport com.android.layoutlib.bridge.util.DynamicIdMap;
332d56b273ef6e2984a4e8914fb67772b173d0a154Xavier Ducrohetimport com.android.ninepatch.NinePatchChunk;
3435ea7cd4c0c89122fda0b57af20061645082ffb9Xavier Ducrohetimport com.android.resources.ResourceType;
359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport com.android.tools.layoutlib.create.MethodAdapter;
369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport com.android.tools.layoutlib.create.OverrideMethod;
37b353495192ba1acce94b8ab8aeeffe3c9a3bcfacXavier Ducrohetimport com.android.util.Pair;
389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
397f9f99ea11051614a7727dfb9f9578b518e76e3cXavier Ducrohetimport android.content.res.BridgeAssetManager;
409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.Bitmap;
417f9f99ea11051614a7727dfb9f9578b518e76e3cXavier Ducrohetimport android.graphics.Typeface_Accessor;
425e7ed8da0d990cbc55071d16b5db270231ff0c89Xavier Ducrohetimport android.graphics.Typeface_Delegate;
439eb6d412af6859b6c0bb969c76bbfc48eec8fd4bXavier Ducrohetimport android.os.Looper;
447f9f99ea11051614a7727dfb9f9578b518e76e3cXavier Ducrohetimport android.os.Looper_Accessor;
452fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohetimport android.view.View;
462fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohetimport android.view.ViewGroup;
472fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohetimport android.view.ViewParent;
489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
4919a021038f2f4683dddef651543d7298f5bd7218Xavier Ducrohetimport java.io.File;
504df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Projectimport java.lang.ref.SoftReference;
519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.lang.reflect.Field;
529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.lang.reflect.Modifier;
53755b46d597b8e8a616d53e2a7dfea295dd78d713Xavier Ducrohetimport java.util.Arrays;
54b353495192ba1acce94b8ab8aeeffe3c9a3bcfacXavier Ducrohetimport java.util.EnumMap;
553c78f2de353df3e287444dd9f9fbab3bd4456217Xavier Ducrohetimport java.util.EnumSet;
569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.HashMap;
579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.Map;
582eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohetimport java.util.concurrent.locks.ReentrantLock;
599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/**
619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Main entry point of the LayoutLib Bridge.
629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p/>To use this bridge, simply instantiate an object of type {@link Bridge} and call
63ffb42f6c5043de226f02318a1311669d35a90711Xavier Ducrohet * {@link #createScene(SceneParams)}
649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */
6519a021038f2f4683dddef651543d7298f5bd7218Xavier Ducrohetpublic final class Bridge extends com.android.ide.common.rendering.api.Bridge {
6683189c985a0e617ba7856343ea8b7080c37396a7Xavier Ducrohet
679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public static class StaticMethodNotImplementedException extends RuntimeException {
689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        private static final long serialVersionUID = 1L;
699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        public StaticMethodNotImplementedException(String msg) {
719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            super(msg);
729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
762eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet     * Lock to ensure only one rendering/inflating happens at a time.
772eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet     * This is due to some singleton in the Android framework.
782eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet     */
792eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet    private final static ReentrantLock sLock = new ReentrantLock();
802eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet
812eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet    /**
82a421f6c0ba8c354e2a81830e6402654bbf732780Xavier Ducrohet     * Maps from id to resource type/name. This is for com.android.internal.R
839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
84b353495192ba1acce94b8ab8aeeffe3c9a3bcfacXavier Ducrohet    private final static Map<Integer, Pair<ResourceType, String>> sRMap =
85b353495192ba1acce94b8ab8aeeffe3c9a3bcfacXavier Ducrohet        new HashMap<Integer, Pair<ResourceType, String>>();
86b353495192ba1acce94b8ab8aeeffe3c9a3bcfacXavier Ducrohet
879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
8883189c985a0e617ba7856343ea8b7080c37396a7Xavier Ducrohet     * Same as sRMap except for int[] instead of int resources. This is for android.R only.
899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
90755b46d597b8e8a616d53e2a7dfea295dd78d713Xavier Ducrohet    private final static Map<IntArray, String> sRArrayMap = new HashMap<IntArray, String>();
919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
9283189c985a0e617ba7856343ea8b7080c37396a7Xavier Ducrohet     * Reverse map compared to sRMap, resource type -> (resource name -> id).
93a421f6c0ba8c354e2a81830e6402654bbf732780Xavier Ducrohet     * This is for com.android.internal.R.
949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
95a421f6c0ba8c354e2a81830e6402654bbf732780Xavier Ducrohet    private final static Map<ResourceType, Map<String, Integer>> sRevRMap =
96b353495192ba1acce94b8ab8aeeffe3c9a3bcfacXavier Ducrohet        new EnumMap<ResourceType, Map<String,Integer>>(ResourceType.class);
9783189c985a0e617ba7856343ea8b7080c37396a7Xavier Ducrohet
98a421f6c0ba8c354e2a81830e6402654bbf732780Xavier Ducrohet    // framework resources are defined as 0x01XX#### where XX is the resource type (layout,
99a421f6c0ba8c354e2a81830e6402654bbf732780Xavier Ducrohet    // drawable, etc...). Using FF as the type allows for 255 resource types before we get a
100a421f6c0ba8c354e2a81830e6402654bbf732780Xavier Ducrohet    // collision which should be fine.
101a421f6c0ba8c354e2a81830e6402654bbf732780Xavier Ducrohet    private final static int DYNAMIC_ID_SEED_START = 0x01ff0000;
102a421f6c0ba8c354e2a81830e6402654bbf732780Xavier Ducrohet    private final static DynamicIdMap sDynamicIds = new DynamicIdMap(DYNAMIC_ID_SEED_START);
103a421f6c0ba8c354e2a81830e6402654bbf732780Xavier Ducrohet
1044df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project    private final static Map<Object, Map<String, SoftReference<Bitmap>>> sProjectBitmapCache =
1054df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project        new HashMap<Object, Map<String, SoftReference<Bitmap>>>();
1062d56b273ef6e2984a4e8914fb67772b173d0a154Xavier Ducrohet    private final static Map<Object, Map<String, SoftReference<NinePatchChunk>>> sProject9PatchCache =
1072d56b273ef6e2984a4e8914fb67772b173d0a154Xavier Ducrohet        new HashMap<Object, Map<String, SoftReference<NinePatchChunk>>>();
1084df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project
1094df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project    private final static Map<String, SoftReference<Bitmap>> sFrameworkBitmapCache =
1104df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project        new HashMap<String, SoftReference<Bitmap>>();
1112d56b273ef6e2984a4e8914fb67772b173d0a154Xavier Ducrohet    private final static Map<String, SoftReference<NinePatchChunk>> sFramework9PatchCache =
1122d56b273ef6e2984a4e8914fb67772b173d0a154Xavier Ducrohet        new HashMap<String, SoftReference<NinePatchChunk>>();
11383189c985a0e617ba7856343ea8b7080c37396a7Xavier Ducrohet
1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    private static Map<String, Map<String, Integer>> sEnumValueMap;
1157d7016e72431ad7ee595d857a19231c69efeb6deXavier Ducrohet    private static Map<String, String> sPlatformProperties;
1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
118755b46d597b8e8a616d53e2a7dfea295dd78d713Xavier Ducrohet     * int[] wrapper to use as keys in maps.
119755b46d597b8e8a616d53e2a7dfea295dd78d713Xavier Ducrohet     */
120755b46d597b8e8a616d53e2a7dfea295dd78d713Xavier Ducrohet    private final static class IntArray {
121755b46d597b8e8a616d53e2a7dfea295dd78d713Xavier Ducrohet        private int[] mArray;
122755b46d597b8e8a616d53e2a7dfea295dd78d713Xavier Ducrohet
123755b46d597b8e8a616d53e2a7dfea295dd78d713Xavier Ducrohet        private IntArray() {
124755b46d597b8e8a616d53e2a7dfea295dd78d713Xavier Ducrohet            // do nothing
125755b46d597b8e8a616d53e2a7dfea295dd78d713Xavier Ducrohet        }
126755b46d597b8e8a616d53e2a7dfea295dd78d713Xavier Ducrohet
127755b46d597b8e8a616d53e2a7dfea295dd78d713Xavier Ducrohet        private IntArray(int[] a) {
128755b46d597b8e8a616d53e2a7dfea295dd78d713Xavier Ducrohet            mArray = a;
129755b46d597b8e8a616d53e2a7dfea295dd78d713Xavier Ducrohet        }
130755b46d597b8e8a616d53e2a7dfea295dd78d713Xavier Ducrohet
131755b46d597b8e8a616d53e2a7dfea295dd78d713Xavier Ducrohet        private void set(int[] a) {
132755b46d597b8e8a616d53e2a7dfea295dd78d713Xavier Ducrohet            mArray = a;
133755b46d597b8e8a616d53e2a7dfea295dd78d713Xavier Ducrohet        }
134755b46d597b8e8a616d53e2a7dfea295dd78d713Xavier Ducrohet
135755b46d597b8e8a616d53e2a7dfea295dd78d713Xavier Ducrohet        @Override
136755b46d597b8e8a616d53e2a7dfea295dd78d713Xavier Ducrohet        public int hashCode() {
137755b46d597b8e8a616d53e2a7dfea295dd78d713Xavier Ducrohet            return Arrays.hashCode(mArray);
138755b46d597b8e8a616d53e2a7dfea295dd78d713Xavier Ducrohet        }
139755b46d597b8e8a616d53e2a7dfea295dd78d713Xavier Ducrohet
140755b46d597b8e8a616d53e2a7dfea295dd78d713Xavier Ducrohet        @Override
141755b46d597b8e8a616d53e2a7dfea295dd78d713Xavier Ducrohet        public boolean equals(Object obj) {
142755b46d597b8e8a616d53e2a7dfea295dd78d713Xavier Ducrohet            if (this == obj) return true;
143755b46d597b8e8a616d53e2a7dfea295dd78d713Xavier Ducrohet            if (obj == null) return false;
144755b46d597b8e8a616d53e2a7dfea295dd78d713Xavier Ducrohet            if (getClass() != obj.getClass()) return false;
145755b46d597b8e8a616d53e2a7dfea295dd78d713Xavier Ducrohet
146755b46d597b8e8a616d53e2a7dfea295dd78d713Xavier Ducrohet            IntArray other = (IntArray) obj;
147755b46d597b8e8a616d53e2a7dfea295dd78d713Xavier Ducrohet            if (!Arrays.equals(mArray, other.mArray)) return false;
148755b46d597b8e8a616d53e2a7dfea295dd78d713Xavier Ducrohet            return true;
149755b46d597b8e8a616d53e2a7dfea295dd78d713Xavier Ducrohet        }
150755b46d597b8e8a616d53e2a7dfea295dd78d713Xavier Ducrohet    }
151755b46d597b8e8a616d53e2a7dfea295dd78d713Xavier Ducrohet
152b353495192ba1acce94b8ab8aeeffe3c9a3bcfacXavier Ducrohet    /** Instance of IntArrayWrapper to be reused in {@link #resolveResourceId(int[])}. */
153755b46d597b8e8a616d53e2a7dfea295dd78d713Xavier Ducrohet    private final static IntArray sIntArrayWrapper = new IntArray();
154755b46d597b8e8a616d53e2a7dfea295dd78d713Xavier Ducrohet
155755b46d597b8e8a616d53e2a7dfea295dd78d713Xavier Ducrohet    /**
156168677c9e2f8438ec5687e3c6b0e41b986c5b230Xavier Ducrohet     * A default log than prints to stdout/stderr.
1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
158168677c9e2f8438ec5687e3c6b0e41b986c5b230Xavier Ducrohet    private final static LayoutLog sDefaultLog = new LayoutLog() {
159168677c9e2f8438ec5687e3c6b0e41b986c5b230Xavier Ducrohet        @Override
16051a7e5447de94791c464cda5cc6ebbf616d73c80Xavier Ducrohet        public void error(String tag, String message, Object data) {
1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            System.err.println(message);
1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
164168677c9e2f8438ec5687e3c6b0e41b986c5b230Xavier Ducrohet        @Override
16551a7e5447de94791c464cda5cc6ebbf616d73c80Xavier Ducrohet        public void error(String tag, String message, Throwable throwable, Object data) {
166168677c9e2f8438ec5687e3c6b0e41b986c5b230Xavier Ducrohet            System.err.println(message);
167168677c9e2f8438ec5687e3c6b0e41b986c5b230Xavier Ducrohet        }
168168677c9e2f8438ec5687e3c6b0e41b986c5b230Xavier Ducrohet
169168677c9e2f8438ec5687e3c6b0e41b986c5b230Xavier Ducrohet        @Override
17051a7e5447de94791c464cda5cc6ebbf616d73c80Xavier Ducrohet        public void warning(String tag, String message, Object data) {
1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            System.out.println(message);
1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    };
1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
175168677c9e2f8438ec5687e3c6b0e41b986c5b230Xavier Ducrohet    /**
176168677c9e2f8438ec5687e3c6b0e41b986c5b230Xavier Ducrohet     * Current log.
177168677c9e2f8438ec5687e3c6b0e41b986c5b230Xavier Ducrohet     */
178168677c9e2f8438ec5687e3c6b0e41b986c5b230Xavier Ducrohet    private static LayoutLog sCurrentLog = sDefaultLog;
179168677c9e2f8438ec5687e3c6b0e41b986c5b230Xavier Ducrohet
180ffb42f6c5043de226f02318a1311669d35a90711Xavier Ducrohet    private EnumSet<Capability> mCapabilities;
1813c78f2de353df3e287444dd9f9fbab3bd4456217Xavier Ducrohet
182c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet    @Override
1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public int getApiLevel() {
18419a021038f2f4683dddef651543d7298f5bd7218Xavier Ducrohet        return com.android.ide.common.rendering.api.Bridge.API_CURRENT;
1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1873c78f2de353df3e287444dd9f9fbab3bd4456217Xavier Ducrohet    @Override
188ffb42f6c5043de226f02318a1311669d35a90711Xavier Ducrohet    public EnumSet<Capability> getCapabilities() {
1893c78f2de353df3e287444dd9f9fbab3bd4456217Xavier Ducrohet        return mCapabilities;
1903c78f2de353df3e287444dd9f9fbab3bd4456217Xavier Ducrohet    }
1913c78f2de353df3e287444dd9f9fbab3bd4456217Xavier Ducrohet
192c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet    @Override
1937d7016e72431ad7ee595d857a19231c69efeb6deXavier Ducrohet    public boolean init(Map<String,String> platformProperties,
1947d7016e72431ad7ee595d857a19231c69efeb6deXavier Ducrohet            File fontLocation,
1957d7016e72431ad7ee595d857a19231c69efeb6deXavier Ducrohet            Map<String, Map<String, Integer>> enumValueMap,
19629c288da5260ac221b941e69b960aa2127cbdef0Xavier Ducrohet            LayoutLog log) {
1977d7016e72431ad7ee595d857a19231c69efeb6deXavier Ducrohet        sPlatformProperties = platformProperties;
1985a09488a158b669577cd8eb557ce4feb62929e75Xavier Ducrohet        sEnumValueMap = enumValueMap;
1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
20001811aa86279af1b341a4fff344d66c0ebdd63daXavier Ducrohet        // don't use EnumSet.allOf(), because the bridge doesn't come with its specific version
2013c78f2de353df3e287444dd9f9fbab3bd4456217Xavier Ducrohet        // of layoutlib_api. It is provided by the client which could have a more recent version
2023c78f2de353df3e287444dd9f9fbab3bd4456217Xavier Ducrohet        // with newer, unsupported capabilities.
2033c78f2de353df3e287444dd9f9fbab3bd4456217Xavier Ducrohet        mCapabilities = EnumSet.of(
204ffb42f6c5043de226f02318a1311669d35a90711Xavier Ducrohet                Capability.UNBOUND_RENDERING,
2054dd2299d5766bf14479578772a0946c5399a0158Xavier Ducrohet                Capability.CUSTOM_BACKGROUND_COLOR,
206ffb42f6c5043de226f02318a1311669d35a90711Xavier Ducrohet                Capability.RENDER,
207fb93ce9684120a36862b5b5e67b1865a652907e9Xavier Ducrohet                Capability.LAYOUT_ONLY,
208ffb42f6c5043de226f02318a1311669d35a90711Xavier Ducrohet                Capability.EMBEDDED_LAYOUT,
209ffb42f6c5043de226f02318a1311669d35a90711Xavier Ducrohet                Capability.VIEW_MANIPULATION,
210479101a9b4142d21d42351684bc9bc65ec3471beXavier Ducrohet                Capability.PLAY_ANIMATION,
2112fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet                Capability.ANIMATED_VIEW_MANIPULATION,
21205b7b69c6c5d418e18db644feed1ec2ca83291ccXavier Ducrohet                Capability.ADAPTER_BINDING,
213891b703f7b1e0e396d16477cc66a286da7161b49Xavier Ducrohet                Capability.EXTENDED_VIEWINFO,
214891b703f7b1e0e396d16477cc66a286da7161b49Xavier Ducrohet                Capability.FIXED_SCALABLE_NINE_PATCH);
2153c78f2de353df3e287444dd9f9fbab3bd4456217Xavier Ducrohet
2163c78f2de353df3e287444dd9f9fbab3bd4456217Xavier Ducrohet
2175a09488a158b669577cd8eb557ce4feb62929e75Xavier Ducrohet        BridgeAssetManager.initSystem();
218c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet
2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // When DEBUG_LAYOUT is set and is not 0 or false, setup a default listener
2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // on static (native) methods which prints the signature on the console and
2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // throws an exception.
22283189c985a0e617ba7856343ea8b7080c37396a7Xavier Ducrohet        // This is useful when testing the rendering in ADT to identify static native
2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // methods that are ignored -- layoutlib_create makes them returns 0/false/null
2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // which is generally OK yet might be a problem, so this is how you'd find out.
2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        //
2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Currently layoutlib_create only overrides static native method.
2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // Static non-natives are not overridden and thus do not get here.
2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        final String debug = System.getenv("DEBUG_LAYOUT");
2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (debug != null && !debug.equals("0") && !debug.equals("false")) {
2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            OverrideMethod.setDefaultListener(new MethodAdapter() {
2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                @Override
2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                public void onInvokeV(String signature, boolean isNative, Object caller) {
234168677c9e2f8438ec5687e3c6b0e41b986c5b230Xavier Ducrohet                    sDefaultLog.error(null, "Missing Stub: " + signature +
23551a7e5447de94791c464cda5cc6ebbf616d73c80Xavier Ducrohet                            (isNative ? " (native)" : ""), null /*data*/);
2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    if (debug.equalsIgnoreCase("throw")) {
2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        // Throwing this exception doesn't seem that useful. It breaks
2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        // the layout editor yet doesn't display anything meaningful to the
2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        // user. Having the error in the console is just as useful. We'll
2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        // throw it only if the environment variable is "throw" or "THROW".
2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        throw new StaticMethodNotImplementedException(signature);
2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            });
2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // load the fonts.
24919a021038f2f4683dddef651543d7298f5bd7218Xavier Ducrohet        FontLoader fontLoader = FontLoader.create(fontLocation.getAbsolutePath());
2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (fontLoader != null) {
2515e7ed8da0d990cbc55071d16b5db270231ff0c89Xavier Ducrohet            Typeface_Delegate.init(fontLoader);
2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        } else {
253c3f979f6fecb8b46e9315fddb2a1f344bf1f1447Xavier Ducrohet            log.error(LayoutLog.TAG_BROKEN,
254c3f979f6fecb8b46e9315fddb2a1f344bf1f1447Xavier Ducrohet                    "Failed create FontLoader in layout lib.", null);
2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return false;
2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
25783189c985a0e617ba7856343ea8b7080c37396a7Xavier Ducrohet
2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // now parse com.android.internal.R (and only this one as android.R is a subset of
2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        // the internal version), and put the content in the maps.
2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        try {
2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            Class<?> r = com.android.internal.R.class;
26283189c985a0e617ba7856343ea8b7080c37396a7Xavier Ducrohet
2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            for (Class<?> inner : r.getDeclaredClasses()) {
264b353495192ba1acce94b8ab8aeeffe3c9a3bcfacXavier Ducrohet                String resTypeName = inner.getSimpleName();
265b353495192ba1acce94b8ab8aeeffe3c9a3bcfacXavier Ducrohet                ResourceType resType = ResourceType.getEnum(resTypeName);
266b353495192ba1acce94b8ab8aeeffe3c9a3bcfacXavier Ducrohet                if (resType != null) {
267b353495192ba1acce94b8ab8aeeffe3c9a3bcfacXavier Ducrohet                    Map<String, Integer> fullMap = new HashMap<String, Integer>();
268a421f6c0ba8c354e2a81830e6402654bbf732780Xavier Ducrohet                    sRevRMap.put(resType, fullMap);
269b353495192ba1acce94b8ab8aeeffe3c9a3bcfacXavier Ducrohet
270b353495192ba1acce94b8ab8aeeffe3c9a3bcfacXavier Ducrohet                    for (Field f : inner.getDeclaredFields()) {
271b353495192ba1acce94b8ab8aeeffe3c9a3bcfacXavier Ducrohet                        // only process static final fields. Since the final attribute may have
272b353495192ba1acce94b8ab8aeeffe3c9a3bcfacXavier Ducrohet                        // been altered by layoutlib_create, we only check static
273b353495192ba1acce94b8ab8aeeffe3c9a3bcfacXavier Ducrohet                        int modifiers = f.getModifiers();
274b353495192ba1acce94b8ab8aeeffe3c9a3bcfacXavier Ducrohet                        if (Modifier.isStatic(modifiers)) {
275b353495192ba1acce94b8ab8aeeffe3c9a3bcfacXavier Ducrohet                            Class<?> type = f.getType();
276b353495192ba1acce94b8ab8aeeffe3c9a3bcfacXavier Ducrohet                            if (type.isArray() && type.getComponentType() == int.class) {
277b353495192ba1acce94b8ab8aeeffe3c9a3bcfacXavier Ducrohet                                // if the object is an int[] we put it in sRArrayMap using an IntArray
278b353495192ba1acce94b8ab8aeeffe3c9a3bcfacXavier Ducrohet                                // wrapper that properly implements equals and hashcode for the array
279b353495192ba1acce94b8ab8aeeffe3c9a3bcfacXavier Ducrohet                                // objects, as required by the map contract.
280b353495192ba1acce94b8ab8aeeffe3c9a3bcfacXavier Ducrohet                                sRArrayMap.put(new IntArray((int[]) f.get(null)), f.getName());
281b353495192ba1acce94b8ab8aeeffe3c9a3bcfacXavier Ducrohet                            } else if (type == int.class) {
282b353495192ba1acce94b8ab8aeeffe3c9a3bcfacXavier Ducrohet                                Integer value = (Integer) f.get(null);
283b353495192ba1acce94b8ab8aeeffe3c9a3bcfacXavier Ducrohet                                sRMap.put(value, Pair.of(resType, f.getName()));
284b353495192ba1acce94b8ab8aeeffe3c9a3bcfacXavier Ducrohet                                fullMap.put(f.getName(), value);
285b353495192ba1acce94b8ab8aeeffe3c9a3bcfacXavier Ducrohet                            } else {
286b353495192ba1acce94b8ab8aeeffe3c9a3bcfacXavier Ducrohet                                assert false;
287b353495192ba1acce94b8ab8aeeffe3c9a3bcfacXavier Ducrohet                            }
2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                        }
2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                    }
2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                }
2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
29229c288da5260ac221b941e69b960aa2127cbdef0Xavier Ducrohet        } catch (Throwable throwable) {
29329c288da5260ac221b941e69b960aa2127cbdef0Xavier Ducrohet            if (log != null) {
294918aaa5717fce6081557c82ce1c439b6922737d5Xavier Ducrohet                log.error(LayoutLog.TAG_BROKEN,
29529c288da5260ac221b941e69b960aa2127cbdef0Xavier Ducrohet                        "Failed to load com.android.internal.R from the layout library jar",
29629c288da5260ac221b941e69b960aa2127cbdef0Xavier Ducrohet                        throwable);
29729c288da5260ac221b941e69b960aa2127cbdef0Xavier Ducrohet            }
2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            return false;
2999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return true;
3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
3045a09488a158b669577cd8eb557ce4feb62929e75Xavier Ducrohet    @Override
3055a09488a158b669577cd8eb557ce4feb62929e75Xavier Ducrohet    public boolean dispose() {
3065a09488a158b669577cd8eb557ce4feb62929e75Xavier Ducrohet        BridgeAssetManager.clearSystem();
30746a329244db12b6f7afc3c9a6409d420241a1058Xavier Ducrohet
30846a329244db12b6f7afc3c9a6409d420241a1058Xavier Ducrohet        // dispose of the default typeface.
3097f9f99ea11051614a7727dfb9f9578b518e76e3cXavier Ducrohet        Typeface_Accessor.resetDefaults();
31046a329244db12b6f7afc3c9a6409d420241a1058Xavier Ducrohet
3115a09488a158b669577cd8eb557ce4feb62929e75Xavier Ducrohet        return true;
3125a09488a158b669577cd8eb557ce4feb62929e75Xavier Ducrohet    }
3135a09488a158b669577cd8eb557ce4feb62929e75Xavier Ducrohet
314c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet    /**
315c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet     * Starts a layout session by inflating and rendering it. The method returns a
316bbbb8326020368958a3f1d248878329e9d6b10c0Xavier Ducrohet     * {@link RenderSession} on which further actions can be taken.
317c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet     *
3181126422ee1f532d8582a4e3b56dbfe505c15e775Xavier Ducrohet     * @param params the {@link SessionParams} object with all the information necessary to create
319ffb42f6c5043de226f02318a1311669d35a90711Xavier Ducrohet     *           the scene.
320bbbb8326020368958a3f1d248878329e9d6b10c0Xavier Ducrohet     * @return a new {@link RenderSession} object that contains the result of the layout.
321c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet     * @since 5
322d604ad1ad442790af53847d24060ecb097106d26Xavier Ducrohet     */
323c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet    @Override
3241126422ee1f532d8582a4e3b56dbfe505c15e775Xavier Ducrohet    public RenderSession createSession(SessionParams params) {
3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        try {
32619a021038f2f4683dddef651543d7298f5bd7218Xavier Ducrohet            Result lastResult = SUCCESS.createResult();
32719a021038f2f4683dddef651543d7298f5bd7218Xavier Ducrohet            RenderSessionImpl scene = new RenderSessionImpl(params);
3282eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet            try {
3299eb6d412af6859b6c0bb969c76bbfc48eec8fd4bXavier Ducrohet                prepareThread();
3302eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet                lastResult = scene.init(params.getTimeout());
331c8aec064f9f304c88f61c8c1aa3d60521b92177aXavier Ducrohet                if (lastResult.isSuccess()) {
332c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet                    lastResult = scene.inflate();
333c8aec064f9f304c88f61c8c1aa3d60521b92177aXavier Ducrohet                    if (lastResult.isSuccess()) {
3345a82d8c58bf91c357c37a82b9f5e5c26f676d847Xavier Ducrohet                        lastResult = scene.render(true /*freshRender*/);
335c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet                    }
336d604ad1ad442790af53847d24060ecb097106d26Xavier Ducrohet                }
3372eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet            } finally {
3382eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet                scene.release();
3399eb6d412af6859b6c0bb969c76bbfc48eec8fd4bXavier Ducrohet                cleanupThread();
340d604ad1ad442790af53847d24060ecb097106d26Xavier Ducrohet            }
341d604ad1ad442790af53847d24060ecb097106d26Xavier Ducrohet
34219a021038f2f4683dddef651543d7298f5bd7218Xavier Ducrohet            return new BridgeRenderSession(scene, lastResult);
343c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet        } catch (Throwable t) {
344c14e7dd8ba15f517a5402ad802377b1d60784416Xavier Ducrohet            // get the real cause of the exception.
345c14e7dd8ba15f517a5402ad802377b1d60784416Xavier Ducrohet            Throwable t2 = t;
346c14e7dd8ba15f517a5402ad802377b1d60784416Xavier Ducrohet            while (t2.getCause() != null) {
347c14e7dd8ba15f517a5402ad802377b1d60784416Xavier Ducrohet                t2 = t.getCause();
348c14e7dd8ba15f517a5402ad802377b1d60784416Xavier Ducrohet            }
34919a021038f2f4683dddef651543d7298f5bd7218Xavier Ducrohet            return new BridgeRenderSession(null,
350639e1bd35231a8f71e7acc95fedaf13ace9b65a9Xavier Ducrohet                    ERROR_UNKNOWN.createResult(t2.getMessage(), t));
3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
354c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet    @Override
355fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet    public Result renderDrawable(DrawableParams params) {
356fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet        try {
357fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet            Result lastResult = SUCCESS.createResult();
358fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet            RenderDrawable action = new RenderDrawable(params);
359fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet            try {
360fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet                prepareThread();
361fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet                lastResult = action.init(params.getTimeout());
362fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet                if (lastResult.isSuccess()) {
363fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet                    lastResult = action.render();
364fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet                }
365fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet            } finally {
366fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet                action.release();
367fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet                cleanupThread();
368fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet            }
369fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet
370fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet            return lastResult;
371fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet        } catch (Throwable t) {
372fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet            // get the real cause of the exception.
373fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet            Throwable t2 = t;
374fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet            while (t2.getCause() != null) {
375fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet                t2 = t.getCause();
376fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet            }
377fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet            return ERROR_UNKNOWN.createResult(t2.getMessage(), t);
378fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet        }
379fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet    }
380fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet
381fd18f573280bbbcc549b35b548580a562bd960e2Xavier Ducrohet    @Override
3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    public void clearCaches(Object projectKey) {
3839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (projectKey != null) {
3849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            sProjectBitmapCache.remove(projectKey);
3859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            sProject9PatchCache.remove(projectKey);
3869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
38883189c985a0e617ba7856343ea8b7080c37396a7Xavier Ducrohet
3892fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet    @Override
3902fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet    public Result getViewParent(Object viewObject) {
3912fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet        if (viewObject instanceof View) {
3922fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet            return Status.SUCCESS.createResult(((View)viewObject).getParent());
3932fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet        }
3942fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet
3952fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet        throw new IllegalArgumentException("viewObject is not a View");
3962fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet    }
3972fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet
3982fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet    @Override
3992fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet    public Result getViewIndex(Object viewObject) {
4002fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet        if (viewObject instanceof View) {
4012fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet            View view = (View) viewObject;
4022fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet            ViewParent parentView = view.getParent();
4032fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet
4042fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet            if (parentView instanceof ViewGroup) {
4052fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet                Status.SUCCESS.createResult(((ViewGroup) parentView).indexOfChild(view));
4062fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet            }
4072fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet
4082fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet            return Status.SUCCESS.createResult();
4092fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet        }
4102fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet
4112fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet        throw new IllegalArgumentException("viewObject is not a View");
4122fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet    }
4132fae858db55fc6984ef923a6226b9408c37c72cbXavier Ducrohet
4149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
4152eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet     * Returns the lock for the bridge
4162eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet     */
4172eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet    public static ReentrantLock getLock() {
4182eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet        return sLock;
4192eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet    }
4202eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet
4212eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet    /**
4229eb6d412af6859b6c0bb969c76bbfc48eec8fd4bXavier Ducrohet     * Prepares the current thread for rendering.
4239eb6d412af6859b6c0bb969c76bbfc48eec8fd4bXavier Ducrohet     *
4249eb6d412af6859b6c0bb969c76bbfc48eec8fd4bXavier Ducrohet     * Note that while this can be called several time, the first call to {@link #cleanupThread()}
4259eb6d412af6859b6c0bb969c76bbfc48eec8fd4bXavier Ducrohet     * will do the clean-up, and make the thread unable to do further scene actions.
4269eb6d412af6859b6c0bb969c76bbfc48eec8fd4bXavier Ducrohet     */
4279eb6d412af6859b6c0bb969c76bbfc48eec8fd4bXavier Ducrohet    public static void prepareThread() {
4289eb6d412af6859b6c0bb969c76bbfc48eec8fd4bXavier Ducrohet        // we need to make sure the Looper has been initialized for this thread.
4299eb6d412af6859b6c0bb969c76bbfc48eec8fd4bXavier Ducrohet        // this is required for View that creates Handler objects.
4309eb6d412af6859b6c0bb969c76bbfc48eec8fd4bXavier Ducrohet        if (Looper.myLooper() == null) {
4319eb6d412af6859b6c0bb969c76bbfc48eec8fd4bXavier Ducrohet            Looper.prepare();
4329eb6d412af6859b6c0bb969c76bbfc48eec8fd4bXavier Ducrohet        }
4339eb6d412af6859b6c0bb969c76bbfc48eec8fd4bXavier Ducrohet    }
4349eb6d412af6859b6c0bb969c76bbfc48eec8fd4bXavier Ducrohet
4359eb6d412af6859b6c0bb969c76bbfc48eec8fd4bXavier Ducrohet    /**
4369eb6d412af6859b6c0bb969c76bbfc48eec8fd4bXavier Ducrohet     * Cleans up thread-specific data. After this, the thread cannot be used for scene actions.
4379eb6d412af6859b6c0bb969c76bbfc48eec8fd4bXavier Ducrohet     * <p>
4389eb6d412af6859b6c0bb969c76bbfc48eec8fd4bXavier Ducrohet     * Note that it doesn't matter how many times {@link #prepareThread()} was called, a single
4399eb6d412af6859b6c0bb969c76bbfc48eec8fd4bXavier Ducrohet     * call to this will prevent the thread from doing further scene actions
4409eb6d412af6859b6c0bb969c76bbfc48eec8fd4bXavier Ducrohet     */
4419eb6d412af6859b6c0bb969c76bbfc48eec8fd4bXavier Ducrohet    public static void cleanupThread() {
4429eb6d412af6859b6c0bb969c76bbfc48eec8fd4bXavier Ducrohet        // clean up the looper
4437f9f99ea11051614a7727dfb9f9578b518e76e3cXavier Ducrohet        Looper_Accessor.cleanupThread();
4449eb6d412af6859b6c0bb969c76bbfc48eec8fd4bXavier Ducrohet    }
4459eb6d412af6859b6c0bb969c76bbfc48eec8fd4bXavier Ducrohet
446168677c9e2f8438ec5687e3c6b0e41b986c5b230Xavier Ducrohet    public static LayoutLog getLog() {
447168677c9e2f8438ec5687e3c6b0e41b986c5b230Xavier Ducrohet        return sCurrentLog;
448168677c9e2f8438ec5687e3c6b0e41b986c5b230Xavier Ducrohet    }
449168677c9e2f8438ec5687e3c6b0e41b986c5b230Xavier Ducrohet
450168677c9e2f8438ec5687e3c6b0e41b986c5b230Xavier Ducrohet    public static void setLog(LayoutLog log) {
451168677c9e2f8438ec5687e3c6b0e41b986c5b230Xavier Ducrohet        // check only the thread currently owning the lock can do this.
452168677c9e2f8438ec5687e3c6b0e41b986c5b230Xavier Ducrohet        if (sLock.isHeldByCurrentThread() == false) {
453168677c9e2f8438ec5687e3c6b0e41b986c5b230Xavier Ducrohet            throw new IllegalStateException("scene must be acquired first. see #acquire(long)");
454168677c9e2f8438ec5687e3c6b0e41b986c5b230Xavier Ducrohet        }
455168677c9e2f8438ec5687e3c6b0e41b986c5b230Xavier Ducrohet
456168677c9e2f8438ec5687e3c6b0e41b986c5b230Xavier Ducrohet        if (log != null) {
457168677c9e2f8438ec5687e3c6b0e41b986c5b230Xavier Ducrohet            sCurrentLog = log;
458168677c9e2f8438ec5687e3c6b0e41b986c5b230Xavier Ducrohet        } else {
459168677c9e2f8438ec5687e3c6b0e41b986c5b230Xavier Ducrohet            sCurrentLog = sDefaultLog;
460168677c9e2f8438ec5687e3c6b0e41b986c5b230Xavier Ducrohet        }
461168677c9e2f8438ec5687e3c6b0e41b986c5b230Xavier Ducrohet    }
462168677c9e2f8438ec5687e3c6b0e41b986c5b230Xavier Ducrohet
4639eb6d412af6859b6c0bb969c76bbfc48eec8fd4bXavier Ducrohet    /**
4649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Returns details of a framework resource from its integer value.
4659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param value the integer value
466b353495192ba1acce94b8ab8aeeffe3c9a3bcfacXavier Ducrohet     * @return a Pair containing the resource type and name, or null if the id
467b353495192ba1acce94b8ab8aeeffe3c9a3bcfacXavier Ducrohet     *     does not match any resource.
4689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
469b353495192ba1acce94b8ab8aeeffe3c9a3bcfacXavier Ducrohet    public static Pair<ResourceType, String> resolveResourceId(int value) {
470a421f6c0ba8c354e2a81830e6402654bbf732780Xavier Ducrohet        Pair<ResourceType, String> pair = sRMap.get(value);
471a421f6c0ba8c354e2a81830e6402654bbf732780Xavier Ducrohet        if (pair == null) {
472a421f6c0ba8c354e2a81830e6402654bbf732780Xavier Ducrohet            pair = sDynamicIds.resolveId(value);
473a421f6c0ba8c354e2a81830e6402654bbf732780Xavier Ducrohet            if (pair == null) {
4744d7f301f94b9d2dda0ef109e9991ad2d77442f75Xavier Ducrohet                //System.out.println(String.format("Missing id: %1$08X (%1$d)", value));
475a421f6c0ba8c354e2a81830e6402654bbf732780Xavier Ducrohet            }
476a421f6c0ba8c354e2a81830e6402654bbf732780Xavier Ducrohet        }
477a421f6c0ba8c354e2a81830e6402654bbf732780Xavier Ducrohet        return pair;
4789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
47983189c985a0e617ba7856343ea8b7080c37396a7Xavier Ducrohet
4809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
4819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Returns the name of a framework resource whose value is an int array.
4829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param array
4839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
484b353495192ba1acce94b8ab8aeeffe3c9a3bcfacXavier Ducrohet    public static String resolveResourceId(int[] array) {
485755b46d597b8e8a616d53e2a7dfea295dd78d713Xavier Ducrohet        sIntArrayWrapper.set(array);
486755b46d597b8e8a616d53e2a7dfea295dd78d713Xavier Ducrohet        return sRArrayMap.get(sIntArrayWrapper);
4879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
48883189c985a0e617ba7856343ea8b7080c37396a7Xavier Ducrohet
4899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
4909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Returns the integer id of a framework resource, from a given resource type and resource name.
4919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param type the type of the resource
4929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param name the name of the resource.
4939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return an {@link Integer} containing the resource id, or null if no resource were found.
4949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
495b353495192ba1acce94b8ab8aeeffe3c9a3bcfacXavier Ducrohet    public static Integer getResourceId(ResourceType type, String name) {
496a421f6c0ba8c354e2a81830e6402654bbf732780Xavier Ducrohet        Map<String, Integer> map = sRevRMap.get(type);
497a421f6c0ba8c354e2a81830e6402654bbf732780Xavier Ducrohet        Integer value = null;
4989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (map != null) {
499a421f6c0ba8c354e2a81830e6402654bbf732780Xavier Ducrohet            value = map.get(name);
5009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
50183189c985a0e617ba7856343ea8b7080c37396a7Xavier Ducrohet
502a421f6c0ba8c354e2a81830e6402654bbf732780Xavier Ducrohet        if (value == null) {
503a421f6c0ba8c354e2a81830e6402654bbf732780Xavier Ducrohet            value = sDynamicIds.getId(type, name);
504a421f6c0ba8c354e2a81830e6402654bbf732780Xavier Ducrohet        }
505a421f6c0ba8c354e2a81830e6402654bbf732780Xavier Ducrohet
506a421f6c0ba8c354e2a81830e6402654bbf732780Xavier Ducrohet        return value;
5079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
50883189c985a0e617ba7856343ea8b7080c37396a7Xavier Ducrohet
5099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
510c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet     * Returns the list of possible enums for a given attribute name.
5119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
512c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet    public static Map<String, Integer> getEnumValues(String attributeName) {
513c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet        if (sEnumValueMap != null) {
514c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet            return sEnumValueMap.get(attributeName);
5159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
51683189c985a0e617ba7856343ea8b7080c37396a7Xavier Ducrohet
5179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        return null;
5189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
51983189c985a0e617ba7856343ea8b7080c37396a7Xavier Ducrohet
5209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
5217d7016e72431ad7ee595d857a19231c69efeb6deXavier Ducrohet     * Returns the platform build properties.
5227d7016e72431ad7ee595d857a19231c69efeb6deXavier Ducrohet     */
5237d7016e72431ad7ee595d857a19231c69efeb6deXavier Ducrohet    public static Map<String, String> getPlatformProperties() {
5247d7016e72431ad7ee595d857a19231c69efeb6deXavier Ducrohet        return sPlatformProperties;
5257d7016e72431ad7ee595d857a19231c69efeb6deXavier Ducrohet    }
5267d7016e72431ad7ee595d857a19231c69efeb6deXavier Ducrohet
5277d7016e72431ad7ee595d857a19231c69efeb6deXavier Ducrohet    /**
5289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Returns the bitmap for a specific path, from a specific project cache, or from the
5299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * framework cache.
5309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param value the path of the bitmap
5319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param projectKey the key of the project, or null to query the framework cache.
5329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return the cached Bitmap or null if not found.
5339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
534c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet    public static Bitmap getCachedBitmap(String value, Object projectKey) {
5359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (projectKey != null) {
5364df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project            Map<String, SoftReference<Bitmap>> map = sProjectBitmapCache.get(projectKey);
5379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (map != null) {
5384df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project                SoftReference<Bitmap> ref = map.get(value);
5394df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project                if (ref != null) {
5404df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project                    return ref.get();
5414df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project                }
5424df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project            }
5434df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project        } else {
5444df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project            SoftReference<Bitmap> ref = sFrameworkBitmapCache.get(value);
5454df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project            if (ref != null) {
5464df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project                return ref.get();
5479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
5489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5494df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project
5504df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project        return null;
5519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
5549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * Sets a bitmap in a project cache or in the framework cache.
5559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param value the path of the bitmap
5569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param bmp the Bitmap object
5579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param projectKey the key of the project, or null to put the bitmap in the framework cache.
5589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
559c2e9651bf386a1f7bf7fc706cf5424950570470cXavier Ducrohet    public static void setCachedBitmap(String value, Bitmap bmp, Object projectKey) {
5609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (projectKey != null) {
5614df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project            Map<String, SoftReference<Bitmap>> map = sProjectBitmapCache.get(projectKey);
5629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (map == null) {
5644df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project                map = new HashMap<String, SoftReference<Bitmap>>();
5659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project                sProjectBitmapCache.put(projectKey, map);
5669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
56783189c985a0e617ba7856343ea8b7080c37396a7Xavier Ducrohet
5684df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project            map.put(value, new SoftReference<Bitmap>(bmp));
5694df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project        } else {
5704df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project            sFrameworkBitmapCache.put(value, new SoftReference<Bitmap>(bmp));
5719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
5729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
5739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
5749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    /**
5752d56b273ef6e2984a4e8914fb67772b173d0a154Xavier Ducrohet     * Returns the 9 patch chunk for a specific path, from a specific project cache, or from the
5769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * framework cache.
5779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param value the path of the 9 patch
5789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @param projectKey the key of the project, or null to query the framework cache.
5799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     * @return the cached 9 patch or null if not found.
5809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     */
5812d56b273ef6e2984a4e8914fb67772b173d0a154Xavier Ducrohet    public static NinePatchChunk getCached9Patch(String value, Object projectKey) {
5829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (projectKey != null) {
5832d56b273ef6e2984a4e8914fb67772b173d0a154Xavier Ducrohet            Map<String, SoftReference<NinePatchChunk>> map = sProject9PatchCache.get(projectKey);
58483189c985a0e617ba7856343ea8b7080c37396a7Xavier Ducrohet
5859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (map != null) {
5862d56b273ef6e2984a4e8914fb67772b173d0a154Xavier Ducrohet                SoftReference<NinePatchChunk> ref = map.get(value);
5874df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project                if (ref != null) {
5884df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project                    return ref.get();
5894df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project                }
5904df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project            }
5914df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project        } else {
5922d56b273ef6e2984a4e8914fb67772b173d0a154Xavier Ducrohet            SoftReference<NinePatchChunk> ref = sFramework9PatchCache.get(value);
5934df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project            if (ref != null) {
5944df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project                return ref.get();
5959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            }
5969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
59783189c985a0e617ba7856343ea8b7080c37396a7Xavier Ducrohet
5984df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project        return null;
5999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
6002eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet
6012eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet    /**
6022eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet     * Sets a 9 patch chunk in a project cache or in the framework cache.
6032eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet     * @param value the path of the 9 patch
6042eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet     * @param ninePatch the 9 patch object
6052eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet     * @param projectKey the key of the project, or null to put the bitmap in the framework cache.
6062eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet     */
6072eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet    public static void setCached9Patch(String value, NinePatchChunk ninePatch, Object projectKey) {
6082eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet        if (projectKey != null) {
6092eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet            Map<String, SoftReference<NinePatchChunk>> map = sProject9PatchCache.get(projectKey);
6102eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet
6112eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet            if (map == null) {
6122eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet                map = new HashMap<String, SoftReference<NinePatchChunk>>();
6132eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet                sProject9PatchCache.put(projectKey, map);
6142eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet            }
6152eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet
6162eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet            map.put(value, new SoftReference<NinePatchChunk>(ninePatch));
6172eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet        } else {
6182eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet            sFramework9PatchCache.put(value, new SoftReference<NinePatchChunk>(ninePatch));
6192eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet        }
6202eea6fab1cbb0a5c8f913491c2d622c904759893Xavier Ducrohet    }
6219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
622