diff options
29 files changed, 311 insertions, 1 deletions
diff --git a/tools/aapt2/Android.bp b/tools/aapt2/Android.bp index bc3a9a1c88c8..8bef221fe5ed 100644 --- a/tools/aapt2/Android.bp +++ b/tools/aapt2/Android.bp @@ -141,6 +141,7 @@ cc_library_host_static { "ResourceValues.cpp", "SdkConstants.cpp", "StringPool.cpp", + "trace/TraceBuffer.cpp", "xml/XmlActionExecutor.cpp", "xml/XmlDom.cpp", "xml/XmlPullParser.cpp", diff --git a/tools/aapt2/Main.cpp b/tools/aapt2/Main.cpp index adf85b0ea8e8..39eb9879f86d 100644 --- a/tools/aapt2/Main.cpp +++ b/tools/aapt2/Main.cpp @@ -37,6 +37,7 @@ #include "cmd/Link.h" #include "cmd/Optimize.h" #include "io/FileStream.h" +#include "trace/TraceBuffer.h" #include "util/Files.h" #include "util/Util.h" @@ -107,9 +108,12 @@ class DaemonCommand : public Command { : Command("daemon", "m"), out_(out), diagnostics_(diagnostics) { SetDescription("Runs aapt in daemon mode. Each subsequent line is a single parameter to the\n" "command. The end of an invocation is signaled by providing an empty line."); + AddOptionalFlag("--trace_folder", "Generate systrace json trace fragment to specified folder.", + &trace_folder_); } - int Action(const std::vector<std::string>& /* args */) override { + int Action(const std::vector<std::string>& arguments) override { + TRACE_FLUSH_ARGS(trace_folder_ ? trace_folder_.value() : "", "daemon", arguments); text::Printer printer(out_); std::cout << "Ready" << std::endl; @@ -150,6 +154,7 @@ class DaemonCommand : public Command { private: io::FileOutputStream* out_; IDiagnostics* diagnostics_; + Maybe<std::string> trace_folder_; }; } // namespace aapt diff --git a/tools/aapt2/ResourceTable.cpp b/tools/aapt2/ResourceTable.cpp index dbd0a0ca1799..7c0619f33851 100644 --- a/tools/aapt2/ResourceTable.cpp +++ b/tools/aapt2/ResourceTable.cpp @@ -30,6 +30,7 @@ #include "NameMangler.h" #include "ResourceValues.h" #include "ValueVisitor.h" +#include "trace/TraceBuffer.h" #include "text/Unicode.h" #include "util/Util.h" @@ -79,6 +80,7 @@ ResourceTablePackage* ResourceTable::FindPackageById(uint8_t id) const { } ResourceTablePackage* ResourceTable::CreatePackage(const StringPiece& name, Maybe<uint8_t> id) { + TRACE_CALL(); ResourceTablePackage* package = FindOrCreatePackage(name); if (id && !package->id) { package->id = id; diff --git a/tools/aapt2/cmd/Command.cpp b/tools/aapt2/cmd/Command.cpp index 4424a357c1dd..919b4c98fa8f 100644 --- a/tools/aapt2/cmd/Command.cpp +++ b/tools/aapt2/cmd/Command.cpp @@ -25,6 +25,7 @@ #include "android-base/utf8.h" #include "androidfw/StringPiece.h" +#include "trace/TraceBuffer.h" #include "util/Util.h" using android::base::StringPrintf; @@ -178,6 +179,7 @@ void Command::Usage(std::ostream* out) { } int Command::Execute(const std::vector<StringPiece>& args, std::ostream* out_error) { + TRACE_NAME_ARGS("Command::Execute", args); std::vector<std::string> file_args; for (size_t i = 0; i < args.size(); i++) { diff --git a/tools/aapt2/cmd/Compile.cpp b/tools/aapt2/cmd/Compile.cpp index bec6c6973613..42dc74c6db55 100644 --- a/tools/aapt2/cmd/Compile.cpp +++ b/tools/aapt2/cmd/Compile.cpp @@ -45,6 +45,7 @@ #include "io/StringStream.h" #include "io/Util.h" #include "io/ZipArchive.h" +#include "trace/TraceBuffer.h" #include "util/Files.h" #include "util/Maybe.h" #include "util/Util.h" @@ -141,6 +142,7 @@ static std::string BuildIntermediateContainerFilename(const ResourcePathData& da static bool CompileTable(IAaptContext* context, const CompileOptions& options, const ResourcePathData& path_data, io::IFile* file, IArchiveWriter* writer, const std::string& output_path) { + TRACE_CALL(); ResourceTable table; { auto fin = file->OpenInputStream(); @@ -286,6 +288,7 @@ static bool CompileTable(IAaptContext* context, const CompileOptions& options, static bool WriteHeaderAndDataToWriter(const StringPiece& output_path, const ResourceFile& file, io::KnownSizeInputStream* in, IArchiveWriter* writer, IDiagnostics* diag) { + TRACE_CALL(); // Start the entry so we can write the header. if (!writer->StartEntry(output_path, 0)) { diag->Error(DiagMessage(output_path) << "failed to open file"); @@ -352,6 +355,7 @@ static bool IsValidFile(IAaptContext* context, const std::string& input_path) { static bool CompileXml(IAaptContext* context, const CompileOptions& options, const ResourcePathData& path_data, io::IFile* file, IArchiveWriter* writer, const std::string& output_path) { + TRACE_CALL(); if (context->IsVerbose()) { context->GetDiagnostics()->Note(DiagMessage(path_data.source) << "compiling XML"); } @@ -451,6 +455,7 @@ static bool CompileXml(IAaptContext* context, const CompileOptions& options, static bool CompilePng(IAaptContext* context, const CompileOptions& options, const ResourcePathData& path_data, io::IFile* file, IArchiveWriter* writer, const std::string& output_path) { + TRACE_CALL(); if (context->IsVerbose()) { context->GetDiagnostics()->Note(DiagMessage(path_data.source) << "compiling PNG"); } @@ -558,6 +563,7 @@ static bool CompilePng(IAaptContext* context, const CompileOptions& options, static bool CompileFile(IAaptContext* context, const CompileOptions& options, const ResourcePathData& path_data, io::IFile* file, IArchiveWriter* writer, const std::string& output_path) { + TRACE_CALL(); if (context->IsVerbose()) { context->GetDiagnostics()->Note(DiagMessage(path_data.source) << "compiling file"); } @@ -632,6 +638,7 @@ class CompileContext : public IAaptContext { int Compile(IAaptContext* context, io::IFileCollection* inputs, IArchiveWriter* output_writer, CompileOptions& options) { + TRACE_CALL(); bool error = false; // Iterate over the input files in a stable, platform-independent manner @@ -707,6 +714,7 @@ int Compile(IAaptContext* context, io::IFileCollection* inputs, IArchiveWriter* } int CompileCommand::Action(const std::vector<std::string>& args) { + TRACE_FLUSH(trace_folder_? trace_folder_.value() : "", "CompileCommand::Action"); CompileContext context(diagnostic_); context.SetVerbose(options_.verbose); diff --git a/tools/aapt2/cmd/Compile.h b/tools/aapt2/cmd/Compile.h index 9b32cb3750a5..d3456b25da9a 100644 --- a/tools/aapt2/cmd/Compile.h +++ b/tools/aapt2/cmd/Compile.h @@ -60,6 +60,8 @@ class CompileCommand : public Command { "Sets the visibility of the compiled resources to the specified\n" "level. Accepted levels: public, private, default", &visibility_); AddOptionalSwitch("-v", "Enables verbose logging", &options_.verbose); + AddOptionalFlag("--trace-folder", "Generate systrace json trace fragment to specified folder.", + &trace_folder_); } int Action(const std::vector<std::string>& args) override; @@ -68,6 +70,7 @@ class CompileCommand : public Command { IDiagnostics* diagnostic_; CompileOptions options_; Maybe<std::string> visibility_; + Maybe<std::string> trace_folder_; }; int Compile(IAaptContext* context, io::IFileCollection* inputs, IArchiveWriter* output_writer, diff --git a/tools/aapt2/cmd/Link.cpp b/tools/aapt2/cmd/Link.cpp index a7b8d2535e79..f354bb610224 100644 --- a/tools/aapt2/cmd/Link.cpp +++ b/tools/aapt2/cmd/Link.cpp @@ -67,6 +67,7 @@ #include "process/IResourceTableConsumer.h" #include "process/SymbolTable.h" #include "split/TableSplitter.h" +#include "trace/TraceBuffer.h" #include "util/Files.h" #include "xml/XmlDom.h" @@ -213,6 +214,7 @@ class FeatureSplitSymbolTableDelegate : public DefaultSymbolTableDelegate { static bool FlattenXml(IAaptContext* context, const xml::XmlResource& xml_res, const StringPiece& path, bool keep_raw_values, bool utf16, OutputFormat format, IArchiveWriter* writer) { + TRACE_CALL(); if (context->IsVerbose()) { context->GetDiagnostics()->Note(DiagMessage(path) << "writing to archive (keep_raw_values=" << (keep_raw_values ? "true" : "false") @@ -250,6 +252,7 @@ static bool FlattenXml(IAaptContext* context, const xml::XmlResource& xml_res, // Inflates an XML file from the source path. static std::unique_ptr<xml::XmlResource> LoadXml(const std::string& path, IDiagnostics* diag) { + TRACE_CALL(); FileInputStream fin(path); if (fin.HadError()) { diag->Error(DiagMessage(path) << "failed to load XML file: " << fin.GetError()); @@ -421,6 +424,7 @@ std::vector<T> make_singleton_vec(T&& val) { std::vector<std::unique_ptr<xml::XmlResource>> ResourceFileFlattener::LinkAndVersionXmlFile( ResourceTable* table, FileOperation* file_op) { + TRACE_CALL(); xml::XmlResource* doc = file_op->xml_to_flatten.get(); const Source& src = doc->file.source; @@ -489,6 +493,7 @@ static auto kDrawableVersions = std::map<std::string, ApiVersion>{ }; bool ResourceFileFlattener::Flatten(ResourceTable* table, IArchiveWriter* archive_writer) { + TRACE_CALL(); bool error = false; std::map<std::pair<ConfigDescription, StringPiece>, FileOperation> config_sorted_files; @@ -806,6 +811,7 @@ class Linker { // Creates a SymbolTable that loads symbols from the various APKs. // Pre-condition: context_->GetCompilationPackage() needs to be set. bool LoadSymbolsFromIncludePaths() { + TRACE_NAME("LoadSymbolsFromIncludePaths: #" + std::to_string(options_.include_paths.size())); auto asset_source = util::make_unique<AssetManagerSymbolSource>(); for (const std::string& path : options_.include_paths) { if (context_->IsVerbose()) { @@ -891,6 +897,7 @@ class Linker { } Maybe<AppInfo> ExtractAppInfoFromManifest(xml::XmlResource* xml_res, IDiagnostics* diag) { + TRACE_CALL(); // Make sure the first element is <manifest> with package attribute. xml::Element* manifest_el = xml::FindRootElement(xml_res->root.get()); if (manifest_el == nullptr) { @@ -1041,6 +1048,7 @@ class Linker { } bool FlattenTable(ResourceTable* table, OutputFormat format, IArchiveWriter* writer) { + TRACE_CALL(); switch (format) { case OutputFormat::kApk: { BigBuffer buffer(1024); @@ -1114,6 +1122,7 @@ class Linker { } bool GenerateJavaClasses() { + TRACE_CALL(); // The set of packages whose R class to call in the main classes onResourcesLoaded callback. std::vector<std::string> packages_to_callback; @@ -1197,6 +1206,7 @@ class Linker { } bool WriteManifestJavaFile(xml::XmlResource* manifest_xml) { + TRACE_CALL(); if (!options_.generate_java_class_path) { return true; } @@ -1254,6 +1264,7 @@ class Linker { } bool WriteProguardFile(const Maybe<std::string>& out, const proguard::KeepSet& keep_set) { + TRACE_CALL(); if (!out) { return true; } @@ -1278,6 +1289,7 @@ class Linker { } bool MergeStaticLibrary(const std::string& input, bool override) { + TRACE_CALL(); if (context_->IsVerbose()) { context_->GetDiagnostics()->Note(DiagMessage() << "merging static library " << input); } @@ -1328,6 +1340,7 @@ class Linker { bool MergeExportedSymbols(const Source& source, const std::vector<SourcedResourceName>& exported_symbols) { + TRACE_CALL(); // Add the exports of this file to the table. for (const SourcedResourceName& exported_symbol : exported_symbols) { ResourceName res_name = exported_symbol.name; @@ -1353,6 +1366,7 @@ class Linker { } bool MergeCompiledFile(const ResourceFile& compiled_file, io::IFile* file, bool override) { + TRACE_CALL(); if (context_->IsVerbose()) { context_->GetDiagnostics()->Note(DiagMessage() << "merging '" << compiled_file.name @@ -1371,6 +1385,7 @@ class Linker { // An io::IFileCollection is created from the ZIP file and added to the set of // io::IFileCollections that are open. bool MergeArchive(const std::string& input, bool override) { + TRACE_CALL(); if (context_->IsVerbose()) { context_->GetDiagnostics()->Note(DiagMessage() << "merging archive " << input); } @@ -1418,6 +1433,7 @@ class Linker { // All other file types are ignored. This is because these files could be coming from a zip, // where we could have other files like classes.dex. bool MergeFile(io::IFile* file, bool override) { + TRACE_CALL(); const Source& src = file->GetSource(); if (util::EndsWith(src.path, ".xml") || util::EndsWith(src.path, ".png")) { @@ -1458,6 +1474,7 @@ class Linker { while ((entry = reader.Next()) != nullptr) { if (entry->Type() == ContainerEntryType::kResTable) { + TRACE_NAME(std::string("Process ResTable:") + file->GetSource().path); pb::ResourceTable pb_table; if (!entry->GetResTable(&pb_table)) { context_->GetDiagnostics()->Error(DiagMessage(src) << "failed to read resource table: " @@ -1478,6 +1495,7 @@ class Linker { return false; } } else if (entry->Type() == ContainerEntryType::kResFile) { + TRACE_NAME(std::string("Process ResFile") + file->GetSource().path); pb::internal::CompiledFile pb_compiled_file; off64_t offset; size_t len; @@ -1551,6 +1569,7 @@ class Linker { // to the IArchiveWriter. bool WriteApk(IArchiveWriter* writer, proguard::KeepSet* keep_set, xml::XmlResource* manifest, ResourceTable* table) { + TRACE_CALL(); const bool keep_raw_values = (context_->GetPackageType() == PackageType::kStaticLib) || options_.keep_raw_values; bool result = FlattenXml(context_, *manifest, kAndroidManifestPath, keep_raw_values, @@ -1632,6 +1651,7 @@ class Linker { } int Run(const std::vector<std::string>& input_files) { + TRACE_CALL(); // Load the AndroidManifest.xml std::unique_ptr<xml::XmlResource> manifest_xml = LoadXml(options_.manifest_path, context_->GetDiagnostics()); @@ -1839,6 +1859,7 @@ class Linker { std::vector<ConfigDescription> excluded_configs; for (auto& config_string : options_.exclude_configs_) { + TRACE_NAME("ConfigDescription::Parse"); ConfigDescription config_description; if (!ConfigDescription::Parse(config_string, &config_description)) { @@ -2038,6 +2059,7 @@ class Linker { }; int LinkCommand::Action(const std::vector<std::string>& args) { + TRACE_FLUSH(trace_folder_ ? trace_folder_.value() : "", "LinkCommand::Action"); LinkContext context(diag_); // Expand all argument-files passed into the command line. These start with '@'. diff --git a/tools/aapt2/cmd/Link.h b/tools/aapt2/cmd/Link.h index 1fc149ab41af..7c583858ee1d 100644 --- a/tools/aapt2/cmd/Link.h +++ b/tools/aapt2/cmd/Link.h @@ -25,6 +25,7 @@ #include "split/TableSplitter.h" #include "format/binary/TableFlattener.h" #include "link/ManifestFixer.h" +#include "trace/TraceBuffer.h" namespace aapt { @@ -277,6 +278,8 @@ class LinkCommand : public Command { "Do not allow overlays with different visibility levels.", &options_.strict_visibility); AddOptionalSwitch("-v", "Enables verbose logging.", &verbose_); + AddOptionalFlag("--trace-folder", "Generate systrace json trace fragment to specified folder.", + &trace_folder_); } int Action(const std::vector<std::string>& args) override; @@ -300,6 +303,7 @@ class LinkCommand : public Command { bool proto_format_ = false; Maybe<std::string> stable_id_file_path_; std::vector<std::string> split_args_; + Maybe<std::string> trace_folder_; }; }// namespace aapt diff --git a/tools/aapt2/compile/Png.cpp b/tools/aapt2/compile/Png.cpp index 33122dccb7de..d396d81d699a 100644 --- a/tools/aapt2/compile/Png.cpp +++ b/tools/aapt2/compile/Png.cpp @@ -27,6 +27,7 @@ #include "androidfw/ResourceTypes.h" #include "Source.h" +#include "trace/TraceBuffer.h" #include "util/BigBuffer.h" #include "util/Util.h" @@ -1233,6 +1234,7 @@ getout: bool Png::process(const Source& source, std::istream* input, BigBuffer* outBuffer, const PngOptions& options) { + TRACE_CALL(); png_byte signature[kPngSignatureSize]; // Read the PNG signature first. diff --git a/tools/aapt2/compile/PngCrunch.cpp b/tools/aapt2/compile/PngCrunch.cpp index 0346a1982d8a..1f4ea44d9f86 100644 --- a/tools/aapt2/compile/PngCrunch.cpp +++ b/tools/aapt2/compile/PngCrunch.cpp @@ -27,6 +27,8 @@ #include "android-base/logging.h" #include "android-base/macros.h" +#include "trace/TraceBuffer.h" + namespace aapt { // Custom deleter that destroys libpng read and info structs. @@ -142,6 +144,7 @@ static void WriteDataToStream(png_structp png_ptr, png_bytep buffer, png_size_t } std::unique_ptr<Image> ReadPng(IAaptContext* context, const Source& source, io::InputStream* in) { + TRACE_CALL(); // Create a diagnostics that has the source information encoded. SourcePathDiagnostics source_diag(source, context->GetDiagnostics()); @@ -480,6 +483,7 @@ static void WriteNinePatch(png_structp write_ptr, png_infop write_info_ptr, bool WritePng(IAaptContext* context, const Image* image, const NinePatch* nine_patch, io::OutputStream* out, const PngOptions& options) { + TRACE_CALL(); // Create and initialize the write png_struct with the default error and // warning handlers. // The header version is also passed in to ensure that this was built against the same diff --git a/tools/aapt2/compile/XmlIdCollector.cpp b/tools/aapt2/compile/XmlIdCollector.cpp index 2199d003bccb..50541152f802 100644 --- a/tools/aapt2/compile/XmlIdCollector.cpp +++ b/tools/aapt2/compile/XmlIdCollector.cpp @@ -22,6 +22,7 @@ #include "ResourceUtils.h" #include "ResourceValues.h" #include "text/Unicode.h" +#include "trace/TraceBuffer.h" #include "xml/XmlDom.h" namespace aapt { @@ -72,6 +73,7 @@ struct IdCollector : public xml::Visitor { } // namespace bool XmlIdCollector::Consume(IAaptContext* context, xml::XmlResource* xmlRes) { + TRACE_CALL(); xmlRes->file.exported_symbols.clear(); SourcePathDiagnostics source_diag(xmlRes->file.source, context->GetDiagnostics()); IdCollector collector(&xmlRes->file.exported_symbols, &source_diag); diff --git a/tools/aapt2/format/Container.cpp b/tools/aapt2/format/Container.cpp index d4b45717e015..f1890488276c 100644 --- a/tools/aapt2/format/Container.cpp +++ b/tools/aapt2/format/Container.cpp @@ -19,6 +19,8 @@ #include "android-base/scopeguard.h" #include "android-base/stringprintf.h" +#include "trace/TraceBuffer.h" + using ::android::base::StringPrintf; using ::google::protobuf::io::CodedInputStream; using ::google::protobuf::io::CodedOutputStream; @@ -171,6 +173,7 @@ ContainerEntryType ContainerReaderEntry::Type() const { } bool ContainerReaderEntry::GetResTable(pb::ResourceTable* out_table) { + TRACE_CALL(); CHECK(type_ == ContainerEntryType::kResTable) << "reading a kResTable when the type is kResFile"; if (length_ > std::numeric_limits<int>::max()) { reader_->error_ = StringPrintf("entry length %zu is too large", length_); @@ -261,6 +264,7 @@ ContainerReader::ContainerReader(io::InputStream* in) total_entry_count_(0u), current_entry_count_(0u), entry_(this) { + TRACE_CALL(); ::google::protobuf::uint32 magic; if (!coded_in_.ReadLittleEndian32(&magic)) { std::ostringstream error; diff --git a/tools/aapt2/format/binary/TableFlattener.cpp b/tools/aapt2/format/binary/TableFlattener.cpp index d677317dc98d..aa578a2a6ff4 100644 --- a/tools/aapt2/format/binary/TableFlattener.cpp +++ b/tools/aapt2/format/binary/TableFlattener.cpp @@ -32,6 +32,7 @@ #include "ValueVisitor.h" #include "format/binary/ChunkWriter.h" #include "format/binary/ResourceTypeExtensions.h" +#include "trace/TraceBuffer.h" #include "util/BigBuffer.h" using namespace android; @@ -238,6 +239,7 @@ class PackageFlattener { } bool FlattenPackage(BigBuffer* buffer) { + TRACE_CALL(); ChunkWriter pkg_writer(buffer); ResTable_package* pkg_header = pkg_writer.StartChunk<ResTable_package>(RES_TABLE_PACKAGE_TYPE); pkg_header->id = util::HostToDevice32(package_->id.value()); @@ -710,6 +712,7 @@ class PackageFlattener { } // namespace bool TableFlattener::Consume(IAaptContext* context, ResourceTable* table) { + TRACE_CALL(); // We must do this before writing the resources, since the string pool IDs may change. table->string_pool.Prune(); table->string_pool.Sort([](const StringPool::Context& a, const StringPool::Context& b) -> int { diff --git a/tools/aapt2/io/Util.cpp b/tools/aapt2/io/Util.cpp index 97516322c4cb..ce6d9352180d 100644 --- a/tools/aapt2/io/Util.cpp +++ b/tools/aapt2/io/Util.cpp @@ -18,6 +18,8 @@ #include "google/protobuf/io/zero_copy_stream_impl_lite.h" +#include "trace/TraceBuffer.h" + using ::android::StringPiece; using ::google::protobuf::io::ZeroCopyOutputStream; @@ -26,6 +28,7 @@ namespace io { bool CopyInputStreamToArchive(IAaptContext* context, InputStream* in, const std::string& out_path, uint32_t compression_flags, IArchiveWriter* writer) { + TRACE_CALL(); if (context->IsVerbose()) { context->GetDiagnostics()->Note(DiagMessage() << "writing " << out_path << " to archive"); } @@ -40,6 +43,7 @@ bool CopyInputStreamToArchive(IAaptContext* context, InputStream* in, const std: bool CopyFileToArchive(IAaptContext* context, io::IFile* file, const std::string& out_path, uint32_t compression_flags, IArchiveWriter* writer) { + TRACE_CALL(); std::unique_ptr<io::IData> data = file->OpenAsData(); if (!data) { context->GetDiagnostics()->Error(DiagMessage(file->GetSource()) << "failed to open file"); @@ -57,6 +61,7 @@ bool CopyFileToArchivePreserveCompression(IAaptContext* context, io::IFile* file bool CopyProtoToArchive(IAaptContext* context, ::google::protobuf::MessageLite* proto_msg, const std::string& out_path, uint32_t compression_flags, IArchiveWriter* writer) { + TRACE_CALL(); if (context->IsVerbose()) { context->GetDiagnostics()->Note(DiagMessage() << "writing " << out_path << " to archive"); } @@ -83,6 +88,7 @@ bool CopyProtoToArchive(IAaptContext* context, ::google::protobuf::MessageLite* } bool Copy(OutputStream* out, InputStream* in) { + TRACE_CALL(); const void* in_buffer; size_t in_len; while (in->Next(&in_buffer, &in_len)) { diff --git a/tools/aapt2/io/ZipArchive.cpp b/tools/aapt2/io/ZipArchive.cpp index 427dc92505d4..f6aaa1280a61 100644 --- a/tools/aapt2/io/ZipArchive.cpp +++ b/tools/aapt2/io/ZipArchive.cpp @@ -20,6 +20,7 @@ #include "ziparchive/zip_archive.h" #include "Source.h" +#include "trace/TraceBuffer.h" #include "util/Files.h" #include "util/Util.h" @@ -93,6 +94,7 @@ ZipFileCollection::ZipFileCollection() : handle_(nullptr) {} std::unique_ptr<ZipFileCollection> ZipFileCollection::Create( const StringPiece& path, std::string* out_error) { + TRACE_CALL(); constexpr static const int32_t kEmptyArchive = -6; std::unique_ptr<ZipFileCollection> collection = diff --git a/tools/aapt2/link/AutoVersioner.cpp b/tools/aapt2/link/AutoVersioner.cpp index 960c7d46cc98..73b92542a755 100644 --- a/tools/aapt2/link/AutoVersioner.cpp +++ b/tools/aapt2/link/AutoVersioner.cpp @@ -23,6 +23,7 @@ #include "ResourceTable.h" #include "SdkConstants.h" #include "ValueVisitor.h" +#include "trace/TraceBuffer.h" using android::ConfigDescription; @@ -70,6 +71,7 @@ ApiVersion FindNextApiVersionForConfig(const ResourceEntry* entry, } bool AutoVersioner::Consume(IAaptContext* context, ResourceTable* table) { + TRACE_NAME("AutoVersioner::Consume"); for (auto& package : table->packages) { for (auto& type : package->types) { if (type->type != ResourceType::kStyle) { diff --git a/tools/aapt2/link/ManifestFixer.cpp b/tools/aapt2/link/ManifestFixer.cpp index 582a5b869c65..b0a2055cafc8 100644 --- a/tools/aapt2/link/ManifestFixer.cpp +++ b/tools/aapt2/link/ManifestFixer.cpp @@ -21,6 +21,7 @@ #include "android-base/logging.h" #include "ResourceUtils.h" +#include "trace/TraceBuffer.h" #include "util/Util.h" #include "xml/XmlActionExecutor.h" #include "xml/XmlDom.h" @@ -451,6 +452,7 @@ static bool RenameManifestPackage(const StringPiece& package_override, xml::Elem } bool ManifestFixer::Consume(IAaptContext* context, xml::XmlResource* doc) { + TRACE_CALL(); xml::Element* root = xml::FindRootElement(doc->root.get()); if (!root || !root->namespace_uri.empty() || root->name != "manifest") { context->GetDiagnostics()->Error(DiagMessage(doc->file.source) diff --git a/tools/aapt2/link/ProductFilter.cpp b/tools/aapt2/link/ProductFilter.cpp index c1a95ee1bcec..793740af3021 100644 --- a/tools/aapt2/link/ProductFilter.cpp +++ b/tools/aapt2/link/ProductFilter.cpp @@ -17,6 +17,7 @@ #include "link/Linkers.h" #include "ResourceTable.h" +#include "trace/TraceBuffer.h" namespace aapt { @@ -81,6 +82,7 @@ ProductFilter::ResourceConfigValueIter ProductFilter::SelectProductToKeep( } bool ProductFilter::Consume(IAaptContext* context, ResourceTable* table) { + TRACE_NAME("ProductFilter::Consume"); bool error = false; for (auto& pkg : table->packages) { for (auto& type : pkg->types) { diff --git a/tools/aapt2/link/ReferenceLinker.cpp b/tools/aapt2/link/ReferenceLinker.cpp index c2340ba65e38..28f09aa48365 100644 --- a/tools/aapt2/link/ReferenceLinker.cpp +++ b/tools/aapt2/link/ReferenceLinker.cpp @@ -27,6 +27,7 @@ #include "link/Linkers.h" #include "process/IResourceTableConsumer.h" #include "process/SymbolTable.h" +#include "trace/TraceBuffer.h" #include "util/Util.h" #include "xml/XmlUtil.h" @@ -353,6 +354,7 @@ bool ReferenceLinker::LinkReference(const CallSite& callsite, Reference* referen } bool ReferenceLinker::Consume(IAaptContext* context, ResourceTable* table) { + TRACE_NAME("ReferenceLinker::Consume"); EmptyDeclStack decl_stack; bool error = false; for (auto& package : table->packages) { diff --git a/tools/aapt2/link/ResourceExcluder.cpp b/tools/aapt2/link/ResourceExcluder.cpp index 2555995dfc8e..b3b9dc47fd84 100644 --- a/tools/aapt2/link/ResourceExcluder.cpp +++ b/tools/aapt2/link/ResourceExcluder.cpp @@ -20,6 +20,7 @@ #include "DominatorTree.h" #include "ResourceTable.h" +#include "trace/TraceBuffer.h" using android::ConfigDescription; @@ -65,6 +66,7 @@ void RemoveIfExcluded(std::set<std::pair<ConfigDescription, int>>& excluded_conf } // namespace bool ResourceExcluder::Consume(IAaptContext* context, ResourceTable* table) { + TRACE_NAME("ResourceExcluder::Consume"); for (auto& package : table->packages) { for (auto& type : package->types) { for (auto& entry : type->entries) { diff --git a/tools/aapt2/link/TableMerger.cpp b/tools/aapt2/link/TableMerger.cpp index cc9fed554350..e9375176f26b 100644 --- a/tools/aapt2/link/TableMerger.cpp +++ b/tools/aapt2/link/TableMerger.cpp @@ -21,6 +21,7 @@ #include "ResourceTable.h" #include "ResourceUtils.h" #include "ResourceValues.h" +#include "trace/TraceBuffer.h" #include "ValueVisitor.h" #include "util/Util.h" @@ -38,6 +39,7 @@ TableMerger::TableMerger(IAaptContext* context, ResourceTable* out_table, } bool TableMerger::Merge(const Source& src, ResourceTable* table, bool overlay) { + TRACE_CALL(); // We allow adding new resources if this is not an overlay, or if the options allow overlays // to add new resources. return MergeImpl(src, table, overlay, options_.auto_add_overlay || !overlay /*allow_new*/); diff --git a/tools/aapt2/link/XmlReferenceLinker.cpp b/tools/aapt2/link/XmlReferenceLinker.cpp index 160ff925f6cc..d68f7dd44c9f 100644 --- a/tools/aapt2/link/XmlReferenceLinker.cpp +++ b/tools/aapt2/link/XmlReferenceLinker.cpp @@ -25,6 +25,7 @@ #include "link/ReferenceLinker.h" #include "process/IResourceTableConsumer.h" #include "process/SymbolTable.h" +#include "trace/TraceBuffer.h" #include "util/Util.h" #include "xml/XmlDom.h" @@ -151,6 +152,7 @@ class XmlVisitor : public xml::PackageAwareVisitor { } // namespace bool XmlReferenceLinker::Consume(IAaptContext* context, xml::XmlResource* resource) { + TRACE_NAME("XmlReferenceLinker::Consume"); CallSite callsite{resource->file.name.package}; std::string out_name = resource->file.name.entry; diff --git a/tools/aapt2/optimize/ResourceDeduper.cpp b/tools/aapt2/optimize/ResourceDeduper.cpp index ee2dfbce7c06..78ebcb97b811 100644 --- a/tools/aapt2/optimize/ResourceDeduper.cpp +++ b/tools/aapt2/optimize/ResourceDeduper.cpp @@ -20,6 +20,7 @@ #include "DominatorTree.h" #include "ResourceTable.h" +#include "trace/TraceBuffer.h" using android::ConfigDescription; @@ -110,6 +111,7 @@ static void DedupeEntry(IAaptContext* context, ResourceEntry* entry) { } // namespace bool ResourceDeduper::Consume(IAaptContext* context, ResourceTable* table) { + TRACE_CALL(); for (auto& package : table->packages) { for (auto& type : package->types) { for (auto& entry : type->entries) { diff --git a/tools/aapt2/optimize/VersionCollapser.cpp b/tools/aapt2/optimize/VersionCollapser.cpp index f9856047ac40..cd791bda250b 100644 --- a/tools/aapt2/optimize/VersionCollapser.cpp +++ b/tools/aapt2/optimize/VersionCollapser.cpp @@ -20,6 +20,7 @@ #include <vector> #include "ResourceTable.h" +#include "trace/TraceBuffer.h" using android::ConfigDescription; @@ -144,6 +145,7 @@ static void CollapseVersions(int min_sdk, ResourceEntry* entry) { } bool VersionCollapser::Consume(IAaptContext* context, ResourceTable* table) { + TRACE_NAME("VersionCollapser::Consume"); const int min_sdk = context->GetMinSdkVersion(); for (auto& package : table->packages) { for (auto& type : package->types) { diff --git a/tools/aapt2/process/SymbolTable.cpp b/tools/aapt2/process/SymbolTable.cpp index 78e00746f6cb..61a8fbbb7f52 100644 --- a/tools/aapt2/process/SymbolTable.cpp +++ b/tools/aapt2/process/SymbolTable.cpp @@ -30,6 +30,7 @@ #include "Resource.h" #include "ResourceUtils.h" #include "ValueVisitor.h" +#include "trace/TraceBuffer.h" #include "util/Util.h" using ::android::ApkAssets; @@ -217,6 +218,7 @@ std::unique_ptr<SymbolTable::Symbol> ResourceTableSymbolSource::FindByName( } bool AssetManagerSymbolSource::AddAssetPath(const StringPiece& path) { + TRACE_CALL(); if (std::unique_ptr<const ApkAssets> apk = ApkAssets::Load(path.data())) { apk_assets_.push_back(std::move(apk)); @@ -233,6 +235,7 @@ bool AssetManagerSymbolSource::AddAssetPath(const StringPiece& path) { } std::map<size_t, std::string> AssetManagerSymbolSource::GetAssignedPackageIds() const { + TRACE_CALL(); std::map<size_t, std::string> package_map; asset_manager_.ForEachPackage([&package_map](const std::string& name, uint8_t id) -> bool { package_map.insert(std::make_pair(id, name)); diff --git a/tools/aapt2/split/TableSplitter.cpp b/tools/aapt2/split/TableSplitter.cpp index 24cd5ba302ea..6a672717f38e 100644 --- a/tools/aapt2/split/TableSplitter.cpp +++ b/tools/aapt2/split/TableSplitter.cpp @@ -27,6 +27,7 @@ #include "androidfw/ConfigDescription.h" #include "ResourceTable.h" +#include "trace/TraceBuffer.h" #include "util/Util.h" using ::android::ConfigDescription; @@ -154,6 +155,7 @@ static void MarkNonPreferredDensitiesAsClaimed( } } bool TableSplitter::VerifySplitConstraints(IAaptContext* context) { + TRACE_CALL(); bool error = false; for (size_t i = 0; i < split_constraints_.size(); i++) { if (split_constraints_[i].configs.size() == 0) { diff --git a/tools/aapt2/trace/TraceBuffer.cpp b/tools/aapt2/trace/TraceBuffer.cpp new file mode 100644 index 000000000000..b4b31d9daf6e --- /dev/null +++ b/tools/aapt2/trace/TraceBuffer.cpp @@ -0,0 +1,151 @@ +/* + * Copyright (C) 2019 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 "TraceBuffer.h" + +#include <chrono> +#include <sstream> +#include <unistd.h> +#include <vector> + +#include <inttypes.h> + +#include "android-base/utf8.h" + +#include "util/Files.h" + +namespace aapt { +namespace tracebuffer { + +namespace { + +constexpr char kBegin = 'B'; +constexpr char kEnd = 'E'; + +struct TracePoint { + pid_t tid; + int64_t time; + std::string tag; + char type; +}; + +std::vector<TracePoint> traces; + +int64_t GetTime() noexcept { + auto now = std::chrono::steady_clock::now(); + return std::chrono::duration_cast<std::chrono::microseconds>(now.time_since_epoch()).count(); +} + +} // namespace anonymous + +void AddWithTime(const std::string& tag, char type, int64_t time) noexcept { + TracePoint t = {getpid(), time, tag, type}; + traces.emplace_back(t); +} + +void Add(const std::string& tag, char type) noexcept { + AddWithTime(tag, type, GetTime()); +} + + + + +void Flush(const std::string& basePath) { + TRACE_CALL(); + if (basePath.empty()) { + return; + } + + std::stringstream s; + s << basePath << aapt::file::sDirSep << "report_aapt2_" << getpid() << ".json"; + FILE* f = android::base::utf8::fopen(s.str().c_str(), "a"); + if (f == nullptr) { + return; + } + + for(const TracePoint& trace : traces) { + fprintf(f, "{\"ts\" : \"%" PRIu64 "\", \"ph\" : \"%c\", \"tid\" : \"%d\" , \"pid\" : \"%d\", " + "\"name\" : \"%s\" },\n", trace.time, trace.type, 0, trace.tid, trace.tag.c_str()); + } + fclose(f); + traces.clear(); +} + +} // namespace tracebuffer + +void BeginTrace(const std::string& tag) { + tracebuffer::Add(tag, tracebuffer::kBegin); +} + +void EndTrace() { + tracebuffer::Add("", tracebuffer::kEnd); +} + +Trace::Trace(const std::string& tag) { + tracebuffer::Add(tag, tracebuffer::kBegin); +} + +Trace::Trace(const std::string& tag, const std::vector<android::StringPiece>& args) { + std::stringstream s; + s << tag; + s << " "; + for (auto& arg : args) { + s << arg.to_string(); + s << " "; + } + tracebuffer::Add(s.str(), tracebuffer::kBegin); +} + +Trace::~Trace() { + tracebuffer::Add("", tracebuffer::kEnd); +} + +FlushTrace::FlushTrace(const std::string& basepath, const std::string& tag) + : basepath_(basepath) { + tracebuffer::Add(tag, tracebuffer::kBegin); +} + +FlushTrace::FlushTrace(const std::string& basepath, const std::string& tag, + const std::vector<android::StringPiece>& args) : basepath_(basepath) { + std::stringstream s; + s << tag; + s << " "; + for (auto& arg : args) { + s << arg.to_string(); + s << " "; + } + tracebuffer::Add(s.str(), tracebuffer::kBegin); +} + +FlushTrace::FlushTrace(const std::string& basepath, const std::string& tag, + const std::vector<std::string>& args) : basepath_(basepath){ + std::stringstream s; + s << tag; + s << " "; + for (auto& arg : args) { + s << arg; + s << " "; + } + tracebuffer::Add(s.str(), tracebuffer::kBegin); +} + +FlushTrace::~FlushTrace() { + tracebuffer::Add("", tracebuffer::kEnd); + tracebuffer::Flush(basepath_); +} + +} // namespace aapt + diff --git a/tools/aapt2/trace/TraceBuffer.h b/tools/aapt2/trace/TraceBuffer.h new file mode 100644 index 000000000000..8618e0eeb731 --- /dev/null +++ b/tools/aapt2/trace/TraceBuffer.h @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2019 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. + */ + +#ifndef AAPT_TRACEBUFFER_H +#define AAPT_TRACEBUFFER_H + +#include <string> +#include <vector> + +#include <androidfw/StringPiece.h> + +namespace aapt { + +// Record timestamps for beginning and end of a task and generate systrace json fragments. +// This is an in-process ftrace which has the advantage of being platform independent. +// These methods are NOT thread-safe since aapt2 is not multi-threaded. + +// Convenience RIAA object to automatically finish an event when object goes out of scope. +class Trace { +public: + Trace(const std::string& tag); + Trace(const std::string& tag, const std::vector<android::StringPiece>& args); + ~Trace(); +}; + +// Manual markers. +void BeginTrace(const std::string& tag); +void EndTrace(); + +// A master trace is required to flush events to disk. Events are formatted in systrace +// json format. +class FlushTrace { +public: + explicit FlushTrace(const std::string& basepath, const std::string& tag); + explicit FlushTrace(const std::string& basepath, const std::string& tag, + const std::vector<android::StringPiece>& args); + explicit FlushTrace(const std::string& basepath, const std::string& tag, + const std::vector<std::string>& args); + ~FlushTrace(); +private: + std::string basepath_; +}; + +#define TRACE_CALL() Trace __t(__func__) +#define TRACE_NAME(tag) Trace __t(tag) +#define TRACE_NAME_ARGS(tag, args) Trace __t(tag, args) + +#define TRACE_FLUSH(basename, tag) FlushTrace __t(basename, tag) +#define TRACE_FLUSH_ARGS(basename, tag, args) FlushTrace __t(basename, tag, args) +} // namespace aapt +#endif //AAPT_TRACEBUFFER_H diff --git a/tools/aapt2/xml/XmlDom.cpp b/tools/aapt2/xml/XmlDom.cpp index acd07c2876c8..9a725fad8727 100644 --- a/tools/aapt2/xml/XmlDom.cpp +++ b/tools/aapt2/xml/XmlDom.cpp @@ -26,6 +26,7 @@ #include "android-base/logging.h" #include "ResourceUtils.h" +#include "trace/TraceBuffer.h" #include "XmlPullParser.h" #include "util/Util.h" @@ -264,6 +265,7 @@ static void CopyAttributes(Element* el, android::ResXMLParser* parser, StringPoo } std::unique_ptr<XmlResource> Inflate(const void* data, size_t len, std::string* out_error) { + TRACE_CALL(); // 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; |