diff --git a/tools/aapt/Resource.cpp b/tools/aapt/Resource.cpp index 869a6fc0b9c58..1d93b895409a5 100644 --- a/tools/aapt/Resource.cpp +++ b/tools/aapt/Resource.cpp @@ -1399,7 +1399,8 @@ status_t buildResources(Bundle* bundle, const sp& assets, sp& split = splits.editItemAt(i); sp flattenedTable = new AaptFile(String8("resources.arsc"), AaptGroupEntry(), String8()); - err = table.flatten(bundle, split->getResourceFilter(), flattenedTable); + err = table.flatten(bundle, split->getResourceFilter(), + flattenedTable, split->isBase()); if (err != NO_ERROR) { fprintf(stderr, "Failed to generate resource table for split '%s'\n", split->getPrintableName().string()); diff --git a/tools/aapt/ResourceTable.cpp b/tools/aapt/ResourceTable.cpp index 49d8699def1f3..b3c364be24515 100644 --- a/tools/aapt/ResourceTable.cpp +++ b/tools/aapt/ResourceTable.cpp @@ -2074,10 +2074,11 @@ bool ResourceTable::hasResources() const { return mNumLocal > 0; } -sp ResourceTable::flatten(Bundle* bundle, const sp& filter) +sp ResourceTable::flatten(Bundle* bundle, const sp& filter, + const bool isBase) { sp data = new AaptFile(String8(), AaptGroupEntry(), String8()); - status_t err = flatten(bundle, filter, data); + status_t err = flatten(bundle, filter, data, isBase); return err == NO_ERROR ? data : NULL; } @@ -2699,7 +2700,9 @@ ResourceTable::validateLocalizations(void) return err; } -status_t ResourceTable::flatten(Bundle* bundle, const sp& filter, const sp& dest) +status_t ResourceTable::flatten(Bundle* bundle, const sp& filter, + const sp& dest, + const bool isBase) { const ConfigDescription nullConfig; @@ -2768,6 +2771,13 @@ status_t ResourceTable::flatten(Bundle* bundle, const sp& configTypeName = "2value"; } + // mipmaps don't get filtered, so they will + // allways end up in the base. Make sure they + // don't end up in a split. + if (typeName == mipmap16 && !isBase) { + continue; + } + const bool filterable = (typeName != mipmap16); const size_t N = t->getOrderedConfigs().size(); @@ -2871,10 +2881,12 @@ status_t ResourceTable::flatten(Bundle* bundle, const sp& return amt; } - status_t err = flattenLibraryTable(data, libraryPackages); - if (err != NO_ERROR) { - fprintf(stderr, "ERROR: failed to write library table\n"); - return err; + if (isBase) { + status_t err = flattenLibraryTable(data, libraryPackages); + if (err != NO_ERROR) { + fprintf(stderr, "ERROR: failed to write library table\n"); + return err; + } } // Build the type chunks inside of this package. @@ -2890,6 +2902,7 @@ status_t ResourceTable::flatten(Bundle* bundle, const sp& continue; } const bool filterable = (typeName != mipmap16); + const bool skipEntireType = (typeName == mipmap16 && !isBase); const size_t N = t != NULL ? t->getOrderedConfigs().size() : 0; @@ -2927,6 +2940,11 @@ status_t ResourceTable::flatten(Bundle* bundle, const sp& if (cl->getPublic()) { typeSpecFlags[ei] |= htodl(ResTable_typeSpec::SPEC_PUBLIC); } + + if (skipEntireType) { + continue; + } + const size_t CN = cl->getEntries().size(); for (size_t ci=0; cimatch(cl->getEntries().keyAt(ci))) { @@ -2943,6 +2961,10 @@ status_t ResourceTable::flatten(Bundle* bundle, const sp& } } + if (skipEntireType) { + continue; + } + // We need to write one type chunk for each configuration for // which we have entries in this type. const size_t NC = t->getUniqueConfigs().size(); diff --git a/tools/aapt/ResourceTable.h b/tools/aapt/ResourceTable.h index d4f47ef9555d0..3721de4af015a 100644 --- a/tools/aapt/ResourceTable.h +++ b/tools/aapt/ResourceTable.h @@ -165,7 +165,8 @@ public: size_t numLocalResources() const; bool hasResources() const; - sp flatten(Bundle* bundle, const sp& filter); + sp flatten(Bundle* bundle, const sp& filter, + const bool isBase); static inline uint32_t makeResId(uint32_t packageId, uint32_t typeId, @@ -206,7 +207,8 @@ public: void addLocalization(const String16& name, const String8& locale, const SourcePos& src); status_t validateLocalizations(void); - status_t flatten(Bundle* bundle, const sp& filter, const sp& dest); + status_t flatten(Bundle* bundle, const sp& filter, + const sp& dest, const bool isBase); status_t flattenLibraryTable(const sp& dest, const Vector >& libs); void writePublicDefinitions(const String16& package, FILE* fp); diff --git a/tools/aapt/tests/ResourceFilter_test.cpp b/tools/aapt/tests/ResourceFilter_test.cpp index 30697bb521250..b55379ebf05d3 100644 --- a/tools/aapt/tests/ResourceFilter_test.cpp +++ b/tools/aapt/tests/ResourceFilter_test.cpp @@ -126,3 +126,38 @@ TEST(WeakResourceFilterTest, MatchesConfigWithRegion) { EXPECT_TRUE(filter.match(config)); } +TEST(StrongResourceFilterTest, MatchesDensities) { + ConfigDescription config; + config.density = 160; + config.version = 4; + std::set configs; + configs.insert(config); + + StrongResourceFilter filter(configs); + + ConfigDescription expectedConfig; + expectedConfig.density = 160; + expectedConfig.version = 4; + ASSERT_TRUE(filter.match(expectedConfig)); +} + +TEST(StrongResourceFilterTest, MatchOnlyMdpiAndExcludeAllOthers) { + std::set configsToMatch; + ConfigDescription config; + config.density = 160; + config.version = 4; + configsToMatch.insert(config); + + std::set configsToNotMatch; + config.density = 480; + configsToNotMatch.insert(config); + + AndResourceFilter filter; + filter.addFilter(new InverseResourceFilter(new StrongResourceFilter(configsToNotMatch))); + filter.addFilter(new StrongResourceFilter(configsToMatch)); + + ConfigDescription expectedConfig; + expectedConfig.density = 160; + expectedConfig.version = 4; + ASSERT_TRUE(filter.match(expectedConfig)); +}