diff options
author | Adam Lesinski <adamlesinski@google.com> | 2017-05-09 15:25:37 -0700 |
---|---|---|
committer | Adam Lesinski <adamlesinski@google.com> | 2017-05-11 11:28:29 -0700 |
commit | 32e7501a27f0f19bccdf9e91f9b87869c093f695 (patch) | |
tree | 50496484fd5cc1b79d7cf633db311eebbf37f3a6 | |
parent | f93dc8b6504200d0b6d502d924a70a743f9b1411 (diff) |
Fix support for @empty in style resolution
If @empty is encountered in XML, do not fallback
to searching through the theme.
Bug: 36891052
Test: make aapt2_tests
Test: bit CtsContentTestCases:android.content.res.cts.TypedArrayTest
Change-Id: Ie3bf7b70af9c7913513a1092afd95d26bec5e635
-rw-r--r-- | core/java/android/content/res/TypedArray.java | 8 | ||||
-rw-r--r-- | libs/androidfw/AttributeResolution.cpp | 103 | ||||
-rw-r--r-- | libs/androidfw/ResourceTypes.cpp | 6 | ||||
-rw-r--r-- | libs/androidfw/tests/AssetManager2_test.cpp | 7 | ||||
-rw-r--r-- | libs/androidfw/tests/AttributeResolution_test.cpp | 56 | ||||
-rw-r--r-- | libs/androidfw/tests/data/styles/R.h | 1 | ||||
-rwxr-xr-x | libs/androidfw/tests/data/styles/build | 3 | ||||
-rw-r--r-- | libs/androidfw/tests/data/styles/res/layout/layout.xml | 4 | ||||
-rw-r--r-- | libs/androidfw/tests/data/styles/res/values/styles.xml | 12 | ||||
-rw-r--r-- | libs/androidfw/tests/data/styles/styles.apk | bin | 2422 -> 2350 bytes |
10 files changed, 111 insertions, 89 deletions
diff --git a/core/java/android/content/res/TypedArray.java b/core/java/android/content/res/TypedArray.java index 0b0f048196a5..f33c75168a5f 100644 --- a/core/java/android/content/res/TypedArray.java +++ b/core/java/android/content/res/TypedArray.java @@ -103,7 +103,8 @@ public class TypedArray { } /** - * Return the number of indices in the array that actually have data. + * Returns the number of indices in the array that actually have data. Attributes with a value + * of @empty are included, as this is an explicit indicator. * * @throws RuntimeException if the TypedArray has already been recycled. */ @@ -116,7 +117,8 @@ public class TypedArray { } /** - * Returns an index in the array that has data. + * Returns an index in the array that has data. Attributes with a value of @empty are included, + * as this is an explicit indicator. * * @param at The index you would like to returned, ranging from 0 to * {@link #getIndexCount()}. @@ -1017,7 +1019,7 @@ public class TypedArray { * @param outValue TypedValue object in which to place the attribute's * data. * - * @return {@code true} if the value was retrieved, false otherwise. + * @return {@code true} if the value was retrieved and not @empty, {@code false} otherwise. * @throws RuntimeException if the TypedArray has already been recycled. */ public boolean getValue(@StyleableRes int index, TypedValue outValue) { diff --git a/libs/androidfw/AttributeResolution.cpp b/libs/androidfw/AttributeResolution.cpp index 2771ade1dd12..60e3845d98a9 100644 --- a/libs/androidfw/AttributeResolution.cpp +++ b/libs/androidfw/AttributeResolution.cpp @@ -44,8 +44,7 @@ class XmlAttributeFinder }; class BagAttributeFinder - : public BackTrackingAttributeFinder<BagAttributeFinder, - const ResTable::bag_entry*> { + : public BackTrackingAttributeFinder<BagAttributeFinder, const ResTable::bag_entry*> { public: BagAttributeFinder(const ResTable::bag_entry* start, const ResTable::bag_entry* end) @@ -76,8 +75,7 @@ bool ResolveAttrs(ResTable::Theme* theme, uint32_t def_style_attr, uint32_t def_style_bag_type_set_flags = 0; if (def_style_attr != 0) { Res_value value; - if (theme->getAttribute(def_style_attr, &value, - &def_style_bag_type_set_flags) >= 0) { + if (theme->getAttribute(def_style_attr, &value, &def_style_bag_type_set_flags) >= 0) { if (value.dataType == Res_value::TYPE_REFERENCE) { def_style_res = value.data; } @@ -127,18 +125,14 @@ bool ResolveAttrs(ResTable::Theme* theme, uint32_t def_style_attr, ALOGI("-> From values: type=0x%x, data=0x%08x", value.dataType, value.data); } - } - - if (value.dataType == Res_value::TYPE_NULL) { - const ResTable::bag_entry* const def_style_entry = - def_style_attr_finder.Find(cur_ident); + } else { + const ResTable::bag_entry* const def_style_entry = def_style_attr_finder.Find(cur_ident); if (def_style_entry != def_style_end) { block = def_style_entry->stringBlock; type_set_flags = def_style_type_set_flags; value = def_style_entry->map.value; if (kDebugStyles) { - ALOGI("-> From def style: type=0x%x, data=0x%08x", value.dataType, - value.data); + ALOGI("-> From def style: type=0x%x, data=0x%08x", value.dataType, value.data); } } } @@ -146,29 +140,24 @@ bool ResolveAttrs(ResTable::Theme* theme, uint32_t def_style_attr, uint32_t resid = 0; if (value.dataType != Res_value::TYPE_NULL) { // Take care of resolving the found resource to its final value. - ssize_t new_block = theme->resolveAttributeReference( - &value, block, &resid, &type_set_flags, &config); + ssize_t new_block = + theme->resolveAttributeReference(&value, block, &resid, &type_set_flags, &config); if (new_block >= 0) block = new_block; if (kDebugStyles) { - ALOGI("-> Resolved attr: type=0x%x, data=0x%08x", value.dataType, - value.data); + ALOGI("-> Resolved attr: type=0x%x, data=0x%08x", value.dataType, value.data); } - } else { + } else if (value.data != Res_value::DATA_NULL_EMPTY) { // If we still don't have a value for this attribute, try to find // it in the theme! - ssize_t new_block = - theme->getAttribute(cur_ident, &value, &type_set_flags); + ssize_t new_block = theme->getAttribute(cur_ident, &value, &type_set_flags); if (new_block >= 0) { if (kDebugStyles) { - ALOGI("-> From theme: type=0x%x, data=0x%08x", value.dataType, - value.data); + ALOGI("-> From theme: type=0x%x, data=0x%08x", value.dataType, value.data); } - new_block = res.resolveReference(&value, new_block, &resid, - &type_set_flags, &config); + new_block = res.resolveReference(&value, new_block, &resid, &type_set_flags, &config); if (new_block >= 0) block = new_block; if (kDebugStyles) { - ALOGI("-> Resolved theme: type=0x%x, data=0x%08x", value.dataType, - value.data); + ALOGI("-> Resolved theme: type=0x%x, data=0x%08x", value.dataType, value.data); } } } @@ -184,8 +173,7 @@ bool ResolveAttrs(ResTable::Theme* theme, uint32_t def_style_attr, } if (kDebugStyles) { - ALOGI("Attribute 0x%08x: type=0x%x, data=0x%08x", cur_ident, - value.dataType, value.data); + ALOGI("Attribute 0x%08x: type=0x%x, data=0x%08x", cur_ident, value.dataType, value.data); } // Write the final value back to Java. @@ -198,7 +186,8 @@ bool ResolveAttrs(ResTable::Theme* theme, uint32_t def_style_attr, out_values[STYLE_CHANGING_CONFIGURATIONS] = type_set_flags; out_values[STYLE_DENSITY] = config.density; - if (out_indices != nullptr && value.dataType != Res_value::TYPE_NULL) { + if (out_indices != nullptr && + (value.dataType != Res_value::TYPE_NULL || value.data == Res_value::DATA_NULL_EMPTY)) { indices_idx++; out_indices[indices_idx] = ii; } @@ -247,8 +236,7 @@ void ApplyStyle(ResTable::Theme* theme, ResXMLParser* xml_parser, uint32_t def_s ssize_t idx = xml_parser->indexOfStyle(); if (idx >= 0 && xml_parser->getAttributeValue(idx, &value) >= 0) { if (value.dataType == value.TYPE_ATTRIBUTE) { - if (theme->getAttribute(value.data, &value, &style_bag_type_set_flags) < - 0) { + if (theme->getAttribute(value.data, &value, &style_bag_type_set_flags) < 0) { value.dataType = Res_value::TYPE_NULL; } } @@ -318,41 +306,34 @@ void ApplyStyle(ResTable::Theme* theme, ResXMLParser* xml_parser, uint32_t def_s // We found the attribute we were looking for. xml_parser->getAttributeValue(xml_attr_idx, &value); if (kDebugStyles) { - ALOGI("-> From XML: type=0x%x, data=0x%08x", value.dataType, - value.data); + ALOGI("-> From XML: type=0x%x, data=0x%08x", value.dataType, value.data); } } - if (value.dataType == Res_value::TYPE_NULL) { - // Walk through the style class values looking for the requested - // attribute. - const ResTable::bag_entry* const style_attr_entry = - style_attr_finder.Find(cur_ident); + if (value.dataType == Res_value::TYPE_NULL && value.data != Res_value::DATA_NULL_EMPTY) { + // Walk through the style class values looking for the requested attribute. + const ResTable::bag_entry* const style_attr_entry = style_attr_finder.Find(cur_ident); if (style_attr_entry != style_attr_end) { // We found the attribute we were looking for. block = style_attr_entry->stringBlock; type_set_flags = style_type_set_flags; value = style_attr_entry->map.value; if (kDebugStyles) { - ALOGI("-> From style: type=0x%x, data=0x%08x", value.dataType, - value.data); + ALOGI("-> From style: type=0x%x, data=0x%08x", value.dataType, value.data); } } } - if (value.dataType == Res_value::TYPE_NULL) { - // Walk through the default style values looking for the requested - // attribute. - const ResTable::bag_entry* const def_style_attr_entry = - def_style_attr_finder.Find(cur_ident); + if (value.dataType == Res_value::TYPE_NULL && value.data != Res_value::DATA_NULL_EMPTY) { + // Walk through the default style values looking for the requested attribute. + const ResTable::bag_entry* const def_style_attr_entry = def_style_attr_finder.Find(cur_ident); if (def_style_attr_entry != def_style_attr_end) { // We found the attribute we were looking for. block = def_style_attr_entry->stringBlock; type_set_flags = style_type_set_flags; value = def_style_attr_entry->map.value; if (kDebugStyles) { - ALOGI("-> From def style: type=0x%x, data=0x%08x", value.dataType, - value.data); + ALOGI("-> From def style: type=0x%x, data=0x%08x", value.dataType, value.data); } } } @@ -360,35 +341,29 @@ void ApplyStyle(ResTable::Theme* theme, ResXMLParser* xml_parser, uint32_t def_s uint32_t resid = 0; if (value.dataType != Res_value::TYPE_NULL) { // Take care of resolving the found resource to its final value. - ssize_t new_block = theme->resolveAttributeReference( - &value, block, &resid, &type_set_flags, &config); + ssize_t new_block = + theme->resolveAttributeReference(&value, block, &resid, &type_set_flags, &config); if (new_block >= 0) { block = new_block; } if (kDebugStyles) { - ALOGI("-> Resolved attr: type=0x%x, data=0x%08x", value.dataType, - value.data); + ALOGI("-> Resolved attr: type=0x%x, data=0x%08x", value.dataType, value.data); } - } else { - // If we still don't have a value for this attribute, try to find - // it in the theme! - ssize_t new_block = - theme->getAttribute(cur_ident, &value, &type_set_flags); + } else if (value.data != Res_value::DATA_NULL_EMPTY) { + // If we still don't have a value for this attribute, try to find it in the theme! + ssize_t new_block = theme->getAttribute(cur_ident, &value, &type_set_flags); if (new_block >= 0) { if (kDebugStyles) { - ALOGI("-> From theme: type=0x%x, data=0x%08x", value.dataType, - value.data); + ALOGI("-> From theme: type=0x%x, data=0x%08x", value.dataType, value.data); } - new_block = res.resolveReference(&value, new_block, &resid, - &type_set_flags, &config); + new_block = res.resolveReference(&value, new_block, &resid, &type_set_flags, &config); if (new_block >= 0) { block = new_block; } if (kDebugStyles) { - ALOGI("-> Resolved theme: type=0x%x, data=0x%08x", value.dataType, - value.data); + ALOGI("-> Resolved theme: type=0x%x, data=0x%08x", value.dataType, value.data); } } } @@ -404,8 +379,7 @@ void ApplyStyle(ResTable::Theme* theme, ResXMLParser* xml_parser, uint32_t def_s } if (kDebugStyles) { - ALOGI("Attribute 0x%08x: type=0x%x, data=0x%08x", cur_ident, - value.dataType, value.data); + ALOGI("Attribute 0x%08x: type=0x%x, data=0x%08x", cur_ident, value.dataType, value.data); } // Write the final value back to Java. @@ -418,7 +392,7 @@ void ApplyStyle(ResTable::Theme* theme, ResXMLParser* xml_parser, uint32_t def_s out_values[STYLE_CHANGING_CONFIGURATIONS] = type_set_flags; out_values[STYLE_DENSITY] = config.density; - if (value.dataType != Res_value::TYPE_NULL) { + if (value.dataType != Res_value::TYPE_NULL || value.data == Res_value::DATA_NULL_EMPTY) { indices_idx++; // out_indices must NOT be nullptr. @@ -502,7 +476,8 @@ bool RetrieveAttributes(const ResTable* res, ResXMLParser* xml_parser, out_values[STYLE_CHANGING_CONFIGURATIONS] = type_set_flags; out_values[STYLE_DENSITY] = config.density; - if (out_indices != nullptr && value.dataType != Res_value::TYPE_NULL) { + if (out_indices != nullptr && + (value.dataType != Res_value::TYPE_NULL || value.data == Res_value::DATA_NULL_EMPTY)) { indices_idx++; out_indices[indices_idx] = ii; } diff --git a/libs/androidfw/ResourceTypes.cpp b/libs/androidfw/ResourceTypes.cpp index f661f29bb7f9..f526dfb8e190 100644 --- a/libs/androidfw/ResourceTypes.cpp +++ b/libs/androidfw/ResourceTypes.cpp @@ -3538,7 +3538,8 @@ status_t ResTable::Theme::applyStyle(uint32_t resID, bool force) attrRes, bag->map.value.dataType, bag->map.value.data, curEntry->value.dataType); } - if (force || curEntry->value.dataType == Res_value::TYPE_NULL) { + if (force || (curEntry->value.dataType == Res_value::TYPE_NULL + && curEntry->value.data != Res_value::DATA_NULL_EMPTY)) { curEntry->stringBlock = bag->stringBlock; curEntry->typeSpecFlags |= bagTypeSpecFlags; curEntry->value = bag->map.value; @@ -3674,7 +3675,8 @@ ssize_t ResTable::Theme::getAttribute(uint32_t resID, Res_value* outValue, } ALOGW("Too many attribute references, stopped at: 0x%08x\n", resID); return BAD_INDEX; - } else if (type != Res_value::TYPE_NULL) { + } else if (type != Res_value::TYPE_NULL + || te.value.data == Res_value::DATA_NULL_EMPTY) { *outValue = te.value; return te.stringBlock; } diff --git a/libs/androidfw/tests/AssetManager2_test.cpp b/libs/androidfw/tests/AssetManager2_test.cpp index d8e5abfe8ce9..fcae53b322b3 100644 --- a/libs/androidfw/tests/AssetManager2_test.cpp +++ b/libs/androidfw/tests/AssetManager2_test.cpp @@ -264,7 +264,7 @@ TEST_F(AssetManager2Test, MergesStylesWithParentFromSingleApkAssets) { const ResolvedBag* bag_two = assetmanager.GetBag(app::R::style::StyleTwo); ASSERT_NE(nullptr, bag_two); - ASSERT_EQ(5u, bag_two->entry_count); + ASSERT_EQ(6u, bag_two->entry_count); // attr_one is inherited from StyleOne. EXPECT_EQ(app::R::attr::attr_one, bag_two->entries[0].key); @@ -295,6 +295,11 @@ TEST_F(AssetManager2Test, MergesStylesWithParentFromSingleApkAssets) { EXPECT_EQ(Res_value::TYPE_INT_DEC, bag_two->entries[4].value.dataType); EXPECT_EQ(3u, bag_two->entries[4].value.data); EXPECT_EQ(0, bag_two->entries[4].cookie); + + EXPECT_EQ(app::R::attr::attr_empty, bag_two->entries[5].key); + EXPECT_EQ(Res_value::TYPE_NULL, bag_two->entries[5].value.dataType); + EXPECT_EQ(Res_value::DATA_NULL_EMPTY, bag_two->entries[5].value.data); + EXPECT_EQ(0, bag_two->entries[5].cookie); } TEST_F(AssetManager2Test, ResolveReferenceToResource) { diff --git a/libs/androidfw/tests/AttributeResolution_test.cpp b/libs/androidfw/tests/AttributeResolution_test.cpp index 1ff2ed40cfc4..2d73ce8f8ee3 100644 --- a/libs/androidfw/tests/AttributeResolution_test.cpp +++ b/libs/androidfw/tests/AttributeResolution_test.cpp @@ -69,8 +69,8 @@ TEST_F(AttributeResolutionTest, Theme) { ResTable::Theme theme(table_); ASSERT_EQ(NO_ERROR, theme.applyStyle(R::style::StyleTwo)); - std::array<uint32_t, 4> attrs{ - {R::attr::attr_one, R::attr::attr_two, R::attr::attr_three, R::attr::attr_four}}; + std::array<uint32_t, 5> attrs{{R::attr::attr_one, R::attr::attr_two, R::attr::attr_three, + R::attr::attr_four, R::attr::attr_empty}}; std::array<uint32_t, attrs.size() * STYLE_NUM_ENTRIES> values; ASSERT_TRUE(ResolveAttrs(&theme, 0 /*def_style_attr*/, 0 /*def_style_res*/, @@ -109,11 +109,21 @@ TEST_F(AttributeResolutionTest, Theme) { EXPECT_EQ(uint32_t(-1), values_cursor[STYLE_ASSET_COOKIE]); EXPECT_EQ(0u, values_cursor[STYLE_DENSITY]); EXPECT_EQ(0u, values_cursor[STYLE_CHANGING_CONFIGURATIONS]); + + // @empty comes from the theme, so it has the same asset cookie and changing configurations flags + // as the theme. + values_cursor += STYLE_NUM_ENTRIES; + EXPECT_EQ(Res_value::TYPE_NULL, values_cursor[STYLE_TYPE]); + EXPECT_EQ(Res_value::DATA_NULL_EMPTY, values_cursor[STYLE_DATA]); + EXPECT_EQ(0u, values_cursor[STYLE_RESOURCE_ID]); + EXPECT_EQ(1u, values_cursor[STYLE_ASSET_COOKIE]); + EXPECT_EQ(0u, values_cursor[STYLE_DENSITY]); + EXPECT_EQ(public_flag, values_cursor[STYLE_CHANGING_CONFIGURATIONS]); } TEST_F(AttributeResolutionXmlTest, XmlParser) { - std::array<uint32_t, 4> attrs{ - {R::attr::attr_one, R::attr::attr_two, R::attr::attr_three, R::attr::attr_four}}; + std::array<uint32_t, 5> attrs{{R::attr::attr_one, R::attr::attr_two, R::attr::attr_three, + R::attr::attr_four, R::attr::attr_empty}}; std::array<uint32_t, attrs.size() * STYLE_NUM_ENTRIES> values; ASSERT_TRUE(RetrieveAttributes(&table_, &xml_parser_, attrs.data(), attrs.size(), values.data(), @@ -121,7 +131,7 @@ TEST_F(AttributeResolutionXmlTest, XmlParser) { uint32_t* values_cursor = values.data(); EXPECT_EQ(Res_value::TYPE_NULL, values_cursor[STYLE_TYPE]); - EXPECT_EQ(0u, values_cursor[STYLE_DATA]); + EXPECT_EQ(Res_value::DATA_NULL_EMPTY, values_cursor[STYLE_DATA]); EXPECT_EQ(0u, values_cursor[STYLE_RESOURCE_ID]); EXPECT_EQ(uint32_t(-1), values_cursor[STYLE_ASSET_COOKIE]); EXPECT_EQ(0u, values_cursor[STYLE_DENSITY]); @@ -150,16 +160,24 @@ TEST_F(AttributeResolutionXmlTest, XmlParser) { EXPECT_EQ(uint32_t(-1), values_cursor[STYLE_ASSET_COOKIE]); EXPECT_EQ(0u, values_cursor[STYLE_DENSITY]); EXPECT_EQ(0u, values_cursor[STYLE_CHANGING_CONFIGURATIONS]); + + values_cursor += STYLE_NUM_ENTRIES; + EXPECT_EQ(Res_value::TYPE_NULL, values_cursor[STYLE_TYPE]); + EXPECT_EQ(Res_value::DATA_NULL_UNDEFINED, values_cursor[STYLE_DATA]); + EXPECT_EQ(0u, values_cursor[STYLE_RESOURCE_ID]); + EXPECT_EQ(uint32_t(-1), values_cursor[STYLE_ASSET_COOKIE]); + EXPECT_EQ(0u, values_cursor[STYLE_DENSITY]); + EXPECT_EQ(0u, values_cursor[STYLE_CHANGING_CONFIGURATIONS]); } TEST_F(AttributeResolutionXmlTest, ThemeAndXmlParser) { ResTable::Theme theme(table_); ASSERT_EQ(NO_ERROR, theme.applyStyle(R::style::StyleTwo)); - std::array<uint32_t, 5> attrs{{R::attr::attr_one, R::attr::attr_two, R::attr::attr_three, - R::attr::attr_four, R::attr::attr_five}}; + std::array<uint32_t, 6> attrs{{R::attr::attr_one, R::attr::attr_two, R::attr::attr_three, + R::attr::attr_four, R::attr::attr_five, R::attr::attr_empty}}; std::array<uint32_t, attrs.size() * STYLE_NUM_ENTRIES> values; - std::array<uint32_t, attrs.size()> indices; + std::array<uint32_t, attrs.size() + 1> indices; ApplyStyle(&theme, &xml_parser_, 0 /*def_style_attr*/, 0 /*def_style_res*/, attrs.data(), attrs.size(), values.data(), indices.data()); @@ -167,12 +185,12 @@ TEST_F(AttributeResolutionXmlTest, ThemeAndXmlParser) { const uint32_t public_flag = ResTable_typeSpec::SPEC_PUBLIC; uint32_t* values_cursor = values.data(); - EXPECT_EQ(Res_value::TYPE_INT_DEC, values_cursor[STYLE_TYPE]); - EXPECT_EQ(1u, values_cursor[STYLE_DATA]); + EXPECT_EQ(Res_value::TYPE_NULL, values_cursor[STYLE_TYPE]); + EXPECT_EQ(Res_value::DATA_NULL_EMPTY, values_cursor[STYLE_DATA]); EXPECT_EQ(0u, values_cursor[STYLE_RESOURCE_ID]); - EXPECT_EQ(1u, values_cursor[STYLE_ASSET_COOKIE]); + EXPECT_EQ(uint32_t(-1), values_cursor[STYLE_ASSET_COOKIE]); EXPECT_EQ(0u, values_cursor[STYLE_DENSITY]); - EXPECT_EQ(public_flag, values_cursor[STYLE_CHANGING_CONFIGURATIONS]); + EXPECT_EQ(0u, values_cursor[STYLE_CHANGING_CONFIGURATIONS]); values_cursor += STYLE_NUM_ENTRIES; EXPECT_EQ(Res_value::TYPE_STRING, values_cursor[STYLE_TYPE]); @@ -203,6 +221,20 @@ TEST_F(AttributeResolutionXmlTest, ThemeAndXmlParser) { EXPECT_EQ(1u, values_cursor[STYLE_ASSET_COOKIE]); EXPECT_EQ(0u, values_cursor[STYLE_DENSITY]); EXPECT_EQ(public_flag, values_cursor[STYLE_CHANGING_CONFIGURATIONS]); + + // @empty comes from the theme, so it has the same asset cookie and changing configurations flags + // as the theme. + values_cursor += STYLE_NUM_ENTRIES; + EXPECT_EQ(Res_value::TYPE_NULL, values_cursor[STYLE_TYPE]); + EXPECT_EQ(Res_value::DATA_NULL_EMPTY, values_cursor[STYLE_DATA]); + EXPECT_EQ(0u, values_cursor[STYLE_RESOURCE_ID]); + EXPECT_EQ(1u, values_cursor[STYLE_ASSET_COOKIE]); + EXPECT_EQ(0u, values_cursor[STYLE_DENSITY]); + EXPECT_EQ(public_flag, values_cursor[STYLE_CHANGING_CONFIGURATIONS]); + + // The first element of indices contains the number of indices. + std::array<uint32_t, 7> expected_indices = {{6u, 0u, 1u, 2u, 3u, 4u, 5u}}; + EXPECT_EQ(expected_indices, indices); } } // namespace android diff --git a/libs/androidfw/tests/data/styles/R.h b/libs/androidfw/tests/data/styles/R.h index 68527c744b37..05073a8869ec 100644 --- a/libs/androidfw/tests/data/styles/R.h +++ b/libs/androidfw/tests/data/styles/R.h @@ -33,6 +33,7 @@ struct R { attr_five = 0x7f010004u, attr_indirect = 0x7f010005u, attr_six = 0x7f010006u, + attr_empty = 0x7f010007u, }; }; diff --git a/libs/androidfw/tests/data/styles/build b/libs/androidfw/tests/data/styles/build index 81f78b1b7b7f..1ef8e6e19208 100755 --- a/libs/androidfw/tests/data/styles/build +++ b/libs/androidfw/tests/data/styles/build @@ -2,4 +2,5 @@ set -e -aapt package -F styles.apk -M AndroidManifest.xml -S res -f +aapt2 compile -o compiled.flata --dir res +aapt2 link -o styles.apk --manifest AndroidManifest.xml compiled.flata diff --git a/libs/androidfw/tests/data/styles/res/layout/layout.xml b/libs/androidfw/tests/data/styles/res/layout/layout.xml index f3aa0f83d9a3..2c5e9476e150 100644 --- a/libs/androidfw/tests/data/styles/res/layout/layout.xml +++ b/libs/androidfw/tests/data/styles/res/layout/layout.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8"?> <View xmlns:app="http://schemas.android.com/apk/res-auto" app:attr_four="?attr/attr_indirect" - app:attr_three="10" /> - + app:attr_three="10" + app:attr_one="@empty" /> diff --git a/libs/androidfw/tests/data/styles/res/values/styles.xml b/libs/androidfw/tests/data/styles/res/values/styles.xml index da592f806d21..3c90317a62c6 100644 --- a/libs/androidfw/tests/data/styles/res/values/styles.xml +++ b/libs/androidfw/tests/data/styles/res/values/styles.xml @@ -33,6 +33,12 @@ <public type="attr" name="attr_indirect" id="0x7f010005" /> <attr name="attr_indirect" /> + <public type="attr" name="attr_six" id="0x7f010006" /> + <attr name="attr_six" /> + + <public type="attr" name="attr_empty" id="0x7f010007" /> + <attr name="attr_empty" /> + <public type="string" name="string_one" id="0x7f030000" /> <string name="string_one">Hi</string> @@ -48,11 +54,9 @@ <item name="attr_two">"string"</item> <item name="attr_three">?attr/attr_indirect</item> <item name="attr_five">@string/string_one</item> + <item name="attr_empty">@empty</item> </style> - - <public type="attr" name="attr_six" id="0x7f010006" /> - <attr name="attr_six" /> - + <public type="style" name="StyleThree" id="0x7f020002" /> <style name="StyleThree"> <item name="attr_six">6</item> diff --git a/libs/androidfw/tests/data/styles/styles.apk b/libs/androidfw/tests/data/styles/styles.apk Binary files differindex d4ccb8391202..72abf8ff2b40 100644 --- a/libs/androidfw/tests/data/styles/styles.apk +++ b/libs/androidfw/tests/data/styles/styles.apk |