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

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

Support custom resource types in proto/binary formats.

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

Bug: b/215108200
Test: TableFlattener_test, ProtoSerialize_test
Change-Id: I9e8a7f946df3899eabeb2f82d5fa4f1df692f8b6
parent 9d4a4d60
Loading
Loading
Loading
Loading
+7 −7
Original line number Diff line number Diff line
@@ -18,19 +18,19 @@

#include <algorithm>
#include <map>
#include <optional>
#include <string>

#include "android-base/logging.h"
#include "android-base/macros.h"
#include "android-base/stringprintf.h"
#include "androidfw/ResourceTypes.h"
#include "androidfw/TypeWrappers.h"

#include "ResourceTable.h"
#include "ResourceUtils.h"
#include "ResourceValues.h"
#include "Source.h"
#include "ValueVisitor.h"
#include "android-base/logging.h"
#include "android-base/macros.h"
#include "android-base/stringprintf.h"
#include "androidfw/ResourceTypes.h"
#include "androidfw/TypeWrappers.h"
#include "format/binary/ResChunkPullParser.h"
#include "util/Util.h"

@@ -364,7 +364,7 @@ bool BinaryResourceParser::ParseType(const ResourceTablePackage* package,
  config.copyFromDtoH(type->config);

  const std::string type_str = util::GetString(type_pool_, type->id - 1);
  const ResourceType* parsed_type = ParseResourceType(type_str);
  std::optional<ResourceNamedTypeRef> parsed_type = ParseResourceNamedType(type_str);
  if (!parsed_type) {
    diag_->Warn(DiagMessage(source_)
                << "invalid type name '" << type_str << "' for type with ID " << type->id);
+1 −1
Original line number Diff line number Diff line
@@ -607,7 +607,7 @@ class PackageFlattener {
        expected_type_id++;
      }
      expected_type_id++;
      type_pool_.MakeRef(to_string(type.named_type.type));
      type_pool_.MakeRef(type.named_type.to_string());

      if (!FlattenTypeSpec(type, type.entries, buffer)) {
        return false;
+41 −0
Original line number Diff line number Diff line
@@ -837,4 +837,45 @@ TEST_F(TableFlattenerTest, FlattenOverlayableNoPolicyFails) {
  ASSERT_FALSE(Flatten(context_.get(), {}, table.get(), &output_table));
}

TEST_F(TableFlattenerTest, FlattenCustomResourceTypes) {
  std::unique_ptr<ResourceTable> table =
      test::ResourceTableBuilder()
          .AddSimple("com.app.test:id/one", ResourceId(0x7f010000))
          .AddSimple("com.app.test:id.2/two", ResourceId(0x7f020000))
          .AddValue("com.app.test:integer/one", ResourceId(0x7f030000),
                    util::make_unique<BinaryPrimitive>(uint8_t(Res_value::TYPE_INT_DEC), 10u))
          .AddValue("com.app.test:integer.1/one", ResourceId(0x7f040000),
                    util::make_unique<BinaryPrimitive>(uint8_t(Res_value::TYPE_INT_DEC), 1u))
          .AddValue("com.app.test:integer.1/one", test::ParseConfigOrDie("v1"),
                    ResourceId(0x7f040000),
                    util::make_unique<BinaryPrimitive>(uint8_t(Res_value::TYPE_INT_DEC), 2u))
          .AddString("com.app.test:layout.custom/bar", ResourceId(0x7f050000), "res/layout/bar.xml")
          .Build();

  ResTable res_table;
  ASSERT_TRUE(Flatten(context_.get(), {}, table.get(), &res_table));

  EXPECT_TRUE(Exists(&res_table, "com.app.test:id/one", ResourceId(0x7f010000), {},
                     Res_value::TYPE_INT_BOOLEAN, 0u, 0u));

  EXPECT_TRUE(Exists(&res_table, "com.app.test:id.2/two", ResourceId(0x7f020000), {},
                     Res_value::TYPE_INT_BOOLEAN, 0u, 0u));

  EXPECT_TRUE(Exists(&res_table, "com.app.test:integer/one", ResourceId(0x7f030000), {},
                     Res_value::TYPE_INT_DEC, 10u, 0u));

  EXPECT_TRUE(Exists(&res_table, "com.app.test:integer.1/one", ResourceId(0x7f040000), {},
                     Res_value::TYPE_INT_DEC, 1u, ResTable_config::CONFIG_VERSION));

  EXPECT_TRUE(Exists(&res_table, "com.app.test:integer.1/one", ResourceId(0x7f040000),
                     test::ParseConfigOrDie("v1"), Res_value::TYPE_INT_DEC, 2u,
                     ResTable_config::CONFIG_VERSION));

  std::u16string bar_path = u"res/layout/bar.xml";
  auto idx = res_table.getTableStringBlock(0)->indexOfString(bar_path.data(), bar_path.size());
  ASSERT_TRUE(idx.has_value());
  EXPECT_TRUE(Exists(&res_table, "com.app.test:layout.custom/bar", ResourceId(0x7f050000), {},
                     Res_value::TYPE_STRING, (uint32_t)*idx, 0u));
}

}  // namespace aapt
+3 −4
Original line number Diff line number Diff line
@@ -429,16 +429,15 @@ static bool DeserializePackageFromPb(const pb::Package& pb_package, const ResStr

  ResourceTablePackage* pkg = out_table->FindOrCreatePackage(pb_package.package_name());
  for (const pb::Type& pb_type : pb_package.type()) {
    const ResourceType* res_type = ParseResourceType(pb_type.name());
    if (res_type == nullptr) {
    auto res_type = ParseResourceNamedType(pb_type.name());
    if (!res_type) {
      std::ostringstream error;
      error << "unknown type '" << pb_type.name() << "'";
      *out_error = error.str();
      return false;
    }

    auto named_type = ResourceNamedTypeWithDefaultName(*res_type);
    ResourceTableType* type = pkg->FindOrCreateType(named_type);
    ResourceTableType* type = pkg->FindOrCreateType(*res_type);

    for (const pb::Entry& pb_entry : pb_type.entry()) {
      ResourceEntry* entry = type->CreateEntry(pb_entry.name());
+1 −1
Original line number Diff line number Diff line
@@ -358,7 +358,7 @@ void SerializeTableToPb(const ResourceTable& table, pb::ResourceTable* out_table
      if (type.id) {
        pb_type->mutable_type_id()->set_id(type.id.value());
      }
      pb_type->set_name(to_string(type.named_type.type).to_string());
      pb_type->set_name(type.named_type.to_string());

      // hardcoded string uses characters which make it an invalid resource name
      static const char* obfuscated_resource_name = "0_resource_name_obfuscated";
Loading