X-Git-Url: https://git.saurik.com/android/aapt.git/blobdiff_plain/b8ea3a3f81e78ebbe5045af5f77175e3722b4d05..f036e32e8db01e6a91ed699cbeaa0294803ac7a2:/ResourceTable.cpp diff --git a/ResourceTable.cpp b/ResourceTable.cpp index 532fb65..fdb39ca 100644 --- a/ResourceTable.cpp +++ b/ResourceTable.cpp @@ -7,6 +7,7 @@ #include "ResourceTable.h" #include "XMLNode.h" +#include "ResourceFilter.h" #include #include @@ -695,7 +696,7 @@ status_t parseAndAddEntry(Bundle* bundle, if (isInProductList(product, String16(bundleProduct))) { ; } else if (strcmp16(String16("default").string(), product.string()) == 0 && - !outTable->hasBagOrEntry(myPackage, curType, ident)) { + !outTable->hasBagOrEntry(myPackage, curType, ident, config)) { ; } else { return NO_ERROR; @@ -782,7 +783,6 @@ 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()); @@ -830,7 +830,6 @@ 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) { @@ -1228,8 +1227,6 @@ 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)); } } @@ -1326,6 +1323,22 @@ status_t compileResourceFile(Bundle* bundle, } } } else if (strcmp16(block.getElementName(&len), string_array16.string()) == 0) { + // Check whether these strings need valid formats. + // (simplified form of what string16 does above) + size_t n = block.getAttributeCount(); + for (size_t i = 0; i < n; i++) { + size_t length; + const uint16_t* attr = block.getAttributeName(i, &length); + if (strcmp16(attr, translatable16.string()) == 0 + || strcmp16(attr, formatted16.string()) == 0) { + const uint16_t* value = block.getAttributeStringValue(i, &length); + if (strcmp16(value, false16.string()) == 0) { + curIsFormatted = false; + break; + } + } + } + curTag = &string_array16; curType = array16; curFormat = ResTable_map::TYPE_REFERENCE|ResTable_map::TYPE_STRING; @@ -1356,6 +1369,12 @@ status_t compileResourceFile(Bundle* bundle, hasErrors = localHasErrors = true; } + String16 product; + identIdx = block.indexOfAttribute(NULL, "product"); + if (identIdx >= 0) { + product = String16(block.getAttributeStringValue(identIdx, &len)); + } + String16 comment(block.getComment(&len) ? block.getComment(&len) : nulStr); if (curIsBag) { @@ -1447,7 +1466,7 @@ status_t compileResourceFile(Bundle* bundle, err = parseAndAddBag(bundle, in, &block, curParams, myPackage, curType, ident, parentIdent, itemIdent, curFormat, curIsFormatted, - curProduct, false, overwrite, outTable); + product, false, overwrite, outTable); if (err == NO_ERROR) { if (curIsPseudolocalizable && localeIsDefined(curParams) && bundle->getPseudolocalize()) { @@ -1456,7 +1475,7 @@ status_t compileResourceFile(Bundle* bundle, block.setPosition(parserPosition); err = parseAndAddBag(bundle, in, &block, pseudoParams, myPackage, curType, ident, parentIdent, itemIdent, curFormat, - curIsFormatted, curProduct, true, overwrite, outTable); + curIsFormatted, product, true, overwrite, outTable); #endif } } @@ -1480,7 +1499,7 @@ status_t compileResourceFile(Bundle* bundle, err = parseAndAddEntry(bundle, in, &block, curParams, myPackage, curType, ident, *curTag, curIsStyled, curFormat, curIsFormatted, - curProduct, false, overwrite, outTable); + product, false, overwrite, outTable); if (err < NO_ERROR) { // Why err < NO_ERROR instead of err != NO_ERROR? hasErrors = localHasErrors = true; @@ -1492,7 +1511,7 @@ status_t compileResourceFile(Bundle* bundle, block.setPosition(parserPosition); err = parseAndAddEntry(bundle, in, &block, pseudoParams, myPackage, curType, ident, *curTag, curIsStyled, curFormat, - curIsFormatted, curProduct, + curIsFormatted, product, true, overwrite, outTable); if (err != NO_ERROR) { hasErrors = localHasErrors = true; @@ -1722,13 +1741,6 @@ status_t ResourceTable::startBag(const SourcePos& sourcePos, // If a parent is explicitly specified, set it. if (bagParent.size() > 0) { - String16 curPar = e->getParent(); - if (curPar.size() > 0 && curPar != bagParent) { - sourcePos.error("Conflicting parents specified, was '%s', now '%s'\n", - String8(e->getParent()).string(), - String8(bagParent).string()); - return UNKNOWN_ERROR; - } e->setParent(bagParent); } @@ -1776,13 +1788,6 @@ status_t ResourceTable::addBag(const SourcePos& sourcePos, // If a parent is explicitly specified, set it. if (bagParent.size() > 0) { - String16 curPar = e->getParent(); - if (curPar.size() > 0 && curPar != bagParent) { - sourcePos.error("Conflicting parents specified, was '%s', now '%s'\n", - String8(e->getParent()).string(), - String8(bagParent).string()); - return UNKNOWN_ERROR; - } e->setParent(bagParent); } @@ -1819,6 +1824,37 @@ bool ResourceTable::hasBagOrEntry(const String16& package, return false; } +bool ResourceTable::hasBagOrEntry(const String16& package, + const String16& type, + const String16& name, + const ResTable_config& config) const +{ + // First look for this in the included resources... + uint32_t rid = mAssets->getIncludedResources() + .identifierForName(name.string(), name.size(), + type.string(), type.size(), + package.string(), package.size()); + if (rid != 0) { + return true; + } + + sp p = mPackages.valueFor(package); + if (p != NULL) { + sp t = p->getTypes().valueFor(type); + if (t != NULL) { + sp c = t->getConfigs().valueFor(name); + if (c != NULL) { + sp e = c->getEntries().valueFor(config); + if (e != NULL) { + return true; + } + } + } + } + + return false; +} + bool ResourceTable::hasBagOrEntry(const String16& ref, const String16* defType, const String16* defPackage) @@ -1959,10 +1995,11 @@ uint32_t ResourceTable::getResId(const String16& ref, bool onlyPublic) const { String16 package, type, name; + bool refOnlyPublic = true; if (!ResTable::expandResourceRef( ref.string(), ref.size(), &package, &type, &name, defType, defPackage ? defPackage:&mAssetsPackage, - outErrorMsg)) { + outErrorMsg, &refOnlyPublic)) { NOISY(printf("Expanding resource: ref=%s\n", String8(ref).string())); NOISY(printf("Expanding resource: defType=%s\n", @@ -1975,7 +2012,7 @@ uint32_t ResourceTable::getResId(const String16& ref, String8(name).string())); return 0; } - uint32_t res = getResId(package, type, name, onlyPublic); + uint32_t res = getResId(package, type, name, onlyPublic && refOnlyPublic); NOISY(printf("Expanded resource: p=%s, t=%s, n=%s, res=%d\n", String8(package).string(), String8(type).string(), String8(name).string(), res)); @@ -2440,7 +2477,7 @@ ResourceTable::validateLocalizations(void) if (configSet.count(defaultLocale) == 0) { fprintf(stdout, "aapt: warning: string '%s' has no default translation in %s; found:", String8(nameIter->first).string(), mBundle->getResourceSourceDirs()[0]); - for (set::iterator locales = configSet.begin(); + for (set::const_iterator locales = configSet.begin(); locales != configSet.end(); locales++) { fprintf(stdout, " %s", (*locales).string()); @@ -2492,123 +2529,6 @@ ResourceTable::validateLocalizations(void) return err; } - -status_t -ResourceFilter::parse(const char* arg) -{ - if (arg == NULL) { - return 0; - } - - const char* p = arg; - const char* q; - - while (true) { - q = strchr(p, ','); - if (q == NULL) { - q = p + strlen(p); - } - - String8 part(p, q-p); - - if (part == "zz_ZZ") { - mContainsPseudo = true; - } - int axis; - uint32_t value; - if (AaptGroupEntry::parseNamePart(part, &axis, &value)) { - fprintf(stderr, "Invalid configuration: %s\n", arg); - fprintf(stderr, " "); - for (int i=0; i()); - } - SortedVector& sv = mData.editValueFor(axis); - sv.add(value); - // if it's a locale with a region, also match an unmodified locale of the - // same language - if (axis == AXIS_LANGUAGE) { - if (value & 0xffff0000) { - sv.add(value & 0x0000ffff); - } - } - p = q; - if (!*p) break; - p++; - } - - return NO_ERROR; -} - -bool -ResourceFilter::match(int axis, uint32_t value) -{ - if (value == 0) { - // they didn't specify anything so take everything - return true; - } - ssize_t index = mData.indexOfKey(axis); - if (index < 0) { - // we didn't request anything on this axis so take everything - return true; - } - const SortedVector& sv = mData.valueAt(index); - return sv.indexOf(value) >= 0; -} - -bool -ResourceFilter::match(const ResTable_config& config) -{ - if (config.locale) { - uint32_t locale = (config.country[1] << 24) | (config.country[0] << 16) - | (config.language[1] << 8) | (config.language[0]); - if (!match(AXIS_LANGUAGE, locale)) { - return false; - } - } - if (!match(AXIS_ORIENTATION, config.orientation)) { - return false; - } - if (!match(AXIS_UIMODETYPE, (config.uiMode&ResTable_config::MASK_UI_MODE_TYPE))) { - return false; - } - if (!match(AXIS_UIMODENIGHT, (config.uiMode&ResTable_config::MASK_UI_MODE_NIGHT))) { - return false; - } - if (!match(AXIS_DENSITY, config.density)) { - return false; - } - if (!match(AXIS_TOUCHSCREEN, config.touchscreen)) { - return false; - } - if (!match(AXIS_KEYSHIDDEN, config.inputFlags)) { - return false; - } - if (!match(AXIS_KEYBOARD, config.keyboard)) { - return false; - } - if (!match(AXIS_NAVIGATION, config.navigation)) { - return false; - } - if (!match(AXIS_SCREENSIZE, config.screenSize)) { - return false; - } - if (!match(AXIS_VERSION, config.version)) { - return false; - } - return true; -} - status_t ResourceTable::flatten(Bundle* bundle, const sp& dest) { ResourceFilter filter; @@ -2620,6 +2540,8 @@ status_t ResourceTable::flatten(Bundle* bundle, const sp& dest) const size_t N = mOrderedPackages.size(); size_t pi; + const static String16 mipmap16("mipmap"); + bool useUTF8 = !bundle->getWantUTF16() && bundle->isMinSdkAtLeast(SDK_FROYO); // Iterate through all data, collecting all values (strings, @@ -2642,7 +2564,10 @@ status_t ResourceTable::flatten(Bundle* bundle, const sp& dest) typeStrings.add(String16(""), false); continue; } - typeStrings.add(t->getName(), false); + const String16 typeName(t->getName()); + typeStrings.add(typeName, false); + + const bool filterable = (typeName != mipmap16); const size_t N = t->getOrderedConfigs().size(); for (size_t ci=0; ci& dest) const size_t N = c->getEntries().size(); for (size_t ei=0; eigetEntries().keyAt(ei); - if (!filter.match(config)) { + if (filterable && !filter.match(config)) { continue; } sp e = c->getEntries().valueAt(ei); @@ -2733,6 +2658,8 @@ status_t ResourceTable::flatten(Bundle* bundle, const sp& dest) "Type name %s not found", String8(typeName).string()); + const bool filterable = (typeName != mipmap16); + const size_t N = t != NULL ? t->getOrderedConfigs().size() : 0; // First write the typeSpec chunk, containing information about @@ -2757,7 +2684,7 @@ status_t ResourceTable::flatten(Bundle* bundle, const sp& dest) (((uint8_t*)data->editData()) + typeSpecStart + sizeof(ResTable_typeSpec)); memset(typeSpecFlags, 0, sizeof(uint32_t)*N); - + for (size_t ei=0; ei cl = t->getOrderedConfigs().itemAt(ei); if (cl->getPublic()) { @@ -2765,11 +2692,11 @@ status_t ResourceTable::flatten(Bundle* bundle, const sp& dest) } const size_t CN = cl->getEntries().size(); for (size_t ci=0; cigetEntries().keyAt(ci))) { + if (filterable && !filter.match(cl->getEntries().keyAt(ci))) { continue; } for (size_t cj=ci+1; cjgetEntries().keyAt(cj))) { + if (filterable && !filter.match(cl->getEntries().keyAt(cj))) { continue; } typeSpecFlags[ei] |= htodl( @@ -2789,7 +2716,8 @@ status_t ResourceTable::flatten(Bundle* bundle, const sp& dest) ConfigDescription config = t->getUniqueConfigs().itemAt(ci); NOISY(printf("Writing config %d config: imsi:%d/%d lang:%c%c cnt:%c%c " - "orien:%d ui:%d touch:%d density:%d key:%d inp:%d nav:%d w:%d h:%d\n", + "orien:%d ui:%d touch:%d density:%d key:%d inp:%d nav:%d sz:%dx%d " + "sw%ddp w%ddp h%ddp\n", ti+1, config.mcc, config.mnc, config.language[0] ? config.language[0] : '-', @@ -2804,9 +2732,12 @@ status_t ResourceTable::flatten(Bundle* bundle, const sp& dest) config.inputFlags, config.navigation, config.screenWidth, - config.screenHeight)); + config.screenHeight, + config.smallestScreenWidthDp, + config.screenWidthDp, + config.screenHeightDp)); - if (!filter.match(config)) { + if (filterable && !filter.match(config)) { continue; } @@ -2827,7 +2758,8 @@ status_t ResourceTable::flatten(Bundle* bundle, const sp& dest) tHeader->entriesStart = htodl(typeSize); tHeader->config = config; NOISY(printf("Writing type %d config: imsi:%d/%d lang:%c%c cnt:%c%c " - "orien:%d ui:%d touch:%d density:%d key:%d inp:%d nav:%d w:%d h:%d\n", + "orien:%d ui:%d touch:%d density:%d key:%d inp:%d nav:%d sz:%dx%d " + "sw%ddp w%ddp h%ddp\n", ti+1, tHeader->config.mcc, tHeader->config.mnc, tHeader->config.language[0] ? tHeader->config.language[0] : '-', @@ -2842,7 +2774,10 @@ status_t ResourceTable::flatten(Bundle* bundle, const sp& dest) tHeader->config.inputFlags, tHeader->config.navigation, tHeader->config.screenWidth, - tHeader->config.screenHeight)); + tHeader->config.screenHeight, + tHeader->config.smallestScreenWidthDp, + tHeader->config.screenWidthDp, + tHeader->config.screenHeightDp)); tHeader->config.swapHtoD(); // Build the entries inside of this type. @@ -3424,7 +3359,8 @@ sp ResourceTable::Type::getEntry(const String16& entry, if (e == NULL) { if (config != NULL) { NOISY(printf("New entry at %s:%d: imsi:%d/%d lang:%c%c cnt:%c%c " - "orien:%d touch:%d density:%d key:%d inp:%d nav:%d w:%d h:%d\n", + "orien:%d touch:%d density:%d key:%d inp:%d nav:%d sz:%dx%d " + "sw%ddp w%ddp h%ddp\n", sourcePos.file.string(), sourcePos.line, config->mcc, config->mnc, config->language[0] ? config->language[0] : '-', @@ -3438,7 +3374,10 @@ sp ResourceTable::Type::getEntry(const String16& entry, config->inputFlags, config->navigation, config->screenWidth, - config->screenHeight)); + config->screenHeight, + config->smallestScreenWidthDp, + config->screenWidthDp, + config->screenHeightDp)); } else { NOISY(printf("New entry at %s:%d: NULL config\n", sourcePos.file.string(), sourcePos.line)); @@ -3670,7 +3609,9 @@ sp ResourceTable::getPackage(const String16& package) { sp p = mPackages.valueFor(package); if (p == NULL) { - if (mIsAppPackage) { + if (mBundle->getIsOverlayPackage()) { + p = new Package(package, 0x00); + } else if (mIsAppPackage) { if (mHaveAppPackage) { fprintf(stderr, "Adding multiple application package resources; only one is allowed.\n" "Use -x to create extended resources.\n");