blob: a1c412801d91e73042004ede284cd084b3d76d35 [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
545 mChild.clear();
546
547 {
548 SCOPED_TRACE("After destroying child");
549 ScreenCapture::captureScreen(&mCapture);
550 mCapture->expectFGColor(64, 64);
551 }
552
553 asTransaction([&](Transaction& t) { t.reparent(mGrandChild, mFGSurfaceControl->getHandle()); });
554
555 {
556 SCOPED_TRACE("After reparenting grandchild");
557 ScreenCapture::captureScreen(&mCapture);
558 mCapture->checkPixel(64, 64, 111, 111, 111);
559 }
560}
561
562TEST_F(ChildLayerTest, ChildrenRelativeZSurvivesParentDestruction) {
563 sp<SurfaceControl> mGrandChild =
564 createSurface(mClient, "Grand Child", 10, 10, PIXEL_FORMAT_RGBA_8888, 0, mChild.get());
565 TransactionUtils::fillSurfaceRGBA8(mGrandChild, 111, 111, 111);
566
567 // draw grand child behind the foreground surface
568 asTransaction([&](Transaction& t) {
569 t.setRelativeLayer(mGrandChild, mFGSurfaceControl->getHandle(), -1);
570 });
571
572 {
573 SCOPED_TRACE("Child visible");
574 ScreenCapture::captureScreen(&mCapture);
575 mCapture->checkPixel(64, 64, 200, 200, 200);
576 }
577
578 asTransaction([&](Transaction& t) {
579 t.reparent(mChild, nullptr);
580 t.reparentChildren(mChild, mFGSurfaceControl->getHandle());
581 });
582
583 {
584 SCOPED_TRACE("foreground visible reparenting grandchild");
585 ScreenCapture::captureScreen(&mCapture);
586 mCapture->checkPixel(64, 64, 195, 63, 63);
587 }
588}
589
590TEST_F(ChildLayerTest, DetachChildrenSameClient) {
591 asTransaction([&](Transaction& t) {
592 t.show(mChild);
593 t.setPosition(mChild, 10, 10);
594 t.setPosition(mFGSurfaceControl, 64, 64);
595 });
596
597 {
598 mCapture = screenshot();
599 // Top left of foreground must now be visible
600 mCapture->expectFGColor(64, 64);
601 // But 10 pixels in we should see the child surface
602 mCapture->expectChildColor(74, 74);
603 // And 10 more pixels we should be back to the foreground surface
604 mCapture->expectFGColor(84, 84);
605 }
606
607 asTransaction([&](Transaction& t) { t.detachChildren(mFGSurfaceControl); });
608
609 asTransaction([&](Transaction& t) { t.hide(mChild); });
610
611 // Since the child has the same client as the parent, it will not get
612 // detached and will be hidden.
613 {
614 mCapture = screenshot();
615 mCapture->expectFGColor(64, 64);
616 mCapture->expectFGColor(74, 74);
617 mCapture->expectFGColor(84, 84);
618 }
619}
620
621TEST_F(ChildLayerTest, DetachChildrenDifferentClient) {
622 sp<SurfaceComposerClient> mNewComposerClient = new SurfaceComposerClient;
623 sp<SurfaceControl> mChildNewClient =
624 createSurface(mNewComposerClient, "New Child Test Surface", 10, 10,
625 PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
626
627 ASSERT_TRUE(mChildNewClient->isValid());
628
629 TransactionUtils::fillSurfaceRGBA8(mChildNewClient, 200, 200, 200);
630
631 asTransaction([&](Transaction& t) {
632 t.hide(mChild);
633 t.show(mChildNewClient);
634 t.setPosition(mChildNewClient, 10, 10);
635 t.setPosition(mFGSurfaceControl, 64, 64);
636 });
637
638 {
639 mCapture = screenshot();
640 // Top left of foreground must now be visible
641 mCapture->expectFGColor(64, 64);
642 // But 10 pixels in we should see the child surface
643 mCapture->expectChildColor(74, 74);
644 // And 10 more pixels we should be back to the foreground surface
645 mCapture->expectFGColor(84, 84);
646 }
647
648 asTransaction([&](Transaction& t) { t.detachChildren(mFGSurfaceControl); });
649
650 asTransaction([&](Transaction& t) { t.hide(mChildNewClient); });
651
652 // Nothing should have changed.
653 {
654 mCapture = screenshot();
655 mCapture->expectFGColor(64, 64);
656 mCapture->expectChildColor(74, 74);
657 mCapture->expectFGColor(84, 84);
658 }
659}
660
661TEST_F(ChildLayerTest, DetachChildrenThenAttach) {
662 sp<SurfaceComposerClient> newComposerClient = new SurfaceComposerClient;
663 sp<SurfaceControl> childNewClient =
664 newComposerClient->createSurface(String8("New Child Test Surface"), 10, 10,
665 PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
666
667 ASSERT_TRUE(childNewClient != nullptr);
668 ASSERT_TRUE(childNewClient->isValid());
669
670 TransactionUtils::fillSurfaceRGBA8(childNewClient, 200, 200, 200);
671
672 Transaction()
673 .hide(mChild)
674 .show(childNewClient)
675 .setPosition(childNewClient, 10, 10)
676 .setPosition(mFGSurfaceControl, 64, 64)
677 .apply();
678
679 {
680 mCapture = screenshot();
681 // Top left of foreground must now be visible
682 mCapture->expectFGColor(64, 64);
683 // But 10 pixels in we should see the child surface
684 mCapture->expectChildColor(74, 74);
685 // And 10 more pixels we should be back to the foreground surface
686 mCapture->expectFGColor(84, 84);
687 }
688
689 Transaction().detachChildren(mFGSurfaceControl).apply();
690 Transaction().hide(childNewClient).apply();
691
692 // Nothing should have changed.
693 {
694 mCapture = screenshot();
695 mCapture->expectFGColor(64, 64);
696 mCapture->expectChildColor(74, 74);
697 mCapture->expectFGColor(84, 84);
698 }
699
700 sp<SurfaceControl> newParentSurface = createLayer(String8("New Parent Surface"), 32, 32, 0);
701 fillLayerColor(ISurfaceComposerClient::eFXSurfaceBufferQueue, newParentSurface, Color::RED, 32,
702 32);
703 Transaction()
704 .setLayer(newParentSurface, INT32_MAX - 1)
705 .show(newParentSurface)
706 .setPosition(newParentSurface, 20, 20)
707 .reparent(childNewClient, newParentSurface->getHandle())
708 .apply();
709 {
710 mCapture = screenshot();
711 // Child is now hidden.
712 mCapture->expectColor(Rect(20, 20, 52, 52), Color::RED);
713 }
714}
715TEST_F(ChildLayerTest, DetachChildrenWithDeferredTransaction) {
716 sp<SurfaceComposerClient> newComposerClient = new SurfaceComposerClient;
717 sp<SurfaceControl> childNewClient =
718 newComposerClient->createSurface(String8("New Child Test Surface"), 10, 10,
719 PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
720
721 ASSERT_TRUE(childNewClient != nullptr);
722 ASSERT_TRUE(childNewClient->isValid());
723
724 TransactionUtils::fillSurfaceRGBA8(childNewClient, 200, 200, 200);
725
726 Transaction()
727 .hide(mChild)
728 .show(childNewClient)
729 .setPosition(childNewClient, 10, 10)
730 .setPosition(mFGSurfaceControl, 64, 64)
731 .apply();
732
733 {
734 mCapture = screenshot();
735 Rect rect = Rect(74, 74, 84, 84);
736 mCapture->expectBorder(rect, Color{195, 63, 63, 255});
737 mCapture->expectColor(rect, Color{200, 200, 200, 255});
738 }
739
740 Transaction()
741 .deferTransactionUntil_legacy(childNewClient, mFGSurfaceControl->getHandle(),
742 mFGSurfaceControl->getSurface()->getNextFrameNumber())
743 .apply();
744 Transaction().detachChildren(mFGSurfaceControl).apply();
745 ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(mFGSurfaceControl, Color::RED, 32, 32));
746
747 // BufferLayer can still dequeue buffers even though there's a detached layer with a
748 // deferred transaction.
749 {
750 SCOPED_TRACE("new buffer");
751 mCapture = screenshot();
752 Rect rect = Rect(74, 74, 84, 84);
753 mCapture->expectBorder(rect, Color::RED);
754 mCapture->expectColor(rect, Color{200, 200, 200, 255});
755 }
756}
757
758TEST_F(ChildLayerTest, ChildrenInheritNonTransformScalingFromParent) {
759 asTransaction([&](Transaction& t) {
760 t.show(mChild);
761 t.setPosition(mChild, 0, 0);
762 t.setPosition(mFGSurfaceControl, 0, 0);
763 });
764
765 {
766 mCapture = screenshot();
767 // We've positioned the child in the top left.
768 mCapture->expectChildColor(0, 0);
769 // But it's only 10x15.
770 mCapture->expectFGColor(10, 15);
771 }
772
773 asTransaction([&](Transaction& t) {
774 t.setOverrideScalingMode(mFGSurfaceControl, NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
775 // We cause scaling by 2.
776 t.setSize(mFGSurfaceControl, 128, 128);
777 });
778
779 {
780 mCapture = screenshot();
781 // We've positioned the child in the top left.
782 mCapture->expectChildColor(0, 0);
783 mCapture->expectChildColor(10, 10);
784 mCapture->expectChildColor(19, 29);
785 // And now it should be scaled all the way to 20x30
786 mCapture->expectFGColor(20, 30);
787 }
788}
789
790// Regression test for b/37673612
791TEST_F(ChildLayerTest, ChildrenWithParentBufferTransform) {
792 asTransaction([&](Transaction& t) {
793 t.show(mChild);
794 t.setPosition(mChild, 0, 0);
795 t.setPosition(mFGSurfaceControl, 0, 0);
796 });
797
798 {
799 mCapture = screenshot();
800 // We've positioned the child in the top left.
801 mCapture->expectChildColor(0, 0);
802 mCapture->expectChildColor(9, 14);
803 // But it's only 10x15.
804 mCapture->expectFGColor(10, 15);
805 }
806 // We set things up as in b/37673612 so that there is a mismatch between the buffer size and
807 // the WM specified state size.
808 asTransaction([&](Transaction& t) { t.setSize(mFGSurfaceControl, 128, 64); });
809 sp<Surface> s = mFGSurfaceControl->getSurface();
810 auto anw = static_cast<ANativeWindow*>(s.get());
811 native_window_set_buffers_transform(anw, NATIVE_WINDOW_TRANSFORM_ROT_90);
812 native_window_set_buffers_dimensions(anw, 64, 128);
813 TransactionUtils::fillSurfaceRGBA8(mFGSurfaceControl, 195, 63, 63);
814 waitForPostedBuffers();
815
816 {
817 // The child should still be in the same place and not have any strange scaling as in
818 // b/37673612.
819 mCapture = screenshot();
820 mCapture->expectChildColor(0, 0);
821 mCapture->expectFGColor(10, 10);
822 }
823}
824
825// A child with a buffer transform from its parents should be cropped by its parent bounds.
826TEST_F(ChildLayerTest, ChildCroppedByParentWithBufferTransform) {
827 asTransaction([&](Transaction& t) {
828 t.show(mChild);
829 t.setPosition(mChild, 0, 0);
830 t.setPosition(mFGSurfaceControl, 0, 0);
831 t.setSize(mChild, 100, 100);
832 });
833 TransactionUtils::fillSurfaceRGBA8(mChild, 200, 200, 200);
834
835 {
836 mCapture = screenshot();
837
838 mCapture->expectChildColor(0, 0);
839 mCapture->expectChildColor(63, 63);
840 mCapture->expectBGColor(64, 64);
841 }
842
843 asTransaction([&](Transaction& t) { t.setSize(mFGSurfaceControl, 128, 64); });
844 sp<Surface> s = mFGSurfaceControl->getSurface();
845 auto anw = static_cast<ANativeWindow*>(s.get());
846 // Apply a 90 transform on the buffer.
847 native_window_set_buffers_transform(anw, NATIVE_WINDOW_TRANSFORM_ROT_90);
848 native_window_set_buffers_dimensions(anw, 64, 128);
849 TransactionUtils::fillSurfaceRGBA8(mFGSurfaceControl, 195, 63, 63);
850 waitForPostedBuffers();
851
852 // The child should be cropped by the new parent bounds.
853 {
854 mCapture = screenshot();
855 mCapture->expectChildColor(0, 0);
856 mCapture->expectChildColor(99, 63);
857 mCapture->expectFGColor(100, 63);
858 mCapture->expectBGColor(128, 64);
859 }
860}
861
862// A child with a scale transform from its parents should be cropped by its parent bounds.
863TEST_F(ChildLayerTest, ChildCroppedByParentWithBufferScale) {
864 asTransaction([&](Transaction& t) {
865 t.show(mChild);
866 t.setPosition(mChild, 0, 0);
867 t.setPosition(mFGSurfaceControl, 0, 0);
868 t.setSize(mChild, 200, 200);
869 });
870 TransactionUtils::fillSurfaceRGBA8(mChild, 200, 200, 200);
871
872 {
873 mCapture = screenshot();
874
875 mCapture->expectChildColor(0, 0);
876 mCapture->expectChildColor(63, 63);
877 mCapture->expectBGColor(64, 64);
878 }
879
880 asTransaction([&](Transaction& t) {
881 t.setOverrideScalingMode(mFGSurfaceControl, NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
882 // Set a scaling by 2.
883 t.setSize(mFGSurfaceControl, 128, 128);
884 });
885
886 // Child should inherit its parents scale but should be cropped by its parent bounds.
887 {
888 mCapture = screenshot();
889 mCapture->expectChildColor(0, 0);
890 mCapture->expectChildColor(127, 127);
891 mCapture->expectBGColor(128, 128);
892 }
893}
894
895// Regression test for b/127368943
896// Child should ignore the buffer transform but apply parent scale transform.
897TEST_F(ChildLayerTest, ChildrenWithParentBufferTransformAndScale) {
898 asTransaction([&](Transaction& t) {
899 t.show(mChild);
900 t.setPosition(mChild, 0, 0);
901 t.setPosition(mFGSurfaceControl, 0, 0);
902 });
903
904 {
905 mCapture = screenshot();
906 mCapture->expectChildColor(0, 0);
907 mCapture->expectChildColor(9, 14);
908 mCapture->expectFGColor(10, 15);
909 }
910
911 // Change the size of the foreground to 128 * 64 so we can test rotation as well.
912 asTransaction([&](Transaction& t) {
913 t.setOverrideScalingMode(mFGSurfaceControl, NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
914 t.setSize(mFGSurfaceControl, 128, 64);
915 });
916 sp<Surface> s = mFGSurfaceControl->getSurface();
917 auto anw = static_cast<ANativeWindow*>(s.get());
918 // Apply a 90 transform on the buffer and submit a buffer half the expected size so that we
919 // have an effective scale of 2.0 applied to the buffer along with a rotation transform.
920 native_window_set_buffers_transform(anw, NATIVE_WINDOW_TRANSFORM_ROT_90);
921 native_window_set_buffers_dimensions(anw, 32, 64);
922 TransactionUtils::fillSurfaceRGBA8(mFGSurfaceControl, 195, 63, 63);
923 waitForPostedBuffers();
924
925 // The child should ignore the buffer transform but apply the 2.0 scale from parent.
926 {
927 mCapture = screenshot();
928 mCapture->expectChildColor(0, 0);
929 mCapture->expectChildColor(19, 29);
930 mCapture->expectFGColor(20, 30);
931 }
932}
933
934TEST_F(ChildLayerTest, Bug36858924) {
935 // Destroy the child layer
936 mChild.clear();
937
938 // Now recreate it as hidden
939 mChild = createSurface(mClient, "Child surface", 10, 10, PIXEL_FORMAT_RGBA_8888,
940 ISurfaceComposerClient::eHidden, mFGSurfaceControl.get());
941
942 // Show the child layer in a deferred transaction
943 asTransaction([&](Transaction& t) {
944 t.deferTransactionUntil_legacy(mChild, mFGSurfaceControl->getHandle(),
945 mFGSurfaceControl->getSurface()->getNextFrameNumber());
946 t.show(mChild);
947 });
948
949 // Render the foreground surface a few times
950 //
951 // Prior to the bugfix for b/36858924, this would usually hang while trying to fill the third
952 // frame because SurfaceFlinger would never process the deferred transaction and would therefore
953 // never acquire/release the first buffer
954 ALOGI("Filling 1");
955 TransactionUtils::fillSurfaceRGBA8(mFGSurfaceControl, 0, 255, 0);
956 ALOGI("Filling 2");
957 TransactionUtils::fillSurfaceRGBA8(mFGSurfaceControl, 0, 0, 255);
958 ALOGI("Filling 3");
959 TransactionUtils::fillSurfaceRGBA8(mFGSurfaceControl, 255, 0, 0);
960 ALOGI("Filling 4");
961 TransactionUtils::fillSurfaceRGBA8(mFGSurfaceControl, 0, 255, 0);
962}
963
964TEST_F(ChildLayerTest, Reparent) {
965 asTransaction([&](Transaction& t) {
966 t.show(mChild);
967 t.setPosition(mChild, 10, 10);
968 t.setPosition(mFGSurfaceControl, 64, 64);
969 });
970
971 {
972 mCapture = screenshot();
973 // Top left of foreground must now be visible
974 mCapture->expectFGColor(64, 64);
975 // But 10 pixels in we should see the child surface
976 mCapture->expectChildColor(74, 74);
977 // And 10 more pixels we should be back to the foreground surface
978 mCapture->expectFGColor(84, 84);
979 }
980
981 asTransaction([&](Transaction& t) { t.reparent(mChild, mBGSurfaceControl->getHandle()); });
982
983 {
984 mCapture = screenshot();
985 mCapture->expectFGColor(64, 64);
986 // In reparenting we should have exposed the entire foreground surface.
987 mCapture->expectFGColor(74, 74);
988 // And the child layer should now begin at 10, 10 (since the BG
989 // layer is at (0, 0)).
990 mCapture->expectBGColor(9, 9);
991 mCapture->expectChildColor(10, 10);
992 }
993}
994
995TEST_F(ChildLayerTest, ReparentToNoParent) {
996 asTransaction([&](Transaction& t) {
997 t.show(mChild);
998 t.setPosition(mChild, 10, 10);
999 t.setPosition(mFGSurfaceControl, 64, 64);
1000 });
1001
1002 {
1003 mCapture = screenshot();
1004 // Top left of foreground must now be visible
1005 mCapture->expectFGColor(64, 64);
1006 // But 10 pixels in we should see the child surface
1007 mCapture->expectChildColor(74, 74);
1008 // And 10 more pixels we should be back to the foreground surface
1009 mCapture->expectFGColor(84, 84);
1010 }
1011 asTransaction([&](Transaction& t) { t.reparent(mChild, nullptr); });
1012 {
1013 mCapture = screenshot();
1014 // The surface should now be offscreen.
1015 mCapture->expectFGColor(64, 64);
1016 mCapture->expectFGColor(74, 74);
1017 mCapture->expectFGColor(84, 84);
1018 }
1019}
1020
1021TEST_F(ChildLayerTest, ReparentFromNoParent) {
1022 sp<SurfaceControl> newSurface = createLayer(String8("New Surface"), 10, 10, 0);
1023 ASSERT_TRUE(newSurface != nullptr);
1024 ASSERT_TRUE(newSurface->isValid());
1025
1026 TransactionUtils::fillSurfaceRGBA8(newSurface, 63, 195, 63);
1027 asTransaction([&](Transaction& t) {
1028 t.hide(mChild);
1029 t.show(newSurface);
1030 t.setPosition(newSurface, 10, 10);
1031 t.setLayer(newSurface, INT32_MAX - 2);
1032 t.setPosition(mFGSurfaceControl, 64, 64);
1033 });
1034
1035 {
1036 mCapture = screenshot();
1037 // Top left of foreground must now be visible
1038 mCapture->expectFGColor(64, 64);
1039 // At 10, 10 we should see the new surface
1040 mCapture->checkPixel(10, 10, 63, 195, 63);
1041 }
1042
1043 asTransaction([&](Transaction& t) { t.reparent(newSurface, mFGSurfaceControl->getHandle()); });
1044
1045 {
1046 mCapture = screenshot();
1047 // newSurface will now be a child of mFGSurface so it will be 10, 10 offset from
1048 // mFGSurface, putting it at 74, 74.
1049 mCapture->expectFGColor(64, 64);
1050 mCapture->checkPixel(74, 74, 63, 195, 63);
1051 mCapture->expectFGColor(84, 84);
1052 }
1053}
1054
1055TEST_F(ChildLayerTest, NestedChildren) {
1056 sp<SurfaceControl> grandchild = createSurface(mClient, "Grandchild surface", 10, 10,
1057 PIXEL_FORMAT_RGBA_8888, 0, mChild.get());
1058 TransactionUtils::fillSurfaceRGBA8(grandchild, 50, 50, 50);
1059
1060 {
1061 mCapture = screenshot();
1062 // Expect the grandchild to begin at 64, 64 because it's a child of mChild layer
1063 // which begins at 64, 64
1064 mCapture->checkPixel(64, 64, 50, 50, 50);
1065 }
1066}
1067
1068TEST_F(ChildLayerTest, ChildLayerRelativeLayer) {
1069 sp<SurfaceControl> relative = createLayer(String8("Relative surface"), 128, 128, 0);
1070 TransactionUtils::fillSurfaceRGBA8(relative, 255, 255, 255);
1071
1072 Transaction t;
1073 t.setLayer(relative, INT32_MAX)
1074 .setRelativeLayer(mChild, relative->getHandle(), 1)
1075 .setPosition(mFGSurfaceControl, 0, 0)
1076 .apply(true);
1077
1078 // We expect that the child should have been elevated above our
1079 // INT_MAX layer even though it's not a child of it.
1080 {
1081 mCapture = screenshot();
1082 mCapture->expectChildColor(0, 0);
1083 mCapture->expectChildColor(9, 9);
1084 mCapture->checkPixel(10, 10, 255, 255, 255);
1085 }
1086}
1087
1088class BoundlessLayerTest : public LayerUpdateTest {
1089protected:
1090 std::unique_ptr<ScreenCapture> mCapture;
1091};
1092
1093// Verify setting a size on a buffer layer has no effect.
1094TEST_F(BoundlessLayerTest, BufferLayerIgnoresSize) {
1095 sp<SurfaceControl> bufferLayer =
1096 createSurface(mClient, "BufferLayer", 45, 45, PIXEL_FORMAT_RGBA_8888, 0,
1097 mFGSurfaceControl.get());
1098 ASSERT_TRUE(bufferLayer->isValid());
1099 ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(bufferLayer, Color::BLACK, 30, 30));
1100 asTransaction([&](Transaction& t) { t.show(bufferLayer); });
1101 {
1102 mCapture = screenshot();
1103 // Top left of background must now be visible
1104 mCapture->expectBGColor(0, 0);
1105 // Foreground Surface bounds must be color layer
1106 mCapture->expectColor(Rect(64, 64, 94, 94), Color::BLACK);
1107 // Buffer layer should not extend past buffer bounds
1108 mCapture->expectFGColor(95, 95);
1109 }
1110}
1111
1112// Verify a boundless color layer will fill its parent bounds. The parent has a buffer size
1113// which will crop the color layer.
1114TEST_F(BoundlessLayerTest, BoundlessColorLayerFillsParentBufferBounds) {
1115 sp<SurfaceControl> colorLayer =
1116 createSurface(mClient, "ColorLayer", 0, 0, PIXEL_FORMAT_RGBA_8888,
1117 ISurfaceComposerClient::eFXSurfaceColor, mFGSurfaceControl.get());
1118 ASSERT_TRUE(colorLayer->isValid());
1119 asTransaction([&](Transaction& t) {
1120 t.setColor(colorLayer, half3{0, 0, 0});
1121 t.show(colorLayer);
1122 });
1123 {
1124 mCapture = screenshot();
1125 // Top left of background must now be visible
1126 mCapture->expectBGColor(0, 0);
1127 // Foreground Surface bounds must be color layer
1128 mCapture->expectColor(Rect(64, 64, 128, 128), Color::BLACK);
1129 // Color layer should not extend past foreground bounds
1130 mCapture->expectBGColor(129, 129);
1131 }
1132}
1133
1134// Verify a boundless color layer will fill its parent bounds. The parent has no buffer but has
1135// a crop which will be used to crop the color layer.
1136TEST_F(BoundlessLayerTest, BoundlessColorLayerFillsParentCropBounds) {
1137 sp<SurfaceControl> cropLayer = createSurface(mClient, "CropLayer", 0, 0, PIXEL_FORMAT_RGBA_8888,
1138 0 /* flags */, mFGSurfaceControl.get());
1139 ASSERT_TRUE(cropLayer->isValid());
1140 sp<SurfaceControl> colorLayer =
1141 createSurface(mClient, "ColorLayer", 0, 0, PIXEL_FORMAT_RGBA_8888,
1142 ISurfaceComposerClient::eFXSurfaceColor, cropLayer.get());
1143 ASSERT_TRUE(colorLayer->isValid());
1144 asTransaction([&](Transaction& t) {
1145 t.setCrop_legacy(cropLayer, Rect(5, 5, 10, 10));
1146 t.setColor(colorLayer, half3{0, 0, 0});
1147 t.show(cropLayer);
1148 t.show(colorLayer);
1149 });
1150 {
1151 mCapture = screenshot();
1152 // Top left of background must now be visible
1153 mCapture->expectBGColor(0, 0);
1154 // Top left of foreground must now be visible
1155 mCapture->expectFGColor(64, 64);
1156 // 5 pixels from the foreground we should see the child surface
1157 mCapture->expectColor(Rect(69, 69, 74, 74), Color::BLACK);
1158 // 10 pixels from the foreground we should be back to the foreground surface
1159 mCapture->expectFGColor(74, 74);
1160 }
1161}
1162
1163// Verify for boundless layer with no children, their transforms have no effect.
1164TEST_F(BoundlessLayerTest, BoundlessColorLayerTransformHasNoEffect) {
1165 sp<SurfaceControl> colorLayer =
1166 createSurface(mClient, "ColorLayer", 0, 0, PIXEL_FORMAT_RGBA_8888,
1167 ISurfaceComposerClient::eFXSurfaceColor, mFGSurfaceControl.get());
1168 ASSERT_TRUE(colorLayer->isValid());
1169 asTransaction([&](Transaction& t) {
1170 t.setPosition(colorLayer, 320, 320);
1171 t.setMatrix(colorLayer, 2, 0, 0, 2);
1172 t.setColor(colorLayer, half3{0, 0, 0});
1173 t.show(colorLayer);
1174 });
1175 {
1176 mCapture = screenshot();
1177 // Top left of background must now be visible
1178 mCapture->expectBGColor(0, 0);
1179 // Foreground Surface bounds must be color layer
1180 mCapture->expectColor(Rect(64, 64, 128, 128), Color::BLACK);
1181 // Color layer should not extend past foreground bounds
1182 mCapture->expectBGColor(129, 129);
1183 }
1184}
1185
1186// Verify for boundless layer with children, their transforms have an effect.
1187TEST_F(BoundlessLayerTest, IntermediateBoundlessLayerCanSetTransform) {
1188 sp<SurfaceControl> boundlessLayerRightShift =
1189 createSurface(mClient, "BoundlessLayerRightShift", 0, 0, PIXEL_FORMAT_RGBA_8888,
1190 0 /* flags */, mFGSurfaceControl.get());
1191 ASSERT_TRUE(boundlessLayerRightShift->isValid());
1192 sp<SurfaceControl> boundlessLayerDownShift =
1193 createSurface(mClient, "BoundlessLayerLeftShift", 0, 0, PIXEL_FORMAT_RGBA_8888,
1194 0 /* flags */, boundlessLayerRightShift.get());
1195 ASSERT_TRUE(boundlessLayerDownShift->isValid());
1196 sp<SurfaceControl> colorLayer =
1197 createSurface(mClient, "ColorLayer", 0, 0, PIXEL_FORMAT_RGBA_8888,
1198 ISurfaceComposerClient::eFXSurfaceColor, boundlessLayerDownShift.get());
1199 ASSERT_TRUE(colorLayer->isValid());
1200 asTransaction([&](Transaction& t) {
1201 t.setPosition(boundlessLayerRightShift, 32, 0);
1202 t.show(boundlessLayerRightShift);
1203 t.setPosition(boundlessLayerDownShift, 0, 32);
1204 t.show(boundlessLayerDownShift);
1205 t.setCrop_legacy(colorLayer, Rect(0, 0, 64, 64));
1206 t.setColor(colorLayer, half3{0, 0, 0});
1207 t.show(colorLayer);
1208 });
1209 {
1210 mCapture = screenshot();
1211 // Top left of background must now be visible
1212 mCapture->expectBGColor(0, 0);
1213 // Top left of foreground must now be visible
1214 mCapture->expectFGColor(64, 64);
1215 // Foreground Surface bounds must be color layer
1216 mCapture->expectColor(Rect(96, 96, 128, 128), Color::BLACK);
1217 // Color layer should not extend past foreground bounds
1218 mCapture->expectBGColor(129, 129);
1219 }
1220}
1221
1222// Verify child layers do not get clipped if they temporarily move into the negative
1223// coordinate space as the result of an intermediate transformation.
1224TEST_F(BoundlessLayerTest, IntermediateBoundlessLayerDoNotCrop) {
1225 sp<SurfaceControl> boundlessLayer =
1226 mClient->createSurface(String8("BoundlessLayer"), 0, 0, PIXEL_FORMAT_RGBA_8888,
1227 0 /* flags */, mFGSurfaceControl.get());
1228 ASSERT_TRUE(boundlessLayer != nullptr);
1229 ASSERT_TRUE(boundlessLayer->isValid());
1230 sp<SurfaceControl> colorLayer =
1231 mClient->createSurface(String8("ColorLayer"), 0, 0, PIXEL_FORMAT_RGBA_8888,
1232 ISurfaceComposerClient::eFXSurfaceColor, boundlessLayer.get());
1233 ASSERT_TRUE(colorLayer != nullptr);
1234 ASSERT_TRUE(colorLayer->isValid());
1235 asTransaction([&](Transaction& t) {
1236 // shift child layer off bounds. If this layer was not boundless, we will
1237 // expect the child layer to be cropped.
1238 t.setPosition(boundlessLayer, 32, 32);
1239 t.show(boundlessLayer);
1240 t.setCrop_legacy(colorLayer, Rect(0, 0, 64, 64));
1241 // undo shift by parent
1242 t.setPosition(colorLayer, -32, -32);
1243 t.setColor(colorLayer, half3{0, 0, 0});
1244 t.show(colorLayer);
1245 });
1246 {
1247 mCapture = screenshot();
1248 // Top left of background must now be visible
1249 mCapture->expectBGColor(0, 0);
1250 // Foreground Surface bounds must be color layer
1251 mCapture->expectColor(Rect(64, 64, 128, 128), Color::BLACK);
1252 // Color layer should not extend past foreground bounds
1253 mCapture->expectBGColor(129, 129);
1254 }
1255}
1256
1257// Verify for boundless root layers with children, their transforms have an effect.
1258TEST_F(BoundlessLayerTest, RootBoundlessLayerCanSetTransform) {
1259 sp<SurfaceControl> rootBoundlessLayer = createSurface(mClient, "RootBoundlessLayer", 0, 0,
1260 PIXEL_FORMAT_RGBA_8888, 0 /* flags */);
1261 ASSERT_TRUE(rootBoundlessLayer->isValid());
1262 sp<SurfaceControl> colorLayer =
1263 createSurface(mClient, "ColorLayer", 0, 0, PIXEL_FORMAT_RGBA_8888,
1264 ISurfaceComposerClient::eFXSurfaceColor, rootBoundlessLayer.get());
1265
1266 ASSERT_TRUE(colorLayer->isValid());
1267 asTransaction([&](Transaction& t) {
1268 t.setLayer(rootBoundlessLayer, INT32_MAX - 1);
1269 t.setPosition(rootBoundlessLayer, 32, 32);
1270 t.show(rootBoundlessLayer);
1271 t.setCrop_legacy(colorLayer, Rect(0, 0, 64, 64));
1272 t.setColor(colorLayer, half3{0, 0, 0});
1273 t.show(colorLayer);
1274 t.hide(mFGSurfaceControl);
1275 });
1276 {
1277 mCapture = screenshot();
1278 // Top left of background must now be visible
1279 mCapture->expectBGColor(0, 0);
1280 // Top left of foreground must now be visible
1281 mCapture->expectBGColor(31, 31);
1282 // Foreground Surface bounds must be color layer
1283 mCapture->expectColor(Rect(32, 32, 96, 96), Color::BLACK);
1284 // Color layer should not extend past foreground bounds
1285 mCapture->expectBGColor(97, 97);
1286 }
1287}
1288
1289class ScreenCaptureTest : public LayerUpdateTest {
1290protected:
1291 std::unique_ptr<ScreenCapture> mCapture;
1292};
1293
1294TEST_F(ScreenCaptureTest, CaptureSingleLayer) {
1295 auto bgHandle = mBGSurfaceControl->getHandle();
1296 ScreenCapture::captureLayers(&mCapture, bgHandle);
1297 mCapture->expectBGColor(0, 0);
1298 // Doesn't capture FG layer which is at 64, 64
1299 mCapture->expectBGColor(64, 64);
1300}
1301
1302TEST_F(ScreenCaptureTest, CaptureLayerWithChild) {
1303 auto fgHandle = mFGSurfaceControl->getHandle();
1304
1305 sp<SurfaceControl> child = createSurface(mClient, "Child surface", 10, 10,
1306 PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
1307 TransactionUtils::fillSurfaceRGBA8(child, 200, 200, 200);
1308
1309 SurfaceComposerClient::Transaction().show(child).apply(true);
1310
1311 // Captures mFGSurfaceControl layer and its child.
1312 ScreenCapture::captureLayers(&mCapture, fgHandle);
1313 mCapture->expectFGColor(10, 10);
1314 mCapture->expectChildColor(0, 0);
1315}
1316
1317TEST_F(ScreenCaptureTest, CaptureLayerChildOnly) {
1318 auto fgHandle = mFGSurfaceControl->getHandle();
1319
1320 sp<SurfaceControl> child = createSurface(mClient, "Child surface", 10, 10,
1321 PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
1322 TransactionUtils::fillSurfaceRGBA8(child, 200, 200, 200);
1323
1324 SurfaceComposerClient::Transaction().show(child).apply(true);
1325
1326 // Captures mFGSurfaceControl's child
1327 ScreenCapture::captureChildLayers(&mCapture, fgHandle);
1328 mCapture->checkPixel(10, 10, 0, 0, 0);
1329 mCapture->expectChildColor(0, 0);
1330}
1331
1332TEST_F(ScreenCaptureTest, CaptureLayerExclude) {
1333 auto fgHandle = mFGSurfaceControl->getHandle();
1334
1335 sp<SurfaceControl> child = createSurface(mClient, "Child surface", 10, 10,
1336 PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
1337 TransactionUtils::fillSurfaceRGBA8(child, 200, 200, 200);
1338 sp<SurfaceControl> child2 = createSurface(mClient, "Child surface", 10, 10,
1339 PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
1340 TransactionUtils::fillSurfaceRGBA8(child2, 200, 0, 200);
1341
1342 SurfaceComposerClient::Transaction()
1343 .show(child)
1344 .show(child2)
1345 .setLayer(child, 1)
1346 .setLayer(child2, 2)
1347 .apply(true);
1348
1349 // Child2 would be visible but its excluded, so we should see child1 color instead.
1350 ScreenCapture::captureChildLayersExcluding(&mCapture, fgHandle, {child2->getHandle()});
1351 mCapture->checkPixel(10, 10, 0, 0, 0);
1352 mCapture->checkPixel(0, 0, 200, 200, 200);
1353}
1354
1355// Like the last test but verifies that children are also exclude.
1356TEST_F(ScreenCaptureTest, CaptureLayerExcludeTree) {
1357 auto fgHandle = mFGSurfaceControl->getHandle();
1358
1359 sp<SurfaceControl> child = createSurface(mClient, "Child surface", 10, 10,
1360 PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
1361 TransactionUtils::fillSurfaceRGBA8(child, 200, 200, 200);
1362 sp<SurfaceControl> child2 = createSurface(mClient, "Child surface", 10, 10,
1363 PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
1364 TransactionUtils::fillSurfaceRGBA8(child2, 200, 0, 200);
1365 sp<SurfaceControl> child3 = createSurface(mClient, "Child surface", 10, 10,
1366 PIXEL_FORMAT_RGBA_8888, 0, child2.get());
1367 TransactionUtils::fillSurfaceRGBA8(child2, 200, 0, 200);
1368
1369 SurfaceComposerClient::Transaction()
1370 .show(child)
1371 .show(child2)
1372 .show(child3)
1373 .setLayer(child, 1)
1374 .setLayer(child2, 2)
1375 .apply(true);
1376
1377 // Child2 would be visible but its excluded, so we should see child1 color instead.
1378 ScreenCapture::captureChildLayersExcluding(&mCapture, fgHandle, {child2->getHandle()});
1379 mCapture->checkPixel(10, 10, 0, 0, 0);
1380 mCapture->checkPixel(0, 0, 200, 200, 200);
1381}
1382
1383TEST_F(ScreenCaptureTest, CaptureTransparent) {
1384 sp<SurfaceControl> child = createSurface(mClient, "Child surface", 10, 10,
1385 PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
1386
1387 TransactionUtils::fillSurfaceRGBA8(child, 200, 200, 200);
1388
1389 SurfaceComposerClient::Transaction().show(child).apply(true);
1390
1391 auto childHandle = child->getHandle();
1392
1393 // Captures child
1394 ScreenCapture::captureLayers(&mCapture, childHandle, {0, 0, 10, 20});
1395 mCapture->expectColor(Rect(0, 0, 9, 9), {200, 200, 200, 255});
1396 // Area outside of child's bounds is transparent.
1397 mCapture->expectColor(Rect(0, 10, 9, 19), {0, 0, 0, 0});
1398}
1399
1400TEST_F(ScreenCaptureTest, DontCaptureRelativeOutsideTree) {
1401 auto fgHandle = mFGSurfaceControl->getHandle();
1402
1403 sp<SurfaceControl> child = createSurface(mClient, "Child surface", 10, 10,
1404 PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
1405 ASSERT_NE(nullptr, child.get()) << "failed to create surface";
1406 sp<SurfaceControl> relative = createLayer(String8("Relative surface"), 10, 10, 0);
1407 TransactionUtils::fillSurfaceRGBA8(child, 200, 200, 200);
1408 TransactionUtils::fillSurfaceRGBA8(relative, 100, 100, 100);
1409
1410 SurfaceComposerClient::Transaction()
1411 .show(child)
1412 // Set relative layer above fg layer so should be shown above when computing all layers.
1413 .setRelativeLayer(relative, fgHandle, 1)
1414 .show(relative)
1415 .apply(true);
1416
1417 // Captures mFGSurfaceControl layer and its child. Relative layer shouldn't be captured.
1418 ScreenCapture::captureLayers(&mCapture, fgHandle);
1419 mCapture->expectFGColor(10, 10);
1420 mCapture->expectChildColor(0, 0);
1421}
1422
1423TEST_F(ScreenCaptureTest, CaptureRelativeInTree) {
1424 auto fgHandle = mFGSurfaceControl->getHandle();
1425
1426 sp<SurfaceControl> child = createSurface(mClient, "Child surface", 10, 10,
1427 PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
1428 sp<SurfaceControl> relative = createSurface(mClient, "Relative surface", 10, 10,
1429 PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
1430 TransactionUtils::fillSurfaceRGBA8(child, 200, 200, 200);
1431 TransactionUtils::fillSurfaceRGBA8(relative, 100, 100, 100);
1432
1433 SurfaceComposerClient::Transaction()
1434 .show(child)
1435 // Set relative layer below fg layer but relative to child layer so it should be shown
1436 // above child layer.
1437 .setLayer(relative, -1)
1438 .setRelativeLayer(relative, child->getHandle(), 1)
1439 .show(relative)
1440 .apply(true);
1441
1442 // Captures mFGSurfaceControl layer and its children. Relative layer is a child of fg so its
1443 // relative value should be taken into account, placing it above child layer.
1444 ScreenCapture::captureLayers(&mCapture, fgHandle);
1445 mCapture->expectFGColor(10, 10);
1446 // Relative layer is showing on top of child layer
1447 mCapture->expectColor(Rect(0, 0, 9, 9), {100, 100, 100, 255});
1448}
1449
Vishnu Nairefc42e22019-12-03 17:36:12 -08001450TEST_F(ScreenCaptureTest, CaptureBoundlessLayerWithSourceCrop) {
1451 sp<SurfaceControl> child = createColorLayer("Child layer", Color::RED, mFGSurfaceControl.get());
1452 SurfaceComposerClient::Transaction().show(child).apply(true);
1453
1454 sp<ISurfaceComposer> sf(ComposerService::getComposerService());
1455 sp<GraphicBuffer> outBuffer;
1456 Rect sourceCrop(0, 0, 10, 10);
1457 ASSERT_EQ(NO_ERROR, sf->captureLayers(child->getHandle(), &outBuffer, sourceCrop));
1458 ScreenCapture sc(outBuffer);
1459
1460 sc.expectColor(Rect(0, 0, 9, 9), Color::RED);
1461}
1462
1463TEST_F(ScreenCaptureTest, CaptureBoundedLayerWithoutSourceCrop) {
1464 sp<SurfaceControl> child = createColorLayer("Child layer", Color::RED, mFGSurfaceControl.get());
1465 Rect layerCrop(0, 0, 10, 10);
1466 SurfaceComposerClient::Transaction().setCrop_legacy(child, layerCrop).show(child).apply(true);
1467
1468 sp<ISurfaceComposer> sf(ComposerService::getComposerService());
1469 sp<GraphicBuffer> outBuffer;
1470 Rect sourceCrop = Rect();
1471 ASSERT_EQ(NO_ERROR, sf->captureLayers(child->getHandle(), &outBuffer, sourceCrop));
1472 ScreenCapture sc(outBuffer);
1473
1474 sc.expectColor(Rect(0, 0, 9, 9), Color::RED);
1475}
1476
1477TEST_F(ScreenCaptureTest, CaptureBoundlessLayerWithoutSourceCropFails) {
1478 sp<SurfaceControl> child = createColorLayer("Child layer", Color::RED, mFGSurfaceControl.get());
1479 SurfaceComposerClient::Transaction().show(child).apply(true);
1480
1481 sp<ISurfaceComposer> sf(ComposerService::getComposerService());
1482 sp<GraphicBuffer> outBuffer;
1483 Rect sourceCrop = Rect();
1484
1485 ASSERT_EQ(BAD_VALUE, sf->captureLayers(child->getHandle(), &outBuffer, sourceCrop));
1486}
1487
1488TEST_F(ScreenCaptureTest, CaptureBufferLayerWithoutBufferFails) {
1489 sp<SurfaceControl> child = createSurface(mClient, "Child surface", 10, 10,
1490 PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
1491 SurfaceComposerClient::Transaction().show(child).apply(true);
1492
1493 sp<ISurfaceComposer> sf(ComposerService::getComposerService());
1494 sp<GraphicBuffer> outBuffer;
1495 Rect sourceCrop = Rect();
1496 ASSERT_EQ(BAD_VALUE, sf->captureLayers(child->getHandle(), &outBuffer, sourceCrop));
1497
1498 TransactionUtils::fillSurfaceRGBA8(child, Color::RED);
1499 SurfaceComposerClient::Transaction().apply(true);
1500 ASSERT_EQ(NO_ERROR, sf->captureLayers(child->getHandle(), &outBuffer, sourceCrop));
1501 ScreenCapture sc(outBuffer);
1502 sc.expectColor(Rect(0, 0, 9, 9), Color::RED);
1503}
1504
Valerie Hau9cfc6d82019-09-23 13:54:07 -07001505// In the following tests we verify successful skipping of a parent layer,
1506// so we use the same verification logic and only change how we mutate
1507// the parent layer to verify that various properties are ignored.
1508class ScreenCaptureChildOnlyTest : public LayerUpdateTest {
1509public:
1510 void SetUp() override {
1511 LayerUpdateTest::SetUp();
1512
1513 mChild = createSurface(mClient, "Child surface", 10, 10, PIXEL_FORMAT_RGBA_8888, 0,
1514 mFGSurfaceControl.get());
1515 TransactionUtils::fillSurfaceRGBA8(mChild, 200, 200, 200);
1516
1517 SurfaceComposerClient::Transaction().show(mChild).apply(true);
1518 }
1519
1520 void verify(std::function<void()> verifyStartingState) {
1521 // Verify starting state before a screenshot is taken.
1522 verifyStartingState();
1523
1524 // Verify child layer does not inherit any of the properties of its
1525 // parent when its screenshot is captured.
1526 auto fgHandle = mFGSurfaceControl->getHandle();
1527 ScreenCapture::captureChildLayers(&mCapture, fgHandle);
1528 mCapture->checkPixel(10, 10, 0, 0, 0);
1529 mCapture->expectChildColor(0, 0);
1530
1531 // Verify all assumptions are still true after the screenshot is taken.
1532 verifyStartingState();
1533 }
1534
1535 std::unique_ptr<ScreenCapture> mCapture;
1536 sp<SurfaceControl> mChild;
1537};
1538
1539// Regression test b/76099859
1540TEST_F(ScreenCaptureChildOnlyTest, CaptureLayerIgnoresParentVisibility) {
1541 SurfaceComposerClient::Transaction().hide(mFGSurfaceControl).apply(true);
1542
1543 // Even though the parent is hidden we should still capture the child.
1544
1545 // Before and after reparenting, verify child is properly hidden
1546 // when rendering full-screen.
1547 verify([&] { screenshot()->expectBGColor(64, 64); });
1548}
1549
1550TEST_F(ScreenCaptureChildOnlyTest, CaptureLayerIgnoresParentCrop) {
1551 SurfaceComposerClient::Transaction()
1552 .setCrop_legacy(mFGSurfaceControl, Rect(0, 0, 1, 1))
1553 .apply(true);
1554
1555 // Even though the parent is cropped out we should still capture the child.
1556
1557 // Before and after reparenting, verify child is cropped by parent.
1558 verify([&] { screenshot()->expectBGColor(65, 65); });
1559}
1560
1561// Regression test b/124372894
1562TEST_F(ScreenCaptureChildOnlyTest, CaptureLayerIgnoresTransform) {
1563 SurfaceComposerClient::Transaction().setMatrix(mFGSurfaceControl, 2, 0, 0, 2).apply(true);
1564
1565 // We should not inherit the parent scaling.
1566
1567 // Before and after reparenting, verify child is properly scaled.
1568 verify([&] { screenshot()->expectChildColor(80, 80); });
1569}
1570
1571TEST_F(ScreenCaptureTest, CaptureLayerWithGrandchild) {
1572 auto fgHandle = mFGSurfaceControl->getHandle();
1573
1574 sp<SurfaceControl> child = createSurface(mClient, "Child surface", 10, 10,
1575 PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
1576 TransactionUtils::fillSurfaceRGBA8(child, 200, 200, 200);
1577
1578 sp<SurfaceControl> grandchild = createSurface(mClient, "Grandchild surface", 5, 5,
1579 PIXEL_FORMAT_RGBA_8888, 0, child.get());
1580
1581 TransactionUtils::fillSurfaceRGBA8(grandchild, 50, 50, 50);
1582 SurfaceComposerClient::Transaction()
1583 .show(child)
1584 .setPosition(grandchild, 5, 5)
1585 .show(grandchild)
1586 .apply(true);
1587
1588 // Captures mFGSurfaceControl, its child, and the grandchild.
1589 ScreenCapture::captureLayers(&mCapture, fgHandle);
1590 mCapture->expectFGColor(10, 10);
1591 mCapture->expectChildColor(0, 0);
1592 mCapture->checkPixel(5, 5, 50, 50, 50);
1593}
1594
1595TEST_F(ScreenCaptureTest, CaptureChildOnly) {
1596 sp<SurfaceControl> child = createSurface(mClient, "Child surface", 10, 10,
1597 PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
1598 TransactionUtils::fillSurfaceRGBA8(child, 200, 200, 200);
1599 auto childHandle = child->getHandle();
1600
1601 SurfaceComposerClient::Transaction().setPosition(child, 5, 5).show(child).apply(true);
1602
1603 // Captures only the child layer, and not the parent.
1604 ScreenCapture::captureLayers(&mCapture, childHandle);
1605 mCapture->expectChildColor(0, 0);
1606 mCapture->expectChildColor(9, 9);
1607}
1608
1609TEST_F(ScreenCaptureTest, CaptureGrandchildOnly) {
1610 sp<SurfaceControl> child = createSurface(mClient, "Child surface", 10, 10,
1611 PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
1612 TransactionUtils::fillSurfaceRGBA8(child, 200, 200, 200);
1613 auto childHandle = child->getHandle();
1614
1615 sp<SurfaceControl> grandchild = createSurface(mClient, "Grandchild surface", 5, 5,
1616 PIXEL_FORMAT_RGBA_8888, 0, child.get());
1617 TransactionUtils::fillSurfaceRGBA8(grandchild, 50, 50, 50);
1618
1619 SurfaceComposerClient::Transaction()
1620 .show(child)
1621 .setPosition(grandchild, 5, 5)
1622 .show(grandchild)
1623 .apply(true);
1624
1625 auto grandchildHandle = grandchild->getHandle();
1626
1627 // Captures only the grandchild.
1628 ScreenCapture::captureLayers(&mCapture, grandchildHandle);
1629 mCapture->checkPixel(0, 0, 50, 50, 50);
1630 mCapture->checkPixel(4, 4, 50, 50, 50);
1631}
1632
1633TEST_F(ScreenCaptureTest, CaptureCrop) {
1634 sp<SurfaceControl> redLayer = createLayer(String8("Red surface"), 60, 60, 0);
1635 sp<SurfaceControl> blueLayer = createSurface(mClient, "Blue surface", 30, 30,
1636 PIXEL_FORMAT_RGBA_8888, 0, redLayer.get());
1637
1638 ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(redLayer, Color::RED, 60, 60));
1639 ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(blueLayer, Color::BLUE, 30, 30));
1640
1641 SurfaceComposerClient::Transaction()
1642 .setLayer(redLayer, INT32_MAX - 1)
1643 .show(redLayer)
1644 .show(blueLayer)
1645 .apply(true);
1646
1647 auto redLayerHandle = redLayer->getHandle();
1648
1649 // Capturing full screen should have both red and blue are visible.
1650 ScreenCapture::captureLayers(&mCapture, redLayerHandle);
1651 mCapture->expectColor(Rect(0, 0, 29, 29), Color::BLUE);
1652 // red area below the blue area
1653 mCapture->expectColor(Rect(0, 30, 59, 59), Color::RED);
1654 // red area to the right of the blue area
1655 mCapture->expectColor(Rect(30, 0, 59, 59), Color::RED);
1656
1657 const Rect crop = Rect(0, 0, 30, 30);
1658 ScreenCapture::captureLayers(&mCapture, redLayerHandle, crop);
1659 // Capturing the cropped screen, cropping out the shown red area, should leave only the blue
1660 // area visible.
1661 mCapture->expectColor(Rect(0, 0, 29, 29), Color::BLUE);
1662 mCapture->checkPixel(30, 30, 0, 0, 0);
1663}
1664
1665TEST_F(ScreenCaptureTest, CaptureSize) {
1666 sp<SurfaceControl> redLayer = createLayer(String8("Red surface"), 60, 60, 0);
1667 sp<SurfaceControl> blueLayer = createSurface(mClient, "Blue surface", 30, 30,
1668 PIXEL_FORMAT_RGBA_8888, 0, redLayer.get());
1669
1670 ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(redLayer, Color::RED, 60, 60));
1671 ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(blueLayer, Color::BLUE, 30, 30));
1672
1673 SurfaceComposerClient::Transaction()
1674 .setLayer(redLayer, INT32_MAX - 1)
1675 .show(redLayer)
1676 .show(blueLayer)
1677 .apply(true);
1678
1679 auto redLayerHandle = redLayer->getHandle();
1680
1681 // Capturing full screen should have both red and blue are visible.
1682 ScreenCapture::captureLayers(&mCapture, redLayerHandle);
1683 mCapture->expectColor(Rect(0, 0, 29, 29), Color::BLUE);
1684 // red area below the blue area
1685 mCapture->expectColor(Rect(0, 30, 59, 59), Color::RED);
1686 // red area to the right of the blue area
1687 mCapture->expectColor(Rect(30, 0, 59, 59), Color::RED);
1688
1689 ScreenCapture::captureLayers(&mCapture, redLayerHandle, Rect::EMPTY_RECT, 0.5);
1690 // Capturing the downsized area (30x30) should leave both red and blue but in a smaller area.
1691 mCapture->expectColor(Rect(0, 0, 14, 14), Color::BLUE);
1692 // red area below the blue area
1693 mCapture->expectColor(Rect(0, 15, 29, 29), Color::RED);
1694 // red area to the right of the blue area
1695 mCapture->expectColor(Rect(15, 0, 29, 29), Color::RED);
1696 mCapture->checkPixel(30, 30, 0, 0, 0);
1697}
1698
1699TEST_F(ScreenCaptureTest, CaptureInvalidLayer) {
1700 sp<SurfaceControl> redLayer = createLayer(String8("Red surface"), 60, 60, 0);
1701
1702 ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(redLayer, Color::RED, 60, 60));
1703
1704 auto redLayerHandle = redLayer->getHandle();
1705 redLayer.clear();
1706 SurfaceComposerClient::Transaction().apply(true);
1707
1708 sp<GraphicBuffer> outBuffer;
1709
1710 // Layer was deleted so captureLayers should fail with NAME_NOT_FOUND
1711 sp<ISurfaceComposer> sf(ComposerService::getComposerService());
1712 ASSERT_EQ(NAME_NOT_FOUND, sf->captureLayers(redLayerHandle, &outBuffer, Rect::EMPTY_RECT, 1.0));
1713}
1714} // namespace android
Ady Abrahamb0dbdaa2020-01-06 16:19:42 -08001715
1716// TODO(b/129481165): remove the #pragma below and fix conversion issues
1717#pragma clang diagnostic pop // ignored "-Wconversion"