summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndroid (Google) Code Review <android-gerrit@google.com>2009-06-30 14:04:55 -0700
committerAndroid (Google) Code Review <android-gerrit@google.com>2009-06-30 14:04:55 -0700
commit6e1647a212317f4ee8bcc23948b6621a59172954 (patch)
tree50a0ac10196a017f438dbd3c4911b02ec040cf9d
parentd8de2ba42679a10db2adc11995d6596a0045ab3a (diff)
parentde7faf658cd40d34c08a98b39477055da8e19172 (diff)
downloadframeworks_base-6e1647a212317f4ee8bcc23948b6621a59172954.zip
frameworks_base-6e1647a212317f4ee8bcc23948b6621a59172954.tar.gz
frameworks_base-6e1647a212317f4ee8bcc23948b6621a59172954.tar.bz2
Merge change 5829 into donut
* changes: Fix issue #1673793: Theme styles don't apply.
-rw-r--r--include/utils/ResourceTypes.h4
-rw-r--r--libs/utils/ResourceTypes.cpp134
-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
5 files changed, 157 insertions, 107 deletions
diff --git a/include/utils/ResourceTypes.h b/include/utils/ResourceTypes.h
index 5c41ead..eb4151a 100644
--- a/include/utils/ResourceTypes.h
+++ b/include/utils/ResourceTypes.h
@@ -1441,7 +1441,7 @@ struct ResTable_type
* This is the beginning of information about an entry in the resource
* table. It holds the reference to the name of this entry, and is
* immediately followed by one of:
- * * A Res_value structures, if FLAG_COMPLEX is -not- set.
+ * * A Res_value structure, if FLAG_COMPLEX is -not- set.
* * An array of ResTable_map structures, if FLAG_COMPLEX is set.
* These supply a set of name/value mappings of data.
*/
@@ -1843,6 +1843,8 @@ private:
status_t parsePackage(
const ResTable_package* const pkg, const Header* const header);
+ void print_value(const Package* pkg, const Res_value& value) const;
+
mutable Mutex mLock;
status_t mError;
diff --git a/libs/utils/ResourceTypes.cpp b/libs/utils/ResourceTypes.cpp
index 7a33220..4a5063a 100644
--- a/libs/utils/ResourceTypes.cpp
+++ b/libs/utils/ResourceTypes.cpp
@@ -3845,7 +3845,7 @@ void print_complex(uint32_t complex, bool isFraction)
& Res_value::COMPLEX_RADIX_MASK];
printf("%f", value);
- if (isFraction) {
+ if (!isFraction) {
switch ((complex>>Res_value::COMPLEX_UNIT_SHIFT)&Res_value::COMPLEX_UNIT_MASK) {
case Res_value::COMPLEX_UNIT_PX: printf("px"); break;
case Res_value::COMPLEX_UNIT_DIP: printf("dp"); break;
@@ -3864,6 +3864,49 @@ void print_complex(uint32_t complex, bool isFraction)
}
}
+void ResTable::print_value(const Package* pkg, const Res_value& value) const
+{
+ if (value.dataType == Res_value::TYPE_NULL) {
+ printf("(null)\n");
+ } else if (value.dataType == Res_value::TYPE_REFERENCE) {
+ printf("(reference) 0x%08x\n", value.data);
+ } else if (value.dataType == Res_value::TYPE_ATTRIBUTE) {
+ printf("(attribute) 0x%08x\n", value.data);
+ } else if (value.dataType == Res_value::TYPE_STRING) {
+ size_t len;
+ const char16_t* str = pkg->header->values.stringAt(
+ value.data, &len);
+ if (str == NULL) {
+ printf("(string) null\n");
+ } else {
+ printf("(string) \"%s\"\n",
+ String8(str, len).string());
+ }
+ } else if (value.dataType == Res_value::TYPE_FLOAT) {
+ printf("(float) %g\n", *(const float*)&value.data);
+ } else if (value.dataType == Res_value::TYPE_DIMENSION) {
+ printf("(dimension) ");
+ print_complex(value.data, false);
+ printf("\n");
+ } else if (value.dataType == Res_value::TYPE_FRACTION) {
+ printf("(fraction) ");
+ print_complex(value.data, true);
+ printf("\n");
+ } else if (value.dataType >= Res_value::TYPE_FIRST_COLOR_INT
+ || value.dataType <= Res_value::TYPE_LAST_COLOR_INT) {
+ printf("(color) #%08x\n", value.data);
+ } else if (value.dataType == Res_value::TYPE_INT_BOOLEAN) {
+ printf("(boolean) %s\n", value.data ? "true" : "false");
+ } else if (value.dataType >= Res_value::TYPE_FIRST_INT
+ || value.dataType <= Res_value::TYPE_LAST_INT) {
+ printf("(int) 0x%08x or %d\n", value.data, value.data);
+ } else {
+ printf("(unknown type) t=0x%02x d=0x%08x (s=0x%04x r=0x%02x)\n",
+ (int)value.dataType, (int)value.data,
+ (int)value.size, (int)value.res0);
+ }
+}
+
void ResTable::print(bool inclValues) const
{
if (mError != 0) {
@@ -3985,27 +4028,31 @@ void ResTable::print(bool inclValues) const
continue;
}
- const Res_value* value = NULL;
+ uint16_t esize = dtohs(ent->size);
+ if ((esize&0x3) != 0) {
+ printf("NON-INTEGER ResTable_entry SIZE: %p\n", (void*)esize);
+ continue;
+ }
+ if ((thisOffset+esize) > typeSize) {
+ printf("ResTable_entry OUT OF BOUNDS: %p+%p+%p (size is %p)\n",
+ (void*)entriesStart, (void*)thisOffset,
+ (void*)esize, (void*)typeSize);
+ continue;
+ }
+
+ const Res_value* valuePtr = NULL;
+ const ResTable_map_entry* bagPtr = NULL;
+ Res_value value;
if ((dtohs(ent->flags)&ResTable_entry::FLAG_COMPLEX) != 0) {
printf("<bag>");
+ bagPtr = (const ResTable_map_entry*)ent;
} else {
- uint16_t esize = dtohs(ent->size);
- if ((esize&0x3) != 0) {
- printf("NON-INTEGER ResTable_entry SIZE: %p\n", (void*)esize);
- continue;
- }
- if ((thisOffset+esize) > typeSize) {
- printf("ResTable_entry OUT OF BOUNDS: %p+%p+%p (size is %p)\n",
- (void*)entriesStart, (void*)thisOffset,
- (void*)esize, (void*)typeSize);
- continue;
- }
-
- value = (const Res_value*)
+ valuePtr = (const Res_value*)
(((const uint8_t*)ent) + esize);
+ value.copyFrom_dtoh(*valuePtr);
printf("t=0x%02x d=0x%08x (s=0x%04x r=0x%02x)",
- (int)value->dataType, (int)dtohl(value->data),
- (int)dtohs(value->size), (int)value->res0);
+ (int)value.dataType, (int)value.data,
+ (int)value.size, (int)value.res0);
}
if ((dtohs(ent->flags)&ResTable_entry::FLAG_PUBLIC) != 0) {
@@ -4014,44 +4061,23 @@ void ResTable::print(bool inclValues) const
printf("\n");
if (inclValues) {
- if (value != NULL) {
+ if (valuePtr != NULL) {
printf(" ");
- if (value->dataType == Res_value::TYPE_NULL) {
- printf("(null)\n");
- } else if (value->dataType == Res_value::TYPE_REFERENCE) {
- printf("(reference) 0x%08x\n", value->data);
- } else if (value->dataType == Res_value::TYPE_ATTRIBUTE) {
- printf("(attribute) 0x%08x\n", value->data);
- } else if (value->dataType == Res_value::TYPE_STRING) {
- size_t len;
- const char16_t* str = pkg->header->values.stringAt(
- value->data, &len);
- if (str == NULL) {
- printf("(string) null\n");
- } else {
- printf("(string) \"%s\"\n",
- String8(str, len).string());
- }
- } else if (value->dataType == Res_value::TYPE_FLOAT) {
- printf("(float) %g\n", *(const float*)&value->data);
- } else if (value->dataType == Res_value::TYPE_DIMENSION) {
- printf("(dimension) ");
- print_complex(value->data, false);
- printf("\n");
- } else if (value->dataType == Res_value::TYPE_FRACTION) {
- printf("(fraction) ");
- print_complex(value->data, true);
- printf("\n");
- } else if (value->dataType >= Res_value::TYPE_FIRST_COLOR_INT
- || value->dataType <= Res_value::TYPE_LAST_COLOR_INT) {
- printf("(color) #%08x\n", value->data);
- } else if (value->dataType == Res_value::TYPE_INT_BOOLEAN) {
- printf("(boolean) %s\n", value->data ? "true" : "false");
- } else if (value->dataType >= Res_value::TYPE_FIRST_INT
- || value->dataType <= Res_value::TYPE_LAST_INT) {
- printf("(int) 0x%08x or %d\n", value->data, value->data);
- } else {
- printf("(unknown type)\n");
+ print_value(pkg, value);
+ } else if (bagPtr != NULL) {
+ const int N = dtohl(bagPtr->count);
+ const ResTable_map* mapPtr = (const ResTable_map*)
+ (((const uint8_t*)ent) + esize);
+ printf(" Parent=0x%08x, Count=%d\n",
+ dtohl(bagPtr->parent.ident), N);
+ for (int i=0; i<N; i++) {
+ printf(" #%i (Key=0x%08x): ",
+ i, dtohl(mapPtr->name.ident));
+ value.copyFrom_dtoh(mapPtr->value);
+ print_value(pkg, value);
+ const size_t size = dtohs(mapPtr->value.size);
+ mapPtr = (ResTable_map*)(((const uint8_t*)mapPtr)
+ + size + sizeof(*mapPtr)-sizeof(mapPtr->value));
}
}
}
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);
+ }
}
}