diff options
Diffstat (limited to 'services/java/com/android/server/AttributeCache.java')
-rw-r--r-- | services/java/com/android/server/AttributeCache.java | 114 |
1 files changed, 63 insertions, 51 deletions
diff --git a/services/java/com/android/server/AttributeCache.java b/services/java/com/android/server/AttributeCache.java index 459ae52..81378dc 100644 --- a/services/java/com/android/server/AttributeCache.java +++ b/services/java/com/android/server/AttributeCache.java @@ -17,56 +17,36 @@ package com.android.server; -import android.content.ComponentName; -import android.content.ContentResolver; import android.content.Context; -import android.content.SharedPreferences; -import android.content.Intent; -import android.content.BroadcastReceiver; +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.provider.Settings; -import android.util.Config; -import android.util.Log; +import android.util.SparseArray; +import java.util.HashMap; import java.util.WeakHashMap; -public final class AttributeCache extends BroadcastReceiver { +/** + * 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<Key, Entry> mMap = - new WeakHashMap<Key, Entry>(); - private final WeakHashMap<String, Context> mContexts = - new WeakHashMap<String, Context>(); + private final WeakHashMap<String, Package> mPackages = + new WeakHashMap<String, Package>(); + private final Configuration mConfiguration = new Configuration(); - final static class Key { - public final String packageName; - public final int resId; - public final int[] styleable; - - public Key(String inPackageName, int inResId, int[] inStyleable) { - packageName = inPackageName; - resId = inResId; - styleable = inStyleable; - } + public final static class Package { + public final Context context; + private final SparseArray<HashMap<int[], Entry>> mMap + = new SparseArray<HashMap<int[], Entry>>(); - @Override public boolean equals(Object obj) { - try { - if (obj != null) { - Key other = (Key)obj; - return packageName.equals(other.packageName) - && resId == other.resId - && styleable == other.styleable; - } - } catch (ClassCastException e) { - } - return false; - } - - @Override public int hashCode() { - return packageName.hashCode() + resId; + public Package(Context c) { + context = c; } } @@ -94,36 +74,68 @@ public final class AttributeCache extends BroadcastReceiver { mContext = context; } - public Entry get(String packageName, int resId, int[] styleable) { + public void removePackage(String packageName) { synchronized (this) { - Key key = new Key(packageName, resId, styleable); - Entry ent = mMap.get(key); - if (ent != null) { - return ent; + 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(); } - Context context = mContexts.get(packageName); - if (context == null) { + } + } + + public Entry get(String packageName, int resId, int[] styleable) { + 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.createPackageContext(packageName, 0); if (context == null) { return null; } - mContexts.put(packageName, context); } 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(context, - context.obtainStyledAttributes(resId, styleable)); - mMap.put(key, ent); + ent = new Entry(pkg.context, + pkg.context.obtainStyledAttributes(resId, styleable)); + map.put(styleable, ent); } catch (Resources.NotFoundException e) { return null; } + return ent; } } - @Override public void onReceive(Context context, Intent intent) { - } } |