diff options
author | 2017-02-21 14:22:30 -0800 | |
---|---|---|
committer | 2017-02-22 11:41:55 -0800 | |
commit | d48944a745f9ed121e6bde22ef6feb3a44fbec39 (patch) | |
tree | 349c152caa68f1283535b2f9c49f5cd8a50eb59b | |
parent | ceb9b2f80f853059233cdd29057f39a5960a74ae (diff) |
AAPT2: Rename strip phase to optimize
- Allow resource deduping, version collapsing, and sparse resource
encoding.
Test: manual
Change-Id: Ia4aa892ab5b06ba1d5ea4a6efb51b00bc3a980c4
-rw-r--r-- | tools/aapt2/Android.bp | 8 | ||||
-rw-r--r-- | tools/aapt2/LoadedApk.cpp | 5 | ||||
-rw-r--r-- | tools/aapt2/LoadedApk.h | 4 | ||||
-rw-r--r-- | tools/aapt2/Main.cpp | 10 | ||||
-rw-r--r-- | tools/aapt2/link/Link.cpp | 2 | ||||
-rw-r--r-- | tools/aapt2/link/Linkers.h | 23 | ||||
-rw-r--r-- | tools/aapt2/optimize/Optimize.cpp (renamed from tools/aapt2/strip/Strip.cpp) | 111 | ||||
-rw-r--r-- | tools/aapt2/optimize/ResourceDeduper.cpp (renamed from tools/aapt2/link/ResourceDeduper.cpp) | 2 | ||||
-rw-r--r-- | tools/aapt2/optimize/ResourceDeduper.h | 41 | ||||
-rw-r--r-- | tools/aapt2/optimize/ResourceDeduper_test.cpp (renamed from tools/aapt2/link/ResourceDeduper_test.cpp) | 2 | ||||
-rw-r--r-- | tools/aapt2/optimize/VersionCollapser.cpp (renamed from tools/aapt2/link/VersionCollapser.cpp) | 2 | ||||
-rw-r--r-- | tools/aapt2/optimize/VersionCollapser.h | 40 | ||||
-rw-r--r-- | tools/aapt2/optimize/VersionCollapser_test.cpp (renamed from tools/aapt2/link/VersionCollapser_test.cpp) | 2 | ||||
-rw-r--r-- | tools/aapt2/readme.md | 15 |
14 files changed, 187 insertions, 80 deletions
diff --git a/tools/aapt2/Android.bp b/tools/aapt2/Android.bp index dabaca6c9cf7..57036aad611b 100644 --- a/tools/aapt2/Android.bp +++ b/tools/aapt2/Android.bp @@ -1,5 +1,5 @@ // -// Copyright (C) 2015 The Android Open Source Project +// Copyright (C) 2017 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. @@ -19,7 +19,7 @@ toolSources = [ "diff/Diff.cpp", "dump/Dump.cpp", "link/Link.cpp", - "strip/Strip.cpp", + "optimize/Optimize.cpp", ] cc_defaults { @@ -96,11 +96,11 @@ cc_library_host_static { "link/ProductFilter.cpp", "link/PrivateAttributeMover.cpp", "link/ReferenceLinker.cpp", - "link/ResourceDeduper.cpp", "link/TableMerger.cpp", - "link/VersionCollapser.cpp", "link/XmlNamespaceRemover.cpp", "link/XmlReferenceLinker.cpp", + "optimize/ResourceDeduper.cpp", + "optimize/VersionCollapser.cpp", "process/SymbolTable.cpp", "proto/ProtoHelpers.cpp", "proto/TableProtoDeserializer.cpp", diff --git a/tools/aapt2/LoadedApk.cpp b/tools/aapt2/LoadedApk.cpp index 407550b112dc..1d04b357131a 100644 --- a/tools/aapt2/LoadedApk.cpp +++ b/tools/aapt2/LoadedApk.cpp @@ -58,7 +58,8 @@ std::unique_ptr<LoadedApk> LoadedApk::LoadApkFromPath(IAaptContext* context, return util::make_unique<LoadedApk>(source, std::move(apk), std::move(table)); } -bool LoadedApk::WriteToArchive(IAaptContext* context, IArchiveWriter* writer) { +bool LoadedApk::WriteToArchive(IAaptContext* context, const TableFlattenerOptions& options, + IArchiveWriter* writer) { std::set<std::string> referenced_resources; // List the files being referenced in the resource table. for (auto& pkg : table_->packages) { @@ -96,7 +97,7 @@ bool LoadedApk::WriteToArchive(IAaptContext* context, IArchiveWriter* writer) { BigBuffer buffer = BigBuffer(1024); // TODO(adamlesinski): How to determine if there were sparse entries (and if to encode // with sparse entries) b/35389232. - TableFlattener flattener({}, &buffer); + TableFlattener flattener(options, &buffer); if (!flattener.Consume(context, table_.get())) { return false; } diff --git a/tools/aapt2/LoadedApk.h b/tools/aapt2/LoadedApk.h index f8878d13ae35..59eb8161a868 100644 --- a/tools/aapt2/LoadedApk.h +++ b/tools/aapt2/LoadedApk.h @@ -21,6 +21,7 @@ #include "ResourceTable.h" #include "flatten/Archive.h" +#include "flatten/TableFlattener.h" #include "io/ZipArchive.h" #include "unflatten/BinaryResourceParser.h" @@ -45,7 +46,8 @@ class LoadedApk { * Writes the APK on disk at the given path, while also removing the resource * files that are not referenced in the resource table. */ - bool WriteToArchive(IAaptContext* context, IArchiveWriter* writer); + bool WriteToArchive(IAaptContext* context, const TableFlattenerOptions& options, + IArchiveWriter* writer); static std::unique_ptr<LoadedApk> LoadApkFromPath(IAaptContext* context, const android::StringPiece& path); diff --git a/tools/aapt2/Main.cpp b/tools/aapt2/Main.cpp index 7d68d364426c..38d9ef84f44b 100644 --- a/tools/aapt2/Main.cpp +++ b/tools/aapt2/Main.cpp @@ -25,7 +25,7 @@ namespace aapt { static const char* sMajorVersion = "2"; // Update minor version whenever a feature or flag is added. -static const char* sMinorVersion = "8"; +static const char* sMinorVersion = "9"; int PrintVersion() { std::cerr << "Android Asset Packaging Tool (aapt) " << sMajorVersion << "." @@ -37,7 +37,7 @@ extern int Compile(const std::vector<android::StringPiece>& args); extern int Link(const std::vector<android::StringPiece>& args); extern int Dump(const std::vector<android::StringPiece>& args); extern int Diff(const std::vector<android::StringPiece>& args); -extern int Strip(const std::vector<android::StringPiece>& args); +extern int Optimize(const std::vector<android::StringPiece>& args); } // namespace aapt @@ -60,8 +60,8 @@ int main(int argc, char** argv) { return aapt::Dump(args); } else if (command == "diff") { return aapt::Diff(args); - } else if (command == "strip") { - return aapt::Strip(args); + } else if (command == "optimize") { + return aapt::Optimize(args); } else if (command == "version") { return aapt::PrintVersion(); } @@ -70,7 +70,7 @@ int main(int argc, char** argv) { std::cerr << "no command specified\n"; } - std::cerr << "\nusage: aapt2 [compile|link|dump|diff|strip|version] ..." + std::cerr << "\nusage: aapt2 [compile|link|dump|diff|optimize|version] ..." << std::endl; return 1; } diff --git a/tools/aapt2/link/Link.cpp b/tools/aapt2/link/Link.cpp index 016246131f5f..49052169b6e6 100644 --- a/tools/aapt2/link/Link.cpp +++ b/tools/aapt2/link/Link.cpp @@ -46,6 +46,8 @@ #include "link/ManifestFixer.h" #include "link/ReferenceLinker.h" #include "link/TableMerger.h" +#include "optimize/ResourceDeduper.h" +#include "optimize/VersionCollapser.h" #include "process/IResourceTableConsumer.h" #include "process/SymbolTable.h" #include "proto/ProtoSerialize.h" diff --git a/tools/aapt2/link/Linkers.h b/tools/aapt2/link/Linkers.h index 4687d2c01d68..d00fa736f28b 100644 --- a/tools/aapt2/link/Linkers.h +++ b/tools/aapt2/link/Linkers.h @@ -58,29 +58,6 @@ class AutoVersioner : public IResourceTableConsumer { DISALLOW_COPY_AND_ASSIGN(AutoVersioner); }; -class VersionCollapser : public IResourceTableConsumer { - public: - VersionCollapser() = default; - - bool Consume(IAaptContext* context, ResourceTable* table) override; - - private: - DISALLOW_COPY_AND_ASSIGN(VersionCollapser); -}; - -/** - * Removes duplicated key-value entries from dominated resources. - */ -class ResourceDeduper : public IResourceTableConsumer { - public: - ResourceDeduper() = default; - - bool Consume(IAaptContext* context, ResourceTable* table) override; - - private: - DISALLOW_COPY_AND_ASSIGN(ResourceDeduper); -}; - /** * If any attribute resource values are defined as public, this consumer will * move all private diff --git a/tools/aapt2/strip/Strip.cpp b/tools/aapt2/optimize/Optimize.cpp index 7260649c26d4..96159622e653 100644 --- a/tools/aapt2/strip/Strip.cpp +++ b/tools/aapt2/optimize/Optimize.cpp @@ -22,21 +22,27 @@ #include "Diagnostics.h" #include "Flags.h" #include "LoadedApk.h" +#include "SdkConstants.h" +#include "flatten/TableFlattener.h" +#include "optimize/ResourceDeduper.h" +#include "optimize/VersionCollapser.h" #include "split/TableSplitter.h" using android::StringPiece; namespace aapt { -struct StripOptions { - /** Path to the output APK. */ +struct OptimizeOptions { + // Path to the output APK. std::string output_path; - /** List of screen density configurations the APK will be optimized for. */ + // List of screen density configurations the APK will be optimized for. std::vector<ConfigDescription> target_configs; + + TableFlattenerOptions table_flattener_options; }; -class StripContext : public IAaptContext { +class OptimizeContext : public IAaptContext { public: IDiagnostics* GetDiagnostics() override { return &diagnostics_; } @@ -61,22 +67,36 @@ class StripContext : public IAaptContext { void SetVerbose(bool val) { verbose_ = val; } - int GetMinSdkVersion() override { return 0; } + void SetMinSdkVersion(int sdk_version) { sdk_version_ = sdk_version; } + + int GetMinSdkVersion() override { return sdk_version_; } private: StdErrDiagnostics diagnostics_; bool verbose_ = false; + int sdk_version_ = 0; }; -class StripCommand { +class OptimizeCommand { public: - StripCommand(StripContext* context, const StripOptions& options) + OptimizeCommand(OptimizeContext* context, const OptimizeOptions& options) : options_(options), context_(context) {} int Run(std::unique_ptr<LoadedApk> apk) { if (context_->IsVerbose()) { - context_->GetDiagnostics()->Note(DiagMessage() << "Stripping APK..."); + context_->GetDiagnostics()->Note(DiagMessage() << "Optimizing APK..."); + } + + VersionCollapser collapser; + if (!collapser.Consume(context_, apk->GetResourceTable())) { + return 1; + } + + ResourceDeduper deduper; + if (!deduper.Consume(context_, apk->GetResourceTable())) { + context_->GetDiagnostics()->Error(DiagMessage() << "failed deduping resources"); + return 1; } // Stripping the APK using the TableSplitter with no splits and the target @@ -92,7 +112,7 @@ class StripCommand { std::unique_ptr<IArchiveWriter> writer = CreateZipFileArchiveWriter(context_->GetDiagnostics(), options_.output_path); - if (!apk->WriteToArchive(context_, writer.get())) { + if (!apk->WriteToArchive(context_, options_.table_flattener_options, writer.get())) { return 1; } @@ -100,33 +120,37 @@ class StripCommand { } private: - StripOptions options_; - StripContext* context_; + OptimizeOptions options_; + OptimizeContext* context_; }; -int Strip(const std::vector<StringPiece>& args) { - StripContext context; - StripOptions options; - std::string target_densities; +int Optimize(const std::vector<StringPiece>& args) { + OptimizeContext context; + OptimizeOptions options; + Maybe<std::string> target_densities; bool verbose = false; Flags flags = Flags() .RequiredFlag("-o", "Path to the output APK.", &options.output_path) - .RequiredFlag( + .OptionalFlag( "--target-densities", "Comma separated list of the screen densities that the APK will " "be optimized for. All the resources that would be unused on " "devices of the given densities will be removed from the APK.", &target_densities) + .OptionalSwitch("--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.table_flattener_options.use_sparse_entries) .OptionalSwitch("-v", "Enables verbose logging", &verbose); - if (!flags.Parse("aapt2 strip", args, &std::cerr)) { + if (!flags.Parse("aapt2 optimize", args, &std::cerr)) { return 1; } if (flags.GetArgs().size() != 1u) { std::cerr << "must have one APK as argument.\n\n"; - flags.Usage("aapt2 strip", &std::cerr); + flags.Usage("aapt2 optimize", &std::cerr); return 1; } @@ -140,32 +164,37 @@ int Strip(const std::vector<StringPiece>& args) { context.SetVerbose(verbose); } - // Parse the target screen densities. - for (const StringPiece& config_str : util::Tokenize(target_densities, ',')) { - ConfigDescription config; - if (!ConfigDescription::Parse(config_str, &config) || config.density == 0) { - context.GetDiagnostics()->Error( - DiagMessage() << "invalid density '" << config_str - << "' for --target-densities option"); - return 1; + if (target_densities) { + // Parse the target screen densities. + for (const StringPiece& config_str : util::Tokenize(target_densities.value(), ',')) { + ConfigDescription config; + if (!ConfigDescription::Parse(config_str, &config) || config.density == 0) { + context.GetDiagnostics()->Error( + DiagMessage() << "invalid density '" << config_str + << "' for --target-densities option"); + return 1; + } + + // Clear the version that can be automatically added. + config.sdkVersion = 0; + + if (config.diff(ConfigDescription::DefaultConfig()) != + ConfigDescription::CONFIG_DENSITY) { + context.GetDiagnostics()->Error( + DiagMessage() << "invalid density '" << config_str + << "' for --target-densities option. Must be only a " + << "density value."); + return 1; + } + + options.target_configs.push_back(config); } - - // Clear the version that can be automatically added. - config.sdkVersion = 0; - - if (config.diff(ConfigDescription::DefaultConfig()) != - ConfigDescription::CONFIG_DENSITY) { - context.GetDiagnostics()->Error( - DiagMessage() << "invalid density '" << config_str - << "' for --target-densities option. Must be only a " - << "density value."); - return 1; - } - - options.target_configs.push_back(config); } - StripCommand cmd(&context, options); + // TODO(adamlesinski): Read manfiest and set the proper minSdkVersion. + // context.SetMinSdkVersion(SDK_O); + + OptimizeCommand cmd(&context, options); return cmd.Run(std::move(apk)); } diff --git a/tools/aapt2/link/ResourceDeduper.cpp b/tools/aapt2/optimize/ResourceDeduper.cpp index 9431dcee9714..3aab2e3a0c78 100644 --- a/tools/aapt2/link/ResourceDeduper.cpp +++ b/tools/aapt2/optimize/ResourceDeduper.cpp @@ -14,7 +14,7 @@ * limitations under the License. */ -#include "link/Linkers.h" +#include "optimize/ResourceDeduper.h" #include <algorithm> diff --git a/tools/aapt2/optimize/ResourceDeduper.h b/tools/aapt2/optimize/ResourceDeduper.h new file mode 100644 index 000000000000..4a669d4e0d09 --- /dev/null +++ b/tools/aapt2/optimize/ResourceDeduper.h @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2017 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_OPTIMIZE_RESOURCEDEDUPER_H +#define AAPT_OPTIMIZE_RESOURCEDEDUPER_H + +#include "android-base/macros.h" + +#include "process/IResourceTableConsumer.h" + +namespace aapt { + +class ResourceTable; + +// Removes duplicated key-value entries from dominated resources. +class ResourceDeduper : public IResourceTableConsumer { + public: + ResourceDeduper() = default; + + bool Consume(IAaptContext* context, ResourceTable* table) override; + + private: + DISALLOW_COPY_AND_ASSIGN(ResourceDeduper); +}; + +} // namespace aapt + +#endif // AAPT_OPTIMIZE_RESOURCEDEDUPER_H diff --git a/tools/aapt2/link/ResourceDeduper_test.cpp b/tools/aapt2/optimize/ResourceDeduper_test.cpp index d38059ddd391..4d00fa6efe37 100644 --- a/tools/aapt2/link/ResourceDeduper_test.cpp +++ b/tools/aapt2/optimize/ResourceDeduper_test.cpp @@ -14,7 +14,7 @@ * limitations under the License. */ -#include "link/Linkers.h" +#include "optimize/ResourceDeduper.h" #include "ResourceTable.h" #include "test/Test.h" diff --git a/tools/aapt2/link/VersionCollapser.cpp b/tools/aapt2/optimize/VersionCollapser.cpp index 3df58994333f..d941b487e439 100644 --- a/tools/aapt2/link/VersionCollapser.cpp +++ b/tools/aapt2/optimize/VersionCollapser.cpp @@ -14,7 +14,7 @@ * limitations under the License. */ -#include "link/Linkers.h" +#include "optimize/VersionCollapser.h" #include <algorithm> #include <vector> diff --git a/tools/aapt2/optimize/VersionCollapser.h b/tools/aapt2/optimize/VersionCollapser.h new file mode 100644 index 000000000000..5ab3b2509b63 --- /dev/null +++ b/tools/aapt2/optimize/VersionCollapser.h @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2017 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_OPTIMIZE_VERSIONCOLLAPSER_H +#define AAPT_OPTIMIZE_VERSIONCOLLAPSER_H + +#include "android-base/macros.h" + +#include "process/IResourceTableConsumer.h" + +namespace aapt { + +class ResourceTable; + +class VersionCollapser : public IResourceTableConsumer { + public: + VersionCollapser() = default; + + bool Consume(IAaptContext* context, ResourceTable* table) override; + + private: + DISALLOW_COPY_AND_ASSIGN(VersionCollapser); +}; + +} // namespace aapt + +#endif // AAPT_OPTIMIZE_VERSIONCOLLAPSER_H diff --git a/tools/aapt2/link/VersionCollapser_test.cpp b/tools/aapt2/optimize/VersionCollapser_test.cpp index 44babb21ae6e..aa0d0c095f57 100644 --- a/tools/aapt2/link/VersionCollapser_test.cpp +++ b/tools/aapt2/optimize/VersionCollapser_test.cpp @@ -14,7 +14,7 @@ * limitations under the License. */ -#include "link/Linkers.h" +#include "optimize/VersionCollapser.h" #include "test/Test.h" diff --git a/tools/aapt2/readme.md b/tools/aapt2/readme.md index 8fa12d00079a..fedd65c4e239 100644 --- a/tools/aapt2/readme.md +++ b/tools/aapt2/readme.md @@ -1,5 +1,20 @@ # Android Asset Packaging Tool 2.0 (AAPT2) release notes +## Version 2.9 +### `aapt2 link ...` +- Added sparse resource type encoding, which encodes resource entries that are sparse with + a binary search tree representation. Only available when minSdkVersion >= API O or resource + qualifier of resource types is >= v26 (or whatever API level O becomes). Enabled with + `--enable-sparse-encoding` flag. +### `aapt2 optimize ...` +- Adds an optimization pass that supports: + - stripping out any density assets that do not match the `--target-densities` list of + densities. + - resource deduping when the resources are dominated and identical (already happens during + `link` phase but this covers apps built with `aapt`). + - new sparse resource type encoding with the `--enable-sparse-encoding` flag if possible + (minSdkVersion >= O or resource qualifier >= v26). + ## Version 2.8 ### `aapt2 link ...` - Adds shared library support. Build a shared library with the `--shared-lib` flag. |