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

Commit 479fa39d authored by Ryan Mitchell's avatar Ryan Mitchell
Browse files

Remove raw values from proto APK

Raw attribute values are not included in xml files when building binary
APKs but they are when building proto APKs. Remove raw attribute values
and create a new convert flag that (--keep-raw-values) that allows raw
value to be kept.

Also added flag to link to keep raw attribute values.

Bug: 115915884
Bug: 116700688
Test: aapt2_tests
Change-Id: Id50136b775b3f43d159ca06181282f6a7b8eaf40
parent d692ddf6
Loading
Loading
Loading
Loading
+5 −1
Original line number Diff line number Diff line
@@ -170,6 +170,7 @@ cc_test_host {
    srcs: [
        "test/Builders.cpp",
        "test/Common.cpp",
        "test/Fixture.cpp",
        "**/*_test.cpp",
    ] + toolSources,
    static_libs: [
@@ -177,7 +178,10 @@ cc_test_host {
        "libgmock",
    ],
    defaults: ["aapt2_defaults"],
    data: ["integration-tests/CompileTest/**/*"],
    data: [
         "integration-tests/CompileTest/**/*",
         "integration-tests/CommandTests/**/*"
    ],
}

// ==========================================================
+17 −12
Original line number Diff line number Diff line
@@ -60,16 +60,17 @@ class IApkSerializer {
class BinaryApkSerializer : public IApkSerializer {
 public:
  BinaryApkSerializer(IAaptContext* context, const Source& source,
                   const TableFlattenerOptions& options)
      : IApkSerializer(context, source), tableFlattenerOptions_(options) {}
                      const TableFlattenerOptions& table_flattener_options,
                      const XmlFlattenerOptions& xml_flattener_options)
      : IApkSerializer(context, source),
        table_flattener_options_(table_flattener_options),
        xml_flattener_options_(xml_flattener_options) {}

  bool SerializeXml(const xml::XmlResource* xml, const std::string& path, bool utf16,
                    IArchiveWriter* writer, uint32_t compression_flags) override {
    BigBuffer buffer(4096);
    XmlFlattenerOptions options = {};
    options.use_utf16 = utf16;
    options.keep_raw_values = true;
    XmlFlattener flattener(&buffer, options);
    xml_flattener_options_.use_utf16 = utf16;
    XmlFlattener flattener(&buffer, xml_flattener_options_);
    if (!flattener.Consume(context_, xml)) {
      return false;
    }
@@ -80,7 +81,7 @@ class BinaryApkSerializer : public IApkSerializer {

  bool SerializeTable(ResourceTable* table, IArchiveWriter* writer) override {
    BigBuffer buffer(4096);
    TableFlattener table_flattener(tableFlattenerOptions_, &buffer);
    TableFlattener table_flattener(table_flattener_options_, &buffer);
    if (!table_flattener.Consume(context_, table)) {
      return false;
    }
@@ -136,7 +137,8 @@ class BinaryApkSerializer : public IApkSerializer {
  }

 private:
  TableFlattenerOptions tableFlattenerOptions_;
  TableFlattenerOptions table_flattener_options_;
  XmlFlattenerOptions xml_flattener_options_;

  DISALLOW_COPY_AND_ASSIGN(BinaryApkSerializer);
};
@@ -252,13 +254,15 @@ class Context : public IAaptContext {
};

int Convert(IAaptContext* context, LoadedApk* apk, IArchiveWriter* output_writer,
            ApkFormat output_format, TableFlattenerOptions& options) {
            ApkFormat output_format, TableFlattenerOptions table_flattener_options,
            XmlFlattenerOptions xml_flattener_options) {
  // Do not change the ordering of strings in the values string pool
  options.sort_stringpool_entries = false;
  table_flattener_options.sort_stringpool_entries = false;

  unique_ptr<IApkSerializer> serializer;
  if (output_format == ApkFormat::kBinary) {
    serializer.reset(new BinaryApkSerializer(context, apk->GetSource(), options));
    serializer.reset(new BinaryApkSerializer(context, apk->GetSource(), table_flattener_options,
                                             xml_flattener_options));
  } else if (output_format == ApkFormat::kProto) {
    serializer.reset(new ProtoApkSerializer(context, apk->GetSource()));
  } else {
@@ -378,7 +382,8 @@ int ConvertCommand::Action(const std::vector<std::string>& args) {
    return 1;
  }

  return Convert(&context, apk.get(), writer.get(), format, options_);
  return Convert(&context, apk.get(), writer.get(), format, table_flattener_options_,
                 xml_flattener_options_);
}

}  // namespace aapt
+11 −4
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@
#include "Command.h"
#include "LoadedApk.h"
#include "format/binary/TableFlattener.h"
#include "format/binary/XmlFlattener.h"

namespace aapt {

@@ -34,7 +35,11 @@ class ConvertCommand : public Command {
    AddOptionalSwitch("--enable-sparse-encoding",
        "Enables encoding sparse entries using a binary search tree.\n"
        "This decreases APK size at the cost of resource retrieval performance.",
        &options_.use_sparse_entries);
         &table_flattener_options_.use_sparse_entries);
    AddOptionalSwitch("--keep-raw-values",
        android::base::StringPrintf("Preserve raw attribute values in xml files when using the"
            " '%s' output format", kOutputFormatBinary),
        &xml_flattener_options_.keep_raw_values);
    AddOptionalSwitch("-v", "Enables verbose logging", &verbose_);
  }

@@ -44,14 +49,16 @@ class ConvertCommand : public Command {
  const static char* kOutputFormatProto;
  const static char* kOutputFormatBinary;

  TableFlattenerOptions options_;
  TableFlattenerOptions table_flattener_options_;
  XmlFlattenerOptions xml_flattener_options_;
  std::string output_path_;
  Maybe<std::string> output_format_;
  bool verbose_ = false;
};

int Convert(IAaptContext* context, LoadedApk* input, IArchiveWriter* output_writer,
            ApkFormat output_format, TableFlattenerOptions& options);
            ApkFormat output_format,TableFlattenerOptions table_flattener_options,
            XmlFlattenerOptions xml_flattener_options);

}  // namespace aapt

+98 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2018 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "Convert.h"

#include "LoadedApk.h"
#include "test/Test.h"

using testing::Eq;
using testing::Ne;

namespace aapt {

using ConvertTest = CommandTestFixture;

TEST_F(ConvertTest, RemoveRawXmlStrings) {
  StdErrDiagnostics diag;
  const std::string compiled_files_dir = GetTestPath("compiled");
  ASSERT_TRUE(CompileFile(GetTestPath("res/xml/test.xml"), R"(<Item AgentCode="007"/>)",
                          compiled_files_dir, &diag));

  const std::string out_apk = GetTestPath("out.apk");
  std::vector<std::string> link_args = {
      "--manifest", GetDefaultManifest(),
      "-o", out_apk,
      "--keep-raw-values",
      "--proto-format"
  };

  ASSERT_TRUE(Link(link_args, compiled_files_dir, &diag));

  const std::string out_convert_apk = GetTestPath("out_convert.apk");
  std::vector<android::StringPiece> convert_args = {
      "-o", out_convert_apk,
      "--output-format", "binary",
      out_apk,
  };
  ASSERT_THAT(ConvertCommand().Execute(convert_args, &std::cerr), Eq(0));

  // Load the binary xml tree
  android::ResXMLTree tree;
  std::unique_ptr<LoadedApk> apk = LoadedApk::LoadApkFromPath(out_convert_apk, &diag);
  AssertLoadXml(apk.get(), "res/xml/test.xml", &tree);

  // Check that the raw string index has not been assigned
  EXPECT_THAT(tree.getAttributeValueStringID(0), Eq(-1));
}

TEST_F(ConvertTest, KeepRawXmlStrings) {
  StdErrDiagnostics diag;
  const std::string compiled_files_dir = GetTestPath("compiled");
  ASSERT_TRUE(CompileFile(GetTestPath("res/xml/test.xml"), R"(<Item AgentCode="007"/>)",
                          compiled_files_dir, &diag));

  const std::string out_apk = GetTestPath("out.apk");
  std::vector<std::string> link_args = {
      "--manifest", GetDefaultManifest(),
      "-o", out_apk,
      "--keep-raw-values",
      "--proto-format"
  };

  ASSERT_TRUE(Link(link_args, compiled_files_dir, &diag));

  const std::string out_convert_apk = GetTestPath("out_convert.apk");
  std::vector<android::StringPiece> convert_args = {
      "-o", out_convert_apk,
      "--output-format", "binary",
      "--keep-raw-values",
      out_apk,
  };
  ASSERT_THAT(ConvertCommand().Execute(convert_args, &std::cerr), Eq(0));

  // Load the binary xml tree
  android::ResXMLTree tree;
  std::unique_ptr<LoadedApk> apk = LoadedApk::LoadApkFromPath(out_convert_apk, &diag);
  AssertLoadXml(apk.get(), "res/xml/test.xml", &tree);

  // Check that the raw string index has been set to the correct string pool entry
  int32_t raw_index = tree.getAttributeValueStringID(0);
  ASSERT_THAT(raw_index, Ne(-1));
  EXPECT_THAT(util::GetString(tree.getStrings(), static_cast<size_t>(raw_index)), Eq("007"));
}

}  // namespace aapt
 No newline at end of file
+2 −1
Original line number Diff line number Diff line
@@ -1545,7 +1545,8 @@ class Linker {
  // 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;
    const bool keep_raw_values = (context_->GetPackageType() == PackageType::kStaticLib)
                                 || options_.keep_raw_values;
    bool result = FlattenXml(context_, *manifest, kAndroidManifestPath, keep_raw_values,
                             true /*utf16*/, options_.output_format, writer);
    if (!result) {
Loading