Implement filter-product

filter-product option is added to aapt2 compile, which filters values
with a given product and removes all other values (including default).
The motivation of this change is to generate product-specific RRO
automatically, making a main resource APK (e.g. framework-res.apk)
identical in all targets.

Bug: 294799593
Test: build
Change-Id: I42eb3e134c7aa120f6bbe2d26d311bd46b586595
diff --git a/tools/aapt2/cmd/Compile.cpp b/tools/aapt2/cmd/Compile.cpp
index b5c290e..728ba8a 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 "process/ProductFilter.h"
 #include "trace/TraceBuffer.h"
 #include "util/Files.h"
 #include "util/Util.h"
@@ -179,6 +180,15 @@
     if (!res_parser.Parse(&xml_parser)) {
       return false;
     }
+
+    if (options.product_.has_value()) {
+      if (!ProductFilter({*options.product_}, /* remove_default_config_values = */ true)
+               .Consume(context, &table)) {
+        context->GetDiagnostics()->Error(android::DiagMessage(path_data.source)
+                                         << "failed to filter product");
+        return false;
+      }
+    }
   }
 
   if (options.pseudolocalize && translatable_file) {
diff --git a/tools/aapt2/cmd/Compile.h b/tools/aapt2/cmd/Compile.h
index 22890fc..61c5b60 100644
--- a/tools/aapt2/cmd/Compile.h
+++ b/tools/aapt2/cmd/Compile.h
@@ -44,6 +44,7 @@
   // See comments on aapt::ResourceParserOptions.
   bool preserve_visibility_of_styleables = false;
   bool verbose = false;
+  std::optional<std::string> product_;
 };
 
 /** Parses flags and compiles resources to be used in linking.  */
@@ -87,6 +88,10 @@
                     "Sets the ratio of resources to generate grammatical gender strings for. The "
                     "ratio has to be a float number between 0 and 1.",
                     &options_.pseudo_localize_gender_ratio);
+    AddOptionalFlag("--filter-product",
+                    "Leave only resources specific to the given product. All "
+                    "other resources (including defaults) are removed.",
+                    &options_.product_);
   }
 
   int Action(const std::vector<std::string>& args) override;
diff --git a/tools/aapt2/cmd/Link.cpp b/tools/aapt2/cmd/Link.cpp
index eb4e38c..159c6fd 100644
--- a/tools/aapt2/cmd/Link.cpp
+++ b/tools/aapt2/cmd/Link.cpp
@@ -66,6 +66,7 @@
 #include "optimize/ResourceDeduper.h"
 #include "optimize/VersionCollapser.h"
 #include "process/IResourceTableConsumer.h"
+#include "process/ProductFilter.h"
 #include "process/SymbolTable.h"
 #include "split/TableSplitter.h"
 #include "trace/TraceBuffer.h"
@@ -2128,7 +2129,7 @@
                                          << "can't select products when building static library");
       }
     } else {
-      ProductFilter product_filter(options_.products);
+      ProductFilter product_filter(options_.products, /* remove_default_config_values = */ false);
       if (!product_filter.Consume(context_, &final_table_)) {
         context_->GetDiagnostics()->Error(android::DiagMessage() << "failed stripping products");
         return 1;