Loading tools/aapt2/Resources.proto +18 −3 Original line number Diff line number Diff line Loading @@ -306,10 +306,25 @@ message FileReference { } // A value that represents a primitive data type (float, int, boolean, etc.). // Corresponds to the fields (type/data) of the C struct android::Res_value. message Primitive { uint32 type = 1; uint32 data = 2; message NullType { } message EmptyType { } oneof oneof_value { NullType null_value = 1; EmptyType empty_value = 2; float float_value = 3; float dimension_value = 4; float fraction_value = 5; int32 int_decimal_value = 6; uint32 int_hexidecimal_value = 7; bool boolean_value = 8; uint32 color_argb8_value = 9; uint32 color_rgb8_value = 10; uint32 color_argb4_value = 11; uint32 color_rgb4_value = 12; } } // A value that represents an XML attribute and what values it accepts. Loading tools/aapt2/format/proto/ProtoDeserialize.cpp +61 −2 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ #include "Locale.h" #include "ResourceTable.h" #include "ResourceUtils.h" #include "ResourceValues.h" #include "ValueVisitor.h" using ::android::ResStringPool; Loading Loading @@ -761,8 +762,66 @@ std::unique_ptr<Item> DeserializeItemFromPb(const pb::Item& pb_item, case pb::Item::kPrim: { const pb::Primitive& pb_prim = pb_item.prim(); return util::make_unique<BinaryPrimitive>(static_cast<uint8_t>(pb_prim.type()), pb_prim.data()); android::Res_value val = {}; switch (pb_prim.oneof_value_case()) { case pb::Primitive::kNullValue: { val.dataType = android::Res_value::TYPE_NULL; val.data = android::Res_value::DATA_NULL_UNDEFINED; } break; case pb::Primitive::kEmptyValue: { val.dataType = android::Res_value::TYPE_NULL; val.data = android::Res_value::DATA_NULL_EMPTY; } break; case pb::Primitive::kFloatValue: { val.dataType = android::Res_value::TYPE_FLOAT; float float_val = pb_prim.float_value(); val.data = *(uint32_t*)&float_val; } break; case pb::Primitive::kDimensionValue: { val.dataType = android::Res_value::TYPE_DIMENSION; float dimen_val = pb_prim.dimension_value(); val.data = *(uint32_t*)&dimen_val; } break; case pb::Primitive::kFractionValue: { val.dataType = android::Res_value::TYPE_FRACTION; float fraction_val = pb_prim.fraction_value(); val.data = *(uint32_t*)&fraction_val; } break; case pb::Primitive::kIntDecimalValue: { val.dataType = android::Res_value::TYPE_INT_DEC; val.data = static_cast<uint32_t>(pb_prim.int_decimal_value()); } break; case pb::Primitive::kIntHexidecimalValue: { val.dataType = android::Res_value::TYPE_INT_HEX; val.data = pb_prim.int_hexidecimal_value(); } break; case pb::Primitive::kBooleanValue: { val.dataType = android::Res_value::TYPE_INT_BOOLEAN; val.data = pb_prim.boolean_value() ? 0xFFFFFFFF : 0x0; } break; case pb::Primitive::kColorArgb8Value: { val.dataType = android::Res_value::TYPE_INT_COLOR_ARGB8; val.data = pb_prim.color_argb8_value(); } break; case pb::Primitive::kColorRgb8Value: { val.dataType = android::Res_value::TYPE_INT_COLOR_RGB8; val.data = pb_prim.color_rgb8_value(); } break; case pb::Primitive::kColorArgb4Value: { val.dataType = android::Res_value::TYPE_INT_COLOR_ARGB4; val.data = pb_prim.color_argb4_value(); } break; case pb::Primitive::kColorRgb4Value: { val.dataType = android::Res_value::TYPE_INT_COLOR_RGB4; val.data = pb_prim.color_rgb4_value(); } break; default: { LOG(FATAL) << "Unexpected Primitive type: " << static_cast<uint32_t>(pb_prim.oneof_value_case()); return {}; } break; } return util::make_unique<BinaryPrimitive>(val); } break; case pb::Item::kId: { Loading tools/aapt2/format/proto/ProtoSerialize.cpp +45 −2 Original line number Diff line number Diff line Loading @@ -436,8 +436,51 @@ class ValueSerializer : public ConstValueVisitor { prim->Flatten(&val); pb::Primitive* pb_prim = out_value_->mutable_item()->mutable_prim(); pb_prim->set_type(val.dataType); pb_prim->set_data(val.data); switch (val.dataType) { case android::Res_value::TYPE_NULL: { if (val.data == android::Res_value::DATA_NULL_UNDEFINED) { pb_prim->set_allocated_null_value(new pb::Primitive_NullType()); } else if (val.data == android::Res_value::DATA_NULL_EMPTY) { pb_prim->set_allocated_empty_value(new pb::Primitive_EmptyType()); } else { LOG(FATAL) << "Unexpected data value for TYPE_NULL BinaryPrimitive: " << val.data; } } break; case android::Res_value::TYPE_FLOAT: { pb_prim->set_float_value(*(float*)&val.data); } break; case android::Res_value::TYPE_DIMENSION: { pb_prim->set_dimension_value(*(float*)&val.data); } break; case android::Res_value::TYPE_FRACTION: { pb_prim->set_fraction_value(*(float*)&val.data); } break; case android::Res_value::TYPE_INT_DEC: { pb_prim->set_int_decimal_value(static_cast<int32_t>(val.data)); } break; case android::Res_value::TYPE_INT_HEX: { pb_prim->set_int_hexidecimal_value(val.data); } break; case android::Res_value::TYPE_INT_BOOLEAN: { pb_prim->set_boolean_value(static_cast<bool>(val.data)); } break; case android::Res_value::TYPE_INT_COLOR_ARGB8: { pb_prim->set_color_argb8_value(val.data); } break; case android::Res_value::TYPE_INT_COLOR_RGB8: { pb_prim->set_color_rgb8_value(val.data); } break; case android::Res_value::TYPE_INT_COLOR_ARGB4: { pb_prim->set_color_argb4_value(val.data); } break; case android::Res_value::TYPE_INT_COLOR_RGB4: { pb_prim->set_color_rgb4_value(val.data); } break; default: LOG(FATAL) << "Unexpected BinaryPrimitive type: " << val.dataType; break; } } void Visit(const Attribute* attr) override { Loading tools/aapt2/format/proto/ProtoSerialize_test.cpp +105 −0 Original line number Diff line number Diff line Loading @@ -254,6 +254,111 @@ TEST(ProtoSerializeTest, SerializeAndDeserializeXml) { EXPECT_THAT(child_text->text, StrEq("woah there")); } TEST(ProtoSerializeTest, SerializeAndDeserializePrimitives) { std::unique_ptr<ResourceTable> table = test::ResourceTableBuilder() .AddValue("android:bool/boolean_true", test::BuildPrimitive(android::Res_value::TYPE_INT_BOOLEAN, true)) .AddValue("android:bool/boolean_false", test::BuildPrimitive(android::Res_value::TYPE_INT_BOOLEAN, false)) .AddValue("android:color/color_rgb8", ResourceUtils::TryParseColor("#AABBCC")) .AddValue("android:color/color_argb8", ResourceUtils::TryParseColor("#11223344")) .AddValue("android:color/color_rgb4", ResourceUtils::TryParseColor("#DEF")) .AddValue("android:color/color_argb4", ResourceUtils::TryParseColor("#5678")) .AddValue("android:integer/integer_444", ResourceUtils::TryParseInt("444")) .AddValue("android:integer/integer_neg_333", ResourceUtils::TryParseInt("-333")) .AddValue("android:integer/hex_int_abcd", ResourceUtils::TryParseInt("0xABCD")) .AddValue("android:dimen/dimen_1.39mm", ResourceUtils::TryParseFloat("1.39mm")) .AddValue("android:fraction/fraction_27", ResourceUtils::TryParseFloat("27%")) .AddValue("android:integer/null", ResourceUtils::MakeEmpty()) .Build(); pb::ResourceTable pb_table; SerializeTableToPb(*table, &pb_table); test::TestFile file_a("res/layout/main.xml"); MockFileCollection files; EXPECT_CALL(files, FindFile(Eq("res/layout/main.xml"))) .WillRepeatedly(::testing::Return(&file_a)); ResourceTable new_table; std::string error; ASSERT_TRUE(DeserializeTableFromPb(pb_table, &files, &new_table, &error)); EXPECT_THAT(error, IsEmpty()); BinaryPrimitive* bp = test::GetValueForConfigAndProduct<BinaryPrimitive>( &new_table, "android:bool/boolean_true", ConfigDescription::DefaultConfig(), ""); ASSERT_THAT(bp, NotNull()); EXPECT_THAT(bp->value.dataType, Eq(android::Res_value::TYPE_INT_BOOLEAN)); EXPECT_THAT(bp->value.data, Eq(ResourceUtils::TryParseBool("true")->value.data)); bp = test::GetValueForConfigAndProduct<BinaryPrimitive>(&new_table, "android:bool/boolean_false", ConfigDescription::DefaultConfig(), ""); ASSERT_THAT(bp, NotNull()); EXPECT_THAT(bp->value.dataType, Eq(android::Res_value::TYPE_INT_BOOLEAN)); EXPECT_THAT(bp->value.data, Eq(ResourceUtils::TryParseBool("false")->value.data)); bp = test::GetValueForConfigAndProduct<BinaryPrimitive>(&new_table, "android:color/color_rgb8", ConfigDescription::DefaultConfig(), ""); ASSERT_THAT(bp, NotNull()); EXPECT_THAT(bp->value.dataType, Eq(android::Res_value::TYPE_INT_COLOR_RGB8)); EXPECT_THAT(bp->value.data, Eq(ResourceUtils::TryParseColor("#AABBCC")->value.data)); bp = test::GetValueForConfigAndProduct<BinaryPrimitive>(&new_table, "android:color/color_argb8", ConfigDescription::DefaultConfig(), ""); ASSERT_THAT(bp, NotNull()); EXPECT_THAT(bp->value.dataType, Eq(android::Res_value::TYPE_INT_COLOR_ARGB8)); EXPECT_THAT(bp->value.data, Eq(ResourceUtils::TryParseColor("#11223344")->value.data)); bp = test::GetValueForConfigAndProduct<BinaryPrimitive>(&new_table, "android:color/color_rgb4", ConfigDescription::DefaultConfig(), ""); ASSERT_THAT(bp, NotNull()); EXPECT_THAT(bp->value.dataType, Eq(android::Res_value::TYPE_INT_COLOR_RGB4)); EXPECT_THAT(bp->value.data, Eq(ResourceUtils::TryParseColor("#DEF")->value.data)); bp = test::GetValueForConfigAndProduct<BinaryPrimitive>(&new_table, "android:color/color_argb4", ConfigDescription::DefaultConfig(), ""); ASSERT_THAT(bp, NotNull()); EXPECT_THAT(bp->value.dataType, Eq(android::Res_value::TYPE_INT_COLOR_ARGB4)); EXPECT_THAT(bp->value.data, Eq(ResourceUtils::TryParseColor("#5678")->value.data)); bp = test::GetValueForConfigAndProduct<BinaryPrimitive>(&new_table, "android:integer/integer_444", ConfigDescription::DefaultConfig(), ""); ASSERT_THAT(bp, NotNull()); EXPECT_THAT(bp->value.dataType, Eq(android::Res_value::TYPE_INT_DEC)); EXPECT_THAT(bp->value.data, Eq(ResourceUtils::TryParseInt("444")->value.data)); bp = test::GetValueForConfigAndProduct<BinaryPrimitive>( &new_table, "android:integer/integer_neg_333", ConfigDescription::DefaultConfig(), ""); ASSERT_THAT(bp, NotNull()); EXPECT_THAT(bp->value.dataType, Eq(android::Res_value::TYPE_INT_DEC)); EXPECT_THAT(bp->value.data, Eq(ResourceUtils::TryParseInt("-333")->value.data)); bp = test::GetValueForConfigAndProduct<BinaryPrimitive>( &new_table, "android:integer/hex_int_abcd", ConfigDescription::DefaultConfig(), ""); ASSERT_THAT(bp, NotNull()); EXPECT_THAT(bp->value.dataType, Eq(android::Res_value::TYPE_INT_HEX)); EXPECT_THAT(bp->value.data, Eq(ResourceUtils::TryParseInt("0xABCD")->value.data)); bp = test::GetValueForConfigAndProduct<BinaryPrimitive>(&new_table, "android:dimen/dimen_1.39mm", ConfigDescription::DefaultConfig(), ""); ASSERT_THAT(bp, NotNull()); EXPECT_THAT(bp->value.dataType, Eq(android::Res_value::TYPE_DIMENSION)); EXPECT_THAT(bp->value.data, Eq(ResourceUtils::TryParseFloat("1.39mm")->value.data)); bp = test::GetValueForConfigAndProduct<BinaryPrimitive>( &new_table, "android:fraction/fraction_27", ConfigDescription::DefaultConfig(), ""); ASSERT_THAT(bp, NotNull()); EXPECT_THAT(bp->value.dataType, Eq(android::Res_value::TYPE_FRACTION)); EXPECT_THAT(bp->value.data, Eq(ResourceUtils::TryParseFloat("27%")->value.data)); bp = test::GetValueForConfigAndProduct<BinaryPrimitive>(&new_table, "android:integer/null", ConfigDescription::DefaultConfig(), ""); ASSERT_THAT(bp, NotNull()); EXPECT_THAT(bp->value.dataType, Eq(android::Res_value::TYPE_NULL)); EXPECT_THAT(bp->value.data, Eq(ResourceUtils::MakeEmpty()->value.data)); } static void ExpectConfigSerializes(const StringPiece& config_str) { const ConfigDescription expected_config = test::ParseConfigOrDie(config_str); pb::Configuration pb_config; Loading Loading
tools/aapt2/Resources.proto +18 −3 Original line number Diff line number Diff line Loading @@ -306,10 +306,25 @@ message FileReference { } // A value that represents a primitive data type (float, int, boolean, etc.). // Corresponds to the fields (type/data) of the C struct android::Res_value. message Primitive { uint32 type = 1; uint32 data = 2; message NullType { } message EmptyType { } oneof oneof_value { NullType null_value = 1; EmptyType empty_value = 2; float float_value = 3; float dimension_value = 4; float fraction_value = 5; int32 int_decimal_value = 6; uint32 int_hexidecimal_value = 7; bool boolean_value = 8; uint32 color_argb8_value = 9; uint32 color_rgb8_value = 10; uint32 color_argb4_value = 11; uint32 color_rgb4_value = 12; } } // A value that represents an XML attribute and what values it accepts. Loading
tools/aapt2/format/proto/ProtoDeserialize.cpp +61 −2 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ #include "Locale.h" #include "ResourceTable.h" #include "ResourceUtils.h" #include "ResourceValues.h" #include "ValueVisitor.h" using ::android::ResStringPool; Loading Loading @@ -761,8 +762,66 @@ std::unique_ptr<Item> DeserializeItemFromPb(const pb::Item& pb_item, case pb::Item::kPrim: { const pb::Primitive& pb_prim = pb_item.prim(); return util::make_unique<BinaryPrimitive>(static_cast<uint8_t>(pb_prim.type()), pb_prim.data()); android::Res_value val = {}; switch (pb_prim.oneof_value_case()) { case pb::Primitive::kNullValue: { val.dataType = android::Res_value::TYPE_NULL; val.data = android::Res_value::DATA_NULL_UNDEFINED; } break; case pb::Primitive::kEmptyValue: { val.dataType = android::Res_value::TYPE_NULL; val.data = android::Res_value::DATA_NULL_EMPTY; } break; case pb::Primitive::kFloatValue: { val.dataType = android::Res_value::TYPE_FLOAT; float float_val = pb_prim.float_value(); val.data = *(uint32_t*)&float_val; } break; case pb::Primitive::kDimensionValue: { val.dataType = android::Res_value::TYPE_DIMENSION; float dimen_val = pb_prim.dimension_value(); val.data = *(uint32_t*)&dimen_val; } break; case pb::Primitive::kFractionValue: { val.dataType = android::Res_value::TYPE_FRACTION; float fraction_val = pb_prim.fraction_value(); val.data = *(uint32_t*)&fraction_val; } break; case pb::Primitive::kIntDecimalValue: { val.dataType = android::Res_value::TYPE_INT_DEC; val.data = static_cast<uint32_t>(pb_prim.int_decimal_value()); } break; case pb::Primitive::kIntHexidecimalValue: { val.dataType = android::Res_value::TYPE_INT_HEX; val.data = pb_prim.int_hexidecimal_value(); } break; case pb::Primitive::kBooleanValue: { val.dataType = android::Res_value::TYPE_INT_BOOLEAN; val.data = pb_prim.boolean_value() ? 0xFFFFFFFF : 0x0; } break; case pb::Primitive::kColorArgb8Value: { val.dataType = android::Res_value::TYPE_INT_COLOR_ARGB8; val.data = pb_prim.color_argb8_value(); } break; case pb::Primitive::kColorRgb8Value: { val.dataType = android::Res_value::TYPE_INT_COLOR_RGB8; val.data = pb_prim.color_rgb8_value(); } break; case pb::Primitive::kColorArgb4Value: { val.dataType = android::Res_value::TYPE_INT_COLOR_ARGB4; val.data = pb_prim.color_argb4_value(); } break; case pb::Primitive::kColorRgb4Value: { val.dataType = android::Res_value::TYPE_INT_COLOR_RGB4; val.data = pb_prim.color_rgb4_value(); } break; default: { LOG(FATAL) << "Unexpected Primitive type: " << static_cast<uint32_t>(pb_prim.oneof_value_case()); return {}; } break; } return util::make_unique<BinaryPrimitive>(val); } break; case pb::Item::kId: { Loading
tools/aapt2/format/proto/ProtoSerialize.cpp +45 −2 Original line number Diff line number Diff line Loading @@ -436,8 +436,51 @@ class ValueSerializer : public ConstValueVisitor { prim->Flatten(&val); pb::Primitive* pb_prim = out_value_->mutable_item()->mutable_prim(); pb_prim->set_type(val.dataType); pb_prim->set_data(val.data); switch (val.dataType) { case android::Res_value::TYPE_NULL: { if (val.data == android::Res_value::DATA_NULL_UNDEFINED) { pb_prim->set_allocated_null_value(new pb::Primitive_NullType()); } else if (val.data == android::Res_value::DATA_NULL_EMPTY) { pb_prim->set_allocated_empty_value(new pb::Primitive_EmptyType()); } else { LOG(FATAL) << "Unexpected data value for TYPE_NULL BinaryPrimitive: " << val.data; } } break; case android::Res_value::TYPE_FLOAT: { pb_prim->set_float_value(*(float*)&val.data); } break; case android::Res_value::TYPE_DIMENSION: { pb_prim->set_dimension_value(*(float*)&val.data); } break; case android::Res_value::TYPE_FRACTION: { pb_prim->set_fraction_value(*(float*)&val.data); } break; case android::Res_value::TYPE_INT_DEC: { pb_prim->set_int_decimal_value(static_cast<int32_t>(val.data)); } break; case android::Res_value::TYPE_INT_HEX: { pb_prim->set_int_hexidecimal_value(val.data); } break; case android::Res_value::TYPE_INT_BOOLEAN: { pb_prim->set_boolean_value(static_cast<bool>(val.data)); } break; case android::Res_value::TYPE_INT_COLOR_ARGB8: { pb_prim->set_color_argb8_value(val.data); } break; case android::Res_value::TYPE_INT_COLOR_RGB8: { pb_prim->set_color_rgb8_value(val.data); } break; case android::Res_value::TYPE_INT_COLOR_ARGB4: { pb_prim->set_color_argb4_value(val.data); } break; case android::Res_value::TYPE_INT_COLOR_RGB4: { pb_prim->set_color_rgb4_value(val.data); } break; default: LOG(FATAL) << "Unexpected BinaryPrimitive type: " << val.dataType; break; } } void Visit(const Attribute* attr) override { Loading
tools/aapt2/format/proto/ProtoSerialize_test.cpp +105 −0 Original line number Diff line number Diff line Loading @@ -254,6 +254,111 @@ TEST(ProtoSerializeTest, SerializeAndDeserializeXml) { EXPECT_THAT(child_text->text, StrEq("woah there")); } TEST(ProtoSerializeTest, SerializeAndDeserializePrimitives) { std::unique_ptr<ResourceTable> table = test::ResourceTableBuilder() .AddValue("android:bool/boolean_true", test::BuildPrimitive(android::Res_value::TYPE_INT_BOOLEAN, true)) .AddValue("android:bool/boolean_false", test::BuildPrimitive(android::Res_value::TYPE_INT_BOOLEAN, false)) .AddValue("android:color/color_rgb8", ResourceUtils::TryParseColor("#AABBCC")) .AddValue("android:color/color_argb8", ResourceUtils::TryParseColor("#11223344")) .AddValue("android:color/color_rgb4", ResourceUtils::TryParseColor("#DEF")) .AddValue("android:color/color_argb4", ResourceUtils::TryParseColor("#5678")) .AddValue("android:integer/integer_444", ResourceUtils::TryParseInt("444")) .AddValue("android:integer/integer_neg_333", ResourceUtils::TryParseInt("-333")) .AddValue("android:integer/hex_int_abcd", ResourceUtils::TryParseInt("0xABCD")) .AddValue("android:dimen/dimen_1.39mm", ResourceUtils::TryParseFloat("1.39mm")) .AddValue("android:fraction/fraction_27", ResourceUtils::TryParseFloat("27%")) .AddValue("android:integer/null", ResourceUtils::MakeEmpty()) .Build(); pb::ResourceTable pb_table; SerializeTableToPb(*table, &pb_table); test::TestFile file_a("res/layout/main.xml"); MockFileCollection files; EXPECT_CALL(files, FindFile(Eq("res/layout/main.xml"))) .WillRepeatedly(::testing::Return(&file_a)); ResourceTable new_table; std::string error; ASSERT_TRUE(DeserializeTableFromPb(pb_table, &files, &new_table, &error)); EXPECT_THAT(error, IsEmpty()); BinaryPrimitive* bp = test::GetValueForConfigAndProduct<BinaryPrimitive>( &new_table, "android:bool/boolean_true", ConfigDescription::DefaultConfig(), ""); ASSERT_THAT(bp, NotNull()); EXPECT_THAT(bp->value.dataType, Eq(android::Res_value::TYPE_INT_BOOLEAN)); EXPECT_THAT(bp->value.data, Eq(ResourceUtils::TryParseBool("true")->value.data)); bp = test::GetValueForConfigAndProduct<BinaryPrimitive>(&new_table, "android:bool/boolean_false", ConfigDescription::DefaultConfig(), ""); ASSERT_THAT(bp, NotNull()); EXPECT_THAT(bp->value.dataType, Eq(android::Res_value::TYPE_INT_BOOLEAN)); EXPECT_THAT(bp->value.data, Eq(ResourceUtils::TryParseBool("false")->value.data)); bp = test::GetValueForConfigAndProduct<BinaryPrimitive>(&new_table, "android:color/color_rgb8", ConfigDescription::DefaultConfig(), ""); ASSERT_THAT(bp, NotNull()); EXPECT_THAT(bp->value.dataType, Eq(android::Res_value::TYPE_INT_COLOR_RGB8)); EXPECT_THAT(bp->value.data, Eq(ResourceUtils::TryParseColor("#AABBCC")->value.data)); bp = test::GetValueForConfigAndProduct<BinaryPrimitive>(&new_table, "android:color/color_argb8", ConfigDescription::DefaultConfig(), ""); ASSERT_THAT(bp, NotNull()); EXPECT_THAT(bp->value.dataType, Eq(android::Res_value::TYPE_INT_COLOR_ARGB8)); EXPECT_THAT(bp->value.data, Eq(ResourceUtils::TryParseColor("#11223344")->value.data)); bp = test::GetValueForConfigAndProduct<BinaryPrimitive>(&new_table, "android:color/color_rgb4", ConfigDescription::DefaultConfig(), ""); ASSERT_THAT(bp, NotNull()); EXPECT_THAT(bp->value.dataType, Eq(android::Res_value::TYPE_INT_COLOR_RGB4)); EXPECT_THAT(bp->value.data, Eq(ResourceUtils::TryParseColor("#DEF")->value.data)); bp = test::GetValueForConfigAndProduct<BinaryPrimitive>(&new_table, "android:color/color_argb4", ConfigDescription::DefaultConfig(), ""); ASSERT_THAT(bp, NotNull()); EXPECT_THAT(bp->value.dataType, Eq(android::Res_value::TYPE_INT_COLOR_ARGB4)); EXPECT_THAT(bp->value.data, Eq(ResourceUtils::TryParseColor("#5678")->value.data)); bp = test::GetValueForConfigAndProduct<BinaryPrimitive>(&new_table, "android:integer/integer_444", ConfigDescription::DefaultConfig(), ""); ASSERT_THAT(bp, NotNull()); EXPECT_THAT(bp->value.dataType, Eq(android::Res_value::TYPE_INT_DEC)); EXPECT_THAT(bp->value.data, Eq(ResourceUtils::TryParseInt("444")->value.data)); bp = test::GetValueForConfigAndProduct<BinaryPrimitive>( &new_table, "android:integer/integer_neg_333", ConfigDescription::DefaultConfig(), ""); ASSERT_THAT(bp, NotNull()); EXPECT_THAT(bp->value.dataType, Eq(android::Res_value::TYPE_INT_DEC)); EXPECT_THAT(bp->value.data, Eq(ResourceUtils::TryParseInt("-333")->value.data)); bp = test::GetValueForConfigAndProduct<BinaryPrimitive>( &new_table, "android:integer/hex_int_abcd", ConfigDescription::DefaultConfig(), ""); ASSERT_THAT(bp, NotNull()); EXPECT_THAT(bp->value.dataType, Eq(android::Res_value::TYPE_INT_HEX)); EXPECT_THAT(bp->value.data, Eq(ResourceUtils::TryParseInt("0xABCD")->value.data)); bp = test::GetValueForConfigAndProduct<BinaryPrimitive>(&new_table, "android:dimen/dimen_1.39mm", ConfigDescription::DefaultConfig(), ""); ASSERT_THAT(bp, NotNull()); EXPECT_THAT(bp->value.dataType, Eq(android::Res_value::TYPE_DIMENSION)); EXPECT_THAT(bp->value.data, Eq(ResourceUtils::TryParseFloat("1.39mm")->value.data)); bp = test::GetValueForConfigAndProduct<BinaryPrimitive>( &new_table, "android:fraction/fraction_27", ConfigDescription::DefaultConfig(), ""); ASSERT_THAT(bp, NotNull()); EXPECT_THAT(bp->value.dataType, Eq(android::Res_value::TYPE_FRACTION)); EXPECT_THAT(bp->value.data, Eq(ResourceUtils::TryParseFloat("27%")->value.data)); bp = test::GetValueForConfigAndProduct<BinaryPrimitive>(&new_table, "android:integer/null", ConfigDescription::DefaultConfig(), ""); ASSERT_THAT(bp, NotNull()); EXPECT_THAT(bp->value.dataType, Eq(android::Res_value::TYPE_NULL)); EXPECT_THAT(bp->value.data, Eq(ResourceUtils::MakeEmpty()->value.data)); } static void ExpectConfigSerializes(const StringPiece& config_str) { const ConfigDescription expected_config = test::ParseConfigOrDie(config_str); pb::Configuration pb_config; Loading