diff --git a/tools/aapt2/ResourceParser.cpp b/tools/aapt2/ResourceParser.cpp index 859fe80c5ce75..c557656632049 100644 --- a/tools/aapt2/ResourceParser.cpp +++ b/tools/aapt2/ResourceParser.cpp @@ -1387,7 +1387,7 @@ Maybe 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) { diff --git a/tools/aapt2/ResourceParser_test.cpp b/tools/aapt2/ResourceParser_test.cpp index 464225fefb857..42374690d1350 100644 --- a/tools/aapt2/ResourceParser_test.cpp +++ b/tools/aapt2/ResourceParser_test.cpp @@ -401,7 +401,7 @@ TEST_F(ResourceParserTest, ParseEnumAttr) { std::string input = R"( - + )"; 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) { diff --git a/tools/aapt2/ResourceUtils.cpp b/tools/aapt2/ResourceUtils.cpp index e0040e486a233..bd2ab53773114 100644 --- a/tools/aapt2/ResourceUtils.cpp +++ b/tools/aapt2/ResourceUtils.cpp @@ -378,7 +378,7 @@ std::unique_ptr 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(value); } diff --git a/tools/aapt2/ResourceValues.h b/tools/aapt2/ResourceValues.h index 168ad61784e7d..fe0883be50aa4 100644 --- a/tools/aapt2/ResourceValues.h +++ b/tools/aapt2/ResourceValues.h @@ -292,6 +292,7 @@ struct Attribute : public BaseValue { struct Symbol { Reference symbol; uint32_t value; + uint8_t type; friend std::ostream& operator<<(std::ostream& out, const Symbol& symbol); }; diff --git a/tools/aapt2/Resources.proto b/tools/aapt2/Resources.proto index b2fc08423d348..65f465240d7dd 100644 --- a/tools/aapt2/Resources.proto +++ b/tools/aapt2/Resources.proto @@ -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. diff --git a/tools/aapt2/format/binary/BinaryResourceParser.cpp b/tools/aapt2/format/binary/BinaryResourceParser.cpp index fd8e36ebf8233..fcd6aaafba7ab 100644 --- a/tools/aapt2/format/binary/BinaryResourceParser.cpp +++ b/tools/aapt2/format/binary/BinaryResourceParser.cpp @@ -614,6 +614,7 @@ std::unique_ptr 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)); } diff --git a/tools/aapt2/format/binary/TableFlattener.cpp b/tools/aapt2/format/binary/TableFlattener.cpp index f2e72da4056a7..b9321174100b8 100644 --- a/tools/aapt2/format/binary/TableFlattener.cpp +++ b/tools/aapt2/format/binary/TableFlattener.cpp @@ -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); } } diff --git a/tools/aapt2/format/proto/ProtoDeserialize.cpp b/tools/aapt2/format/proto/ProtoDeserialize.cpp index bb21c1c539fbb..efbf636878f2d 100644 --- a/tools/aapt2/format/proto/ProtoDeserialize.cpp +++ b/tools/aapt2/format/proto/ProtoDeserialize.cpp @@ -708,6 +708,8 @@ std::unique_ptr 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); diff --git a/tools/aapt2/format/proto/ProtoSerialize.cpp b/tools/aapt2/format/proto/ProtoSerialize.cpp index a54822b20302e..aa6547e81624f 100644 --- a/tools/aapt2/format/proto/ProtoSerialize.cpp +++ b/tools/aapt2/format/proto/ProtoSerialize.cpp @@ -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); } } diff --git a/tools/aapt2/format/proto/ProtoSerialize_test.cpp b/tools/aapt2/format/proto/ProtoSerialize_test.cpp index f252f33f44fba..e7f23302652c0 100644 --- a/tools/aapt2/format/proto/ProtoSerialize_test.cpp +++ b/tools/aapt2/format/proto/ProtoSerialize_test.cpp @@ -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( &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(&new_table, "com.app.a:layout/abc"); ASSERT_THAT(actual_ref, NotNull()); diff --git a/tools/aapt2/process/SymbolTable.cpp b/tools/aapt2/process/SymbolTable.cpp index 61a8fbbb7f521..bc09f19b94d5b 100644 --- a/tools/aapt2/process/SymbolTable.cpp +++ b/tools/aapt2/process/SymbolTable.cpp @@ -313,6 +313,7 @@ static std::unique_ptr 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)); } }