summaryrefslogtreecommitdiffstats
path: root/services/java
diff options
context:
space:
mode:
Diffstat (limited to 'services/java')
-rw-r--r--services/java/com/android/server/AttributeCache.java114
-rw-r--r--services/java/com/android/server/PackageManagerService.java1
-rw-r--r--services/java/com/android/server/am/ActivityManagerService.java11
3 files changed, 74 insertions, 52 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) {
- }
}
diff --git a/services/java/com/android/server/PackageManagerService.java b/services/java/com/android/server/PackageManagerService.java
index 972aa98..4ea2831 100644
--- a/services/java/com/android/server/PackageManagerService.java
+++ b/services/java/com/android/server/PackageManagerService.java
@@ -3292,6 +3292,7 @@ class PackageManagerService extends IPackageManager.Stub {
if (extras != null) {
intent.putExtras(extras);
}
+ intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
am.broadcastIntent(
null, intent,
null, null, 0, null, null, null, false, false);
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index 6d04b6b..f716571 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -17,6 +17,7 @@
package com.android.server.am;
import com.android.internal.os.BatteryStatsImpl;
+import com.android.server.AttributeCache;
import com.android.server.IntentResolver;
import com.android.server.ProcessMap;
import com.android.server.ProcessStats;
@@ -61,7 +62,6 @@ import android.content.pm.ServiceInfo;
import android.content.res.Configuration;
import android.graphics.Bitmap;
import android.net.Uri;
-import android.os.BatteryStats;
import android.os.Binder;
import android.os.Bundle;
import android.os.Environment;
@@ -10715,6 +10715,10 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
uninstallPackageLocked(ssp,
intent.getIntExtra(Intent.EXTRA_UID, -1), false);
+ AttributeCache ac = AttributeCache.instance();
+ if (ac != null) {
+ ac.removePackage(ssp);
+ }
}
}
}
@@ -11765,6 +11769,11 @@ public final class ActivityManagerService extends ActivityManagerNative implemen
Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
null, false, false, MY_PID, Process.SYSTEM_UID);
+
+ AttributeCache ac = AttributeCache.instance();
+ if (ac != null) {
+ ac.updateConfiguration(mConfiguration);
+ }
}
}