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

Commit 27a01ef0 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "AAPT2: Fix up file IO"

parents 4e8da712 06460ef0
Loading
Loading
Loading
Loading
+1 −0
Original line number Original line Diff line number Diff line
@@ -87,6 +87,7 @@ cc_library_host_static {
        "flatten/Archive.cpp",
        "flatten/Archive.cpp",
        "flatten/TableFlattener.cpp",
        "flatten/TableFlattener.cpp",
        "flatten/XmlFlattener.cpp",
        "flatten/XmlFlattener.cpp",
        "io/BigBufferStreams.cpp",
        "io/File.cpp",
        "io/File.cpp",
        "io/FileSystem.cpp",
        "io/FileSystem.cpp",
        "io/Io.cpp",
        "io/Io.cpp",
+10 −15
Original line number Original line Diff line number Diff line
@@ -20,6 +20,7 @@
#include "ValueVisitor.h"
#include "ValueVisitor.h"
#include "flatten/Archive.h"
#include "flatten/Archive.h"
#include "flatten/TableFlattener.h"
#include "flatten/TableFlattener.h"
#include "io/BigBufferInputStream.h"


namespace aapt {
namespace aapt {


@@ -27,8 +28,7 @@ std::unique_ptr<LoadedApk> LoadedApk::LoadApkFromPath(IAaptContext* context,
                                                      const android::StringPiece& path) {
                                                      const android::StringPiece& path) {
  Source source(path);
  Source source(path);
  std::string error;
  std::string error;
  std::unique_ptr<io::ZipFileCollection> apk =
  std::unique_ptr<io::ZipFileCollection> apk = io::ZipFileCollection::Create(path, &error);
      io::ZipFileCollection::Create(path, &error);
  if (!apk) {
  if (!apk) {
    context->GetDiagnostics()->Error(DiagMessage(source) << error);
    context->GetDiagnostics()->Error(DiagMessage(source) << error);
    return {};
    return {};
@@ -36,21 +36,18 @@ std::unique_ptr<LoadedApk> LoadedApk::LoadApkFromPath(IAaptContext* context,


  io::IFile* file = apk->FindFile("resources.arsc");
  io::IFile* file = apk->FindFile("resources.arsc");
  if (!file) {
  if (!file) {
    context->GetDiagnostics()->Error(DiagMessage(source)
    context->GetDiagnostics()->Error(DiagMessage(source) << "no resources.arsc found");
                                     << "no resources.arsc found");
    return {};
    return {};
  }
  }


  std::unique_ptr<io::IData> data = file->OpenAsData();
  std::unique_ptr<io::IData> data = file->OpenAsData();
  if (!data) {
  if (!data) {
    context->GetDiagnostics()->Error(DiagMessage(source)
    context->GetDiagnostics()->Error(DiagMessage(source) << "could not open resources.arsc");
                                     << "could not open resources.arsc");
    return {};
    return {};
  }
  }


  std::unique_ptr<ResourceTable> table = util::make_unique<ResourceTable>();
  std::unique_ptr<ResourceTable> table = util::make_unique<ResourceTable>();
  BinaryResourceParser parser(context, table.get(), source, data->data(),
  BinaryResourceParser parser(context, table.get(), source, data->data(), data->size());
                              data->size());
  if (!parser.Parse()) {
  if (!parser.Parse()) {
    return {};
    return {};
  }
  }
@@ -92,9 +89,9 @@ bool LoadedApk::WriteToArchive(IAaptContext* context, const TableFlattenerOption
      continue;
      continue;
    }
    }


    // The resource table needs to be reserialized since it might have changed.
    // The resource table needs to be re-serialized since it might have changed.
    if (path == "resources.arsc") {
    if (path == "resources.arsc") {
      BigBuffer buffer = BigBuffer(1024);
      BigBuffer buffer(4096);
      // TODO(adamlesinski): How to determine if there were sparse entries (and if to encode
      // TODO(adamlesinski): How to determine if there were sparse entries (and if to encode
      // with sparse entries) b/35389232.
      // with sparse entries) b/35389232.
      TableFlattener flattener(options, &buffer);
      TableFlattener flattener(options, &buffer);
@@ -102,8 +99,8 @@ bool LoadedApk::WriteToArchive(IAaptContext* context, const TableFlattenerOption
        return false;
        return false;
      }
      }


      if (!writer->StartEntry(path, ArchiveEntry::kAlign) || !writer->WriteEntry(buffer) ||
      io::BigBufferInputStream input_stream(&buffer);
          !writer->FinishEntry()) {
      if (!writer->WriteFile(path, ArchiveEntry::kAlign, &input_stream)) {
        context->GetDiagnostics()->Error(DiagMessage()
        context->GetDiagnostics()->Error(DiagMessage()
                                         << "Error when writing file '" << path << "' in APK.");
                                         << "Error when writing file '" << path << "' in APK.");
        return false;
        return false;
@@ -113,14 +110,12 @@ bool LoadedApk::WriteToArchive(IAaptContext* context, const TableFlattenerOption


    std::unique_ptr<io::IData> data = file->OpenAsData();
    std::unique_ptr<io::IData> data = file->OpenAsData();
    uint32_t compression_flags = file->WasCompressed() ? ArchiveEntry::kCompress : 0u;
    uint32_t compression_flags = file->WasCompressed() ? ArchiveEntry::kCompress : 0u;
    if (!writer->StartEntry(path, compression_flags) ||
    if (!writer->WriteFile(path, compression_flags, data.get())) {
        !writer->WriteEntry(data->data(), data->size()) || !writer->FinishEntry()) {
      context->GetDiagnostics()->Error(DiagMessage()
      context->GetDiagnostics()->Error(DiagMessage()
                                       << "Error when writing file '" << path << "' in APK.");
                                       << "Error when writing file '" << path << "' in APK.");
      return false;
      return false;
    }
    }
  }
  }

  return true;
  return true;
}
}


+1 −1
Original line number Original line Diff line number Diff line
@@ -25,7 +25,7 @@ namespace aapt {
static const char* sMajorVersion = "2";
static const char* sMajorVersion = "2";


// Update minor version whenever a feature or flag is added.
// Update minor version whenever a feature or flag is added.
static const char* sMinorVersion = "10";
static const char* sMinorVersion = "11";


int PrintVersion() {
int PrintVersion() {
  std::cerr << "Android Asset Packaging Tool (aapt) " << sMajorVersion << "."
  std::cerr << "Android Asset Packaging Tool (aapt) " << sMajorVersion << "."
+31 −72
Original line number Original line Diff line number Diff line
@@ -37,6 +37,7 @@
#include "compile/XmlIdCollector.h"
#include "compile/XmlIdCollector.h"
#include "flatten/Archive.h"
#include "flatten/Archive.h"
#include "flatten/XmlFlattener.h"
#include "flatten/XmlFlattener.h"
#include "io/BigBufferOutputStream.h"
#include "proto/ProtoSerialize.h"
#include "proto/ProtoSerialize.h"
#include "util/Files.h"
#include "util/Files.h"
#include "util/Maybe.h"
#include "util/Maybe.h"
@@ -46,7 +47,6 @@


using android::StringPiece;
using android::StringPiece;
using google::protobuf::io::CopyingOutputStreamAdaptor;
using google::protobuf::io::CopyingOutputStreamAdaptor;
using google::protobuf::io::ZeroCopyOutputStream;


namespace aapt {
namespace aapt {


@@ -142,10 +142,10 @@ static bool LoadInputFilesFromDir(
    IAaptContext* context, const CompileOptions& options,
    IAaptContext* context, const CompileOptions& options,
    std::vector<ResourcePathData>* out_path_data) {
    std::vector<ResourcePathData>* out_path_data) {
  const std::string& root_dir = options.res_dir.value();
  const std::string& root_dir = options.res_dir.value();
  std::unique_ptr<DIR, decltype(closedir)*> d(opendir(root_dir.data()),
  std::unique_ptr<DIR, decltype(closedir)*> d(opendir(root_dir.data()), closedir);
                                              closedir);
  if (!d) {
  if (!d) {
    context->GetDiagnostics()->Error(DiagMessage() << strerror(errno));
    context->GetDiagnostics()->Error(DiagMessage()
                                     << android::base::SystemErrorCodeToString(errno));
    return false;
    return false;
  }
  }


@@ -161,10 +161,10 @@ static bool LoadInputFilesFromDir(
      continue;
      continue;
    }
    }


    std::unique_ptr<DIR, decltype(closedir)*> subdir(
    std::unique_ptr<DIR, decltype(closedir)*> subdir(opendir(prefix_path.data()), closedir);
        opendir(prefix_path.data()), closedir);
    if (!subdir) {
    if (!subdir) {
      context->GetDiagnostics()->Error(DiagMessage() << strerror(errno));
      context->GetDiagnostics()->Error(DiagMessage()
                                       << android::base::SystemErrorCodeToString(errno));
      return false;
      return false;
    }
    }


@@ -177,8 +177,7 @@ static bool LoadInputFilesFromDir(
      file::AppendPath(&full_path, leaf_entry->d_name);
      file::AppendPath(&full_path, leaf_entry->d_name);


      std::string err_str;
      std::string err_str;
      Maybe<ResourcePathData> path_data =
      Maybe<ResourcePathData> path_data = ExtractResourcePathData(full_path, &err_str);
          ExtractResourcePathData(full_path, &err_str);
      if (!path_data) {
      if (!path_data) {
        context->GetDiagnostics()->Error(DiagMessage() << err_str);
        context->GetDiagnostics()->Error(DiagMessage() << err_str);
        return false;
        return false;
@@ -199,7 +198,7 @@ static bool CompileTable(IAaptContext* context, const CompileOptions& options,
    std::ifstream fin(path_data.source.path, std::ifstream::binary);
    std::ifstream fin(path_data.source.path, std::ifstream::binary);
    if (!fin) {
    if (!fin) {
      context->GetDiagnostics()->Error(DiagMessage(path_data.source)
      context->GetDiagnostics()->Error(DiagMessage(path_data.source)
                                       << strerror(errno));
                                       << android::base::SystemErrorCodeToString(errno));
      return false;
      return false;
    }
    }


@@ -249,8 +248,7 @@ static bool CompileTable(IAaptContext* context, const CompileOptions& options,


  // Create the file/zip entry.
  // Create the file/zip entry.
  if (!writer->StartEntry(output_path, 0)) {
  if (!writer->StartEntry(output_path, 0)) {
    context->GetDiagnostics()->Error(DiagMessage(output_path)
    context->GetDiagnostics()->Error(DiagMessage(output_path) << "failed to open");
                                     << "failed to open");
    return false;
    return false;
  }
  }


@@ -258,21 +256,18 @@ static bool CompileTable(IAaptContext* context, const CompileOptions& options,
  // writer->FinishEntry().
  // writer->FinishEntry().
  {
  {
    // Wrap our IArchiveWriter with an adaptor that implements the
    // Wrap our IArchiveWriter with an adaptor that implements the
    // ZeroCopyOutputStream
    // ZeroCopyOutputStream interface.
    // interface.
    CopyingOutputStreamAdaptor copying_adaptor(writer);
    CopyingOutputStreamAdaptor copying_adaptor(writer);


    std::unique_ptr<pb::ResourceTable> pb_table = SerializeTableToPb(&table);
    std::unique_ptr<pb::ResourceTable> pb_table = SerializeTableToPb(&table);
    if (!pb_table->SerializeToZeroCopyStream(&copying_adaptor)) {
    if (!pb_table->SerializeToZeroCopyStream(&copying_adaptor)) {
      context->GetDiagnostics()->Error(DiagMessage(output_path)
      context->GetDiagnostics()->Error(DiagMessage(output_path) << "failed to write");
                                       << "failed to write");
      return false;
      return false;
    }
    }
  }
  }


  if (!writer->FinishEntry()) {
  if (!writer->FinishEntry()) {
    context->GetDiagnostics()->Error(DiagMessage(output_path)
    context->GetDiagnostics()->Error(DiagMessage(output_path) << "failed to finish entry");
                                     << "failed to finish entry");
    return false;
    return false;
  }
  }
  return true;
  return true;
@@ -293,16 +288,14 @@ static bool WriteHeaderAndBufferToWriter(const StringPiece& output_path,
  // writer->FinishEntry().
  // writer->FinishEntry().
  {
  {
    // Wrap our IArchiveWriter with an adaptor that implements the
    // Wrap our IArchiveWriter with an adaptor that implements the
    // ZeroCopyOutputStream
    // ZeroCopyOutputStream interface.
    // interface.
    CopyingOutputStreamAdaptor copying_adaptor(writer);
    CopyingOutputStreamAdaptor copying_adaptor(writer);
    CompiledFileOutputStream output_stream(&copying_adaptor);
    CompiledFileOutputStream output_stream(&copying_adaptor);


    // Number of CompiledFiles.
    // Number of CompiledFiles.
    output_stream.WriteLittleEndian32(1);
    output_stream.WriteLittleEndian32(1);


    std::unique_ptr<pb::CompiledFile> compiled_file =
    std::unique_ptr<pb::CompiledFile> compiled_file = SerializeCompiledFileToPb(file);
        SerializeCompiledFileToPb(file);
    output_stream.WriteCompiledFile(compiled_file.get());
    output_stream.WriteCompiledFile(compiled_file.get());
    output_stream.WriteData(&buffer);
    output_stream.WriteData(&buffer);


@@ -371,14 +364,12 @@ static bool FlattenXmlToOutStream(IAaptContext* context,
    return false;
    return false;
  }
  }


  std::unique_ptr<pb::CompiledFile> pb_compiled_file =
  std::unique_ptr<pb::CompiledFile> pb_compiled_file = SerializeCompiledFileToPb(xmlres->file);
      SerializeCompiledFileToPb(xmlres->file);
  out->WriteCompiledFile(pb_compiled_file.get());
  out->WriteCompiledFile(pb_compiled_file.get());
  out->WriteData(&buffer);
  out->WriteData(&buffer);


  if (out->HadError()) {
  if (out->HadError()) {
    context->GetDiagnostics()->Error(DiagMessage(output_path)
    context->GetDiagnostics()->Error(DiagMessage(output_path) << "failed to write data");
                                     << "failed to write data");
    return false;
    return false;
  }
  }
  return true;
  return true;
@@ -388,8 +379,7 @@ static bool CompileXml(IAaptContext* context, const CompileOptions& options,
                       const ResourcePathData& path_data,
                       const ResourcePathData& path_data,
                       IArchiveWriter* writer, const std::string& output_path) {
                       IArchiveWriter* writer, const std::string& output_path) {
  if (context->IsVerbose()) {
  if (context->IsVerbose()) {
    context->GetDiagnostics()->Note(DiagMessage(path_data.source)
    context->GetDiagnostics()->Note(DiagMessage(path_data.source) << "compiling XML");
                                    << "compiling XML");
  }
  }


  std::unique_ptr<xml::XmlResource> xmlres;
  std::unique_ptr<xml::XmlResource> xmlres;
@@ -397,7 +387,7 @@ static bool CompileXml(IAaptContext* context, const CompileOptions& options,
    std::ifstream fin(path_data.source.path, std::ifstream::binary);
    std::ifstream fin(path_data.source.path, std::ifstream::binary);
    if (!fin) {
    if (!fin) {
      context->GetDiagnostics()->Error(DiagMessage(path_data.source)
      context->GetDiagnostics()->Error(DiagMessage(path_data.source)
                                       << strerror(errno));
                                       << android::base::SystemErrorCodeToString(errno));
      return false;
      return false;
    }
    }


@@ -470,31 +460,6 @@ static bool CompileXml(IAaptContext* context, const CompileOptions& options,
  return true;
  return true;
}
}


class BigBufferOutputStream : public io::OutputStream {
 public:
  explicit BigBufferOutputStream(BigBuffer* buffer) : buffer_(buffer) {}

  bool Next(void** data, int* len) override {
    size_t count;
    *data = buffer_->NextBlock(&count);
    *len = static_cast<int>(count);
    return true;
  }

  void BackUp(int count) override { buffer_->BackUp(count); }

  google::protobuf::int64 ByteCount() const override {
    return buffer_->size();
  }

  bool HadError() const override { return false; }

 private:
  BigBuffer* buffer_;

  DISALLOW_COPY_AND_ASSIGN(BigBufferOutputStream);
};

static bool CompilePng(IAaptContext* context, const CompileOptions& options,
static bool CompilePng(IAaptContext* context, const CompileOptions& options,
                       const ResourcePathData& path_data,
                       const ResourcePathData& path_data,
                       IArchiveWriter* writer, const std::string& output_path) {
                       IArchiveWriter* writer, const std::string& output_path) {
@@ -520,7 +485,7 @@ static bool CompilePng(IAaptContext* context, const CompileOptions& options,
    }
    }


    BigBuffer crunched_png_buffer(4096);
    BigBuffer crunched_png_buffer(4096);
    BigBufferOutputStream crunched_png_buffer_out(&crunched_png_buffer);
    io::BigBufferOutputStream crunched_png_buffer_out(&crunched_png_buffer);


    // Ensure that we only keep the chunks we care about if we end up
    // Ensure that we only keep the chunks we care about if we end up
    // using the original PNG instead of the crunched one.
    // using the original PNG instead of the crunched one.
@@ -533,8 +498,7 @@ static bool CompilePng(IAaptContext* context, const CompileOptions& options,
    std::unique_ptr<NinePatch> nine_patch;
    std::unique_ptr<NinePatch> nine_patch;
    if (path_data.extension == "9.png") {
    if (path_data.extension == "9.png") {
      std::string err;
      std::string err;
      nine_patch = NinePatch::Create(image->rows.get(), image->width,
      nine_patch = NinePatch::Create(image->rows.get(), image->width, image->height, &err);
                                     image->height, &err);
      if (!nine_patch) {
      if (!nine_patch) {
        context->GetDiagnostics()->Error(DiagMessage() << err);
        context->GetDiagnostics()->Error(DiagMessage() << err);
        return false;
        return false;
@@ -547,8 +511,7 @@ static bool CompilePng(IAaptContext* context, const CompileOptions& options,
      // width - 2.
      // width - 2.
      image->width -= 2;
      image->width -= 2;
      image->height -= 2;
      image->height -= 2;
      memmove(image->rows.get(), image->rows.get() + 1,
      memmove(image->rows.get(), image->rows.get() + 1, image->height * sizeof(uint8_t**));
              image->height * sizeof(uint8_t**));
      for (int32_t h = 0; h < image->height; h++) {
      for (int32_t h = 0; h < image->height; h++) {
        memmove(image->rows[h], image->rows[h] + 4, image->width * 4);
        memmove(image->rows[h], image->rows[h] + 4, image->width * 4);
      }
      }
@@ -560,8 +523,7 @@ static bool CompilePng(IAaptContext* context, const CompileOptions& options,
    }
    }


    // Write the crunched PNG.
    // Write the crunched PNG.
    if (!WritePng(context, image.get(), nine_patch.get(),
    if (!WritePng(context, image.get(), nine_patch.get(), &crunched_png_buffer_out, {})) {
                  &crunched_png_buffer_out, {})) {
      return false;
      return false;
    }
    }


@@ -574,24 +536,21 @@ static bool CompilePng(IAaptContext* context, const CompileOptions& options,
      // The re-encoded PNG is larger than the original, and there is
      // The re-encoded PNG is larger than the original, and there is
      // no mandatory transformation. Use the original.
      // no mandatory transformation. Use the original.
      if (context->IsVerbose()) {
      if (context->IsVerbose()) {
        context->GetDiagnostics()->Note(
        context->GetDiagnostics()->Note(DiagMessage(path_data.source)
            DiagMessage(path_data.source)
                                        << "original PNG is smaller than crunched PNG"
                                        << "original PNG is smaller than crunched PNG"
                                        << ", using original");
                                        << ", using original");
      }
      }


      PngChunkFilter png_chunk_filter_again(content);
      png_chunk_filter.Rewind();
      BigBuffer filtered_png_buffer(4096);
      BigBuffer filtered_png_buffer(4096);
      BigBufferOutputStream filtered_png_buffer_out(&filtered_png_buffer);
      io::BigBufferOutputStream filtered_png_buffer_out(&filtered_png_buffer);
      io::Copy(&filtered_png_buffer_out, &png_chunk_filter_again);
      io::Copy(&filtered_png_buffer_out, &png_chunk_filter);
      buffer.AppendBuffer(std::move(filtered_png_buffer));
      buffer.AppendBuffer(std::move(filtered_png_buffer));
    }
    }


    if (context->IsVerbose()) {
    if (context->IsVerbose()) {
      // For debugging only, use the legacy PNG cruncher and compare the
      // For debugging only, use the legacy PNG cruncher and compare the resulting file sizes.
      // resulting file sizes.
      // This will help catch exotic cases where the new code may generate larger PNGs.
      // This will help catch exotic cases where the new code may generate
      // larger PNGs.
      std::stringstream legacy_stream(content);
      std::stringstream legacy_stream(content);
      BigBuffer legacy_buffer(4096);
      BigBuffer legacy_buffer(4096);
      Png png(context->GetDiagnostics());
      Png png(context->GetDiagnostics());
+0 −1
Original line number Original line Diff line number Diff line
@@ -33,7 +33,6 @@
namespace aapt {
namespace aapt {


constexpr bool kDebug = false;
constexpr bool kDebug = false;
constexpr size_t kPngSignatureSize = 8u;


struct PngInfo {
struct PngInfo {
  ~PngInfo() {
  ~PngInfo() {
Loading