summaryrefslogtreecommitdiffstats
path: root/services/core/java/com/android/server/AttributeCache.java
diff options
context:
space:
mode:
Diffstat (limited to 'services/core/java/com/android/server/AttributeCache.java')
-rw-r--r--services/core/java/com/android/server/AttributeCache.java143
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;
+ }
+ }
+}
+