blob: 976ee3519cf5c5e88e87958dbf40732b52399b7d [file] [log] [blame]
chaviw3efadb12020-07-27 10:07:15 -07001/*
2 * Copyright (C) 2020 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17// TODO(b/129481165): remove the #pragma below and fix conversion issues
18#pragma clang diagnostic push
19#pragma clang diagnostic ignored "-Wconversion"
20
chaviw70cb6a42020-07-30 13:57:36 -070021#include <private/android_filesystem_config.h>
22
chaviw3efadb12020-07-27 10:07:15 -070023#include "LayerTransactionTest.h"
24
25namespace android {
26
27class ScreenCaptureTest : public LayerTransactionTest {
28protected:
29 virtual void SetUp() {
30 LayerTransactionTest::SetUp();
31 ASSERT_EQ(NO_ERROR, mClient->initCheck());
32
Huihong Luo31b5ac22022-08-15 20:38:10 -070033 const auto ids = SurfaceComposerClient::getPhysicalDisplayIds();
34 ASSERT_FALSE(ids.empty());
35 const auto display = SurfaceComposerClient::getPhysicalDisplayToken(ids.front());
chaviw3efadb12020-07-27 10:07:15 -070036 ASSERT_FALSE(display == nullptr);
37
Marin Shalamanova7fe3042021-01-29 21:02:08 +010038 ui::DisplayMode mode;
39 ASSERT_EQ(NO_ERROR, SurfaceComposerClient::getActiveDisplayMode(display, &mode));
40 const ui::Size& resolution = mode.resolution;
chaviw3efadb12020-07-27 10:07:15 -070041
chaviw79468ab2021-10-27 11:11:24 -050042 mDisplaySize = resolution;
43
chaviw3efadb12020-07-27 10:07:15 -070044 // Background surface
45 mBGSurfaceControl = createLayer(String8("BG Test Surface"), resolution.getWidth(),
46 resolution.getHeight(), 0);
47 ASSERT_TRUE(mBGSurfaceControl != nullptr);
48 ASSERT_TRUE(mBGSurfaceControl->isValid());
49 TransactionUtils::fillSurfaceRGBA8(mBGSurfaceControl, 63, 63, 195);
50
51 // Foreground surface
52 mFGSurfaceControl = createLayer(String8("FG Test Surface"), 64, 64, 0);
53
54 ASSERT_TRUE(mFGSurfaceControl != nullptr);
55 ASSERT_TRUE(mFGSurfaceControl->isValid());
56
57 TransactionUtils::fillSurfaceRGBA8(mFGSurfaceControl, 195, 63, 63);
58
59 asTransaction([&](Transaction& t) {
Dominik Laskowski29fa1462021-04-27 15:51:50 -070060 t.setDisplayLayerStack(display, ui::DEFAULT_LAYER_STACK);
chaviw3efadb12020-07-27 10:07:15 -070061
62 t.setLayer(mBGSurfaceControl, INT32_MAX - 2).show(mBGSurfaceControl);
63
64 t.setLayer(mFGSurfaceControl, INT32_MAX - 1)
65 .setPosition(mFGSurfaceControl, 64, 64)
66 .show(mFGSurfaceControl);
67 });
68 }
69
70 virtual void TearDown() {
71 LayerTransactionTest::TearDown();
72 mBGSurfaceControl = 0;
73 mFGSurfaceControl = 0;
74 }
75
76 sp<SurfaceControl> mBGSurfaceControl;
77 sp<SurfaceControl> mFGSurfaceControl;
78 std::unique_ptr<ScreenCapture> mCapture;
chaviw79468ab2021-10-27 11:11:24 -050079 ui::Size mDisplaySize;
chaviw3efadb12020-07-27 10:07:15 -070080};
81
chaviw4b9d5e12020-08-04 18:30:35 -070082TEST_F(ScreenCaptureTest, SetFlagsSecureEUidSystem) {
83 sp<SurfaceControl> layer;
84 ASSERT_NO_FATAL_FAILURE(
85 layer = createLayer("test", 32, 32,
86 ISurfaceComposerClient::eSecure |
87 ISurfaceComposerClient::eFXSurfaceBufferQueue));
88 ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(layer, Color::RED, 32, 32));
89
90 Transaction().show(layer).setLayer(layer, INT32_MAX).apply(true);
91
chaviwf5bb97b2021-04-28 15:35:37 -050092 {
93 // Ensure the UID is not root because root has all permissions
94 UIDFaker f(AID_APP_START);
95 ASSERT_EQ(PERMISSION_DENIED, ScreenCapture::captureDisplay(mCaptureArgs, mCaptureResults));
96 }
chaviw4b9d5e12020-08-04 18:30:35 -070097
98 UIDFaker f(AID_SYSTEM);
99
100 // By default the system can capture screenshots with secure layers but they
101 // will be blacked out
chaviw8ffc7b82020-08-18 11:25:37 -0700102 ASSERT_EQ(NO_ERROR, ScreenCapture::captureDisplay(mCaptureArgs, mCaptureResults));
chaviw4b9d5e12020-08-04 18:30:35 -0700103
104 {
105 SCOPED_TRACE("as system");
106 auto shot = screenshot();
107 shot->expectColor(Rect(0, 0, 32, 32), Color::BLACK);
108 }
109
110 // Here we pass captureSecureLayers = true and since we are AID_SYSTEM we should be able
111 // to receive them...we are expected to take care with the results.
112 DisplayCaptureArgs args;
113 args.displayToken = mDisplay;
114 args.captureSecureLayers = true;
chaviw8ffc7b82020-08-18 11:25:37 -0700115 ASSERT_EQ(NO_ERROR, ScreenCapture::captureDisplay(args, mCaptureResults));
chaviw4b9d5e12020-08-04 18:30:35 -0700116 ASSERT_TRUE(mCaptureResults.capturedSecureLayers);
Alec Mouri14d5b862022-04-27 21:20:04 +0000117 ScreenCapture sc(mCaptureResults.buffer, mCaptureResults.capturedHdrLayers);
chaviw4b9d5e12020-08-04 18:30:35 -0700118 sc.expectColor(Rect(0, 0, 32, 32), Color::RED);
119}
120
Garfield Tande619fa2020-10-02 17:13:53 -0700121TEST_F(ScreenCaptureTest, CaptureChildSetParentFlagsSecureEUidSystem) {
122 sp<SurfaceControl> parentLayer;
123 ASSERT_NO_FATAL_FAILURE(
124 parentLayer = createLayer("parent-test", 32, 32,
125 ISurfaceComposerClient::eSecure |
126 ISurfaceComposerClient::eFXSurfaceBufferQueue));
127 ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(parentLayer, Color::RED, 32, 32));
128
129 sp<SurfaceControl> childLayer;
130 ASSERT_NO_FATAL_FAILURE(childLayer = createLayer("child-test", 10, 10,
131 ISurfaceComposerClient::eFXSurfaceBufferQueue,
132 parentLayer.get()));
133 ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(childLayer, Color::BLUE, 10, 10));
134
135 Transaction().show(parentLayer).setLayer(parentLayer, INT32_MAX).show(childLayer).apply(true);
136
137 UIDFaker f(AID_SYSTEM);
138
139 {
140 SCOPED_TRACE("as system");
141 auto shot = screenshot();
142 shot->expectColor(Rect(0, 0, 10, 10), Color::BLACK);
143 }
144
145 // Here we pass captureSecureLayers = true and since we are AID_SYSTEM we should be able
146 // to receive them...we are expected to take care with the results.
147 DisplayCaptureArgs args;
148 args.displayToken = mDisplay;
149 args.captureSecureLayers = true;
150 ASSERT_EQ(NO_ERROR, ScreenCapture::captureDisplay(args, mCaptureResults));
151 ASSERT_TRUE(mCaptureResults.capturedSecureLayers);
Alec Mouri14d5b862022-04-27 21:20:04 +0000152 ScreenCapture sc(mCaptureResults.buffer, mCaptureResults.capturedHdrLayers);
Garfield Tande619fa2020-10-02 17:13:53 -0700153 sc.expectColor(Rect(0, 0, 10, 10), Color::BLUE);
154}
155
chaviw3efadb12020-07-27 10:07:15 -0700156TEST_F(ScreenCaptureTest, CaptureSingleLayer) {
chaviw70cb6a42020-07-30 13:57:36 -0700157 LayerCaptureArgs captureArgs;
158 captureArgs.layerHandle = mBGSurfaceControl->getHandle();
159 ScreenCapture::captureLayers(&mCapture, captureArgs);
chaviw3efadb12020-07-27 10:07:15 -0700160 mCapture->expectBGColor(0, 0);
161 // Doesn't capture FG layer which is at 64, 64
162 mCapture->expectBGColor(64, 64);
163}
164
165TEST_F(ScreenCaptureTest, CaptureLayerWithChild) {
chaviw3efadb12020-07-27 10:07:15 -0700166 sp<SurfaceControl> child = createSurface(mClient, "Child surface", 10, 10,
167 PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
168 TransactionUtils::fillSurfaceRGBA8(child, 200, 200, 200);
169
170 SurfaceComposerClient::Transaction().show(child).apply(true);
171
172 // Captures mFGSurfaceControl layer and its child.
chaviw70cb6a42020-07-30 13:57:36 -0700173 LayerCaptureArgs captureArgs;
174 captureArgs.layerHandle = mFGSurfaceControl->getHandle();
175 ScreenCapture::captureLayers(&mCapture, captureArgs);
chaviw3efadb12020-07-27 10:07:15 -0700176 mCapture->expectFGColor(10, 10);
177 mCapture->expectChildColor(0, 0);
178}
179
180TEST_F(ScreenCaptureTest, CaptureLayerChildOnly) {
181 auto fgHandle = mFGSurfaceControl->getHandle();
182
183 sp<SurfaceControl> child = createSurface(mClient, "Child surface", 10, 10,
184 PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
185 TransactionUtils::fillSurfaceRGBA8(child, 200, 200, 200);
186
187 SurfaceComposerClient::Transaction().show(child).apply(true);
188
189 // Captures mFGSurfaceControl's child
chaviw70cb6a42020-07-30 13:57:36 -0700190 LayerCaptureArgs captureArgs;
191 captureArgs.layerHandle = fgHandle;
192 captureArgs.childrenOnly = true;
193 ScreenCapture::captureLayers(&mCapture, captureArgs);
chaviw3efadb12020-07-27 10:07:15 -0700194 mCapture->checkPixel(10, 10, 0, 0, 0);
195 mCapture->expectChildColor(0, 0);
196}
197
198TEST_F(ScreenCaptureTest, CaptureLayerExclude) {
199 auto fgHandle = mFGSurfaceControl->getHandle();
200
201 sp<SurfaceControl> child = createSurface(mClient, "Child surface", 10, 10,
202 PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
203 TransactionUtils::fillSurfaceRGBA8(child, 200, 200, 200);
204 sp<SurfaceControl> child2 = createSurface(mClient, "Child surface", 10, 10,
205 PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
206 TransactionUtils::fillSurfaceRGBA8(child2, 200, 0, 200);
207
208 SurfaceComposerClient::Transaction()
209 .show(child)
210 .show(child2)
211 .setLayer(child, 1)
212 .setLayer(child2, 2)
213 .apply(true);
214
215 // Child2 would be visible but its excluded, so we should see child1 color instead.
chaviw70cb6a42020-07-30 13:57:36 -0700216 LayerCaptureArgs captureArgs;
217 captureArgs.layerHandle = fgHandle;
218 captureArgs.childrenOnly = true;
219 captureArgs.excludeHandles = {child2->getHandle()};
220 ScreenCapture::captureLayers(&mCapture, captureArgs);
chaviw3efadb12020-07-27 10:07:15 -0700221 mCapture->checkPixel(10, 10, 0, 0, 0);
222 mCapture->checkPixel(0, 0, 200, 200, 200);
223}
224
225// Like the last test but verifies that children are also exclude.
226TEST_F(ScreenCaptureTest, CaptureLayerExcludeTree) {
227 auto fgHandle = mFGSurfaceControl->getHandle();
228
229 sp<SurfaceControl> child = createSurface(mClient, "Child surface", 10, 10,
230 PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
231 TransactionUtils::fillSurfaceRGBA8(child, 200, 200, 200);
232 sp<SurfaceControl> child2 = createSurface(mClient, "Child surface", 10, 10,
233 PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
234 TransactionUtils::fillSurfaceRGBA8(child2, 200, 0, 200);
235 sp<SurfaceControl> child3 = createSurface(mClient, "Child surface", 10, 10,
236 PIXEL_FORMAT_RGBA_8888, 0, child2.get());
237 TransactionUtils::fillSurfaceRGBA8(child2, 200, 0, 200);
238
239 SurfaceComposerClient::Transaction()
240 .show(child)
241 .show(child2)
242 .show(child3)
243 .setLayer(child, 1)
244 .setLayer(child2, 2)
245 .apply(true);
246
247 // Child2 would be visible but its excluded, so we should see child1 color instead.
chaviw70cb6a42020-07-30 13:57:36 -0700248 LayerCaptureArgs captureArgs;
249 captureArgs.layerHandle = fgHandle;
250 captureArgs.childrenOnly = true;
251 captureArgs.excludeHandles = {child2->getHandle()};
252 ScreenCapture::captureLayers(&mCapture, captureArgs);
chaviw3efadb12020-07-27 10:07:15 -0700253 mCapture->checkPixel(10, 10, 0, 0, 0);
254 mCapture->checkPixel(0, 0, 200, 200, 200);
255}
256
257TEST_F(ScreenCaptureTest, CaptureTransparent) {
258 sp<SurfaceControl> child = createSurface(mClient, "Child surface", 10, 10,
259 PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
260
261 TransactionUtils::fillSurfaceRGBA8(child, 200, 200, 200);
262
263 SurfaceComposerClient::Transaction().show(child).apply(true);
264
chaviw3efadb12020-07-27 10:07:15 -0700265 // Captures child
chaviw70cb6a42020-07-30 13:57:36 -0700266 LayerCaptureArgs captureArgs;
267 captureArgs.layerHandle = child->getHandle();
268 captureArgs.sourceCrop = {0, 0, 10, 20};
269 ScreenCapture::captureLayers(&mCapture, captureArgs);
chaviw3efadb12020-07-27 10:07:15 -0700270 mCapture->expectColor(Rect(0, 0, 9, 9), {200, 200, 200, 255});
271 // Area outside of child's bounds is transparent.
272 mCapture->expectColor(Rect(0, 10, 9, 19), {0, 0, 0, 0});
273}
274
275TEST_F(ScreenCaptureTest, DontCaptureRelativeOutsideTree) {
chaviw3efadb12020-07-27 10:07:15 -0700276 sp<SurfaceControl> child = createSurface(mClient, "Child surface", 10, 10,
277 PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
278 ASSERT_NE(nullptr, child.get()) << "failed to create surface";
279 sp<SurfaceControl> relative = createLayer(String8("Relative surface"), 10, 10, 0);
280 TransactionUtils::fillSurfaceRGBA8(child, 200, 200, 200);
281 TransactionUtils::fillSurfaceRGBA8(relative, 100, 100, 100);
282
283 SurfaceComposerClient::Transaction()
284 .show(child)
285 // Set relative layer above fg layer so should be shown above when computing all layers.
Pablo Gamito11dcc222020-09-12 15:49:39 +0000286 .setRelativeLayer(relative, mFGSurfaceControl, 1)
chaviw3efadb12020-07-27 10:07:15 -0700287 .show(relative)
288 .apply(true);
289
290 // Captures mFGSurfaceControl layer and its child. Relative layer shouldn't be captured.
chaviw70cb6a42020-07-30 13:57:36 -0700291 LayerCaptureArgs captureArgs;
292 captureArgs.layerHandle = mFGSurfaceControl->getHandle();
293 ScreenCapture::captureLayers(&mCapture, captureArgs);
chaviw3efadb12020-07-27 10:07:15 -0700294 mCapture->expectFGColor(10, 10);
295 mCapture->expectChildColor(0, 0);
296}
297
298TEST_F(ScreenCaptureTest, CaptureRelativeInTree) {
chaviw3efadb12020-07-27 10:07:15 -0700299 sp<SurfaceControl> child = createSurface(mClient, "Child surface", 10, 10,
300 PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
301 sp<SurfaceControl> relative = createSurface(mClient, "Relative surface", 10, 10,
302 PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
303 TransactionUtils::fillSurfaceRGBA8(child, 200, 200, 200);
304 TransactionUtils::fillSurfaceRGBA8(relative, 100, 100, 100);
305
306 SurfaceComposerClient::Transaction()
307 .show(child)
308 // Set relative layer below fg layer but relative to child layer so it should be shown
309 // above child layer.
310 .setLayer(relative, -1)
Pablo Gamito11dcc222020-09-12 15:49:39 +0000311 .setRelativeLayer(relative, child, 1)
chaviw3efadb12020-07-27 10:07:15 -0700312 .show(relative)
313 .apply(true);
314
315 // Captures mFGSurfaceControl layer and its children. Relative layer is a child of fg so its
316 // relative value should be taken into account, placing it above child layer.
chaviw70cb6a42020-07-30 13:57:36 -0700317 LayerCaptureArgs captureArgs;
318 captureArgs.layerHandle = mFGSurfaceControl->getHandle();
319 ScreenCapture::captureLayers(&mCapture, captureArgs);
chaviw3efadb12020-07-27 10:07:15 -0700320 mCapture->expectFGColor(10, 10);
321 // Relative layer is showing on top of child layer
322 mCapture->expectColor(Rect(0, 0, 9, 9), {100, 100, 100, 255});
323}
324
325TEST_F(ScreenCaptureTest, CaptureBoundlessLayerWithSourceCrop) {
326 sp<SurfaceControl> child = createColorLayer("Child layer", Color::RED, mFGSurfaceControl.get());
327 SurfaceComposerClient::Transaction().show(child).apply(true);
328
chaviw70cb6a42020-07-30 13:57:36 -0700329 LayerCaptureArgs captureArgs;
330 captureArgs.layerHandle = child->getHandle();
331 captureArgs.sourceCrop = {0, 0, 10, 10};
332 ScreenCapture::captureLayers(&mCapture, captureArgs);
chaviw3efadb12020-07-27 10:07:15 -0700333
334 mCapture->expectColor(Rect(0, 0, 9, 9), Color::RED);
335}
336
337TEST_F(ScreenCaptureTest, CaptureBoundedLayerWithoutSourceCrop) {
338 sp<SurfaceControl> child = createColorLayer("Child layer", Color::RED, mFGSurfaceControl.get());
339 Rect layerCrop(0, 0, 10, 10);
chaviw25714502021-02-11 10:01:08 -0800340 SurfaceComposerClient::Transaction().setCrop(child, layerCrop).show(child).apply(true);
chaviw3efadb12020-07-27 10:07:15 -0700341
chaviw70cb6a42020-07-30 13:57:36 -0700342 LayerCaptureArgs captureArgs;
343 captureArgs.layerHandle = child->getHandle();
344 ScreenCapture::captureLayers(&mCapture, captureArgs);
chaviw3efadb12020-07-27 10:07:15 -0700345
346 mCapture->expectColor(Rect(0, 0, 9, 9), Color::RED);
347}
348
349TEST_F(ScreenCaptureTest, CaptureBoundlessLayerWithoutSourceCropFails) {
350 sp<SurfaceControl> child = createColorLayer("Child layer", Color::RED, mFGSurfaceControl.get());
351 SurfaceComposerClient::Transaction().show(child).apply(true);
352
chaviw3efadb12020-07-27 10:07:15 -0700353 LayerCaptureArgs args;
354 args.layerHandle = child->getHandle();
355
356 ScreenCaptureResults captureResults;
chaviw8ffc7b82020-08-18 11:25:37 -0700357 ASSERT_EQ(BAD_VALUE, ScreenCapture::captureLayers(args, captureResults));
chaviw3efadb12020-07-27 10:07:15 -0700358}
359
360TEST_F(ScreenCaptureTest, CaptureBufferLayerWithoutBufferFails) {
361 sp<SurfaceControl> child = createSurface(mClient, "Child surface", 10, 10,
Robert Carr5b3b9142021-02-22 12:27:32 -0800362 PIXEL_FORMAT_RGBA_8888,
363 ISurfaceComposerClient::eFXSurfaceBufferState,
364 mFGSurfaceControl.get());
365
chaviw3efadb12020-07-27 10:07:15 -0700366 SurfaceComposerClient::Transaction().show(child).apply(true);
chaviw3efadb12020-07-27 10:07:15 -0700367 sp<GraphicBuffer> outBuffer;
368
369 LayerCaptureArgs args;
370 args.layerHandle = child->getHandle();
371 args.childrenOnly = false;
372
373 ScreenCaptureResults captureResults;
chaviw8ffc7b82020-08-18 11:25:37 -0700374 ASSERT_EQ(BAD_VALUE, ScreenCapture::captureLayers(args, captureResults));
chaviw3efadb12020-07-27 10:07:15 -0700375
Patrick Williams83f36b22022-09-14 17:57:35 +0000376 ASSERT_NO_FATAL_FAILURE(fillBufferLayerColor(child, Color::RED, 32, 32));
chaviw3efadb12020-07-27 10:07:15 -0700377 SurfaceComposerClient::Transaction().apply(true);
chaviw8ffc7b82020-08-18 11:25:37 -0700378 ASSERT_EQ(NO_ERROR, ScreenCapture::captureLayers(args, captureResults));
Alec Mouri14d5b862022-04-27 21:20:04 +0000379 ScreenCapture sc(captureResults.buffer, captureResults.capturedHdrLayers);
chaviw3efadb12020-07-27 10:07:15 -0700380 sc.expectColor(Rect(0, 0, 9, 9), Color::RED);
381}
382
383TEST_F(ScreenCaptureTest, CaptureLayerWithGrandchild) {
chaviw3efadb12020-07-27 10:07:15 -0700384 sp<SurfaceControl> child = createSurface(mClient, "Child surface", 10, 10,
385 PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
386 TransactionUtils::fillSurfaceRGBA8(child, 200, 200, 200);
387
388 sp<SurfaceControl> grandchild = createSurface(mClient, "Grandchild surface", 5, 5,
389 PIXEL_FORMAT_RGBA_8888, 0, child.get());
390
391 TransactionUtils::fillSurfaceRGBA8(grandchild, 50, 50, 50);
392 SurfaceComposerClient::Transaction()
393 .show(child)
394 .setPosition(grandchild, 5, 5)
395 .show(grandchild)
396 .apply(true);
397
398 // Captures mFGSurfaceControl, its child, and the grandchild.
chaviw70cb6a42020-07-30 13:57:36 -0700399 LayerCaptureArgs captureArgs;
400 captureArgs.layerHandle = mFGSurfaceControl->getHandle();
401 ScreenCapture::captureLayers(&mCapture, captureArgs);
chaviw3efadb12020-07-27 10:07:15 -0700402 mCapture->expectFGColor(10, 10);
403 mCapture->expectChildColor(0, 0);
404 mCapture->checkPixel(5, 5, 50, 50, 50);
405}
406
407TEST_F(ScreenCaptureTest, CaptureChildOnly) {
408 sp<SurfaceControl> child = createSurface(mClient, "Child surface", 10, 10,
409 PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
410 TransactionUtils::fillSurfaceRGBA8(child, 200, 200, 200);
chaviw3efadb12020-07-27 10:07:15 -0700411
412 SurfaceComposerClient::Transaction().setPosition(child, 5, 5).show(child).apply(true);
413
414 // Captures only the child layer, and not the parent.
chaviw70cb6a42020-07-30 13:57:36 -0700415 LayerCaptureArgs captureArgs;
416 captureArgs.layerHandle = child->getHandle();
417 ScreenCapture::captureLayers(&mCapture, captureArgs);
chaviw3efadb12020-07-27 10:07:15 -0700418 mCapture->expectChildColor(0, 0);
419 mCapture->expectChildColor(9, 9);
420}
421
422TEST_F(ScreenCaptureTest, CaptureGrandchildOnly) {
423 sp<SurfaceControl> child = createSurface(mClient, "Child surface", 10, 10,
424 PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
425 TransactionUtils::fillSurfaceRGBA8(child, 200, 200, 200);
426 auto childHandle = child->getHandle();
427
428 sp<SurfaceControl> grandchild = createSurface(mClient, "Grandchild surface", 5, 5,
429 PIXEL_FORMAT_RGBA_8888, 0, child.get());
430 TransactionUtils::fillSurfaceRGBA8(grandchild, 50, 50, 50);
431
432 SurfaceComposerClient::Transaction()
433 .show(child)
434 .setPosition(grandchild, 5, 5)
435 .show(grandchild)
436 .apply(true);
437
chaviw3efadb12020-07-27 10:07:15 -0700438 // Captures only the grandchild.
chaviw70cb6a42020-07-30 13:57:36 -0700439 LayerCaptureArgs captureArgs;
440 captureArgs.layerHandle = grandchild->getHandle();
441 ScreenCapture::captureLayers(&mCapture, captureArgs);
chaviw3efadb12020-07-27 10:07:15 -0700442 mCapture->checkPixel(0, 0, 50, 50, 50);
443 mCapture->checkPixel(4, 4, 50, 50, 50);
444}
445
446TEST_F(ScreenCaptureTest, CaptureCrop) {
Robert Carr5b3b9142021-02-22 12:27:32 -0800447 sp<SurfaceControl> redLayer = createLayer(String8("Red surface"), 60, 60,
448 ISurfaceComposerClient::eFXSurfaceBufferState);
chaviw3efadb12020-07-27 10:07:15 -0700449 sp<SurfaceControl> blueLayer = createSurface(mClient, "Blue surface", 30, 30,
Robert Carr5b3b9142021-02-22 12:27:32 -0800450 PIXEL_FORMAT_RGBA_8888,
451 ISurfaceComposerClient::eFXSurfaceBufferState,
452 redLayer.get());
chaviw3efadb12020-07-27 10:07:15 -0700453
Patrick Williams83f36b22022-09-14 17:57:35 +0000454 ASSERT_NO_FATAL_FAILURE(fillBufferLayerColor(redLayer, Color::RED, 60, 60));
455 ASSERT_NO_FATAL_FAILURE(fillBufferLayerColor(blueLayer, Color::BLUE, 30, 30));
chaviw3efadb12020-07-27 10:07:15 -0700456
457 SurfaceComposerClient::Transaction()
458 .setLayer(redLayer, INT32_MAX - 1)
459 .show(redLayer)
460 .show(blueLayer)
461 .apply(true);
462
chaviw3efadb12020-07-27 10:07:15 -0700463 // Capturing full screen should have both red and blue are visible.
chaviw70cb6a42020-07-30 13:57:36 -0700464 LayerCaptureArgs captureArgs;
465 captureArgs.layerHandle = redLayer->getHandle();
466 ScreenCapture::captureLayers(&mCapture, captureArgs);
chaviw3efadb12020-07-27 10:07:15 -0700467 mCapture->expectColor(Rect(0, 0, 29, 29), Color::BLUE);
468 // red area below the blue area
469 mCapture->expectColor(Rect(0, 30, 59, 59), Color::RED);
470 // red area to the right of the blue area
471 mCapture->expectColor(Rect(30, 0, 59, 59), Color::RED);
472
chaviw70cb6a42020-07-30 13:57:36 -0700473 captureArgs.sourceCrop = {0, 0, 30, 30};
474 ScreenCapture::captureLayers(&mCapture, captureArgs);
chaviw3efadb12020-07-27 10:07:15 -0700475 // Capturing the cropped screen, cropping out the shown red area, should leave only the blue
476 // area visible.
477 mCapture->expectColor(Rect(0, 0, 29, 29), Color::BLUE);
478 mCapture->checkPixel(30, 30, 0, 0, 0);
479}
480
481TEST_F(ScreenCaptureTest, CaptureSize) {
Robert Carr5b3b9142021-02-22 12:27:32 -0800482 sp<SurfaceControl> redLayer =
483 createLayer(String8("Red surface"), 60, 60, ISurfaceComposerClient::eFXSurfaceBufferState);
chaviw3efadb12020-07-27 10:07:15 -0700484 sp<SurfaceControl> blueLayer = createSurface(mClient, "Blue surface", 30, 30,
Robert Carr5b3b9142021-02-22 12:27:32 -0800485 PIXEL_FORMAT_RGBA_8888,
486 ISurfaceComposerClient::eFXSurfaceBufferState,
487 redLayer.get());
chaviw3efadb12020-07-27 10:07:15 -0700488
Patrick Williams83f36b22022-09-14 17:57:35 +0000489 ASSERT_NO_FATAL_FAILURE(fillBufferLayerColor(redLayer, Color::RED, 60, 60));
490 ASSERT_NO_FATAL_FAILURE(fillBufferLayerColor(blueLayer, Color::BLUE, 30, 30));
chaviw3efadb12020-07-27 10:07:15 -0700491
492 SurfaceComposerClient::Transaction()
493 .setLayer(redLayer, INT32_MAX - 1)
494 .show(redLayer)
495 .show(blueLayer)
496 .apply(true);
497
chaviw3efadb12020-07-27 10:07:15 -0700498 // Capturing full screen should have both red and blue are visible.
chaviw70cb6a42020-07-30 13:57:36 -0700499 LayerCaptureArgs captureArgs;
500 captureArgs.layerHandle = redLayer->getHandle();
501 ScreenCapture::captureLayers(&mCapture, captureArgs);
chaviw3efadb12020-07-27 10:07:15 -0700502 mCapture->expectColor(Rect(0, 0, 29, 29), Color::BLUE);
503 // red area below the blue area
504 mCapture->expectColor(Rect(0, 30, 59, 59), Color::RED);
505 // red area to the right of the blue area
506 mCapture->expectColor(Rect(30, 0, 59, 59), Color::RED);
507
chaviw17ac24b2021-01-28 18:50:05 -0800508 captureArgs.frameScaleX = 0.5f;
509 captureArgs.frameScaleY = 0.5f;
Robert Carr5b3b9142021-02-22 12:27:32 -0800510 sleep(1);
chaviw17ac24b2021-01-28 18:50:05 -0800511
chaviw70cb6a42020-07-30 13:57:36 -0700512 ScreenCapture::captureLayers(&mCapture, captureArgs);
chaviw3efadb12020-07-27 10:07:15 -0700513 // Capturing the downsized area (30x30) should leave both red and blue but in a smaller area.
514 mCapture->expectColor(Rect(0, 0, 14, 14), Color::BLUE);
515 // red area below the blue area
516 mCapture->expectColor(Rect(0, 15, 29, 29), Color::RED);
517 // red area to the right of the blue area
518 mCapture->expectColor(Rect(15, 0, 29, 29), Color::RED);
519 mCapture->checkPixel(30, 30, 0, 0, 0);
520}
521
522TEST_F(ScreenCaptureTest, CaptureInvalidLayer) {
chaviw3efadb12020-07-27 10:07:15 -0700523 LayerCaptureArgs args;
Ady Abrahamd11bade2022-08-01 16:18:03 -0700524 args.layerHandle = sp<BBinder>::make();
chaviw3efadb12020-07-27 10:07:15 -0700525
526 ScreenCaptureResults captureResults;
chaviw3efadb12020-07-27 10:07:15 -0700527 // Layer was deleted so captureLayers should fail with NAME_NOT_FOUND
chaviw8ffc7b82020-08-18 11:25:37 -0700528 ASSERT_EQ(NAME_NOT_FOUND, ScreenCapture::captureLayers(args, captureResults));
chaviw3efadb12020-07-27 10:07:15 -0700529}
530
Garfield Tan9c9c1912021-07-19 12:02:16 -0700531TEST_F(ScreenCaptureTest, CaptureTooLargeLayer) {
532 sp<SurfaceControl> redLayer = createLayer(String8("Red surface"), 60, 60);
533 ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(redLayer, Color::RED, 60, 60));
534
535 Transaction().show(redLayer).setLayer(redLayer, INT32_MAX).apply(true);
536
537 LayerCaptureArgs captureArgs;
538 captureArgs.layerHandle = redLayer->getHandle();
539 captureArgs.frameScaleX = INT32_MAX / 60;
540 captureArgs.frameScaleY = INT32_MAX / 60;
541
542 ScreenCaptureResults captureResults;
543 ASSERT_EQ(BAD_VALUE, ScreenCapture::captureLayers(captureArgs, captureResults));
544}
545
chaviwf5bb97b2021-04-28 15:35:37 -0500546TEST_F(ScreenCaptureTest, CaptureSecureLayer) {
Robert Carr5b3b9142021-02-22 12:27:32 -0800547 sp<SurfaceControl> redLayer = createLayer(String8("Red surface"), 60, 60,
548 ISurfaceComposerClient::eFXSurfaceBufferState);
chaviw70cb6a42020-07-30 13:57:36 -0700549 sp<SurfaceControl> secureLayer =
550 createLayer(String8("Secure surface"), 30, 30,
551 ISurfaceComposerClient::eSecure |
Robert Carr5b3b9142021-02-22 12:27:32 -0800552 ISurfaceComposerClient::eFXSurfaceBufferState,
chaviw70cb6a42020-07-30 13:57:36 -0700553 redLayer.get());
Patrick Williams83f36b22022-09-14 17:57:35 +0000554 ASSERT_NO_FATAL_FAILURE(fillBufferLayerColor(redLayer, Color::RED, 60, 60));
555 ASSERT_NO_FATAL_FAILURE(fillBufferLayerColor(secureLayer, Color::BLUE, 30, 30));
chaviw70cb6a42020-07-30 13:57:36 -0700556
557 auto redLayerHandle = redLayer->getHandle();
558 Transaction()
559 .show(redLayer)
560 .show(secureLayer)
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700561 .setLayerStack(redLayer, ui::DEFAULT_LAYER_STACK)
chaviw70cb6a42020-07-30 13:57:36 -0700562 .setLayer(redLayer, INT32_MAX)
563 .apply();
564
chaviw70cb6a42020-07-30 13:57:36 -0700565 LayerCaptureArgs args;
566 args.layerHandle = redLayerHandle;
567 args.childrenOnly = false;
568 ScreenCaptureResults captureResults;
569
chaviwf5bb97b2021-04-28 15:35:37 -0500570 {
571 // Ensure the UID is not root because root has all permissions
572 UIDFaker f(AID_APP_START);
573 // Call from outside system with secure layers will result in permission denied
574 ASSERT_EQ(PERMISSION_DENIED, ScreenCapture::captureLayers(args, captureResults));
575 }
chaviw70cb6a42020-07-30 13:57:36 -0700576
577 UIDFaker f(AID_SYSTEM);
578
579 // From system request, only red layer will be screenshot since the blue layer is secure.
580 // Black will be present where the secure layer is.
581 ScreenCapture::captureLayers(&mCapture, args);
582 mCapture->expectColor(Rect(0, 0, 30, 30), Color::BLACK);
583 mCapture->expectColor(Rect(30, 30, 60, 60), Color::RED);
584
585 // Passing flag secure so the blue layer should be screenshot too.
586 args.captureSecureLayers = true;
587 ScreenCapture::captureLayers(&mCapture, args);
588 mCapture->expectColor(Rect(0, 0, 30, 30), Color::BLUE);
589 mCapture->expectColor(Rect(30, 30, 60, 60), Color::RED);
590}
591
chaviw4b9d5e12020-08-04 18:30:35 -0700592TEST_F(ScreenCaptureTest, CaptureDisplayWithUid) {
593 uid_t fakeUid = 12345;
594
595 DisplayCaptureArgs captureArgs;
596 captureArgs.displayToken = mDisplay;
597
598 sp<SurfaceControl> layer;
599 ASSERT_NO_FATAL_FAILURE(layer = createLayer("test layer", 32, 32,
600 ISurfaceComposerClient::eFXSurfaceBufferQueue,
601 mBGSurfaceControl.get()));
602 ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(layer, Color::RED, 32, 32));
603
604 Transaction().show(layer).setLayer(layer, INT32_MAX).apply();
605
606 // Make sure red layer with the background layer is screenshot.
607 ScreenCapture::captureDisplay(&mCapture, captureArgs);
608 mCapture->expectColor(Rect(0, 0, 32, 32), Color::RED);
609 mCapture->expectBorder(Rect(0, 0, 32, 32), {63, 63, 195, 255});
610
611 // From non system uid, can't request screenshot without a specified uid.
612 UIDFaker f(fakeUid);
chaviw8ffc7b82020-08-18 11:25:37 -0700613 ASSERT_EQ(PERMISSION_DENIED, ScreenCapture::captureDisplay(captureArgs, mCaptureResults));
chaviw4b9d5e12020-08-04 18:30:35 -0700614
615 // Make screenshot request with current uid set. No layers were created with the current
616 // uid so screenshot will be black.
617 captureArgs.uid = fakeUid;
618 ScreenCapture::captureDisplay(&mCapture, captureArgs);
619 mCapture->expectColor(Rect(0, 0, 32, 32), Color::BLACK);
620 mCapture->expectBorder(Rect(0, 0, 32, 32), Color::BLACK);
621
622 sp<SurfaceControl> layerWithFakeUid;
623 // Create a new layer with the current uid
624 ASSERT_NO_FATAL_FAILURE(layerWithFakeUid =
625 createLayer("new test layer", 32, 32,
626 ISurfaceComposerClient::eFXSurfaceBufferQueue,
627 mBGSurfaceControl.get()));
628 ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(layerWithFakeUid, Color::GREEN, 32, 32));
629 Transaction()
630 .show(layerWithFakeUid)
631 .setLayer(layerWithFakeUid, INT32_MAX)
632 .setPosition(layerWithFakeUid, 128, 128)
633 .apply();
634
635 // Screenshot from the fakeUid caller with the uid requested allows the layer
636 // with that uid to be screenshotted. Everything else is black
637 ScreenCapture::captureDisplay(&mCapture, captureArgs);
638 mCapture->expectColor(Rect(128, 128, 160, 160), Color::GREEN);
639 mCapture->expectBorder(Rect(128, 128, 160, 160), Color::BLACK);
640}
641
chaviwc5676c62020-09-18 15:01:04 -0700642TEST_F(ScreenCaptureTest, CaptureDisplayPrimaryDisplayOnly) {
643 sp<SurfaceControl> layer;
644 ASSERT_NO_FATAL_FAILURE(
645 layer = createLayer("test layer", 0, 0, ISurfaceComposerClient::eFXSurfaceEffect));
646
647 const Color layerColor = Color::RED;
648 const Rect bounds = Rect(10, 10, 40, 40);
649
650 Transaction()
651 .show(layer)
652 .hide(mFGSurfaceControl)
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700653 .setLayerStack(layer, ui::DEFAULT_LAYER_STACK)
chaviwc5676c62020-09-18 15:01:04 -0700654 .setLayer(layer, INT32_MAX)
655 .setColor(layer, {layerColor.r / 255, layerColor.g / 255, layerColor.b / 255})
chaviw25714502021-02-11 10:01:08 -0800656 .setCrop(layer, bounds)
chaviwc5676c62020-09-18 15:01:04 -0700657 .apply();
658
659 DisplayCaptureArgs captureArgs;
660 captureArgs.displayToken = mDisplay;
661
662 {
663 ScreenCapture::captureDisplay(&mCapture, captureArgs);
664 mCapture->expectColor(bounds, layerColor);
665 mCapture->expectBorder(bounds, {63, 63, 195, 255});
666 }
667
668 Transaction()
669 .setFlags(layer, layer_state_t::eLayerSkipScreenshot,
670 layer_state_t::eLayerSkipScreenshot)
671 .apply();
672
673 {
674 // Can't screenshot test layer since it now has flag
675 // eLayerSkipScreenshot
676 ScreenCapture::captureDisplay(&mCapture, captureArgs);
677 mCapture->expectColor(bounds, {63, 63, 195, 255});
678 mCapture->expectBorder(bounds, {63, 63, 195, 255});
679 }
680}
681
682TEST_F(ScreenCaptureTest, CaptureDisplayChildPrimaryDisplayOnly) {
683 sp<SurfaceControl> layer;
684 sp<SurfaceControl> childLayer;
685 ASSERT_NO_FATAL_FAILURE(
686 layer = createLayer("test layer", 0, 0, ISurfaceComposerClient::eFXSurfaceEffect));
687 ASSERT_NO_FATAL_FAILURE(childLayer = createLayer("test layer", 0, 0,
688 ISurfaceComposerClient::eFXSurfaceEffect,
689 layer.get()));
690
691 const Color layerColor = Color::RED;
692 const Color childColor = Color::BLUE;
693 const Rect bounds = Rect(10, 10, 40, 40);
694 const Rect childBounds = Rect(20, 20, 30, 30);
695
696 Transaction()
697 .show(layer)
698 .show(childLayer)
699 .hide(mFGSurfaceControl)
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700700 .setLayerStack(layer, ui::DEFAULT_LAYER_STACK)
chaviwc5676c62020-09-18 15:01:04 -0700701 .setLayer(layer, INT32_MAX)
702 .setColor(layer, {layerColor.r / 255, layerColor.g / 255, layerColor.b / 255})
703 .setColor(childLayer, {childColor.r / 255, childColor.g / 255, childColor.b / 255})
chaviw25714502021-02-11 10:01:08 -0800704 .setCrop(layer, bounds)
705 .setCrop(childLayer, childBounds)
chaviwc5676c62020-09-18 15:01:04 -0700706 .apply();
707
708 DisplayCaptureArgs captureArgs;
709 captureArgs.displayToken = mDisplay;
710
711 {
712 ScreenCapture::captureDisplay(&mCapture, captureArgs);
713 mCapture->expectColor(childBounds, childColor);
714 mCapture->expectBorder(childBounds, layerColor);
715 mCapture->expectBorder(bounds, {63, 63, 195, 255});
716 }
717
718 Transaction()
719 .setFlags(layer, layer_state_t::eLayerSkipScreenshot,
720 layer_state_t::eLayerSkipScreenshot)
721 .apply();
722
723 {
724 // Can't screenshot child layer since the parent has the flag
725 // eLayerSkipScreenshot
726 ScreenCapture::captureDisplay(&mCapture, captureArgs);
727 mCapture->expectColor(childBounds, {63, 63, 195, 255});
728 mCapture->expectBorder(childBounds, {63, 63, 195, 255});
729 mCapture->expectBorder(bounds, {63, 63, 195, 255});
730 }
731}
732
chaviw4b9d5e12020-08-04 18:30:35 -0700733TEST_F(ScreenCaptureTest, CaptureLayerWithUid) {
734 uid_t fakeUid = 12345;
735
736 sp<SurfaceControl> layer;
737 ASSERT_NO_FATAL_FAILURE(layer = createLayer("test layer", 32, 32,
738 ISurfaceComposerClient::eFXSurfaceBufferQueue,
739 mBGSurfaceControl.get()));
740 ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(layer, Color::RED, 32, 32));
741
742 Transaction().show(layer).setLayer(layer, INT32_MAX).apply();
743
744 LayerCaptureArgs captureArgs;
745 captureArgs.layerHandle = mBGSurfaceControl->getHandle();
746 captureArgs.childrenOnly = false;
747
748 // Make sure red layer with the background layer is screenshot.
749 ScreenCapture::captureLayers(&mCapture, captureArgs);
750 mCapture->expectColor(Rect(0, 0, 32, 32), Color::RED);
751 mCapture->expectBorder(Rect(0, 0, 32, 32), {63, 63, 195, 255});
752
753 // From non system uid, can't request screenshot without a specified uid.
754 std::unique_ptr<UIDFaker> uidFaker = std::make_unique<UIDFaker>(fakeUid);
755
chaviw8ffc7b82020-08-18 11:25:37 -0700756 ASSERT_EQ(PERMISSION_DENIED, ScreenCapture::captureLayers(captureArgs, mCaptureResults));
chaviw4b9d5e12020-08-04 18:30:35 -0700757
758 // Make screenshot request with current uid set. No layers were created with the current
759 // uid so screenshot will be black.
760 captureArgs.uid = fakeUid;
761 ScreenCapture::captureLayers(&mCapture, captureArgs);
762 mCapture->expectColor(Rect(0, 0, 32, 32), Color::TRANSPARENT);
763 mCapture->expectBorder(Rect(0, 0, 32, 32), Color::TRANSPARENT);
764
765 sp<SurfaceControl> layerWithFakeUid;
766 // Create a new layer with the current uid
767 ASSERT_NO_FATAL_FAILURE(layerWithFakeUid =
768 createLayer("new test layer", 32, 32,
769 ISurfaceComposerClient::eFXSurfaceBufferQueue,
770 mBGSurfaceControl.get()));
771 ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(layerWithFakeUid, Color::GREEN, 32, 32));
772 Transaction()
773 .show(layerWithFakeUid)
774 .setLayer(layerWithFakeUid, INT32_MAX)
775 .setPosition(layerWithFakeUid, 128, 128)
776 // reparent a layer that was created with a different uid to the new layer.
Pablo Gamito11dcc222020-09-12 15:49:39 +0000777 .reparent(layer, layerWithFakeUid)
chaviw4b9d5e12020-08-04 18:30:35 -0700778 .apply();
779
780 // Screenshot from the fakeUid caller with the uid requested allows the layer
781 // with that uid to be screenshotted. The child layer is skipped since it was created
782 // from a different uid.
783 ScreenCapture::captureLayers(&mCapture, captureArgs);
784 mCapture->expectColor(Rect(128, 128, 160, 160), Color::GREEN);
785 mCapture->expectBorder(Rect(128, 128, 160, 160), Color::TRANSPARENT);
786
787 // Clear fake calling uid so it's back to system.
788 uidFaker = nullptr;
789 // Screenshot from the test caller with the uid requested allows the layer
790 // with that uid to be screenshotted. The child layer is skipped since it was created
791 // from a different uid.
792 ScreenCapture::captureLayers(&mCapture, captureArgs);
793 mCapture->expectColor(Rect(128, 128, 160, 160), Color::GREEN);
794 mCapture->expectBorder(Rect(128, 128, 160, 160), Color::TRANSPARENT);
795
796 // Screenshot from the fakeUid caller with no uid requested allows everything to be screenshot.
797 captureArgs.uid = -1;
798 ScreenCapture::captureLayers(&mCapture, captureArgs);
799 mCapture->expectColor(Rect(128, 128, 160, 160), Color::RED);
800 mCapture->expectBorder(Rect(128, 128, 160, 160), {63, 63, 195, 255});
801}
802
chaviw17ac24b2021-01-28 18:50:05 -0800803TEST_F(ScreenCaptureTest, CaptureWithGrayscale) {
804 sp<SurfaceControl> layer;
805 ASSERT_NO_FATAL_FAILURE(layer = createLayer("test layer", 32, 32,
806 ISurfaceComposerClient::eFXSurfaceBufferState,
807 mBGSurfaceControl.get()));
Patrick Williams83f36b22022-09-14 17:57:35 +0000808 ASSERT_NO_FATAL_FAILURE(fillBufferLayerColor(layer, Color::RED, 32, 32));
chaviw17ac24b2021-01-28 18:50:05 -0800809 Transaction().show(layer).setLayer(layer, INT32_MAX).apply();
810
811 LayerCaptureArgs captureArgs;
812 captureArgs.layerHandle = layer->getHandle();
813
814 ScreenCapture::captureLayers(&mCapture, captureArgs);
815 mCapture->expectColor(Rect(0, 0, 32, 32), Color::RED);
816
817 captureArgs.grayscale = true;
818
819 const uint8_t tolerance = 1;
820
821 // Values based on SurfaceFlinger::calculateColorMatrix
822 float3 luminance{0.213f, 0.715f, 0.072f};
823
824 ScreenCapture::captureLayers(&mCapture, captureArgs);
825
826 uint8_t expectedColor = luminance.r * 255;
827 mCapture->expectColor(Rect(0, 0, 32, 32),
828 Color{expectedColor, expectedColor, expectedColor, 255}, tolerance);
829
Patrick Williams83f36b22022-09-14 17:57:35 +0000830 ASSERT_NO_FATAL_FAILURE(fillBufferLayerColor(layer, Color::BLUE, 32, 32));
chaviw17ac24b2021-01-28 18:50:05 -0800831 ScreenCapture::captureLayers(&mCapture, captureArgs);
832
833 expectedColor = luminance.b * 255;
834 mCapture->expectColor(Rect(0, 0, 32, 32),
835 Color{expectedColor, expectedColor, expectedColor, 255}, tolerance);
836}
837
chaviw79468ab2021-10-27 11:11:24 -0500838TEST_F(ScreenCaptureTest, CaptureOffscreen) {
839 sp<SurfaceControl> layer;
840 ASSERT_NO_FATAL_FAILURE(layer = createLayer("test layer", 32, 32,
841 ISurfaceComposerClient::eFXSurfaceBufferState,
842 mBGSurfaceControl.get()));
Patrick Williams83f36b22022-09-14 17:57:35 +0000843 ASSERT_NO_FATAL_FAILURE(fillBufferLayerColor(layer, Color::RED, 32, 32));
chaviw79468ab2021-10-27 11:11:24 -0500844
845 Transaction().show(layer).hide(mFGSurfaceControl).reparent(layer, nullptr).apply();
846
847 DisplayCaptureArgs displayCaptureArgs;
848 displayCaptureArgs.displayToken = mDisplay;
849
850 {
851 // Validate that the red layer is not on screen
852 ScreenCapture::captureDisplay(&mCapture, displayCaptureArgs);
853 mCapture->expectColor(Rect(0, 0, mDisplaySize.width, mDisplaySize.height),
854 {63, 63, 195, 255});
855 }
856
857 LayerCaptureArgs captureArgs;
858 captureArgs.layerHandle = layer->getHandle();
859
860 ScreenCapture::captureLayers(&mCapture, captureArgs);
861 mCapture->expectSize(32, 32);
862 mCapture->expectColor(Rect(0, 0, 32, 32), Color::RED);
863}
864
Alec Mouri14d5b862022-04-27 21:20:04 +0000865TEST_F(ScreenCaptureTest, CaptureNonHdrLayer) {
866 sp<SurfaceControl> layer;
867 ASSERT_NO_FATAL_FAILURE(layer = createLayer("test layer", 32, 32,
868 ISurfaceComposerClient::eFXSurfaceBufferState,
869 mBGSurfaceControl.get()));
Patrick Williams83f36b22022-09-14 17:57:35 +0000870 ASSERT_NO_FATAL_FAILURE(fillBufferLayerColor(layer, Color::BLACK, 32, 32));
Alec Mouri14d5b862022-04-27 21:20:04 +0000871 Transaction()
872 .show(layer)
873 .setLayer(layer, INT32_MAX)
874 .setDataspace(layer, ui::Dataspace::V0_SRGB)
875 .apply();
876
877 LayerCaptureArgs captureArgs;
878 captureArgs.layerHandle = layer->getHandle();
879
880 ScreenCapture::captureLayers(&mCapture, captureArgs);
881 mCapture->expectColor(Rect(0, 0, 32, 32), Color::BLACK);
882 ASSERT_FALSE(mCapture->capturedHdrLayers());
883}
884
885TEST_F(ScreenCaptureTest, CaptureHdrLayer) {
886 sp<SurfaceControl> layer;
887 ASSERT_NO_FATAL_FAILURE(layer = createLayer("test layer", 32, 32,
888 ISurfaceComposerClient::eFXSurfaceBufferState,
889 mBGSurfaceControl.get()));
Patrick Williams83f36b22022-09-14 17:57:35 +0000890 ASSERT_NO_FATAL_FAILURE(fillBufferLayerColor(layer, Color::BLACK, 32, 32));
Alec Mouri14d5b862022-04-27 21:20:04 +0000891 Transaction()
892 .show(layer)
893 .setLayer(layer, INT32_MAX)
894 .setDataspace(layer, ui::Dataspace::BT2020_ITU_PQ)
895 .apply();
896
897 LayerCaptureArgs captureArgs;
898 captureArgs.layerHandle = layer->getHandle();
899
900 ScreenCapture::captureLayers(&mCapture, captureArgs);
901 mCapture->expectColor(Rect(0, 0, 32, 32), Color::BLACK);
902 ASSERT_TRUE(mCapture->capturedHdrLayers());
903}
904
chaviw3efadb12020-07-27 10:07:15 -0700905// In the following tests we verify successful skipping of a parent layer,
906// so we use the same verification logic and only change how we mutate
907// the parent layer to verify that various properties are ignored.
908class ScreenCaptureChildOnlyTest : public ScreenCaptureTest {
909public:
910 void SetUp() override {
911 ScreenCaptureTest::SetUp();
912
913 mChild = createSurface(mClient, "Child surface", 10, 10, PIXEL_FORMAT_RGBA_8888, 0,
914 mFGSurfaceControl.get());
915 TransactionUtils::fillSurfaceRGBA8(mChild, 200, 200, 200);
916
917 SurfaceComposerClient::Transaction().show(mChild).apply(true);
918 }
919
920 void verify(std::function<void()> verifyStartingState) {
921 // Verify starting state before a screenshot is taken.
922 verifyStartingState();
923
924 // Verify child layer does not inherit any of the properties of its
925 // parent when its screenshot is captured.
chaviw70cb6a42020-07-30 13:57:36 -0700926 LayerCaptureArgs captureArgs;
927 captureArgs.layerHandle = mFGSurfaceControl->getHandle();
928 captureArgs.childrenOnly = true;
929 ScreenCapture::captureLayers(&mCapture, captureArgs);
chaviw3efadb12020-07-27 10:07:15 -0700930 mCapture->checkPixel(10, 10, 0, 0, 0);
931 mCapture->expectChildColor(0, 0);
932
933 // Verify all assumptions are still true after the screenshot is taken.
934 verifyStartingState();
935 }
936
937 std::unique_ptr<ScreenCapture> mCapture;
938 sp<SurfaceControl> mChild;
939};
940
941// Regression test b/76099859
942TEST_F(ScreenCaptureChildOnlyTest, CaptureLayerIgnoresParentVisibility) {
943 SurfaceComposerClient::Transaction().hide(mFGSurfaceControl).apply(true);
944
945 // Even though the parent is hidden we should still capture the child.
946
947 // Before and after reparenting, verify child is properly hidden
948 // when rendering full-screen.
949 verify([&] { screenshot()->expectBGColor(64, 64); });
950}
951
952TEST_F(ScreenCaptureChildOnlyTest, CaptureLayerIgnoresParentCrop) {
chaviw25714502021-02-11 10:01:08 -0800953 SurfaceComposerClient::Transaction().setCrop(mFGSurfaceControl, Rect(0, 0, 1, 1)).apply(true);
chaviw3efadb12020-07-27 10:07:15 -0700954
955 // Even though the parent is cropped out we should still capture the child.
956
957 // Before and after reparenting, verify child is cropped by parent.
958 verify([&] { screenshot()->expectBGColor(65, 65); });
959}
960
961// Regression test b/124372894
962TEST_F(ScreenCaptureChildOnlyTest, CaptureLayerIgnoresTransform) {
963 SurfaceComposerClient::Transaction().setMatrix(mFGSurfaceControl, 2, 0, 0, 2).apply(true);
964
965 // We should not inherit the parent scaling.
966
967 // Before and after reparenting, verify child is properly scaled.
968 verify([&] { screenshot()->expectChildColor(80, 80); });
969}
970
Garfield Tande619fa2020-10-02 17:13:53 -0700971} // namespace android
Marin Shalamanovbed7fd32020-12-21 20:02:20 +0100972
973// TODO(b/129481165): remove the #pragma below and fix conversion issues
Robert Carr5b3b9142021-02-22 12:27:32 -0800974#pragma clang diagnostic pop // ignored "-Wconversion"