Dump offscreen layers in dumpsys and winscope trace

Now that clients can keep layers alive by holding a reference to its handle and clients can also
create layers, we need to an easier way to keep track of layers that are offscreen but not
destroyed. This change keeps track of the calling pid and uid so it is easier to track the creating
process. Since the tracing thread will also read from mOffscreenLayers, we want to protect
access to it with the tracing lock.

Bug:127687760
Test: run dumpsys check for offscreen layers
Test: capture sf trace and check for offscreen layers
Change-Id: I400f33b11b0a4f78f4c35027c457eb56ff12c22e
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 5121835..688c5ee 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -22,6 +22,7 @@
 #include "Layer.h"
 
 #include <android-base/stringprintf.h>
+#include <binder/IPCThreadState.h>
 #include <compositionengine/Display.h>
 #include <compositionengine/Layer.h>
 #include <compositionengine/LayerFECompositionState.h>
@@ -121,7 +122,8 @@
     mFrameTracker.setDisplayRefreshPeriod(compositorTiming.interval);
 
     mSchedulerLayerHandle = mFlinger->mScheduler->registerLayer(mName.c_str(), mWindowType);
-
+    mCallingPid = args.callingPid;
+    mCallingUid = args.callingUid;
     mFlinger->onLayerCreated();
 }
 
@@ -135,6 +137,21 @@
     mFlinger->onLayerDestroyed(this);
 }
 
+LayerCreationArgs::LayerCreationArgs(SurfaceFlinger* flinger, const sp<Client>& client,
+                                     const String8& name, uint32_t w, uint32_t h, uint32_t flags,
+                                     LayerMetadata metadata)
+      : flinger(flinger),
+        client(client),
+        name(name),
+        w(w),
+        h(h),
+        flags(flags),
+        metadata(std::move(metadata)) {
+    IPCThreadState* ipc = IPCThreadState::self();
+    callingPid = ipc->getCallingPid();
+    callingUid = ipc->getCallingUid();
+}
+
 // ---------------------------------------------------------------------------
 // callbacks
 // ---------------------------------------------------------------------------
@@ -1340,6 +1357,11 @@
     mFrameEventHistory.dump(result);
 }
 
+void Layer::dumpCallingUidPid(std::string& result) const {
+    StringAppendF(&result, "Layer %s (%s) pid:%d uid:%d\n", getName().string(), getType(),
+                  mCallingPid, mCallingUid);
+}
+
 void Layer::onDisconnect() {
     Mutex::Autolock lock(mFrameEventHistoryMutex);
     mFrameEventHistory.onDisconnect();
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index 9107189..4954239 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -80,9 +80,7 @@
 
 struct LayerCreationArgs {
     LayerCreationArgs(SurfaceFlinger* flinger, const sp<Client>& client, const String8& name,
-                      uint32_t w, uint32_t h, uint32_t flags, LayerMetadata metadata)
-          : flinger(flinger), client(client), name(name), w(w), h(h), flags(flags),
-            metadata(std::move(metadata)) {}
+                      uint32_t w, uint32_t h, uint32_t flags, LayerMetadata metadata);
 
     SurfaceFlinger* flinger;
     const sp<Client>& client;
@@ -91,6 +89,8 @@
     uint32_t h;
     uint32_t flags;
     LayerMetadata metadata;
+    pid_t callingPid;
+    uid_t callingUid;
 };
 
 class Layer : public virtual compositionengine::LayerFE {
@@ -600,6 +600,7 @@
     void miniDump(std::string& result, const sp<DisplayDevice>& display) const;
     void dumpFrameStats(std::string& result) const;
     void dumpFrameEvents(std::string& result);
+    void dumpCallingUidPid(std::string& result) const;
     void clearFrameStats();
     void logFrameStats();
     void getFrameStats(FrameStats* outStats) const;
@@ -924,6 +925,11 @@
     bool mGetHandleCalled = false;
 
     void removeRemoteSyncPoints();
+
+    // Tracks the process and user id of the caller when creating this layer
+    // to help debugging.
+    pid_t mCallingPid;
+    uid_t mCallingUid;
 };
 
 } // namespace android
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index e804923..c081dde 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -2872,32 +2872,31 @@
 
 void SurfaceFlinger::commitTransaction()
 {
-    if (!mLayersPendingRemoval.isEmpty()) {
-        // Notify removed layers now that they can't be drawn from
-        for (const auto& l : mLayersPendingRemoval) {
-            recordBufferingStats(l->getName().string(),
-                    l->getOccupancyHistory(true));
-
-            // Ensure any buffers set to display on any children are released.
-            if (l->isRemovedFromCurrentState()) {
-                l->latchAndReleaseBuffer();
-            }
-
-            // If the layer has been removed and has no parent, then it will not be reachable
-            // when traversing layers on screen. Add the layer to the offscreenLayers set to
-            // ensure we can copy its current to drawing state.
-            if (!l->getParent()) {
-                mOffscreenLayers.emplace(l.get());
-            }
-        }
-        mLayersPendingRemoval.clear();
-    }
-
-    // If this transaction is part of a window animation then the next frame
-    // we composite should be considered an animation as well.
-    mAnimCompositionPending = mAnimTransactionPending;
-
     withTracingLock([&]() {
+        if (!mLayersPendingRemoval.isEmpty()) {
+            // Notify removed layers now that they can't be drawn from
+            for (const auto& l : mLayersPendingRemoval) {
+                recordBufferingStats(l->getName().string(), l->getOccupancyHistory(true));
+
+                // Ensure any buffers set to display on any children are released.
+                if (l->isRemovedFromCurrentState()) {
+                    l->latchAndReleaseBuffer();
+                }
+
+                // If the layer has been removed and has no parent, then it will not be reachable
+                // when traversing layers on screen. Add the layer to the offscreenLayers set to
+                // ensure we can copy its current to drawing state.
+                if (!l->getParent()) {
+                    mOffscreenLayers.emplace(l.get());
+                }
+            }
+            mLayersPendingRemoval.clear();
+        }
+
+        // If this transaction is part of a window animation then the next frame
+        // we composite should be considered an animation as well.
+        mAnimCompositionPending = mAnimTransactionPending;
+
         mDrawingState = mCurrentState;
         // clear the "changed" flags in current state
         mCurrentState.colorMatrixChanged = false;
@@ -4286,9 +4285,11 @@
             if (asProto) {
                 result.append(layersProto.SerializeAsString());
             } else {
+                // Dump info that we need to access from the main thread
                 const auto layerTree = LayerProtoParser::generateLayerTree(layersProto);
                 result.append(LayerProtoParser::layerTreeToString(layerTree));
                 result.append("\n");
+                dumpOffscreenLayers(result);
             }
         }
     }
@@ -4546,12 +4547,54 @@
     return layersProto;
 }
 
+void SurfaceFlinger::dumpOffscreenLayersProto(LayersProto& layersProto, uint32_t traceFlags) const {
+    // Add a fake invisible root layer to the proto output and parent all the offscreen layers to
+    // it.
+    LayerProto* rootProto = layersProto.add_layers();
+    const int32_t offscreenRootLayerId = INT32_MAX - 2;
+    rootProto->set_id(offscreenRootLayerId);
+    rootProto->set_name("Offscreen Root");
+
+    for (Layer* offscreenLayer : mOffscreenLayers) {
+        // Add layer as child of the fake root
+        rootProto->add_children(offscreenLayer->sequence);
+
+        // Add layer
+        LayerProto* layerProto = layersProto.add_layers();
+        offscreenLayer->writeToProtoDrawingState(layerProto, traceFlags);
+        offscreenLayer->writeToProtoCommonState(layerProto, LayerVector::StateSet::Drawing,
+                                                traceFlags);
+        layerProto->set_parent(offscreenRootLayerId);
+
+        // Add children
+        offscreenLayer->traverseInZOrder(LayerVector::StateSet::Drawing, [&](Layer* layer) {
+            if (layer == offscreenLayer) {
+                return;
+            }
+            LayerProto* childProto = layersProto.add_layers();
+            layer->writeToProtoDrawingState(childProto, traceFlags);
+            layer->writeToProtoCommonState(childProto, LayerVector::StateSet::Drawing, traceFlags);
+        });
+    }
+}
+
 LayersProto SurfaceFlinger::dumpProtoFromMainThread(uint32_t traceFlags) {
     LayersProto layersProto;
     postMessageSync(new LambdaMessage([&]() { layersProto = dumpDrawingStateProto(traceFlags); }));
     return layersProto;
 }
 
+void SurfaceFlinger::dumpOffscreenLayers(std::string& result) {
+    result.append("Offscreen Layers:\n");
+    postMessageSync(new LambdaMessage([&]() {
+        for (Layer* offscreenLayer : mOffscreenLayers) {
+            offscreenLayer->traverseInZOrder(LayerVector::StateSet::Drawing, [&](Layer* layer) {
+                layer->dumpCallingUidPid(result);
+            });
+        }
+    }));
+}
+
 void SurfaceFlinger::dumpAllLocked(const DumpArgs& args, std::string& result) const {
     const bool colorize = !args.empty() && args[0] == String16("--color");
     Colorizer colorizer(colorize);
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 8408ef5..d44ff9c 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -876,8 +876,11 @@
     void dumpDisplayIdentificationData(std::string& result) const;
     void dumpWideColorInfo(std::string& result) const;
     LayersProto dumpDrawingStateProto(uint32_t traceFlags = SurfaceTracing::TRACE_ALL) const;
+    void dumpOffscreenLayersProto(LayersProto& layersProto,
+                                  uint32_t traceFlags = SurfaceTracing::TRACE_ALL) const;
     LayersProto dumpProtoFromMainThread(uint32_t traceFlags = SurfaceTracing::TRACE_ALL)
             EXCLUDES(mStateLock);
+    void dumpOffscreenLayers(std::string& result) EXCLUDES(mStateLock);
     void withTracingLock(std::function<void()> operation) REQUIRES(mStateLock);
 
     bool isLayerTripleBufferingDisabled() const {
diff --git a/services/surfaceflinger/SurfaceTracing.cpp b/services/surfaceflinger/SurfaceTracing.cpp
index 9053f2c..eb26cd0 100644
--- a/services/surfaceflinger/SurfaceTracing.cpp
+++ b/services/surfaceflinger/SurfaceTracing.cpp
@@ -163,6 +163,7 @@
     entry.set_elapsed_realtime_nanos(elapsedRealtimeNano());
     entry.set_where(where);
     LayersProto layers(mFlinger.dumpDrawingStateProto(mTraceFlags));
+    mFlinger.dumpOffscreenLayersProto(layers);
     entry.mutable_layers()->Swap(&layers);
 
     return entry;