Update LayerVector if the mirrorRoot is already inside
Mirror display creation and commitment are executed in different
threads. The mMirrorDisplays may not have been updated when
commitMirrorDisplays, so do the commitCreatedLayers first. If
handleLayerCreatedLocked adding mirrorRoot to LayerVector of
mCurrentState is executed before commitMirrorDisplays updating the
LayerStack of the mirrorRoot as -1, The order of LayerVector will
be disordered. Finally, the mirrorRoot cannot be found when removing.
In order to fix this problem. Before commitMirrorDisplays sets the
LayerStack of mirrorRoot, it needs to confirm whether the mirrorRoot
is in LayerVector. If it is in LayerVector, re-add the layer to
ensure that it is on the tail.
Bug: 294942764
Test: Monkey test with 10 screen recording
(cherry picked from https://partner-android-review.googlesource.com/q/commit:dd3d3ef5a393ee331c14de707321b3e7e3f60446)
Merged-In: Iebcab7249ddbab31e8549c6d51a9b09c4c3549f4
Change-Id: Iebcab7249ddbab31e8549c6d51a9b09c4c3549f4
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 286222e..c61f2a1 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -8102,7 +8102,13 @@
// Set mirror layer's default layer stack to -1 so it doesn't end up rendered on a display
// accidentally.
sp<Layer> rootMirrorLayer = LayerHandle::getLayer(mirrorDisplay.rootHandle);
- rootMirrorLayer->setLayerStack(ui::LayerStack::fromValue(-1));
+ ssize_t idx = mCurrentState.layersSortedByZ.indexOf(rootMirrorLayer);
+ bool ret = rootMirrorLayer->setLayerStack(ui::LayerStack::fromValue(-1));
+ if (idx >= 0 && ret) {
+ mCurrentState.layersSortedByZ.removeAt(idx);
+ mCurrentState.layersSortedByZ.add(rootMirrorLayer);
+ }
+
for (const auto& layer : mDrawingState.layersSortedByZ) {
if (layer->getLayerStack() != mirrorDisplay.layerStack ||
layer->isInternalDisplayOverlay()) {