blob: 81613c6a9fdba1b9d8abf7f310b78854b4f6b650 [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
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
18package com.android.server;
19
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080020import android.content.Context;
Dianne Hackbornde7faf62009-06-30 13:27:30 -070021import android.content.pm.ActivityInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080022import android.content.pm.PackageManager;
Dianne Hackbornde7faf62009-06-30 13:27:30 -070023import android.content.res.Configuration;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080024import android.content.res.Resources;
25import android.content.res.TypedArray;
Dianne Hackbornbb4ca522012-12-03 14:09:06 -080026import android.os.UserHandle;
Dianne Hackbornde7faf62009-06-30 13:27:30 -070027import android.util.SparseArray;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080028
Dianne Hackbornde7faf62009-06-30 13:27:30 -070029import java.util.HashMap;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080030import java.util.WeakHashMap;
31
Dianne Hackbornde7faf62009-06-30 13:27:30 -070032/**
33 * TODO: This should be better integrated into the system so it doesn't need
34 * special calls from the activity manager to clear it.
35 */
36public final class AttributeCache {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080037 private static AttributeCache sInstance = null;
Dianne Hackbornbb4ca522012-12-03 14:09:06 -080038
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080039 private final Context mContext;
Dianne Hackbornbb4ca522012-12-03 14:09:06 -080040 private final SparseArray<WeakHashMap<String, Package>> mPackages =
41 new SparseArray<WeakHashMap<String, Package>>();
Dianne Hackbornde7faf62009-06-30 13:27:30 -070042 private final Configuration mConfiguration = new Configuration();
Dianne Hackbornbb4ca522012-12-03 14:09:06 -080043
Dianne Hackbornde7faf62009-06-30 13:27:30 -070044 public final static class Package {
45 public final Context context;
46 private final SparseArray<HashMap<int[], Entry>> mMap
47 = new SparseArray<HashMap<int[], Entry>>();
Dianne Hackbornbb4ca522012-12-03 14:09:06 -080048
Dianne Hackbornde7faf62009-06-30 13:27:30 -070049 public Package(Context c) {
50 context = c;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080051 }
52 }
Dianne Hackbornbb4ca522012-12-03 14:09:06 -080053
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080054 public final static class Entry {
55 public final Context context;
56 public final TypedArray array;
Dianne Hackbornbb4ca522012-12-03 14:09:06 -080057
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080058 public Entry(Context c, TypedArray ta) {
59 context = c;
60 array = ta;
61 }
62 }
Dianne Hackbornbb4ca522012-12-03 14:09:06 -080063
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080064 public static void init(Context context) {
65 if (sInstance == null) {
66 sInstance = new AttributeCache(context);
67 }
68 }
Dianne Hackbornbb4ca522012-12-03 14:09:06 -080069
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080070 public static AttributeCache instance() {
71 return sInstance;
72 }
Dianne Hackbornbb4ca522012-12-03 14:09:06 -080073
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080074 public AttributeCache(Context context) {
75 mContext = context;
76 }
Dianne Hackbornbb4ca522012-12-03 14:09:06 -080077
Dianne Hackbornde7faf62009-06-30 13:27:30 -070078 public void removePackage(String packageName) {
79 synchronized (this) {
Dianne Hackbornbb4ca522012-12-03 14:09:06 -080080 for (int i=0; i<mPackages.size(); i++) {
81 mPackages.valueAt(i).remove(packageName);
82 }
Dianne Hackbornde7faf62009-06-30 13:27:30 -070083 }
84 }
Dianne Hackbornbb4ca522012-12-03 14:09:06 -080085
Dianne Hackbornde7faf62009-06-30 13:27:30 -070086 public void updateConfiguration(Configuration config) {
87 synchronized (this) {
88 int changes = mConfiguration.updateFrom(config);
89 if ((changes & ~(ActivityInfo.CONFIG_FONT_SCALE |
90 ActivityInfo.CONFIG_KEYBOARD_HIDDEN |
91 ActivityInfo.CONFIG_ORIENTATION)) != 0) {
92 // The configurations being masked out are ones that commonly
93 // change so we don't want flushing the cache... all others
94 // will flush the cache.
95 mPackages.clear();
96 }
97 }
98 }
Dianne Hackbornbb4ca522012-12-03 14:09:06 -080099
100 public void removeUser(int userId) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800101 synchronized (this) {
Dianne Hackbornbb4ca522012-12-03 14:09:06 -0800102 mPackages.remove(userId);
103 }
104 }
105
106 public Entry get(int userId, String packageName, int resId, int[] styleable) {
107 synchronized (this) {
108 WeakHashMap<String, Package> packages = mPackages.get(userId);
109 if (packages == null) {
110 packages = new WeakHashMap<String, Package>();
111 mPackages.put(userId, packages);
112 }
113 Package pkg = packages.get(packageName);
Dianne Hackbornde7faf62009-06-30 13:27:30 -0700114 HashMap<int[], Entry> map = null;
115 Entry ent = null;
116 if (pkg != null) {
117 map = pkg.mMap.get(resId);
118 if (map != null) {
119 ent = map.get(styleable);
120 if (ent != null) {
121 return ent;
122 }
123 }
124 } else {
125 Context context;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800126 try {
Dianne Hackbornbb4ca522012-12-03 14:09:06 -0800127 context = mContext.createPackageContextAsUser(packageName, 0,
128 new UserHandle(userId));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800129 if (context == null) {
130 return null;
131 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800132 } catch (PackageManager.NameNotFoundException e) {
133 return null;
134 }
Dianne Hackbornde7faf62009-06-30 13:27:30 -0700135 pkg = new Package(context);
Dianne Hackbornbb4ca522012-12-03 14:09:06 -0800136 packages.put(packageName, pkg);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800137 }
Dianne Hackbornde7faf62009-06-30 13:27:30 -0700138
139 if (map == null) {
140 map = new HashMap<int[], Entry>();
141 pkg.mMap.put(resId, map);
142 }
143
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800144 try {
Dianne Hackbornde7faf62009-06-30 13:27:30 -0700145 ent = new Entry(pkg.context,
146 pkg.context.obtainStyledAttributes(resId, styleable));
147 map.put(styleable, ent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800148 } catch (Resources.NotFoundException e) {
149 return null;
150 }
Dianne Hackbornde7faf62009-06-30 13:27:30 -0700151
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800152 return ent;
153 }
154 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800155}
156