From e59f0d80ec19249f72c07ae191ad673d040443e3 Mon Sep 17 00:00:00 2001 From: Adam Lesinski Date: Fri, 13 Oct 2017 09:36:53 -0700 Subject: [PATCH] AAPT2: Enable building proto artifacts - This will allow the bundle tool to ingest the outputs of the aapt2 link phase. Bug: 64143208 Test: manual Change-Id: I1a4b3ce5c2ffbbdc4bc642c3371a9ef2e7e9ad71 --- tools/aapt2/Debug.cpp | 34 ++--- tools/aapt2/Debug.h | 6 +- tools/aapt2/ResourceUtils.cpp | 11 +- tools/aapt2/Resources.proto | 11 ++ tools/aapt2/ResourcesInternal.proto | 13 +- tools/aapt2/cmd/Dump.cpp | 12 +- tools/aapt2/cmd/Link.cpp | 142 +++++++++++------- tools/aapt2/format/Container_test.cpp | 2 +- tools/aapt2/format/binary/XmlFlattener.cpp | 21 +-- tools/aapt2/format/binary/XmlFlattener.h | 6 +- tools/aapt2/format/proto/ProtoDeserialize.cpp | 46 +++--- tools/aapt2/format/proto/ProtoSerialize.cpp | 32 ++-- 12 files changed, 188 insertions(+), 148 deletions(-) diff --git a/tools/aapt2/Debug.cpp b/tools/aapt2/Debug.cpp index 1555d61264931..61c304b2c048d 100644 --- a/tools/aapt2/Debug.cpp +++ b/tools/aapt2/Debug.cpp @@ -35,11 +35,11 @@ namespace aapt { namespace { -class PrintVisitor : public DescendingValueVisitor { +class PrintVisitor : public ConstValueVisitor { public: - using DescendingValueVisitor::Visit; + using ConstValueVisitor::Visit; - void Visit(Attribute* attr) override { + void Visit(const Attribute* attr) override { std::cout << "(attr) type="; attr->PrintMask(&std::cout); static constexpr uint32_t kMask = @@ -55,7 +55,7 @@ class PrintVisitor : public DescendingValueVisitor { } } - void Visit(Style* style) override { + void Visit(const Style* style) override { std::cout << "(style)"; if (style->parent) { const Reference& parent_ref = style->parent.value(); @@ -90,15 +90,15 @@ class PrintVisitor : public DescendingValueVisitor { } } - void Visit(Array* array) override { + void Visit(const Array* array) override { array->Print(&std::cout); } - void Visit(Plural* plural) override { + void Visit(const Plural* plural) override { plural->Print(&std::cout); } - void Visit(Styleable* styleable) override { + void Visit(const Styleable* styleable) override { std::cout << "(styleable)"; for (const auto& attr : styleable->entries) { std::cout << "\n "; @@ -116,17 +116,17 @@ class PrintVisitor : public DescendingValueVisitor { } } - void VisitItem(Item* item) override { + void VisitItem(const Item* item) override { item->Print(&std::cout); } }; } // namespace -void Debug::PrintTable(ResourceTable* table, const DebugPrintTableOptions& options) { +void Debug::PrintTable(const ResourceTable& table, const DebugPrintTableOptions& options) { PrintVisitor visitor; - for (auto& package : table->packages) { + for (const auto& package : table.packages) { std::cout << "Package name=" << package->name; if (package->id) { std::cout << " id=" << std::hex << (int)package->id.value() << std::dec; @@ -261,11 +261,11 @@ void Debug::DumpHex(const void* data, size_t len) { namespace { -class XmlPrinter : public xml::Visitor { +class XmlPrinter : public xml::ConstVisitor { public: - using xml::Visitor::Visit; + using xml::ConstVisitor::Visit; - void Visit(xml::Element* el) override { + void Visit(const xml::Element* el) override { const size_t previous_size = prefix_.size(); for (const xml::NamespaceDecl& decl : el->namespace_decls) { @@ -301,11 +301,11 @@ class XmlPrinter : public xml::Visitor { } prefix_ += " "; - xml::Visitor::Visit(el); + xml::ConstVisitor::Visit(el); prefix_.resize(previous_size); } - void Visit(xml::Text* text) override { + void Visit(const xml::Text* text) override { std::cerr << prefix_ << "T: '" << text->text << "'\n"; } @@ -315,9 +315,9 @@ class XmlPrinter : public xml::Visitor { } // namespace -void Debug::DumpXml(xml::XmlResource* doc) { +void Debug::DumpXml(const xml::XmlResource& doc) { XmlPrinter printer; - doc->root->Accept(&printer); + doc.root->Accept(&printer); } } // namespace aapt diff --git a/tools/aapt2/Debug.h b/tools/aapt2/Debug.h index e2456c7f98b24..296d04bd49bdd 100644 --- a/tools/aapt2/Debug.h +++ b/tools/aapt2/Debug.h @@ -31,13 +31,11 @@ struct DebugPrintTableOptions { }; struct Debug { - static void PrintTable(ResourceTable* table, - const DebugPrintTableOptions& options = {}); + static void PrintTable(const ResourceTable& table, const DebugPrintTableOptions& options = {}); static void PrintStyleGraph(ResourceTable* table, const ResourceName& target_style); static void DumpHex(const void* data, size_t len); - static void DumpXml(xml::XmlResource* doc); - static std::string ToString(xml::XmlResource* doc); + static void DumpXml(const xml::XmlResource& doc); }; } // namespace aapt diff --git a/tools/aapt2/ResourceUtils.cpp b/tools/aapt2/ResourceUtils.cpp index 6fac6e9dfefee..24187d96fec53 100644 --- a/tools/aapt2/ResourceUtils.cpp +++ b/tools/aapt2/ResourceUtils.cpp @@ -704,8 +704,15 @@ std::unique_ptr ParseBinaryResValue(const ResourceType& type, const Config } else { if (type != ResourceType::kString && util::StartsWith(str, "res/")) { // This must be a FileReference. - return util::make_unique(dst_pool->MakeRef( - str, StringPool::Context(StringPool::Context::kHighPriority, config))); + std::unique_ptr file_ref = + util::make_unique(dst_pool->MakeRef( + str, StringPool::Context(StringPool::Context::kHighPriority, config))); + if (util::EndsWith(*file_ref->path, ".xml")) { + file_ref->type = ResourceFile::Type::kBinaryXml; + } else if (util::EndsWith(*file_ref->path, ".png")) { + file_ref->type = ResourceFile::Type::kPng; + } + return std::move(file_ref); } // There are no styles associated with this string, so treat it as a simple string. diff --git a/tools/aapt2/Resources.proto b/tools/aapt2/Resources.proto index 174b7f6b7c8cd..7e7c86d53d24e 100644 --- a/tools/aapt2/Resources.proto +++ b/tools/aapt2/Resources.proto @@ -269,8 +269,19 @@ message StyledString { // A value that is a reference to an external entity, like an XML file or a PNG. message FileReference { + enum Type { + UNKNOWN = 0; + PNG = 1; + BINARY_XML = 2; + PROTO_XML = 3; + } + // Path to a file within the APK (typically res/type-config/entry.ext). string path = 1; + + // The type of file this path points to. For UAM bundle, this cannot be + // BINARY_XML. + Type type = 2; } // A value that represents a primitive data type (float, int, boolean, etc.). diff --git a/tools/aapt2/ResourcesInternal.proto b/tools/aapt2/ResourcesInternal.proto index c16cf6515de1f..520b242ee5094 100644 --- a/tools/aapt2/ResourcesInternal.proto +++ b/tools/aapt2/ResourcesInternal.proto @@ -41,14 +41,8 @@ message CompiledFile { // The configuration for which the resource is defined. aapt.pb.Configuration config = 2; - enum Type { - UNKNOWN = 0; - PNG = 1; - BINARY_XML = 2; - PROTO_XML = 3; - } - - Type type = 3; + // The type of the file. + aapt.pb.FileReference.Type type = 3; // The filesystem path to where the source file originated. // Mainly used to display helpful error messages. @@ -56,7 +50,4 @@ message CompiledFile { // Any symbols this file auto-generates/exports (eg. @+id/foo in an XML file). repeated Symbol exported_symbol = 5; - - // If this is a compiled XML file, this is the root node. - aapt.pb.XmlNode xml_root = 6; } diff --git a/tools/aapt2/cmd/Dump.cpp b/tools/aapt2/cmd/Dump.cpp index 7be6dc018ad5a..090c3fbc5731a 100644 --- a/tools/aapt2/cmd/Dump.cpp +++ b/tools/aapt2/cmd/Dump.cpp @@ -65,21 +65,19 @@ static bool TryDumpFile(IAaptContext* context, const std::string& file_path) { std::unique_ptr zip = io::ZipFileCollection::Create(file_path, &err); if (zip) { ResourceTable table; - if (io::IFile* file = zip->FindFile("resources.arsc.flat")) { + if (io::IFile* file = zip->FindFile("resources.pb")) { std::unique_ptr data = file->OpenAsData(); if (data == nullptr) { - context->GetDiagnostics()->Error(DiagMessage(file_path) - << "failed to open resources.arsc.flat"); + context->GetDiagnostics()->Error(DiagMessage(file_path) << "failed to open resources.pb"); return false; } pb::ResourceTable pb_table; if (!pb_table.ParseFromArray(data->data(), data->size())) { - context->GetDiagnostics()->Error(DiagMessage(file_path) << "invalid resources.arsc.flat"); + context->GetDiagnostics()->Error(DiagMessage(file_path) << "invalid resources.pb"); return false; } - ResourceTable table; if (!DeserializeTableFromPb(pb_table, &table, &err)) { context->GetDiagnostics()->Error(DiagMessage(file_path) << "failed to parse table: " << err); @@ -98,7 +96,7 @@ static bool TryDumpFile(IAaptContext* context, const std::string& file_path) { } } - Debug::PrintTable(&table, print_options); + Debug::PrintTable(table, print_options); return true; } @@ -137,7 +135,7 @@ static bool TryDumpFile(IAaptContext* context, const std::string& file_path) { continue; } - Debug::PrintTable(&table, print_options); + Debug::PrintTable(table, print_options); } else if (entry->Type() == ContainerEntryType::kResFile) { pb::internal::CompiledFile pb_compiled_file; off64_t offset; diff --git a/tools/aapt2/cmd/Link.cpp b/tools/aapt2/cmd/Link.cpp index baee9c98ecd7c..55a4c438755c6 100644 --- a/tools/aapt2/cmd/Link.cpp +++ b/tools/aapt2/cmd/Link.cpp @@ -71,6 +71,14 @@ using ::android::base::StringPrintf; namespace aapt { +constexpr static const char kApkResourceTablePath[] = "resources.arsc"; +constexpr static const char kProtoResourceTablePath[] = "resources.pb"; + +enum class OutputFormat { + kApk, + kProto, +}; + struct LinkOptions { std::string output_path; std::string manifest_path; @@ -79,6 +87,7 @@ struct LinkOptions { std::vector assets_dirs; bool output_to_directory = false; bool auto_add_overlay = false; + OutputFormat output_format = OutputFormat::kApk; // Java/Proguard options. Maybe generate_java_class_path; @@ -253,26 +262,39 @@ class FeatureSplitSymbolTableDelegate : public DefaultSymbolTableDelegate { IAaptContext* context_; }; -static bool FlattenXml(IAaptContext* context, xml::XmlResource* xml_res, const StringPiece& path, - bool keep_raw_values, bool utf16, IArchiveWriter* writer) { - BigBuffer buffer(1024); - XmlFlattenerOptions options = {}; - options.keep_raw_values = keep_raw_values; - options.use_utf16 = utf16; - XmlFlattener flattener(&buffer, options); - if (!flattener.Consume(context, xml_res)) { - return false; - } - +static bool FlattenXml(IAaptContext* context, const xml::XmlResource& xml_res, + const StringPiece& path, bool keep_raw_values, bool utf16, + OutputFormat format, IArchiveWriter* writer) { if (context->IsVerbose()) { context->GetDiagnostics()->Note(DiagMessage(path) << "writing to archive (keep_raw_values=" << (keep_raw_values ? "true" : "false") << ")"); } - io::BigBufferInputStream input_stream(&buffer); - return io::CopyInputStreamToArchive(context, &input_stream, path.to_string(), - ArchiveEntry::kCompress, writer); + switch (format) { + case OutputFormat::kApk: { + BigBuffer buffer(1024); + XmlFlattenerOptions options = {}; + options.keep_raw_values = keep_raw_values; + options.use_utf16 = utf16; + XmlFlattener flattener(&buffer, options); + if (!flattener.Consume(context, &xml_res)) { + return false; + } + + io::BigBufferInputStream input_stream(&buffer); + return io::CopyInputStreamToArchive(context, &input_stream, path.to_string(), + ArchiveEntry::kCompress, writer); + } break; + + case OutputFormat::kProto: { + pb::XmlNode pb_node; + SerializeXmlResourceToPb(xml_res, &pb_node); + return io::CopyProtoToArchive(context, &pb_node, path.to_string(), ArchiveEntry::kCompress, + writer); + } break; + } + return false; } static std::unique_ptr LoadTableFromPb(const Source& source, const void* data, @@ -310,6 +332,7 @@ struct ResourceFileFlattenerOptions { bool keep_raw_values = false; bool do_not_compress_anything = false; bool update_proguard_spec = false; + OutputFormat output_format = OutputFormat::kApk; std::unordered_set extensions_to_not_compress; }; @@ -627,8 +650,9 @@ bool ResourceFileFlattener::Flatten(ResourceTable* table, IArchiveWriter* archiv return false; } } - error |= !FlattenXml(context_, doc.get(), dst_path, options_.keep_raw_values, - false /*utf16*/, archive_writer); + + error |= !FlattenXml(context_, *doc, dst_path, options_.keep_raw_values, + false /*utf16*/, options_.output_format, archive_writer); } } else { error |= !io::CopyFileToArchive(context_, file_op.file_to_copy, file_op.dst_path, @@ -927,23 +951,29 @@ class LinkCommand { } } - bool FlattenTable(ResourceTable* table, IArchiveWriter* writer) { - BigBuffer buffer(1024); - TableFlattener flattener(options_.table_flattener_options, &buffer); - if (!flattener.Consume(context_, table)) { - context_->GetDiagnostics()->Error(DiagMessage() << "failed to flatten resource table"); - return false; + bool FlattenTable(ResourceTable* table, OutputFormat format, IArchiveWriter* writer) { + switch (format) { + case OutputFormat::kApk: { + BigBuffer buffer(1024); + TableFlattener flattener(options_.table_flattener_options, &buffer); + if (!flattener.Consume(context_, table)) { + context_->GetDiagnostics()->Error(DiagMessage() << "failed to flatten resource table"); + return false; + } + + io::BigBufferInputStream input_stream(&buffer); + return io::CopyInputStreamToArchive(context_, &input_stream, kApkResourceTablePath, + ArchiveEntry::kAlign, writer); + } break; + + case OutputFormat::kProto: { + pb::ResourceTable pb_table; + SerializeTableToPb(*table, &pb_table); + return io::CopyProtoToArchive(context_, &pb_table, kProtoResourceTablePath, + ArchiveEntry::kCompress, writer); + } break; } - - io::BigBufferInputStream input_stream(&buffer); - return io::CopyInputStreamToArchive(context_, &input_stream, "resources.arsc", - ArchiveEntry::kAlign, writer); - } - - bool FlattenTableToPb(ResourceTable* table, IArchiveWriter* writer) { - pb::ResourceTable pb_table; - SerializeTableToPb(*table, &pb_table); - return io::CopyProtoToArchive(context_, &pb_table, "resources.arsc.flat", 0, writer); + return false; } bool WriteJavaFile(ResourceTable* table, const StringPiece& package_name_to_generate, @@ -1172,7 +1202,7 @@ class LinkCommand { } std::unique_ptr LoadTablePbFromCollection(io::IFileCollection* collection) { - io::IFile* file = collection->FindFile("resources.arsc.flat"); + io::IFile* file = collection->FindFile(kProtoResourceTablePath); if (!file) { return {}; } @@ -1466,15 +1496,13 @@ class LinkCommand { return true; } - /** - * Writes the AndroidManifest, ResourceTable, and all XML files referenced by - * the ResourceTable to the IArchiveWriter. - */ + // Writes the AndroidManifest, ResourceTable, and all XML files referenced by the ResourceTable + // to the IArchiveWriter. bool WriteApk(IArchiveWriter* writer, proguard::KeepSet* keep_set, xml::XmlResource* manifest, ResourceTable* table) { const bool keep_raw_values = context_->GetPackageType() == PackageType::kStaticLib; - bool result = FlattenXml(context_, manifest, "AndroidManifest.xml", keep_raw_values, - true /*utf16*/, writer); + bool result = FlattenXml(context_, *manifest, "AndroidManifest.xml", keep_raw_values, + true /*utf16*/, options_.output_format, writer); if (!result) { return false; } @@ -1489,6 +1517,7 @@ class LinkCommand { file_flattener_options.no_xml_namespaces = options_.no_xml_namespaces; file_flattener_options.update_proguard_spec = static_cast(options_.generate_proguard_rules_path); + file_flattener_options.output_format = options_.output_format; ResourceFileFlattener file_flattener(file_flattener_options, context_, keep_set); @@ -1497,15 +1526,9 @@ class LinkCommand { return false; } - if (context_->GetPackageType() == PackageType::kStaticLib) { - if (!FlattenTableToPb(table, writer)) { - return false; - } - } else { - if (!FlattenTable(table, writer)) { - context_->GetDiagnostics()->Error(DiagMessage() << "failed to write resources.arsc"); - return false; - } + if (!FlattenTable(table, options_.output_format, writer)) { + context_->GetDiagnostics()->Error(DiagMessage() << "failed to write resource table"); + return false; } return true; } @@ -1869,6 +1892,7 @@ int Link(const std::vector& args, IDiagnostics* diagnostics) { bool verbose = false; bool shared_lib = false; bool static_lib = false; + bool proto_format = false; Maybe stable_id_file_path; std::vector split_args; Flags flags = @@ -1949,6 +1973,10 @@ int Link(const std::vector& args, IDiagnostics* diagnostics) { .OptionalSwitch("--shared-lib", "Generates a shared Android runtime library.", &shared_lib) .OptionalSwitch("--static-lib", "Generate a static Android library.", &static_lib) + .OptionalSwitch("--proto-format", + "Generates compiled resources in Protobuf format.\n" + "Suitable as input to the bundle tool for generating an App Bundle.", + &proto_format) .OptionalSwitch("--no-static-lib-packages", "Merge all library resources under the app's package.", &options.no_static_lib_packages) @@ -2035,21 +2063,25 @@ int Link(const std::vector& args, IDiagnostics* diagnostics) { context.SetVerbose(verbose); } - if (shared_lib && static_lib) { - context.GetDiagnostics()->Error(DiagMessage() - << "only one of --shared-lib and --static-lib can be defined"); + if (int{shared_lib} + int{static_lib} + int{proto_format} > 1) { + context.GetDiagnostics()->Error( + DiagMessage() + << "only one of --shared-lib, --static-lib, or --proto_format can be defined"); return 1; } + // The default build type. + context.SetPackageType(PackageType::kApp); + context.SetPackageId(kAppPackageId); + if (shared_lib) { context.SetPackageType(PackageType::kSharedLib); context.SetPackageId(0x00); } else if (static_lib) { context.SetPackageType(PackageType::kStaticLib); - context.SetPackageId(kAppPackageId); - } else { - context.SetPackageType(PackageType::kApp); - context.SetPackageId(kAppPackageId); + options.output_format = OutputFormat::kProto; + } else if (proto_format) { + options.output_format = OutputFormat::kProto; } if (package_id) { diff --git a/tools/aapt2/format/Container_test.cpp b/tools/aapt2/format/Container_test.cpp index 3d064d0169fb6..dc81a3ae2219a 100644 --- a/tools/aapt2/format/Container_test.cpp +++ b/tools/aapt2/format/Container_test.cpp @@ -43,7 +43,7 @@ TEST(ContainerTest, SerializeCompiledFile) { pb::internal::CompiledFile pb_compiled_file; pb_compiled_file.set_resource_name("android:layout/main.xml"); - pb_compiled_file.set_type(pb::internal::CompiledFile::Type::CompiledFile_Type_PROTO_XML); + pb_compiled_file.set_type(pb::FileReference::PROTO_XML); pb_compiled_file.set_source_path("res/layout/main.xml"); io::StringInputStream data(expected_data); ASSERT_TRUE(writer.AddResFileEntry(pb_compiled_file, &data)); diff --git a/tools/aapt2/format/binary/XmlFlattener.cpp b/tools/aapt2/format/binary/XmlFlattener.cpp index 2456c3dfd5e9e..345cc95cfb29b 100644 --- a/tools/aapt2/format/binary/XmlFlattener.cpp +++ b/tools/aapt2/format/binary/XmlFlattener.cpp @@ -56,9 +56,9 @@ static bool cmp_xml_attribute_by_id(const xml::Attribute* a, const xml::Attribut return false; } -class XmlFlattenerVisitor : public xml::Visitor { +class XmlFlattenerVisitor : public xml::ConstVisitor { public: - using xml::Visitor::Visit; + using xml::ConstVisitor::Visit; StringPool pool; std::map package_pools; @@ -74,7 +74,7 @@ class XmlFlattenerVisitor : public xml::Visitor { : buffer_(buffer), options_(options) { } - void Visit(xml::Text* node) override { + void Visit(const xml::Text* node) override { if (util::TrimWhitespace(node->text).empty()) { // Skip whitespace only text nodes. return; @@ -95,7 +95,7 @@ class XmlFlattenerVisitor : public xml::Visitor { writer.Finish(); } - void Visit(xml::Element* node) override { + void Visit(const xml::Element* node) override { for (const xml::NamespaceDecl& decl : node->namespace_decls) { // Skip dedicated tools namespace. if (decl.uri != xml::kSchemaTools) { @@ -125,7 +125,7 @@ class XmlFlattenerVisitor : public xml::Visitor { start_writer.Finish(); } - xml::Visitor::Visit(node); + xml::ConstVisitor::Visit(node); { ChunkWriter end_writer(buffer_); @@ -182,12 +182,13 @@ class XmlFlattenerVisitor : public xml::Visitor { writer.Finish(); } - void WriteAttributes(xml::Element* node, ResXMLTree_attrExt* flat_elem, ChunkWriter* writer) { + void WriteAttributes(const xml::Element* node, ResXMLTree_attrExt* flat_elem, + ChunkWriter* writer) { filtered_attrs_.clear(); filtered_attrs_.reserve(node->attributes.size()); // Filter the attributes. - for (xml::Attribute& attr : node->attributes) { + for (const xml::Attribute& attr : node->attributes) { if (attr.namespace_uri != xml::kSchemaTools) { filtered_attrs_.push_back(&attr); } @@ -282,12 +283,12 @@ class XmlFlattenerVisitor : public xml::Visitor { XmlFlattenerOptions options_; // Scratch vector to filter attributes. We avoid allocations making this a member. - std::vector filtered_attrs_; + std::vector filtered_attrs_; }; } // namespace -bool XmlFlattener::Flatten(IAaptContext* context, xml::Node* node) { +bool XmlFlattener::Flatten(IAaptContext* context, const xml::Node* node) { BigBuffer node_buffer(1024); XmlFlattenerVisitor visitor(&node_buffer, options_); node->Accept(&visitor); @@ -341,7 +342,7 @@ bool XmlFlattener::Flatten(IAaptContext* context, xml::Node* node) { return true; } -bool XmlFlattener::Consume(IAaptContext* context, xml::XmlResource* resource) { +bool XmlFlattener::Consume(IAaptContext* context, const xml::XmlResource* resource) { if (!resource->root) { return false; } diff --git a/tools/aapt2/format/binary/XmlFlattener.h b/tools/aapt2/format/binary/XmlFlattener.h index 8db2281cd74ab..1f9e777f7a1a9 100644 --- a/tools/aapt2/format/binary/XmlFlattener.h +++ b/tools/aapt2/format/binary/XmlFlattener.h @@ -34,18 +34,18 @@ struct XmlFlattenerOptions { bool use_utf16 = false; }; -class XmlFlattener : public IXmlResourceConsumer { +class XmlFlattener { public: XmlFlattener(BigBuffer* buffer, XmlFlattenerOptions options) : buffer_(buffer), options_(options) { } - bool Consume(IAaptContext* context, xml::XmlResource* resource) override; + bool Consume(IAaptContext* context, const xml::XmlResource* resource); private: DISALLOW_COPY_AND_ASSIGN(XmlFlattener); - bool Flatten(IAaptContext* context, xml::Node* node); + bool Flatten(IAaptContext* context, const xml::Node* node); BigBuffer* buffer_; XmlFlattenerOptions options_; diff --git a/tools/aapt2/format/proto/ProtoDeserialize.cpp b/tools/aapt2/format/proto/ProtoDeserialize.cpp index c722307240c15..86bd86536cc46 100644 --- a/tools/aapt2/format/proto/ProtoDeserialize.cpp +++ b/tools/aapt2/format/proto/ProtoDeserialize.cpp @@ -390,8 +390,15 @@ static bool DeserializePackageFromPb(const pb::Package& pb_package, const ResStr } ResourceTableType* type = pkg->FindOrCreateType(*res_type); + if (pb_type.has_type_id()) { + type->id = static_cast(pb_type.type_id().id()); + } + for (const pb::Entry& pb_entry : pb_type.entry()) { ResourceEntry* entry = type->FindOrCreateEntry(pb_entry.name()); + if (pb_entry.has_entry_id()) { + entry->id = static_cast(pb_entry.entry_id().id()); + } // Deserialize the symbol status (public/private with source and comments). if (pb_entry.has_symbol_status()) { @@ -405,21 +412,11 @@ static bool DeserializePackageFromPb(const pb::Package& pb_package, const ResStr const SymbolState visibility = DeserializeVisibilityFromPb(pb_status.visibility()); entry->symbol_status.state = visibility; - if (visibility == SymbolState::kPublic) { - // This is a public symbol, we must encode the ID now if there is one. - if (pb_entry.has_entry_id()) { - entry->id = static_cast(pb_entry.entry_id().id()); - } - - if (type->symbol_status.state != SymbolState::kPublic) { - // If the type has not been made public, do so now. - type->symbol_status.state = SymbolState::kPublic; - if (pb_type.has_type_id()) { - type->id = static_cast(pb_type.type_id().id()); - } - } + // Propagate the public visibility up to the Type. + type->symbol_status.state = SymbolState::kPublic; } else if (visibility == SymbolState::kPrivate) { + // Only propagate if no previous state was assigned. if (type->symbol_status.state == SymbolState::kUndefined) { type->symbol_status.state = SymbolState::kPrivate; } @@ -484,15 +481,14 @@ bool DeserializeTableFromPb(const pb::ResourceTable& pb_table, ResourceTable* ou return true; } -static ResourceFile::Type DeserializeCompiledFileType( - const pb::internal::CompiledFile::Type& pb_type) { - switch (pb_type) { - case pb::internal::CompiledFile::Type::CompiledFile_Type_PNG: - return ResourceFile::Type::kPng; - case pb::internal::CompiledFile::Type::CompiledFile_Type_BINARY_XML: +static ResourceFile::Type DeserializeFileReferenceTypeFromPb(const pb::FileReference::Type& type) { + switch (type) { + case pb::FileReference::BINARY_XML: return ResourceFile::Type::kBinaryXml; - case pb::internal::CompiledFile::Type::CompiledFile_Type_PROTO_XML: + case pb::FileReference::PROTO_XML: return ResourceFile::Type::kProtoXml; + case pb::FileReference::PNG: + return ResourceFile::Type::kPng; default: return ResourceFile::Type::kUnknown; } @@ -510,7 +506,7 @@ bool DeserializeCompiledFileFromPb(const pb::internal::CompiledFile& pb_file, out_file->name = name_ref.ToResourceName(); out_file->source.path = pb_file.source_path(); - out_file->type = DeserializeCompiledFileType(pb_file.type()); + out_file->type = DeserializeFileReferenceTypeFromPb(pb_file.type()); std::string config_error; if (!DeserializeConfigFromPb(pb_file.config(), &out_file->config, &config_error)) { @@ -773,8 +769,12 @@ std::unique_ptr DeserializeItemFromPb(const pb::Item& pb_item, } break; case pb::Item::kFile: { - return util::make_unique(value_pool->MakeRef( - pb_item.file().path(), StringPool::Context(StringPool::Context::kHighPriority, config))); + const pb::FileReference& pb_file = pb_item.file(); + std::unique_ptr file_ref = + util::make_unique(value_pool->MakeRef( + pb_file.path(), StringPool::Context(StringPool::Context::kHighPriority, config))); + file_ref->type = DeserializeFileReferenceTypeFromPb(pb_file.type()); + return std::move(file_ref); } break; default: diff --git a/tools/aapt2/format/proto/ProtoSerialize.cpp b/tools/aapt2/format/proto/ProtoSerialize.cpp index a75bbc73568bb..1d184fe5a8d20 100644 --- a/tools/aapt2/format/proto/ProtoSerialize.cpp +++ b/tools/aapt2/format/proto/ProtoSerialize.cpp @@ -361,6 +361,19 @@ static pb::Plural_Arity SerializePluralEnumToPb(size_t plural_idx) { return pb::Plural_Arity_OTHER; } +static pb::FileReference::Type SerializeFileReferenceTypeToPb(const ResourceFile::Type& type) { + switch (type) { + case ResourceFile::Type::kBinaryXml: + return pb::FileReference::BINARY_XML; + case ResourceFile::Type::kProtoXml: + return pb::FileReference::PROTO_XML; + case ResourceFile::Type::kPng: + return pb::FileReference::PNG; + default: + return pb::FileReference::UNKNOWN; + } +} + namespace { class ValueSerializer : public ConstValueVisitor { @@ -395,7 +408,9 @@ class ValueSerializer : public ConstValueVisitor { } void Visit(const FileReference* file) override { - out_value_->mutable_item()->mutable_file()->set_path(*file->path); + pb::FileReference* pb_file = out_value_->mutable_item()->mutable_file(); + pb_file->set_path(*file->path); + pb_file->set_type(SerializeFileReferenceTypeToPb(file->type)); } void Visit(const Id* /*id*/) override { @@ -507,23 +522,10 @@ void SerializeItemToPb(const Item& item, pb::Item* out_item) { out_item->MergeFrom(value.item()); } -static pb::internal::CompiledFile::Type SerializeCompiledFileType(const ResourceFile::Type& type) { - switch (type) { - case ResourceFile::Type::kPng: - return pb::internal::CompiledFile::Type::CompiledFile_Type_PNG; - case ResourceFile::Type::kBinaryXml: - return pb::internal::CompiledFile::Type::CompiledFile_Type_BINARY_XML; - case ResourceFile::Type::kProtoXml: - return pb::internal::CompiledFile::Type::CompiledFile_Type_PROTO_XML; - default: - return pb::internal::CompiledFile::Type::CompiledFile_Type_UNKNOWN; - } -} - void SerializeCompiledFileToPb(const ResourceFile& file, pb::internal::CompiledFile* out_file) { out_file->set_resource_name(file.name.ToString()); out_file->set_source_path(file.source.path); - out_file->set_type(SerializeCompiledFileType(file.type)); + out_file->set_type(SerializeFileReferenceTypeToPb(file.type)); SerializeConfig(file.config, out_file->mutable_config()); for (const SourcedResourceName& exported : file.exported_symbols) {