Merge "Set isRelativeOf flag when calling setZOrderRelativeOf"
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 6a45625..7065460 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -908,7 +908,6 @@
}
setZOrderRelativeOf(nullptr);
}
- mCurrentState.isRelativeOf = false;
setTransactionFlags(eTransactionNeeded);
return true;
}
@@ -931,6 +930,8 @@
mCurrentState.zOrderRelativeOf = relativeOf;
mCurrentState.sequence++;
mCurrentState.modified = true;
+ mCurrentState.isRelativeOf = relativeOf != nullptr;
+
setTransactionFlags(eTransactionNeeded);
}
@@ -952,7 +953,6 @@
mCurrentState.sequence++;
mCurrentState.modified = true;
mCurrentState.z = relativeZ;
- mCurrentState.isRelativeOf = true;
auto oldZOrderRelativeOf = mCurrentState.zOrderRelativeOf.promote();
if (oldZOrderRelativeOf != nullptr) {
diff --git a/services/surfaceflinger/tests/RelativeZ_test.cpp b/services/surfaceflinger/tests/RelativeZ_test.cpp
index 8549db2..8c56d27 100644
--- a/services/surfaceflinger/tests/RelativeZ_test.cpp
+++ b/services/surfaceflinger/tests/RelativeZ_test.cpp
@@ -144,4 +144,63 @@
sc->checkPixel(1, 1, Color::GREEN.r, Color::GREEN.g, Color::GREEN.b);
}
}
+
+TEST_F(RelativeZTest, LayerAndRelativeRemoved) {
+ std::unique_ptr<ScreenCapture> sc;
+
+ // Background layer (RED)
+ // Foregroud layer (GREEN)
+ // Child layer (BLUE) (relative to relativeToLayer layer)
+ // Relative layer (WHITE)
+ sp<SurfaceControl> childLayer =
+ createColorLayer("Child layer", Color::BLUE, mForegroundLayer.get());
+ sp<SurfaceControl> relativeToLayer =
+ createColorLayer("Relative layer", Color::WHITE, mForegroundLayer.get());
+
+ Transaction{}
+ .setRelativeLayer(childLayer, relativeToLayer->getHandle(), 1)
+ .show(childLayer)
+ .show(relativeToLayer)
+ .apply();
+
+ {
+ // The childLayer should be in front of relativeToLayer.
+ ScreenCapture::captureScreen(&sc);
+ sc->checkPixel(1, 1, Color::BLUE.r, Color::BLUE.g, Color::BLUE.b);
+ }
+
+ // Remove layer that childLayer is relative to
+ // Background layer (RED)
+ // Foregroud layer (GREEN)
+ // Child layer (BLUE) (relative to relativeToLayer layer)
+ Transaction{}.reparent(relativeToLayer, nullptr).apply();
+ relativeToLayer = 0;
+
+ {
+ // The child layer is relative to an deleted layer so it won't be drawn.
+ ScreenCapture::captureScreen(&sc);
+ sc->checkPixel(1, 1, Color::GREEN.r, Color::GREEN.g, Color::GREEN.b);
+ }
+
+ // Background layer (RED)
+ // Foregroud layer (GREEN)
+ Transaction{}.reparent(childLayer, nullptr).apply();
+
+ {
+ // The child layer is offscreen, so it won't be drawn.
+ ScreenCapture::captureScreen(&sc);
+ sc->checkPixel(1, 1, Color::GREEN.r, Color::GREEN.g, Color::GREEN.b);
+ }
+
+ // Background layer (RED)
+ // Foregroud layer (GREEN)
+ // Child layer (BLUE)
+ Transaction{}.reparent(childLayer, mForegroundLayer->getHandle()).apply();
+
+ {
+ // The relative z info for child layer should be reset, leaving the child layer on top.
+ ScreenCapture::captureScreen(&sc);
+ sc->checkPixel(1, 1, Color::BLUE.r, Color::BLUE.g, Color::BLUE.b);
+ }
+}
} // namespace android