Allow offscreen mirrored layers to be captured.
If an offscreen layer is valid and has content, we should be able to
take a screen capture of it.
If we're mirroring content, but it's not on screen, we need
to ensure updateMirrorInfo is called to get the updated hierarchy. This
will allow the mirror content to get properly screenshot
Test: screencapture offscreen
Test: MirrorLayerTest
Test: ScreenCaptureTest
Change-Id: I31f806eb616e2d6f800da6328c9878a3e47d6a14
Bug: 188222480
diff --git a/services/surfaceflinger/tests/ScreenCapture_test.cpp b/services/surfaceflinger/tests/ScreenCapture_test.cpp
index 95301b3..f9b3185 100644
--- a/services/surfaceflinger/tests/ScreenCapture_test.cpp
+++ b/services/surfaceflinger/tests/ScreenCapture_test.cpp
@@ -37,6 +37,8 @@
ASSERT_EQ(NO_ERROR, SurfaceComposerClient::getActiveDisplayMode(display, &mode));
const ui::Size& resolution = mode.resolution;
+ mDisplaySize = resolution;
+
// Background surface
mBGSurfaceControl = createLayer(String8("BG Test Surface"), resolution.getWidth(),
resolution.getHeight(), 0);
@@ -72,6 +74,7 @@
sp<SurfaceControl> mBGSurfaceControl;
sp<SurfaceControl> mFGSurfaceControl;
std::unique_ptr<ScreenCapture> mCapture;
+ ui::Size mDisplaySize;
};
TEST_F(ScreenCaptureTest, SetFlagsSecureEUidSystem) {
@@ -515,18 +518,8 @@
}
TEST_F(ScreenCaptureTest, CaptureInvalidLayer) {
- sp<SurfaceControl> redLayer = createLayer(String8("Red surface"), 60, 60,
- ISurfaceComposerClient::eFXSurfaceBufferState);
-
- ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(redLayer, Color::RED, 60, 60));
-
- auto redLayerHandle = redLayer->getHandle();
- Transaction().reparent(redLayer, nullptr).apply();
- redLayer.clear();
- SurfaceComposerClient::Transaction().apply(true);
-
LayerCaptureArgs args;
- args.layerHandle = redLayerHandle;
+ args.layerHandle = new BBinder();
ScreenCaptureResults captureResults;
// Layer was deleted so captureLayers should fail with NAME_NOT_FOUND
@@ -840,6 +833,33 @@
Color{expectedColor, expectedColor, expectedColor, 255}, tolerance);
}
+TEST_F(ScreenCaptureTest, CaptureOffscreen) {
+ sp<SurfaceControl> layer;
+ ASSERT_NO_FATAL_FAILURE(layer = createLayer("test layer", 32, 32,
+ ISurfaceComposerClient::eFXSurfaceBufferState,
+ mBGSurfaceControl.get()));
+ ASSERT_NO_FATAL_FAILURE(fillBufferStateLayerColor(layer, Color::RED, 32, 32));
+
+ Transaction().show(layer).hide(mFGSurfaceControl).reparent(layer, nullptr).apply();
+
+ DisplayCaptureArgs displayCaptureArgs;
+ displayCaptureArgs.displayToken = mDisplay;
+
+ {
+ // Validate that the red layer is not on screen
+ ScreenCapture::captureDisplay(&mCapture, displayCaptureArgs);
+ mCapture->expectColor(Rect(0, 0, mDisplaySize.width, mDisplaySize.height),
+ {63, 63, 195, 255});
+ }
+
+ LayerCaptureArgs captureArgs;
+ captureArgs.layerHandle = layer->getHandle();
+
+ ScreenCapture::captureLayers(&mCapture, captureArgs);
+ mCapture->expectSize(32, 32);
+ mCapture->expectColor(Rect(0, 0, 32, 32), Color::RED);
+}
+
// In the following tests we verify successful skipping of a parent layer,
// so we use the same verification logic and only change how we mutate
// the parent layer to verify that various properties are ignored.