AAPT: Filtering resource fix
Previously, when filtering resources from an APK using -c option, if one qualifier matched, we would keep the resource. However, in the case of something like -c fr-FR,sw360dp and with a resource in the APK like so drawable-fr-FR-sw600dp-v13 we would want this resource to be excluded, as it does not match the sw360dp qualifier (must be less than or equal to it). This CL fixed the behavior of the filter to require that all defined qualifier axis be matched. Bug:17142358 Change-Id: Ie48f3d516a0e610abc7ba8a7ced4eb3ab52534d4
This commit is contained in:
@@ -56,24 +56,34 @@ WeakResourceFilter::match(const ResTable_config& config) const
|
||||
return true;
|
||||
}
|
||||
|
||||
uint32_t matchedAxis = 0x0;
|
||||
const size_t N = mConfigs.size();
|
||||
for (size_t i = 0; i < N; i++) {
|
||||
const std::pair<ConfigDescription, uint32_t>& entry = mConfigs[i];
|
||||
uint32_t diff = entry.first.diff(config);
|
||||
if ((diff & entry.second) == 0) {
|
||||
return true;
|
||||
// Mark the axis that was matched.
|
||||
matchedAxis |= entry.second;
|
||||
} else if ((diff & entry.second) == ResTable_config::CONFIG_LOCALE) {
|
||||
// If the locales differ, but the languages are the same and
|
||||
// the locale we are matching only has a language specified,
|
||||
// we match.
|
||||
if (config.language[0] && memcmp(config.language, entry.first.language, sizeof(config.language)) == 0) {
|
||||
if (config.language[0] &&
|
||||
memcmp(config.language, entry.first.language, sizeof(config.language)) == 0) {
|
||||
if (config.country[0] == 0) {
|
||||
return true;
|
||||
matchedAxis |= ResTable_config::CONFIG_LOCALE;
|
||||
}
|
||||
}
|
||||
} else if ((diff & entry.second) == ResTable_config::CONFIG_SMALLEST_SCREEN_SIZE) {
|
||||
// Special case if the smallest screen width doesn't match. We check that the
|
||||
// config being matched has a smaller screen width than the filter specified.
|
||||
if (config.smallestScreenWidthDp != 0 &&
|
||||
config.smallestScreenWidthDp < entry.first.smallestScreenWidthDp) {
|
||||
matchedAxis |= ResTable_config::CONFIG_SMALLEST_SCREEN_SIZE;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
return matchedAxis == (mConfigMask & mask);
|
||||
}
|
||||
|
||||
status_t
|
||||
|
||||
@@ -24,8 +24,7 @@ public:
|
||||
};
|
||||
|
||||
/**
|
||||
* Implements logic for parsing and handling "-c" and "--preferred-configurations"
|
||||
* options.
|
||||
* Implements logic for parsing and handling "-c" options.
|
||||
*/
|
||||
class WeakResourceFilter : public ResourceFilter {
|
||||
public:
|
||||
|
||||
@@ -75,6 +75,17 @@ TEST(WeakResourceFilterTest, MatchesConfigWithSameValueAxisAndOtherUnrelatedAxis
|
||||
EXPECT_TRUE(filter.match(config));
|
||||
}
|
||||
|
||||
TEST(WeakResourceFilterTest, MatchesConfigWithOneMatchingAxis) {
|
||||
WeakResourceFilter filter;
|
||||
ASSERT_EQ(NO_ERROR, filter.parse(String8("fr_FR,sw360dp,normal,en_US")));
|
||||
|
||||
ConfigDescription config;
|
||||
config.language[0] = 'e';
|
||||
config.language[1] = 'n';
|
||||
|
||||
EXPECT_TRUE(filter.match(config));
|
||||
}
|
||||
|
||||
TEST(WeakResourceFilterTest, DoesNotMatchConfigWithDifferentValueAxis) {
|
||||
WeakResourceFilter filter;
|
||||
ASSERT_EQ(NO_ERROR, filter.parse(String8("fr")));
|
||||
@@ -86,6 +97,32 @@ TEST(WeakResourceFilterTest, DoesNotMatchConfigWithDifferentValueAxis) {
|
||||
EXPECT_FALSE(filter.match(config));
|
||||
}
|
||||
|
||||
TEST(WeakResourceFilterTest, DoesNotMatchWhenOneQualifierIsExplicitlyNotMatched) {
|
||||
WeakResourceFilter filter;
|
||||
ASSERT_EQ(NO_ERROR, filter.parse(String8("fr_FR,en_US,normal,large,xxhdpi,sw320dp")));
|
||||
|
||||
ConfigDescription config;
|
||||
config.language[0] = 'f';
|
||||
config.language[1] = 'r';
|
||||
config.smallestScreenWidthDp = 600;
|
||||
config.version = 13;
|
||||
|
||||
EXPECT_FALSE(filter.match(config));
|
||||
}
|
||||
|
||||
TEST(WeakResourceFilterTest, MatchesSmallestWidthWhenSmaller) {
|
||||
WeakResourceFilter filter;
|
||||
ASSERT_EQ(NO_ERROR, filter.parse(String8("sw600dp")));
|
||||
|
||||
ConfigDescription config;
|
||||
config.language[0] = 'f';
|
||||
config.language[1] = 'r';
|
||||
config.smallestScreenWidthDp = 320;
|
||||
config.version = 13;
|
||||
|
||||
EXPECT_TRUE(filter.match(config));
|
||||
}
|
||||
|
||||
TEST(WeakResourceFilterTest, MatchesConfigWithSameLanguageButNoRegionSpecified) {
|
||||
WeakResourceFilter filter;
|
||||
ASSERT_EQ(NO_ERROR, filter.parse(String8("de-rDE")));
|
||||
|
||||
Reference in New Issue
Block a user