]> git.saurik.com Git - android/aapt.git/commitdiff
am f4750724: am 9d829f98: am 21e6e2de: Merge "Change generated dependency file names"
authorXavier Ducrohet <xav@android.com>
Thu, 18 Aug 2011 21:48:49 +0000 (14:48 -0700)
committerAndroid Git Automerger <android-git-automerger@android.com>
Thu, 18 Aug 2011 21:48:49 +0000 (14:48 -0700)
* commit 'f4750724cf8db972a052cb388dc9a39fc7aa6dd6':
  Change generated dependency file names

1  2 
Command.cpp
Package.cpp
Resource.cpp

diff --combined Command.cpp
index daf53e06bd7566457694975f15d7df616eeb74d6,7297b1eb28c47e2af7439e9fb8be8d212d084f9a..178e7fdcffd3192a9dc48a35c207c5e22ba6ad1b
@@@ -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++) {
@@@ -1546,7 -1391,9 +1546,9 @@@ int doPackage(Bundle* bundle
      assets = new AaptAssets();
  
      // Set up the resource gathering in assets if we're going to generate
-     // dependency files
+     // dependency files. Every time we encounter a resource while slurping
+     // the tree, we'll add it to these stores so we have full resource paths
+     // to write to a dependency file.
      if (bundle->getGenDependencies()) {
          sp<FilePathStore> resPathStore = new FilePathStore;
          assets->setFullResPaths(resPathStore);
          goto bail;
      }
  
+     // If we've been asked to generate a dependency file, do that here
      if (bundle->getGenDependencies()) {
+         // If this is the packaging step, generate the dependency file next to
+         // the output apk (e.g. bin/resources.ap_.d)
          if (outputAPKFile) {
              dependencyFile = String8(outputAPKFile);
-             // Strip the extension and add new one
-             dependencyFile = dependencyFile.getBasePath();
+             // Add the .d extension to the dependency file.
              dependencyFile.append(".d");
          } else {
+             // Else if this is the R.java dependency generation step,
+             // generate the dependency file in the R.java package subdirectory
+             // e.g. gen/com/foo/app/R.java.d
              dependencyFile = String8(bundle->getRClassDir());
-             dependencyFile.appendPath("R.d");
+             dependencyFile.appendPath("R.java.d");
          }
          // Make sure we have a clean dependency file to start with
          fp = fopen(dependencyFile, "w");
      // Write out R.java constants
      if (assets->getPackage() == assets->getSymbolsPrivatePackage()) {
          if (bundle->getCustomPackage() == NULL) {
+             // Write the R.java file into the appropriate class directory
+             // e.g. gen/com/foo/app/R.java
              err = writeResourceSymbols(bundle, assets, assets->getPackage(), true);
-             // Copy R.java for libraries
+             // If we have library files, we're going to write our R.java file into
+             // the appropriate class directory for those libraries as well.
+             // e.g. gen/com/foo/app/lib/R.java
              if (bundle->getExtraPackages() != NULL) {
                  // Split on colon
                  String8 libs(bundle->getExtraPackages());
                  char* packageString = strtok(libs.lockBuffer(libs.length()), ":");
                  while (packageString != NULL) {
+                     // Write the R.java file out with the correct package name
                      err = writeResourceSymbols(bundle, assets, String8(packageString), true);
                      packageString = strtok(NULL, ":");
                  }
          }
      }
  
+     // If we've been asked to generate a dependency file, we need to finish up here.
+     // the writeResourceSymbols and writeAPK functions have already written the target
+     // half of the dependency file, now we need to write the prerequisites. (files that
+     // the R.java file or .ap_ file depend on)
      if (bundle->getGenDependencies()) {
          // Now that writeResourceSymbols or writeAPK has taken care of writing
          // the targets to our dependency file, we'll write the prereqs
          fprintf(fp, " : ");
          bool includeRaw = (outputAPKFile != NULL);
          err = writeDependencyPreReqs(bundle, assets, fp, includeRaw);
-         // Also manually add the AndroidManifeset since it's a non-asset
+         // Also manually add the AndroidManifeset since it's not under res/ or assets/
+         // and therefore was not added to our pathstores during slurping
          fprintf(fp, "%s \\\n", bundle->getAndroidManifestFile());
          fclose(fp);
      }
diff --combined Package.cpp
index c9f687088b4f1afb92b22c22a78ff50c4372fff3,46ba3c1ff2bc509f3bb4c159774f22c4e0047e27..1e3efdeca17639015a0dd4618d2bcbd8fa5ed518
@@@ -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);
@@@ -177,12 -177,17 +177,17 @@@ status_t writeAPK(Bundle* bundle, cons
          }
      }
  
+     // If we've been asked to generate a dependency file for the .ap_ package,
+     // do so here
      if (bundle->getGenDependencies()) {
-         // Add this file to the dependency file
-         String8 dependencyFile = outputFile.getBasePath();
+         // The dependency file gets output to the same directory
+         // as the specified output file with an additional .d extension.
+         // e.g. bin/resources.ap_.d
+         String8 dependencyFile = outputFile;
          dependencyFile.append(".d");
  
          FILE* fp = fopen(dependencyFile.string(), "a");
+         // Add this file to the dependency file
          fprintf(fp, "%s \\\n", outputFile.string());
          fclose(fp);
      }
@@@ -223,45 -228,34 +228,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);
@@@ -471,7 -465,7 +476,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 2d5138bab3fa9997496e2a08491f7093c4ed4057,f64728d0a8c571ddbc9685fc3af7dce07af50fe5..bb56af9afb7dcc4852051dad5e8b1d37b44b9298
@@@ -158,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)
@@@ -295,12 -294,12 +295,12 @@@ 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)
  {
      bool hasErrors = false;
      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) {
@@@ -554,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());
@@@ -839,24 -838,18 +839,24 @@@ status_t buildResources(Bundle* bundle
      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) {
@@@ -1958,10 -1890,12 +1958,12 @@@ status_t writeResourceSymbols(Bundle* b
          }
          fclose(fp);
  
+         // If we were asked to generate a dependency file, we'll go ahead and add this R.java
+         // as a target in the dependency file right next to it.
          if (bundle->getGenDependencies()) {
              // Add this R.java to the dependency file
              String8 dependencyFile(bundle->getRClassDir());
-             dependencyFile.appendPath("R.d");
+             dependencyFile.appendPath("R.java.d");
  
              fp = fopen(dependencyFile.string(), "a");
              fprintf(fp,"%s \\\n", dest.string());
@@@ -2206,13 -2140,12 +2208,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();