]> git.saurik.com Git - android/aapt.git/commitdiff
resolved conflicts for merge of ea9e6d24 to honeycomb-plus-aosp
authorXavier Ducrohet <xav@android.com>
Thu, 21 Jul 2011 00:45:11 +0000 (17:45 -0700)
committerXavier Ducrohet <xav@android.com>
Thu, 21 Jul 2011 00:45:11 +0000 (17:45 -0700)
Change-Id: I8e047147a4d2c899b6654c03a5f32b04d929e602

1  2 
Command.cpp
Package.cpp
Resource.cpp

diff --combined Command.cpp
index 2f9e9bef8218a9d40154eb78f329e5f23a47f0b4,3bc5fa1c34c3373cab8d756d4ef42a09e70687af..daf53e06bd7566457694975f15d7df616eeb74d6
@@@ -198,10 -198,8 +198,10 @@@ int doList(Bundle* bundle
          if (&res == NULL) {
              printf("\nNo resource table found.\n");
          } else {
 +#ifndef HAVE_ANDROID_OS
              printf("\nResource table:\n");
              res.print(false);
 +#endif
          }
  
          Asset* manifestAsset = assets.openNonAsset("AndroidManifest.xml",
@@@ -291,27 -289,6 +291,27 @@@ static int32_t getIntegerAttribute(cons
      return value.data;
  }
  
 +static int32_t getResolvedIntegerAttribute(const ResTable* resTable, const ResXMLTree& tree,
 +        uint32_t attrRes, String8* outError, int32_t defValue = -1)
 +{
 +    ssize_t idx = indexOfAttribute(tree, attrRes);
 +    if (idx < 0) {
 +        return defValue;
 +    }
 +    Res_value value;
 +    if (tree.getAttributeValue(idx, &value) != NO_ERROR) {
 +        if (value.dataType == Res_value::TYPE_REFERENCE) {
 +            resTable->resolveReference(&value, 0);
 +        }
 +        if (value.dataType < Res_value::TYPE_FIRST_INT
 +                || value.dataType > Res_value::TYPE_LAST_INT) {
 +            if (outError != NULL) *outError = "attribute is not an integer value";
 +            return defValue;
 +        }
 +    }
 +    return value.data;
 +}
 +
  static String8 getResolvedAttribute(const ResTable* resTable, const ResXMLTree& tree,
          uint32_t attrRes, String8* outError)
  {
  // These are attribute resource constants for the platform, as found
  // in android.R.attr
  enum {
 +    LABEL_ATTR = 0x01010001,
 +    ICON_ATTR = 0x01010002,
      NAME_ATTR = 0x01010003,
      VERSION_CODE_ATTR = 0x0101021b,
      VERSION_NAME_ATTR = 0x0101021c,
 -    LABEL_ATTR = 0x01010001,
 -    ICON_ATTR = 0x01010002,
 +    SCREEN_ORIENTATION_ATTR = 0x0101001e,
      MIN_SDK_VERSION_ATTR = 0x0101020c,
      MAX_SDK_VERSION_ATTR = 0x01010271,
      REQ_TOUCH_SCREEN_ATTR = 0x01010227,
      REQUIRED_ATTR = 0x0101028e,
      SCREEN_SIZE_ATTR = 0x010102ca,
      SCREEN_DENSITY_ATTR = 0x010102cb,
 +    REQUIRES_SMALLEST_WIDTH_DP_ATTR = 0x01010364,
 +    COMPATIBLE_WIDTH_LIMIT_DP_ATTR = 0x01010365,
 +    LARGEST_WIDTH_LIMIT_DP_ATTR = 0x01010366,
  };
  
  const char *getComponentName(String8 &pkgName, String8 &componentName) {
@@@ -448,24 -421,6 +448,24 @@@ int doDump(Bundle* bundle
          return 1;
      }
  
 +    // Make a dummy config for retrieving resources...  we need to supply
 +    // non-default values for some configs so that we can retrieve resources
 +    // in the app that don't have a default.  The most important of these is
 +    // the API version because key resources like icons will have an implicit
 +    // version if they are using newer config types like density.
 +    ResTable_config config;
 +    config.language[0] = 'e';
 +    config.language[1] = 'n';
 +    config.country[0] = 'U';
 +    config.country[1] = 'S';
 +    config.orientation = ResTable_config::ORIENTATION_PORT;
 +    config.density = ResTable_config::DENSITY_MEDIUM;
 +    config.sdkVersion = 10000; // Very high.
 +    config.screenWidthDp = 320;
 +    config.screenHeightDp = 480;
 +    config.smallestScreenWidthDp = 320;
 +    assets.setConfiguration(config);
 +
      const ResTable& res = assets.getResources(false);
      if (&res == NULL) {
          fprintf(stderr, "ERROR: dump failed because no resource table was found\n");
      }
  
      if (strcmp("resources", option) == 0) {
 +#ifndef HAVE_ANDROID_OS
          res.print(bundle->getValues());
 -
 +#endif
      } else if (strcmp("xmltree", option) == 0) {
          if (bundle->getFileSpecCount() < 3) {
              fprintf(stderr, "ERROR: no dump xmltree resource file specified\n");
                  }
              }
          } else if (strcmp("badging", option) == 0) {
 +            Vector<String8> locales;
 +            res.getLocales(&locales);
 +
 +            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);
 +            }
 +
              size_t len;
              ResXMLTree::event_code_t code;
              int depth = 0;
              bool specTouchscreenFeature = false; // touchscreen-related
              bool specMultitouchFeature = false;
              bool reqDistinctMultitouchFeature = false;
 +            bool specScreenPortraitFeature = false;
 +            bool specScreenLandscapeFeature = false;
 +            bool reqScreenPortraitFeature = false;
 +            bool reqScreenLandscapeFeature = false;
              // 2.2 also added some other features that apps can request, but that
              // have no corresponding permission, so we cannot implement any
              // back-compatibility heuristic for them. The below are thus unnecessary
              int largeScreen = 1;
              int xlargeScreen = 1;
              int anyDensity = 1;
 +            int requiresSmallestWidthDp = 0;
 +            int compatibleWidthLimitDp = 0;
 +            int largestWidthLimitDp = 0;
              String8 pkg;
              String8 activityName;
              String8 activityLabel;
                      } else if (depth < 3) {
                          if (withinActivity && isMainActivity && isLauncherActivity) {
                              const char *aName = getComponentName(pkg, activityName);
 +                            printf("launchable-activity:");
                              if (aName != NULL) {
 -                                printf("launchable activity name='%s'", aName);
 +                                printf(" name='%s' ", aName);
                              }
 -                            printf("label='%s' icon='%s'\n",
 +                            printf(" label='%s' icon='%s'\n",
                                      activityLabel.string(),
                                      activityIcon.string());
                          }
                      withinApplication = false;
                      if (tag == "application") {
                          withinApplication = true;
 -                        String8 label = getResolvedAttribute(&res, tree, LABEL_ATTR, &error);
 -                         if (error != "") {
 -                             fprintf(stderr, "ERROR getting 'android:label' attribute: %s\n", error.string());
 -                             goto bail;
 +
 +                        String8 label;
 +                        const size_t NL = locales.size();
 +                        for (size_t i=0; i<NL; i++) {
 +                            const char* localeStr =  locales[i].string();
 +                            assets.setLocale(localeStr != NULL ? localeStr : "");
 +                            String8 llabel = getResolvedAttribute(&res, tree, LABEL_ATTR, &error);
 +                            if (llabel != "") {
 +                                if (localeStr == NULL || strlen(localeStr) == 0) {
 +                                    label = llabel;
 +                                    printf("application-label:'%s'\n", llabel.string());
 +                                } else {
 +                                    if (label == "") {
 +                                        label = llabel;
 +                                    }
 +                                    printf("application-label-%s:'%s'\n", localeStr,
 +                                            llabel.string());
 +                                }
 +                            }
                          }
 -                        printf("application: label='%s' ", label.string());
 +
 +                        ResTable_config tmpConfig = config;
 +                        const size_t ND = densities.size();
 +                        for (size_t i=0; i<ND; i++) {
 +                            tmpConfig.density = densities[i];
 +                            assets.setConfiguration(tmpConfig);
 +                            String8 icon = getResolvedAttribute(&res, tree, ICON_ATTR, &error);
 +                            if (icon != "") {
 +                                printf("application-icon-%d:'%s'\n", densities[i], icon.string());
 +                            }
 +                        }
 +                        assets.setConfiguration(config);
 +
                          String8 icon = getResolvedAttribute(&res, tree, ICON_ATTR, &error);
                          if (error != "") {
                              fprintf(stderr, "ERROR getting 'android:icon' attribute: %s\n", error.string());
                              goto bail;
                          }
 -                        printf("icon='%s'\n", icon.string());
                          int32_t testOnly = getIntegerAttribute(tree, TEST_ONLY_ATTR, &error, 0);
                          if (error != "") {
                              fprintf(stderr, "ERROR getting 'android:testOnly' attribute: %s\n", error.string());
                              goto bail;
                          }
 +                        printf("application: label='%s' ", label.string());
 +                        printf("icon='%s'\n", icon.string());
                          if (testOnly != 0) {
                              printf("testOnly='%d'\n", testOnly);
                          }
                                  XLARGE_SCREEN_ATTR, NULL, 1);
                          anyDensity = getIntegerAttribute(tree,
                                  ANY_DENSITY_ATTR, NULL, 1);
 +                        requiresSmallestWidthDp = getIntegerAttribute(tree,
 +                                REQUIRES_SMALLEST_WIDTH_DP_ATTR, NULL, 0);
 +                        compatibleWidthLimitDp = getIntegerAttribute(tree,
 +                                COMPATIBLE_WIDTH_LIMIT_DP_ATTR, NULL, 0);
 +                        largestWidthLimitDp = getIntegerAttribute(tree,
 +                                LARGEST_WIDTH_LIMIT_DP_ATTR, NULL, 0);
                      } else if (tag == "uses-feature") {
                          String8 name = getAttribute(tree, NAME_ATTR, &error);
  
                                  // these have no corresponding permission to check for,
                                  // but should imply the foundational telephony permission
                                  reqTelephonySubFeature = true;
 +                            } else if (name == "android.hardware.screen.portrait") {
 +                                specScreenPortraitFeature = true;
 +                            } else if (name == "android.hardware.screen.landscape") {
 +                                specScreenLandscapeFeature = true;
                              }
                              printf("uses-feature%s:'%s'\n",
                                      req ? "" : "-not-required", name.string());
                              fprintf(stderr, "ERROR getting 'android:icon' attribute: %s\n", error.string());
                              goto bail;
                          }
 +
 +                        int32_t orien = getResolvedIntegerAttribute(&res, tree,
 +                                SCREEN_ORIENTATION_ATTR, &error);
 +                        if (error == "") {
 +                            if (orien == 0 || orien == 6 || orien == 8) {
 +                                // Requests landscape, sensorLandscape, or reverseLandscape.
 +                                reqScreenLandscapeFeature = true;
 +                            } else if (orien == 1 || orien == 7 || orien == 9) {
 +                                // Requests portrait, sensorPortrait, or reversePortrait.
 +                                reqScreenPortraitFeature = true;
 +                            }
 +                        }
                      } else if (tag == "uses-library") {
                          String8 libraryName = getAttribute(tree, NAME_ATTR, &error);
                          if (error != "") {
                  printf("uses-feature:'android.hardware.touchscreen.multitouch'\n");
              }
  
 +            // Landscape/portrait-related compatibility logic
 +            if (!specScreenLandscapeFeature && !specScreenPortraitFeature) {
 +                // If the app has specified any activities in its manifest
 +                // that request a specific orientation, then assume that
 +                // orientation is required.
 +                if (reqScreenLandscapeFeature) {
 +                    printf("uses-feature:'android.hardware.screen.landscape'\n");
 +                }
 +                if (reqScreenPortraitFeature) {
 +                    printf("uses-feature:'android.hardware.screen.portrait'\n");
 +                }
 +            }
 +
              if (hasMainActivity) {
                  printf("main\n");
              }
                  printf("other-services\n");
              }
  
 +            // For modern apps, if screen size buckets haven't been specified
 +            // but the new width ranges have, then infer the buckets from them.
 +            if (smallScreen > 0 && normalScreen > 0 && largeScreen > 0 && xlargeScreen > 0
 +                    && requiresSmallestWidthDp > 0) {
 +                int compatWidth = compatibleWidthLimitDp;
 +                if (compatWidth <= 0) compatWidth = requiresSmallestWidthDp;
 +                if (requiresSmallestWidthDp <= 240 && compatWidth >= 240) {
 +                    smallScreen = -1;
 +                } else {
 +                    smallScreen = 0;
 +                }
 +                if (requiresSmallestWidthDp <= 320 && compatWidth >= 320) {
 +                    normalScreen = -1;
 +                } else {
 +                    normalScreen = 0;
 +                }
 +                if (requiresSmallestWidthDp <= 480 && compatWidth >= 480) {
 +                    largeScreen = -1;
 +                } else {
 +                    largeScreen = 0;
 +                }
 +                if (requiresSmallestWidthDp <= 720 && compatWidth >= 720) {
 +                    xlargeScreen = -1;
 +                } else {
 +                    xlargeScreen = 0;
 +                }
 +            }
 +
              // Determine default values for any unspecified screen sizes,
              // based on the target SDK of the package.  As of 4 (donut)
              // the screen size support was introduced, so all default to
                  xlargeScreen = targetSdk >= 9 ? -1 : 0;
              }
              if (anyDensity > 0) {
 -                anyDensity = targetSdk >= 4 ? -1 : 0;
 +                anyDensity = (targetSdk >= 4 || requiresSmallestWidthDp > 0
 +                        || compatibleWidthLimitDp > 0) ? -1 : 0;
              }
              printf("supports-screens:");
              if (smallScreen != 0) printf(" 'small'");
              if (largeScreen != 0) printf(" 'large'");
              if (xlargeScreen != 0) printf(" 'xlarge'");
              printf("\n");
 -
              printf("supports-any-density: '%s'\n", anyDensity ? "true" : "false");
 +            if (requiresSmallestWidthDp > 0) {
 +                printf("requires-smallest-width:'%d'\n", requiresSmallestWidthDp);
 +            }
 +            if (compatibleWidthLimitDp > 0) {
 +                printf("compatible-width-limit:'%d'\n", compatibleWidthLimitDp);
 +            }
 +            if (largestWidthLimitDp > 0) {
 +                printf("largest-width-limit:'%d'\n", largestWidthLimitDp);
 +            }
  
              printf("locales:");
 -            Vector<String8> locales;
 -            res.getLocales(&locales);
              const size_t NL = locales.size();
              for (size_t i=0; i<NL; i++) {
                  const char* localeStr =  locales[i].string();
              }
              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++) {
@@@ -1659,3 -1504,25 +1659,25 @@@ bail
      }
      return retVal;
  }
+ /*
+  * Do PNG Crunching
+  * PRECONDITIONS
+  *  -S flag points to a source directory containing drawable* folders
+  *  -C flag points to destination directory. The folder structure in the
+  *     source directory will be mirrored to the destination (cache) directory
+  *
+  * POSTCONDITIONS
+  *  Destination directory will be updated to match the PNG files in
+  *  the source directory. 
+  */
+ int doCrunch(Bundle* bundle)
+ {
+     fprintf(stdout, "Crunching PNG Files in ");
+     fprintf(stdout, "source dir: %s\n", bundle->getResourceSourceDirs()[0]);
+     fprintf(stdout, "To destination dir: %s\n", bundle->getCrunchedOutputDir());
+     updatePreProcessedCache(bundle);
+     return NO_ERROR;
+ }
diff --combined Package.cpp
index 57e20b38a66411b1121239c74d63e33dff57e7f2,62af30e77b70c9a4af5b5f61a173068c8a46b3ef..c9f687088b4f1afb92b22c22a78ff50c4372fff3
@@@ -33,8 -33,8 +33,8 @@@ static const char* kNoCompressExt[] = 
  
  /* fwd decls, so I can write this downward */
  ssize_t processAssets(Bundle* bundle, ZipFile* zip, const sp<AaptAssets>& assets);
 -ssize_t processAssets(Bundle* bundle, ZipFile* zip,
 -                        const sp<AaptDir>& dir, const AaptGroupEntry& ge);
 +ssize_t processAssets(Bundle* bundle, ZipFile* zip, const sp<AaptDir>& dir,
 +                        const AaptGroupEntry& ge, const ResourceFilter* filter);
  bool processFile(Bundle* bundle, ZipFile* zip,
                          const sp<AaptGroup>& group, const sp<AaptFile>& file);
  bool okayToCompress(Bundle* bundle, const String8& pathName);
@@@ -50,6 -50,11 +50,11 @@@ ssize_t processJarFiles(Bundle* bundle
  status_t writeAPK(Bundle* bundle, const sp<AaptAssets>& assets,
                         const String8& outputFile)
  {
+     #if BENCHMARK
+     fprintf(stdout, "BENCHMARK: Starting APK Bundling \n");
+     long startAPKTime = clock();
+     #endif /* BENCHMARK */
      status_t result = NO_ERROR;
      ZipFile* zip = NULL;
      int count;
@@@ -197,6 -202,10 +202,10 @@@ bail
  
      if (result == NO_ERROR && bundle->getVerbose())
          printf("Done!\n");
+     #if BENCHMARK
+     fprintf(stdout, "BENCHMARK: End APK Bundling. Time Elapsed: %f ms \n",(clock() - startAPKTime)/1000.0);
+     #endif /* BENCHMARK */
      return result;
  }
  
@@@ -214,45 -223,34 +223,45 @@@ ssize_t processAssets(Bundle* bundle, Z
      const size_t N = assets->getGroupEntries().size();
      for (size_t i=0; i<N; i++) {
          const AaptGroupEntry& ge = assets->getGroupEntries()[i];
 -        if (!filter.match(ge.toParams())) {
 -            continue;
 -        }
 -        ssize_t res = processAssets(bundle, zip, assets, ge);
 +
 +        ssize_t res = processAssets(bundle, zip, assets, ge, &filter);
          if (res < 0) {
              return res;
          }
 +
          count += res;
      }
  
      return count;
  }
  
 -ssize_t processAssets(Bundle* bundle, ZipFile* zip,
 -                      const sp<AaptDir>& dir, const AaptGroupEntry& ge)
 +ssize_t processAssets(Bundle* bundle, ZipFile* zip, const sp<AaptDir>& dir,
 +        const AaptGroupEntry& ge, const ResourceFilter* filter)
  {
      ssize_t count = 0;
  
      const size_t ND = dir->getDirs().size();
      size_t i;
      for (i=0; i<ND; i++) {
 -        ssize_t res = processAssets(bundle, zip, dir->getDirs().valueAt(i), ge);
 +        const sp<AaptDir>& subDir = dir->getDirs().valueAt(i);
 +
 +        const bool filterable = filter != NULL && subDir->getLeaf().find("mipmap-") != 0;
 +
 +        if (filterable && subDir->getLeaf() != subDir->getPath() && !filter->match(ge.toParams())) {
 +            continue;
 +        }
 +
 +        ssize_t res = processAssets(bundle, zip, subDir, ge, filterable ? filter : NULL);
          if (res < 0) {
              return res;
          }
          count += res;
      }
  
 +    if (filter != NULL && !filter->match(ge.toParams())) {
 +        return count;
 +    }
 +
      const size_t NF = dir->getFiles().size();
      for (i=0; i<NF; i++) {
          sp<AaptGroup> gp = dir->getFiles().valueAt(i);
@@@ -462,7 -460,7 +471,7 @@@ ssize_t processJarFile(ZipFile* jar, Zi
  
  ssize_t processJarFiles(Bundle* bundle, ZipFile* zip)
  {
 -    ssize_t err;
 +    status_t err;
      ssize_t count = 0;
      const android::Vector<const char*>& jars = bundle->getJarFiles();
  
          ZipFile jar;
          err = jar.open(jars[i], ZipFile::kOpenReadOnly);
          if (err != 0) {
 -            fprintf(stderr, "ERROR: unable to open '%s' as a zip file: %zd\n",
 +            fprintf(stderr, "ERROR: unable to open '%s' as a zip file: %d\n",
                  jars[i], err);
              return err;
          }
diff --combined Resource.cpp
index 1724c8c99fc7e950b15842f8d016fb1612942637,5152d3b5ed3fd4879b952f5af0ca34a6b18b45aa..2d5138bab3fa9997496e2a08491f7093c4ed4057
  #include "ResourceTable.h"
  #include "Images.h"
  
+ #include "CrunchCache.h"
+ #include "FileFinder.h"
+ #include "CacheUpdater.h"
  #define NOISY(x) // x
  
  // ==========================================================================
@@@ -154,10 -158,9 +158,10 @@@ private
  
  bool isValidResourceType(const String8& type)
  {
 -    return type == "anim" || type == "drawable" || type == "layout"
 +    return type == "anim" || type == "animator" || type == "interpolator"
 +        || type == "drawable" || type == "layout"
          || type == "values" || type == "xml" || type == "raw"
 -        || type == "color" || type == "menu";
 +        || type == "color" || type == "menu" || type == "mipmap";
  }
  
  static sp<AaptFile> getResourceFile(const sp<AaptAssets>& assets, bool makeIfNecessary=true)
@@@ -291,20 -294,21 +295,21 @@@ static status_t makeFileResources(Bundl
  }
  
  static status_t preProcessImages(Bundle* bundle, const sp<AaptAssets>& assets,
 -                          const sp<ResourceTypeSet>& set)
 +                          const sp<ResourceTypeSet>& set, const char* type)
  {
-     ResourceDirIterator it(set, String8(type));
-     Vector<sp<AaptFile> > newNameFiles;
-     Vector<String8> newNamePaths;
      bool hasErrors = false;
-     ssize_t res;
-     while ((res=it.next()) == NO_ERROR) {
-         res = preProcessImage(bundle, assets, it.getFile(), NULL);
-         if (res < NO_ERROR) {
-             hasErrors = true;
+     ssize_t res = NO_ERROR;
+     if (bundle->getUseCrunchCache() == false) {
 -        ResourceDirIterator it(set, String8("drawable"));
++        ResourceDirIterator it(set, String8(type));
+         Vector<sp<AaptFile> > newNameFiles;
+         Vector<String8> newNamePaths;
+         while ((res=it.next()) == NO_ERROR) {
+             res = preProcessImage(bundle, assets, it.getFile(), NULL);
+             if (res < NO_ERROR) {
+                 hasErrors = true;
+             }
          }
      }
      return (hasErrors || (res < NO_ERROR)) ? UNKNOWN_ERROR : NO_ERROR;
  }
  
@@@ -549,11 -553,11 +554,11 @@@ static bool applyFileOverlay(Bundle *bu
                          DefaultKeyedVector<AaptGroupEntry, sp<AaptFile> > baseFiles =
                                  baseGroup->getFiles();
                          for (size_t i=0; i < baseFiles.size(); i++) {
 -                            printf("baseFile %ld has flavor %s\n", i,
 +                            printf("baseFile %zd has flavor %s\n", i,
                                      baseFiles.keyAt(i).toString().string());
                          }
                          for (size_t i=0; i < overlayFiles.size(); i++) {
 -                            printf("overlayFile %ld has flavor %s\n", i,
 +                            printf("overlayFile %zd has flavor %s\n", i,
                                      overlayFiles.keyAt(i).toString().string());
                          }
                      }
                                  keyAt(overlayGroupIndex));
                          if(baseFileIndex < UNKNOWN_ERROR) {
                              if (bundle->getVerbose()) {
 -                                printf("found a match (%ld) for overlay file %s, for flavor %s\n",
 +                                printf("found a match (%zd) for overlay file %s, for flavor %s\n",
                                          baseFileIndex,
                                          overlayGroup->getLeaf().string(),
                                          overlayFiles.keyAt(overlayGroupIndex).toString().string());
@@@ -754,6 -758,35 +759,35 @@@ status_t massageManifest(Bundle* bundle
              } \
          } while (0)
  
+ status_t updatePreProcessedCache(Bundle* bundle)
+ {
+     #if BENCHMARK
+     fprintf(stdout, "BENCHMARK: Starting PNG PreProcessing \n");
+     long startPNGTime = clock();
+     #endif /* BENCHMARK */
+     String8 source(bundle->getResourceSourceDirs()[0]);
+     String8 dest(bundle->getCrunchedOutputDir());
+     FileFinder* ff = new SystemFileFinder();
+     CrunchCache cc(source,dest,ff);
+     CacheUpdater* cu = new SystemCacheUpdater(bundle);
+     size_t numFiles = cc.crunch(cu);
+     if (bundle->getVerbose())
+         fprintf(stdout, "Crunched %d PNG files to update cache\n", (int)numFiles);
+     delete ff;
+     delete cu;
+     #if BENCHMARK
+     fprintf(stdout, "BENCHMARK: End PNG PreProcessing. Time Elapsed: %f ms \n"
+             ,(clock() - startPNGTime)/1000.0);
+     #endif /* BENCHMARK */
+     return 0;
+ }
  status_t buildResources(Bundle* bundle, const sp<AaptAssets>& assets)
  {
      // First, look for a package file to parse.  This is required to
      sp<ResourceTypeSet> drawables;
      sp<ResourceTypeSet> layouts;
      sp<ResourceTypeSet> anims;
 +    sp<ResourceTypeSet> animators;
 +    sp<ResourceTypeSet> interpolators;
      sp<ResourceTypeSet> xmls;
      sp<ResourceTypeSet> raws;
      sp<ResourceTypeSet> colors;
      sp<ResourceTypeSet> menus;
 +    sp<ResourceTypeSet> mipmaps;
  
      ASSIGN_IT(drawable);
      ASSIGN_IT(layout);
      ASSIGN_IT(anim);
 +    ASSIGN_IT(animator);
 +    ASSIGN_IT(interpolator);
      ASSIGN_IT(xml);
      ASSIGN_IT(raw);
      ASSIGN_IT(color);
      ASSIGN_IT(menu);
 +    ASSIGN_IT(mipmap);
  
      assets->setResources(resources);
      // now go through any resource overlays and collect their files
      if (!applyFileOverlay(bundle, assets, &drawables, "drawable") ||
              !applyFileOverlay(bundle, assets, &layouts, "layout") ||
              !applyFileOverlay(bundle, assets, &anims, "anim") ||
 +            !applyFileOverlay(bundle, assets, &animators, "animator") ||
 +            !applyFileOverlay(bundle, assets, &interpolators, "interpolator") ||
              !applyFileOverlay(bundle, assets, &xmls, "xml") ||
              !applyFileOverlay(bundle, assets, &raws, "raw") ||
              !applyFileOverlay(bundle, assets, &colors, "color") ||
 -            !applyFileOverlay(bundle, assets, &menus, "menu")) {
 +            !applyFileOverlay(bundle, assets, &menus, "menu") ||
 +            !applyFileOverlay(bundle, assets, &mipmaps, "mipmap")) {
          return UNKNOWN_ERROR;
      }
  
  
      if (drawables != NULL) {
          if (bundle->getOutputAPKFile() != NULL) {
 -            err = preProcessImages(bundle, assets, drawables);
 +            err = preProcessImages(bundle, assets, drawables, "drawable");
          }
          if (err == NO_ERROR) {
              err = makeFileResources(bundle, assets, &table, drawables, "drawable");
          }
      }
  
 +    if (mipmaps != NULL) {
 +        if (bundle->getOutputAPKFile() != NULL) {
 +            err = preProcessImages(bundle, assets, mipmaps, "mipmap");
 +        }
 +        if (err == NO_ERROR) {
 +            err = makeFileResources(bundle, assets, &table, mipmaps, "mipmap");
 +            if (err != NO_ERROR) {
 +                hasErrors = true;
 +            }
 +        } else {
 +            hasErrors = true;
 +        }
 +    }
 +
      if (layouts != NULL) {
          err = makeFileResources(bundle, assets, &table, layouts, "layout");
          if (err != NO_ERROR) {
          }
      }
  
 +    if (animators != NULL) {
 +        err = makeFileResources(bundle, assets, &table, animators, "animator");
 +        if (err != NO_ERROR) {
 +            hasErrors = true;
 +        }
 +    }
 +
 +    if (interpolators != NULL) {
 +        err = makeFileResources(bundle, assets, &table, interpolators, "interpolator");
 +        if (err != NO_ERROR) {
 +            hasErrors = true;
 +        }
 +    }
 +
      if (xmls != NULL) {
          err = makeFileResources(bundle, assets, &table, xmls, "xml");
          if (err != NO_ERROR) {
          err = NO_ERROR;
      }
  
 +    if (animators != NULL) {
 +        ResourceDirIterator it(animators, String8("animator"));
 +        while ((err=it.next()) == NO_ERROR) {
 +            err = compileXmlFile(assets, it.getFile(), &table, xmlFlags);
 +            if (err != NO_ERROR) {
 +                hasErrors = true;
 +            }
 +        }
 +
 +        if (err < NO_ERROR) {
 +            hasErrors = true;
 +        }
 +        err = NO_ERROR;
 +    }
 +
 +    if (interpolators != NULL) {
 +        ResourceDirIterator it(interpolators, String8("interpolator"));
 +        while ((err=it.next()) == NO_ERROR) {
 +            err = compileXmlFile(assets, it.getFile(), &table, xmlFlags);
 +            if (err != NO_ERROR) {
 +                hasErrors = true;
 +            }
 +        }
 +
 +        if (err < NO_ERROR) {
 +            hasErrors = true;
 +        }
 +        err = NO_ERROR;
 +    }
 +
      if (xmls != NULL) {
          ResourceDirIterator it(xmls, String8("xml"));
          while ((err=it.next()) == NO_ERROR) {
@@@ -2172,13 -2138,12 +2206,13 @@@ writeProguardForLayouts(ProguardKeepSet
      // tag:attribute pairs that should be checked in layout files.
      KeyedVector<String8, NamespaceAttributePair> kLayoutTagAttrPairs;
      addTagAttrPair(&kLayoutTagAttrPairs, "view", NULL, "class");
 +    addTagAttrPair(&kLayoutTagAttrPairs, "fragment", NULL, "class");
      addTagAttrPair(&kLayoutTagAttrPairs, "fragment", RESOURCES_ANDROID_NAMESPACE, "name");
  
      // tag:attribute pairs that should be checked in xml files.
      KeyedVector<String8, NamespaceAttributePair> kXmlTagAttrPairs;
      addTagAttrPair(&kXmlTagAttrPairs, "PreferenceScreen", RESOURCES_ANDROID_NAMESPACE, "fragment");
 -    addTagAttrPair(&kXmlTagAttrPairs, "Header", RESOURCES_ANDROID_NAMESPACE, "fragment");
 +    addTagAttrPair(&kXmlTagAttrPairs, "header", RESOURCES_ANDROID_NAMESPACE, "fragment");
  
      const Vector<sp<AaptDir> >& dirs = assets->resDirs();
      const size_t K = dirs.size();