Add --exclude-sources to AAPT2 link

Information about where resources are defined can make having
reproducible builds more difficult, makes the generates resources.pb
large, and can exposes details about the machines that compiled the
resources.

The --exclude-sources flags can only be used when building a proto APK
and prevents source information from being included in the generated
resources protobuf.

Bug: 134929532
Test: checked debug string with and without the string
Change-Id: Ia345f067fe781ea82a4bcad37eb55576c72c44d7
diff --git a/tools/aapt2/cmd/Link.cpp b/tools/aapt2/cmd/Link.cpp
index bbf71e7..99a686b 100644
--- a/tools/aapt2/cmd/Link.cpp
+++ b/tools/aapt2/cmd/Link.cpp
@@ -1084,7 +1084,8 @@
 
       case OutputFormat::kProto: {
         pb::ResourceTable pb_table;
-        SerializeTableToPb(*table, &pb_table, context_->GetDiagnostics());
+        SerializeTableToPb(*table, &pb_table, context_->GetDiagnostics(),
+                           options_.proto_table_flattener_options);
         return io::CopyProtoToArchive(context_, &pb_table, kProtoResourceTablePath,
                                       ArchiveEntry::kCompress, writer);
       } break;
diff --git a/tools/aapt2/cmd/Link.h b/tools/aapt2/cmd/Link.h
index 324807c..56bff8f 100644
--- a/tools/aapt2/cmd/Link.h
+++ b/tools/aapt2/cmd/Link.h
@@ -24,6 +24,7 @@
 #include "Resource.h"
 #include "split/TableSplitter.h"
 #include "format/binary/TableFlattener.h"
+#include "format/proto/ProtoSerialize.h"
 #include "link/ManifestFixer.h"
 #include "trace/TraceBuffer.h"
 
@@ -81,6 +82,7 @@
 
   // Flattening options.
   TableFlattenerOptions table_flattener_options;
+  SerializeTableOptions proto_table_flattener_options;
   bool keep_raw_values = false;
 
   // Split APK options.
@@ -245,9 +247,9 @@
             "<add-resource> tags.",
         &options_.auto_add_overlay);
     AddOptionalSwitch("--override-styles-instead-of-overlaying",
-                      "Causes styles defined in -R resources to replace previous definitions\n"
-                      "instead of merging into them\n",
-                      &options_.override_styles_instead_of_overlaying);
+        "Causes styles defined in -R resources to replace previous definitions\n"
+            "instead of merging into them\n",
+        &options_.override_styles_instead_of_overlaying);
     AddOptionalFlag("--rename-manifest-package", "Renames the package in AndroidManifest.xml.",
         &options_.manifest_fixer_options.rename_manifest_package);
     AddOptionalFlag("--rename-instrumentation-target-package",
@@ -283,13 +285,18 @@
     AddOptionalSwitch("--strict-visibility",
         "Do not allow overlays with different visibility levels.",
         &options_.strict_visibility);
-    AddOptionalSwitch("-v", "Enables verbose logging.", &verbose_);
-    AddOptionalFlag("--trace-folder", "Generate systrace json trace fragment to specified folder.",
-                    &trace_folder_);
+    AddOptionalSwitch("--exclude-sources",
+        "Do not serialize source file information when generating resources in\n"
+            "Protobuf format.",
+        &options_.proto_table_flattener_options.exclude_sources);
+    AddOptionalFlag("--trace-folder",
+        "Generate systrace json trace fragment to specified folder.",
+        &trace_folder_);
     AddOptionalSwitch("--merge-only",
-          "Only merge the resources, without verifying resource references. This flag\n"
-          "should only be used together with the --static-lib flag.",
-          &options_.merge_only);
+        "Only merge the resources, without verifying resource references. This flag\n"
+            "should only be used together with the --static-lib flag.",
+        &options_.merge_only);
+    AddOptionalSwitch("-v", "Enables verbose logging.", &verbose_);
   }
 
   int Action(const std::vector<std::string>& args) override;
diff --git a/tools/aapt2/format/proto/ProtoSerialize.cpp b/tools/aapt2/format/proto/ProtoSerialize.cpp
index aa6547e..e4b3fce 100644
--- a/tools/aapt2/format/proto/ProtoSerialize.cpp
+++ b/tools/aapt2/format/proto/ProtoSerialize.cpp
@@ -290,8 +290,10 @@
     pb::Overlayable* pb_overlayable = pb_table->add_overlayable();
     pb_overlayable->set_name(overlayable_item.overlayable->name);
     pb_overlayable->set_actor(overlayable_item.overlayable->actor);
-    SerializeSourceToPb(overlayable_item.overlayable->source, source_pool,
-                        pb_overlayable->mutable_source());
+    if (source_pool != nullptr) {
+      SerializeSourceToPb(overlayable_item.overlayable->source, source_pool,
+                          pb_overlayable->mutable_source());
+    }
   }
 
   pb::OverlayableItem* pb_overlayable_item = pb_entry->mutable_overlayable_item();
@@ -319,14 +321,17 @@
     pb_overlayable_item->add_policy(pb::OverlayableItem::OEM);
   }
 
-  SerializeSourceToPb(overlayable_item.source, source_pool,
-                      pb_overlayable_item->mutable_source());
+  if (source_pool != nullptr) {
+    SerializeSourceToPb(overlayable_item.source, source_pool,
+                        pb_overlayable_item->mutable_source());
+  }
   pb_overlayable_item->set_comment(overlayable_item.comment);
 }
 
 void SerializeTableToPb(const ResourceTable& table, pb::ResourceTable* out_table,
-                        IDiagnostics* diag) {
-  StringPool source_pool;
+                        IDiagnostics* diag, SerializeTableOptions options) {
+  auto source_pool = (options.exclude_sources) ? nullptr : util::make_unique<StringPool>();
+
   pb::ToolFingerprint* pb_fingerprint = out_table->add_tool_fingerprint();
   pb_fingerprint->set_tool(util::GetToolName());
   pb_fingerprint->set_version(util::GetToolFingerprint());
@@ -356,32 +361,40 @@
         // Write the Visibility struct.
         pb::Visibility* pb_visibility = pb_entry->mutable_visibility();
         pb_visibility->set_level(SerializeVisibilityToPb(entry->visibility.level));
-        SerializeSourceToPb(entry->visibility.source, &source_pool,
-                            pb_visibility->mutable_source());
+        if (source_pool != nullptr) {
+          SerializeSourceToPb(entry->visibility.source, source_pool.get(),
+                              pb_visibility->mutable_source());
+        }
         pb_visibility->set_comment(entry->visibility.comment);
 
         if (entry->allow_new) {
           pb::AllowNew* pb_allow_new = pb_entry->mutable_allow_new();
-          SerializeSourceToPb(entry->allow_new.value().source, &source_pool,
-                              pb_allow_new->mutable_source());
+          if (source_pool != nullptr) {
+            SerializeSourceToPb(entry->allow_new.value().source, source_pool.get(),
+                                pb_allow_new->mutable_source());
+          }
           pb_allow_new->set_comment(entry->allow_new.value().comment);
         }
 
         if (entry->overlayable_item) {
-          SerializeOverlayableItemToPb(entry->overlayable_item.value(), overlayables, &source_pool,
-                                       pb_entry, out_table);
+          SerializeOverlayableItemToPb(entry->overlayable_item.value(), overlayables,
+                                       source_pool.get(), pb_entry, out_table);
         }
 
         for (const std::unique_ptr<ResourceConfigValue>& config_value : entry->values) {
           pb::ConfigValue* pb_config_value = pb_entry->add_config_value();
           SerializeConfig(config_value->config, pb_config_value->mutable_config());
           pb_config_value->mutable_config()->set_product(config_value->product);
-          SerializeValueToPb(*config_value->value, pb_config_value->mutable_value(), &source_pool);
+          SerializeValueToPb(*config_value->value, pb_config_value->mutable_value(),
+                             source_pool.get());
         }
       }
     }
   }
-  SerializeStringPoolToPb(source_pool, out_table->mutable_source_pool(), diag);
+
+  if (source_pool != nullptr) {
+    SerializeStringPoolToPb(*source_pool, out_table->mutable_source_pool(), diag);
+  }
 }
 
 static pb::Reference_Type SerializeReferenceTypeToPb(Reference::Type type) {
diff --git a/tools/aapt2/format/proto/ProtoSerialize.h b/tools/aapt2/format/proto/ProtoSerialize.h
index 33ffd18..7a3ea99 100644
--- a/tools/aapt2/format/proto/ProtoSerialize.h
+++ b/tools/aapt2/format/proto/ProtoSerialize.h
@@ -35,6 +35,11 @@
   bool remove_empty_text_nodes = false;
 };
 
+struct SerializeTableOptions {
+    /** Prevent serializing the source pool and source protos.  */
+    bool exclude_sources = false;
+};
+
 // Serializes a Value to its protobuf representation. An optional StringPool will hold the
 // source path string.
 void SerializeValueToPb(const Value& value, pb::Value* out_value, StringPool* src_pool = nullptr);
@@ -59,7 +64,8 @@
 void SerializeConfig(const android::ConfigDescription& config, pb::Configuration* out_pb_config);
 
 // Serializes a ResourceTable into its protobuf representation.
-void SerializeTableToPb(const ResourceTable& table, pb::ResourceTable* out_table, IDiagnostics* diag);
+void SerializeTableToPb(const ResourceTable& table, pb::ResourceTable* out_table,
+                        IDiagnostics* diag, SerializeTableOptions options = {});
 
 // Serializes a ResourceFile into its protobuf representation.
 void SerializeCompiledFileToPb(const ResourceFile& file, pb::internal::CompiledFile* out_file);