Merge "Fix serializing dynamic references to proto"

This commit is contained in:
Clark Duvall
2020-01-13 23:10:50 +00:00
committed by Android (Google) Code Review
6 changed files with 69 additions and 1 deletions

View File

@@ -800,7 +800,12 @@ std::unique_ptr<Item> ParseBinaryResValue(const ResourceType& type, const Config
}
// This is a normal reference.
return util::make_unique<Reference>(data, ref_type);
auto reference = util::make_unique<Reference>(data, ref_type);
if (res_value.dataType == android::Res_value::TYPE_DYNAMIC_REFERENCE ||
res_value.dataType == android::Res_value::TYPE_DYNAMIC_ATTRIBUTE) {
reference->is_dynamic = true;
}
return reference;
} break;
}

View File

@@ -109,6 +109,20 @@ TEST(ResourceUtilsTest, ParsePrivateReference) {
EXPECT_TRUE(private_ref);
}
TEST(ResourceUtilsTest, ParseBinaryDynamicReference) {
android::Res_value value = {};
value.data = util::HostToDevice32(0x01);
value.dataType = android::Res_value::TYPE_DYNAMIC_REFERENCE;
std::unique_ptr<Item> item = ResourceUtils::ParseBinaryResValue(ResourceType::kId,
android::ConfigDescription(),
android::ResStringPool(), value,
nullptr);
Reference* ref = ValueCast<Reference>(item.get());
EXPECT_TRUE(ref->is_dynamic);
EXPECT_EQ(ref->id.value().id, 0x01);
}
TEST(ResourceUtilsTest, FailToParseAutoCreateNonIdReference) {
bool create = false;
bool private_ref = false;

View File

@@ -269,6 +269,11 @@ message CompoundValue {
}
}
// Message holding a boolean, so it can be optionally encoded.
message Boolean {
bool value = 1;
}
// A value that is a reference to another resource. This reference can be by name or resource ID.
message Reference {
enum Type {
@@ -289,6 +294,9 @@ message Reference {
// Whether this reference is referencing a private resource (@*package:type/entry).
bool private = 4;
// Whether this reference is dynamic.
Boolean is_dynamic = 5;
}
// A value that represents an ID. This is just a placeholder, as ID values are used to occupy a

View File

@@ -634,6 +634,7 @@ static bool DeserializeReferenceFromPb(const pb::Reference& pb_ref, Reference* o
std::string* out_error) {
out_ref->reference_type = DeserializeReferenceTypeFromPb(pb_ref.type());
out_ref->private_reference = pb_ref.private_();
out_ref->is_dynamic = pb_ref.is_dynamic().value();
if (pb_ref.id() != 0) {
out_ref->id = ResourceId(pb_ref.id());

View File

@@ -418,6 +418,9 @@ static void SerializeReferenceToPb(const Reference& ref, pb::Reference* pb_ref)
pb_ref->set_private_(ref.private_reference);
pb_ref->set_type(SerializeReferenceTypeToPb(ref.reference_type));
if (ref.is_dynamic) {
pb_ref->mutable_is_dynamic()->set_value(ref.is_dynamic);
}
}
template <typename T>

View File

@@ -608,4 +608,41 @@ TEST(ProtoSerializeTest, SerializeAndDeserializeOverlayable) {
ASSERT_FALSE(search_result.value().entry->overlayable_item);
}
TEST(ProtoSerializeTest, SerializeAndDeserializeDynamicReference) {
Reference ref(ResourceId(0x00010001));
ref.is_dynamic = true;
pb::Item pb_item;
SerializeItemToPb(ref, &pb_item);
ASSERT_TRUE(pb_item.has_ref());
EXPECT_EQ(pb_item.ref().id(), ref.id.value().id);
EXPECT_TRUE(pb_item.ref().is_dynamic().value());
std::unique_ptr<Item> item = DeserializeItemFromPb(pb_item, android::ResStringPool(),
android::ConfigDescription(), nullptr,
nullptr, nullptr);
Reference* actual_ref = ValueCast<Reference>(item.get());
EXPECT_EQ(actual_ref->id.value().id, ref.id.value().id);
EXPECT_TRUE(actual_ref->is_dynamic);
}
TEST(ProtoSerializeTest, SerializeAndDeserializeNonDynamicReference) {
Reference ref(ResourceId(0x00010001));
pb::Item pb_item;
SerializeItemToPb(ref, &pb_item);
ASSERT_TRUE(pb_item.has_ref());
EXPECT_EQ(pb_item.ref().id(), ref.id.value().id);
EXPECT_FALSE(pb_item.ref().has_is_dynamic());
std::unique_ptr<Item> item = DeserializeItemFromPb(pb_item, android::ResStringPool(),
android::ConfigDescription(), nullptr,
nullptr, nullptr);
Reference* actual_ref = ValueCast<Reference>(item.get());
EXPECT_EQ(actual_ref->id.value().id, ref.id.value().id);
EXPECT_FALSE(actual_ref->is_dynamic);
}
} // namespace aapt