From 27f69f4e06961fdecd1078b2292d764a157e5e1c Mon Sep 17 00:00:00 2001 From: Adam Lesinski Date: Thu, 21 Aug 2014 13:19:12 -0700 Subject: [PATCH] AAPT: mipmaps should not end up in Splits Mipmaps are never filtered, and so they will always end up in the base APK. Make sure they get omitted from any split. Change-Id: Id24b082bc9bd2d3f031a58bd0de4d30b4f0de7e0 --- tools/aapt/Resource.cpp | 3 +- tools/aapt/ResourceTable.cpp | 36 +++++++++++++++++++----- tools/aapt/ResourceTable.h | 6 ++-- tools/aapt/tests/ResourceFilter_test.cpp | 35 +++++++++++++++++++++++ 4 files changed, 70 insertions(+), 10 deletions(-) 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)); +}