diff options
Diffstat (limited to 'services/java')
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); + } } } |
