Merge change 4831 into donut

* changes:
  Add app version to the backup metadata
diff --git a/include/utils/ResourceTypes.h b/include/utils/ResourceTypes.h
index 9b8c302..68f9233 100644
--- a/include/utils/ResourceTypes.h
+++ b/include/utils/ResourceTypes.h
@@ -1781,7 +1781,7 @@
     void getLocales(Vector<String8>* locales) const;
 
 #ifndef HAVE_ANDROID_OS
-    void print() const;
+    void print(bool inclValues) const;
 #endif
 
 private:
diff --git a/libs/utils/ResourceTypes.cpp b/libs/utils/ResourceTypes.cpp
index 3d12dca..69d47f0 100644
--- a/libs/utils/ResourceTypes.cpp
+++ b/libs/utils/ResourceTypes.cpp
@@ -3830,9 +3830,45 @@
 #define CHAR16_ARRAY_EQ(constant, var, len) \
         ((len == (sizeof(constant)/sizeof(constant[0]))) && (0 == memcmp((var), (constant), (len))))
 
-void ResTable::print() const
+void print_complex(uint32_t complex, bool isFraction)
 {
-    printf("mError=0x%x (%s)\n", mError, strerror(mError));
+    const float MANTISSA_MULT =
+        1.0f / (1<<Res_value::COMPLEX_MANTISSA_SHIFT);
+    const float RADIX_MULTS[] = {
+        1.0f*MANTISSA_MULT, 1.0f/(1<<7)*MANTISSA_MULT,
+        1.0f/(1<<15)*MANTISSA_MULT, 1.0f/(1<<23)*MANTISSA_MULT
+    };
+
+    float value = (complex&(Res_value::COMPLEX_MANTISSA_MASK
+                   <<Res_value::COMPLEX_MANTISSA_SHIFT))
+            * RADIX_MULTS[(complex>>Res_value::COMPLEX_RADIX_SHIFT)
+                            & Res_value::COMPLEX_RADIX_MASK];
+    printf("%f", value);
+    
+    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;
+            case Res_value::COMPLEX_UNIT_SP: printf("sp"); break;
+            case Res_value::COMPLEX_UNIT_PT: printf("pt"); break;
+            case Res_value::COMPLEX_UNIT_IN: printf("in"); break;
+            case Res_value::COMPLEX_UNIT_MM: printf("mm"); break;
+            default: printf(" (unknown unit)"); break;
+        }
+    } else {
+        switch ((complex>>Res_value::COMPLEX_UNIT_SHIFT)&Res_value::COMPLEX_UNIT_MASK) {
+            case Res_value::COMPLEX_UNIT_FRACTION: printf("%%"); break;
+            case Res_value::COMPLEX_UNIT_FRACTION_PARENT: printf("%%p"); break;
+            default: printf(" (unknown unit)"); break;
+        }
+    }
+}
+
+void ResTable::print(bool inclValues) const
+{
+    if (mError != 0) {
+        printf("mError=0x%x (%s)\n", mError, strerror(mError));
+    }
 #if 0
     printf("mParams=%c%c-%c%c,\n",
             mParams.language[0], mParams.language[1],
@@ -3947,6 +3983,8 @@
                                  (void*)(entriesStart + thisOffset));
                             continue;
                         }
+                        
+                        const Res_value* value = NULL;
                         if ((dtohs(ent->flags)&ResTable_entry::FLAG_COMPLEX) != 0) {
                             printf("<bag>");
                         } else {
@@ -3962,7 +4000,7 @@
                                 continue;
                             }
                             
-                            const Res_value* value = (const Res_value*)
+                            value = (const Res_value*)
                                 (((const uint8_t*)ent) + esize);
                             printf("t=0x%02x d=0x%08x (s=0x%04x r=0x%02x)",
                                    (int)value->dataType, (int)dtohl(value->data),
@@ -3973,6 +4011,49 @@
                             printf(" (PUBLIC)");
                         }
                         printf("\n");
+                        
+                        if (inclValues) {
+                            if (value != 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");
+                                }
+                            }
+                        }
                     }
                 }
             }
diff --git a/tools/aapt/Bundle.h b/tools/aapt/Bundle.h
index 2eb7a1d..a6fedf3 100644
--- a/tools/aapt/Bundle.h
+++ b/tools/aapt/Bundle.h
@@ -34,6 +34,7 @@
           mForce(false), mGrayscaleTolerance(0), mMakePackageDirs(false),
           mUpdate(false), mExtending(false),
           mRequireLocalization(false), mPseudolocalize(false),
+          mValues(false),
           mCompressionMethod(0), mOutputAPKFile(NULL),
           mAssetSourceDir(NULL),
           mAndroidManifestFile(NULL), mPublicOutputFile(NULL),
@@ -72,6 +73,8 @@
     void setRequireLocalization(bool val) { mRequireLocalization = val; }
     bool getPseudolocalize(void) const { return mPseudolocalize; }
     void setPseudolocalize(bool val) { mPseudolocalize = val; }
+    bool getValues(void) const { return mValues; }
+    void setValues(bool val) { mValues = val; }
     int getCompressionMethod(void) const { return mCompressionMethod; }
     void setCompressionMethod(int val) { mCompressionMethod = val; }
     const char* getOutputAPKFile() const { return mOutputAPKFile; }
@@ -151,6 +154,7 @@
     bool        mExtending;
     bool        mRequireLocalization;
     bool        mPseudolocalize;
+    bool        mValues;
     int         mCompressionMethod;
     const char* mOutputAPKFile;
     const char* mAssetSourceDir;
diff --git a/tools/aapt/Command.cpp b/tools/aapt/Command.cpp
index dc91a48..503f661 100644
--- a/tools/aapt/Command.cpp
+++ b/tools/aapt/Command.cpp
@@ -196,7 +196,7 @@
             printf("\nNo resource table found.\n");
         } else {
             printf("\nResource table:\n");
-            res.print();
+            res.print(false);
         }
 
         Asset* manifestAsset = assets.openNonAsset("AndroidManifest.xml",
@@ -380,7 +380,7 @@
     }
 
     if (strcmp("resources", option) == 0) {
-        res.print();
+        res.print(bundle->getValues());
 
     } else if (strcmp("xmltree", option) == 0) {
         if (bundle->getFileSpecCount() < 3) {
@@ -732,11 +732,12 @@
                            activityIcon.string());
                 }
             }
+            
             printf("locales:");
             Vector<String8> locales;
             res.getLocales(&locales);
-            const size_t N = locales.size();
-            for (size_t i=0; i<N; i++) {
+            const size_t NL = locales.size();
+            for (size_t i=0; i<NL; i++) {
                 const char* localeStr =  locales[i].string();
                 if (localeStr == NULL || strlen(localeStr) == 0) {
                     localeStr = "--_--";
@@ -744,6 +745,24 @@
                 printf(" '%s'", localeStr);
             }
             printf("\n");
+            
+            Vector<ResTable_config> configs;
+            res.getConfigurations(&configs);
+            SortedVector<int> densities;
+            const size_t NC = configs.size();
+            for (size_t i=0; i<NC; i++) {
+                int dens = configs[i].density;
+                if (dens == 0) dens = 160;
+                densities.add(dens);
+            }
+            
+            printf("densities:");
+            const size_t ND = densities.size();
+            for (size_t i=0; i<ND; i++) {
+                printf(" '%d'", densities[i]);
+            }
+            printf("\n");
+            
             AssetDir* dir = assets.openNonAssetDir(assetsCookie, "lib");
             if (dir != NULL) {
                 if (dir->getFileCount() > 0) {
diff --git a/tools/aapt/Main.cpp b/tools/aapt/Main.cpp
index 8bf2b07..12a0445 100644
--- a/tools/aapt/Main.cpp
+++ b/tools/aapt/Main.cpp
@@ -45,7 +45,7 @@
         " %s l[ist] [-v] [-a] file.{zip,jar,apk}\n"
         "   List contents of Zip-compatible archive.\n\n", gProgName);
     fprintf(stderr,
-        " %s d[ump] WHAT file.{apk} [asset [asset ...]]\n"
+        " %s d[ump] [--values] WHAT file.{apk} [asset [asset ...]]\n"
         "   badging          Print the label and icon for the app declared in APK.\n"
         "   permissions      Print the permissions from the APK.\n"
         "   resources        Print the resource table from the APK.\n"
@@ -123,6 +123,8 @@
         "       inserts android:targetSdkVersion in to manifest.\n"
         "   --max-sdk-version\n"
         "       inserts android:maxSdkVersion in to manifest.\n"
+        "   --values\n"
+        "       when used with \"dump resources\" also includes resource values.\n"
         "   --version-code\n"
         "       inserts android:versionCode in to manifest.\n"
         "   --version-name\n"
@@ -396,6 +398,8 @@
                         goto bail;
                     }
                     bundle.setVersionName(argv[0]);
+                } else if (strcmp(cp, "-values") == 0) {
+                    bundle.setValues(true);
                 } else {
                     fprintf(stderr, "ERROR: Unknown option '-%s'\n", cp);
                     wantUsage = true;