AAPT2: Refactor flags into commands

Refactors the flag based command invocation into classes that make using
subcommands easier.

Test: manual tests of printing
Change-Id: Ic8df6af0be30db552e32150afebecbfeec7e1075
diff --git a/tools/aapt2/cmd/Optimize.h b/tools/aapt2/cmd/Optimize.h
new file mode 100644
index 0000000..43bc216
--- /dev/null
+++ b/tools/aapt2/cmd/Optimize.h
@@ -0,0 +1,124 @@
+/*
+ * 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.
+ */
+
+#ifndef AAPT2_OPTIMIZE_H
+#define AAPT2_OPTIMIZE_H
+
+#include "AppInfo.h"
+#include "Command.h"
+#include "configuration/ConfigurationParser.h"
+#include "format/binary/TableFlattener.h"
+#include "split/TableSplitter.h"
+
+namespace aapt {
+
+struct OptimizeOptions {
+  friend class OptimizeCommand;
+
+  // Path to the output APK.
+  Maybe<std::string> output_path;
+  // Path to the output APK directory for splits.
+  Maybe<std::string> output_dir;
+
+  // Details of the app extracted from the AndroidManifest.xml
+  AppInfo app_info;
+
+  // Blacklist of unused resources that should be removed from the apk.
+  std::unordered_set<ResourceName> resources_blacklist;
+
+  // Split APK options.
+  TableSplitterOptions table_splitter_options;
+
+  // List of output split paths. These are in the same order as `split_constraints`.
+  std::vector<std::string> split_paths;
+
+  // List of SplitConstraints governing what resources go into each split. Ordered by `split_paths`.
+  std::vector<SplitConstraints> split_constraints;
+
+  TableFlattenerOptions table_flattener_options;
+
+  Maybe<std::vector<aapt::configuration::OutputArtifact>> apk_artifacts;
+
+  // Set of artifacts to keep when generating multi-APK splits. If the list is empty, all artifacts
+  // are kept and will be written as output.
+  std::unordered_set<std::string> kept_artifacts;
+};
+
+class OptimizeCommand : public Command {
+ public:
+  explicit OptimizeCommand() : Command("optimize") {
+    SetDescription("Preforms resource optimizations on an apk.");
+    AddOptionalFlag("-o", "Path to the output APK.", &options_.output_path);
+    AddOptionalFlag("-d", "Path to the output directory (for splits).", &options_.output_dir);
+    AddOptionalFlag("-x", "Path to XML configuration file.", &config_path_);
+    AddOptionalSwitch("-p", "Print the multi APK artifacts and exit.", &print_only_);
+    AddOptionalFlag(
+        "--target-densities",
+        "Comma separated list of the screen densities that the APK will be optimized for.\n"
+            "All the resources that would be unused on devices of the given densities will be \n"
+            "removed from the APK.",
+        &target_densities_);
+    AddOptionalFlag("--whitelist-path",
+        "Path to the whitelist.cfg file containing whitelisted resources \n"
+            "whose names should not be altered in final resource tables.",
+        &whitelist_path_);
+    AddOptionalFlag("--resources-config-path",
+        "Path to the resources.cfg file containing the list of resources and \n"
+            "directives to each resource. \n"
+            "Format: type/resource_name#[directive][,directive]",
+        &resources_config_path_);
+    AddOptionalFlagList("-c",
+        "Comma separated list of configurations to include. The default\n"
+            "is all configurations.",
+        &configs_);
+    AddOptionalFlagList("--split",
+        "Split resources matching a set of configs out to a "
+            "Split APK.\nSyntax: path/to/output.apk;<config>[,<config>[...]].\n"
+            "On Windows, use a semicolon ';' separator instead.",
+        &split_args_);
+    AddOptionalFlagList("--keep-artifacts",
+        "Comma separated list of artifacts to keep. If none are specified,\n"
+            "all artifacts will be kept.",
+        &kept_artifacts_);
+    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_.table_flattener_options.use_sparse_entries);
+    AddOptionalSwitch("--enable-resource-obfuscation",
+        "Enables obfuscation of key string pool to single value",
+        &options_.table_flattener_options.collapse_key_stringpool);
+    AddOptionalSwitch("-v", "Enables verbose logging", &verbose_);
+  }
+
+  int Action(const std::vector<std::string>& args) override;
+
+ private:
+  OptimizeOptions options_;
+
+  Maybe<std::string> config_path_;
+  Maybe<std::string> whitelist_path_;
+  Maybe<std::string> resources_config_path_;
+  Maybe<std::string> target_densities_;
+  std::vector<std::string> configs_;
+  std::vector<std::string> split_args_;
+  std::unordered_set<std::string> kept_artifacts_;
+  bool print_only_ = false;
+  bool verbose_ = false;
+};
+
+}// namespace aapt
+
+#endif //AAPT2_OPTIMIZE_H
\ No newline at end of file