Fix issue #1673793: Theme styles don't apply.

It turns out this was not a problem in the resource code at all.  Rather,
the system process has a cache of pre-loaded attributes it uses to avoid
continually reloading things as it needs them.  Well it turns out this
cache wasn't flushed after a package was uninstalled or a configuration
changed, so you could re-install an app where you change its style resources
so its theme now points to one that is inconsistent in the cache.

This is mostly a problem for developers, where they continually install
new versions of an app where resources have changed.  This could possibly
show up when updating an app on a normal phone, although the problem would
eventually correct itself since this cache uses weak references.

Anyway, the cache is now reworked to be flushed appropriately.

This change also includes an update to aapt to be able to dump the
contents of bags in resources.
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 @@
  * 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 @@
     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 @@
                             & 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 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 @@
                             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 @@
                         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));
                                 }
                             }
                         }