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

Commit 0181038d authored by Iurii Makhno's avatar Iurii Makhno Committed by Android (Google) Code Review
Browse files

Merge changes I9e8a7f94,Ieed256e4,If9ddcd52,I7d16ca83

* changes:
  Support custom resource types in proto/binary formats.
  Use dot instead of colon as separator of custom part.
  Switch ResourceTable to use ResourceNamedType instead of ResourceType.
  Refactor a couple of places to ensure ResourceNamedTypeRef is valid when used.
parents dc9235a1 ce8fc148
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});
        }
      }
+3 −3
Original line number Diff line number Diff line
@@ -139,10 +139,10 @@ ResourceNamedTypeRef ResourceNamedTypeWithDefaultName(ResourceType t) {
}

std::optional<ResourceNamedTypeRef> ParseResourceNamedType(const android::StringPiece& s) {
  auto colon = std::find(s.begin(), s.end(), ':');
  auto dot = std::find(s.begin(), s.end(), '.');
  const ResourceType* parsedType;
  if (colon != s.end() && colon != std::prev(s.end())) {
    parsedType = ParseResourceType(s.substr(s.begin(), colon));
  if (dot != s.end() && dot != std::prev(s.end())) {
    parsedType = ParseResourceType(s.substr(s.begin(), dot));
  } else {
    parsedType = ParseResourceType(s);
  }
+5 −3
Original line number Diff line number Diff line
@@ -981,12 +981,14 @@ bool static ParseGroupImpl(xml::XmlPullParser* parser, ParsedResource* out_resou
    return false;
  }

  std::optional<ResourceNamedTypeRef> parsed_type = ParseResourceNamedType(maybe_type.value());
  if (!parsed_type) {
  std::optional<ResourceNamedTypeRef> maybe_parsed_type =
      ParseResourceNamedType(maybe_type.value());
  if (!maybe_parsed_type) {
    diag->Error(DiagMessage(out_resource->source)
                << "invalid resource type '" << maybe_type.value() << "' in <" << tag_name << ">");
    return false;
  }
  auto parsed_type = maybe_parsed_type->ToResourceNamedType();

  std::optional<StringPiece> maybe_id_str = xml::FindNonEmptyAttribute(parser, "first-id");
  if (!maybe_id_str) {
@@ -1039,7 +1041,7 @@ bool static ParseGroupImpl(xml::XmlPullParser* parser, ParsedResource* out_resou
      }

      ParsedResource& entry_res = out_resource->child_resources.emplace_back(ParsedResource{
          .name = ResourceName{{}, *parsed_type, maybe_name.value().to_string()},
          .name = ResourceName{{}, parsed_type, maybe_name.value().to_string()},
          .source = item_source,
          .comment = std::move(comment),
      });
+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;

Loading