[sf] write transaction trace to disk on error

Flush always on transaction traces to disk when we detect
errors like: - out of order buffer updates or cycles in
the layer hierarchy so it easier to investigate issues
from dogfood (ref bug b/272189296)

Bug: 282110579, 238781169
Fixes: 277265947
Test: presubmit

Change-Id: I22dbd7cd43d94763ac941f0c3871dc7e4ea8db8d
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index f0ccc14..e0ffb6b 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -909,6 +909,29 @@
         ALOGE("Run StartPropertySetThread failed!");
     }
 
+    if (mTransactionTracing) {
+        TransactionTraceWriter::getInstance().setWriterFunction([&](const std::string& prefix,
+                                                                    bool overwrite) {
+            auto writeFn = [&]() {
+                const std::string filename =
+                        TransactionTracing::DIR_NAME + prefix + TransactionTracing::FILE_NAME;
+                if (overwrite) {
+                    std::ifstream file(filename);
+                    if (file.is_open()) {
+                        return;
+                    }
+                }
+                mTransactionTracing->flush();
+                mTransactionTracing->writeToFile(filename);
+            };
+            if (std::this_thread::get_id() == mMainThreadId) {
+                writeFn();
+            } else {
+                mScheduler->schedule(writeFn).get();
+            }
+        });
+    }
+
     ALOGV("Done initializing");
 }
 
@@ -6728,7 +6751,7 @@
                         mTransactionTracing->setBufferSize(
                                 TransactionTracing::ACTIVE_TRACING_BUFFER_SIZE);
                     } else {
-                        mTransactionTracing->writeToFile();
+                        TransactionTraceWriter::getInstance().invoke("", /* overwrite= */ true);
                         mTransactionTracing->setBufferSize(
                                 TransactionTracing::CONTINUOUS_TRACING_BUFFER_SIZE);
                     }