Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e9fedbe2 authored by Clark DuVall's avatar Clark DuVall
Browse files

Fix serializing dynamic references to proto

The is_dynamic bit on references was getting lost when converting to
proto and back. This was preventing bundles from being used as shared
libraries, since layout inflation would fail when it hit a dynamic
reference.

Bug: 146491000
Test: Build a shared library with a layout that has a dynamic reference,
      and attempt to inflate that layout.

Change-Id: Ia0e615670d2ac52f9266e3eec8813af7687d3323
parent 3df3e3b0
Loading
Loading
Loading
Loading
+6 −1
Original line number Diff line number Diff line
@@ -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;
  }

+14 −0
Original line number Diff line number Diff line
@@ -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;
+8 −0
Original line number Diff line number Diff line
@@ -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
+1 −0
Original line number Diff line number Diff line
@@ -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());
+3 −0
Original line number Diff line number Diff line
@@ -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>
Loading