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

Commit b54ef10f authored by Adam Lesinski's avatar Adam Lesinski
Browse files

AAPT2: Ensure string pool ordering is compact

Keep styledstrings at the beginning of the StringPool
to reduce the padding in the StyledString array.

Bug:32336940
Test: manual
Change-Id: Iec820c21a54daac40ecc3b2f87517a0f1efc9d3d
parent 011cef54
Loading
Loading
Loading
Loading
+4 −3
Original line number Diff line number Diff line
@@ -533,7 +533,8 @@ std::unique_ptr<Item> ResourceParser::parseXml(xml::XmlPullParser* parser,
  if (!styleString.spans.empty()) {
    // This can only be a StyledString.
    return util::make_unique<StyledString>(mTable->stringPool.makeRef(
        styleString, StringPool::Context{1, mConfig}));
        styleString,
        StringPool::Context(StringPool::Context::kStylePriority, mConfig)));
  }

  auto onCreateReference = [&](const ResourceName& name) {
@@ -559,13 +560,13 @@ std::unique_ptr<Item> ResourceParser::parseXml(xml::XmlPullParser* parser,
  if (typeMask & android::ResTable_map::TYPE_STRING) {
    // Use the trimmed, escaped string.
    return util::make_unique<String>(mTable->stringPool.makeRef(
        styleString.str, StringPool::Context{1, mConfig}));
        styleString.str, StringPool::Context(mConfig)));
  }

  if (allowRawValue) {
    // We can't parse this so return a RawString if we are allowed.
    return util::make_unique<RawString>(
        mTable->stringPool.makeRef(rawValue, StringPool::Context{1, mConfig}));
        mTable->stringPool.makeRef(rawValue, StringPool::Context(mConfig)));
  }
  return {};
}
+15 −2
Original line number Diff line number Diff line
@@ -42,9 +42,22 @@ struct StyleString {

class StringPool {
 public:
  struct Context {
    uint32_t priority;
  class Context {
   public:
    enum : uint32_t {
      kStylePriority = 0u,
      kHighPriority = 1u,
      kNormalPriority = 0x7fffffffu,
      kLowPriority = 0xffffffffu,
    };
    uint32_t priority = kNormalPriority;
    ConfigDescription config;

    Context() = default;
    Context(uint32_t p, const ConfigDescription& c) : priority(p), config(c) {}
    explicit Context(uint32_t p) : priority(p) {}
    explicit Context(const ConfigDescription& c)
        : priority(kNormalPriority), config(c) {}
  };

  class Entry;
+2 −2
Original line number Diff line number Diff line
@@ -63,7 +63,7 @@ struct XmlFlattenerVisitor : public xml::Visitor {
      dest->index = util::deviceToHost32(-1);
    } else {
      mStringRefs.push_back(StringFlattenDest{
          mPool.makeRef(str, StringPool::Context{priority}), dest});
          mPool.makeRef(str, StringPool::Context(priority)), dest});
    }
  }

@@ -256,7 +256,7 @@ struct XmlFlattenerVisitor : public xml::Visitor {

        StringPool::Ref nameRef =
            mPackagePools[aaptAttr.id.value().packageId()].makeRef(
                xmlAttr->name, StringPool::Context{aaptAttr.id.value().id});
                xmlAttr->name, StringPool::Context(aaptAttr.id.value().id));

        // Add it to the list of strings to flatten.
        addString(nameRef, &flatAttr->name);
+403 −388
Original line number Diff line number Diff line
@@ -30,8 +30,9 @@ class ReferenceIdToNameVisitor : public ValueVisitor {
 public:
  using ValueVisitor::visit;

    explicit ReferenceIdToNameVisitor(const std::map<ResourceId, ResourceNameRef>* mapping) :
            mMapping(mapping) {
  explicit ReferenceIdToNameVisitor(
      const std::map<ResourceId, ResourceNameRef>* mapping)
      : mMapping(mapping) {
    assert(mMapping);
  }

@@ -56,10 +57,12 @@ public:
  PackagePbDeserializer(const android::ResStringPool* valuePool,
                        const android::ResStringPool* sourcePool,
                        const android::ResStringPool* symbolPool,
                          const Source& source, IDiagnostics* diag) :
            mValuePool(valuePool), mSourcePool(sourcePool), mSymbolPool(symbolPool),
            mSource(source), mDiag(diag) {
    }
                        const Source& source, IDiagnostics* diag)
      : mValuePool(valuePool),
        mSourcePool(sourcePool),
        mSymbolPool(symbolPool),
        mSource(source),
        mDiag(diag) {}

 public:
  bool deserializeFromPb(const pb::Package& pbPackage, ResourceTable* table) {
@@ -70,11 +73,13 @@ public:

    std::map<ResourceId, ResourceNameRef> idIndex;

        ResourceTablePackage* pkg = table->createPackage(pbPackage.package_name(), id);
    ResourceTablePackage* pkg =
        table->createPackage(pbPackage.package_name(), id);
    for (const pb::Type& pbType : pbPackage.types()) {
      const ResourceType* resType = parseResourceType(pbType.name());
      if (!resType) {
                mDiag->error(DiagMessage(mSource) << "unknown type '" << pbType.name() << "'");
        mDiag->error(DiagMessage(mSource) << "unknown type '" << pbType.name()
                                          << "'");
        return {};
      }

@@ -83,7 +88,8 @@ public:
      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()) {
@@ -95,11 +101,13 @@ public:
            entry->symbolStatus.comment = pbStatus.comment();
          }

                    SymbolState visibility = deserializeVisibilityFromPb(pbStatus.visibility());
          SymbolState visibility =
              deserializeVisibilityFromPb(pbStatus.visibility());
          entry->symbolStatus.state = visibility;

          if (visibility == SymbolState::kPublic) {
                        // This is a public symbol, we must encode the ID now if there is one.
            // This is a public symbol, we must encode the ID now if there is
            // one.
            if (pbEntry.has_id()) {
              entry->id = static_cast<uint16_t>(pbEntry.id());
            }
@@ -132,16 +140,16 @@ public:
            return {};
          }

                    ResourceConfigValue* configValue = entry->findOrCreateValue(config,
                                                                                pbConfig.product());
          ResourceConfigValue* configValue =
              entry->findOrCreateValue(config, pbConfig.product());
          if (configValue->value) {
            // Duplicate config.
            mDiag->error(DiagMessage(mSource) << "duplicate configuration");
            return {};
          }

                    configValue->value = deserializeValueFromPb(pbConfigValue.value(),
                                                                config, &table->stringPool);
          configValue->value = deserializeValueFromPb(
              pbConfigValue.value(), config, &table->stringPool);
          if (!configValue->value) {
            return {};
          }
@@ -184,30 +192,30 @@ private:
      if (spans && spans->name.index != android::ResStringPool_span::END) {
        StyleString styleStr = {str};
        while (spans->name.index != android::ResStringPool_span::END) {
                    styleStr.spans.push_back(Span{
                            util::getString(*mValuePool, spans->name.index),
                            spans->firstChar,
                            spans->lastChar
                    });
          styleStr.spans.push_back(
              Span{util::getString(*mValuePool, spans->name.index),
                   spans->firstChar, spans->lastChar});
          spans++;
        }
                return util::make_unique<StyledString>(
                        pool->makeRef(styleStr, StringPool::Context{ 1, config }));
        return util::make_unique<StyledString>(pool->makeRef(
            styleStr,
            StringPool::Context(StringPool::Context::kStylePriority, config)));
      }
      return util::make_unique<String>(
                    pool->makeRef(str, StringPool::Context{ 1, config }));
          pool->makeRef(str, StringPool::Context(config)));

    } else if (pbItem.has_raw_str()) {
      const uint32_t idx = pbItem.raw_str().idx();
      const std::string str = util::getString(*mValuePool, idx);
      return util::make_unique<RawString>(
                    pool->makeRef(str, StringPool::Context{ 1, config }));
          pool->makeRef(str, StringPool::Context(config)));

    } else if (pbItem.has_file()) {
      const uint32_t idx = pbItem.file().path_idx();
      const std::string str = util::getString(*mValuePool, idx);
            return util::make_unique<FileReference>(
                    pool->makeRef(str, StringPool::Context{ 0, config }));
      return util::make_unique<FileReference>(pool->makeRef(
          str,
          StringPool::Context(StringPool::Context::kHighPriority, config)));

    } else {
      mDiag->error(DiagMessage(mSource) << "unknown item");
@@ -251,7 +259,8 @@ private:
        std::unique_ptr<Style> style = util::make_unique<Style>();
        if (pbStyle.has_parent()) {
          style->parent = Reference();
                    if (!deserializeReferenceFromPb(pbStyle.parent(), &style->parent.value())) {
          if (!deserializeReferenceFromPb(pbStyle.parent(),
                                          &style->parent.value())) {
            return {};
          }

@@ -295,8 +304,8 @@ private:
        const pb::Array& pbArray = pbCompoundValue.array();
        std::unique_ptr<Array> array = util::make_unique<Array>();
        for (const pb::Array_Entry& pbEntry : pbArray.entries()) {
                    std::unique_ptr<Item> item = deserializeItemFromPb(pbEntry.item(), config,
                                                                       pool);
          std::unique_ptr<Item> item =
              deserializeItemFromPb(pbEntry.item(), config, pool);
          if (!item) {
            return {};
          }
@@ -311,8 +320,8 @@ private:
        std::unique_ptr<Plural> plural = util::make_unique<Plural>();
        for (const pb::Plural_Entry& pbEntry : pbPlural.entries()) {
          size_t pluralIdx = deserializePluralEnumFromPb(pbEntry.arity());
                    plural->values[pluralIdx] = deserializeItemFromPb(pbEntry.item(), config,
                                                                      pool);
          plural->values[pluralIdx] =
              deserializeItemFromPb(pbEntry.item(), config, pool);
          if (!plural->values[pluralIdx]) {
            return {};
          }
@@ -337,7 +346,8 @@ private:
    return value;
  }

    bool deserializeReferenceFromPb(const pb::Reference& pbRef, Reference* outRef) {
  bool deserializeReferenceFromPb(const pb::Reference& pbRef,
                                  Reference* outRef) {
    outRef->referenceType = deserializeReferenceTypeFromPb(pbRef.type());
    outRef->privateReference = pbRef.private_();

@@ -350,7 +360,8 @@ private:
    }

    if (pbRef.has_symbol_idx()) {
            const std::string strSymbol = util::getString(*mSymbolPool, pbRef.symbol_idx());
      const std::string strSymbol =
          util::getString(*mSymbolPool, pbRef.symbol_idx());
      ResourceNameRef nameRef;
      if (!ResourceUtils::parseResourceName(strSymbol, &nameRef, nullptr)) {
        mDiag->error(DiagMessage(mSource) << "invalid reference name '"
@@ -386,10 +397,11 @@ private:

}  // namespace

std::unique_ptr<ResourceTable> deserializeTableFromPb(const pb::ResourceTable& pbTable,
                                                      const Source& source,
std::unique_ptr<ResourceTable> deserializeTableFromPb(
    const pb::ResourceTable& pbTable, const Source& source,
    IDiagnostics* diag) {
    // We import the android namespace because on Windows NO_ERROR is a macro, not an enum, which
  // We import the android namespace because on Windows NO_ERROR is a macro, not
  // an enum, which
  // causes errors when qualifying it with android::
  using namespace android;

@@ -428,7 +440,8 @@ std::unique_ptr<ResourceTable> deserializeTableFromPb(const pb::ResourceTable& p
    }
  }

    PackagePbDeserializer packagePbDeserializer(&valuePool, &sourcePool, &symbolPool, source, diag);
  PackagePbDeserializer packagePbDeserializer(&valuePool, &sourcePool,
                                              &symbolPool, source, diag);
  for (const pb::Package& pbPackage : pbTable.packages()) {
    if (!packagePbDeserializer.deserializeFromPb(pbPackage, table.get())) {
      return {};
@@ -437,16 +450,16 @@ std::unique_ptr<ResourceTable> deserializeTableFromPb(const pb::ResourceTable& p
  return table;
}

std::unique_ptr<ResourceFile> deserializeCompiledFileFromPb(const pb::CompiledFile& pbFile,
                                                            const Source& source,
                                                            IDiagnostics* diag) {
std::unique_ptr<ResourceFile> deserializeCompiledFileFromPb(
    const pb::CompiledFile& pbFile, const Source& source, IDiagnostics* diag) {
  std::unique_ptr<ResourceFile> file = util::make_unique<ResourceFile>();

  ResourceNameRef nameRef;

  // Need to create an lvalue here so that nameRef can point to something real.
  if (!ResourceUtils::parseResourceName(pbFile.resource_name(), &nameRef)) {
        diag->error(DiagMessage(source) << "invalid resource name in compiled file header: "
    diag->error(DiagMessage(source)
                << "invalid resource name in compiled file header: "
                << pbFile.resource_name());
    return {};
  }
@@ -455,9 +468,11 @@ std::unique_ptr<ResourceFile> deserializeCompiledFileFromPb(const pb::CompiledFi
  deserializeConfigDescriptionFromPb(pbFile.config(), &file->config);

  for (const pb::CompiledFile_Symbol& pbSymbol : pbFile.exported_symbols()) {
        // Need to create an lvalue here so that nameRef can point to something real.
    // Need to create an lvalue here so that nameRef can point to something
    // real.
    if (!ResourceUtils::parseResourceName(pbSymbol.resource_name(), &nameRef)) {
            diag->error(DiagMessage(source) << "invalid resource name for exported symbol in "
      diag->error(DiagMessage(source)
                  << "invalid resource name for exported symbol in "
                     "compiled file header: "
                  << pbFile.resource_name());
      return {};
+499 −479

File changed.

Preview size limit exceeded, changes collapsed.