diff options
Diffstat (limited to 'services/core/java/com/android/server/AttributeCache.java')
-rw-r--r-- | services/core/java/com/android/server/AttributeCache.java | 143 |
1 files changed, 143 insertions, 0 deletions
diff --git a/services/core/java/com/android/server/AttributeCache.java b/services/core/java/com/android/server/AttributeCache.java new file mode 100644 index 0000000..427dbc0 --- /dev/null +++ b/services/core/java/com/android/server/AttributeCache.java @@ -0,0 +1,143 @@ +/* +** +** Copyright 2007, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + +package com.android.server; + +import android.content.Context; +import android.content.pm.ActivityInfo; +import android.content.pm.PackageManager; +import android.content.res.Configuration; +import android.content.res.Resources; +import android.content.res.TypedArray; +import android.os.UserHandle; +import android.util.SparseArray; + +import java.util.HashMap; +import java.util.WeakHashMap; + +/** + * TODO: This should be better integrated into the system so it doesn't need + * special calls from the activity manager to clear it. + */ +public final class AttributeCache { + private static AttributeCache sInstance = null; + + private final Context mContext; + private final WeakHashMap<String, Package> mPackages = + new WeakHashMap<String, Package>(); + private final Configuration mConfiguration = new Configuration(); + + public final static class Package { + public final Context context; + private final SparseArray<HashMap<int[], Entry>> mMap + = new SparseArray<HashMap<int[], Entry>>(); + + public Package(Context c) { + context = c; + } + } + + public final static class Entry { + public final Context context; + public final TypedArray array; + + public Entry(Context c, TypedArray ta) { + context = c; + array = ta; + } + } + + public static void init(Context context) { + if (sInstance == null) { + sInstance = new AttributeCache(context); + } + } + + public static AttributeCache instance() { + return sInstance; + } + + public AttributeCache(Context context) { + mContext = context; + } + + public void removePackage(String packageName) { + synchronized (this) { + mPackages.remove(packageName); + } + } + + public void updateConfiguration(Configuration config) { + synchronized (this) { + int changes = mConfiguration.updateFrom(config); + if ((changes & ~(ActivityInfo.CONFIG_FONT_SCALE | + ActivityInfo.CONFIG_KEYBOARD_HIDDEN | + ActivityInfo.CONFIG_ORIENTATION)) != 0) { + // The configurations being masked out are ones that commonly + // change so we don't want flushing the cache... all others + // will flush the cache. + mPackages.clear(); + } + } + } + + public Entry get(String packageName, int resId, int[] styleable, int userId) { + synchronized (this) { + Package pkg = mPackages.get(packageName); + HashMap<int[], Entry> map = null; + Entry ent = null; + if (pkg != null) { + map = pkg.mMap.get(resId); + if (map != null) { + ent = map.get(styleable); + if (ent != null) { + return ent; + } + } + } else { + Context context; + try { + context = mContext.createPackageContextAsUser(packageName, 0, + new UserHandle(userId)); + if (context == null) { + return null; + } + } catch (PackageManager.NameNotFoundException e) { + return null; + } + pkg = new Package(context); + mPackages.put(packageName, pkg); + } + + if (map == null) { + map = new HashMap<int[], Entry>(); + pkg.mMap.put(resId, map); + } + + try { + ent = new Entry(pkg.context, + pkg.context.obtainStyledAttributes(resId, styleable)); + map.put(styleable, ent); + } catch (Resources.NotFoundException e) { + return null; + } + + return ent; + } + } +} + |