blob: 2a250ff52e0527fa5c169135e80eccf1c7282f99 [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
21#include "LayerTransactionTest.h"
22
23namespace android {
24
25class ScreenCaptureTest : public LayerTransactionTest {
26protected:
27 virtual void SetUp() {
28 LayerTransactionTest::SetUp();
29 ASSERT_EQ(NO_ERROR, mClient->initCheck());
30
31 const auto display = SurfaceComposerClient::getInternalDisplayToken();
32 ASSERT_FALSE(display == nullptr);
33
34 DisplayConfig config;
35 ASSERT_EQ(NO_ERROR, SurfaceComposerClient::getActiveDisplayConfig(display, &config));
36 const ui::Size& resolution = config.resolution;
37
38 // Background surface
39 mBGSurfaceControl = createLayer(String8("BG Test Surface"), resolution.getWidth(),
40 resolution.getHeight(), 0);
41 ASSERT_TRUE(mBGSurfaceControl != nullptr);
42 ASSERT_TRUE(mBGSurfaceControl->isValid());
43 TransactionUtils::fillSurfaceRGBA8(mBGSurfaceControl, 63, 63, 195);
44
45 // Foreground surface
46 mFGSurfaceControl = createLayer(String8("FG Test Surface"), 64, 64, 0);
47
48 ASSERT_TRUE(mFGSurfaceControl != nullptr);
49 ASSERT_TRUE(mFGSurfaceControl->isValid());
50
51 TransactionUtils::fillSurfaceRGBA8(mFGSurfaceControl, 195, 63, 63);
52
53 asTransaction([&](Transaction& t) {
54 t.setDisplayLayerStack(display, 0);
55
56 t.setLayer(mBGSurfaceControl, INT32_MAX - 2).show(mBGSurfaceControl);
57
58 t.setLayer(mFGSurfaceControl, INT32_MAX - 1)
59 .setPosition(mFGSurfaceControl, 64, 64)
60 .show(mFGSurfaceControl);
61 });
62 }
63
64 virtual void TearDown() {
65 LayerTransactionTest::TearDown();
66 mBGSurfaceControl = 0;
67 mFGSurfaceControl = 0;
68 }
69
70 sp<SurfaceControl> mBGSurfaceControl;
71 sp<SurfaceControl> mFGSurfaceControl;
72 std::unique_ptr<ScreenCapture> mCapture;
73};
74
75TEST_F(ScreenCaptureTest, CaptureSingleLayer) {
76 auto bgHandle = mBGSurfaceControl->getHandle();
77 ScreenCapture::captureLayers(&mCapture, bgHandle);
78 mCapture->expectBGColor(0, 0);
79 // Doesn't capture FG layer which is at 64, 64
80 mCapture->expectBGColor(64, 64);
81}
82
83TEST_F(ScreenCaptureTest, CaptureLayerWithChild) {
84 auto fgHandle = mFGSurfaceControl->getHandle();
85
86 sp<SurfaceControl> child = createSurface(mClient, "Child surface", 10, 10,
87 PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
88 TransactionUtils::fillSurfaceRGBA8(child, 200, 200, 200);
89
90 SurfaceComposerClient::Transaction().show(child).apply(true);
91
92 // Captures mFGSurfaceControl layer and its child.
93 ScreenCapture::captureLayers(&mCapture, fgHandle);
94 mCapture->expectFGColor(10, 10);
95 mCapture->expectChildColor(0, 0);
96}
97
98TEST_F(ScreenCaptureTest, CaptureLayerChildOnly) {
99 auto fgHandle = mFGSurfaceControl->getHandle();
100
101 sp<SurfaceControl> child = createSurface(mClient, "Child surface", 10, 10,
102 PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
103 TransactionUtils::fillSurfaceRGBA8(child, 200, 200, 200);
104
105 SurfaceComposerClient::Transaction().show(child).apply(true);
106
107 // Captures mFGSurfaceControl's child
108 ScreenCapture::captureChildLayers(&mCapture, fgHandle);
109 mCapture->checkPixel(10, 10, 0, 0, 0);
110 mCapture->expectChildColor(0, 0);
111}
112
113TEST_F(ScreenCaptureTest, CaptureLayerExclude) {
114 auto fgHandle = mFGSurfaceControl->getHandle();
115
116 sp<SurfaceControl> child = createSurface(mClient, "Child surface", 10, 10,
117 PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
118 TransactionUtils::fillSurfaceRGBA8(child, 200, 200, 200);
119 sp<SurfaceControl> child2 = createSurface(mClient, "Child surface", 10, 10,
120 PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
121 TransactionUtils::fillSurfaceRGBA8(child2, 200, 0, 200);
122
123 SurfaceComposerClient::Transaction()
124 .show(child)
125 .show(child2)
126 .setLayer(child, 1)
127 .setLayer(child2, 2)
128 .apply(true);
129
130 // Child2 would be visible but its excluded, so we should see child1 color instead.
131 ScreenCapture::captureChildLayersExcluding(&mCapture, fgHandle, {child2->getHandle()});
132 mCapture->checkPixel(10, 10, 0, 0, 0);
133 mCapture->checkPixel(0, 0, 200, 200, 200);
134}
135
136// Like the last test but verifies that children are also exclude.
137TEST_F(ScreenCaptureTest, CaptureLayerExcludeTree) {
138 auto fgHandle = mFGSurfaceControl->getHandle();
139
140 sp<SurfaceControl> child = createSurface(mClient, "Child surface", 10, 10,
141 PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
142 TransactionUtils::fillSurfaceRGBA8(child, 200, 200, 200);
143 sp<SurfaceControl> child2 = createSurface(mClient, "Child surface", 10, 10,
144 PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
145 TransactionUtils::fillSurfaceRGBA8(child2, 200, 0, 200);
146 sp<SurfaceControl> child3 = createSurface(mClient, "Child surface", 10, 10,
147 PIXEL_FORMAT_RGBA_8888, 0, child2.get());
148 TransactionUtils::fillSurfaceRGBA8(child2, 200, 0, 200);
149
150 SurfaceComposerClient::Transaction()
151 .show(child)
152 .show(child2)
153 .show(child3)
154 .setLayer(child, 1)
155 .setLayer(child2, 2)
156 .apply(true);
157
158 // Child2 would be visible but its excluded, so we should see child1 color instead.
159 ScreenCapture::captureChildLayersExcluding(&mCapture, fgHandle, {child2->getHandle()});
160 mCapture->checkPixel(10, 10, 0, 0, 0);
161 mCapture->checkPixel(0, 0, 200, 200, 200);
162}
163
164TEST_F(ScreenCaptureTest, CaptureTransparent) {
165 sp<SurfaceControl> child = createSurface(mClient, "Child surface", 10, 10,
166 PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
167
168 TransactionUtils::fillSurfaceRGBA8(child, 200, 200, 200);
169
170 SurfaceComposerClient::Transaction().show(child).apply(true);
171
172 auto childHandle = child->getHandle();
173
174 // Captures child
175 ScreenCapture::captureLayers(&mCapture, childHandle, {0, 0, 10, 20});
176 mCapture->expectColor(Rect(0, 0, 9, 9), {200, 200, 200, 255});
177 // Area outside of child's bounds is transparent.
178 mCapture->expectColor(Rect(0, 10, 9, 19), {0, 0, 0, 0});
179}
180
181TEST_F(ScreenCaptureTest, DontCaptureRelativeOutsideTree) {
182 auto fgHandle = mFGSurfaceControl->getHandle();
183
184 sp<SurfaceControl> child = createSurface(mClient, "Child surface", 10, 10,
185 PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
186 ASSERT_NE(nullptr, child.get()) << "failed to create surface";
187 sp<SurfaceControl> relative = createLayer(String8("Relative surface"), 10, 10, 0);
188 TransactionUtils::fillSurfaceRGBA8(child, 200, 200, 200);
189 TransactionUtils::fillSurfaceRGBA8(relative, 100, 100, 100);
190
191 SurfaceComposerClient::Transaction()
192 .show(child)
193 // Set relative layer above fg layer so should be shown above when computing all layers.
194 .setRelativeLayer(relative, fgHandle, 1)
195 .show(relative)
196 .apply(true);
197
198 // Captures mFGSurfaceControl layer and its child. Relative layer shouldn't be captured.
199 ScreenCapture::captureLayers(&mCapture, fgHandle);
200 mCapture->expectFGColor(10, 10);
201 mCapture->expectChildColor(0, 0);
202}
203
204TEST_F(ScreenCaptureTest, CaptureRelativeInTree) {
205 auto fgHandle = mFGSurfaceControl->getHandle();
206
207 sp<SurfaceControl> child = createSurface(mClient, "Child surface", 10, 10,
208 PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
209 sp<SurfaceControl> relative = createSurface(mClient, "Relative surface", 10, 10,
210 PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
211 TransactionUtils::fillSurfaceRGBA8(child, 200, 200, 200);
212 TransactionUtils::fillSurfaceRGBA8(relative, 100, 100, 100);
213
214 SurfaceComposerClient::Transaction()
215 .show(child)
216 // Set relative layer below fg layer but relative to child layer so it should be shown
217 // above child layer.
218 .setLayer(relative, -1)
219 .setRelativeLayer(relative, child->getHandle(), 1)
220 .show(relative)
221 .apply(true);
222
223 // Captures mFGSurfaceControl layer and its children. Relative layer is a child of fg so its
224 // relative value should be taken into account, placing it above child layer.
225 ScreenCapture::captureLayers(&mCapture, fgHandle);
226 mCapture->expectFGColor(10, 10);
227 // Relative layer is showing on top of child layer
228 mCapture->expectColor(Rect(0, 0, 9, 9), {100, 100, 100, 255});
229}
230
231TEST_F(ScreenCaptureTest, CaptureBoundlessLayerWithSourceCrop) {
232 sp<SurfaceControl> child = createColorLayer("Child layer", Color::RED, mFGSurfaceControl.get());
233 SurfaceComposerClient::Transaction().show(child).apply(true);
234
235 sp<ISurfaceComposer> sf(ComposerService::getComposerService());
236 Rect sourceCrop(0, 0, 10, 10);
237 sp<IBinder> childHandle = child->getHandle();
238 ScreenCapture::captureLayers(&mCapture, childHandle, sourceCrop);
239
240 mCapture->expectColor(Rect(0, 0, 9, 9), Color::RED);
241}
242
243TEST_F(ScreenCaptureTest, CaptureBoundedLayerWithoutSourceCrop) {
244 sp<SurfaceControl> child = createColorLayer("Child layer", Color::RED, mFGSurfaceControl.get());
245 Rect layerCrop(0, 0, 10, 10);
246 SurfaceComposerClient::Transaction().setCrop_legacy(child, layerCrop).show(child).apply(true);
247
248 sp<ISurfaceComposer> sf(ComposerService::getComposerService());
249 sp<GraphicBuffer> outBuffer;
250 sp<IBinder> childHandle = child->getHandle();
251 ScreenCapture::captureLayers(&mCapture, childHandle);
252
253 mCapture->expectColor(Rect(0, 0, 9, 9), Color::RED);
254}
255
256TEST_F(ScreenCaptureTest, CaptureBoundlessLayerWithoutSourceCropFails) {
257 sp<SurfaceControl> child = createColorLayer("Child layer", Color::RED, mFGSurfaceControl.get());
258 SurfaceComposerClient::Transaction().show(child).apply(true);
259
260 sp<ISurfaceComposer> sf(ComposerService::getComposerService());
261
262 LayerCaptureArgs args;
263 args.layerHandle = child->getHandle();
264
265 ScreenCaptureResults captureResults;
266 ASSERT_EQ(BAD_VALUE, sf->captureLayers(args, captureResults));
267}
268
269TEST_F(ScreenCaptureTest, CaptureBufferLayerWithoutBufferFails) {
270 sp<SurfaceControl> child = createSurface(mClient, "Child surface", 10, 10,
271 PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
272 SurfaceComposerClient::Transaction().show(child).apply(true);
273
274 sp<ISurfaceComposer> sf(ComposerService::getComposerService());
275 sp<GraphicBuffer> outBuffer;
276
277 LayerCaptureArgs args;
278 args.layerHandle = child->getHandle();
279 args.childrenOnly = false;
280
281 ScreenCaptureResults captureResults;
282 ASSERT_EQ(BAD_VALUE, sf->captureLayers(args, captureResults));
283
284 TransactionUtils::fillSurfaceRGBA8(child, Color::RED);
285 SurfaceComposerClient::Transaction().apply(true);
286 ASSERT_EQ(NO_ERROR, sf->captureLayers(args, captureResults));
287 ScreenCapture sc(captureResults.buffer);
288 sc.expectColor(Rect(0, 0, 9, 9), Color::RED);
289}
290
291TEST_F(ScreenCaptureTest, CaptureLayerWithGrandchild) {
292 auto fgHandle = mFGSurfaceControl->getHandle();
293
294 sp<SurfaceControl> child = createSurface(mClient, "Child surface", 10, 10,
295 PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
296 TransactionUtils::fillSurfaceRGBA8(child, 200, 200, 200);
297
298 sp<SurfaceControl> grandchild = createSurface(mClient, "Grandchild surface", 5, 5,
299 PIXEL_FORMAT_RGBA_8888, 0, child.get());
300
301 TransactionUtils::fillSurfaceRGBA8(grandchild, 50, 50, 50);
302 SurfaceComposerClient::Transaction()
303 .show(child)
304 .setPosition(grandchild, 5, 5)
305 .show(grandchild)
306 .apply(true);
307
308 // Captures mFGSurfaceControl, its child, and the grandchild.
309 ScreenCapture::captureLayers(&mCapture, fgHandle);
310 mCapture->expectFGColor(10, 10);
311 mCapture->expectChildColor(0, 0);
312 mCapture->checkPixel(5, 5, 50, 50, 50);
313}
314
315TEST_F(ScreenCaptureTest, CaptureChildOnly) {
316 sp<SurfaceControl> child = createSurface(mClient, "Child surface", 10, 10,
317 PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
318 TransactionUtils::fillSurfaceRGBA8(child, 200, 200, 200);
319 auto childHandle = child->getHandle();
320
321 SurfaceComposerClient::Transaction().setPosition(child, 5, 5).show(child).apply(true);
322
323 // Captures only the child layer, and not the parent.
324 ScreenCapture::captureLayers(&mCapture, childHandle);
325 mCapture->expectChildColor(0, 0);
326 mCapture->expectChildColor(9, 9);
327}
328
329TEST_F(ScreenCaptureTest, CaptureGrandchildOnly) {
330 sp<SurfaceControl> child = createSurface(mClient, "Child surface", 10, 10,
331 PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
332 TransactionUtils::fillSurfaceRGBA8(child, 200, 200, 200);
333 auto childHandle = child->getHandle();
334
335 sp<SurfaceControl> grandchild = createSurface(mClient, "Grandchild surface", 5, 5,
336 PIXEL_FORMAT_RGBA_8888, 0, child.get());
337 TransactionUtils::fillSurfaceRGBA8(grandchild, 50, 50, 50);
338
339 SurfaceComposerClient::Transaction()
340 .show(child)
341 .setPosition(grandchild, 5, 5)
342 .show(grandchild)
343 .apply(true);
344
345 auto grandchildHandle = grandchild->getHandle();
346
347 // Captures only the grandchild.
348 ScreenCapture::captureLayers(&mCapture, grandchildHandle);
349 mCapture->checkPixel(0, 0, 50, 50, 50);
350 mCapture->checkPixel(4, 4, 50, 50, 50);
351}
352
353TEST_F(ScreenCaptureTest, CaptureCrop) {
354 sp<SurfaceControl> redLayer = createLayer(String8("Red surface"), 60, 60, 0);
355 sp<SurfaceControl> blueLayer = createSurface(mClient, "Blue surface", 30, 30,
356 PIXEL_FORMAT_RGBA_8888, 0, redLayer.get());
357
358 ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(redLayer, Color::RED, 60, 60));
359 ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(blueLayer, Color::BLUE, 30, 30));
360
361 SurfaceComposerClient::Transaction()
362 .setLayer(redLayer, INT32_MAX - 1)
363 .show(redLayer)
364 .show(blueLayer)
365 .apply(true);
366
367 auto redLayerHandle = redLayer->getHandle();
368
369 // Capturing full screen should have both red and blue are visible.
370 ScreenCapture::captureLayers(&mCapture, redLayerHandle);
371 mCapture->expectColor(Rect(0, 0, 29, 29), Color::BLUE);
372 // red area below the blue area
373 mCapture->expectColor(Rect(0, 30, 59, 59), Color::RED);
374 // red area to the right of the blue area
375 mCapture->expectColor(Rect(30, 0, 59, 59), Color::RED);
376
377 const Rect crop = Rect(0, 0, 30, 30);
378 ScreenCapture::captureLayers(&mCapture, redLayerHandle, crop);
379 // Capturing the cropped screen, cropping out the shown red area, should leave only the blue
380 // area visible.
381 mCapture->expectColor(Rect(0, 0, 29, 29), Color::BLUE);
382 mCapture->checkPixel(30, 30, 0, 0, 0);
383}
384
385TEST_F(ScreenCaptureTest, CaptureSize) {
386 sp<SurfaceControl> redLayer = createLayer(String8("Red surface"), 60, 60, 0);
387 sp<SurfaceControl> blueLayer = createSurface(mClient, "Blue surface", 30, 30,
388 PIXEL_FORMAT_RGBA_8888, 0, redLayer.get());
389
390 ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(redLayer, Color::RED, 60, 60));
391 ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(blueLayer, Color::BLUE, 30, 30));
392
393 SurfaceComposerClient::Transaction()
394 .setLayer(redLayer, INT32_MAX - 1)
395 .show(redLayer)
396 .show(blueLayer)
397 .apply(true);
398
399 auto redLayerHandle = redLayer->getHandle();
400
401 // Capturing full screen should have both red and blue are visible.
402 ScreenCapture::captureLayers(&mCapture, redLayerHandle);
403 mCapture->expectColor(Rect(0, 0, 29, 29), Color::BLUE);
404 // red area below the blue area
405 mCapture->expectColor(Rect(0, 30, 59, 59), Color::RED);
406 // red area to the right of the blue area
407 mCapture->expectColor(Rect(30, 0, 59, 59), Color::RED);
408
409 ScreenCapture::captureLayers(&mCapture, redLayerHandle, Rect::EMPTY_RECT, 0.5);
410 // Capturing the downsized area (30x30) should leave both red and blue but in a smaller area.
411 mCapture->expectColor(Rect(0, 0, 14, 14), Color::BLUE);
412 // red area below the blue area
413 mCapture->expectColor(Rect(0, 15, 29, 29), Color::RED);
414 // red area to the right of the blue area
415 mCapture->expectColor(Rect(15, 0, 29, 29), Color::RED);
416 mCapture->checkPixel(30, 30, 0, 0, 0);
417}
418
419TEST_F(ScreenCaptureTest, CaptureInvalidLayer) {
420 sp<SurfaceControl> redLayer = createLayer(String8("Red surface"), 60, 60, 0);
421
422 ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(redLayer, Color::RED, 60, 60));
423
424 auto redLayerHandle = redLayer->getHandle();
425 Transaction().reparent(redLayer, nullptr).apply();
426 redLayer.clear();
427 SurfaceComposerClient::Transaction().apply(true);
428
429 LayerCaptureArgs args;
430 args.layerHandle = redLayerHandle;
431
432 ScreenCaptureResults captureResults;
433 sp<ISurfaceComposer> sf(ComposerService::getComposerService());
434 // Layer was deleted so captureLayers should fail with NAME_NOT_FOUND
435 ASSERT_EQ(NAME_NOT_FOUND, sf->captureLayers(args, captureResults));
436}
437
438// In the following tests we verify successful skipping of a parent layer,
439// so we use the same verification logic and only change how we mutate
440// the parent layer to verify that various properties are ignored.
441class ScreenCaptureChildOnlyTest : public ScreenCaptureTest {
442public:
443 void SetUp() override {
444 ScreenCaptureTest::SetUp();
445
446 mChild = createSurface(mClient, "Child surface", 10, 10, PIXEL_FORMAT_RGBA_8888, 0,
447 mFGSurfaceControl.get());
448 TransactionUtils::fillSurfaceRGBA8(mChild, 200, 200, 200);
449
450 SurfaceComposerClient::Transaction().show(mChild).apply(true);
451 }
452
453 void verify(std::function<void()> verifyStartingState) {
454 // Verify starting state before a screenshot is taken.
455 verifyStartingState();
456
457 // Verify child layer does not inherit any of the properties of its
458 // parent when its screenshot is captured.
459 auto fgHandle = mFGSurfaceControl->getHandle();
460 ScreenCapture::captureChildLayers(&mCapture, fgHandle);
461 mCapture->checkPixel(10, 10, 0, 0, 0);
462 mCapture->expectChildColor(0, 0);
463
464 // Verify all assumptions are still true after the screenshot is taken.
465 verifyStartingState();
466 }
467
468 std::unique_ptr<ScreenCapture> mCapture;
469 sp<SurfaceControl> mChild;
470};
471
472// Regression test b/76099859
473TEST_F(ScreenCaptureChildOnlyTest, CaptureLayerIgnoresParentVisibility) {
474 SurfaceComposerClient::Transaction().hide(mFGSurfaceControl).apply(true);
475
476 // Even though the parent is hidden we should still capture the child.
477
478 // Before and after reparenting, verify child is properly hidden
479 // when rendering full-screen.
480 verify([&] { screenshot()->expectBGColor(64, 64); });
481}
482
483TEST_F(ScreenCaptureChildOnlyTest, CaptureLayerIgnoresParentCrop) {
484 SurfaceComposerClient::Transaction()
485 .setCrop_legacy(mFGSurfaceControl, Rect(0, 0, 1, 1))
486 .apply(true);
487
488 // Even though the parent is cropped out we should still capture the child.
489
490 // Before and after reparenting, verify child is cropped by parent.
491 verify([&] { screenshot()->expectBGColor(65, 65); });
492}
493
494// Regression test b/124372894
495TEST_F(ScreenCaptureChildOnlyTest, CaptureLayerIgnoresTransform) {
496 SurfaceComposerClient::Transaction().setMatrix(mFGSurfaceControl, 2, 0, 0, 2).apply(true);
497
498 // We should not inherit the parent scaling.
499
500 // Before and after reparenting, verify child is properly scaled.
501 verify([&] { screenshot()->expectChildColor(80, 80); });
502}
503
504} // namespace android