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",
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) {
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++) {
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);
}
/* 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);
}
}
+ // 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);
}
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);
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;
}
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)
}
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) {
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());
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) {
}
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());
// 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();