SF: Support display mirroring with new frontend

Bug: 238781169
Test: presubmit
Change-Id: I569822bd1dd70e2b0b660042329abb27f263dc66
diff --git a/services/surfaceflinger/FrontEnd/LayerCreationArgs.h b/services/surfaceflinger/FrontEnd/LayerCreationArgs.h
index 7b5a157..9d2aaab 100644
--- a/services/surfaceflinger/FrontEnd/LayerCreationArgs.h
+++ b/services/surfaceflinger/FrontEnd/LayerCreationArgs.h
@@ -18,10 +18,12 @@
 
 #include <binder/Binder.h>
 #include <gui/LayerMetadata.h>
+#include <ui/LayerStack.h>
 #include <utils/StrongPointer.h>
 #include <cstdint>
 #include <limits>
 #include <optional>
+
 constexpr uint32_t UNASSIGNED_LAYER_ID = std::numeric_limits<uint32_t>::max();
 
 namespace android {
@@ -51,6 +53,7 @@
     bool addToRoot = true;
     wp<IBinder> parentHandle = nullptr;
     wp<IBinder> mirrorLayerHandle = nullptr;
+    ui::LayerStack layerStackToMirror = ui::INVALID_LAYER_STACK;
 };
 
 } // namespace android::surfaceflinger
diff --git a/services/surfaceflinger/FrontEnd/LayerHierarchy.cpp b/services/surfaceflinger/FrontEnd/LayerHierarchy.cpp
index 678d36b..a4fac1c 100644
--- a/services/surfaceflinger/FrontEnd/LayerHierarchy.cpp
+++ b/services/surfaceflinger/FrontEnd/LayerHierarchy.cpp
@@ -252,8 +252,8 @@
     attachToParent(hierarchy);
     attachToRelativeParent(hierarchy);
 
-    if (layer->mirrorId != UNASSIGNED_LAYER_ID) {
-        LayerHierarchy* mirror = getHierarchyFromId(layer->mirrorId);
+    for (uint32_t mirrorId : layer->mirrorIds) {
+        LayerHierarchy* mirror = getHierarchyFromId(mirrorId);
         hierarchy->addChild(mirror, LayerHierarchy::Variant::Mirror);
     }
 }
@@ -292,14 +292,14 @@
     auto it = hierarchy->mChildren.begin();
     while (it != hierarchy->mChildren.end()) {
         if (it->second == LayerHierarchy::Variant::Mirror) {
-            hierarchy->mChildren.erase(it);
-            break;
+            it = hierarchy->mChildren.erase(it);
+        } else {
+            it++;
         }
-        it++;
     }
 
-    if (layer->mirrorId != UNASSIGNED_LAYER_ID) {
-        hierarchy->addChild(getHierarchyFromId(layer->mirrorId), LayerHierarchy::Variant::Mirror);
+    for (uint32_t mirrorId : layer->mirrorIds) {
+        hierarchy->addChild(getHierarchyFromId(mirrorId), LayerHierarchy::Variant::Mirror);
     }
 }
 
diff --git a/services/surfaceflinger/FrontEnd/LayerLifecycleManager.cpp b/services/surfaceflinger/FrontEnd/LayerLifecycleManager.cpp
index 5514c06..547a852 100644
--- a/services/surfaceflinger/FrontEnd/LayerLifecycleManager.cpp
+++ b/services/surfaceflinger/FrontEnd/LayerLifecycleManager.cpp
@@ -44,9 +44,28 @@
 
         layer.parentId = linkLayer(layer.parentId, layer.id);
         layer.relativeParentId = linkLayer(layer.relativeParentId, layer.id);
-        layer.mirrorId = linkLayer(layer.mirrorId, layer.id);
+        if (layer.layerStackToMirror != ui::INVALID_LAYER_STACK) {
+            // if this layer is mirroring a display, then walk though all the existing root layers
+            // for the layer stack and add them as children to be mirrored.
+            mDisplayMirroringLayers.emplace_back(layer.id);
+            for (auto& rootLayer : mLayers) {
+                if (rootLayer->isRoot() && rootLayer->layerStack == layer.layerStackToMirror) {
+                    layer.mirrorIds.emplace_back(rootLayer->id);
+                    linkLayer(rootLayer->id, layer.id);
+                }
+            }
+        } else {
+            // Check if we are mirroring a single layer, and if so add it to the list of children
+            // to be mirrored.
+            layer.layerIdToMirror = linkLayer(layer.layerIdToMirror, layer.id);
+            if (layer.layerIdToMirror != UNASSIGNED_LAYER_ID) {
+                layer.mirrorIds.emplace_back(layer.layerIdToMirror);
+            }
+        }
         layer.touchCropId = linkLayer(layer.touchCropId, layer.id);
-
+        if (layer.isRoot()) {
+            updateDisplayMirrorLayers(layer);
+        }
         mLayers.emplace_back(std::move(newLayer));
     }
 }
@@ -85,7 +104,14 @@
 
         layer.parentId = unlinkLayer(layer.parentId, layer.id);
         layer.relativeParentId = unlinkLayer(layer.relativeParentId, layer.id);
-        layer.mirrorId = unlinkLayer(layer.mirrorId, layer.id);
+        if (layer.layerStackToMirror != ui::INVALID_LAYER_STACK) {
+            layer.mirrorIds = unlinkLayers(layer.mirrorIds, layer.id);
+            swapErase(mDisplayMirroringLayers, layer.id);
+        } else {
+            layer.layerIdToMirror = unlinkLayer(layer.layerIdToMirror, layer.id);
+            layer.mirrorIds.clear();
+        }
+
         layer.touchCropId = unlinkLayer(layer.touchCropId, layer.id);
 
         auto& references = it->second.references;
@@ -106,8 +132,8 @@
             if (linkedLayer->relativeParentId == layer.id) {
                 linkedLayer->relativeParentId = UNASSIGNED_LAYER_ID;
             }
-            if (linkedLayer->mirrorId == layer.id) {
-                linkedLayer->mirrorId = UNASSIGNED_LAYER_ID;
+            if (swapErase(linkedLayer->mirrorIds, layer.id)) {
+                linkedLayer->changes |= RequestedLayerState::Changes::Mirror;
             }
             if (linkedLayer->touchCropId == layer.id) {
                 linkedLayer->touchCropId = UNASSIGNED_LAYER_ID;
@@ -200,6 +226,12 @@
             if (oldParentId != layer->parentId) {
                 unlinkLayer(oldParentId, layer->id);
                 layer->parentId = linkLayer(layer->parentId, layer->id);
+                if (oldParentId == UNASSIGNED_LAYER_ID) {
+                    updateDisplayMirrorLayers(*layer);
+                }
+            }
+            if (layer->what & layer_state_t::eLayerStackChanged && layer->isRoot()) {
+                updateDisplayMirrorLayers(*layer);
             }
             if (oldRelativeParentId != layer->relativeParentId) {
                 unlinkLayer(oldRelativeParentId, layer->id);
@@ -308,6 +340,14 @@
     return UNASSIGNED_LAYER_ID;
 }
 
+std::vector<uint32_t> LayerLifecycleManager::unlinkLayers(const std::vector<uint32_t>& layerIds,
+                                                          uint32_t linkedLayer) {
+    for (uint32_t layerId : layerIds) {
+        unlinkLayer(layerId, linkedLayer);
+    }
+    return {};
+}
+
 std::string LayerLifecycleManager::References::getDebugString() const {
     std::string debugInfo = owner.name + "[" + std::to_string(owner.id) + "] refs:";
     std::for_each(references.begin(), references.end(),
@@ -329,4 +369,30 @@
     mGlobalChanges |= RequestedLayerState::Changes::Hierarchy;
 }
 
+// Some layers mirror the entire display stack. Since we don't have a single root layer per display
+// we have to track all these layers and update what they mirror when the list of root layers
+// on a display changes. This function walks through the list of display mirroring layers
+// and updates its list of layers that its mirroring. This function should be called when a new
+// root layer is added, removed or moved to another display.
+void LayerLifecycleManager::updateDisplayMirrorLayers(RequestedLayerState& rootLayer) {
+    for (uint32_t mirrorLayerId : mDisplayMirroringLayers) {
+        RequestedLayerState* mirrorLayer = getLayerFromId(mirrorLayerId);
+        bool canBeMirrored =
+                rootLayer.isRoot() && rootLayer.layerStack == mirrorLayer->layerStackToMirror;
+        bool currentlyMirrored =
+                std::find(mirrorLayer->mirrorIds.begin(), mirrorLayer->mirrorIds.end(),
+                          rootLayer.id) != mirrorLayer->mirrorIds.end();
+
+        if (canBeMirrored && !currentlyMirrored) {
+            mirrorLayer->mirrorIds.emplace_back(rootLayer.id);
+            linkLayer(rootLayer.id, mirrorLayer->id);
+            mirrorLayer->changes |= RequestedLayerState::Changes::Mirror;
+        } else if (!canBeMirrored && currentlyMirrored) {
+            swapErase(mirrorLayer->mirrorIds, rootLayer.id);
+            unlinkLayer(rootLayer.id, mirrorLayer->id);
+            mirrorLayer->changes |= RequestedLayerState::Changes::Mirror;
+        }
+    }
+}
+
 } // namespace android::surfaceflinger::frontend
diff --git a/services/surfaceflinger/FrontEnd/LayerLifecycleManager.h b/services/surfaceflinger/FrontEnd/LayerLifecycleManager.h
index 63a7afc..25d27ee 100644
--- a/services/surfaceflinger/FrontEnd/LayerLifecycleManager.h
+++ b/services/surfaceflinger/FrontEnd/LayerLifecycleManager.h
@@ -80,6 +80,9 @@
     std::vector<uint32_t>* getLinkedLayersFromId(uint32_t);
     uint32_t linkLayer(uint32_t layerId, uint32_t layerToLink);
     uint32_t unlinkLayer(uint32_t layerId, uint32_t linkedLayer);
+    std::vector<uint32_t> unlinkLayers(const std::vector<uint32_t>& layerIds, uint32_t linkedLayer);
+
+    void updateDisplayMirrorLayers(RequestedLayerState& rootLayer);
 
     struct References {
         // Lifetime tied to mLayers
@@ -90,6 +93,8 @@
     std::unordered_map<uint32_t, References> mIdToLayer;
     // Listeners are invoked once changes are committed.
     std::vector<std::shared_ptr<ILifecycleListener>> mListeners;
+    // Layers that mirror a display stack (see updateDisplayMirrorLayers)
+    std::vector<uint32_t> mDisplayMirroringLayers;
 
     // Aggregation of changes since last commit.
     ftl::Flags<RequestedLayerState::Changes> mGlobalChanges;
diff --git a/services/surfaceflinger/FrontEnd/LayerSnapshot.cpp b/services/surfaceflinger/FrontEnd/LayerSnapshot.cpp
index 3a0540c..4e69565 100644
--- a/services/surfaceflinger/FrontEnd/LayerSnapshot.cpp
+++ b/services/surfaceflinger/FrontEnd/LayerSnapshot.cpp
@@ -112,6 +112,10 @@
 }
 
 bool LayerSnapshot::getIsVisible() const {
+    if (handleSkipScreenshotFlag & outputFilter.toInternalDisplay) {
+        return false;
+    }
+
     if (!hasSomethingToDraw()) {
         return false;
     }
@@ -125,6 +129,7 @@
 
 std::string LayerSnapshot::getIsVisibleReason() const {
     // not visible
+    if (handleSkipScreenshotFlag & outputFilter.toInternalDisplay) return "eLayerSkipScreenshot";
     if (!hasSomethingToDraw()) return "!hasSomethingToDraw";
     if (invalidTransform) return "invalidTransform";
     if (isHiddenByPolicyFromParent) return "hidden by parent or layer flag";
diff --git a/services/surfaceflinger/FrontEnd/LayerSnapshot.h b/services/surfaceflinger/FrontEnd/LayerSnapshot.h
index 4512ade..159410f 100644
--- a/services/surfaceflinger/FrontEnd/LayerSnapshot.h
+++ b/services/surfaceflinger/FrontEnd/LayerSnapshot.h
@@ -84,6 +84,7 @@
     gui::GameMode gameMode;
     scheduler::LayerInfo::FrameRate frameRate;
     ui::Transform::RotationFlags fixedTransformHint;
+    bool handleSkipScreenshotFlag = false;
     ChildState childState;
 
     static bool isOpaqueFormat(PixelFormat format);
diff --git a/services/surfaceflinger/FrontEnd/LayerSnapshotBuilder.cpp b/services/surfaceflinger/FrontEnd/LayerSnapshotBuilder.cpp
index cc26591..d0ffe61 100644
--- a/services/surfaceflinger/FrontEnd/LayerSnapshotBuilder.cpp
+++ b/services/surfaceflinger/FrontEnd/LayerSnapshotBuilder.cpp
@@ -714,6 +714,10 @@
         snapshot.fixedTransformHint = requested.fixedTransformHint != ui::Transform::ROT_INVALID
                 ? requested.fixedTransformHint
                 : parentSnapshot.fixedTransformHint;
+        // Display mirrors are always placed in a VirtualDisplay so we never want to capture layers
+        // marked as skip capture
+        snapshot.handleSkipScreenshotFlag = parentSnapshot.handleSkipScreenshotFlag ||
+                (requested.layerStackToMirror != ui::INVALID_LAYER_STACK);
     }
 
     if (forceUpdate || requested.changes.get() != 0) {
diff --git a/services/surfaceflinger/FrontEnd/RequestedLayerState.cpp b/services/surfaceflinger/FrontEnd/RequestedLayerState.cpp
index b7fa4f0..d63b126 100644
--- a/services/surfaceflinger/FrontEnd/RequestedLayerState.cpp
+++ b/services/surfaceflinger/FrontEnd/RequestedLayerState.cpp
@@ -45,6 +45,16 @@
     return layerId == UNASSIGNED_LAYER_ID ? "none" : std::to_string(layerId);
 }
 
+std::string layerIdsToString(const std::vector<uint32_t>& layerIds) {
+    std::stringstream stream;
+    stream << "{";
+    for (auto layerId : layerIds) {
+        stream << layerId << ",";
+    }
+    stream << "}";
+    return stream.str();
+}
+
 } // namespace
 
 RequestedLayerState::RequestedLayerState(const LayerCreationArgs& args)
@@ -64,8 +74,11 @@
     if (args.parentHandle != nullptr) {
         canBeRoot = false;
     }
-    mirrorId = LayerHandle::getLayerId(args.mirrorLayerHandle.promote());
-    if (mirrorId != UNASSIGNED_LAYER_ID) {
+    layerIdToMirror = LayerHandle::getLayerId(args.mirrorLayerHandle.promote());
+    if (layerIdToMirror != UNASSIGNED_LAYER_ID) {
+        changes |= RequestedLayerState::Changes::Mirror;
+    } else if (args.layerStackToMirror != ui::INVALID_LAYER_STACK) {
+        layerStackToMirror = args.layerStackToMirror;
         changes |= RequestedLayerState::Changes::Mirror;
     }
 
@@ -309,7 +322,7 @@
     return "[" + std::to_string(id) + "]" + name + ",parent=" + layerIdToString(parentId) +
             ",relativeParent=" + layerIdToString(relativeParentId) +
             ",isRelativeOf=" + std::to_string(isRelativeOf) +
-            ",mirrorId=" + layerIdToString(mirrorId) +
+            ",mirrorIds=" + layerIdsToString(mirrorIds) +
             ",handleAlive=" + std::to_string(handleAlive) + ",z=" + std::to_string(z);
 }
 
diff --git a/services/surfaceflinger/FrontEnd/RequestedLayerState.h b/services/surfaceflinger/FrontEnd/RequestedLayerState.h
index 3a16531..6317b95 100644
--- a/services/surfaceflinger/FrontEnd/RequestedLayerState.h
+++ b/services/surfaceflinger/FrontEnd/RequestedLayerState.h
@@ -97,13 +97,15 @@
     std::shared_ptr<renderengine::ExternalTexture> externalTexture;
     gui::GameMode gameMode;
     scheduler::LayerInfo::FrameRate requestedFrameRate;
+    ui::LayerStack layerStackToMirror = ui::INVALID_LAYER_STACK;
+    uint32_t layerIdToMirror = UNASSIGNED_LAYER_ID;
 
     // book keeping states
     bool handleAlive = true;
     bool isRelativeOf = false;
     uint32_t parentId = UNASSIGNED_LAYER_ID;
     uint32_t relativeParentId = UNASSIGNED_LAYER_ID;
-    uint32_t mirrorId = UNASSIGNED_LAYER_ID;
+    std::vector<uint32_t> mirrorIds{};
     uint32_t touchCropId = UNASSIGNED_LAYER_ID;
     uint32_t bgColorLayerId = UNASSIGNED_LAYER_ID;
     ftl::Flags<RequestedLayerState::Changes> changes;
diff --git a/services/surfaceflinger/FrontEnd/SwapErase.h b/services/surfaceflinger/FrontEnd/SwapErase.h
index f672f99..0061c53 100644
--- a/services/surfaceflinger/FrontEnd/SwapErase.h
+++ b/services/surfaceflinger/FrontEnd/SwapErase.h
@@ -23,12 +23,15 @@
 // remove an element from a vector that avoids relocating all the elements after the one
 // that is erased.
 template <typename T>
-void swapErase(std::vector<T>& vec, const T& value) {
+bool swapErase(std::vector<T>& vec, const T& value) {
+    bool found = false;
     auto it = std::find(vec.begin(), vec.end(), value);
     if (it != vec.end()) {
         std::iter_swap(it, vec.end() - 1);
         vec.erase(vec.end() - 1);
+        found = true;
     }
+    return found;
 }
 
 // Similar to swapErase(std::vector<T>& vec, const T& value) but erases the first element