[sf] fix overflow in snapshot generator
Fixes a couple of issues that caused the snapshot
builder to crash from a stack overflow:
- mirror layers were temporarily rooted to the display
with the default layer stack
- there was no check to prevent a layer from mirroring
itself (causing a cycle in the hierarchy)
Also modifies the layer trace generator to easily generate
test data for the transaction trace test suite.
Test: atest transactiontrace_testsuite
Fixes: 282110579
Change-Id: I2954f838e333b857b4b755e11666c2580d97c2b6
diff --git a/services/surfaceflinger/FrontEnd/LayerLifecycleManager.cpp b/services/surfaceflinger/FrontEnd/LayerLifecycleManager.cpp
index cd9515c..c9eb9c4 100644
--- a/services/surfaceflinger/FrontEnd/LayerLifecycleManager.cpp
+++ b/services/surfaceflinger/FrontEnd/LayerLifecycleManager.cpp
@@ -28,6 +28,14 @@
using namespace ftl::flag_operators;
+namespace {
+// Returns true if the layer is root of a display and can be mirrored by mirroringLayer
+bool canMirrorRootLayer(RequestedLayerState& mirroringLayer, RequestedLayerState& rootLayer) {
+ return rootLayer.isRoot() && rootLayer.layerStack == mirroringLayer.layerStackToMirror &&
+ rootLayer.id != mirroringLayer.id;
+}
+} // namespace
+
void LayerLifecycleManager::addLayers(std::vector<std::unique_ptr<RequestedLayerState>> newLayers) {
if (newLayers.empty()) {
return;
@@ -46,11 +54,15 @@
layer.parentId = linkLayer(layer.parentId, layer.id);
layer.relativeParentId = linkLayer(layer.relativeParentId, layer.id);
if (layer.layerStackToMirror != ui::INVALID_LAYER_STACK) {
+ // Set mirror layer's default layer stack to -1 so it doesn't end up rendered on a
+ // display accidentally.
+ layer.layerStack = 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) {
+ if (canMirrorRootLayer(layer, *rootLayer)) {
layer.mirrorIds.emplace_back(rootLayer->id);
linkLayer(rootLayer->id, layer.id);
}
@@ -383,10 +395,9 @@
// 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;
+ for (uint32_t mirroringLayerId : mDisplayMirroringLayers) {
+ RequestedLayerState* mirrorLayer = getLayerFromId(mirroringLayerId);
+ bool canBeMirrored = canMirrorRootLayer(*mirrorLayer, rootLayer);
bool currentlyMirrored =
std::find(mirrorLayer->mirrorIds.begin(), mirrorLayer->mirrorIds.end(),
rootLayer.id) != mirrorLayer->mirrorIds.end();