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

Commit f0c5ff46 authored by Iurii Makhno's avatar Iurii Makhno
Browse files

Switch ResourceTable to use ResourceNamedType instead of ResourceType.

DD: go/custom-resource-types-in-aapt2

Bug: b/215108200
Test: existing
Change-Id: If9ddcd529dff66c8ec4238f56ab64391c2f44c28
parent aeac0d01
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -273,7 +273,7 @@ void Debug::PrintTable(const ResourceTable& table, const DebugPrintTableOptions&
    printer->Indent();
    for (const auto& type : package.types) {
      printer->Print("type ");
      printer->Print(to_string(type.type));
      printer->Print(type.named_type.to_string());
      if (type.id) {
        printer->Print(StringPrintf(" id=%02x", type.id.value()));
      }
@@ -287,7 +287,7 @@ void Debug::PrintTable(const ResourceTable& table, const DebugPrintTableOptions&
        printer->Print(" ");

        // Write the name without the package (this is obvious and too verbose).
        printer->Print(to_string(type.type));
        printer->Print(type.named_type.to_string());
        printer->Print("/");
        printer->Print(entry.name);

@@ -547,7 +547,7 @@ void Debug::DumpOverlayable(const ResourceTable& table, text::Printer* printer)
          const auto policy_subsection = StringPrintf(R"(policies="%s")",
              android::idmap2::policy::PoliciesToDebugString(overlayable_item.policies).c_str());
          const auto value =
            StringPrintf("%s/%s", to_string(type->type).data(), entry->name.c_str());
              StringPrintf("%s/%s", type->named_type.to_string().data(), entry->name.c_str());
          items.push_back(DumpOverlayableEntry{overlayable_section, policy_subsection, value});
        }
      }
+26 −17
Original line number Diff line number Diff line
@@ -43,8 +43,9 @@ namespace aapt {
const char* Overlayable::kActorScheme = "overlay";

namespace {
bool less_than_type(const std::unique_ptr<ResourceTableType>& lhs, ResourceType rhs) {
  return lhs->type < rhs;
bool less_than_type(const std::unique_ptr<ResourceTableType>& lhs,
                    const ResourceNamedTypeRef& rhs) {
  return lhs->named_type < rhs;
}

template <typename T>
@@ -115,18 +116,24 @@ ResourceTablePackage* ResourceTable::FindOrCreatePackage(const android::StringPi
}

template <typename Func, typename Elements>
static ResourceTableType* FindTypeRunAction(ResourceType type, Elements& entries, Func action) {
static ResourceTableType* FindTypeRunAction(const ResourceNamedTypeRef& type, Elements& entries,
                                            Func action) {
  const auto iter = std::lower_bound(entries.begin(), entries.end(), type, less_than_type);
  const bool found = iter != entries.end() && type == (*iter)->type;
  const bool found = iter != entries.end() && type == (*iter)->named_type;
  return action(found, iter);
}

ResourceTableType* ResourceTablePackage::FindType(ResourceType type) const {
ResourceTableType* ResourceTablePackage::FindTypeWithDefaultName(const ResourceType type) const {
  auto named_type = ResourceNamedTypeWithDefaultName(type);
  return FindType(named_type);
}

ResourceTableType* ResourceTablePackage::FindType(const ResourceNamedTypeRef& type) const {
  return FindTypeRunAction(type, types,
                           [&](bool found, auto& iter) { return found ? iter->get() : nullptr; });
}

ResourceTableType* ResourceTablePackage::FindOrCreateType(ResourceType type) {
ResourceTableType* ResourceTablePackage::FindOrCreateType(const ResourceNamedTypeRef& type) {
  return FindTypeRunAction(type, types, [&](bool found, auto& iter) {
    return found ? iter->get() : types.emplace(iter, new ResourceTableType(type))->get();
  });
@@ -329,7 +336,7 @@ struct PackageViewComparer {

struct TypeViewComparer {
  bool operator()(const ResourceTableTypeView& lhs, const ResourceTableTypeView& rhs) {
    return lhs.id != rhs.id ? lhs.id < rhs.id : lhs.type < rhs.type;
    return lhs.id != rhs.id ? lhs.id < rhs.id : lhs.named_type < rhs.named_type;
  }
};

@@ -355,7 +362,8 @@ void InsertEntryIntoTableView(ResourceTableView& table, const ResourceTablePacka
                                       id ? id.value().package_id() : std::optional<uint8_t>{}};
  auto view_package = package_inserter.Insert(table.packages, std::move(new_package));

  ResourceTableTypeView new_type{type->type, id ? id.value().type_id() : std::optional<uint8_t>{}};
  ResourceTableTypeView new_type{type->named_type,
                                 id ? id.value().type_id() : std::optional<uint8_t>{}};
  auto view_type = type_inserter.Insert(view_package->types, std::move(new_type));

  if (visibility.level == Visibility::Level::kPublic) {
@@ -420,13 +428,14 @@ ResourceTableView ResourceTable::GetPartitionedView(const ResourceTableViewOptio
    // we can reuse those packages for other types that need to be extracted from this package.
    // `start_index` is the index of the first newly created package that can be reused.
    const size_t start_index = new_packages.size();
    std::map<ResourceType, size_t> type_new_package_index;
    std::map<ResourceNamedType, size_t> type_new_package_index;
    for (auto type_it = package.types.begin(); type_it != package.types.end();) {
      auto& type = *type_it;
      auto type_index_iter = type_new_package_index.find(type.type);
      auto type_index_iter = type_new_package_index.find(type.named_type);
      if (type_index_iter == type_new_package_index.end()) {
        // First occurrence of the resource type in this package. Keep it in this package.
        type_new_package_index.insert(type_index_iter, std::make_pair(type.type, start_index));
        type_new_package_index.insert(type_index_iter,
                                      std::make_pair(type.named_type, start_index));
        ++type_it;
        continue;
      }
@@ -440,7 +449,7 @@ ResourceTableView ResourceTable::GetPartitionedView(const ResourceTableViewOptio

      // Move the type into a new package
      auto& other_package = new_packages[index];
      type_new_package_index[type.type] = index + 1;
      type_new_package_index[type.named_type] = index + 1;
      type_inserter.Insert(other_package.types, std::move(type));
      type_it = package.types.erase(type_it);
    }
@@ -473,7 +482,7 @@ bool ResourceTable::AddResource(NewResource&& res, IDiagnostics* diag) {
  }

  auto package = FindOrCreatePackage(res.name.package);
  auto type = package->FindOrCreateType(res.name.type.type);
  auto type = package->FindOrCreateType(res.name.type);
  auto entry_it = std::equal_range(type->entries.begin(), type->entries.end(), res.name.entry,
                                   NameEqualRange<ResourceEntry>{});
  const size_t entry_count = std::distance(entry_it.first, entry_it.second);
@@ -593,7 +602,7 @@ std::optional<ResourceTable::SearchResult> ResourceTable::FindResource(
    return {};
  }

  ResourceTableType* type = package->FindType(name.type.type);
  ResourceTableType* type = package->FindType(name.type);
  if (type == nullptr) {
    return {};
  }
@@ -612,7 +621,7 @@ std::optional<ResourceTable::SearchResult> ResourceTable::FindResource(const Res
    return {};
  }

  ResourceTableType* type = package->FindType(name.type.type);
  ResourceTableType* type = package->FindType(name.type);
  if (type == nullptr) {
    return {};
  }
@@ -633,7 +642,7 @@ bool ResourceTable::RemoveResource(const ResourceNameRef& name, ResourceId id) c
    return {};
  }

  ResourceTableType* type = package->FindType(name.type.type);
  ResourceTableType* type = package->FindType(name.type);
  if (type == nullptr) {
    return {};
  }
@@ -655,7 +664,7 @@ std::unique_ptr<ResourceTable> ResourceTable::Clone() const {
  for (const auto& pkg : packages) {
    ResourceTablePackage* new_pkg = new_table->FindOrCreatePackage(pkg->name);
    for (const auto& type : pkg->types) {
      ResourceTableType* new_type = new_pkg->FindOrCreateType(type->type);
      ResourceTableType* new_type = new_pkg->FindOrCreateType(type->named_type);
      new_type->visibility_level = type->visibility_level;

      for (const auto& entry : type->entries) {
+8 −5
Original line number Diff line number Diff line
@@ -168,7 +168,7 @@ class ResourceEntry {
class ResourceTableType {
 public:
  // The logical type of resource (string, drawable, layout, etc.).
  const ResourceType type;
  const ResourceNamedType named_type;

  // Whether this type is public (and must maintain the same type ID across builds).
  Visibility::Level visibility_level = Visibility::Level::kUndefined;
@@ -176,7 +176,9 @@ class ResourceTableType {
  // List of resources for this type.
  std::vector<std::unique_ptr<ResourceEntry>> entries;

  explicit ResourceTableType(const ResourceType type) : type(type) {}
  explicit ResourceTableType(const ResourceNamedTypeRef& type)
      : named_type(type.ToResourceNamedType()) {
  }

  ResourceEntry* CreateEntry(const android::StringPiece& name);
  ResourceEntry* FindEntry(const android::StringPiece& name) const;
@@ -196,8 +198,9 @@ class ResourceTablePackage {
  }

  ResourceTablePackage() = default;
  ResourceTableType* FindType(ResourceType type) const;
  ResourceTableType* FindOrCreateType(ResourceType type);
  ResourceTableType* FindTypeWithDefaultName(const ResourceType type) const;
  ResourceTableType* FindType(const ResourceNamedTypeRef& type) const;
  ResourceTableType* FindOrCreateType(const ResourceNamedTypeRef& type);

 private:
  DISALLOW_COPY_AND_ASSIGN(ResourceTablePackage);
@@ -217,7 +220,7 @@ struct ResourceTableEntryView {
};

struct ResourceTableTypeView {
  ResourceType type;
  ResourceNamedType named_type;
  std::optional<uint8_t> id;
  Visibility::Level visibility_level = Visibility::Level::kUndefined;

+2 −2
Original line number Diff line number Diff line
@@ -243,9 +243,9 @@ static bool CompileTable(IAaptContext* context, const CompileOptions& options,
                r_txt_printer.Print("private ");
            }

            if (type->type != ResourceType::kStyleable) {
            if (type->named_type.type != ResourceType::kStyleable) {
              r_txt_printer.Print("int ");
              r_txt_printer.Print(to_string(type->type));
              r_txt_printer.Print(type->named_type.to_string());
              r_txt_printer.Print(" ");
              r_txt_printer.Println(entry->name);
            } else {
+13 −11
Original line number Diff line number Diff line
@@ -105,7 +105,7 @@ static bool EmitResourceConfigValueDiff(
  Value* value_b = config_value_b->value.get();
  if (!value_a->Equals(value_b)) {
    std::stringstream str_stream;
    str_stream << "value " << pkg_a.name << ":" << type_a.type << "/" << entry_a.name
    str_stream << "value " << pkg_a.name << ":" << type_a.named_type << "/" << entry_a.name
               << " config=" << config_value_a->config << " does not match:\n";
    value_a->Print(&str_stream);
    str_stream << "\n vs \n";
@@ -128,7 +128,7 @@ static bool EmitResourceEntryDiff(IAaptContext* context, LoadedApk* apk_a,
    auto config_value_b = entry_b.FindValue(config_value_a->config);
    if (!config_value_b) {
      std::stringstream str_stream;
      str_stream << "missing " << pkg_a.name << ":" << type_a.type << "/" << entry_a.name
      str_stream << "missing " << pkg_a.name << ":" << type_a.named_type << "/" << entry_a.name
                 << " config=" << config_value_a->config;
      EmitDiffLine(apk_b->GetSource(), str_stream.str());
      diff = true;
@@ -143,7 +143,7 @@ static bool EmitResourceEntryDiff(IAaptContext* context, LoadedApk* apk_a,
    auto config_value_a = entry_a.FindValue(config_value_b->config);
    if (!config_value_a) {
      std::stringstream str_stream;
      str_stream << "new config " << pkg_b.name << ":" << type_b.type << "/" << entry_b.name
      str_stream << "new config " << pkg_b.name << ":" << type_b.named_type << "/" << entry_b.name
                 << " config=" << config_value_b->config;
      EmitDiffLine(apk_b->GetSource(), str_stream.str());
      diff = true;
@@ -164,13 +164,15 @@ static bool EmitResourceTypeDiff(IAaptContext* context, LoadedApk* apk_a,
    if (entry_b_iter == type_b.entries.end()) {
      // Type A contains a type that type B does not have.
      std::stringstream str_stream;
      str_stream << "missing " << pkg_a.name << ":" << type_a.type << "/" << entry_a_iter->name;
      str_stream << "missing " << pkg_a.name << ":" << type_a.named_type << "/"
                 << entry_a_iter->name;
      EmitDiffLine(apk_a->GetSource(), str_stream.str());
      diff = true;
    } else if (entry_a_iter == type_a.entries.end()) {
      // Type B contains a type that type A does not have.
      std::stringstream str_stream;
      str_stream << "new entry " << pkg_b.name << ":" << type_b.type << "/" << entry_b_iter->name;
      str_stream << "new entry " << pkg_b.name << ":" << type_b.named_type << "/"
                 << entry_b_iter->name;
      EmitDiffLine(apk_b->GetSource(), str_stream.str());
      diff = true;
    } else {
@@ -178,7 +180,7 @@ static bool EmitResourceTypeDiff(IAaptContext* context, LoadedApk* apk_a,
      const auto& entry_b = *entry_b_iter;
      if (IsSymbolVisibilityDifferent(entry_a.visibility, entry_b.visibility)) {
        std::stringstream str_stream;
        str_stream << pkg_a.name << ":" << type_a.type << "/" << entry_a.name
        str_stream << pkg_a.name << ":" << type_a.named_type << "/" << entry_a.name
                   << " has different visibility (";
        if (entry_b.visibility.staged_api) {
          str_stream << "STAGED ";
@@ -203,7 +205,7 @@ static bool EmitResourceTypeDiff(IAaptContext* context, LoadedApk* apk_a,
      } else if (IsIdDiff(entry_a.visibility.level, entry_a.id, entry_b.visibility.level,
                          entry_b.id)) {
        std::stringstream str_stream;
        str_stream << pkg_a.name << ":" << type_a.type << "/" << entry_a.name
        str_stream << pkg_a.name << ":" << type_a.named_type << "/" << entry_a.name
                   << " has different public ID (";
        if (entry_b.id) {
          str_stream << "0x" << std::hex << entry_b.id.value();
@@ -243,13 +245,13 @@ static bool EmitResourcePackageDiff(IAaptContext* context, LoadedApk* apk_a,
    if (type_b_iter == pkg_b.types.end()) {
      // Type A contains a type that type B does not have.
      std::stringstream str_stream;
      str_stream << "missing " << pkg_a.name << ":" << type_a_iter->type;
      str_stream << "missing " << pkg_a.name << ":" << type_a_iter->named_type;
      EmitDiffLine(apk_a->GetSource(), str_stream.str());
      diff = true;
    } else if (type_a_iter == pkg_a.types.end()) {
      // Type B contains a type that type A does not have.
      std::stringstream str_stream;
      str_stream << "new type " << pkg_b.name << ":" << type_b_iter->type;
      str_stream << "new type " << pkg_b.name << ":" << type_b_iter->named_type;
      EmitDiffLine(apk_b->GetSource(), str_stream.str());
      diff = true;
    } else {
@@ -257,7 +259,7 @@ static bool EmitResourcePackageDiff(IAaptContext* context, LoadedApk* apk_a,
      const auto& type_b = *type_b_iter;
      if (type_a.visibility_level != type_b.visibility_level) {
        std::stringstream str_stream;
        str_stream << pkg_a.name << ":" << type_a.type << " has different visibility (";
        str_stream << pkg_a.name << ":" << type_a.named_type << " has different visibility (";
        if (type_b.visibility_level == Visibility::Level::kPublic) {
          str_stream << "PUBLIC";
        } else {
@@ -274,7 +276,7 @@ static bool EmitResourcePackageDiff(IAaptContext* context, LoadedApk* apk_a,
        diff = true;
      } else if (IsIdDiff(type_a.visibility_level, type_a.id, type_b.visibility_level, type_b.id)) {
        std::stringstream str_stream;
        str_stream << pkg_a.name << ":" << type_a.type << " has different public ID (";
        str_stream << pkg_a.name << ":" << type_a.named_type << " has different public ID (";
        if (type_b.id) {
          str_stream << "0x" << std::hex << type_b.id.value();
        } else {
Loading