Retain parsed attribute type
If the value of an attribute enum is defined as a hexadecimal integer, flatten uses of the attribute as with the android::Res_value::TYPE_INT_HEX type. This change adds a "type" field to pb::Attribute::Symbol, which if left unset, will have a default value of android::Res_value::TYPE_INT_DEC when deserialized by aapt2. Bug: 124474141 Test: aapt2_tests and manual compilation of files and inspection using `aapt2 dump chunks` Change-Id: Ibf12394284fdbe3a8047f7ecf4fe68517dfc3abb
This commit is contained in:
@@ -1387,7 +1387,7 @@ Maybe<Attribute::Symbol> ResourceParser::ParseEnumOrFlagItem(
|
||||
|
||||
return Attribute::Symbol{
|
||||
Reference(ResourceNameRef({}, ResourceType::kId, maybe_name.value())),
|
||||
val.data};
|
||||
val.data, val.dataType};
|
||||
}
|
||||
|
||||
bool ResourceParser::ParseStyleItem(xml::XmlPullParser* parser, Style* style) {
|
||||
|
||||
@@ -401,7 +401,7 @@ TEST_F(ResourceParserTest, ParseEnumAttr) {
|
||||
std::string input = R"(
|
||||
<attr name="foo">
|
||||
<enum name="bar" value="0"/>
|
||||
<enum name="bat" value="1"/>
|
||||
<enum name="bat" value="0x1"/>
|
||||
<enum name="baz" value="2"/>
|
||||
</attr>)";
|
||||
ASSERT_TRUE(TestParse(input));
|
||||
@@ -414,14 +414,17 @@ TEST_F(ResourceParserTest, ParseEnumAttr) {
|
||||
ASSERT_TRUE(enum_attr->symbols[0].symbol.name);
|
||||
EXPECT_THAT(enum_attr->symbols[0].symbol.name.value().entry, Eq("bar"));
|
||||
EXPECT_THAT(enum_attr->symbols[0].value, Eq(0u));
|
||||
EXPECT_THAT(enum_attr->symbols[0].type, Eq(Res_value::TYPE_INT_DEC));
|
||||
|
||||
ASSERT_TRUE(enum_attr->symbols[1].symbol.name);
|
||||
EXPECT_THAT(enum_attr->symbols[1].symbol.name.value().entry, Eq("bat"));
|
||||
EXPECT_THAT(enum_attr->symbols[1].value, Eq(1u));
|
||||
EXPECT_THAT(enum_attr->symbols[1].type, Eq(Res_value::TYPE_INT_HEX));
|
||||
|
||||
ASSERT_TRUE(enum_attr->symbols[2].symbol.name);
|
||||
EXPECT_THAT(enum_attr->symbols[2].symbol.name.value().entry, Eq("baz"));
|
||||
EXPECT_THAT(enum_attr->symbols[2].value, Eq(2u));
|
||||
EXPECT_THAT(enum_attr->symbols[2].type, Eq(Res_value::TYPE_INT_DEC));
|
||||
}
|
||||
|
||||
TEST_F(ResourceParserTest, ParseFlagAttr) {
|
||||
|
||||
@@ -378,7 +378,7 @@ std::unique_ptr<BinaryPrimitive> TryParseEnumSymbol(const Attribute* enum_attr,
|
||||
const ResourceName& enum_symbol_resource_name = symbol.symbol.name.value();
|
||||
if (trimmed_str == enum_symbol_resource_name.entry) {
|
||||
android::Res_value value = {};
|
||||
value.dataType = android::Res_value::TYPE_INT_DEC;
|
||||
value.dataType = symbol.type;
|
||||
value.data = symbol.value;
|
||||
return util::make_unique<BinaryPrimitive>(value);
|
||||
}
|
||||
|
||||
@@ -292,6 +292,7 @@ struct Attribute : public BaseValue<Attribute> {
|
||||
struct Symbol {
|
||||
Reference symbol;
|
||||
uint32_t value;
|
||||
uint8_t type;
|
||||
|
||||
friend std::ostream& operator<<(std::ostream& out, const Symbol& symbol);
|
||||
};
|
||||
|
||||
@@ -388,6 +388,9 @@ message Attribute {
|
||||
|
||||
// The value of the enum/flag.
|
||||
uint32 value = 4;
|
||||
|
||||
// The data type of the enum/flag as defined in android::Res_value.
|
||||
uint32 type = 5;
|
||||
}
|
||||
|
||||
// Bitmask of formats allowed for an attribute.
|
||||
|
||||
@@ -614,6 +614,7 @@ std::unique_ptr<Attribute> BinaryResourceParser::ParseAttr(const ResourceNameRef
|
||||
if (attr->type_mask & (ResTable_map::TYPE_ENUM | ResTable_map::TYPE_FLAGS)) {
|
||||
Attribute::Symbol symbol;
|
||||
symbol.value = util::DeviceToHost32(map_entry.value.data);
|
||||
symbol.type = map_entry.value.dataType;
|
||||
symbol.symbol = Reference(util::DeviceToHost32(map_entry.name.ident));
|
||||
attr->symbols.push_back(std::move(symbol));
|
||||
}
|
||||
|
||||
@@ -107,7 +107,7 @@ class MapFlattenVisitor : public ValueVisitor {
|
||||
}
|
||||
|
||||
for (Attribute::Symbol& s : attr->symbols) {
|
||||
BinaryPrimitive val(Res_value::TYPE_INT_DEC, s.value);
|
||||
BinaryPrimitive val(s.type, s.value);
|
||||
FlattenEntry(&s.symbol, &val);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -708,6 +708,8 @@ std::unique_ptr<Value> DeserializeValueFromPb(const pb::Value& pb_value,
|
||||
return {};
|
||||
}
|
||||
symbol.value = pb_symbol.value();
|
||||
symbol.type = pb_symbol.type() != 0U ? pb_symbol.type()
|
||||
: android::Res_value::TYPE_INT_DEC;
|
||||
attr->symbols.push_back(std::move(symbol));
|
||||
}
|
||||
value = std::move(attr);
|
||||
|
||||
@@ -552,6 +552,7 @@ class ValueSerializer : public ConstValueVisitor {
|
||||
SerializeItemMetaDataToPb(symbol.symbol, pb_symbol, src_pool_);
|
||||
SerializeReferenceToPb(symbol.symbol, pb_symbol->mutable_name());
|
||||
pb_symbol->set_value(symbol.value);
|
||||
pb_symbol->set_type(symbol.type);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -80,7 +80,7 @@ TEST(ProtoSerializeTest, SerializeSinglePackage) {
|
||||
test::BuildPrimitive(android::Res_value::TYPE_INT_DEC, 123u), context->GetDiagnostics()));
|
||||
ASSERT_TRUE(table->AddResource(
|
||||
test::ParseNameOrDie("com.app.a:integer/one"), test::ParseConfigOrDie("land"), "tablet",
|
||||
test::BuildPrimitive(android::Res_value::TYPE_INT_DEC, 321u), context->GetDiagnostics()));
|
||||
test::BuildPrimitive(android::Res_value::TYPE_INT_HEX, 321u), context->GetDiagnostics()));
|
||||
|
||||
// Make a reference with both resource name and resource ID.
|
||||
// The reference should point to a resource outside of this table to test that both name and id
|
||||
@@ -133,11 +133,13 @@ TEST(ProtoSerializeTest, SerializeSinglePackage) {
|
||||
&new_table, "com.app.a:integer/one", test::ParseConfigOrDie("land"), "");
|
||||
ASSERT_THAT(prim, NotNull());
|
||||
EXPECT_THAT(prim->value.data, Eq(123u));
|
||||
EXPECT_THAT(prim->value.dataType, Eq(0x10));
|
||||
|
||||
prim = test::GetValueForConfigAndProduct<BinaryPrimitive>(
|
||||
&new_table, "com.app.a:integer/one", test::ParseConfigOrDie("land"), "tablet");
|
||||
ASSERT_THAT(prim, NotNull());
|
||||
EXPECT_THAT(prim->value.data, Eq(321u));
|
||||
EXPECT_THAT(prim->value.dataType, Eq(0x11));
|
||||
|
||||
Reference* actual_ref = test::GetValue<Reference>(&new_table, "com.app.a:layout/abc");
|
||||
ASSERT_THAT(actual_ref, NotNull());
|
||||
|
||||
@@ -313,6 +313,7 @@ static std::unique_ptr<SymbolTable::Symbol> LookupAttributeInTable(
|
||||
symbol.symbol.name = parsed_name.value();
|
||||
symbol.symbol.id = ResourceId(map_entry.key);
|
||||
symbol.value = map_entry.value.data;
|
||||
symbol.type = map_entry.value.dataType;
|
||||
s->attribute->symbols.push_back(std::move(symbol));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user