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