diff --git a/tools/aapt2/Format.proto b/tools/aapt2/Format.proto index 8381fa0094675..6be7f02dc7d26 100644 --- a/tools/aapt2/Format.proto +++ b/tools/aapt2/Format.proto @@ -67,21 +67,12 @@ message CompiledFile { // Top level message representing a resource table. message ResourceTable { - // The string pool containing string values (strings that actually end up in the binary ARSC - // file) referenced throughout the resource table. - optional StringPool string_pool = 1; - // The string pool containing source paths referenced throughout the resource table. This does // not end up in the final binary ARSC file. - optional StringPool source_pool = 2; - - // The string pool containing the names of unresolved symbols. This does not end up in the final - // binary ARSC file. Unresolved symbols are just resource names that haven't had a resource ID - // assigned to them, therefore can't be referenced by resource ID. - optional StringPool symbol_pool = 3; + optional StringPool source_pool = 1; // Resource definitions corresponding to an Android package. - repeated Package packages = 4; + repeated Package packages = 2; } // Defines resources for an Android package. @@ -202,9 +193,10 @@ message Item { optional Reference ref = 1; optional String str = 2; optional RawString raw_str = 3; - optional FileReference file = 4; - optional Id id = 5; - optional Primitive prim = 6; + optional StyledString styled_str = 4; + optional FileReference file = 5; + optional Id id = 6; + optional Primitive prim = 7; } // A CompoundValue is an abstract type. It represents a value that is a made of other values. @@ -233,10 +225,8 @@ message Reference { // The resource ID (0xPPTTEEEE) of the resource being referred. optional uint32 id = 2; - // If the resource ID is not resolved, the index into the symbol string pool where the name of - // the reference is stored. The symbol string pool is located at the top level ResourceTable - // message. - optional uint32 symbol_idx = 3; + // The optional resource name. + optional string name = 3; // Whether this reference is referencing a private resource (@*package:type/entry). optional bool private = 4; @@ -249,23 +239,41 @@ message Id { // A value that is a string. message String { - // The index into the values string pool, located at the top level ResourceTable message. - optional uint32 idx = 1; + optional string value = 1; } // A value that is a raw string, which is unescaped/uninterpreted. This is typically used to // represent the value of a style attribute before the attribute is compiled and the set of // allowed values is known. message RawString { - // The index into the values string pool, located at the top level ResourceTable message. - optional uint32 idx = 1; + optional string value = 1; +} + +// A string with styling information, like html tags that specify boldness, italics, etc. +message StyledString { + // The raw text of the string. + optional string value = 1; + + // A Span marks a region of the string text that is styled. + message Span { + // The name of the tag, and its attributes, encoded as follows: + // tag_name;attr1=value1;attr2=value2;[...] + optional string tag = 1; + + // The first character position this span applies to, in UTF-16 offset. + optional uint32 first_char = 2; + + // The last character position this span applies to, in UTF-16 offset. + optional uint32 last_char = 3; + } + + repeated Span span = 2; } // A value that is a reference to an external entity, like an XML file or a PNG. message FileReference { - // The index into the values string pool, located at the top level ResourceTable message. This - // represents the path to the file within an APK (typically res/type-config/entry.ext). - optional uint32 path_idx = 1; + // Path to a file within the APK (typically res/type-config/entry.ext). + optional string path = 1; } // A value that represents a primitive data type (float, int, boolean, etc.). diff --git a/tools/aapt2/proto/TableProtoDeserializer.cpp b/tools/aapt2/proto/TableProtoDeserializer.cpp index 37d5ed0cf59d9..e891954bc5235 100644 --- a/tools/aapt2/proto/TableProtoDeserializer.cpp +++ b/tools/aapt2/proto/TableProtoDeserializer.cpp @@ -55,15 +55,10 @@ class ReferenceIdToNameVisitor : public ValueVisitor { class PackagePbDeserializer { public: - PackagePbDeserializer(const android::ResStringPool* valuePool, - const android::ResStringPool* sourcePool, - const android::ResStringPool* symbolPool, - const Source& source, IDiagnostics* diag) - : value_pool_(valuePool), - source_pool_(sourcePool), - symbol_pool_(symbolPool), - source_(source), - diag_(diag) {} + PackagePbDeserializer(const android::ResStringPool* sourcePool, const Source& source, + IDiagnostics* diag) + : source_pool_(sourcePool), source_(source), diag_(diag) { + } public: bool DeserializeFromPb(const pb::Package& pbPackage, ResourceTable* table) { @@ -87,8 +82,7 @@ class PackagePbDeserializer { for (const pb::Entry& pbEntry : pbType.entries()) { ResourceEntry* entry = type->FindOrCreateEntry(pbEntry.name()); - // Deserialize the symbol status (public/private with source and - // comments). + // Deserialize the symbol status (public/private with source and comments). if (pbEntry.has_symbol_status()) { const pb::SymbolStatus& pbStatus = pbEntry.symbol_status(); if (pbStatus.has_source()) { @@ -161,8 +155,7 @@ class PackagePbDeserializer { private: std::unique_ptr DeserializeItemFromPb(const pb::Item& pb_item, - const ConfigDescription& config, - StringPool* pool) { + const ConfigDescription& config, StringPool* pool) { if (pb_item.has_ref()) { const pb::Reference& pb_ref = pb_item.ref(); std::unique_ptr ref = util::make_unique(); @@ -173,45 +166,32 @@ class PackagePbDeserializer { } else if (pb_item.has_prim()) { const pb::Primitive& pb_prim = pb_item.prim(); - android::Res_value prim = {}; - prim.dataType = static_cast(pb_prim.type()); - prim.data = pb_prim.data(); - return util::make_unique(prim); + return util::make_unique(static_cast(pb_prim.type()), + pb_prim.data()); } else if (pb_item.has_id()) { return util::make_unique(); } else if (pb_item.has_str()) { - const uint32_t idx = pb_item.str().idx(); - const std::string str = util::GetString(*value_pool_, idx); - - const android::ResStringPool_span* spans = value_pool_->styleAt(idx); - if (spans && spans->name.index != android::ResStringPool_span::END) { - StyleString style_str = {str}; - while (spans->name.index != android::ResStringPool_span::END) { - style_str.spans.push_back( - Span{util::GetString(*value_pool_, spans->name.index), - spans->firstChar, spans->lastChar}); - spans++; - } - return util::make_unique(pool->MakeRef( - style_str, StringPool::Context(StringPool::Context::kNormalPriority, config))); - } return util::make_unique( - pool->MakeRef(str, StringPool::Context(config))); + pool->MakeRef(pb_item.str().value(), StringPool::Context(config))); } else if (pb_item.has_raw_str()) { - const uint32_t idx = pb_item.raw_str().idx(); - const std::string str = util::GetString(*value_pool_, idx); return util::make_unique( - pool->MakeRef(str, StringPool::Context(config))); + pool->MakeRef(pb_item.raw_str().value(), StringPool::Context(config))); + + } else if (pb_item.has_styled_str()) { + const pb::StyledString& pb_str = pb_item.styled_str(); + StyleString style_str{pb_str.value()}; + for (const pb::StyledString::Span& pb_span : pb_str.span()) { + style_str.spans.push_back(Span{pb_span.tag(), pb_span.first_char(), pb_span.last_char()}); + } + return util::make_unique(pool->MakeRef( + style_str, StringPool::Context(StringPool::Context::kNormalPriority, config))); } else if (pb_item.has_file()) { - const uint32_t idx = pb_item.file().path_idx(); - const std::string str = util::GetString(*value_pool_, idx); return util::make_unique(pool->MakeRef( - str, - StringPool::Context(StringPool::Context::kHighPriority, config))); + pb_item.file().path(), StringPool::Context(StringPool::Context::kHighPriority, config))); } else { diag_->Error(DiagMessage(source_) << "unknown item"); @@ -255,15 +235,13 @@ class PackagePbDeserializer { std::unique_ptr