• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2 **
3 ** Copyright 2007, The Android Open Source Project
4 **
5 ** Licensed under the Apache License, Version 2.0 (the "License");
6 ** you may not use this file except in compliance with the License.
7 ** You may obtain a copy of the License at
8 **
9 **     http://www.apache.org/licenses/LICENSE-2.0
10 **
11 ** Unless required by applicable law or agreed to in writing, software
12 ** distributed under the License is distributed on an "AS IS" BASIS,
13 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 ** See the License for the specific language governing permissions and
15 ** limitations under the License.
16 */
17 
18 package com.android.server;
19 
20 import android.content.Context;
21 import android.content.pm.ActivityInfo;
22 import android.content.pm.PackageManager;
23 import android.content.res.Configuration;
24 import android.content.res.Resources;
25 import android.content.res.TypedArray;
26 import android.util.SparseArray;
27 
28 import java.util.HashMap;
29 import java.util.WeakHashMap;
30 
31 /**
32  * TODO: This should be better integrated into the system so it doesn't need
33  * special calls from the activity manager to clear it.
34  */
35 public final class AttributeCache {
36     private static AttributeCache sInstance = null;
37 
38     private final Context mContext;
39     private final WeakHashMap<String, Package> mPackages =
40             new WeakHashMap<String, Package>();
41     private final Configuration mConfiguration = new Configuration();
42 
43     public final static class Package {
44         public final Context context;
45         private final SparseArray<HashMap<int[], Entry>> mMap
46                 = new SparseArray<HashMap<int[], Entry>>();
47 
Package(Context c)48         public Package(Context c) {
49             context = c;
50         }
51     }
52 
53     public final static class Entry {
54         public final Context context;
55         public final TypedArray array;
56 
Entry(Context c, TypedArray ta)57         public Entry(Context c, TypedArray ta) {
58             context = c;
59             array = ta;
60         }
61     }
62 
init(Context context)63     public static void init(Context context) {
64         if (sInstance == null) {
65             sInstance = new AttributeCache(context);
66         }
67     }
68 
instance()69     public static AttributeCache instance() {
70         return sInstance;
71     }
72 
AttributeCache(Context context)73     public AttributeCache(Context context) {
74         mContext = context;
75     }
76 
removePackage(String packageName)77     public void removePackage(String packageName) {
78         synchronized (this) {
79             mPackages.remove(packageName);
80         }
81     }
82 
updateConfiguration(Configuration config)83     public void updateConfiguration(Configuration config) {
84         synchronized (this) {
85             int changes = mConfiguration.updateFrom(config);
86             if ((changes & ~(ActivityInfo.CONFIG_FONT_SCALE |
87                     ActivityInfo.CONFIG_KEYBOARD_HIDDEN |
88                     ActivityInfo.CONFIG_ORIENTATION)) != 0) {
89                 // The configurations being masked out are ones that commonly
90                 // change so we don't want flushing the cache... all others
91                 // will flush the cache.
92                 mPackages.clear();
93             }
94         }
95     }
96 
get(String packageName, int resId, int[] styleable)97     public Entry get(String packageName, int resId, int[] styleable) {
98         synchronized (this) {
99             Package pkg = mPackages.get(packageName);
100             HashMap<int[], Entry> map = null;
101             Entry ent = null;
102             if (pkg != null) {
103                 map = pkg.mMap.get(resId);
104                 if (map != null) {
105                     ent = map.get(styleable);
106                     if (ent != null) {
107                         return ent;
108                     }
109                 }
110             } else {
111                 Context context;
112                 try {
113                     context = mContext.createPackageContext(packageName, 0);
114                     if (context == null) {
115                         return null;
116                     }
117                 } catch (PackageManager.NameNotFoundException e) {
118                     return null;
119                 }
120                 pkg = new Package(context);
121                 mPackages.put(packageName, pkg);
122             }
123 
124             if (map == null) {
125                 map = new HashMap<int[], Entry>();
126                 pkg.mMap.put(resId, map);
127             }
128 
129             try {
130                 ent = new Entry(pkg.context,
131                         pkg.context.obtainStyledAttributes(resId, styleable));
132                 map.put(styleable, ent);
133             } catch (Resources.NotFoundException e) {
134                 return null;
135             }
136 
137             return ent;
138         }
139     }
140 }
141 
142