Add layer tracing's MODE_GENERATED_BUGREPORT_ONLY

The generated layers trace can be quite large (100-400 MB), which is way above
the perfetto's field upload budget.

On the field (AOT) we want the layers trace to be generated only when a bugreport
is taken and not when a perfetto's field upload happens. We achieve it as follows:
- In the AOT configuration, enable the 'android.surfaceflinger_layers' data source
  with MODE_GENERATED_BUGREPORT_ONLY.
- When LayerTracing receives perfetto's OnFlush event and MODE_GENERATED_BUGREPORT_ONLY is enabled,
  generate the layers trace only if the OnFlush event is due to a bugreport being taken:
    args.flush_flags.reason() == perfetto::FlushFlags::Reason::kTraceClone &&
    args.flush_flags.clone_target() == perfetto::FlushFlags::CloneTarget::kBugreport

In a test environment instead, we can use MODE_GENERATED to test the layers trace generation
without having to take a bugreport.

Bug: b/293429094
Test: 1. Manually start the perfetto's android.surfaceflinger_layers data source
         with MODE_GENERATED_BUGREPORT_ONLY setting a high bugreport_score (e.g. 50000)
      2. Take a bugreport (adb bugreport)
      3. Verify that FS/data/misc/perfetto-traces/bugreport/systrace.pftrace (in the bugreport)
         contains the generated layers trace. E.g. inspect bugreport with go/winscope.
Change-Id: I5b3ce59cc762fd5a22170e677e48be987380c94e
diff --git a/services/surfaceflinger/Tracing/LayerDataSource.cpp b/services/surfaceflinger/Tracing/LayerDataSource.cpp
index 25e768e..ed1e2ec 100644
--- a/services/surfaceflinger/Tracing/LayerDataSource.cpp
+++ b/services/surfaceflinger/Tracing/LayerDataSource.cpp
@@ -51,8 +51,9 @@
     if (config.has_mode() && config.mode() != LayerTracing::Mode::MODE_UNSPECIFIED) {
         mMode = static_cast<LayerTracing::Mode>(config.mode());
     } else {
-        mMode = LayerTracing::Mode::MODE_GENERATED;
-        ALOGD("Received config with unspecified 'mode'. Using 'GENERATED' as default");
+        mMode = LayerTracing::Mode::MODE_GENERATED_BUGREPORT_ONLY;
+        ALOGD("Received config with unspecified 'mode'."
+              " Using 'MODE_GENERATED_BUGREPORT_ONLY' as default");
     }
 
     mFlags = 0;
@@ -68,10 +69,16 @@
     }
 }
 
-void LayerDataSource::OnFlush(const LayerDataSource::FlushArgs&) {
-    ALOGD("Received OnFlush event (mode = 0x%02x, flags = 0x%02x)", mMode, mFlags);
+void LayerDataSource::OnFlush(const LayerDataSource::FlushArgs& args) {
+    ALOGD("Received OnFlush event"
+          " (mode = 0x%02x, flags = 0x%02x, reason = 0x%" PRIx64 ", clone_target = 0x%0" PRIx64 ")",
+          mMode, mFlags, args.flush_flags.reason(), args.flush_flags.clone_target());
+
+    bool isBugreport = args.flush_flags.reason() == perfetto::FlushFlags::Reason::kTraceClone &&
+            args.flush_flags.clone_target() == perfetto::FlushFlags::CloneTarget::kBugreport;
+
     if (auto* p = mLayerTracing.load()) {
-        p->onFlush(mMode, mFlags);
+        p->onFlush(mMode, mFlags, isBugreport);
     }
 }
 
diff --git a/services/surfaceflinger/Tracing/LayerTracing.cpp b/services/surfaceflinger/Tracing/LayerTracing.cpp
index 403e105..41bcdf0 100644
--- a/services/surfaceflinger/Tracing/LayerTracing.cpp
+++ b/services/surfaceflinger/Tracing/LayerTracing.cpp
@@ -67,9 +67,27 @@
             break;
         }
         case Mode::MODE_GENERATED: {
+            // This tracing mode processes the buffer of transactions (owned by TransactionTracing),
+            // generates layers snapshots and writes them to perfetto. This happens every time an
+            // OnFlush event is received.
             ALOGD("Started generated tracing (waiting for OnFlush event to generated layers)");
             break;
         }
+        case Mode::MODE_GENERATED_BUGREPORT_ONLY: {
+            // Same as MODE_GENERATED, but only when the received OnFlush event is due to a
+            // bugreport being taken. This mode exists because the generated layers trace is very
+            // large (hundreds of MB), hence we want to include it only in bugreports and not in
+            // field uploads.
+            //
+            // Note that perfetto communicates only whether the OnFlush event is due to a bugreport
+            // or not, hence we need an additional "bugreport only" tracing mode.
+            // If perfetto had communicated when the OnFlush is due to a field upload, then we could
+            // have had a single "generated" tracing mode that would have been a noop in case of
+            // field uploads.
+            ALOGD("Started 'generated bugreport only' tracing"
+                  " (waiting for bugreport's OnFlush event to generate layers)");
+            break;
+        }
         case Mode::MODE_DUMP: {
             auto snapshot = mTakeLayersSnapshotProto(flags);
             addProtoSnapshotToOstream(std::move(snapshot), Mode::MODE_DUMP);
@@ -82,10 +100,18 @@
     }
 }
 
-void LayerTracing::onFlush(Mode mode, uint32_t flags) {
+void LayerTracing::onFlush(Mode mode, uint32_t flags, bool isBugreport) {
     // In "generated" mode process the buffer of transactions (owned by TransactionTracing),
-    // generate a sequence of layers snapshots and write them to perfetto.
-    if (mode != Mode::MODE_GENERATED) {
+    // generate layers snapshots and write them to perfetto.
+    if (mode != Mode::MODE_GENERATED && mode != Mode::MODE_GENERATED_BUGREPORT_ONLY) {
+        ALOGD("Skipping layers trace generation (not a 'generated' tracing session)");
+        return;
+    }
+
+    // In "generated bugreport only" mode skip the layers snapshot generation
+    // if the perfetto's OnFlush event is not due to a bugreport being taken.
+    if (mode == Mode::MODE_GENERATED_BUGREPORT_ONLY && !isBugreport) {
+        ALOGD("Skipping layers trace generation (not a bugreport OnFlush event)");
         return;
     }
 
@@ -147,14 +173,23 @@
 }
 
 void LayerTracing::writeSnapshotToPerfetto(const perfetto::protos::LayersSnapshotProto& snapshot,
-                                           Mode mode) {
+                                           Mode srcMode) {
     const auto snapshotBytes = snapshot.SerializeAsString();
 
     LayerDataSource::Trace([&](LayerDataSource::TraceContext context) {
-        if (mode != context.GetCustomTlsState()->mMode) {
+        auto dstMode = context.GetCustomTlsState()->mMode;
+        if (srcMode == Mode::MODE_GENERATED) {
+            // Layers snapshots produced by LayerTraceGenerator have srcMode == MODE_GENERATED
+            // and should be written to tracing sessions with MODE_GENERATED
+            // or MODE_GENERATED_BUGREPORT_ONLY.
+            if (dstMode != Mode::MODE_GENERATED && dstMode != Mode::MODE_GENERATED_BUGREPORT_ONLY) {
+                return;
+            }
+        } else if (srcMode != dstMode) {
             return;
         }
-        if (!checkAndUpdateLastVsyncIdWrittenToPerfetto(mode, snapshot.vsync_id())) {
+
+        if (!checkAndUpdateLastVsyncIdWrittenToPerfetto(srcMode, snapshot.vsync_id())) {
             return;
         }
         {
@@ -176,7 +211,7 @@
     // In some situations (e.g. two bugreports taken shortly one after the other) the generated
     // sequence of layers snapshots might overlap. Here we check the snapshot's vsyncid to make
     // sure that in generated tracing mode a given snapshot is written only once to perfetto.
-    if (mode != Mode::MODE_GENERATED) {
+    if (mode != Mode::MODE_GENERATED && mode != Mode::MODE_GENERATED_BUGREPORT_ONLY) {
         return true;
     }
 
diff --git a/services/surfaceflinger/Tracing/LayerTracing.h b/services/surfaceflinger/Tracing/LayerTracing.h
index fe7f06d..2895ba7 100644
--- a/services/surfaceflinger/Tracing/LayerTracing.h
+++ b/services/surfaceflinger/Tracing/LayerTracing.h
@@ -55,7 +55,9 @@
  * and written to perfetto.
  *
  *
- * E.g. start active mode tracing:
+ * E.g. start active mode tracing
+ * (replace mode value with MODE_DUMP, MODE_GENERATED or MODE_GENERATED_BUGREPORT_ONLY to enable
+ * different tracing modes):
  *
    adb shell -t perfetto \
      -c - --txt \
@@ -79,7 +81,7 @@
            }
        }
    }
-   EOF
+EOF
  *
  */
 class LayerTracing {
@@ -106,7 +108,7 @@
     // Start event from perfetto data source
     void onStart(Mode mode, uint32_t flags);
     // Flush event from perfetto data source
-    void onFlush(Mode mode, uint32_t flags);
+    void onFlush(Mode mode, uint32_t flags, bool isBugreport);
     // Stop event from perfetto data source
     void onStop(Mode mode);