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

Commit e6d547f7 authored by Ryan Mitchell's avatar Ryan Mitchell Committed by Android (Google) Code Review
Browse files

Merge "AAPT2: Fix resource table load time regression"

parents a04bd3d2 8d4ee973
Loading
Loading
Loading
Loading
+5 −5
Original line number Original line Diff line number Diff line
@@ -51,7 +51,7 @@ static bool less_than_struct_with_name(const std::unique_ptr<T>& lhs, const Stri


template <typename T>
template <typename T>
static bool less_than_struct_with_name_and_id(const std::unique_ptr<T>& lhs,
static bool less_than_struct_with_name_and_id(const std::unique_ptr<T>& lhs,
                                              const std::pair<StringPiece, Maybe<uint8_t>>& rhs) {
                                              const std::pair<StringPiece, Maybe<uint16_t>>& rhs) {
  int name_cmp = lhs->name.compare(0, lhs->name.size(), rhs.first.data(), rhs.first.size());
  int name_cmp = lhs->name.compare(0, lhs->name.size(), rhs.first.data(), rhs.first.size());
  return name_cmp < 0 || (name_cmp == 0 && rhs.second && lhs->id < rhs.second);
  return name_cmp < 0 || (name_cmp == 0 && rhs.second && lhs->id < rhs.second);
}
}
@@ -141,7 +141,7 @@ ResourceTableType* ResourceTablePackage::FindOrCreateType(ResourceType type,
  return types.emplace(iter, std::move(new_type))->get();
  return types.emplace(iter, std::move(new_type))->get();
}
}


ResourceEntry* ResourceTableType::FindEntry(const StringPiece& name, const Maybe<uint8_t> id) {
ResourceEntry* ResourceTableType::FindEntry(const StringPiece& name, const Maybe<uint16_t> id) {
  const auto last = entries.end();
  const auto last = entries.end();
  auto iter = std::lower_bound(entries.begin(), last, std::make_pair(name, id),
  auto iter = std::lower_bound(entries.begin(), last, std::make_pair(name, id),
      less_than_struct_with_name_and_id<ResourceEntry>);
      less_than_struct_with_name_and_id<ResourceEntry>);
@@ -152,7 +152,7 @@ ResourceEntry* ResourceTableType::FindEntry(const StringPiece& name, const Maybe
}
}


ResourceEntry* ResourceTableType::FindOrCreateEntry(const StringPiece& name,
ResourceEntry* ResourceTableType::FindOrCreateEntry(const StringPiece& name,
                                                    const Maybe<uint8_t> id) {
                                                    const Maybe<uint16_t > id) {
  auto last = entries.end();
  auto last = entries.end();
  auto iter = std::lower_bound(entries.begin(), last, std::make_pair(name, id),
  auto iter = std::lower_bound(entries.begin(), last, std::make_pair(name, id),
                               less_than_struct_with_name_and_id<ResourceEntry>);
                               less_than_struct_with_name_and_id<ResourceEntry>);
@@ -450,7 +450,7 @@ bool ResourceTable::AddResourceImpl(const ResourceNameRef& name, const ResourceI
  }
  }


  ResourceEntry* entry = type->FindOrCreateEntry(name.entry, use_id ? res_id.entry_id()
  ResourceEntry* entry = type->FindOrCreateEntry(name.entry, use_id ? res_id.entry_id()
                                                                    : Maybe<uint8_t>());
                                                                    : Maybe<uint16_t>());


  // Check for entries appearing twice with two different entry ids
  // Check for entries appearing twice with two different entry ids
  if (check_id && entry->id && entry->id.value() != res_id.entry_id()) {
  if (check_id && entry->id && entry->id.value() != res_id.entry_id()) {
@@ -561,7 +561,7 @@ bool ResourceTable::SetVisibilityImpl(const ResourceNameRef& name, const Visibil
  }
  }


  ResourceEntry* entry = type->FindOrCreateEntry(name.entry, use_id ? res_id.entry_id()
  ResourceEntry* entry = type->FindOrCreateEntry(name.entry, use_id ? res_id.entry_id()
                                                                    : Maybe<uint8_t>());
                                                                    : Maybe<uint16_t>());


  // Check for entries appearing twice with two different entry ids
  // Check for entries appearing twice with two different entry ids
  if (check_id && entry->id && entry->id.value() != res_id.entry_id()) {
  if (check_id && entry->id && entry->id.value() != res_id.entry_id()) {
+3 −2
Original line number Original line Diff line number Diff line
@@ -146,9 +146,10 @@ class ResourceTableType {


  explicit ResourceTableType(const ResourceType type) : type(type) {}
  explicit ResourceTableType(const ResourceType type) : type(type) {}


  ResourceEntry* FindEntry(const android::StringPiece& name, Maybe<uint8_t> id = Maybe<uint8_t>());
  ResourceEntry* FindEntry(const android::StringPiece& name,
                           Maybe<uint16_t> id = Maybe<uint16_t>());
  ResourceEntry* FindOrCreateEntry(const android::StringPiece& name,
  ResourceEntry* FindOrCreateEntry(const android::StringPiece& name,
                                   Maybe<uint8_t> id = Maybe<uint8_t>());
                                   Maybe<uint16_t> id = Maybe<uint16_t>());


 private:
 private:
  DISALLOW_COPY_AND_ASSIGN(ResourceTableType);
  DISALLOW_COPY_AND_ASSIGN(ResourceTableType);
+40 −0
Original line number Original line Diff line number Diff line
@@ -258,4 +258,44 @@ TEST(ResourceTableTest, SetOverlayable) {
  ASSERT_FALSE(table.SetOverlayable(name, overlayable, test::GetDiagnostics()));
  ASSERT_FALSE(table.SetOverlayable(name, overlayable, test::GetDiagnostics()));
}
}


TEST(ResourceTableTest, AllowDuplictaeResourcesNames) {
  ResourceTable table(/* validate_resources */ false);

  const ResourceName foo_name = test::ParseNameOrDie("android:bool/foo");
  ASSERT_TRUE(table.AddResourceWithId(foo_name, ResourceId(0x7f0100ff), ConfigDescription{} , "",
                                      test::BuildPrimitive(android::Res_value::TYPE_INT_BOOLEAN, 0),
                                      test::GetDiagnostics()));
  ASSERT_TRUE(table.AddResourceWithId(foo_name, ResourceId(0x7f010100), ConfigDescription{} , "",
                                      test::BuildPrimitive(android::Res_value::TYPE_INT_BOOLEAN, 1),
                                      test::GetDiagnostics()));

  ASSERT_TRUE(table.SetVisibilityWithId(foo_name, Visibility{Visibility::Level::kPublic},
                                        ResourceId(0x7f0100ff), test::GetDiagnostics()));
  ASSERT_TRUE(table.SetVisibilityWithId(foo_name, Visibility{Visibility::Level::kPrivate},
                                        ResourceId(0x7f010100), test::GetDiagnostics()));

  auto package = table.FindPackageById(0x7f);
  ASSERT_THAT(package, NotNull());
  auto type = package->FindType(ResourceType::kBool);
  ASSERT_THAT(type, NotNull());

  auto entry1 = type->FindEntry("foo", 0x00ff);
  ASSERT_THAT(entry1, NotNull());
  ASSERT_THAT(entry1->id, Eq(0x00ff));
  ASSERT_THAT(entry1->values[0], NotNull());
  ASSERT_THAT(entry1->values[0]->value, NotNull());
  ASSERT_THAT(ValueCast<BinaryPrimitive>(entry1->values[0]->value.get()), NotNull());
  ASSERT_THAT(ValueCast<BinaryPrimitive>(entry1->values[0]->value.get())->value.data, Eq(0u));
  ASSERT_THAT(entry1->visibility.level, Visibility::Level::kPublic);

  auto entry2 = type->FindEntry("foo", 0x0100);
  ASSERT_THAT(entry2, NotNull());
  ASSERT_THAT(entry2->id, Eq(0x0100));
  ASSERT_THAT(entry2->values[0], NotNull());
  ASSERT_THAT(entry1->values[0]->value, NotNull());
  ASSERT_THAT(ValueCast<BinaryPrimitive>(entry2->values[0]->value.get()), NotNull());
  ASSERT_THAT(ValueCast<BinaryPrimitive>(entry2->values[0]->value.get())->value.data, Eq(1u));
  ASSERT_THAT(entry2->visibility.level, Visibility::Level::kPrivate);
}

}  // namespace aapt
}  // namespace aapt