blob: 013694fd479c90063b4c8c41748a847fe16db42b [file] [log] [blame]
chaviw3efadb12020-07-27 10:07:15 -07001/*
2 * Copyright (C) 2020 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17// TODO(b/129481165): remove the #pragma below and fix conversion issues
18#pragma clang diagnostic push
19#pragma clang diagnostic ignored "-Wconversion"
20
chaviw70cb6a42020-07-30 13:57:36 -070021#include <private/android_filesystem_config.h>
22
chaviw3efadb12020-07-27 10:07:15 -070023#include "LayerTransactionTest.h"
24
25namespace android {
26
27class ScreenCaptureTest : public LayerTransactionTest {
28protected:
29 virtual void SetUp() {
30 LayerTransactionTest::SetUp();
31 ASSERT_EQ(NO_ERROR, mClient->initCheck());
32
Huihong Luo31b5ac22022-08-15 20:38:10 -070033 const auto ids = SurfaceComposerClient::getPhysicalDisplayIds();
34 ASSERT_FALSE(ids.empty());
35 const auto display = SurfaceComposerClient::getPhysicalDisplayToken(ids.front());
chaviw3efadb12020-07-27 10:07:15 -070036 ASSERT_FALSE(display == nullptr);
37
Marin Shalamanova7fe3042021-01-29 21:02:08 +010038 ui::DisplayMode mode;
39 ASSERT_EQ(NO_ERROR, SurfaceComposerClient::getActiveDisplayMode(display, &mode));
40 const ui::Size& resolution = mode.resolution;
chaviw3efadb12020-07-27 10:07:15 -070041
chaviw79468ab2021-10-27 11:11:24 -050042 mDisplaySize = resolution;
43
chaviw3efadb12020-07-27 10:07:15 -070044 // Background surface
45 mBGSurfaceControl = createLayer(String8("BG Test Surface"), resolution.getWidth(),
46 resolution.getHeight(), 0);
47 ASSERT_TRUE(mBGSurfaceControl != nullptr);
48 ASSERT_TRUE(mBGSurfaceControl->isValid());
49 TransactionUtils::fillSurfaceRGBA8(mBGSurfaceControl, 63, 63, 195);
50
51 // Foreground surface
52 mFGSurfaceControl = createLayer(String8("FG Test Surface"), 64, 64, 0);
53
54 ASSERT_TRUE(mFGSurfaceControl != nullptr);
55 ASSERT_TRUE(mFGSurfaceControl->isValid());
56
57 TransactionUtils::fillSurfaceRGBA8(mFGSurfaceControl, 195, 63, 63);
58
59 asTransaction([&](Transaction& t) {
Dominik Laskowski29fa1462021-04-27 15:51:50 -070060 t.setDisplayLayerStack(display, ui::DEFAULT_LAYER_STACK);
chaviw3efadb12020-07-27 10:07:15 -070061
62 t.setLayer(mBGSurfaceControl, INT32_MAX - 2).show(mBGSurfaceControl);
63
64 t.setLayer(mFGSurfaceControl, INT32_MAX - 1)
65 .setPosition(mFGSurfaceControl, 64, 64)
66 .show(mFGSurfaceControl);
67 });
68 }
69
70 virtual void TearDown() {
71 LayerTransactionTest::TearDown();
72 mBGSurfaceControl = 0;
73 mFGSurfaceControl = 0;
74 }
75
76 sp<SurfaceControl> mBGSurfaceControl;
77 sp<SurfaceControl> mFGSurfaceControl;
78 std::unique_ptr<ScreenCapture> mCapture;
chaviw79468ab2021-10-27 11:11:24 -050079 ui::Size mDisplaySize;
chaviw3efadb12020-07-27 10:07:15 -070080};
81
chaviw4b9d5e12020-08-04 18:30:35 -070082TEST_F(ScreenCaptureTest, SetFlagsSecureEUidSystem) {
83 sp<SurfaceControl> layer;
84 ASSERT_NO_FATAL_FAILURE(
85 layer = createLayer("test", 32, 32,
86 ISurfaceComposerClient::eSecure |
87 ISurfaceComposerClient::eFXSurfaceBufferQueue));
88 ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(layer, Color::RED, 32, 32));
89
90 Transaction().show(layer).setLayer(layer, INT32_MAX).apply(true);
91
chaviwf5bb97b2021-04-28 15:35:37 -050092 {
93 // Ensure the UID is not root because root has all permissions
94 UIDFaker f(AID_APP_START);
95 ASSERT_EQ(PERMISSION_DENIED, ScreenCapture::captureDisplay(mCaptureArgs, mCaptureResults));
96 }
chaviw4b9d5e12020-08-04 18:30:35 -070097
98 UIDFaker f(AID_SYSTEM);
99
100 // By default the system can capture screenshots with secure layers but they
101 // will be blacked out
chaviw8ffc7b82020-08-18 11:25:37 -0700102 ASSERT_EQ(NO_ERROR, ScreenCapture::captureDisplay(mCaptureArgs, mCaptureResults));
chaviw4b9d5e12020-08-04 18:30:35 -0700103
104 {
105 SCOPED_TRACE("as system");
106 auto shot = screenshot();
107 shot->expectColor(Rect(0, 0, 32, 32), Color::BLACK);
108 }
109
110 // Here we pass captureSecureLayers = true and since we are AID_SYSTEM we should be able
111 // to receive them...we are expected to take care with the results.
112 DisplayCaptureArgs args;
113 args.displayToken = mDisplay;
114 args.captureSecureLayers = true;
chaviw8ffc7b82020-08-18 11:25:37 -0700115 ASSERT_EQ(NO_ERROR, ScreenCapture::captureDisplay(args, mCaptureResults));
chaviw4b9d5e12020-08-04 18:30:35 -0700116 ASSERT_TRUE(mCaptureResults.capturedSecureLayers);
Alec Mouri14d5b862022-04-27 21:20:04 +0000117 ScreenCapture sc(mCaptureResults.buffer, mCaptureResults.capturedHdrLayers);
chaviw4b9d5e12020-08-04 18:30:35 -0700118 sc.expectColor(Rect(0, 0, 32, 32), Color::RED);
119}
120
Garfield Tande619fa2020-10-02 17:13:53 -0700121TEST_F(ScreenCaptureTest, CaptureChildSetParentFlagsSecureEUidSystem) {
122 sp<SurfaceControl> parentLayer;
123 ASSERT_NO_FATAL_FAILURE(
124 parentLayer = createLayer("parent-test", 32, 32,
125 ISurfaceComposerClient::eSecure |
126 ISurfaceComposerClient::eFXSurfaceBufferQueue));
127 ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(parentLayer, Color::RED, 32, 32));
128
129 sp<SurfaceControl> childLayer;
130 ASSERT_NO_FATAL_FAILURE(childLayer = createLayer("child-test", 10, 10,
131 ISurfaceComposerClient::eFXSurfaceBufferQueue,
132 parentLayer.get()));
133 ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(childLayer, Color::BLUE, 10, 10));
134
135 Transaction().show(parentLayer).setLayer(parentLayer, INT32_MAX).show(childLayer).apply(true);
136
137 UIDFaker f(AID_SYSTEM);
138
139 {
140 SCOPED_TRACE("as system");
141 auto shot = screenshot();
142 shot->expectColor(Rect(0, 0, 10, 10), Color::BLACK);
143 }
144
145 // Here we pass captureSecureLayers = true and since we are AID_SYSTEM we should be able
146 // to receive them...we are expected to take care with the results.
147 DisplayCaptureArgs args;
148 args.displayToken = mDisplay;
149 args.captureSecureLayers = true;
150 ASSERT_EQ(NO_ERROR, ScreenCapture::captureDisplay(args, mCaptureResults));
151 ASSERT_TRUE(mCaptureResults.capturedSecureLayers);
Alec Mouri14d5b862022-04-27 21:20:04 +0000152 ScreenCapture sc(mCaptureResults.buffer, mCaptureResults.capturedHdrLayers);
Garfield Tande619fa2020-10-02 17:13:53 -0700153 sc.expectColor(Rect(0, 0, 10, 10), Color::BLUE);
154}
155
chaviw3efadb12020-07-27 10:07:15 -0700156TEST_F(ScreenCaptureTest, CaptureSingleLayer) {
chaviw70cb6a42020-07-30 13:57:36 -0700157 LayerCaptureArgs captureArgs;
158 captureArgs.layerHandle = mBGSurfaceControl->getHandle();
159 ScreenCapture::captureLayers(&mCapture, captureArgs);
chaviw3efadb12020-07-27 10:07:15 -0700160 mCapture->expectBGColor(0, 0);
161 // Doesn't capture FG layer which is at 64, 64
162 mCapture->expectBGColor(64, 64);
163}
164
165TEST_F(ScreenCaptureTest, CaptureLayerWithChild) {
chaviw3efadb12020-07-27 10:07:15 -0700166 sp<SurfaceControl> child = createSurface(mClient, "Child surface", 10, 10,
167 PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
168 TransactionUtils::fillSurfaceRGBA8(child, 200, 200, 200);
169
170 SurfaceComposerClient::Transaction().show(child).apply(true);
171
172 // Captures mFGSurfaceControl layer and its child.
chaviw70cb6a42020-07-30 13:57:36 -0700173 LayerCaptureArgs captureArgs;
174 captureArgs.layerHandle = mFGSurfaceControl->getHandle();
175 ScreenCapture::captureLayers(&mCapture, captureArgs);
chaviw3efadb12020-07-27 10:07:15 -0700176 mCapture->expectFGColor(10, 10);
177 mCapture->expectChildColor(0, 0);
178}
179
180TEST_F(ScreenCaptureTest, CaptureLayerChildOnly) {
181 auto fgHandle = mFGSurfaceControl->getHandle();
182
183 sp<SurfaceControl> child = createSurface(mClient, "Child surface", 10, 10,
184 PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
185 TransactionUtils::fillSurfaceRGBA8(child, 200, 200, 200);
186
187 SurfaceComposerClient::Transaction().show(child).apply(true);
188
189 // Captures mFGSurfaceControl's child
chaviw70cb6a42020-07-30 13:57:36 -0700190 LayerCaptureArgs captureArgs;
191 captureArgs.layerHandle = fgHandle;
192 captureArgs.childrenOnly = true;
193 ScreenCapture::captureLayers(&mCapture, captureArgs);
chaviw3efadb12020-07-27 10:07:15 -0700194 mCapture->checkPixel(10, 10, 0, 0, 0);
195 mCapture->expectChildColor(0, 0);
196}
197
198TEST_F(ScreenCaptureTest, CaptureLayerExclude) {
199 auto fgHandle = mFGSurfaceControl->getHandle();
200
201 sp<SurfaceControl> child = createSurface(mClient, "Child surface", 10, 10,
202 PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
203 TransactionUtils::fillSurfaceRGBA8(child, 200, 200, 200);
204 sp<SurfaceControl> child2 = createSurface(mClient, "Child surface", 10, 10,
205 PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
206 TransactionUtils::fillSurfaceRGBA8(child2, 200, 0, 200);
207
208 SurfaceComposerClient::Transaction()
209 .show(child)
210 .show(child2)
211 .setLayer(child, 1)
212 .setLayer(child2, 2)
213 .apply(true);
214
215 // Child2 would be visible but its excluded, so we should see child1 color instead.
chaviw70cb6a42020-07-30 13:57:36 -0700216 LayerCaptureArgs captureArgs;
217 captureArgs.layerHandle = fgHandle;
218 captureArgs.childrenOnly = true;
219 captureArgs.excludeHandles = {child2->getHandle()};
220 ScreenCapture::captureLayers(&mCapture, captureArgs);
chaviw3efadb12020-07-27 10:07:15 -0700221 mCapture->checkPixel(10, 10, 0, 0, 0);
222 mCapture->checkPixel(0, 0, 200, 200, 200);
223}
224
Ajinkya Chalke02844632023-03-01 12:10:14 +0000225TEST_F(ScreenCaptureTest, CaptureLayerExcludeThroughDisplayArgs) {
226 mCaptureArgs.excludeHandles = {mFGSurfaceControl->getHandle()};
227 ScreenCapture::captureDisplay(&mCapture, mCaptureArgs);
228 mCapture->expectBGColor(0, 0);
229 // Doesn't capture FG layer which is at 64, 64
230 mCapture->expectBGColor(64, 64);
231}
232
chaviw3efadb12020-07-27 10:07:15 -0700233// Like the last test but verifies that children are also exclude.
234TEST_F(ScreenCaptureTest, CaptureLayerExcludeTree) {
235 auto fgHandle = mFGSurfaceControl->getHandle();
236
237 sp<SurfaceControl> child = createSurface(mClient, "Child surface", 10, 10,
238 PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
239 TransactionUtils::fillSurfaceRGBA8(child, 200, 200, 200);
240 sp<SurfaceControl> child2 = createSurface(mClient, "Child surface", 10, 10,
241 PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
242 TransactionUtils::fillSurfaceRGBA8(child2, 200, 0, 200);
243 sp<SurfaceControl> child3 = createSurface(mClient, "Child surface", 10, 10,
244 PIXEL_FORMAT_RGBA_8888, 0, child2.get());
245 TransactionUtils::fillSurfaceRGBA8(child2, 200, 0, 200);
246
247 SurfaceComposerClient::Transaction()
248 .show(child)
249 .show(child2)
250 .show(child3)
251 .setLayer(child, 1)
252 .setLayer(child2, 2)
253 .apply(true);
254
255 // Child2 would be visible but its excluded, so we should see child1 color instead.
chaviw70cb6a42020-07-30 13:57:36 -0700256 LayerCaptureArgs captureArgs;
257 captureArgs.layerHandle = fgHandle;
258 captureArgs.childrenOnly = true;
259 captureArgs.excludeHandles = {child2->getHandle()};
260 ScreenCapture::captureLayers(&mCapture, captureArgs);
chaviw3efadb12020-07-27 10:07:15 -0700261 mCapture->checkPixel(10, 10, 0, 0, 0);
262 mCapture->checkPixel(0, 0, 200, 200, 200);
263}
264
265TEST_F(ScreenCaptureTest, CaptureTransparent) {
266 sp<SurfaceControl> child = createSurface(mClient, "Child surface", 10, 10,
267 PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
268
269 TransactionUtils::fillSurfaceRGBA8(child, 200, 200, 200);
270
271 SurfaceComposerClient::Transaction().show(child).apply(true);
272
chaviw3efadb12020-07-27 10:07:15 -0700273 // Captures child
chaviw70cb6a42020-07-30 13:57:36 -0700274 LayerCaptureArgs captureArgs;
275 captureArgs.layerHandle = child->getHandle();
276 captureArgs.sourceCrop = {0, 0, 10, 20};
277 ScreenCapture::captureLayers(&mCapture, captureArgs);
chaviw3efadb12020-07-27 10:07:15 -0700278 mCapture->expectColor(Rect(0, 0, 9, 9), {200, 200, 200, 255});
279 // Area outside of child's bounds is transparent.
280 mCapture->expectColor(Rect(0, 10, 9, 19), {0, 0, 0, 0});
281}
282
283TEST_F(ScreenCaptureTest, DontCaptureRelativeOutsideTree) {
chaviw3efadb12020-07-27 10:07:15 -0700284 sp<SurfaceControl> child = createSurface(mClient, "Child surface", 10, 10,
285 PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
286 ASSERT_NE(nullptr, child.get()) << "failed to create surface";
287 sp<SurfaceControl> relative = createLayer(String8("Relative surface"), 10, 10, 0);
288 TransactionUtils::fillSurfaceRGBA8(child, 200, 200, 200);
289 TransactionUtils::fillSurfaceRGBA8(relative, 100, 100, 100);
290
291 SurfaceComposerClient::Transaction()
292 .show(child)
293 // Set relative layer above fg layer so should be shown above when computing all layers.
Pablo Gamito11dcc222020-09-12 15:49:39 +0000294 .setRelativeLayer(relative, mFGSurfaceControl, 1)
chaviw3efadb12020-07-27 10:07:15 -0700295 .show(relative)
296 .apply(true);
297
298 // Captures mFGSurfaceControl layer and its child. Relative layer shouldn't be captured.
chaviw70cb6a42020-07-30 13:57:36 -0700299 LayerCaptureArgs captureArgs;
300 captureArgs.layerHandle = mFGSurfaceControl->getHandle();
301 ScreenCapture::captureLayers(&mCapture, captureArgs);
chaviw3efadb12020-07-27 10:07:15 -0700302 mCapture->expectFGColor(10, 10);
303 mCapture->expectChildColor(0, 0);
304}
305
306TEST_F(ScreenCaptureTest, CaptureRelativeInTree) {
chaviw3efadb12020-07-27 10:07:15 -0700307 sp<SurfaceControl> child = createSurface(mClient, "Child surface", 10, 10,
308 PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
309 sp<SurfaceControl> relative = createSurface(mClient, "Relative surface", 10, 10,
310 PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
311 TransactionUtils::fillSurfaceRGBA8(child, 200, 200, 200);
312 TransactionUtils::fillSurfaceRGBA8(relative, 100, 100, 100);
313
314 SurfaceComposerClient::Transaction()
315 .show(child)
316 // Set relative layer below fg layer but relative to child layer so it should be shown
317 // above child layer.
318 .setLayer(relative, -1)
Pablo Gamito11dcc222020-09-12 15:49:39 +0000319 .setRelativeLayer(relative, child, 1)
chaviw3efadb12020-07-27 10:07:15 -0700320 .show(relative)
321 .apply(true);
322
323 // Captures mFGSurfaceControl layer and its children. Relative layer is a child of fg so its
324 // relative value should be taken into account, placing it above child layer.
chaviw70cb6a42020-07-30 13:57:36 -0700325 LayerCaptureArgs captureArgs;
326 captureArgs.layerHandle = mFGSurfaceControl->getHandle();
327 ScreenCapture::captureLayers(&mCapture, captureArgs);
chaviw3efadb12020-07-27 10:07:15 -0700328 mCapture->expectFGColor(10, 10);
329 // Relative layer is showing on top of child layer
330 mCapture->expectColor(Rect(0, 0, 9, 9), {100, 100, 100, 255});
331}
332
333TEST_F(ScreenCaptureTest, CaptureBoundlessLayerWithSourceCrop) {
334 sp<SurfaceControl> child = createColorLayer("Child layer", Color::RED, mFGSurfaceControl.get());
335 SurfaceComposerClient::Transaction().show(child).apply(true);
336
chaviw70cb6a42020-07-30 13:57:36 -0700337 LayerCaptureArgs captureArgs;
338 captureArgs.layerHandle = child->getHandle();
339 captureArgs.sourceCrop = {0, 0, 10, 10};
340 ScreenCapture::captureLayers(&mCapture, captureArgs);
chaviw3efadb12020-07-27 10:07:15 -0700341
342 mCapture->expectColor(Rect(0, 0, 9, 9), Color::RED);
343}
344
345TEST_F(ScreenCaptureTest, CaptureBoundedLayerWithoutSourceCrop) {
346 sp<SurfaceControl> child = createColorLayer("Child layer", Color::RED, mFGSurfaceControl.get());
347 Rect layerCrop(0, 0, 10, 10);
chaviw25714502021-02-11 10:01:08 -0800348 SurfaceComposerClient::Transaction().setCrop(child, layerCrop).show(child).apply(true);
chaviw3efadb12020-07-27 10:07:15 -0700349
chaviw70cb6a42020-07-30 13:57:36 -0700350 LayerCaptureArgs captureArgs;
351 captureArgs.layerHandle = child->getHandle();
352 ScreenCapture::captureLayers(&mCapture, captureArgs);
chaviw3efadb12020-07-27 10:07:15 -0700353
354 mCapture->expectColor(Rect(0, 0, 9, 9), Color::RED);
355}
356
357TEST_F(ScreenCaptureTest, CaptureBoundlessLayerWithoutSourceCropFails) {
358 sp<SurfaceControl> child = createColorLayer("Child layer", Color::RED, mFGSurfaceControl.get());
359 SurfaceComposerClient::Transaction().show(child).apply(true);
360
chaviw3efadb12020-07-27 10:07:15 -0700361 LayerCaptureArgs args;
362 args.layerHandle = child->getHandle();
363
364 ScreenCaptureResults captureResults;
chaviw8ffc7b82020-08-18 11:25:37 -0700365 ASSERT_EQ(BAD_VALUE, ScreenCapture::captureLayers(args, captureResults));
chaviw3efadb12020-07-27 10:07:15 -0700366}
367
368TEST_F(ScreenCaptureTest, CaptureBufferLayerWithoutBufferFails) {
369 sp<SurfaceControl> child = createSurface(mClient, "Child surface", 10, 10,
Robert Carr5b3b9142021-02-22 12:27:32 -0800370 PIXEL_FORMAT_RGBA_8888,
371 ISurfaceComposerClient::eFXSurfaceBufferState,
372 mFGSurfaceControl.get());
373
chaviw3efadb12020-07-27 10:07:15 -0700374 SurfaceComposerClient::Transaction().show(child).apply(true);
chaviw3efadb12020-07-27 10:07:15 -0700375 sp<GraphicBuffer> outBuffer;
376
377 LayerCaptureArgs args;
378 args.layerHandle = child->getHandle();
379 args.childrenOnly = false;
380
381 ScreenCaptureResults captureResults;
chaviw8ffc7b82020-08-18 11:25:37 -0700382 ASSERT_EQ(BAD_VALUE, ScreenCapture::captureLayers(args, captureResults));
chaviw3efadb12020-07-27 10:07:15 -0700383
Patrick Williams83f36b22022-09-14 17:57:35 +0000384 ASSERT_NO_FATAL_FAILURE(fillBufferLayerColor(child, Color::RED, 32, 32));
chaviw3efadb12020-07-27 10:07:15 -0700385 SurfaceComposerClient::Transaction().apply(true);
chaviw8ffc7b82020-08-18 11:25:37 -0700386 ASSERT_EQ(NO_ERROR, ScreenCapture::captureLayers(args, captureResults));
Alec Mouri14d5b862022-04-27 21:20:04 +0000387 ScreenCapture sc(captureResults.buffer, captureResults.capturedHdrLayers);
chaviw3efadb12020-07-27 10:07:15 -0700388 sc.expectColor(Rect(0, 0, 9, 9), Color::RED);
389}
390
391TEST_F(ScreenCaptureTest, CaptureLayerWithGrandchild) {
chaviw3efadb12020-07-27 10:07:15 -0700392 sp<SurfaceControl> child = createSurface(mClient, "Child surface", 10, 10,
393 PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
394 TransactionUtils::fillSurfaceRGBA8(child, 200, 200, 200);
395
396 sp<SurfaceControl> grandchild = createSurface(mClient, "Grandchild surface", 5, 5,
397 PIXEL_FORMAT_RGBA_8888, 0, child.get());
398
399 TransactionUtils::fillSurfaceRGBA8(grandchild, 50, 50, 50);
400 SurfaceComposerClient::Transaction()
401 .show(child)
402 .setPosition(grandchild, 5, 5)
403 .show(grandchild)
404 .apply(true);
405
406 // Captures mFGSurfaceControl, its child, and the grandchild.
chaviw70cb6a42020-07-30 13:57:36 -0700407 LayerCaptureArgs captureArgs;
408 captureArgs.layerHandle = mFGSurfaceControl->getHandle();
409 ScreenCapture::captureLayers(&mCapture, captureArgs);
chaviw3efadb12020-07-27 10:07:15 -0700410 mCapture->expectFGColor(10, 10);
411 mCapture->expectChildColor(0, 0);
412 mCapture->checkPixel(5, 5, 50, 50, 50);
413}
414
415TEST_F(ScreenCaptureTest, CaptureChildOnly) {
416 sp<SurfaceControl> child = createSurface(mClient, "Child surface", 10, 10,
417 PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
418 TransactionUtils::fillSurfaceRGBA8(child, 200, 200, 200);
chaviw3efadb12020-07-27 10:07:15 -0700419
420 SurfaceComposerClient::Transaction().setPosition(child, 5, 5).show(child).apply(true);
421
422 // Captures only the child layer, and not the parent.
chaviw70cb6a42020-07-30 13:57:36 -0700423 LayerCaptureArgs captureArgs;
424 captureArgs.layerHandle = child->getHandle();
425 ScreenCapture::captureLayers(&mCapture, captureArgs);
chaviw3efadb12020-07-27 10:07:15 -0700426 mCapture->expectChildColor(0, 0);
427 mCapture->expectChildColor(9, 9);
428}
429
430TEST_F(ScreenCaptureTest, CaptureGrandchildOnly) {
431 sp<SurfaceControl> child = createSurface(mClient, "Child surface", 10, 10,
432 PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
433 TransactionUtils::fillSurfaceRGBA8(child, 200, 200, 200);
434 auto childHandle = child->getHandle();
435
436 sp<SurfaceControl> grandchild = createSurface(mClient, "Grandchild surface", 5, 5,
437 PIXEL_FORMAT_RGBA_8888, 0, child.get());
438 TransactionUtils::fillSurfaceRGBA8(grandchild, 50, 50, 50);
439
440 SurfaceComposerClient::Transaction()
441 .show(child)
442 .setPosition(grandchild, 5, 5)
443 .show(grandchild)
444 .apply(true);
445
chaviw3efadb12020-07-27 10:07:15 -0700446 // Captures only the grandchild.
chaviw70cb6a42020-07-30 13:57:36 -0700447 LayerCaptureArgs captureArgs;
448 captureArgs.layerHandle = grandchild->getHandle();
449 ScreenCapture::captureLayers(&mCapture, captureArgs);
chaviw3efadb12020-07-27 10:07:15 -0700450 mCapture->checkPixel(0, 0, 50, 50, 50);
451 mCapture->checkPixel(4, 4, 50, 50, 50);
452}
453
454TEST_F(ScreenCaptureTest, CaptureCrop) {
Robert Carr5b3b9142021-02-22 12:27:32 -0800455 sp<SurfaceControl> redLayer = createLayer(String8("Red surface"), 60, 60,
456 ISurfaceComposerClient::eFXSurfaceBufferState);
chaviw3efadb12020-07-27 10:07:15 -0700457 sp<SurfaceControl> blueLayer = createSurface(mClient, "Blue surface", 30, 30,
Robert Carr5b3b9142021-02-22 12:27:32 -0800458 PIXEL_FORMAT_RGBA_8888,
459 ISurfaceComposerClient::eFXSurfaceBufferState,
460 redLayer.get());
chaviw3efadb12020-07-27 10:07:15 -0700461
Patrick Williams83f36b22022-09-14 17:57:35 +0000462 ASSERT_NO_FATAL_FAILURE(fillBufferLayerColor(redLayer, Color::RED, 60, 60));
463 ASSERT_NO_FATAL_FAILURE(fillBufferLayerColor(blueLayer, Color::BLUE, 30, 30));
chaviw3efadb12020-07-27 10:07:15 -0700464
465 SurfaceComposerClient::Transaction()
466 .setLayer(redLayer, INT32_MAX - 1)
467 .show(redLayer)
468 .show(blueLayer)
469 .apply(true);
470
chaviw3efadb12020-07-27 10:07:15 -0700471 // Capturing full screen should have both red and blue are visible.
chaviw70cb6a42020-07-30 13:57:36 -0700472 LayerCaptureArgs captureArgs;
473 captureArgs.layerHandle = redLayer->getHandle();
474 ScreenCapture::captureLayers(&mCapture, captureArgs);
chaviw3efadb12020-07-27 10:07:15 -0700475 mCapture->expectColor(Rect(0, 0, 29, 29), Color::BLUE);
476 // red area below the blue area
477 mCapture->expectColor(Rect(0, 30, 59, 59), Color::RED);
478 // red area to the right of the blue area
479 mCapture->expectColor(Rect(30, 0, 59, 59), Color::RED);
480
chaviw70cb6a42020-07-30 13:57:36 -0700481 captureArgs.sourceCrop = {0, 0, 30, 30};
482 ScreenCapture::captureLayers(&mCapture, captureArgs);
chaviw3efadb12020-07-27 10:07:15 -0700483 // Capturing the cropped screen, cropping out the shown red area, should leave only the blue
484 // area visible.
485 mCapture->expectColor(Rect(0, 0, 29, 29), Color::BLUE);
486 mCapture->checkPixel(30, 30, 0, 0, 0);
487}
488
489TEST_F(ScreenCaptureTest, CaptureSize) {
Robert Carr5b3b9142021-02-22 12:27:32 -0800490 sp<SurfaceControl> redLayer =
491 createLayer(String8("Red surface"), 60, 60, ISurfaceComposerClient::eFXSurfaceBufferState);
chaviw3efadb12020-07-27 10:07:15 -0700492 sp<SurfaceControl> blueLayer = createSurface(mClient, "Blue surface", 30, 30,
Robert Carr5b3b9142021-02-22 12:27:32 -0800493 PIXEL_FORMAT_RGBA_8888,
494 ISurfaceComposerClient::eFXSurfaceBufferState,
495 redLayer.get());
chaviw3efadb12020-07-27 10:07:15 -0700496
Patrick Williams83f36b22022-09-14 17:57:35 +0000497 ASSERT_NO_FATAL_FAILURE(fillBufferLayerColor(redLayer, Color::RED, 60, 60));
498 ASSERT_NO_FATAL_FAILURE(fillBufferLayerColor(blueLayer, Color::BLUE, 30, 30));
chaviw3efadb12020-07-27 10:07:15 -0700499
500 SurfaceComposerClient::Transaction()
501 .setLayer(redLayer, INT32_MAX - 1)
502 .show(redLayer)
503 .show(blueLayer)
504 .apply(true);
505
chaviw3efadb12020-07-27 10:07:15 -0700506 // Capturing full screen should have both red and blue are visible.
chaviw70cb6a42020-07-30 13:57:36 -0700507 LayerCaptureArgs captureArgs;
508 captureArgs.layerHandle = redLayer->getHandle();
509 ScreenCapture::captureLayers(&mCapture, captureArgs);
chaviw3efadb12020-07-27 10:07:15 -0700510 mCapture->expectColor(Rect(0, 0, 29, 29), Color::BLUE);
511 // red area below the blue area
512 mCapture->expectColor(Rect(0, 30, 59, 59), Color::RED);
513 // red area to the right of the blue area
514 mCapture->expectColor(Rect(30, 0, 59, 59), Color::RED);
515
chaviw17ac24b2021-01-28 18:50:05 -0800516 captureArgs.frameScaleX = 0.5f;
517 captureArgs.frameScaleY = 0.5f;
Robert Carr5b3b9142021-02-22 12:27:32 -0800518 sleep(1);
chaviw17ac24b2021-01-28 18:50:05 -0800519
chaviw70cb6a42020-07-30 13:57:36 -0700520 ScreenCapture::captureLayers(&mCapture, captureArgs);
chaviw3efadb12020-07-27 10:07:15 -0700521 // Capturing the downsized area (30x30) should leave both red and blue but in a smaller area.
522 mCapture->expectColor(Rect(0, 0, 14, 14), Color::BLUE);
523 // red area below the blue area
524 mCapture->expectColor(Rect(0, 15, 29, 29), Color::RED);
525 // red area to the right of the blue area
526 mCapture->expectColor(Rect(15, 0, 29, 29), Color::RED);
527 mCapture->checkPixel(30, 30, 0, 0, 0);
528}
529
530TEST_F(ScreenCaptureTest, CaptureInvalidLayer) {
chaviw3efadb12020-07-27 10:07:15 -0700531 LayerCaptureArgs args;
Ady Abrahamd11bade2022-08-01 16:18:03 -0700532 args.layerHandle = sp<BBinder>::make();
chaviw3efadb12020-07-27 10:07:15 -0700533
534 ScreenCaptureResults captureResults;
chaviw3efadb12020-07-27 10:07:15 -0700535 // Layer was deleted so captureLayers should fail with NAME_NOT_FOUND
chaviw8ffc7b82020-08-18 11:25:37 -0700536 ASSERT_EQ(NAME_NOT_FOUND, ScreenCapture::captureLayers(args, captureResults));
chaviw3efadb12020-07-27 10:07:15 -0700537}
538
Garfield Tan9c9c1912021-07-19 12:02:16 -0700539TEST_F(ScreenCaptureTest, CaptureTooLargeLayer) {
540 sp<SurfaceControl> redLayer = createLayer(String8("Red surface"), 60, 60);
541 ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(redLayer, Color::RED, 60, 60));
542
543 Transaction().show(redLayer).setLayer(redLayer, INT32_MAX).apply(true);
544
545 LayerCaptureArgs captureArgs;
546 captureArgs.layerHandle = redLayer->getHandle();
547 captureArgs.frameScaleX = INT32_MAX / 60;
548 captureArgs.frameScaleY = INT32_MAX / 60;
549
550 ScreenCaptureResults captureResults;
551 ASSERT_EQ(BAD_VALUE, ScreenCapture::captureLayers(captureArgs, captureResults));
552}
553
chaviwf5bb97b2021-04-28 15:35:37 -0500554TEST_F(ScreenCaptureTest, CaptureSecureLayer) {
Robert Carr5b3b9142021-02-22 12:27:32 -0800555 sp<SurfaceControl> redLayer = createLayer(String8("Red surface"), 60, 60,
556 ISurfaceComposerClient::eFXSurfaceBufferState);
chaviw70cb6a42020-07-30 13:57:36 -0700557 sp<SurfaceControl> secureLayer =
558 createLayer(String8("Secure surface"), 30, 30,
559 ISurfaceComposerClient::eSecure |
Robert Carr5b3b9142021-02-22 12:27:32 -0800560 ISurfaceComposerClient::eFXSurfaceBufferState,
chaviw70cb6a42020-07-30 13:57:36 -0700561 redLayer.get());
Patrick Williams83f36b22022-09-14 17:57:35 +0000562 ASSERT_NO_FATAL_FAILURE(fillBufferLayerColor(redLayer, Color::RED, 60, 60));
563 ASSERT_NO_FATAL_FAILURE(fillBufferLayerColor(secureLayer, Color::BLUE, 30, 30));
chaviw70cb6a42020-07-30 13:57:36 -0700564
565 auto redLayerHandle = redLayer->getHandle();
566 Transaction()
567 .show(redLayer)
568 .show(secureLayer)
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700569 .setLayerStack(redLayer, ui::DEFAULT_LAYER_STACK)
chaviw70cb6a42020-07-30 13:57:36 -0700570 .setLayer(redLayer, INT32_MAX)
571 .apply();
572
chaviw70cb6a42020-07-30 13:57:36 -0700573 LayerCaptureArgs args;
574 args.layerHandle = redLayerHandle;
575 args.childrenOnly = false;
576 ScreenCaptureResults captureResults;
577
chaviwf5bb97b2021-04-28 15:35:37 -0500578 {
579 // Ensure the UID is not root because root has all permissions
580 UIDFaker f(AID_APP_START);
581 // Call from outside system with secure layers will result in permission denied
582 ASSERT_EQ(PERMISSION_DENIED, ScreenCapture::captureLayers(args, captureResults));
583 }
chaviw70cb6a42020-07-30 13:57:36 -0700584
585 UIDFaker f(AID_SYSTEM);
586
587 // From system request, only red layer will be screenshot since the blue layer is secure.
588 // Black will be present where the secure layer is.
589 ScreenCapture::captureLayers(&mCapture, args);
590 mCapture->expectColor(Rect(0, 0, 30, 30), Color::BLACK);
591 mCapture->expectColor(Rect(30, 30, 60, 60), Color::RED);
592
593 // Passing flag secure so the blue layer should be screenshot too.
594 args.captureSecureLayers = true;
595 ScreenCapture::captureLayers(&mCapture, args);
596 mCapture->expectColor(Rect(0, 0, 30, 30), Color::BLUE);
597 mCapture->expectColor(Rect(30, 30, 60, 60), Color::RED);
598}
599
chaviw4b9d5e12020-08-04 18:30:35 -0700600TEST_F(ScreenCaptureTest, CaptureDisplayWithUid) {
601 uid_t fakeUid = 12345;
602
603 DisplayCaptureArgs captureArgs;
604 captureArgs.displayToken = mDisplay;
605
606 sp<SurfaceControl> layer;
607 ASSERT_NO_FATAL_FAILURE(layer = createLayer("test layer", 32, 32,
608 ISurfaceComposerClient::eFXSurfaceBufferQueue,
609 mBGSurfaceControl.get()));
610 ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(layer, Color::RED, 32, 32));
611
612 Transaction().show(layer).setLayer(layer, INT32_MAX).apply();
613
614 // Make sure red layer with the background layer is screenshot.
615 ScreenCapture::captureDisplay(&mCapture, captureArgs);
616 mCapture->expectColor(Rect(0, 0, 32, 32), Color::RED);
617 mCapture->expectBorder(Rect(0, 0, 32, 32), {63, 63, 195, 255});
618
619 // From non system uid, can't request screenshot without a specified uid.
620 UIDFaker f(fakeUid);
chaviw8ffc7b82020-08-18 11:25:37 -0700621 ASSERT_EQ(PERMISSION_DENIED, ScreenCapture::captureDisplay(captureArgs, mCaptureResults));
chaviw4b9d5e12020-08-04 18:30:35 -0700622
623 // Make screenshot request with current uid set. No layers were created with the current
624 // uid so screenshot will be black.
625 captureArgs.uid = fakeUid;
626 ScreenCapture::captureDisplay(&mCapture, captureArgs);
627 mCapture->expectColor(Rect(0, 0, 32, 32), Color::BLACK);
628 mCapture->expectBorder(Rect(0, 0, 32, 32), Color::BLACK);
629
630 sp<SurfaceControl> layerWithFakeUid;
631 // Create a new layer with the current uid
632 ASSERT_NO_FATAL_FAILURE(layerWithFakeUid =
633 createLayer("new test layer", 32, 32,
634 ISurfaceComposerClient::eFXSurfaceBufferQueue,
635 mBGSurfaceControl.get()));
636 ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(layerWithFakeUid, Color::GREEN, 32, 32));
637 Transaction()
638 .show(layerWithFakeUid)
639 .setLayer(layerWithFakeUid, INT32_MAX)
640 .setPosition(layerWithFakeUid, 128, 128)
641 .apply();
642
643 // Screenshot from the fakeUid caller with the uid requested allows the layer
644 // with that uid to be screenshotted. Everything else is black
645 ScreenCapture::captureDisplay(&mCapture, captureArgs);
646 mCapture->expectColor(Rect(128, 128, 160, 160), Color::GREEN);
647 mCapture->expectBorder(Rect(128, 128, 160, 160), Color::BLACK);
648}
649
chaviwc5676c62020-09-18 15:01:04 -0700650TEST_F(ScreenCaptureTest, CaptureDisplayPrimaryDisplayOnly) {
651 sp<SurfaceControl> layer;
652 ASSERT_NO_FATAL_FAILURE(
653 layer = createLayer("test layer", 0, 0, ISurfaceComposerClient::eFXSurfaceEffect));
654
655 const Color layerColor = Color::RED;
656 const Rect bounds = Rect(10, 10, 40, 40);
657
658 Transaction()
659 .show(layer)
660 .hide(mFGSurfaceControl)
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700661 .setLayerStack(layer, ui::DEFAULT_LAYER_STACK)
chaviwc5676c62020-09-18 15:01:04 -0700662 .setLayer(layer, INT32_MAX)
663 .setColor(layer, {layerColor.r / 255, layerColor.g / 255, layerColor.b / 255})
chaviw25714502021-02-11 10:01:08 -0800664 .setCrop(layer, bounds)
chaviwc5676c62020-09-18 15:01:04 -0700665 .apply();
666
667 DisplayCaptureArgs captureArgs;
668 captureArgs.displayToken = mDisplay;
669
670 {
671 ScreenCapture::captureDisplay(&mCapture, captureArgs);
672 mCapture->expectColor(bounds, layerColor);
673 mCapture->expectBorder(bounds, {63, 63, 195, 255});
674 }
675
676 Transaction()
677 .setFlags(layer, layer_state_t::eLayerSkipScreenshot,
678 layer_state_t::eLayerSkipScreenshot)
679 .apply();
680
681 {
682 // Can't screenshot test layer since it now has flag
683 // eLayerSkipScreenshot
684 ScreenCapture::captureDisplay(&mCapture, captureArgs);
685 mCapture->expectColor(bounds, {63, 63, 195, 255});
686 mCapture->expectBorder(bounds, {63, 63, 195, 255});
687 }
688}
689
690TEST_F(ScreenCaptureTest, CaptureDisplayChildPrimaryDisplayOnly) {
691 sp<SurfaceControl> layer;
692 sp<SurfaceControl> childLayer;
693 ASSERT_NO_FATAL_FAILURE(
694 layer = createLayer("test layer", 0, 0, ISurfaceComposerClient::eFXSurfaceEffect));
695 ASSERT_NO_FATAL_FAILURE(childLayer = createLayer("test layer", 0, 0,
696 ISurfaceComposerClient::eFXSurfaceEffect,
697 layer.get()));
698
699 const Color layerColor = Color::RED;
700 const Color childColor = Color::BLUE;
701 const Rect bounds = Rect(10, 10, 40, 40);
702 const Rect childBounds = Rect(20, 20, 30, 30);
703
704 Transaction()
705 .show(layer)
706 .show(childLayer)
707 .hide(mFGSurfaceControl)
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700708 .setLayerStack(layer, ui::DEFAULT_LAYER_STACK)
chaviwc5676c62020-09-18 15:01:04 -0700709 .setLayer(layer, INT32_MAX)
710 .setColor(layer, {layerColor.r / 255, layerColor.g / 255, layerColor.b / 255})
711 .setColor(childLayer, {childColor.r / 255, childColor.g / 255, childColor.b / 255})
chaviw25714502021-02-11 10:01:08 -0800712 .setCrop(layer, bounds)
713 .setCrop(childLayer, childBounds)
chaviwc5676c62020-09-18 15:01:04 -0700714 .apply();
715
716 DisplayCaptureArgs captureArgs;
717 captureArgs.displayToken = mDisplay;
718
719 {
720 ScreenCapture::captureDisplay(&mCapture, captureArgs);
721 mCapture->expectColor(childBounds, childColor);
722 mCapture->expectBorder(childBounds, layerColor);
723 mCapture->expectBorder(bounds, {63, 63, 195, 255});
724 }
725
726 Transaction()
727 .setFlags(layer, layer_state_t::eLayerSkipScreenshot,
728 layer_state_t::eLayerSkipScreenshot)
729 .apply();
730
731 {
732 // Can't screenshot child layer since the parent has the flag
733 // eLayerSkipScreenshot
734 ScreenCapture::captureDisplay(&mCapture, captureArgs);
735 mCapture->expectColor(childBounds, {63, 63, 195, 255});
736 mCapture->expectBorder(childBounds, {63, 63, 195, 255});
737 mCapture->expectBorder(bounds, {63, 63, 195, 255});
738 }
739}
740
chaviw4b9d5e12020-08-04 18:30:35 -0700741TEST_F(ScreenCaptureTest, CaptureLayerWithUid) {
742 uid_t fakeUid = 12345;
743
744 sp<SurfaceControl> layer;
745 ASSERT_NO_FATAL_FAILURE(layer = createLayer("test layer", 32, 32,
746 ISurfaceComposerClient::eFXSurfaceBufferQueue,
747 mBGSurfaceControl.get()));
748 ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(layer, Color::RED, 32, 32));
749
750 Transaction().show(layer).setLayer(layer, INT32_MAX).apply();
751
752 LayerCaptureArgs captureArgs;
753 captureArgs.layerHandle = mBGSurfaceControl->getHandle();
754 captureArgs.childrenOnly = false;
755
756 // Make sure red layer with the background layer is screenshot.
757 ScreenCapture::captureLayers(&mCapture, captureArgs);
758 mCapture->expectColor(Rect(0, 0, 32, 32), Color::RED);
759 mCapture->expectBorder(Rect(0, 0, 32, 32), {63, 63, 195, 255});
760
761 // From non system uid, can't request screenshot without a specified uid.
762 std::unique_ptr<UIDFaker> uidFaker = std::make_unique<UIDFaker>(fakeUid);
763
chaviw8ffc7b82020-08-18 11:25:37 -0700764 ASSERT_EQ(PERMISSION_DENIED, ScreenCapture::captureLayers(captureArgs, mCaptureResults));
chaviw4b9d5e12020-08-04 18:30:35 -0700765
766 // Make screenshot request with current uid set. No layers were created with the current
767 // uid so screenshot will be black.
768 captureArgs.uid = fakeUid;
769 ScreenCapture::captureLayers(&mCapture, captureArgs);
770 mCapture->expectColor(Rect(0, 0, 32, 32), Color::TRANSPARENT);
771 mCapture->expectBorder(Rect(0, 0, 32, 32), Color::TRANSPARENT);
772
773 sp<SurfaceControl> layerWithFakeUid;
774 // Create a new layer with the current uid
775 ASSERT_NO_FATAL_FAILURE(layerWithFakeUid =
776 createLayer("new test layer", 32, 32,
777 ISurfaceComposerClient::eFXSurfaceBufferQueue,
778 mBGSurfaceControl.get()));
779 ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(layerWithFakeUid, Color::GREEN, 32, 32));
780 Transaction()
781 .show(layerWithFakeUid)
782 .setLayer(layerWithFakeUid, INT32_MAX)
783 .setPosition(layerWithFakeUid, 128, 128)
784 // reparent a layer that was created with a different uid to the new layer.
Pablo Gamito11dcc222020-09-12 15:49:39 +0000785 .reparent(layer, layerWithFakeUid)
chaviw4b9d5e12020-08-04 18:30:35 -0700786 .apply();
787
788 // Screenshot from the fakeUid caller with the uid requested allows the layer
789 // with that uid to be screenshotted. The child layer is skipped since it was created
790 // from a different uid.
791 ScreenCapture::captureLayers(&mCapture, captureArgs);
792 mCapture->expectColor(Rect(128, 128, 160, 160), Color::GREEN);
793 mCapture->expectBorder(Rect(128, 128, 160, 160), Color::TRANSPARENT);
794
795 // Clear fake calling uid so it's back to system.
796 uidFaker = nullptr;
797 // Screenshot from the test caller with the uid requested allows the layer
798 // with that uid to be screenshotted. The child layer is skipped since it was created
799 // from a different uid.
800 ScreenCapture::captureLayers(&mCapture, captureArgs);
801 mCapture->expectColor(Rect(128, 128, 160, 160), Color::GREEN);
802 mCapture->expectBorder(Rect(128, 128, 160, 160), Color::TRANSPARENT);
803
804 // Screenshot from the fakeUid caller with no uid requested allows everything to be screenshot.
805 captureArgs.uid = -1;
806 ScreenCapture::captureLayers(&mCapture, captureArgs);
807 mCapture->expectColor(Rect(128, 128, 160, 160), Color::RED);
808 mCapture->expectBorder(Rect(128, 128, 160, 160), {63, 63, 195, 255});
809}
810
chaviw17ac24b2021-01-28 18:50:05 -0800811TEST_F(ScreenCaptureTest, CaptureWithGrayscale) {
812 sp<SurfaceControl> layer;
813 ASSERT_NO_FATAL_FAILURE(layer = createLayer("test layer", 32, 32,
814 ISurfaceComposerClient::eFXSurfaceBufferState,
815 mBGSurfaceControl.get()));
Patrick Williams83f36b22022-09-14 17:57:35 +0000816 ASSERT_NO_FATAL_FAILURE(fillBufferLayerColor(layer, Color::RED, 32, 32));
chaviw17ac24b2021-01-28 18:50:05 -0800817 Transaction().show(layer).setLayer(layer, INT32_MAX).apply();
818
819 LayerCaptureArgs captureArgs;
820 captureArgs.layerHandle = layer->getHandle();
821
822 ScreenCapture::captureLayers(&mCapture, captureArgs);
823 mCapture->expectColor(Rect(0, 0, 32, 32), Color::RED);
824
825 captureArgs.grayscale = true;
826
827 const uint8_t tolerance = 1;
828
829 // Values based on SurfaceFlinger::calculateColorMatrix
830 float3 luminance{0.213f, 0.715f, 0.072f};
831
832 ScreenCapture::captureLayers(&mCapture, captureArgs);
833
834 uint8_t expectedColor = luminance.r * 255;
835 mCapture->expectColor(Rect(0, 0, 32, 32),
836 Color{expectedColor, expectedColor, expectedColor, 255}, tolerance);
837
Patrick Williams83f36b22022-09-14 17:57:35 +0000838 ASSERT_NO_FATAL_FAILURE(fillBufferLayerColor(layer, Color::BLUE, 32, 32));
chaviw17ac24b2021-01-28 18:50:05 -0800839 ScreenCapture::captureLayers(&mCapture, captureArgs);
840
841 expectedColor = luminance.b * 255;
842 mCapture->expectColor(Rect(0, 0, 32, 32),
843 Color{expectedColor, expectedColor, expectedColor, 255}, tolerance);
844}
845
chaviw79468ab2021-10-27 11:11:24 -0500846TEST_F(ScreenCaptureTest, CaptureOffscreen) {
847 sp<SurfaceControl> layer;
848 ASSERT_NO_FATAL_FAILURE(layer = createLayer("test layer", 32, 32,
849 ISurfaceComposerClient::eFXSurfaceBufferState,
850 mBGSurfaceControl.get()));
Patrick Williams83f36b22022-09-14 17:57:35 +0000851 ASSERT_NO_FATAL_FAILURE(fillBufferLayerColor(layer, Color::RED, 32, 32));
chaviw79468ab2021-10-27 11:11:24 -0500852
853 Transaction().show(layer).hide(mFGSurfaceControl).reparent(layer, nullptr).apply();
854
855 DisplayCaptureArgs displayCaptureArgs;
856 displayCaptureArgs.displayToken = mDisplay;
857
858 {
859 // Validate that the red layer is not on screen
860 ScreenCapture::captureDisplay(&mCapture, displayCaptureArgs);
861 mCapture->expectColor(Rect(0, 0, mDisplaySize.width, mDisplaySize.height),
862 {63, 63, 195, 255});
863 }
864
865 LayerCaptureArgs captureArgs;
866 captureArgs.layerHandle = layer->getHandle();
867
868 ScreenCapture::captureLayers(&mCapture, captureArgs);
869 mCapture->expectSize(32, 32);
870 mCapture->expectColor(Rect(0, 0, 32, 32), Color::RED);
871}
872
Alec Mouri14d5b862022-04-27 21:20:04 +0000873TEST_F(ScreenCaptureTest, CaptureNonHdrLayer) {
874 sp<SurfaceControl> layer;
875 ASSERT_NO_FATAL_FAILURE(layer = createLayer("test layer", 32, 32,
876 ISurfaceComposerClient::eFXSurfaceBufferState,
877 mBGSurfaceControl.get()));
Patrick Williams83f36b22022-09-14 17:57:35 +0000878 ASSERT_NO_FATAL_FAILURE(fillBufferLayerColor(layer, Color::BLACK, 32, 32));
Alec Mouri14d5b862022-04-27 21:20:04 +0000879 Transaction()
880 .show(layer)
881 .setLayer(layer, INT32_MAX)
882 .setDataspace(layer, ui::Dataspace::V0_SRGB)
883 .apply();
884
885 LayerCaptureArgs captureArgs;
886 captureArgs.layerHandle = layer->getHandle();
887
888 ScreenCapture::captureLayers(&mCapture, captureArgs);
889 mCapture->expectColor(Rect(0, 0, 32, 32), Color::BLACK);
890 ASSERT_FALSE(mCapture->capturedHdrLayers());
891}
892
893TEST_F(ScreenCaptureTest, CaptureHdrLayer) {
894 sp<SurfaceControl> layer;
895 ASSERT_NO_FATAL_FAILURE(layer = createLayer("test layer", 32, 32,
896 ISurfaceComposerClient::eFXSurfaceBufferState,
897 mBGSurfaceControl.get()));
Patrick Williams83f36b22022-09-14 17:57:35 +0000898 ASSERT_NO_FATAL_FAILURE(fillBufferLayerColor(layer, Color::BLACK, 32, 32));
Alec Mouri14d5b862022-04-27 21:20:04 +0000899 Transaction()
900 .show(layer)
901 .setLayer(layer, INT32_MAX)
902 .setDataspace(layer, ui::Dataspace::BT2020_ITU_PQ)
903 .apply();
904
905 LayerCaptureArgs captureArgs;
906 captureArgs.layerHandle = layer->getHandle();
907
908 ScreenCapture::captureLayers(&mCapture, captureArgs);
909 mCapture->expectColor(Rect(0, 0, 32, 32), Color::BLACK);
910 ASSERT_TRUE(mCapture->capturedHdrLayers());
911}
912
chaviw3efadb12020-07-27 10:07:15 -0700913// In the following tests we verify successful skipping of a parent layer,
914// so we use the same verification logic and only change how we mutate
915// the parent layer to verify that various properties are ignored.
916class ScreenCaptureChildOnlyTest : public ScreenCaptureTest {
917public:
918 void SetUp() override {
919 ScreenCaptureTest::SetUp();
920
921 mChild = createSurface(mClient, "Child surface", 10, 10, PIXEL_FORMAT_RGBA_8888, 0,
922 mFGSurfaceControl.get());
923 TransactionUtils::fillSurfaceRGBA8(mChild, 200, 200, 200);
924
925 SurfaceComposerClient::Transaction().show(mChild).apply(true);
926 }
927
928 void verify(std::function<void()> verifyStartingState) {
929 // Verify starting state before a screenshot is taken.
930 verifyStartingState();
931
932 // Verify child layer does not inherit any of the properties of its
933 // parent when its screenshot is captured.
chaviw70cb6a42020-07-30 13:57:36 -0700934 LayerCaptureArgs captureArgs;
935 captureArgs.layerHandle = mFGSurfaceControl->getHandle();
936 captureArgs.childrenOnly = true;
937 ScreenCapture::captureLayers(&mCapture, captureArgs);
chaviw3efadb12020-07-27 10:07:15 -0700938 mCapture->checkPixel(10, 10, 0, 0, 0);
939 mCapture->expectChildColor(0, 0);
940
941 // Verify all assumptions are still true after the screenshot is taken.
942 verifyStartingState();
943 }
944
945 std::unique_ptr<ScreenCapture> mCapture;
946 sp<SurfaceControl> mChild;
947};
948
949// Regression test b/76099859
950TEST_F(ScreenCaptureChildOnlyTest, CaptureLayerIgnoresParentVisibility) {
951 SurfaceComposerClient::Transaction().hide(mFGSurfaceControl).apply(true);
952
953 // Even though the parent is hidden we should still capture the child.
954
955 // Before and after reparenting, verify child is properly hidden
956 // when rendering full-screen.
957 verify([&] { screenshot()->expectBGColor(64, 64); });
958}
959
960TEST_F(ScreenCaptureChildOnlyTest, CaptureLayerIgnoresParentCrop) {
chaviw25714502021-02-11 10:01:08 -0800961 SurfaceComposerClient::Transaction().setCrop(mFGSurfaceControl, Rect(0, 0, 1, 1)).apply(true);
chaviw3efadb12020-07-27 10:07:15 -0700962
963 // Even though the parent is cropped out we should still capture the child.
964
965 // Before and after reparenting, verify child is cropped by parent.
966 verify([&] { screenshot()->expectBGColor(65, 65); });
967}
968
969// Regression test b/124372894
970TEST_F(ScreenCaptureChildOnlyTest, CaptureLayerIgnoresTransform) {
971 SurfaceComposerClient::Transaction().setMatrix(mFGSurfaceControl, 2, 0, 0, 2).apply(true);
972
973 // We should not inherit the parent scaling.
974
975 // Before and after reparenting, verify child is properly scaled.
976 verify([&] { screenshot()->expectChildColor(80, 80); });
977}
978
Garfield Tande619fa2020-10-02 17:13:53 -0700979} // namespace android
Marin Shalamanovbed7fd32020-12-21 20:02:20 +0100980
981// TODO(b/129481165): remove the #pragma below and fix conversion issues
Robert Carr5b3b9142021-02-22 12:27:32 -0800982#pragma clang diagnostic pop // ignored "-Wconversion"