From 8a7b4cb99290ec8c1b7d7df4f6e64999a9f4de6e Mon Sep 17 00:00:00 2001 From: Pierre Lecesne Date: Tue, 31 Jan 2017 23:58:27 +0000 Subject: [PATCH] Backbone of the new aapt2 strip command. The strip command takes an APK as argument and a --target-densities flag which contains the list of screen densities for which to optimize the APK. All the resources that would be unused for a device having the given densities are stripped from the APK leaving only the ones actually being used. Test: Manual. Change-Id: I68368b00876a18ccdbbfc0a8dd265bd361117933 --- tools/aapt2/Android.bp | 1 + tools/aapt2/Main.cpp | 5 +- tools/aapt2/strip/Strip.cpp | 156 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 161 insertions(+), 1 deletion(-) create mode 100644 tools/aapt2/strip/Strip.cpp diff --git a/tools/aapt2/Android.bp b/tools/aapt2/Android.bp index 8c2808309deb..dabaca6c9cf7 100644 --- a/tools/aapt2/Android.bp +++ b/tools/aapt2/Android.bp @@ -19,6 +19,7 @@ toolSources = [ "diff/Diff.cpp", "dump/Dump.cpp", "link/Link.cpp", + "strip/Strip.cpp", ] cc_defaults { diff --git a/tools/aapt2/Main.cpp b/tools/aapt2/Main.cpp index 15d7e2e2241b..3ed698b79764 100644 --- a/tools/aapt2/Main.cpp +++ b/tools/aapt2/Main.cpp @@ -37,6 +37,7 @@ extern int Compile(const std::vector& args); extern int Link(const std::vector& args); extern int Dump(const std::vector& args); extern int Diff(const std::vector& args); +extern int Strip(const std::vector& args); } // namespace aapt @@ -59,6 +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 == "version") { return aapt::PrintVersion(); } @@ -67,7 +70,7 @@ int main(int argc, char** argv) { std::cerr << "no command specified\n"; } - std::cerr << "\nusage: aapt2 [compile|link|dump|diff|version] ..." + std::cerr << "\nusage: aapt2 [compile|link|dump|diff|strip|version] ..." << std::endl; return 1; } diff --git a/tools/aapt2/strip/Strip.cpp b/tools/aapt2/strip/Strip.cpp new file mode 100644 index 000000000000..b3787ec69f08 --- /dev/null +++ b/tools/aapt2/strip/Strip.cpp @@ -0,0 +1,156 @@ +/* + * 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. + */ + +#include +#include + +#include "androidfw/StringPiece.h" + +#include "Diagnostics.h" +#include "Flags.h" +#include "LoadedApk.h" + +using android::StringPiece; + +namespace aapt { + +struct StripOptions { + /** Path to the output APK. */ + std::string output_path; + + /** List of screen density configurations the APK will be optimized for. */ + std::vector target_configs; +}; + +class StripContext : public IAaptContext { + public: + IDiagnostics* GetDiagnostics() override { return &diagnostics_; } + + NameMangler* GetNameMangler() override { + abort(); + return nullptr; + } + + const std::string& GetCompilationPackage() override { + static std::string empty; + return empty; + } + + uint8_t GetPackageId() override { return 0; } + + SymbolTable* GetExternalSymbols() override { + abort(); + return nullptr; + } + + bool IsVerbose() override { return verbose_; } + + void SetVerbose(bool val) { verbose_ = val; } + + int GetMinSdkVersion() override { return 0; } + + private: + StdErrDiagnostics diagnostics_; + bool verbose_ = false; +}; + +class StripCommand { + public: + StripCommand(StripContext* context, const StripOptions& options) + : options_(options), + context_(context) {} + + int Run(std::unique_ptr apk) { + if (context_->IsVerbose()) { + context_->GetDiagnostics()->Note(DiagMessage() << "Stripping APK..."); + } + + // TODO(lecesne): Implement stripping here. + + return 0; + } + + private: + StripOptions options_; + StripContext* context_; +}; + +int Strip(const std::vector& args) { + StripContext context; + StripOptions options; + std::string target_densities; + bool verbose = false; + Flags flags = + Flags() + .RequiredFlag("-o", "Path to the output APK.", &options.output_path) + .RequiredFlag( + "--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("-v", "Enables verbose logging", &verbose); + + if (!flags.Parse("aapt2 strip", 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); + return 1; + } + + std::unique_ptr apk = + LoadedApk::LoadApkFromPath(&context, flags.GetArgs()[0]); + if (!apk) { + return 1; + } + + if (verbose) { + 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; + } + + // 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); + return cmd.Run(std::move(apk)); +} + +} // namespace aapt -- 2.11.0