AAPT2: Get list of multi-APK artifacts without APK file

Allow the optimize command to produce a list of output artifact names
without needing to read the input APK from disk. This not only saves
disk reads for a file that will not be used, it also allows the list
of outputs to be generated without having an APK file yet.

Test: unit tests
Test: split an APK
Test: print list of outputs without an APK
Change-Id: I4e18e63f298a07f26ab0de2b2f0acb769bb535ba
diff --git a/tools/aapt2/cmd/Optimize.cpp b/tools/aapt2/cmd/Optimize.cpp
index d8bb999..9c76119 100644
--- a/tools/aapt2/cmd/Optimize.cpp
+++ b/tools/aapt2/cmd/Optimize.cpp
@@ -377,44 +377,10 @@
   }
 
   const std::string& apk_path = flags.GetArgs()[0];
-  std::unique_ptr<LoadedApk> apk = LoadedApk::LoadApkFromPath(apk_path, context.GetDiagnostics());
-  if (!apk) {
-    return 1;
-  }
 
   context.SetVerbose(verbose);
   IDiagnostics* diag = context.GetDiagnostics();
 
-  if (target_densities) {
-    // Parse the target screen densities.
-    for (const StringPiece& config_str : util::Tokenize(target_densities.value(), ',')) {
-      Maybe<uint16_t> target_density = ParseTargetDensityParameter(config_str, diag);
-      if (!target_density) {
-        return 1;
-      }
-      options.table_splitter_options.preferred_densities.push_back(target_density.value());
-    }
-  }
-
-  std::unique_ptr<IConfigFilter> filter;
-  if (!configs.empty()) {
-    filter = ParseConfigFilterParameters(configs, diag);
-    if (filter == nullptr) {
-      return 1;
-    }
-    options.table_splitter_options.config_filter = filter.get();
-  }
-
-  // Parse the split parameters.
-  for (const std::string& split_arg : split_args) {
-    options.split_paths.emplace_back();
-    options.split_constraints.emplace_back();
-    if (!ParseSplitParameter(split_arg, diag, &options.split_paths.back(),
-                             &options.split_constraints.back())) {
-      return 1;
-    }
-  }
-
   if (config_path) {
     std::string& path = config_path.value();
     Maybe<ConfigurationParser> for_path = ConfigurationParser::ForPath(path);
@@ -456,6 +422,41 @@
     return 1;
   }
 
+  std::unique_ptr<LoadedApk> apk = LoadedApk::LoadApkFromPath(apk_path, context.GetDiagnostics());
+  if (!apk) {
+    return 1;
+  }
+
+  if (target_densities) {
+    // Parse the target screen densities.
+    for (const StringPiece& config_str : util::Tokenize(target_densities.value(), ',')) {
+      Maybe<uint16_t> target_density = ParseTargetDensityParameter(config_str, diag);
+      if (!target_density) {
+        return 1;
+      }
+      options.table_splitter_options.preferred_densities.push_back(target_density.value());
+    }
+  }
+
+  std::unique_ptr<IConfigFilter> filter;
+  if (!configs.empty()) {
+    filter = ParseConfigFilterParameters(configs, diag);
+    if (filter == nullptr) {
+      return 1;
+    }
+    options.table_splitter_options.config_filter = filter.get();
+  }
+
+  // Parse the split parameters.
+  for (const std::string& split_arg : split_args) {
+    options.split_paths.emplace_back();
+    options.split_constraints.emplace_back();
+    if (!ParseSplitParameter(split_arg, diag, &options.split_paths.back(),
+                             &options.split_constraints.back())) {
+      return 1;
+    }
+  }
+
   if (options.table_flattener_options.collapse_key_stringpool) {
     if (whitelist_path) {
       std::string& path = whitelist_path.value();