Respect relative layer value if in tree when screenshotting.
Relative layers need to be screenshotted so the dim layer can be
captured in the correct place. However, there are other relative layers
that are not in the tree that shouldn't be part of the screenshot. This
change allows relative layer value to be handled correctly as long as the
layer it's relative to is in the tree to capture. This ensures relative
layers in the tree are captured the correct order, but also ignores any
relative layers that are not in the tree.
Change-Id: If0e0ea1417f01ad1bfe518744ae2b9827009c4c6
Fixes: 77823704
Test: Open app with dialog and go to recents. Dim is screenshotted.
Test: Open app with IME and go to recents. IME is not screenshotted.
Test: Transaction_test#DontCaptureRelativeOutsideTree, CaptureRelativeInTree
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index d382a1a..be3967b 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -51,6 +51,7 @@
#include "RenderEngine/Texture.h"
#include <math/vec4.h>
+#include <vector>
using namespace android::surfaceflinger;
@@ -564,6 +565,10 @@
const LayerVector::Visitor& visitor);
void traverseInZOrder(LayerVector::StateSet stateSet, const LayerVector::Visitor& visitor);
+ /**
+ * Traverse only children in z order, ignoring relative layers that are not children of the
+ * parent.
+ */
void traverseChildrenInZOrder(LayerVector::StateSet stateSet,
const LayerVector::Visitor& visitor);
@@ -778,6 +783,22 @@
wp<Layer> mDrawingParent;
mutable LayerBE mBE;
+
+private:
+ /**
+ * Returns an unsorted vector of all layers that are part of this tree.
+ * That includes the current layer and all its descendants.
+ */
+ std::vector<Layer*> getLayersInTree(LayerVector::StateSet stateSet);
+ /**
+ * Traverses layers that are part of this tree in the correct z order.
+ * layersInTree must be sorted before calling this method.
+ */
+ void traverseChildrenInZOrderInner(const std::vector<Layer*>& layersInTree,
+ LayerVector::StateSet stateSet,
+ const LayerVector::Visitor& visitor);
+ LayerVector makeChildrenTraversalList(LayerVector::StateSet stateSet,
+ const std::vector<Layer*>& layersInTree);
};
// ---------------------------------------------------------------------------