summaryrefslogtreecommitdiffstats
path: root/tools/aapt
diff options
context:
space:
mode:
authorEric Fischer <enf@google.com>2010-09-15 15:59:21 -0700
committerEric Fischer <enf@google.com>2010-09-23 10:32:47 -0700
commit90964040cabfc67f92a7c3322a02401bb6f8ae82 (patch)
tree52f1ce1de971a071026a12e145837e015e60d26a /tools/aapt
parent89647b1172cdf40a3681922150122b0bd2ea83f1 (diff)
downloadframeworks_base-90964040cabfc67f92a7c3322a02401bb6f8ae82.zip
frameworks_base-90964040cabfc67f92a7c3322a02401bb6f8ae82.tar.gz
frameworks_base-90964040cabfc67f92a7c3322a02401bb6f8ae82.tar.bz2
Add an aapt option to allow string variations for different devices.
The --product option to aapt is a comma-separated list of characteristics of the device being built for. For example, --product nosdcard,grayscale for a device with no SD card and a grayscale screen. Strings can specify a product="characteristic" option to cause that version of the string to be used only for that type of device. All such strings should also specify, at the end of the block, product="default", which will be used if none of the variations match. For example: <string name="choose" product="bw">Choose black or white</string> <string name="choose" product="grayscale">Choose a shade of gray</string> <string name="choose" product="default">Choose a color</string> The default characteristic will also be used when no --product option is specified. Change-Id: Ie6c1505599e02e15b7818e8be6ec47bc6ce71aaa
Diffstat (limited to 'tools/aapt')
-rw-r--r--tools/aapt/Bundle.h5
-rw-r--r--tools/aapt/Main.cpp13
-rw-r--r--tools/aapt/ResourceTable.cpp82
3 files changed, 95 insertions, 5 deletions
diff --git a/tools/aapt/Bundle.h b/tools/aapt/Bundle.h
index a1bc241..c5aa573 100644
--- a/tools/aapt/Bundle.h
+++ b/tools/aapt/Bundle.h
@@ -45,7 +45,7 @@ public:
mRClassDir(NULL), mResourceIntermediatesDir(NULL), mManifestMinSdkVersion(NULL),
mMinSdkVersion(NULL), mTargetSdkVersion(NULL), mMaxSdkVersion(NULL),
mVersionCode(NULL), mVersionName(NULL), mCustomPackage(NULL),
- mMaxResVersion(NULL), mDebugMode(false),
+ mMaxResVersion(NULL), mDebugMode(false), mProduct(NULL),
mArgc(0), mArgv(NULL)
{}
~Bundle(void) {}
@@ -139,6 +139,8 @@ public:
void setMaxResVersion(const char * val) { mMaxResVersion = val; }
bool getDebugMode() { return mDebugMode; }
void setDebugMode(bool val) { mDebugMode = val; }
+ const char* getProduct() const { return mProduct; }
+ void setProduct(const char * val) { mProduct = val; }
/*
* Set and get the file specification.
@@ -237,6 +239,7 @@ private:
const char* mCustomPackage;
const char* mMaxResVersion;
bool mDebugMode;
+ const char* mProduct;
/* file specification */
int mArgc;
diff --git a/tools/aapt/Main.cpp b/tools/aapt/Main.cpp
index 71c023d..739b01f 100644
--- a/tools/aapt/Main.cpp
+++ b/tools/aapt/Main.cpp
@@ -67,6 +67,7 @@ void usage(void)
" [-A asset-source-dir] [-G class-list-file] [-P public-definitions-file] \\\n"
" [-S resource-sources [-S resource-sources ...]] "
" [-F apk-file] [-J R-file-dir] \\\n"
+ " [--product product1,product2,...] \\\n"
" [raw-files-dir [raw-files-dir] ...]\n"
"\n"
" Package the android resources. It will read assets and resources that are\n"
@@ -154,6 +155,9 @@ void usage(void)
" components target the given package. Useful when used in\n"
" conjunction with --rename-manifest-package to fix tests against\n"
" a package that has been renamed.\n"
+ " --product\n"
+ " Specifies which variant to choose for strings that have\n"
+ " product variants\n"
" --utf16\n"
" changes default encoding for resources to UTF-16. Only useful when API\n"
" level is set to 7 or higher where the default encoding is UTF-8.\n");
@@ -484,6 +488,15 @@ int main(int argc, char* const argv[])
bundle.setInstrumentationPackageNameOverride(argv[0]);
} else if (strcmp(cp, "-auto-add-overlay") == 0) {
bundle.setAutoAddOverlay(true);
+ } else if (strcmp(cp, "-product") == 0) {
+ argc--;
+ argv++;
+ if (!argc) {
+ fprintf(stderr, "ERROR: No argument supplied for '--product' option\n");
+ wantUsage = true;
+ goto bail;
+ }
+ bundle.setProduct(argv[0]);
} else {
fprintf(stderr, "ERROR: Unknown option '-%s'\n", cp);
wantUsage = true;
diff --git a/tools/aapt/ResourceTable.cpp b/tools/aapt/ResourceTable.cpp
index 755b93b..532fb65 100644
--- a/tools/aapt/ResourceTable.cpp
+++ b/tools/aapt/ResourceTable.cpp
@@ -574,6 +574,7 @@ status_t parseAndAddBag(Bundle* bundle,
const String16& itemIdent,
int32_t curFormat,
bool isFormatted,
+ const String16& product,
bool pseudolocalize,
const bool overwrite,
ResourceTable* outTable)
@@ -606,6 +607,32 @@ status_t parseAndAddBag(Bundle* bundle,
return err;
}
+/*
+ * Returns true if needle is one of the elements in the comma-separated list
+ * haystack, false otherwise.
+ */
+bool isInProductList(const String16& needle, const String16& haystack) {
+ const char16_t *needle2 = needle.string();
+ const char16_t *haystack2 = haystack.string();
+ size_t needlesize = needle.size();
+
+ while (*haystack2 != '\0') {
+ if (strncmp16(haystack2, needle2, needlesize) == 0) {
+ if (haystack2[needlesize] == '\0' || haystack2[needlesize] == ',') {
+ return true;
+ }
+ }
+
+ while (*haystack2 != '\0' && *haystack2 != ',') {
+ haystack2++;
+ }
+ if (*haystack2 == ',') {
+ haystack2++;
+ }
+ }
+
+ return false;
+}
status_t parseAndAddEntry(Bundle* bundle,
const sp<AaptFile>& in,
@@ -618,6 +645,7 @@ status_t parseAndAddEntry(Bundle* bundle,
bool curIsStyled,
int32_t curFormat,
bool isFormatted,
+ const String16& product,
bool pseudolocalize,
const bool overwrite,
ResourceTable* outTable)
@@ -634,6 +662,47 @@ status_t parseAndAddEntry(Bundle* bundle,
return err;
}
+ /*
+ * If a product type was specified on the command line
+ * and also in the string, and the two are not the same,
+ * return without adding the string.
+ */
+
+ const char *bundleProduct = bundle->getProduct();
+ if (bundleProduct == NULL) {
+ bundleProduct = "";
+ }
+
+ if (product.size() != 0) {
+ /*
+ * If the command-line-specified product is empty, only "default"
+ * matches. Other variants are skipped. This is so generation
+ * of the R.java file when the product is not known is predictable.
+ */
+
+ if (bundleProduct[0] == '\0') {
+ if (strcmp16(String16("default").string(), product.string()) != 0) {
+ return NO_ERROR;
+ }
+ } else {
+ /*
+ * The command-line product is not empty.
+ * If the product for this string is on the command-line list,
+ * it matches. "default" also matches, but only if nothing
+ * else has matched already.
+ */
+
+ if (isInProductList(product, String16(bundleProduct))) {
+ ;
+ } else if (strcmp16(String16("default").string(), product.string()) == 0 &&
+ !outTable->hasBagOrEntry(myPackage, curType, ident)) {
+ ;
+ } else {
+ return NO_ERROR;
+ }
+ }
+ }
+
NOISY(printf("Adding resource entry l=%c%c c=%c%c orien=%d d=%d id=%s: %s\n",
config.language[0], config.language[1],
config.country[0], config.country[1],
@@ -713,6 +782,7 @@ status_t compileResourceFile(Bundle* bundle,
const String16 translatable16("translatable");
const String16 formatted16("formatted");
const String16 false16("false");
+ const String16 product16("product");
const String16 myPackage(assets->getPackage());
@@ -760,6 +830,7 @@ status_t compileResourceFile(Bundle* bundle,
bool curIsStyled = false;
bool curIsPseudolocalizable = false;
bool curIsFormatted = fileIsTranslatable;
+ String16 curProduct;
bool localHasErrors = false;
if (strcmp16(block.getElementName(&len), skip16.string()) == 0) {
@@ -1157,6 +1228,8 @@ status_t compileResourceFile(Bundle* bundle,
translatable.setTo(block.getAttributeStringValue(i, &length));
} else if (strcmp16(attr, formatted16.string()) == 0) {
formatted.setTo(block.getAttributeStringValue(i, &length));
+ } else if (strcmp16(attr, product16.string()) == 0) {
+ curProduct.setTo(block.getAttributeStringValue(i, &length));
}
}
@@ -1374,7 +1447,7 @@ status_t compileResourceFile(Bundle* bundle,
err = parseAndAddBag(bundle, in, &block, curParams, myPackage, curType,
ident, parentIdent, itemIdent, curFormat, curIsFormatted,
- false, overwrite, outTable);
+ curProduct, false, overwrite, outTable);
if (err == NO_ERROR) {
if (curIsPseudolocalizable && localeIsDefined(curParams)
&& bundle->getPseudolocalize()) {
@@ -1383,7 +1456,7 @@ status_t compileResourceFile(Bundle* bundle,
block.setPosition(parserPosition);
err = parseAndAddBag(bundle, in, &block, pseudoParams, myPackage,
curType, ident, parentIdent, itemIdent, curFormat,
- curIsFormatted, true, overwrite, outTable);
+ curIsFormatted, curProduct, true, overwrite, outTable);
#endif
}
}
@@ -1407,7 +1480,7 @@ status_t compileResourceFile(Bundle* bundle,
err = parseAndAddEntry(bundle, in, &block, curParams, myPackage, curType, ident,
*curTag, curIsStyled, curFormat, curIsFormatted,
- false, overwrite, outTable);
+ curProduct, false, overwrite, outTable);
if (err < NO_ERROR) { // Why err < NO_ERROR instead of err != NO_ERROR?
hasErrors = localHasErrors = true;
@@ -1419,7 +1492,8 @@ status_t compileResourceFile(Bundle* bundle,
block.setPosition(parserPosition);
err = parseAndAddEntry(bundle, in, &block, pseudoParams, myPackage, curType,
ident, *curTag, curIsStyled, curFormat,
- curIsFormatted, true, overwrite, outTable);
+ curIsFormatted, curProduct,
+ true, overwrite, outTable);
if (err != NO_ERROR) {
hasErrors = localHasErrors = true;
}