19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** 39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** Copyright 2007, The Android Open Source Project 49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** 59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** Licensed under the Apache License, Version 2.0 (the "License"); 69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** you may not use this file except in compliance with the License. 79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** You may obtain a copy of the License at 89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** 99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** http://www.apache.org/licenses/LICENSE-2.0 109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** 119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** Unless required by applicable law or agreed to in writing, software 129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** distributed under the License is distributed on an "AS IS" BASIS, 139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** See the License for the specific language governing permissions and 159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** limitations under the License. 169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project*/ 179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage com.android.server; 199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.Context; 21de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackbornimport android.content.pm.ActivityInfo; 229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.pm.PackageManager; 23de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackbornimport android.content.res.Configuration; 249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.res.Resources; 259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.res.TypedArray; 26de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackbornimport android.util.SparseArray; 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 28de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackbornimport java.util.HashMap; 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.WeakHashMap; 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 31de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn/** 32de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn * TODO: This should be better integrated into the system so it doesn't need 33de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn * special calls from the activity manager to clear it. 34de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn */ 35de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackbornpublic final class AttributeCache { 369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static AttributeCache sInstance = null; 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final Context mContext; 39de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn private final WeakHashMap<String, Package> mPackages = 40de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn new WeakHashMap<String, Package>(); 41de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn private final Configuration mConfiguration = new Configuration(); 429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 43de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn public final static class Package { 44de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn public final Context context; 45de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn private final SparseArray<HashMap<int[], Entry>> mMap 46de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn = new SparseArray<HashMap<int[], Entry>>(); 479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 48de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn public Package(Context c) { 49de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn context = c; 509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final static class Entry { 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final Context context; 559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final TypedArray array; 569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public Entry(Context c, TypedArray ta) { 589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project context = c; 599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project array = ta; 609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static void init(Context context) { 649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (sInstance == null) { 659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sInstance = new AttributeCache(context); 669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static AttributeCache instance() { 709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return sInstance; 719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public AttributeCache(Context context) { 749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContext = context; 759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 77de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn public void removePackage(String packageName) { 789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (this) { 79de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn mPackages.remove(packageName); 80de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn } 81de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn } 82de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn 83de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn public void updateConfiguration(Configuration config) { 84de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn synchronized (this) { 85de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn int changes = mConfiguration.updateFrom(config); 86de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn if ((changes & ~(ActivityInfo.CONFIG_FONT_SCALE | 87de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn ActivityInfo.CONFIG_KEYBOARD_HIDDEN | 88de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn ActivityInfo.CONFIG_ORIENTATION)) != 0) { 89de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn // The configurations being masked out are ones that commonly 90de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn // change so we don't want flushing the cache... all others 91de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn // will flush the cache. 92de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn mPackages.clear(); 939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 94de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn } 95de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn } 96de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn 97de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn public Entry get(String packageName, int resId, int[] styleable) { 98de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn synchronized (this) { 99de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn Package pkg = mPackages.get(packageName); 100de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn HashMap<int[], Entry> map = null; 101de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn Entry ent = null; 102de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn if (pkg != null) { 103de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn map = pkg.mMap.get(resId); 104de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn if (map != null) { 105de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn ent = map.get(styleable); 106de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn if (ent != null) { 107de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn return ent; 108de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn } 109de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn } 110de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn } else { 111de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn Context context; 1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project context = mContext.createPackageContext(packageName, 0); 1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (context == null) { 1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (PackageManager.NameNotFoundException e) { 1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 120de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn pkg = new Package(context); 121de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn mPackages.put(packageName, pkg); 1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 123de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn 124de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn if (map == null) { 125de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn map = new HashMap<int[], Entry>(); 126de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn pkg.mMap.put(resId, map); 127de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn } 128de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn 1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 130de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn ent = new Entry(pkg.context, 131de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn pkg.context.obtainStyledAttributes(resId, styleable)); 132de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn map.put(styleable, ent); 1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (Resources.NotFoundException e) { 1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 136de7faf658cd40d34c08a98b39477055da8e19172Dianne Hackborn 1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return ent; 1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 142