blob: cdd9d92063034609d0619809ab35f402ebbaedda [file] [log] [blame]
Valerie Hau9cfc6d82019-09-23 13:54:07 -07001/*
2 * Copyright (C) 2019 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
Ady Abrahamb0dbdaa2020-01-06 16:19:42 -080017// TODO(b/129481165): remove the #pragma below and fix conversion issues
18#pragma clang diagnostic push
19#pragma clang diagnostic ignored "-Wconversion"
20
Valerie Hau9cfc6d82019-09-23 13:54:07 -070021#include "LayerTransactionTest.h"
22
23namespace android {
24
25using android::hardware::graphics::common::V1_1::BufferUsage;
26
27::testing::Environment* const binderEnv =
28 ::testing::AddGlobalTestEnvironment(new BinderEnvironment());
29
30class LayerUpdateTest : public LayerTransactionTest {
31protected:
32 virtual void SetUp() {
33 LayerTransactionTest::SetUp();
34 ASSERT_EQ(NO_ERROR, mClient->initCheck());
35
36 const auto display = SurfaceComposerClient::getInternalDisplayToken();
37 ASSERT_FALSE(display == nullptr);
38
Dominik Laskowski3cb3d4e2019-11-21 11:14:45 -080039 DisplayConfig config;
40 ASSERT_EQ(NO_ERROR, SurfaceComposerClient::getActiveDisplayConfig(display, &config));
41 const ui::Size& resolution = config.resolution;
Valerie Hau9cfc6d82019-09-23 13:54:07 -070042
43 // Background surface
Dominik Laskowski3cb3d4e2019-11-21 11:14:45 -080044 mBGSurfaceControl = createLayer(String8("BG Test Surface"), resolution.getWidth(),
45 resolution.getHeight(), 0);
Valerie Hau9cfc6d82019-09-23 13:54:07 -070046 ASSERT_TRUE(mBGSurfaceControl != nullptr);
47 ASSERT_TRUE(mBGSurfaceControl->isValid());
48 TransactionUtils::fillSurfaceRGBA8(mBGSurfaceControl, 63, 63, 195);
49
50 // Foreground surface
51 mFGSurfaceControl = createLayer(String8("FG Test Surface"), 64, 64, 0);
52
53 ASSERT_TRUE(mFGSurfaceControl != nullptr);
54 ASSERT_TRUE(mFGSurfaceControl->isValid());
55
56 TransactionUtils::fillSurfaceRGBA8(mFGSurfaceControl, 195, 63, 63);
57
58 // Synchronization surface
59 mSyncSurfaceControl = createLayer(String8("Sync Test Surface"), 1, 1, 0);
60 ASSERT_TRUE(mSyncSurfaceControl != nullptr);
61 ASSERT_TRUE(mSyncSurfaceControl->isValid());
62
63 TransactionUtils::fillSurfaceRGBA8(mSyncSurfaceControl, 31, 31, 31);
64
65 asTransaction([&](Transaction& t) {
66 t.setDisplayLayerStack(display, 0);
67
68 t.setLayer(mBGSurfaceControl, INT32_MAX - 2).show(mBGSurfaceControl);
69
70 t.setLayer(mFGSurfaceControl, INT32_MAX - 1)
71 .setPosition(mFGSurfaceControl, 64, 64)
72 .show(mFGSurfaceControl);
73
74 t.setLayer(mSyncSurfaceControl, INT32_MAX - 1)
Dominik Laskowski3cb3d4e2019-11-21 11:14:45 -080075 .setPosition(mSyncSurfaceControl, resolution.getWidth() - 2,
76 resolution.getHeight() - 2)
Valerie Hau9cfc6d82019-09-23 13:54:07 -070077 .show(mSyncSurfaceControl);
78 });
79 }
80
81 virtual void TearDown() {
82 LayerTransactionTest::TearDown();
83 mBGSurfaceControl = 0;
84 mFGSurfaceControl = 0;
85 mSyncSurfaceControl = 0;
86 }
87
88 void waitForPostedBuffers() {
89 // Since the sync surface is in synchronous mode (i.e. double buffered)
90 // posting three buffers to it should ensure that at least two
91 // SurfaceFlinger::handlePageFlip calls have been made, which should
92 // guaranteed that a buffer posted to another Surface has been retired.
93 TransactionUtils::fillSurfaceRGBA8(mSyncSurfaceControl, 31, 31, 31);
94 TransactionUtils::fillSurfaceRGBA8(mSyncSurfaceControl, 31, 31, 31);
95 TransactionUtils::fillSurfaceRGBA8(mSyncSurfaceControl, 31, 31, 31);
96 }
97
98 sp<SurfaceControl> mBGSurfaceControl;
99 sp<SurfaceControl> mFGSurfaceControl;
100
101 // This surface is used to ensure that the buffers posted to
102 // mFGSurfaceControl have been picked up by SurfaceFlinger.
103 sp<SurfaceControl> mSyncSurfaceControl;
104};
105
106TEST_F(LayerUpdateTest, RelativesAreNotDetached) {
107 std::unique_ptr<ScreenCapture> sc;
108
109 sp<SurfaceControl> relative = createLayer(String8("relativeTestSurface"), 10, 10, 0);
110 TransactionUtils::fillSurfaceRGBA8(relative, 10, 10, 10);
111 waitForPostedBuffers();
112
113 Transaction{}
114 .setRelativeLayer(relative, mFGSurfaceControl->getHandle(), 1)
115 .setPosition(relative, 64, 64)
116 .apply();
117
118 {
119 // The relative should be on top of the FG control.
120 ScreenCapture::captureScreen(&sc);
121 sc->checkPixel(64, 64, 10, 10, 10);
122 }
123 Transaction{}.detachChildren(mFGSurfaceControl).apply();
124
125 {
126 // Nothing should change at this point.
127 ScreenCapture::captureScreen(&sc);
128 sc->checkPixel(64, 64, 10, 10, 10);
129 }
130
131 Transaction{}.hide(relative).apply();
132
133 {
134 // Ensure that the relative was actually hidden, rather than
135 // being left in the detached but visible state.
136 ScreenCapture::captureScreen(&sc);
137 sc->expectFGColor(64, 64);
138 }
139}
140
141class GeometryLatchingTest : public LayerUpdateTest {
142protected:
143 void EXPECT_INITIAL_STATE(const char* trace) {
144 SCOPED_TRACE(trace);
145 ScreenCapture::captureScreen(&sc);
146 // We find the leading edge of the FG surface.
147 sc->expectFGColor(127, 127);
148 sc->expectBGColor(128, 128);
149 }
150
151 void lockAndFillFGBuffer() {
152 TransactionUtils::fillSurfaceRGBA8(mFGSurfaceControl, 195, 63, 63, false);
153 }
154
155 void unlockFGBuffer() {
156 sp<Surface> s = mFGSurfaceControl->getSurface();
157 ASSERT_EQ(NO_ERROR, s->unlockAndPost());
158 waitForPostedBuffers();
159 }
160
161 void completeFGResize() {
162 TransactionUtils::fillSurfaceRGBA8(mFGSurfaceControl, 195, 63, 63);
163 waitForPostedBuffers();
164 }
165 void restoreInitialState() {
166 asTransaction([&](Transaction& t) {
167 t.setSize(mFGSurfaceControl, 64, 64);
168 t.setPosition(mFGSurfaceControl, 64, 64);
169 t.setCrop_legacy(mFGSurfaceControl, Rect(0, 0, 64, 64));
170 });
171
172 EXPECT_INITIAL_STATE("After restoring initial state");
173 }
174 std::unique_ptr<ScreenCapture> sc;
175};
176
177class CropLatchingTest : public GeometryLatchingTest {
178protected:
179 void EXPECT_CROPPED_STATE(const char* trace) {
180 SCOPED_TRACE(trace);
181 ScreenCapture::captureScreen(&sc);
182 // The edge should be moved back one pixel by our crop.
183 sc->expectFGColor(126, 126);
184 sc->expectBGColor(127, 127);
185 sc->expectBGColor(128, 128);
186 }
187
188 void EXPECT_RESIZE_STATE(const char* trace) {
189 SCOPED_TRACE(trace);
190 ScreenCapture::captureScreen(&sc);
191 // The FG is now resized too 128,128 at 64,64
192 sc->expectFGColor(64, 64);
193 sc->expectFGColor(191, 191);
194 sc->expectBGColor(192, 192);
195 }
196};
197
198TEST_F(LayerUpdateTest, DeferredTransactionTest) {
199 std::unique_ptr<ScreenCapture> sc;
200 {
201 SCOPED_TRACE("before anything");
202 ScreenCapture::captureScreen(&sc);
203 sc->expectBGColor(32, 32);
204 sc->expectFGColor(96, 96);
205 sc->expectBGColor(160, 160);
206 }
207
208 // set up two deferred transactions on different frames
209 asTransaction([&](Transaction& t) {
210 t.setAlpha(mFGSurfaceControl, 0.75);
211 t.deferTransactionUntil_legacy(mFGSurfaceControl, mSyncSurfaceControl->getHandle(),
212 mSyncSurfaceControl->getSurface()->getNextFrameNumber());
213 });
214
215 asTransaction([&](Transaction& t) {
216 t.setPosition(mFGSurfaceControl, 128, 128);
217 t.deferTransactionUntil_legacy(mFGSurfaceControl, mSyncSurfaceControl->getHandle(),
218 mSyncSurfaceControl->getSurface()->getNextFrameNumber() + 1);
219 });
220
221 {
222 SCOPED_TRACE("before any trigger");
223 ScreenCapture::captureScreen(&sc);
224 sc->expectBGColor(32, 32);
225 sc->expectFGColor(96, 96);
226 sc->expectBGColor(160, 160);
227 }
228
229 // should trigger the first deferred transaction, but not the second one
230 TransactionUtils::fillSurfaceRGBA8(mSyncSurfaceControl, 31, 31, 31);
231 {
232 SCOPED_TRACE("after first trigger");
233 ScreenCapture::captureScreen(&sc);
234 sc->expectBGColor(32, 32);
235 sc->checkPixel(96, 96, 162, 63, 96);
236 sc->expectBGColor(160, 160);
237 }
238
239 // should show up immediately since it's not deferred
240 asTransaction([&](Transaction& t) { t.setAlpha(mFGSurfaceControl, 1.0); });
241
242 // trigger the second deferred transaction
243 TransactionUtils::fillSurfaceRGBA8(mSyncSurfaceControl, 31, 31, 31);
244 {
245 SCOPED_TRACE("after second trigger");
246 ScreenCapture::captureScreen(&sc);
247 sc->expectBGColor(32, 32);
248 sc->expectBGColor(96, 96);
249 sc->expectFGColor(160, 160);
250 }
251}
252
253TEST_F(LayerUpdateTest, LayerWithNoBuffersResizesImmediately) {
254 std::unique_ptr<ScreenCapture> sc;
255
256 sp<SurfaceControl> childNoBuffer =
257 createSurface(mClient, "Bufferless child", 0 /* buffer width */, 0 /* buffer height */,
258 PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
259 sp<SurfaceControl> childBuffer = createSurface(mClient, "Buffered child", 20, 20,
260 PIXEL_FORMAT_RGBA_8888, 0, childNoBuffer.get());
261 TransactionUtils::fillSurfaceRGBA8(childBuffer, 200, 200, 200);
262 SurfaceComposerClient::Transaction{}
263 .setCrop_legacy(childNoBuffer, Rect(0, 0, 10, 10))
264 .show(childNoBuffer)
265 .show(childBuffer)
266 .apply(true);
267 {
268 ScreenCapture::captureScreen(&sc);
269 sc->expectChildColor(73, 73);
270 sc->expectFGColor(74, 74);
271 }
272 SurfaceComposerClient::Transaction{}
273 .setCrop_legacy(childNoBuffer, Rect(0, 0, 20, 20))
274 .apply(true);
275 {
276 ScreenCapture::captureScreen(&sc);
277 sc->expectChildColor(73, 73);
278 sc->expectChildColor(74, 74);
279 }
280}
281
282TEST_F(LayerUpdateTest, MergingTransactions) {
283 std::unique_ptr<ScreenCapture> sc;
284 {
285 SCOPED_TRACE("before move");
286 ScreenCapture::captureScreen(&sc);
287 sc->expectBGColor(0, 12);
288 sc->expectFGColor(75, 75);
289 sc->expectBGColor(145, 145);
290 }
291
292 Transaction t1, t2;
293 t1.setPosition(mFGSurfaceControl, 128, 128);
294 t2.setPosition(mFGSurfaceControl, 0, 0);
295 // We expect that the position update from t2 now
296 // overwrites the position update from t1.
297 t1.merge(std::move(t2));
298 t1.apply();
299
300 {
301 ScreenCapture::captureScreen(&sc);
302 sc->expectFGColor(1, 1);
303 }
304}
305
306TEST_F(LayerUpdateTest, MergingTransactionFlags) {
307 Transaction().hide(mFGSurfaceControl).apply();
308 std::unique_ptr<ScreenCapture> sc;
309 {
310 SCOPED_TRACE("before merge");
311 ScreenCapture::captureScreen(&sc);
312 sc->expectBGColor(0, 12);
313 sc->expectBGColor(75, 75);
314 sc->expectBGColor(145, 145);
315 }
316
317 Transaction t1, t2;
318 t1.show(mFGSurfaceControl);
319 t2.setFlags(mFGSurfaceControl, 0 /* flags */, layer_state_t::eLayerSecure /* mask */);
320 t1.merge(std::move(t2));
321 t1.apply();
322
323 {
324 SCOPED_TRACE("after merge");
325 ScreenCapture::captureScreen(&sc);
326 sc->expectFGColor(75, 75);
327 }
328}
329
330class ChildLayerTest : public LayerUpdateTest {
331protected:
332 void SetUp() override {
333 LayerUpdateTest::SetUp();
334 mChild = createSurface(mClient, "Child surface", 10, 15, PIXEL_FORMAT_RGBA_8888, 0,
335 mFGSurfaceControl.get());
336 TransactionUtils::fillSurfaceRGBA8(mChild, 200, 200, 200);
337
338 {
339 SCOPED_TRACE("before anything");
340 mCapture = screenshot();
341 mCapture->expectChildColor(64, 64);
342 }
343 }
344 void TearDown() override {
345 LayerUpdateTest::TearDown();
346 mChild = 0;
347 }
348
349 sp<SurfaceControl> mChild;
350 std::unique_ptr<ScreenCapture> mCapture;
351};
352
353TEST_F(ChildLayerTest, ChildLayerPositioning) {
354 asTransaction([&](Transaction& t) {
355 t.show(mChild);
356 t.setPosition(mChild, 10, 10);
357 t.setPosition(mFGSurfaceControl, 64, 64);
358 });
359
360 {
361 mCapture = screenshot();
362 // Top left of foreground must now be visible
363 mCapture->expectFGColor(64, 64);
364 // But 10 pixels in we should see the child surface
365 mCapture->expectChildColor(74, 74);
366 // And 10 more pixels we should be back to the foreground surface
367 mCapture->expectFGColor(84, 84);
368 }
369
370 asTransaction([&](Transaction& t) { t.setPosition(mFGSurfaceControl, 0, 0); });
371
372 {
373 mCapture = screenshot();
374 // Top left of foreground should now be at 0, 0
375 mCapture->expectFGColor(0, 0);
376 // But 10 pixels in we should see the child surface
377 mCapture->expectChildColor(10, 10);
378 // And 10 more pixels we should be back to the foreground surface
379 mCapture->expectFGColor(20, 20);
380 }
381}
382
383TEST_F(ChildLayerTest, ChildLayerCropping) {
384 asTransaction([&](Transaction& t) {
385 t.show(mChild);
386 t.setPosition(mChild, 0, 0);
387 t.setPosition(mFGSurfaceControl, 0, 0);
388 t.setCrop_legacy(mFGSurfaceControl, Rect(0, 0, 5, 5));
389 });
390
391 {
392 mCapture = screenshot();
393 mCapture->expectChildColor(0, 0);
394 mCapture->expectChildColor(4, 4);
395 mCapture->expectBGColor(5, 5);
396 }
397}
398
399TEST_F(ChildLayerTest, ChildLayerConstraints) {
400 asTransaction([&](Transaction& t) {
401 t.show(mChild);
402 t.setPosition(mFGSurfaceControl, 0, 0);
403 t.setPosition(mChild, 63, 63);
404 });
405
406 {
407 mCapture = screenshot();
408 mCapture->expectFGColor(0, 0);
409 // Last pixel in foreground should now be the child.
410 mCapture->expectChildColor(63, 63);
411 // But the child should be constrained and the next pixel
412 // must be the background
413 mCapture->expectBGColor(64, 64);
414 }
415}
416
417TEST_F(ChildLayerTest, ChildLayerScaling) {
418 asTransaction([&](Transaction& t) { t.setPosition(mFGSurfaceControl, 0, 0); });
419
420 // Find the boundary between the parent and child
421 {
422 mCapture = screenshot();
423 mCapture->expectChildColor(9, 9);
424 mCapture->expectFGColor(10, 10);
425 }
426
427 asTransaction([&](Transaction& t) { t.setMatrix(mFGSurfaceControl, 2.0, 0, 0, 2.0); });
428
429 // The boundary should be twice as far from the origin now.
430 // The pixels from the last test should all be child now
431 {
432 mCapture = screenshot();
433 mCapture->expectChildColor(9, 9);
434 mCapture->expectChildColor(10, 10);
435 mCapture->expectChildColor(19, 19);
436 mCapture->expectFGColor(20, 20);
437 }
438}
439
440// A child with a scale transform should be cropped by its parent bounds.
441TEST_F(ChildLayerTest, ChildLayerScalingCroppedByParent) {
442 asTransaction([&](Transaction& t) {
443 t.setPosition(mFGSurfaceControl, 0, 0);
444 t.setPosition(mChild, 0, 0);
445 });
446
447 // Find the boundary between the parent and child.
448 {
449 mCapture = screenshot();
450 mCapture->expectChildColor(0, 0);
451 mCapture->expectChildColor(9, 9);
452 mCapture->expectFGColor(10, 10);
453 }
454
455 asTransaction([&](Transaction& t) { t.setMatrix(mChild, 10.0, 0, 0, 10.0); });
456
457 // The child should fill its parent bounds and be cropped by it.
458 {
459 mCapture = screenshot();
460 mCapture->expectChildColor(0, 0);
461 mCapture->expectChildColor(63, 63);
462 mCapture->expectBGColor(64, 64);
463 }
464}
465
466TEST_F(ChildLayerTest, ChildLayerAlpha) {
467 TransactionUtils::fillSurfaceRGBA8(mBGSurfaceControl, 0, 0, 254);
468 TransactionUtils::fillSurfaceRGBA8(mFGSurfaceControl, 254, 0, 0);
469 TransactionUtils::fillSurfaceRGBA8(mChild, 0, 254, 0);
470 waitForPostedBuffers();
471
472 asTransaction([&](Transaction& t) {
473 t.show(mChild);
474 t.setPosition(mChild, 0, 0);
475 t.setPosition(mFGSurfaceControl, 0, 0);
476 });
477
478 {
479 mCapture = screenshot();
480 // Unblended child color
481 mCapture->checkPixel(0, 0, 0, 254, 0);
482 }
483
484 asTransaction([&](Transaction& t) { t.setAlpha(mChild, 0.5); });
485
486 {
487 mCapture = screenshot();
488 // Child and BG blended.
489 mCapture->checkPixel(0, 0, 127, 127, 0);
490 }
491
492 asTransaction([&](Transaction& t) { t.setAlpha(mFGSurfaceControl, 0.5); });
493
494 {
495 mCapture = screenshot();
496 // Child and BG blended.
497 mCapture->checkPixel(0, 0, 95, 64, 95);
498 }
499}
500
501TEST_F(ChildLayerTest, ReparentChildren) {
502 asTransaction([&](Transaction& t) {
503 t.show(mChild);
504 t.setPosition(mChild, 10, 10);
505 t.setPosition(mFGSurfaceControl, 64, 64);
506 });
507
508 {
509 mCapture = screenshot();
510 // Top left of foreground must now be visible
511 mCapture->expectFGColor(64, 64);
512 // But 10 pixels in we should see the child surface
513 mCapture->expectChildColor(74, 74);
514 // And 10 more pixels we should be back to the foreground surface
515 mCapture->expectFGColor(84, 84);
516 }
517
518 asTransaction([&](Transaction& t) {
519 t.reparentChildren(mFGSurfaceControl, mBGSurfaceControl->getHandle());
520 });
521
522 {
523 mCapture = screenshot();
524 mCapture->expectFGColor(64, 64);
525 // In reparenting we should have exposed the entire foreground surface.
526 mCapture->expectFGColor(74, 74);
527 // And the child layer should now begin at 10, 10 (since the BG
528 // layer is at (0, 0)).
529 mCapture->expectBGColor(9, 9);
530 mCapture->expectChildColor(10, 10);
531 }
532}
533
534TEST_F(ChildLayerTest, ChildrenSurviveParentDestruction) {
535 sp<SurfaceControl> mGrandChild =
536 createSurface(mClient, "Grand Child", 10, 10, PIXEL_FORMAT_RGBA_8888, 0, mChild.get());
537 TransactionUtils::fillSurfaceRGBA8(mGrandChild, 111, 111, 111);
538
539 {
540 SCOPED_TRACE("Grandchild visible");
541 ScreenCapture::captureScreen(&mCapture);
542 mCapture->checkPixel(64, 64, 111, 111, 111);
543 }
544
Robert Carr0e328f62020-02-06 17:12:08 -0800545 Transaction().reparent(mChild, nullptr).apply();
Valerie Hau9cfc6d82019-09-23 13:54:07 -0700546 mChild.clear();
547
548 {
549 SCOPED_TRACE("After destroying child");
550 ScreenCapture::captureScreen(&mCapture);
551 mCapture->expectFGColor(64, 64);
552 }
553
554 asTransaction([&](Transaction& t) { t.reparent(mGrandChild, mFGSurfaceControl->getHandle()); });
555
556 {
557 SCOPED_TRACE("After reparenting grandchild");
558 ScreenCapture::captureScreen(&mCapture);
559 mCapture->checkPixel(64, 64, 111, 111, 111);
560 }
561}
562
563TEST_F(ChildLayerTest, ChildrenRelativeZSurvivesParentDestruction) {
564 sp<SurfaceControl> mGrandChild =
565 createSurface(mClient, "Grand Child", 10, 10, PIXEL_FORMAT_RGBA_8888, 0, mChild.get());
566 TransactionUtils::fillSurfaceRGBA8(mGrandChild, 111, 111, 111);
567
568 // draw grand child behind the foreground surface
569 asTransaction([&](Transaction& t) {
570 t.setRelativeLayer(mGrandChild, mFGSurfaceControl->getHandle(), -1);
571 });
572
573 {
574 SCOPED_TRACE("Child visible");
575 ScreenCapture::captureScreen(&mCapture);
576 mCapture->checkPixel(64, 64, 200, 200, 200);
577 }
578
579 asTransaction([&](Transaction& t) {
580 t.reparent(mChild, nullptr);
581 t.reparentChildren(mChild, mFGSurfaceControl->getHandle());
582 });
583
584 {
585 SCOPED_TRACE("foreground visible reparenting grandchild");
586 ScreenCapture::captureScreen(&mCapture);
587 mCapture->checkPixel(64, 64, 195, 63, 63);
588 }
589}
590
591TEST_F(ChildLayerTest, DetachChildrenSameClient) {
592 asTransaction([&](Transaction& t) {
593 t.show(mChild);
594 t.setPosition(mChild, 10, 10);
595 t.setPosition(mFGSurfaceControl, 64, 64);
596 });
597
598 {
599 mCapture = screenshot();
600 // Top left of foreground must now be visible
601 mCapture->expectFGColor(64, 64);
602 // But 10 pixels in we should see the child surface
603 mCapture->expectChildColor(74, 74);
604 // And 10 more pixels we should be back to the foreground surface
605 mCapture->expectFGColor(84, 84);
606 }
607
608 asTransaction([&](Transaction& t) { t.detachChildren(mFGSurfaceControl); });
609
610 asTransaction([&](Transaction& t) { t.hide(mChild); });
611
612 // Since the child has the same client as the parent, it will not get
613 // detached and will be hidden.
614 {
615 mCapture = screenshot();
616 mCapture->expectFGColor(64, 64);
617 mCapture->expectFGColor(74, 74);
618 mCapture->expectFGColor(84, 84);
619 }
620}
621
622TEST_F(ChildLayerTest, DetachChildrenDifferentClient) {
623 sp<SurfaceComposerClient> mNewComposerClient = new SurfaceComposerClient;
624 sp<SurfaceControl> mChildNewClient =
625 createSurface(mNewComposerClient, "New Child Test Surface", 10, 10,
626 PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
627
628 ASSERT_TRUE(mChildNewClient->isValid());
629
630 TransactionUtils::fillSurfaceRGBA8(mChildNewClient, 200, 200, 200);
631
632 asTransaction([&](Transaction& t) {
633 t.hide(mChild);
634 t.show(mChildNewClient);
635 t.setPosition(mChildNewClient, 10, 10);
636 t.setPosition(mFGSurfaceControl, 64, 64);
637 });
638
639 {
640 mCapture = screenshot();
641 // Top left of foreground must now be visible
642 mCapture->expectFGColor(64, 64);
643 // But 10 pixels in we should see the child surface
644 mCapture->expectChildColor(74, 74);
645 // And 10 more pixels we should be back to the foreground surface
646 mCapture->expectFGColor(84, 84);
647 }
648
649 asTransaction([&](Transaction& t) { t.detachChildren(mFGSurfaceControl); });
650
651 asTransaction([&](Transaction& t) { t.hide(mChildNewClient); });
652
653 // Nothing should have changed.
654 {
655 mCapture = screenshot();
656 mCapture->expectFGColor(64, 64);
657 mCapture->expectChildColor(74, 74);
658 mCapture->expectFGColor(84, 84);
659 }
660}
661
662TEST_F(ChildLayerTest, DetachChildrenThenAttach) {
663 sp<SurfaceComposerClient> newComposerClient = new SurfaceComposerClient;
664 sp<SurfaceControl> childNewClient =
665 newComposerClient->createSurface(String8("New Child Test Surface"), 10, 10,
666 PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
667
668 ASSERT_TRUE(childNewClient != nullptr);
669 ASSERT_TRUE(childNewClient->isValid());
670
671 TransactionUtils::fillSurfaceRGBA8(childNewClient, 200, 200, 200);
672
673 Transaction()
674 .hide(mChild)
675 .show(childNewClient)
676 .setPosition(childNewClient, 10, 10)
677 .setPosition(mFGSurfaceControl, 64, 64)
678 .apply();
679
680 {
681 mCapture = screenshot();
682 // Top left of foreground must now be visible
683 mCapture->expectFGColor(64, 64);
684 // But 10 pixels in we should see the child surface
685 mCapture->expectChildColor(74, 74);
686 // And 10 more pixels we should be back to the foreground surface
687 mCapture->expectFGColor(84, 84);
688 }
689
690 Transaction().detachChildren(mFGSurfaceControl).apply();
691 Transaction().hide(childNewClient).apply();
692
693 // Nothing should have changed.
694 {
695 mCapture = screenshot();
696 mCapture->expectFGColor(64, 64);
697 mCapture->expectChildColor(74, 74);
698 mCapture->expectFGColor(84, 84);
699 }
700
701 sp<SurfaceControl> newParentSurface = createLayer(String8("New Parent Surface"), 32, 32, 0);
702 fillLayerColor(ISurfaceComposerClient::eFXSurfaceBufferQueue, newParentSurface, Color::RED, 32,
703 32);
704 Transaction()
705 .setLayer(newParentSurface, INT32_MAX - 1)
706 .show(newParentSurface)
707 .setPosition(newParentSurface, 20, 20)
708 .reparent(childNewClient, newParentSurface->getHandle())
709 .apply();
710 {
711 mCapture = screenshot();
712 // Child is now hidden.
713 mCapture->expectColor(Rect(20, 20, 52, 52), Color::RED);
714 }
715}
716TEST_F(ChildLayerTest, DetachChildrenWithDeferredTransaction) {
717 sp<SurfaceComposerClient> newComposerClient = new SurfaceComposerClient;
718 sp<SurfaceControl> childNewClient =
719 newComposerClient->createSurface(String8("New Child Test Surface"), 10, 10,
720 PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
721
722 ASSERT_TRUE(childNewClient != nullptr);
723 ASSERT_TRUE(childNewClient->isValid());
724
725 TransactionUtils::fillSurfaceRGBA8(childNewClient, 200, 200, 200);
726
727 Transaction()
728 .hide(mChild)
729 .show(childNewClient)
730 .setPosition(childNewClient, 10, 10)
731 .setPosition(mFGSurfaceControl, 64, 64)
732 .apply();
733
734 {
735 mCapture = screenshot();
736 Rect rect = Rect(74, 74, 84, 84);
737 mCapture->expectBorder(rect, Color{195, 63, 63, 255});
738 mCapture->expectColor(rect, Color{200, 200, 200, 255});
739 }
740
741 Transaction()
742 .deferTransactionUntil_legacy(childNewClient, mFGSurfaceControl->getHandle(),
743 mFGSurfaceControl->getSurface()->getNextFrameNumber())
744 .apply();
745 Transaction().detachChildren(mFGSurfaceControl).apply();
746 ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(mFGSurfaceControl, Color::RED, 32, 32));
747
748 // BufferLayer can still dequeue buffers even though there's a detached layer with a
749 // deferred transaction.
750 {
751 SCOPED_TRACE("new buffer");
752 mCapture = screenshot();
753 Rect rect = Rect(74, 74, 84, 84);
754 mCapture->expectBorder(rect, Color::RED);
755 mCapture->expectColor(rect, Color{200, 200, 200, 255});
756 }
757}
758
759TEST_F(ChildLayerTest, ChildrenInheritNonTransformScalingFromParent) {
760 asTransaction([&](Transaction& t) {
761 t.show(mChild);
762 t.setPosition(mChild, 0, 0);
763 t.setPosition(mFGSurfaceControl, 0, 0);
764 });
765
766 {
767 mCapture = screenshot();
768 // We've positioned the child in the top left.
769 mCapture->expectChildColor(0, 0);
770 // But it's only 10x15.
771 mCapture->expectFGColor(10, 15);
772 }
773
774 asTransaction([&](Transaction& t) {
775 t.setOverrideScalingMode(mFGSurfaceControl, NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
776 // We cause scaling by 2.
777 t.setSize(mFGSurfaceControl, 128, 128);
778 });
779
780 {
781 mCapture = screenshot();
782 // We've positioned the child in the top left.
783 mCapture->expectChildColor(0, 0);
784 mCapture->expectChildColor(10, 10);
785 mCapture->expectChildColor(19, 29);
786 // And now it should be scaled all the way to 20x30
787 mCapture->expectFGColor(20, 30);
788 }
789}
790
791// Regression test for b/37673612
792TEST_F(ChildLayerTest, ChildrenWithParentBufferTransform) {
793 asTransaction([&](Transaction& t) {
794 t.show(mChild);
795 t.setPosition(mChild, 0, 0);
796 t.setPosition(mFGSurfaceControl, 0, 0);
797 });
798
799 {
800 mCapture = screenshot();
801 // We've positioned the child in the top left.
802 mCapture->expectChildColor(0, 0);
803 mCapture->expectChildColor(9, 14);
804 // But it's only 10x15.
805 mCapture->expectFGColor(10, 15);
806 }
807 // We set things up as in b/37673612 so that there is a mismatch between the buffer size and
808 // the WM specified state size.
809 asTransaction([&](Transaction& t) { t.setSize(mFGSurfaceControl, 128, 64); });
810 sp<Surface> s = mFGSurfaceControl->getSurface();
811 auto anw = static_cast<ANativeWindow*>(s.get());
812 native_window_set_buffers_transform(anw, NATIVE_WINDOW_TRANSFORM_ROT_90);
813 native_window_set_buffers_dimensions(anw, 64, 128);
814 TransactionUtils::fillSurfaceRGBA8(mFGSurfaceControl, 195, 63, 63);
815 waitForPostedBuffers();
816
817 {
818 // The child should still be in the same place and not have any strange scaling as in
819 // b/37673612.
820 mCapture = screenshot();
821 mCapture->expectChildColor(0, 0);
822 mCapture->expectFGColor(10, 10);
823 }
824}
825
826// A child with a buffer transform from its parents should be cropped by its parent bounds.
827TEST_F(ChildLayerTest, ChildCroppedByParentWithBufferTransform) {
828 asTransaction([&](Transaction& t) {
829 t.show(mChild);
830 t.setPosition(mChild, 0, 0);
831 t.setPosition(mFGSurfaceControl, 0, 0);
832 t.setSize(mChild, 100, 100);
833 });
834 TransactionUtils::fillSurfaceRGBA8(mChild, 200, 200, 200);
835
836 {
837 mCapture = screenshot();
838
839 mCapture->expectChildColor(0, 0);
840 mCapture->expectChildColor(63, 63);
841 mCapture->expectBGColor(64, 64);
842 }
843
844 asTransaction([&](Transaction& t) { t.setSize(mFGSurfaceControl, 128, 64); });
845 sp<Surface> s = mFGSurfaceControl->getSurface();
846 auto anw = static_cast<ANativeWindow*>(s.get());
847 // Apply a 90 transform on the buffer.
848 native_window_set_buffers_transform(anw, NATIVE_WINDOW_TRANSFORM_ROT_90);
849 native_window_set_buffers_dimensions(anw, 64, 128);
850 TransactionUtils::fillSurfaceRGBA8(mFGSurfaceControl, 195, 63, 63);
851 waitForPostedBuffers();
852
853 // The child should be cropped by the new parent bounds.
854 {
855 mCapture = screenshot();
856 mCapture->expectChildColor(0, 0);
857 mCapture->expectChildColor(99, 63);
858 mCapture->expectFGColor(100, 63);
859 mCapture->expectBGColor(128, 64);
860 }
861}
862
863// A child with a scale transform from its parents should be cropped by its parent bounds.
864TEST_F(ChildLayerTest, ChildCroppedByParentWithBufferScale) {
865 asTransaction([&](Transaction& t) {
866 t.show(mChild);
867 t.setPosition(mChild, 0, 0);
868 t.setPosition(mFGSurfaceControl, 0, 0);
869 t.setSize(mChild, 200, 200);
870 });
871 TransactionUtils::fillSurfaceRGBA8(mChild, 200, 200, 200);
872
873 {
874 mCapture = screenshot();
875
876 mCapture->expectChildColor(0, 0);
877 mCapture->expectChildColor(63, 63);
878 mCapture->expectBGColor(64, 64);
879 }
880
881 asTransaction([&](Transaction& t) {
882 t.setOverrideScalingMode(mFGSurfaceControl, NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
883 // Set a scaling by 2.
884 t.setSize(mFGSurfaceControl, 128, 128);
885 });
886
887 // Child should inherit its parents scale but should be cropped by its parent bounds.
888 {
889 mCapture = screenshot();
890 mCapture->expectChildColor(0, 0);
891 mCapture->expectChildColor(127, 127);
892 mCapture->expectBGColor(128, 128);
893 }
894}
895
896// Regression test for b/127368943
897// Child should ignore the buffer transform but apply parent scale transform.
898TEST_F(ChildLayerTest, ChildrenWithParentBufferTransformAndScale) {
899 asTransaction([&](Transaction& t) {
900 t.show(mChild);
901 t.setPosition(mChild, 0, 0);
902 t.setPosition(mFGSurfaceControl, 0, 0);
903 });
904
905 {
906 mCapture = screenshot();
907 mCapture->expectChildColor(0, 0);
908 mCapture->expectChildColor(9, 14);
909 mCapture->expectFGColor(10, 15);
910 }
911
912 // Change the size of the foreground to 128 * 64 so we can test rotation as well.
913 asTransaction([&](Transaction& t) {
914 t.setOverrideScalingMode(mFGSurfaceControl, NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
915 t.setSize(mFGSurfaceControl, 128, 64);
916 });
917 sp<Surface> s = mFGSurfaceControl->getSurface();
918 auto anw = static_cast<ANativeWindow*>(s.get());
919 // Apply a 90 transform on the buffer and submit a buffer half the expected size so that we
920 // have an effective scale of 2.0 applied to the buffer along with a rotation transform.
921 native_window_set_buffers_transform(anw, NATIVE_WINDOW_TRANSFORM_ROT_90);
922 native_window_set_buffers_dimensions(anw, 32, 64);
923 TransactionUtils::fillSurfaceRGBA8(mFGSurfaceControl, 195, 63, 63);
924 waitForPostedBuffers();
925
926 // The child should ignore the buffer transform but apply the 2.0 scale from parent.
927 {
928 mCapture = screenshot();
929 mCapture->expectChildColor(0, 0);
930 mCapture->expectChildColor(19, 29);
931 mCapture->expectFGColor(20, 30);
932 }
933}
934
935TEST_F(ChildLayerTest, Bug36858924) {
936 // Destroy the child layer
937 mChild.clear();
938
939 // Now recreate it as hidden
940 mChild = createSurface(mClient, "Child surface", 10, 10, PIXEL_FORMAT_RGBA_8888,
941 ISurfaceComposerClient::eHidden, mFGSurfaceControl.get());
942
943 // Show the child layer in a deferred transaction
944 asTransaction([&](Transaction& t) {
945 t.deferTransactionUntil_legacy(mChild, mFGSurfaceControl->getHandle(),
946 mFGSurfaceControl->getSurface()->getNextFrameNumber());
947 t.show(mChild);
948 });
949
950 // Render the foreground surface a few times
951 //
952 // Prior to the bugfix for b/36858924, this would usually hang while trying to fill the third
953 // frame because SurfaceFlinger would never process the deferred transaction and would therefore
954 // never acquire/release the first buffer
955 ALOGI("Filling 1");
956 TransactionUtils::fillSurfaceRGBA8(mFGSurfaceControl, 0, 255, 0);
957 ALOGI("Filling 2");
958 TransactionUtils::fillSurfaceRGBA8(mFGSurfaceControl, 0, 0, 255);
959 ALOGI("Filling 3");
960 TransactionUtils::fillSurfaceRGBA8(mFGSurfaceControl, 255, 0, 0);
961 ALOGI("Filling 4");
962 TransactionUtils::fillSurfaceRGBA8(mFGSurfaceControl, 0, 255, 0);
963}
964
965TEST_F(ChildLayerTest, Reparent) {
966 asTransaction([&](Transaction& t) {
967 t.show(mChild);
968 t.setPosition(mChild, 10, 10);
969 t.setPosition(mFGSurfaceControl, 64, 64);
970 });
971
972 {
973 mCapture = screenshot();
974 // Top left of foreground must now be visible
975 mCapture->expectFGColor(64, 64);
976 // But 10 pixels in we should see the child surface
977 mCapture->expectChildColor(74, 74);
978 // And 10 more pixels we should be back to the foreground surface
979 mCapture->expectFGColor(84, 84);
980 }
981
982 asTransaction([&](Transaction& t) { t.reparent(mChild, mBGSurfaceControl->getHandle()); });
983
984 {
985 mCapture = screenshot();
986 mCapture->expectFGColor(64, 64);
987 // In reparenting we should have exposed the entire foreground surface.
988 mCapture->expectFGColor(74, 74);
989 // And the child layer should now begin at 10, 10 (since the BG
990 // layer is at (0, 0)).
991 mCapture->expectBGColor(9, 9);
992 mCapture->expectChildColor(10, 10);
993 }
994}
995
996TEST_F(ChildLayerTest, ReparentToNoParent) {
997 asTransaction([&](Transaction& t) {
998 t.show(mChild);
999 t.setPosition(mChild, 10, 10);
1000 t.setPosition(mFGSurfaceControl, 64, 64);
1001 });
1002
1003 {
1004 mCapture = screenshot();
1005 // Top left of foreground must now be visible
1006 mCapture->expectFGColor(64, 64);
1007 // But 10 pixels in we should see the child surface
1008 mCapture->expectChildColor(74, 74);
1009 // And 10 more pixels we should be back to the foreground surface
1010 mCapture->expectFGColor(84, 84);
1011 }
1012 asTransaction([&](Transaction& t) { t.reparent(mChild, nullptr); });
1013 {
1014 mCapture = screenshot();
1015 // The surface should now be offscreen.
1016 mCapture->expectFGColor(64, 64);
1017 mCapture->expectFGColor(74, 74);
1018 mCapture->expectFGColor(84, 84);
1019 }
1020}
1021
1022TEST_F(ChildLayerTest, ReparentFromNoParent) {
1023 sp<SurfaceControl> newSurface = createLayer(String8("New Surface"), 10, 10, 0);
1024 ASSERT_TRUE(newSurface != nullptr);
1025 ASSERT_TRUE(newSurface->isValid());
1026
1027 TransactionUtils::fillSurfaceRGBA8(newSurface, 63, 195, 63);
1028 asTransaction([&](Transaction& t) {
1029 t.hide(mChild);
1030 t.show(newSurface);
1031 t.setPosition(newSurface, 10, 10);
1032 t.setLayer(newSurface, INT32_MAX - 2);
1033 t.setPosition(mFGSurfaceControl, 64, 64);
1034 });
1035
1036 {
1037 mCapture = screenshot();
1038 // Top left of foreground must now be visible
1039 mCapture->expectFGColor(64, 64);
1040 // At 10, 10 we should see the new surface
1041 mCapture->checkPixel(10, 10, 63, 195, 63);
1042 }
1043
1044 asTransaction([&](Transaction& t) { t.reparent(newSurface, mFGSurfaceControl->getHandle()); });
1045
1046 {
1047 mCapture = screenshot();
1048 // newSurface will now be a child of mFGSurface so it will be 10, 10 offset from
1049 // mFGSurface, putting it at 74, 74.
1050 mCapture->expectFGColor(64, 64);
1051 mCapture->checkPixel(74, 74, 63, 195, 63);
1052 mCapture->expectFGColor(84, 84);
1053 }
1054}
1055
1056TEST_F(ChildLayerTest, NestedChildren) {
1057 sp<SurfaceControl> grandchild = createSurface(mClient, "Grandchild surface", 10, 10,
1058 PIXEL_FORMAT_RGBA_8888, 0, mChild.get());
1059 TransactionUtils::fillSurfaceRGBA8(grandchild, 50, 50, 50);
1060
1061 {
1062 mCapture = screenshot();
1063 // Expect the grandchild to begin at 64, 64 because it's a child of mChild layer
1064 // which begins at 64, 64
1065 mCapture->checkPixel(64, 64, 50, 50, 50);
1066 }
1067}
1068
1069TEST_F(ChildLayerTest, ChildLayerRelativeLayer) {
1070 sp<SurfaceControl> relative = createLayer(String8("Relative surface"), 128, 128, 0);
1071 TransactionUtils::fillSurfaceRGBA8(relative, 255, 255, 255);
1072
1073 Transaction t;
1074 t.setLayer(relative, INT32_MAX)
1075 .setRelativeLayer(mChild, relative->getHandle(), 1)
1076 .setPosition(mFGSurfaceControl, 0, 0)
1077 .apply(true);
1078
1079 // We expect that the child should have been elevated above our
1080 // INT_MAX layer even though it's not a child of it.
1081 {
1082 mCapture = screenshot();
1083 mCapture->expectChildColor(0, 0);
1084 mCapture->expectChildColor(9, 9);
1085 mCapture->checkPixel(10, 10, 255, 255, 255);
1086 }
1087}
1088
1089class BoundlessLayerTest : public LayerUpdateTest {
1090protected:
1091 std::unique_ptr<ScreenCapture> mCapture;
1092};
1093
1094// Verify setting a size on a buffer layer has no effect.
1095TEST_F(BoundlessLayerTest, BufferLayerIgnoresSize) {
1096 sp<SurfaceControl> bufferLayer =
1097 createSurface(mClient, "BufferLayer", 45, 45, PIXEL_FORMAT_RGBA_8888, 0,
1098 mFGSurfaceControl.get());
1099 ASSERT_TRUE(bufferLayer->isValid());
1100 ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(bufferLayer, Color::BLACK, 30, 30));
1101 asTransaction([&](Transaction& t) { t.show(bufferLayer); });
1102 {
1103 mCapture = screenshot();
1104 // Top left of background must now be visible
1105 mCapture->expectBGColor(0, 0);
1106 // Foreground Surface bounds must be color layer
1107 mCapture->expectColor(Rect(64, 64, 94, 94), Color::BLACK);
1108 // Buffer layer should not extend past buffer bounds
1109 mCapture->expectFGColor(95, 95);
1110 }
1111}
1112
1113// Verify a boundless color layer will fill its parent bounds. The parent has a buffer size
1114// which will crop the color layer.
1115TEST_F(BoundlessLayerTest, BoundlessColorLayerFillsParentBufferBounds) {
1116 sp<SurfaceControl> colorLayer =
1117 createSurface(mClient, "ColorLayer", 0, 0, PIXEL_FORMAT_RGBA_8888,
Vishnu Nairfa247b12020-02-11 08:58:26 -08001118 ISurfaceComposerClient::eFXSurfaceEffect, mFGSurfaceControl.get());
Valerie Hau9cfc6d82019-09-23 13:54:07 -07001119 ASSERT_TRUE(colorLayer->isValid());
1120 asTransaction([&](Transaction& t) {
1121 t.setColor(colorLayer, half3{0, 0, 0});
1122 t.show(colorLayer);
1123 });
1124 {
1125 mCapture = screenshot();
1126 // Top left of background must now be visible
1127 mCapture->expectBGColor(0, 0);
1128 // Foreground Surface bounds must be color layer
1129 mCapture->expectColor(Rect(64, 64, 128, 128), Color::BLACK);
1130 // Color layer should not extend past foreground bounds
1131 mCapture->expectBGColor(129, 129);
1132 }
1133}
1134
1135// Verify a boundless color layer will fill its parent bounds. The parent has no buffer but has
1136// a crop which will be used to crop the color layer.
1137TEST_F(BoundlessLayerTest, BoundlessColorLayerFillsParentCropBounds) {
1138 sp<SurfaceControl> cropLayer = createSurface(mClient, "CropLayer", 0, 0, PIXEL_FORMAT_RGBA_8888,
1139 0 /* flags */, mFGSurfaceControl.get());
1140 ASSERT_TRUE(cropLayer->isValid());
1141 sp<SurfaceControl> colorLayer =
1142 createSurface(mClient, "ColorLayer", 0, 0, PIXEL_FORMAT_RGBA_8888,
Vishnu Nairfa247b12020-02-11 08:58:26 -08001143 ISurfaceComposerClient::eFXSurfaceEffect, cropLayer.get());
Valerie Hau9cfc6d82019-09-23 13:54:07 -07001144 ASSERT_TRUE(colorLayer->isValid());
1145 asTransaction([&](Transaction& t) {
1146 t.setCrop_legacy(cropLayer, Rect(5, 5, 10, 10));
1147 t.setColor(colorLayer, half3{0, 0, 0});
1148 t.show(cropLayer);
1149 t.show(colorLayer);
1150 });
1151 {
1152 mCapture = screenshot();
1153 // Top left of background must now be visible
1154 mCapture->expectBGColor(0, 0);
1155 // Top left of foreground must now be visible
1156 mCapture->expectFGColor(64, 64);
1157 // 5 pixels from the foreground we should see the child surface
1158 mCapture->expectColor(Rect(69, 69, 74, 74), Color::BLACK);
1159 // 10 pixels from the foreground we should be back to the foreground surface
1160 mCapture->expectFGColor(74, 74);
1161 }
1162}
1163
1164// Verify for boundless layer with no children, their transforms have no effect.
1165TEST_F(BoundlessLayerTest, BoundlessColorLayerTransformHasNoEffect) {
1166 sp<SurfaceControl> colorLayer =
1167 createSurface(mClient, "ColorLayer", 0, 0, PIXEL_FORMAT_RGBA_8888,
Vishnu Nairfa247b12020-02-11 08:58:26 -08001168 ISurfaceComposerClient::eFXSurfaceEffect, mFGSurfaceControl.get());
Valerie Hau9cfc6d82019-09-23 13:54:07 -07001169 ASSERT_TRUE(colorLayer->isValid());
1170 asTransaction([&](Transaction& t) {
1171 t.setPosition(colorLayer, 320, 320);
1172 t.setMatrix(colorLayer, 2, 0, 0, 2);
1173 t.setColor(colorLayer, half3{0, 0, 0});
1174 t.show(colorLayer);
1175 });
1176 {
1177 mCapture = screenshot();
1178 // Top left of background must now be visible
1179 mCapture->expectBGColor(0, 0);
1180 // Foreground Surface bounds must be color layer
1181 mCapture->expectColor(Rect(64, 64, 128, 128), Color::BLACK);
1182 // Color layer should not extend past foreground bounds
1183 mCapture->expectBGColor(129, 129);
1184 }
1185}
1186
1187// Verify for boundless layer with children, their transforms have an effect.
1188TEST_F(BoundlessLayerTest, IntermediateBoundlessLayerCanSetTransform) {
1189 sp<SurfaceControl> boundlessLayerRightShift =
1190 createSurface(mClient, "BoundlessLayerRightShift", 0, 0, PIXEL_FORMAT_RGBA_8888,
1191 0 /* flags */, mFGSurfaceControl.get());
1192 ASSERT_TRUE(boundlessLayerRightShift->isValid());
1193 sp<SurfaceControl> boundlessLayerDownShift =
1194 createSurface(mClient, "BoundlessLayerLeftShift", 0, 0, PIXEL_FORMAT_RGBA_8888,
1195 0 /* flags */, boundlessLayerRightShift.get());
1196 ASSERT_TRUE(boundlessLayerDownShift->isValid());
1197 sp<SurfaceControl> colorLayer =
1198 createSurface(mClient, "ColorLayer", 0, 0, PIXEL_FORMAT_RGBA_8888,
Vishnu Nairfa247b12020-02-11 08:58:26 -08001199 ISurfaceComposerClient::eFXSurfaceEffect, boundlessLayerDownShift.get());
Valerie Hau9cfc6d82019-09-23 13:54:07 -07001200 ASSERT_TRUE(colorLayer->isValid());
1201 asTransaction([&](Transaction& t) {
1202 t.setPosition(boundlessLayerRightShift, 32, 0);
1203 t.show(boundlessLayerRightShift);
1204 t.setPosition(boundlessLayerDownShift, 0, 32);
1205 t.show(boundlessLayerDownShift);
1206 t.setCrop_legacy(colorLayer, Rect(0, 0, 64, 64));
1207 t.setColor(colorLayer, half3{0, 0, 0});
1208 t.show(colorLayer);
1209 });
1210 {
1211 mCapture = screenshot();
1212 // Top left of background must now be visible
1213 mCapture->expectBGColor(0, 0);
1214 // Top left of foreground must now be visible
1215 mCapture->expectFGColor(64, 64);
1216 // Foreground Surface bounds must be color layer
1217 mCapture->expectColor(Rect(96, 96, 128, 128), Color::BLACK);
1218 // Color layer should not extend past foreground bounds
1219 mCapture->expectBGColor(129, 129);
1220 }
1221}
1222
1223// Verify child layers do not get clipped if they temporarily move into the negative
1224// coordinate space as the result of an intermediate transformation.
1225TEST_F(BoundlessLayerTest, IntermediateBoundlessLayerDoNotCrop) {
1226 sp<SurfaceControl> boundlessLayer =
1227 mClient->createSurface(String8("BoundlessLayer"), 0, 0, PIXEL_FORMAT_RGBA_8888,
1228 0 /* flags */, mFGSurfaceControl.get());
1229 ASSERT_TRUE(boundlessLayer != nullptr);
1230 ASSERT_TRUE(boundlessLayer->isValid());
1231 sp<SurfaceControl> colorLayer =
1232 mClient->createSurface(String8("ColorLayer"), 0, 0, PIXEL_FORMAT_RGBA_8888,
Vishnu Nairfa247b12020-02-11 08:58:26 -08001233 ISurfaceComposerClient::eFXSurfaceEffect, boundlessLayer.get());
Valerie Hau9cfc6d82019-09-23 13:54:07 -07001234 ASSERT_TRUE(colorLayer != nullptr);
1235 ASSERT_TRUE(colorLayer->isValid());
1236 asTransaction([&](Transaction& t) {
1237 // shift child layer off bounds. If this layer was not boundless, we will
1238 // expect the child layer to be cropped.
1239 t.setPosition(boundlessLayer, 32, 32);
1240 t.show(boundlessLayer);
1241 t.setCrop_legacy(colorLayer, Rect(0, 0, 64, 64));
1242 // undo shift by parent
1243 t.setPosition(colorLayer, -32, -32);
1244 t.setColor(colorLayer, half3{0, 0, 0});
1245 t.show(colorLayer);
1246 });
1247 {
1248 mCapture = screenshot();
1249 // Top left of background must now be visible
1250 mCapture->expectBGColor(0, 0);
1251 // Foreground Surface bounds must be color layer
1252 mCapture->expectColor(Rect(64, 64, 128, 128), Color::BLACK);
1253 // Color layer should not extend past foreground bounds
1254 mCapture->expectBGColor(129, 129);
1255 }
1256}
1257
1258// Verify for boundless root layers with children, their transforms have an effect.
1259TEST_F(BoundlessLayerTest, RootBoundlessLayerCanSetTransform) {
1260 sp<SurfaceControl> rootBoundlessLayer = createSurface(mClient, "RootBoundlessLayer", 0, 0,
1261 PIXEL_FORMAT_RGBA_8888, 0 /* flags */);
1262 ASSERT_TRUE(rootBoundlessLayer->isValid());
1263 sp<SurfaceControl> colorLayer =
1264 createSurface(mClient, "ColorLayer", 0, 0, PIXEL_FORMAT_RGBA_8888,
Vishnu Nairfa247b12020-02-11 08:58:26 -08001265 ISurfaceComposerClient::eFXSurfaceEffect, rootBoundlessLayer.get());
Valerie Hau9cfc6d82019-09-23 13:54:07 -07001266
1267 ASSERT_TRUE(colorLayer->isValid());
1268 asTransaction([&](Transaction& t) {
1269 t.setLayer(rootBoundlessLayer, INT32_MAX - 1);
1270 t.setPosition(rootBoundlessLayer, 32, 32);
1271 t.show(rootBoundlessLayer);
1272 t.setCrop_legacy(colorLayer, Rect(0, 0, 64, 64));
1273 t.setColor(colorLayer, half3{0, 0, 0});
1274 t.show(colorLayer);
1275 t.hide(mFGSurfaceControl);
1276 });
1277 {
1278 mCapture = screenshot();
1279 // Top left of background must now be visible
1280 mCapture->expectBGColor(0, 0);
1281 // Top left of foreground must now be visible
1282 mCapture->expectBGColor(31, 31);
1283 // Foreground Surface bounds must be color layer
1284 mCapture->expectColor(Rect(32, 32, 96, 96), Color::BLACK);
1285 // Color layer should not extend past foreground bounds
1286 mCapture->expectBGColor(97, 97);
1287 }
1288}
1289
1290class ScreenCaptureTest : public LayerUpdateTest {
1291protected:
1292 std::unique_ptr<ScreenCapture> mCapture;
1293};
1294
1295TEST_F(ScreenCaptureTest, CaptureSingleLayer) {
1296 auto bgHandle = mBGSurfaceControl->getHandle();
1297 ScreenCapture::captureLayers(&mCapture, bgHandle);
1298 mCapture->expectBGColor(0, 0);
1299 // Doesn't capture FG layer which is at 64, 64
1300 mCapture->expectBGColor(64, 64);
1301}
1302
1303TEST_F(ScreenCaptureTest, CaptureLayerWithChild) {
1304 auto fgHandle = mFGSurfaceControl->getHandle();
1305
1306 sp<SurfaceControl> child = createSurface(mClient, "Child surface", 10, 10,
1307 PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
1308 TransactionUtils::fillSurfaceRGBA8(child, 200, 200, 200);
1309
1310 SurfaceComposerClient::Transaction().show(child).apply(true);
1311
1312 // Captures mFGSurfaceControl layer and its child.
1313 ScreenCapture::captureLayers(&mCapture, fgHandle);
1314 mCapture->expectFGColor(10, 10);
1315 mCapture->expectChildColor(0, 0);
1316}
1317
1318TEST_F(ScreenCaptureTest, CaptureLayerChildOnly) {
1319 auto fgHandle = mFGSurfaceControl->getHandle();
1320
1321 sp<SurfaceControl> child = createSurface(mClient, "Child surface", 10, 10,
1322 PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
1323 TransactionUtils::fillSurfaceRGBA8(child, 200, 200, 200);
1324
1325 SurfaceComposerClient::Transaction().show(child).apply(true);
1326
1327 // Captures mFGSurfaceControl's child
1328 ScreenCapture::captureChildLayers(&mCapture, fgHandle);
1329 mCapture->checkPixel(10, 10, 0, 0, 0);
1330 mCapture->expectChildColor(0, 0);
1331}
1332
1333TEST_F(ScreenCaptureTest, CaptureLayerExclude) {
1334 auto fgHandle = mFGSurfaceControl->getHandle();
1335
1336 sp<SurfaceControl> child = createSurface(mClient, "Child surface", 10, 10,
1337 PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
1338 TransactionUtils::fillSurfaceRGBA8(child, 200, 200, 200);
1339 sp<SurfaceControl> child2 = createSurface(mClient, "Child surface", 10, 10,
1340 PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
1341 TransactionUtils::fillSurfaceRGBA8(child2, 200, 0, 200);
1342
1343 SurfaceComposerClient::Transaction()
1344 .show(child)
1345 .show(child2)
1346 .setLayer(child, 1)
1347 .setLayer(child2, 2)
1348 .apply(true);
1349
1350 // Child2 would be visible but its excluded, so we should see child1 color instead.
1351 ScreenCapture::captureChildLayersExcluding(&mCapture, fgHandle, {child2->getHandle()});
1352 mCapture->checkPixel(10, 10, 0, 0, 0);
1353 mCapture->checkPixel(0, 0, 200, 200, 200);
1354}
1355
1356// Like the last test but verifies that children are also exclude.
1357TEST_F(ScreenCaptureTest, CaptureLayerExcludeTree) {
1358 auto fgHandle = mFGSurfaceControl->getHandle();
1359
1360 sp<SurfaceControl> child = createSurface(mClient, "Child surface", 10, 10,
1361 PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
1362 TransactionUtils::fillSurfaceRGBA8(child, 200, 200, 200);
1363 sp<SurfaceControl> child2 = createSurface(mClient, "Child surface", 10, 10,
1364 PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
1365 TransactionUtils::fillSurfaceRGBA8(child2, 200, 0, 200);
1366 sp<SurfaceControl> child3 = createSurface(mClient, "Child surface", 10, 10,
1367 PIXEL_FORMAT_RGBA_8888, 0, child2.get());
1368 TransactionUtils::fillSurfaceRGBA8(child2, 200, 0, 200);
1369
1370 SurfaceComposerClient::Transaction()
1371 .show(child)
1372 .show(child2)
1373 .show(child3)
1374 .setLayer(child, 1)
1375 .setLayer(child2, 2)
1376 .apply(true);
1377
1378 // Child2 would be visible but its excluded, so we should see child1 color instead.
1379 ScreenCapture::captureChildLayersExcluding(&mCapture, fgHandle, {child2->getHandle()});
1380 mCapture->checkPixel(10, 10, 0, 0, 0);
1381 mCapture->checkPixel(0, 0, 200, 200, 200);
1382}
1383
1384TEST_F(ScreenCaptureTest, CaptureTransparent) {
1385 sp<SurfaceControl> child = createSurface(mClient, "Child surface", 10, 10,
1386 PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
1387
1388 TransactionUtils::fillSurfaceRGBA8(child, 200, 200, 200);
1389
1390 SurfaceComposerClient::Transaction().show(child).apply(true);
1391
1392 auto childHandle = child->getHandle();
1393
1394 // Captures child
1395 ScreenCapture::captureLayers(&mCapture, childHandle, {0, 0, 10, 20});
1396 mCapture->expectColor(Rect(0, 0, 9, 9), {200, 200, 200, 255});
1397 // Area outside of child's bounds is transparent.
1398 mCapture->expectColor(Rect(0, 10, 9, 19), {0, 0, 0, 0});
1399}
1400
1401TEST_F(ScreenCaptureTest, DontCaptureRelativeOutsideTree) {
1402 auto fgHandle = mFGSurfaceControl->getHandle();
1403
1404 sp<SurfaceControl> child = createSurface(mClient, "Child surface", 10, 10,
1405 PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
1406 ASSERT_NE(nullptr, child.get()) << "failed to create surface";
1407 sp<SurfaceControl> relative = createLayer(String8("Relative surface"), 10, 10, 0);
1408 TransactionUtils::fillSurfaceRGBA8(child, 200, 200, 200);
1409 TransactionUtils::fillSurfaceRGBA8(relative, 100, 100, 100);
1410
1411 SurfaceComposerClient::Transaction()
1412 .show(child)
1413 // Set relative layer above fg layer so should be shown above when computing all layers.
1414 .setRelativeLayer(relative, fgHandle, 1)
1415 .show(relative)
1416 .apply(true);
1417
1418 // Captures mFGSurfaceControl layer and its child. Relative layer shouldn't be captured.
1419 ScreenCapture::captureLayers(&mCapture, fgHandle);
1420 mCapture->expectFGColor(10, 10);
1421 mCapture->expectChildColor(0, 0);
1422}
1423
1424TEST_F(ScreenCaptureTest, CaptureRelativeInTree) {
1425 auto fgHandle = mFGSurfaceControl->getHandle();
1426
1427 sp<SurfaceControl> child = createSurface(mClient, "Child surface", 10, 10,
1428 PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
1429 sp<SurfaceControl> relative = createSurface(mClient, "Relative surface", 10, 10,
1430 PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
1431 TransactionUtils::fillSurfaceRGBA8(child, 200, 200, 200);
1432 TransactionUtils::fillSurfaceRGBA8(relative, 100, 100, 100);
1433
1434 SurfaceComposerClient::Transaction()
1435 .show(child)
1436 // Set relative layer below fg layer but relative to child layer so it should be shown
1437 // above child layer.
1438 .setLayer(relative, -1)
1439 .setRelativeLayer(relative, child->getHandle(), 1)
1440 .show(relative)
1441 .apply(true);
1442
1443 // Captures mFGSurfaceControl layer and its children. Relative layer is a child of fg so its
1444 // relative value should be taken into account, placing it above child layer.
1445 ScreenCapture::captureLayers(&mCapture, fgHandle);
1446 mCapture->expectFGColor(10, 10);
1447 // Relative layer is showing on top of child layer
1448 mCapture->expectColor(Rect(0, 0, 9, 9), {100, 100, 100, 255});
1449}
1450
Vishnu Nairefc42e22019-12-03 17:36:12 -08001451TEST_F(ScreenCaptureTest, CaptureBoundlessLayerWithSourceCrop) {
1452 sp<SurfaceControl> child = createColorLayer("Child layer", Color::RED, mFGSurfaceControl.get());
1453 SurfaceComposerClient::Transaction().show(child).apply(true);
1454
1455 sp<ISurfaceComposer> sf(ComposerService::getComposerService());
1456 sp<GraphicBuffer> outBuffer;
1457 Rect sourceCrop(0, 0, 10, 10);
1458 ASSERT_EQ(NO_ERROR, sf->captureLayers(child->getHandle(), &outBuffer, sourceCrop));
1459 ScreenCapture sc(outBuffer);
1460
1461 sc.expectColor(Rect(0, 0, 9, 9), Color::RED);
1462}
1463
1464TEST_F(ScreenCaptureTest, CaptureBoundedLayerWithoutSourceCrop) {
1465 sp<SurfaceControl> child = createColorLayer("Child layer", Color::RED, mFGSurfaceControl.get());
1466 Rect layerCrop(0, 0, 10, 10);
1467 SurfaceComposerClient::Transaction().setCrop_legacy(child, layerCrop).show(child).apply(true);
1468
1469 sp<ISurfaceComposer> sf(ComposerService::getComposerService());
1470 sp<GraphicBuffer> outBuffer;
1471 Rect sourceCrop = Rect();
1472 ASSERT_EQ(NO_ERROR, sf->captureLayers(child->getHandle(), &outBuffer, sourceCrop));
1473 ScreenCapture sc(outBuffer);
1474
1475 sc.expectColor(Rect(0, 0, 9, 9), Color::RED);
1476}
1477
1478TEST_F(ScreenCaptureTest, CaptureBoundlessLayerWithoutSourceCropFails) {
1479 sp<SurfaceControl> child = createColorLayer("Child layer", Color::RED, mFGSurfaceControl.get());
1480 SurfaceComposerClient::Transaction().show(child).apply(true);
1481
1482 sp<ISurfaceComposer> sf(ComposerService::getComposerService());
1483 sp<GraphicBuffer> outBuffer;
1484 Rect sourceCrop = Rect();
1485
1486 ASSERT_EQ(BAD_VALUE, sf->captureLayers(child->getHandle(), &outBuffer, sourceCrop));
1487}
1488
1489TEST_F(ScreenCaptureTest, CaptureBufferLayerWithoutBufferFails) {
1490 sp<SurfaceControl> child = createSurface(mClient, "Child surface", 10, 10,
1491 PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
1492 SurfaceComposerClient::Transaction().show(child).apply(true);
1493
1494 sp<ISurfaceComposer> sf(ComposerService::getComposerService());
1495 sp<GraphicBuffer> outBuffer;
1496 Rect sourceCrop = Rect();
1497 ASSERT_EQ(BAD_VALUE, sf->captureLayers(child->getHandle(), &outBuffer, sourceCrop));
1498
1499 TransactionUtils::fillSurfaceRGBA8(child, Color::RED);
1500 SurfaceComposerClient::Transaction().apply(true);
1501 ASSERT_EQ(NO_ERROR, sf->captureLayers(child->getHandle(), &outBuffer, sourceCrop));
1502 ScreenCapture sc(outBuffer);
1503 sc.expectColor(Rect(0, 0, 9, 9), Color::RED);
1504}
1505
Valerie Hau9cfc6d82019-09-23 13:54:07 -07001506// In the following tests we verify successful skipping of a parent layer,
1507// so we use the same verification logic and only change how we mutate
1508// the parent layer to verify that various properties are ignored.
1509class ScreenCaptureChildOnlyTest : public LayerUpdateTest {
1510public:
1511 void SetUp() override {
1512 LayerUpdateTest::SetUp();
1513
1514 mChild = createSurface(mClient, "Child surface", 10, 10, PIXEL_FORMAT_RGBA_8888, 0,
1515 mFGSurfaceControl.get());
1516 TransactionUtils::fillSurfaceRGBA8(mChild, 200, 200, 200);
1517
1518 SurfaceComposerClient::Transaction().show(mChild).apply(true);
1519 }
1520
1521 void verify(std::function<void()> verifyStartingState) {
1522 // Verify starting state before a screenshot is taken.
1523 verifyStartingState();
1524
1525 // Verify child layer does not inherit any of the properties of its
1526 // parent when its screenshot is captured.
1527 auto fgHandle = mFGSurfaceControl->getHandle();
1528 ScreenCapture::captureChildLayers(&mCapture, fgHandle);
1529 mCapture->checkPixel(10, 10, 0, 0, 0);
1530 mCapture->expectChildColor(0, 0);
1531
1532 // Verify all assumptions are still true after the screenshot is taken.
1533 verifyStartingState();
1534 }
1535
1536 std::unique_ptr<ScreenCapture> mCapture;
1537 sp<SurfaceControl> mChild;
1538};
1539
1540// Regression test b/76099859
1541TEST_F(ScreenCaptureChildOnlyTest, CaptureLayerIgnoresParentVisibility) {
1542 SurfaceComposerClient::Transaction().hide(mFGSurfaceControl).apply(true);
1543
1544 // Even though the parent is hidden we should still capture the child.
1545
1546 // Before and after reparenting, verify child is properly hidden
1547 // when rendering full-screen.
1548 verify([&] { screenshot()->expectBGColor(64, 64); });
1549}
1550
1551TEST_F(ScreenCaptureChildOnlyTest, CaptureLayerIgnoresParentCrop) {
1552 SurfaceComposerClient::Transaction()
1553 .setCrop_legacy(mFGSurfaceControl, Rect(0, 0, 1, 1))
1554 .apply(true);
1555
1556 // Even though the parent is cropped out we should still capture the child.
1557
1558 // Before and after reparenting, verify child is cropped by parent.
1559 verify([&] { screenshot()->expectBGColor(65, 65); });
1560}
1561
1562// Regression test b/124372894
1563TEST_F(ScreenCaptureChildOnlyTest, CaptureLayerIgnoresTransform) {
1564 SurfaceComposerClient::Transaction().setMatrix(mFGSurfaceControl, 2, 0, 0, 2).apply(true);
1565
1566 // We should not inherit the parent scaling.
1567
1568 // Before and after reparenting, verify child is properly scaled.
1569 verify([&] { screenshot()->expectChildColor(80, 80); });
1570}
1571
1572TEST_F(ScreenCaptureTest, CaptureLayerWithGrandchild) {
1573 auto fgHandle = mFGSurfaceControl->getHandle();
1574
1575 sp<SurfaceControl> child = createSurface(mClient, "Child surface", 10, 10,
1576 PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
1577 TransactionUtils::fillSurfaceRGBA8(child, 200, 200, 200);
1578
1579 sp<SurfaceControl> grandchild = createSurface(mClient, "Grandchild surface", 5, 5,
1580 PIXEL_FORMAT_RGBA_8888, 0, child.get());
1581
1582 TransactionUtils::fillSurfaceRGBA8(grandchild, 50, 50, 50);
1583 SurfaceComposerClient::Transaction()
1584 .show(child)
1585 .setPosition(grandchild, 5, 5)
1586 .show(grandchild)
1587 .apply(true);
1588
1589 // Captures mFGSurfaceControl, its child, and the grandchild.
1590 ScreenCapture::captureLayers(&mCapture, fgHandle);
1591 mCapture->expectFGColor(10, 10);
1592 mCapture->expectChildColor(0, 0);
1593 mCapture->checkPixel(5, 5, 50, 50, 50);
1594}
1595
1596TEST_F(ScreenCaptureTest, CaptureChildOnly) {
1597 sp<SurfaceControl> child = createSurface(mClient, "Child surface", 10, 10,
1598 PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
1599 TransactionUtils::fillSurfaceRGBA8(child, 200, 200, 200);
1600 auto childHandle = child->getHandle();
1601
1602 SurfaceComposerClient::Transaction().setPosition(child, 5, 5).show(child).apply(true);
1603
1604 // Captures only the child layer, and not the parent.
1605 ScreenCapture::captureLayers(&mCapture, childHandle);
1606 mCapture->expectChildColor(0, 0);
1607 mCapture->expectChildColor(9, 9);
1608}
1609
1610TEST_F(ScreenCaptureTest, CaptureGrandchildOnly) {
1611 sp<SurfaceControl> child = createSurface(mClient, "Child surface", 10, 10,
1612 PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
1613 TransactionUtils::fillSurfaceRGBA8(child, 200, 200, 200);
1614 auto childHandle = child->getHandle();
1615
1616 sp<SurfaceControl> grandchild = createSurface(mClient, "Grandchild surface", 5, 5,
1617 PIXEL_FORMAT_RGBA_8888, 0, child.get());
1618 TransactionUtils::fillSurfaceRGBA8(grandchild, 50, 50, 50);
1619
1620 SurfaceComposerClient::Transaction()
1621 .show(child)
1622 .setPosition(grandchild, 5, 5)
1623 .show(grandchild)
1624 .apply(true);
1625
1626 auto grandchildHandle = grandchild->getHandle();
1627
1628 // Captures only the grandchild.
1629 ScreenCapture::captureLayers(&mCapture, grandchildHandle);
1630 mCapture->checkPixel(0, 0, 50, 50, 50);
1631 mCapture->checkPixel(4, 4, 50, 50, 50);
1632}
1633
1634TEST_F(ScreenCaptureTest, CaptureCrop) {
1635 sp<SurfaceControl> redLayer = createLayer(String8("Red surface"), 60, 60, 0);
1636 sp<SurfaceControl> blueLayer = createSurface(mClient, "Blue surface", 30, 30,
1637 PIXEL_FORMAT_RGBA_8888, 0, redLayer.get());
1638
1639 ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(redLayer, Color::RED, 60, 60));
1640 ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(blueLayer, Color::BLUE, 30, 30));
1641
1642 SurfaceComposerClient::Transaction()
1643 .setLayer(redLayer, INT32_MAX - 1)
1644 .show(redLayer)
1645 .show(blueLayer)
1646 .apply(true);
1647
1648 auto redLayerHandle = redLayer->getHandle();
1649
1650 // Capturing full screen should have both red and blue are visible.
1651 ScreenCapture::captureLayers(&mCapture, redLayerHandle);
1652 mCapture->expectColor(Rect(0, 0, 29, 29), Color::BLUE);
1653 // red area below the blue area
1654 mCapture->expectColor(Rect(0, 30, 59, 59), Color::RED);
1655 // red area to the right of the blue area
1656 mCapture->expectColor(Rect(30, 0, 59, 59), Color::RED);
1657
1658 const Rect crop = Rect(0, 0, 30, 30);
1659 ScreenCapture::captureLayers(&mCapture, redLayerHandle, crop);
1660 // Capturing the cropped screen, cropping out the shown red area, should leave only the blue
1661 // area visible.
1662 mCapture->expectColor(Rect(0, 0, 29, 29), Color::BLUE);
1663 mCapture->checkPixel(30, 30, 0, 0, 0);
1664}
1665
1666TEST_F(ScreenCaptureTest, CaptureSize) {
1667 sp<SurfaceControl> redLayer = createLayer(String8("Red surface"), 60, 60, 0);
1668 sp<SurfaceControl> blueLayer = createSurface(mClient, "Blue surface", 30, 30,
1669 PIXEL_FORMAT_RGBA_8888, 0, redLayer.get());
1670
1671 ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(redLayer, Color::RED, 60, 60));
1672 ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(blueLayer, Color::BLUE, 30, 30));
1673
1674 SurfaceComposerClient::Transaction()
1675 .setLayer(redLayer, INT32_MAX - 1)
1676 .show(redLayer)
1677 .show(blueLayer)
1678 .apply(true);
1679
1680 auto redLayerHandle = redLayer->getHandle();
1681
1682 // Capturing full screen should have both red and blue are visible.
1683 ScreenCapture::captureLayers(&mCapture, redLayerHandle);
1684 mCapture->expectColor(Rect(0, 0, 29, 29), Color::BLUE);
1685 // red area below the blue area
1686 mCapture->expectColor(Rect(0, 30, 59, 59), Color::RED);
1687 // red area to the right of the blue area
1688 mCapture->expectColor(Rect(30, 0, 59, 59), Color::RED);
1689
1690 ScreenCapture::captureLayers(&mCapture, redLayerHandle, Rect::EMPTY_RECT, 0.5);
1691 // Capturing the downsized area (30x30) should leave both red and blue but in a smaller area.
1692 mCapture->expectColor(Rect(0, 0, 14, 14), Color::BLUE);
1693 // red area below the blue area
1694 mCapture->expectColor(Rect(0, 15, 29, 29), Color::RED);
1695 // red area to the right of the blue area
1696 mCapture->expectColor(Rect(15, 0, 29, 29), Color::RED);
1697 mCapture->checkPixel(30, 30, 0, 0, 0);
1698}
1699
1700TEST_F(ScreenCaptureTest, CaptureInvalidLayer) {
1701 sp<SurfaceControl> redLayer = createLayer(String8("Red surface"), 60, 60, 0);
1702
1703 ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(redLayer, Color::RED, 60, 60));
1704
1705 auto redLayerHandle = redLayer->getHandle();
Robert Carr0e328f62020-02-06 17:12:08 -08001706 Transaction().reparent(redLayer, nullptr).apply();
Valerie Hau9cfc6d82019-09-23 13:54:07 -07001707 redLayer.clear();
1708 SurfaceComposerClient::Transaction().apply(true);
1709
1710 sp<GraphicBuffer> outBuffer;
1711
1712 // Layer was deleted so captureLayers should fail with NAME_NOT_FOUND
1713 sp<ISurfaceComposer> sf(ComposerService::getComposerService());
1714 ASSERT_EQ(NAME_NOT_FOUND, sf->captureLayers(redLayerHandle, &outBuffer, Rect::EMPTY_RECT, 1.0));
1715}
1716} // namespace android
Ady Abrahamb0dbdaa2020-01-06 16:19:42 -08001717
1718// TODO(b/129481165): remove the #pragma below and fix conversion issues
1719#pragma clang diagnostic pop // ignored "-Wconversion"