blob: 79864e05afb130e36d098b48a0bff13fd479bc23 [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
Melody Hsue69bb172023-10-27 13:51:17 +000018#include <sys/types.h>
19#include <cstdint>
chaviw3efadb12020-07-27 10:07:15 -070020#pragma clang diagnostic push
21#pragma clang diagnostic ignored "-Wconversion"
22
chaviw70cb6a42020-07-30 13:57:36 -070023#include <private/android_filesystem_config.h>
Patrick Williams1c8d8422023-07-06 11:23:17 -050024#include <ui/DisplayState.h>
chaviw70cb6a42020-07-30 13:57:36 -070025
chaviw3efadb12020-07-27 10:07:15 -070026#include "LayerTransactionTest.h"
27
28namespace android {
29
30class ScreenCaptureTest : public LayerTransactionTest {
31protected:
32 virtual void SetUp() {
33 LayerTransactionTest::SetUp();
34 ASSERT_EQ(NO_ERROR, mClient->initCheck());
35
Melody Hsue69bb172023-10-27 13:51:17 +000036 // Root surface
37 mRootSurfaceControl =
38 createLayer(String8("RootTestSurface"), mDisplayWidth, mDisplayHeight, 0);
39 ASSERT_TRUE(mRootSurfaceControl != nullptr);
40 ASSERT_TRUE(mRootSurfaceControl->isValid());
chaviw79468ab2021-10-27 11:11:24 -050041
chaviw3efadb12020-07-27 10:07:15 -070042 // Background surface
Melody Hsue69bb172023-10-27 13:51:17 +000043 mBGSurfaceControl = createLayer(String8("BG Test Surface"), mDisplayWidth, mDisplayHeight,
44 0, mRootSurfaceControl.get());
chaviw3efadb12020-07-27 10:07:15 -070045 ASSERT_TRUE(mBGSurfaceControl != nullptr);
46 ASSERT_TRUE(mBGSurfaceControl->isValid());
47 TransactionUtils::fillSurfaceRGBA8(mBGSurfaceControl, 63, 63, 195);
48
49 // Foreground surface
Melody Hsue69bb172023-10-27 13:51:17 +000050 mFGSurfaceControl =
51 createLayer(String8("FG Test Surface"), 64, 64, 0, mRootSurfaceControl.get());
chaviw3efadb12020-07-27 10:07:15 -070052
53 ASSERT_TRUE(mFGSurfaceControl != nullptr);
54 ASSERT_TRUE(mFGSurfaceControl->isValid());
55
56 TransactionUtils::fillSurfaceRGBA8(mFGSurfaceControl, 195, 63, 63);
57
58 asTransaction([&](Transaction& t) {
Melody Hsue69bb172023-10-27 13:51:17 +000059 t.setDisplayLayerStack(mDisplay, ui::DEFAULT_LAYER_STACK);
chaviw3efadb12020-07-27 10:07:15 -070060
61 t.setLayer(mBGSurfaceControl, INT32_MAX - 2).show(mBGSurfaceControl);
62
63 t.setLayer(mFGSurfaceControl, INT32_MAX - 1)
64 .setPosition(mFGSurfaceControl, 64, 64)
65 .show(mFGSurfaceControl);
66 });
Melody Hsue69bb172023-10-27 13:51:17 +000067
68 mCaptureArgs.sourceCrop = mDisplayRect;
69 mCaptureArgs.layerHandle = mRootSurfaceControl->getHandle();
chaviw3efadb12020-07-27 10:07:15 -070070 }
71
72 virtual void TearDown() {
73 LayerTransactionTest::TearDown();
74 mBGSurfaceControl = 0;
75 mFGSurfaceControl = 0;
76 }
77
Melody Hsue69bb172023-10-27 13:51:17 +000078 sp<SurfaceControl> mRootSurfaceControl;
chaviw3efadb12020-07-27 10:07:15 -070079 sp<SurfaceControl> mBGSurfaceControl;
80 sp<SurfaceControl> mFGSurfaceControl;
81 std::unique_ptr<ScreenCapture> mCapture;
Melody Hsue69bb172023-10-27 13:51:17 +000082 LayerCaptureArgs mCaptureArgs;
chaviw3efadb12020-07-27 10:07:15 -070083};
84
chaviw4b9d5e12020-08-04 18:30:35 -070085TEST_F(ScreenCaptureTest, SetFlagsSecureEUidSystem) {
86 sp<SurfaceControl> layer;
87 ASSERT_NO_FATAL_FAILURE(
88 layer = createLayer("test", 32, 32,
89 ISurfaceComposerClient::eSecure |
Melody Hsue69bb172023-10-27 13:51:17 +000090 ISurfaceComposerClient::eFXSurfaceBufferQueue,
91 mRootSurfaceControl.get()));
chaviw4b9d5e12020-08-04 18:30:35 -070092 ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(layer, Color::RED, 32, 32));
93
94 Transaction().show(layer).setLayer(layer, INT32_MAX).apply(true);
95
chaviwf5bb97b2021-04-28 15:35:37 -050096 {
97 // Ensure the UID is not root because root has all permissions
98 UIDFaker f(AID_APP_START);
Melody Hsue69bb172023-10-27 13:51:17 +000099 ASSERT_EQ(PERMISSION_DENIED, ScreenCapture::captureLayers(mCaptureArgs, mCaptureResults));
chaviwf5bb97b2021-04-28 15:35:37 -0500100 }
chaviw4b9d5e12020-08-04 18:30:35 -0700101
102 UIDFaker f(AID_SYSTEM);
103
104 // By default the system can capture screenshots with secure layers but they
105 // will be blacked out
Melody Hsue69bb172023-10-27 13:51:17 +0000106 ASSERT_EQ(NO_ERROR, ScreenCapture::captureLayers(mCaptureArgs, mCaptureResults));
chaviw4b9d5e12020-08-04 18:30:35 -0700107
108 {
109 SCOPED_TRACE("as system");
110 auto shot = screenshot();
111 shot->expectColor(Rect(0, 0, 32, 32), Color::BLACK);
112 }
113
114 // Here we pass captureSecureLayers = true and since we are AID_SYSTEM we should be able
115 // to receive them...we are expected to take care with the results.
Melody Hsue69bb172023-10-27 13:51:17 +0000116 mCaptureArgs.captureSecureLayers = true;
117 ASSERT_EQ(NO_ERROR, ScreenCapture::captureLayers(mCaptureArgs, mCaptureResults));
chaviw4b9d5e12020-08-04 18:30:35 -0700118 ASSERT_TRUE(mCaptureResults.capturedSecureLayers);
Alec Mouri14d5b862022-04-27 21:20:04 +0000119 ScreenCapture sc(mCaptureResults.buffer, mCaptureResults.capturedHdrLayers);
chaviw4b9d5e12020-08-04 18:30:35 -0700120 sc.expectColor(Rect(0, 0, 32, 32), Color::RED);
121}
122
Garfield Tande619fa2020-10-02 17:13:53 -0700123TEST_F(ScreenCaptureTest, CaptureChildSetParentFlagsSecureEUidSystem) {
124 sp<SurfaceControl> parentLayer;
125 ASSERT_NO_FATAL_FAILURE(
126 parentLayer = createLayer("parent-test", 32, 32,
127 ISurfaceComposerClient::eSecure |
Melody Hsue69bb172023-10-27 13:51:17 +0000128 ISurfaceComposerClient::eFXSurfaceBufferQueue,
129 mRootSurfaceControl.get()));
Garfield Tande619fa2020-10-02 17:13:53 -0700130 ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(parentLayer, Color::RED, 32, 32));
131
132 sp<SurfaceControl> childLayer;
133 ASSERT_NO_FATAL_FAILURE(childLayer = createLayer("child-test", 10, 10,
134 ISurfaceComposerClient::eFXSurfaceBufferQueue,
135 parentLayer.get()));
136 ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(childLayer, Color::BLUE, 10, 10));
137
138 Transaction().show(parentLayer).setLayer(parentLayer, INT32_MAX).show(childLayer).apply(true);
139
140 UIDFaker f(AID_SYSTEM);
141
142 {
143 SCOPED_TRACE("as system");
144 auto shot = screenshot();
145 shot->expectColor(Rect(0, 0, 10, 10), Color::BLACK);
146 }
147
148 // Here we pass captureSecureLayers = true and since we are AID_SYSTEM we should be able
149 // to receive them...we are expected to take care with the results.
Melody Hsue69bb172023-10-27 13:51:17 +0000150 mCaptureArgs.captureSecureLayers = true;
151 ASSERT_EQ(NO_ERROR, ScreenCapture::captureLayers(mCaptureArgs, mCaptureResults));
Garfield Tande619fa2020-10-02 17:13:53 -0700152 ASSERT_TRUE(mCaptureResults.capturedSecureLayers);
Alec Mouri14d5b862022-04-27 21:20:04 +0000153 ScreenCapture sc(mCaptureResults.buffer, mCaptureResults.capturedHdrLayers);
Garfield Tande619fa2020-10-02 17:13:53 -0700154 sc.expectColor(Rect(0, 0, 10, 10), Color::BLUE);
155}
156
chaviw3efadb12020-07-27 10:07:15 -0700157TEST_F(ScreenCaptureTest, CaptureSingleLayer) {
chaviw70cb6a42020-07-30 13:57:36 -0700158 LayerCaptureArgs captureArgs;
159 captureArgs.layerHandle = mBGSurfaceControl->getHandle();
160 ScreenCapture::captureLayers(&mCapture, captureArgs);
chaviw3efadb12020-07-27 10:07:15 -0700161 mCapture->expectBGColor(0, 0);
162 // Doesn't capture FG layer which is at 64, 64
163 mCapture->expectBGColor(64, 64);
164}
165
166TEST_F(ScreenCaptureTest, CaptureLayerWithChild) {
chaviw3efadb12020-07-27 10:07:15 -0700167 sp<SurfaceControl> child = createSurface(mClient, "Child surface", 10, 10,
168 PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
169 TransactionUtils::fillSurfaceRGBA8(child, 200, 200, 200);
170
171 SurfaceComposerClient::Transaction().show(child).apply(true);
172
173 // Captures mFGSurfaceControl layer and its child.
chaviw70cb6a42020-07-30 13:57:36 -0700174 LayerCaptureArgs captureArgs;
175 captureArgs.layerHandle = mFGSurfaceControl->getHandle();
176 ScreenCapture::captureLayers(&mCapture, captureArgs);
chaviw3efadb12020-07-27 10:07:15 -0700177 mCapture->expectFGColor(10, 10);
178 mCapture->expectChildColor(0, 0);
179}
180
181TEST_F(ScreenCaptureTest, CaptureLayerChildOnly) {
182 auto fgHandle = mFGSurfaceControl->getHandle();
183
184 sp<SurfaceControl> child = createSurface(mClient, "Child surface", 10, 10,
185 PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
186 TransactionUtils::fillSurfaceRGBA8(child, 200, 200, 200);
187
188 SurfaceComposerClient::Transaction().show(child).apply(true);
189
190 // Captures mFGSurfaceControl's child
chaviw70cb6a42020-07-30 13:57:36 -0700191 LayerCaptureArgs captureArgs;
192 captureArgs.layerHandle = fgHandle;
193 captureArgs.childrenOnly = true;
194 ScreenCapture::captureLayers(&mCapture, captureArgs);
chaviw3efadb12020-07-27 10:07:15 -0700195 mCapture->checkPixel(10, 10, 0, 0, 0);
196 mCapture->expectChildColor(0, 0);
197}
198
199TEST_F(ScreenCaptureTest, CaptureLayerExclude) {
200 auto fgHandle = mFGSurfaceControl->getHandle();
201
202 sp<SurfaceControl> child = createSurface(mClient, "Child surface", 10, 10,
203 PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
204 TransactionUtils::fillSurfaceRGBA8(child, 200, 200, 200);
205 sp<SurfaceControl> child2 = createSurface(mClient, "Child surface", 10, 10,
206 PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
207 TransactionUtils::fillSurfaceRGBA8(child2, 200, 0, 200);
208
209 SurfaceComposerClient::Transaction()
210 .show(child)
211 .show(child2)
212 .setLayer(child, 1)
213 .setLayer(child2, 2)
214 .apply(true);
215
216 // Child2 would be visible but its excluded, so we should see child1 color instead.
chaviw70cb6a42020-07-30 13:57:36 -0700217 LayerCaptureArgs captureArgs;
218 captureArgs.layerHandle = fgHandle;
219 captureArgs.childrenOnly = true;
220 captureArgs.excludeHandles = {child2->getHandle()};
221 ScreenCapture::captureLayers(&mCapture, captureArgs);
chaviw3efadb12020-07-27 10:07:15 -0700222 mCapture->checkPixel(10, 10, 0, 0, 0);
223 mCapture->checkPixel(0, 0, 200, 200, 200);
224}
225
Ajinkya Chalke02844632023-03-01 12:10:14 +0000226TEST_F(ScreenCaptureTest, CaptureLayerExcludeThroughDisplayArgs) {
227 mCaptureArgs.excludeHandles = {mFGSurfaceControl->getHandle()};
Melody Hsue69bb172023-10-27 13:51:17 +0000228 ScreenCapture::captureLayers(&mCapture, mCaptureArgs);
Ajinkya Chalke02844632023-03-01 12:10:14 +0000229 mCapture->expectBGColor(0, 0);
230 // Doesn't capture FG layer which is at 64, 64
231 mCapture->expectBGColor(64, 64);
232}
233
chaviw3efadb12020-07-27 10:07:15 -0700234// Like the last test but verifies that children are also exclude.
235TEST_F(ScreenCaptureTest, CaptureLayerExcludeTree) {
236 auto fgHandle = mFGSurfaceControl->getHandle();
237
238 sp<SurfaceControl> child = createSurface(mClient, "Child surface", 10, 10,
239 PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
240 TransactionUtils::fillSurfaceRGBA8(child, 200, 200, 200);
241 sp<SurfaceControl> child2 = createSurface(mClient, "Child surface", 10, 10,
242 PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
243 TransactionUtils::fillSurfaceRGBA8(child2, 200, 0, 200);
244 sp<SurfaceControl> child3 = createSurface(mClient, "Child surface", 10, 10,
245 PIXEL_FORMAT_RGBA_8888, 0, child2.get());
246 TransactionUtils::fillSurfaceRGBA8(child2, 200, 0, 200);
247
248 SurfaceComposerClient::Transaction()
249 .show(child)
250 .show(child2)
251 .show(child3)
252 .setLayer(child, 1)
253 .setLayer(child2, 2)
254 .apply(true);
255
256 // Child2 would be visible but its excluded, so we should see child1 color instead.
chaviw70cb6a42020-07-30 13:57:36 -0700257 LayerCaptureArgs captureArgs;
258 captureArgs.layerHandle = fgHandle;
259 captureArgs.childrenOnly = true;
260 captureArgs.excludeHandles = {child2->getHandle()};
261 ScreenCapture::captureLayers(&mCapture, captureArgs);
chaviw3efadb12020-07-27 10:07:15 -0700262 mCapture->checkPixel(10, 10, 0, 0, 0);
263 mCapture->checkPixel(0, 0, 200, 200, 200);
264}
265
266TEST_F(ScreenCaptureTest, CaptureTransparent) {
267 sp<SurfaceControl> child = createSurface(mClient, "Child surface", 10, 10,
268 PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
269
270 TransactionUtils::fillSurfaceRGBA8(child, 200, 200, 200);
271
272 SurfaceComposerClient::Transaction().show(child).apply(true);
273
chaviw3efadb12020-07-27 10:07:15 -0700274 // Captures child
chaviw70cb6a42020-07-30 13:57:36 -0700275 LayerCaptureArgs captureArgs;
276 captureArgs.layerHandle = child->getHandle();
277 captureArgs.sourceCrop = {0, 0, 10, 20};
278 ScreenCapture::captureLayers(&mCapture, captureArgs);
chaviw3efadb12020-07-27 10:07:15 -0700279 mCapture->expectColor(Rect(0, 0, 9, 9), {200, 200, 200, 255});
280 // Area outside of child's bounds is transparent.
281 mCapture->expectColor(Rect(0, 10, 9, 19), {0, 0, 0, 0});
282}
283
284TEST_F(ScreenCaptureTest, DontCaptureRelativeOutsideTree) {
chaviw3efadb12020-07-27 10:07:15 -0700285 sp<SurfaceControl> child = createSurface(mClient, "Child surface", 10, 10,
286 PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
287 ASSERT_NE(nullptr, child.get()) << "failed to create surface";
288 sp<SurfaceControl> relative = createLayer(String8("Relative surface"), 10, 10, 0);
289 TransactionUtils::fillSurfaceRGBA8(child, 200, 200, 200);
290 TransactionUtils::fillSurfaceRGBA8(relative, 100, 100, 100);
291
292 SurfaceComposerClient::Transaction()
293 .show(child)
294 // Set relative layer above fg layer so should be shown above when computing all layers.
Pablo Gamito11dcc222020-09-12 15:49:39 +0000295 .setRelativeLayer(relative, mFGSurfaceControl, 1)
chaviw3efadb12020-07-27 10:07:15 -0700296 .show(relative)
297 .apply(true);
298
299 // Captures mFGSurfaceControl layer and its child. Relative layer shouldn't be captured.
chaviw70cb6a42020-07-30 13:57:36 -0700300 LayerCaptureArgs captureArgs;
301 captureArgs.layerHandle = mFGSurfaceControl->getHandle();
302 ScreenCapture::captureLayers(&mCapture, captureArgs);
chaviw3efadb12020-07-27 10:07:15 -0700303 mCapture->expectFGColor(10, 10);
304 mCapture->expectChildColor(0, 0);
305}
306
307TEST_F(ScreenCaptureTest, CaptureRelativeInTree) {
chaviw3efadb12020-07-27 10:07:15 -0700308 sp<SurfaceControl> child = createSurface(mClient, "Child surface", 10, 10,
309 PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
310 sp<SurfaceControl> relative = createSurface(mClient, "Relative surface", 10, 10,
311 PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
312 TransactionUtils::fillSurfaceRGBA8(child, 200, 200, 200);
313 TransactionUtils::fillSurfaceRGBA8(relative, 100, 100, 100);
314
315 SurfaceComposerClient::Transaction()
316 .show(child)
317 // Set relative layer below fg layer but relative to child layer so it should be shown
318 // above child layer.
319 .setLayer(relative, -1)
Pablo Gamito11dcc222020-09-12 15:49:39 +0000320 .setRelativeLayer(relative, child, 1)
chaviw3efadb12020-07-27 10:07:15 -0700321 .show(relative)
322 .apply(true);
323
324 // Captures mFGSurfaceControl layer and its children. Relative layer is a child of fg so its
325 // relative value should be taken into account, placing it above child layer.
chaviw70cb6a42020-07-30 13:57:36 -0700326 LayerCaptureArgs captureArgs;
327 captureArgs.layerHandle = mFGSurfaceControl->getHandle();
328 ScreenCapture::captureLayers(&mCapture, captureArgs);
chaviw3efadb12020-07-27 10:07:15 -0700329 mCapture->expectFGColor(10, 10);
330 // Relative layer is showing on top of child layer
331 mCapture->expectColor(Rect(0, 0, 9, 9), {100, 100, 100, 255});
332}
333
334TEST_F(ScreenCaptureTest, CaptureBoundlessLayerWithSourceCrop) {
335 sp<SurfaceControl> child = createColorLayer("Child layer", Color::RED, mFGSurfaceControl.get());
336 SurfaceComposerClient::Transaction().show(child).apply(true);
337
chaviw70cb6a42020-07-30 13:57:36 -0700338 LayerCaptureArgs captureArgs;
339 captureArgs.layerHandle = child->getHandle();
340 captureArgs.sourceCrop = {0, 0, 10, 10};
341 ScreenCapture::captureLayers(&mCapture, captureArgs);
chaviw3efadb12020-07-27 10:07:15 -0700342
343 mCapture->expectColor(Rect(0, 0, 9, 9), Color::RED);
344}
345
346TEST_F(ScreenCaptureTest, CaptureBoundedLayerWithoutSourceCrop) {
347 sp<SurfaceControl> child = createColorLayer("Child layer", Color::RED, mFGSurfaceControl.get());
348 Rect layerCrop(0, 0, 10, 10);
chaviw25714502021-02-11 10:01:08 -0800349 SurfaceComposerClient::Transaction().setCrop(child, layerCrop).show(child).apply(true);
chaviw3efadb12020-07-27 10:07:15 -0700350
chaviw70cb6a42020-07-30 13:57:36 -0700351 LayerCaptureArgs captureArgs;
352 captureArgs.layerHandle = child->getHandle();
353 ScreenCapture::captureLayers(&mCapture, captureArgs);
chaviw3efadb12020-07-27 10:07:15 -0700354
355 mCapture->expectColor(Rect(0, 0, 9, 9), Color::RED);
356}
357
358TEST_F(ScreenCaptureTest, CaptureBoundlessLayerWithoutSourceCropFails) {
359 sp<SurfaceControl> child = createColorLayer("Child layer", Color::RED, mFGSurfaceControl.get());
360 SurfaceComposerClient::Transaction().show(child).apply(true);
361
chaviw3efadb12020-07-27 10:07:15 -0700362 LayerCaptureArgs args;
363 args.layerHandle = child->getHandle();
364
365 ScreenCaptureResults captureResults;
chaviw8ffc7b82020-08-18 11:25:37 -0700366 ASSERT_EQ(BAD_VALUE, ScreenCapture::captureLayers(args, captureResults));
chaviw3efadb12020-07-27 10:07:15 -0700367}
368
369TEST_F(ScreenCaptureTest, CaptureBufferLayerWithoutBufferFails) {
370 sp<SurfaceControl> child = createSurface(mClient, "Child surface", 10, 10,
Robert Carr5b3b9142021-02-22 12:27:32 -0800371 PIXEL_FORMAT_RGBA_8888,
372 ISurfaceComposerClient::eFXSurfaceBufferState,
373 mFGSurfaceControl.get());
374
chaviw3efadb12020-07-27 10:07:15 -0700375 SurfaceComposerClient::Transaction().show(child).apply(true);
chaviw3efadb12020-07-27 10:07:15 -0700376 sp<GraphicBuffer> outBuffer;
377
378 LayerCaptureArgs args;
379 args.layerHandle = child->getHandle();
380 args.childrenOnly = false;
381
382 ScreenCaptureResults captureResults;
chaviw8ffc7b82020-08-18 11:25:37 -0700383 ASSERT_EQ(BAD_VALUE, ScreenCapture::captureLayers(args, captureResults));
chaviw3efadb12020-07-27 10:07:15 -0700384
Patrick Williams83f36b22022-09-14 17:57:35 +0000385 ASSERT_NO_FATAL_FAILURE(fillBufferLayerColor(child, Color::RED, 32, 32));
chaviw3efadb12020-07-27 10:07:15 -0700386 SurfaceComposerClient::Transaction().apply(true);
chaviw8ffc7b82020-08-18 11:25:37 -0700387 ASSERT_EQ(NO_ERROR, ScreenCapture::captureLayers(args, captureResults));
Alec Mouri14d5b862022-04-27 21:20:04 +0000388 ScreenCapture sc(captureResults.buffer, captureResults.capturedHdrLayers);
chaviw3efadb12020-07-27 10:07:15 -0700389 sc.expectColor(Rect(0, 0, 9, 9), Color::RED);
390}
391
392TEST_F(ScreenCaptureTest, CaptureLayerWithGrandchild) {
chaviw3efadb12020-07-27 10:07:15 -0700393 sp<SurfaceControl> child = createSurface(mClient, "Child surface", 10, 10,
394 PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
395 TransactionUtils::fillSurfaceRGBA8(child, 200, 200, 200);
396
397 sp<SurfaceControl> grandchild = createSurface(mClient, "Grandchild surface", 5, 5,
398 PIXEL_FORMAT_RGBA_8888, 0, child.get());
399
400 TransactionUtils::fillSurfaceRGBA8(grandchild, 50, 50, 50);
401 SurfaceComposerClient::Transaction()
402 .show(child)
403 .setPosition(grandchild, 5, 5)
404 .show(grandchild)
405 .apply(true);
406
407 // Captures mFGSurfaceControl, its child, and the grandchild.
chaviw70cb6a42020-07-30 13:57:36 -0700408 LayerCaptureArgs captureArgs;
409 captureArgs.layerHandle = mFGSurfaceControl->getHandle();
410 ScreenCapture::captureLayers(&mCapture, captureArgs);
chaviw3efadb12020-07-27 10:07:15 -0700411 mCapture->expectFGColor(10, 10);
412 mCapture->expectChildColor(0, 0);
413 mCapture->checkPixel(5, 5, 50, 50, 50);
414}
415
416TEST_F(ScreenCaptureTest, CaptureChildOnly) {
417 sp<SurfaceControl> child = createSurface(mClient, "Child surface", 10, 10,
418 PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
419 TransactionUtils::fillSurfaceRGBA8(child, 200, 200, 200);
chaviw3efadb12020-07-27 10:07:15 -0700420
421 SurfaceComposerClient::Transaction().setPosition(child, 5, 5).show(child).apply(true);
422
423 // Captures only the child layer, and not the parent.
chaviw70cb6a42020-07-30 13:57:36 -0700424 LayerCaptureArgs captureArgs;
425 captureArgs.layerHandle = child->getHandle();
426 ScreenCapture::captureLayers(&mCapture, captureArgs);
chaviw3efadb12020-07-27 10:07:15 -0700427 mCapture->expectChildColor(0, 0);
428 mCapture->expectChildColor(9, 9);
429}
430
431TEST_F(ScreenCaptureTest, CaptureGrandchildOnly) {
432 sp<SurfaceControl> child = createSurface(mClient, "Child surface", 10, 10,
433 PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
434 TransactionUtils::fillSurfaceRGBA8(child, 200, 200, 200);
435 auto childHandle = child->getHandle();
436
437 sp<SurfaceControl> grandchild = createSurface(mClient, "Grandchild surface", 5, 5,
438 PIXEL_FORMAT_RGBA_8888, 0, child.get());
439 TransactionUtils::fillSurfaceRGBA8(grandchild, 50, 50, 50);
440
441 SurfaceComposerClient::Transaction()
442 .show(child)
443 .setPosition(grandchild, 5, 5)
444 .show(grandchild)
445 .apply(true);
446
chaviw3efadb12020-07-27 10:07:15 -0700447 // Captures only the grandchild.
chaviw70cb6a42020-07-30 13:57:36 -0700448 LayerCaptureArgs captureArgs;
449 captureArgs.layerHandle = grandchild->getHandle();
450 ScreenCapture::captureLayers(&mCapture, captureArgs);
chaviw3efadb12020-07-27 10:07:15 -0700451 mCapture->checkPixel(0, 0, 50, 50, 50);
452 mCapture->checkPixel(4, 4, 50, 50, 50);
453}
454
455TEST_F(ScreenCaptureTest, CaptureCrop) {
Robert Carr5b3b9142021-02-22 12:27:32 -0800456 sp<SurfaceControl> redLayer = createLayer(String8("Red surface"), 60, 60,
457 ISurfaceComposerClient::eFXSurfaceBufferState);
chaviw3efadb12020-07-27 10:07:15 -0700458 sp<SurfaceControl> blueLayer = createSurface(mClient, "Blue surface", 30, 30,
Robert Carr5b3b9142021-02-22 12:27:32 -0800459 PIXEL_FORMAT_RGBA_8888,
460 ISurfaceComposerClient::eFXSurfaceBufferState,
461 redLayer.get());
chaviw3efadb12020-07-27 10:07:15 -0700462
Patrick Williams83f36b22022-09-14 17:57:35 +0000463 ASSERT_NO_FATAL_FAILURE(fillBufferLayerColor(redLayer, Color::RED, 60, 60));
464 ASSERT_NO_FATAL_FAILURE(fillBufferLayerColor(blueLayer, Color::BLUE, 30, 30));
chaviw3efadb12020-07-27 10:07:15 -0700465
466 SurfaceComposerClient::Transaction()
467 .setLayer(redLayer, INT32_MAX - 1)
468 .show(redLayer)
469 .show(blueLayer)
470 .apply(true);
471
chaviw3efadb12020-07-27 10:07:15 -0700472 // Capturing full screen should have both red and blue are visible.
chaviw70cb6a42020-07-30 13:57:36 -0700473 LayerCaptureArgs captureArgs;
474 captureArgs.layerHandle = redLayer->getHandle();
475 ScreenCapture::captureLayers(&mCapture, captureArgs);
chaviw3efadb12020-07-27 10:07:15 -0700476 mCapture->expectColor(Rect(0, 0, 29, 29), Color::BLUE);
477 // red area below the blue area
478 mCapture->expectColor(Rect(0, 30, 59, 59), Color::RED);
479 // red area to the right of the blue area
480 mCapture->expectColor(Rect(30, 0, 59, 59), Color::RED);
481
chaviw70cb6a42020-07-30 13:57:36 -0700482 captureArgs.sourceCrop = {0, 0, 30, 30};
483 ScreenCapture::captureLayers(&mCapture, captureArgs);
chaviw3efadb12020-07-27 10:07:15 -0700484 // Capturing the cropped screen, cropping out the shown red area, should leave only the blue
485 // area visible.
486 mCapture->expectColor(Rect(0, 0, 29, 29), Color::BLUE);
487 mCapture->checkPixel(30, 30, 0, 0, 0);
488}
489
490TEST_F(ScreenCaptureTest, CaptureSize) {
Robert Carr5b3b9142021-02-22 12:27:32 -0800491 sp<SurfaceControl> redLayer =
492 createLayer(String8("Red surface"), 60, 60, ISurfaceComposerClient::eFXSurfaceBufferState);
chaviw3efadb12020-07-27 10:07:15 -0700493 sp<SurfaceControl> blueLayer = createSurface(mClient, "Blue surface", 30, 30,
Robert Carr5b3b9142021-02-22 12:27:32 -0800494 PIXEL_FORMAT_RGBA_8888,
495 ISurfaceComposerClient::eFXSurfaceBufferState,
496 redLayer.get());
chaviw3efadb12020-07-27 10:07:15 -0700497
Patrick Williams83f36b22022-09-14 17:57:35 +0000498 ASSERT_NO_FATAL_FAILURE(fillBufferLayerColor(redLayer, Color::RED, 60, 60));
499 ASSERT_NO_FATAL_FAILURE(fillBufferLayerColor(blueLayer, Color::BLUE, 30, 30));
chaviw3efadb12020-07-27 10:07:15 -0700500
501 SurfaceComposerClient::Transaction()
502 .setLayer(redLayer, INT32_MAX - 1)
503 .show(redLayer)
504 .show(blueLayer)
505 .apply(true);
506
chaviw3efadb12020-07-27 10:07:15 -0700507 // Capturing full screen should have both red and blue are visible.
chaviw70cb6a42020-07-30 13:57:36 -0700508 LayerCaptureArgs captureArgs;
509 captureArgs.layerHandle = redLayer->getHandle();
510 ScreenCapture::captureLayers(&mCapture, captureArgs);
chaviw3efadb12020-07-27 10:07:15 -0700511 mCapture->expectColor(Rect(0, 0, 29, 29), Color::BLUE);
512 // red area below the blue area
513 mCapture->expectColor(Rect(0, 30, 59, 59), Color::RED);
514 // red area to the right of the blue area
515 mCapture->expectColor(Rect(30, 0, 59, 59), Color::RED);
516
chaviw17ac24b2021-01-28 18:50:05 -0800517 captureArgs.frameScaleX = 0.5f;
518 captureArgs.frameScaleY = 0.5f;
Robert Carr5b3b9142021-02-22 12:27:32 -0800519 sleep(1);
chaviw17ac24b2021-01-28 18:50:05 -0800520
chaviw70cb6a42020-07-30 13:57:36 -0700521 ScreenCapture::captureLayers(&mCapture, captureArgs);
chaviw3efadb12020-07-27 10:07:15 -0700522 // Capturing the downsized area (30x30) should leave both red and blue but in a smaller area.
523 mCapture->expectColor(Rect(0, 0, 14, 14), Color::BLUE);
524 // red area below the blue area
525 mCapture->expectColor(Rect(0, 15, 29, 29), Color::RED);
526 // red area to the right of the blue area
527 mCapture->expectColor(Rect(15, 0, 29, 29), Color::RED);
528 mCapture->checkPixel(30, 30, 0, 0, 0);
529}
530
531TEST_F(ScreenCaptureTest, CaptureInvalidLayer) {
chaviw3efadb12020-07-27 10:07:15 -0700532 LayerCaptureArgs args;
Ady Abrahamd11bade2022-08-01 16:18:03 -0700533 args.layerHandle = sp<BBinder>::make();
chaviw3efadb12020-07-27 10:07:15 -0700534
535 ScreenCaptureResults captureResults;
chaviw3efadb12020-07-27 10:07:15 -0700536 // Layer was deleted so captureLayers should fail with NAME_NOT_FOUND
chaviw8ffc7b82020-08-18 11:25:37 -0700537 ASSERT_EQ(NAME_NOT_FOUND, ScreenCapture::captureLayers(args, captureResults));
chaviw3efadb12020-07-27 10:07:15 -0700538}
539
Garfield Tan9c9c1912021-07-19 12:02:16 -0700540TEST_F(ScreenCaptureTest, CaptureTooLargeLayer) {
541 sp<SurfaceControl> redLayer = createLayer(String8("Red surface"), 60, 60);
542 ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(redLayer, Color::RED, 60, 60));
543
544 Transaction().show(redLayer).setLayer(redLayer, INT32_MAX).apply(true);
545
546 LayerCaptureArgs captureArgs;
547 captureArgs.layerHandle = redLayer->getHandle();
548 captureArgs.frameScaleX = INT32_MAX / 60;
549 captureArgs.frameScaleY = INT32_MAX / 60;
550
551 ScreenCaptureResults captureResults;
552 ASSERT_EQ(BAD_VALUE, ScreenCapture::captureLayers(captureArgs, captureResults));
553}
554
chaviwf5bb97b2021-04-28 15:35:37 -0500555TEST_F(ScreenCaptureTest, CaptureSecureLayer) {
Robert Carr5b3b9142021-02-22 12:27:32 -0800556 sp<SurfaceControl> redLayer = createLayer(String8("Red surface"), 60, 60,
557 ISurfaceComposerClient::eFXSurfaceBufferState);
chaviw70cb6a42020-07-30 13:57:36 -0700558 sp<SurfaceControl> secureLayer =
559 createLayer(String8("Secure surface"), 30, 30,
560 ISurfaceComposerClient::eSecure |
Robert Carr5b3b9142021-02-22 12:27:32 -0800561 ISurfaceComposerClient::eFXSurfaceBufferState,
chaviw70cb6a42020-07-30 13:57:36 -0700562 redLayer.get());
Patrick Williams83f36b22022-09-14 17:57:35 +0000563 ASSERT_NO_FATAL_FAILURE(fillBufferLayerColor(redLayer, Color::RED, 60, 60));
564 ASSERT_NO_FATAL_FAILURE(fillBufferLayerColor(secureLayer, Color::BLUE, 30, 30));
chaviw70cb6a42020-07-30 13:57:36 -0700565
566 auto redLayerHandle = redLayer->getHandle();
567 Transaction()
568 .show(redLayer)
569 .show(secureLayer)
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700570 .setLayerStack(redLayer, ui::DEFAULT_LAYER_STACK)
chaviw70cb6a42020-07-30 13:57:36 -0700571 .setLayer(redLayer, INT32_MAX)
572 .apply();
573
chaviw70cb6a42020-07-30 13:57:36 -0700574 LayerCaptureArgs args;
575 args.layerHandle = redLayerHandle;
576 args.childrenOnly = false;
577 ScreenCaptureResults captureResults;
578
chaviwf5bb97b2021-04-28 15:35:37 -0500579 {
580 // Ensure the UID is not root because root has all permissions
581 UIDFaker f(AID_APP_START);
582 // Call from outside system with secure layers will result in permission denied
583 ASSERT_EQ(PERMISSION_DENIED, ScreenCapture::captureLayers(args, captureResults));
584 }
chaviw70cb6a42020-07-30 13:57:36 -0700585
586 UIDFaker f(AID_SYSTEM);
587
588 // From system request, only red layer will be screenshot since the blue layer is secure.
589 // Black will be present where the secure layer is.
590 ScreenCapture::captureLayers(&mCapture, args);
591 mCapture->expectColor(Rect(0, 0, 30, 30), Color::BLACK);
592 mCapture->expectColor(Rect(30, 30, 60, 60), Color::RED);
593
594 // Passing flag secure so the blue layer should be screenshot too.
595 args.captureSecureLayers = true;
596 ScreenCapture::captureLayers(&mCapture, args);
597 mCapture->expectColor(Rect(0, 0, 30, 30), Color::BLUE);
598 mCapture->expectColor(Rect(30, 30, 60, 60), Color::RED);
599}
600
Melody Hsue69bb172023-10-27 13:51:17 +0000601TEST_F(ScreenCaptureTest, ScreenshotProtectedBuffer) {
602 const uint32_t bufferWidth = 60;
603 const uint32_t bufferHeight = 60;
chaviw4b9d5e12020-08-04 18:30:35 -0700604
Melody Hsue69bb172023-10-27 13:51:17 +0000605 sp<SurfaceControl> layer =
606 createLayer(String8("Colored surface"), bufferWidth, bufferHeight,
607 ISurfaceComposerClient::eFXSurfaceBufferState, mRootSurfaceControl.get());
chaviw4b9d5e12020-08-04 18:30:35 -0700608
Melody Hsue69bb172023-10-27 13:51:17 +0000609 Transaction().show(layer).setLayer(layer, INT32_MAX).apply(true);
chaviw4b9d5e12020-08-04 18:30:35 -0700610
Melody Hsue69bb172023-10-27 13:51:17 +0000611 sp<Surface> surface = layer->getSurface();
612 ASSERT_TRUE(surface != nullptr);
613 sp<ANativeWindow> anw(surface);
chaviw4b9d5e12020-08-04 18:30:35 -0700614
Melody Hsue69bb172023-10-27 13:51:17 +0000615 ASSERT_EQ(NO_ERROR, native_window_api_connect(anw.get(), NATIVE_WINDOW_API_CPU));
616 ASSERT_EQ(NO_ERROR, native_window_set_usage(anw.get(), GRALLOC_USAGE_PROTECTED));
chaviw4b9d5e12020-08-04 18:30:35 -0700617
Melody Hsue69bb172023-10-27 13:51:17 +0000618 int fenceFd;
619 ANativeWindowBuffer* buf = nullptr;
chaviw4b9d5e12020-08-04 18:30:35 -0700620
Melody Hsue69bb172023-10-27 13:51:17 +0000621 // End test if device does not support USAGE_PROTECTED
622 // b/309965549 This check does not exit the test when running on AVDs
623 status_t err = anw->dequeueBuffer(anw.get(), &buf, &fenceFd);
624 if (err) {
625 return;
626 }
627 anw->queueBuffer(anw.get(), buf, fenceFd);
chaviw4b9d5e12020-08-04 18:30:35 -0700628
Melody Hsue69bb172023-10-27 13:51:17 +0000629 // USAGE_PROTECTED buffer is read as a black screen
630 ScreenCaptureResults captureResults;
631 ASSERT_EQ(NO_ERROR, ScreenCapture::captureLayers(mCaptureArgs, captureResults));
chaviw4b9d5e12020-08-04 18:30:35 -0700632
Melody Hsue69bb172023-10-27 13:51:17 +0000633 ScreenCapture sc(captureResults.buffer, captureResults.capturedHdrLayers);
634 sc.expectColor(Rect(0, 0, bufferWidth, bufferHeight), Color::BLACK);
635
636 // Reading color data will expectedly result in crash, only check usage bit
637 // b/309965549 Checking that the usage bit is protected does not work for
638 // devices that do not support usage protected.
639 mCaptureArgs.allowProtected = true;
640 ASSERT_EQ(NO_ERROR, ScreenCapture::captureLayers(mCaptureArgs, captureResults));
641 // ASSERT_EQ(GRALLOC_USAGE_PROTECTED, GRALLOC_USAGE_PROTECTED &
642 // captureResults.buffer->getUsage());
chaviw4b9d5e12020-08-04 18:30:35 -0700643}
644
Melody Hsue69bb172023-10-27 13:51:17 +0000645TEST_F(ScreenCaptureTest, CaptureLayer) {
chaviwc5676c62020-09-18 15:01:04 -0700646 sp<SurfaceControl> layer;
Melody Hsue69bb172023-10-27 13:51:17 +0000647 ASSERT_NO_FATAL_FAILURE(layer = createLayer("test layer", 0, 0,
648 ISurfaceComposerClient::eFXSurfaceEffect,
649 mRootSurfaceControl.get()));
chaviwc5676c62020-09-18 15:01:04 -0700650
651 const Color layerColor = Color::RED;
652 const Rect bounds = Rect(10, 10, 40, 40);
653
654 Transaction()
655 .show(layer)
656 .hide(mFGSurfaceControl)
chaviwc5676c62020-09-18 15:01:04 -0700657 .setLayer(layer, INT32_MAX)
658 .setColor(layer, {layerColor.r / 255, layerColor.g / 255, layerColor.b / 255})
chaviw25714502021-02-11 10:01:08 -0800659 .setCrop(layer, bounds)
chaviwc5676c62020-09-18 15:01:04 -0700660 .apply();
661
chaviwc5676c62020-09-18 15:01:04 -0700662 {
Melody Hsue69bb172023-10-27 13:51:17 +0000663 ScreenCapture::captureLayers(&mCapture, mCaptureArgs);
chaviwc5676c62020-09-18 15:01:04 -0700664 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
Melody Hsue69bb172023-10-27 13:51:17 +0000676 ScreenCapture::captureLayers(&mCapture, mCaptureArgs);
chaviwc5676c62020-09-18 15:01:04 -0700677 mCapture->expectColor(bounds, {63, 63, 195, 255});
678 mCapture->expectBorder(bounds, {63, 63, 195, 255});
679 }
680}
681
Melody Hsue69bb172023-10-27 13:51:17 +0000682TEST_F(ScreenCaptureTest, CaptureLayerChild) {
chaviwc5676c62020-09-18 15:01:04 -0700683 sp<SurfaceControl> layer;
684 sp<SurfaceControl> childLayer;
Melody Hsue69bb172023-10-27 13:51:17 +0000685 ASSERT_NO_FATAL_FAILURE(layer = createLayer("test layer", 0, 0,
686 ISurfaceComposerClient::eFXSurfaceEffect,
687 mRootSurfaceControl.get()));
chaviwc5676c62020-09-18 15:01:04 -0700688 ASSERT_NO_FATAL_FAILURE(childLayer = createLayer("test layer", 0, 0,
689 ISurfaceComposerClient::eFXSurfaceEffect,
690 layer.get()));
691
692 const Color layerColor = Color::RED;
693 const Color childColor = Color::BLUE;
694 const Rect bounds = Rect(10, 10, 40, 40);
695 const Rect childBounds = Rect(20, 20, 30, 30);
696
697 Transaction()
698 .show(layer)
699 .show(childLayer)
700 .hide(mFGSurfaceControl)
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
chaviwc5676c62020-09-18 15:01:04 -0700708 {
Melody Hsue69bb172023-10-27 13:51:17 +0000709 ScreenCapture::captureLayers(&mCapture, mCaptureArgs);
chaviwc5676c62020-09-18 15:01:04 -0700710 mCapture->expectColor(childBounds, childColor);
711 mCapture->expectBorder(childBounds, layerColor);
712 mCapture->expectBorder(bounds, {63, 63, 195, 255});
713 }
714
715 Transaction()
716 .setFlags(layer, layer_state_t::eLayerSkipScreenshot,
717 layer_state_t::eLayerSkipScreenshot)
718 .apply();
719
720 {
721 // Can't screenshot child layer since the parent has the flag
722 // eLayerSkipScreenshot
Melody Hsue69bb172023-10-27 13:51:17 +0000723 ScreenCapture::captureLayers(&mCapture, mCaptureArgs);
chaviwc5676c62020-09-18 15:01:04 -0700724 mCapture->expectColor(childBounds, {63, 63, 195, 255});
725 mCapture->expectBorder(childBounds, {63, 63, 195, 255});
726 mCapture->expectBorder(bounds, {63, 63, 195, 255});
727 }
728}
729
chaviw4b9d5e12020-08-04 18:30:35 -0700730TEST_F(ScreenCaptureTest, CaptureLayerWithUid) {
731 uid_t fakeUid = 12345;
732
733 sp<SurfaceControl> layer;
734 ASSERT_NO_FATAL_FAILURE(layer = createLayer("test layer", 32, 32,
735 ISurfaceComposerClient::eFXSurfaceBufferQueue,
736 mBGSurfaceControl.get()));
737 ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(layer, Color::RED, 32, 32));
738
739 Transaction().show(layer).setLayer(layer, INT32_MAX).apply();
740
741 LayerCaptureArgs captureArgs;
742 captureArgs.layerHandle = mBGSurfaceControl->getHandle();
743 captureArgs.childrenOnly = false;
744
745 // Make sure red layer with the background layer is screenshot.
746 ScreenCapture::captureLayers(&mCapture, captureArgs);
747 mCapture->expectColor(Rect(0, 0, 32, 32), Color::RED);
748 mCapture->expectBorder(Rect(0, 0, 32, 32), {63, 63, 195, 255});
749
750 // From non system uid, can't request screenshot without a specified uid.
751 std::unique_ptr<UIDFaker> uidFaker = std::make_unique<UIDFaker>(fakeUid);
752
chaviw8ffc7b82020-08-18 11:25:37 -0700753 ASSERT_EQ(PERMISSION_DENIED, ScreenCapture::captureLayers(captureArgs, mCaptureResults));
chaviw4b9d5e12020-08-04 18:30:35 -0700754
755 // Make screenshot request with current uid set. No layers were created with the current
756 // uid so screenshot will be black.
757 captureArgs.uid = fakeUid;
758 ScreenCapture::captureLayers(&mCapture, captureArgs);
759 mCapture->expectColor(Rect(0, 0, 32, 32), Color::TRANSPARENT);
760 mCapture->expectBorder(Rect(0, 0, 32, 32), Color::TRANSPARENT);
761
762 sp<SurfaceControl> layerWithFakeUid;
763 // Create a new layer with the current uid
764 ASSERT_NO_FATAL_FAILURE(layerWithFakeUid =
765 createLayer("new test layer", 32, 32,
766 ISurfaceComposerClient::eFXSurfaceBufferQueue,
767 mBGSurfaceControl.get()));
768 ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(layerWithFakeUid, Color::GREEN, 32, 32));
769 Transaction()
770 .show(layerWithFakeUid)
771 .setLayer(layerWithFakeUid, INT32_MAX)
772 .setPosition(layerWithFakeUid, 128, 128)
773 // reparent a layer that was created with a different uid to the new layer.
Pablo Gamito11dcc222020-09-12 15:49:39 +0000774 .reparent(layer, layerWithFakeUid)
chaviw4b9d5e12020-08-04 18:30:35 -0700775 .apply();
776
777 // Screenshot from the fakeUid caller with the uid requested allows the layer
778 // with that uid to be screenshotted. The child layer is skipped since it was created
779 // from a different uid.
780 ScreenCapture::captureLayers(&mCapture, captureArgs);
781 mCapture->expectColor(Rect(128, 128, 160, 160), Color::GREEN);
782 mCapture->expectBorder(Rect(128, 128, 160, 160), Color::TRANSPARENT);
783
784 // Clear fake calling uid so it's back to system.
785 uidFaker = nullptr;
786 // Screenshot from the test caller with the uid requested allows the layer
787 // with that uid to be screenshotted. The child layer is skipped since it was created
788 // from a different uid.
789 ScreenCapture::captureLayers(&mCapture, captureArgs);
790 mCapture->expectColor(Rect(128, 128, 160, 160), Color::GREEN);
791 mCapture->expectBorder(Rect(128, 128, 160, 160), Color::TRANSPARENT);
792
793 // Screenshot from the fakeUid caller with no uid requested allows everything to be screenshot.
794 captureArgs.uid = -1;
795 ScreenCapture::captureLayers(&mCapture, captureArgs);
796 mCapture->expectColor(Rect(128, 128, 160, 160), Color::RED);
797 mCapture->expectBorder(Rect(128, 128, 160, 160), {63, 63, 195, 255});
798}
799
chaviw17ac24b2021-01-28 18:50:05 -0800800TEST_F(ScreenCaptureTest, CaptureWithGrayscale) {
801 sp<SurfaceControl> layer;
802 ASSERT_NO_FATAL_FAILURE(layer = createLayer("test layer", 32, 32,
803 ISurfaceComposerClient::eFXSurfaceBufferState,
804 mBGSurfaceControl.get()));
Patrick Williams83f36b22022-09-14 17:57:35 +0000805 ASSERT_NO_FATAL_FAILURE(fillBufferLayerColor(layer, Color::RED, 32, 32));
chaviw17ac24b2021-01-28 18:50:05 -0800806 Transaction().show(layer).setLayer(layer, INT32_MAX).apply();
807
808 LayerCaptureArgs captureArgs;
809 captureArgs.layerHandle = layer->getHandle();
810
811 ScreenCapture::captureLayers(&mCapture, captureArgs);
812 mCapture->expectColor(Rect(0, 0, 32, 32), Color::RED);
813
814 captureArgs.grayscale = true;
815
816 const uint8_t tolerance = 1;
817
818 // Values based on SurfaceFlinger::calculateColorMatrix
819 float3 luminance{0.213f, 0.715f, 0.072f};
820
821 ScreenCapture::captureLayers(&mCapture, captureArgs);
822
823 uint8_t expectedColor = luminance.r * 255;
824 mCapture->expectColor(Rect(0, 0, 32, 32),
825 Color{expectedColor, expectedColor, expectedColor, 255}, tolerance);
826
Patrick Williams83f36b22022-09-14 17:57:35 +0000827 ASSERT_NO_FATAL_FAILURE(fillBufferLayerColor(layer, Color::BLUE, 32, 32));
chaviw17ac24b2021-01-28 18:50:05 -0800828 ScreenCapture::captureLayers(&mCapture, captureArgs);
829
830 expectedColor = luminance.b * 255;
831 mCapture->expectColor(Rect(0, 0, 32, 32),
832 Color{expectedColor, expectedColor, expectedColor, 255}, tolerance);
833}
834
chaviw79468ab2021-10-27 11:11:24 -0500835TEST_F(ScreenCaptureTest, CaptureOffscreen) {
836 sp<SurfaceControl> layer;
837 ASSERT_NO_FATAL_FAILURE(layer = createLayer("test layer", 32, 32,
838 ISurfaceComposerClient::eFXSurfaceBufferState,
839 mBGSurfaceControl.get()));
Patrick Williams83f36b22022-09-14 17:57:35 +0000840 ASSERT_NO_FATAL_FAILURE(fillBufferLayerColor(layer, Color::RED, 32, 32));
chaviw79468ab2021-10-27 11:11:24 -0500841
842 Transaction().show(layer).hide(mFGSurfaceControl).reparent(layer, nullptr).apply();
843
chaviw79468ab2021-10-27 11:11:24 -0500844 {
845 // Validate that the red layer is not on screen
Melody Hsue69bb172023-10-27 13:51:17 +0000846 ScreenCapture::captureLayers(&mCapture, mCaptureArgs);
847 mCapture->expectColor(Rect(0, 0, mDisplayWidth, mDisplayHeight), {63, 63, 195, 255});
chaviw79468ab2021-10-27 11:11:24 -0500848 }
849
850 LayerCaptureArgs captureArgs;
851 captureArgs.layerHandle = layer->getHandle();
852
853 ScreenCapture::captureLayers(&mCapture, captureArgs);
854 mCapture->expectSize(32, 32);
855 mCapture->expectColor(Rect(0, 0, 32, 32), Color::RED);
856}
857
Alec Mouri14d5b862022-04-27 21:20:04 +0000858TEST_F(ScreenCaptureTest, CaptureNonHdrLayer) {
859 sp<SurfaceControl> layer;
860 ASSERT_NO_FATAL_FAILURE(layer = createLayer("test layer", 32, 32,
861 ISurfaceComposerClient::eFXSurfaceBufferState,
862 mBGSurfaceControl.get()));
Patrick Williams83f36b22022-09-14 17:57:35 +0000863 ASSERT_NO_FATAL_FAILURE(fillBufferLayerColor(layer, Color::BLACK, 32, 32));
Alec Mouri14d5b862022-04-27 21:20:04 +0000864 Transaction()
865 .show(layer)
866 .setLayer(layer, INT32_MAX)
867 .setDataspace(layer, ui::Dataspace::V0_SRGB)
868 .apply();
869
870 LayerCaptureArgs captureArgs;
871 captureArgs.layerHandle = layer->getHandle();
872
873 ScreenCapture::captureLayers(&mCapture, captureArgs);
874 mCapture->expectColor(Rect(0, 0, 32, 32), Color::BLACK);
875 ASSERT_FALSE(mCapture->capturedHdrLayers());
876}
877
878TEST_F(ScreenCaptureTest, CaptureHdrLayer) {
879 sp<SurfaceControl> layer;
880 ASSERT_NO_FATAL_FAILURE(layer = createLayer("test layer", 32, 32,
881 ISurfaceComposerClient::eFXSurfaceBufferState,
882 mBGSurfaceControl.get()));
Patrick Williams83f36b22022-09-14 17:57:35 +0000883 ASSERT_NO_FATAL_FAILURE(fillBufferLayerColor(layer, Color::BLACK, 32, 32));
Alec Mouri14d5b862022-04-27 21:20:04 +0000884 Transaction()
885 .show(layer)
886 .setLayer(layer, INT32_MAX)
887 .setDataspace(layer, ui::Dataspace::BT2020_ITU_PQ)
888 .apply();
889
890 LayerCaptureArgs captureArgs;
891 captureArgs.layerHandle = layer->getHandle();
892
893 ScreenCapture::captureLayers(&mCapture, captureArgs);
894 mCapture->expectColor(Rect(0, 0, 32, 32), Color::BLACK);
895 ASSERT_TRUE(mCapture->capturedHdrLayers());
896}
897
chaviw3efadb12020-07-27 10:07:15 -0700898// In the following tests we verify successful skipping of a parent layer,
899// so we use the same verification logic and only change how we mutate
900// the parent layer to verify that various properties are ignored.
901class ScreenCaptureChildOnlyTest : public ScreenCaptureTest {
902public:
903 void SetUp() override {
904 ScreenCaptureTest::SetUp();
905
906 mChild = createSurface(mClient, "Child surface", 10, 10, PIXEL_FORMAT_RGBA_8888, 0,
907 mFGSurfaceControl.get());
908 TransactionUtils::fillSurfaceRGBA8(mChild, 200, 200, 200);
909
910 SurfaceComposerClient::Transaction().show(mChild).apply(true);
911 }
912
913 void verify(std::function<void()> verifyStartingState) {
914 // Verify starting state before a screenshot is taken.
915 verifyStartingState();
916
917 // Verify child layer does not inherit any of the properties of its
918 // parent when its screenshot is captured.
chaviw70cb6a42020-07-30 13:57:36 -0700919 LayerCaptureArgs captureArgs;
920 captureArgs.layerHandle = mFGSurfaceControl->getHandle();
921 captureArgs.childrenOnly = true;
922 ScreenCapture::captureLayers(&mCapture, captureArgs);
chaviw3efadb12020-07-27 10:07:15 -0700923 mCapture->checkPixel(10, 10, 0, 0, 0);
924 mCapture->expectChildColor(0, 0);
925
926 // Verify all assumptions are still true after the screenshot is taken.
927 verifyStartingState();
928 }
929
930 std::unique_ptr<ScreenCapture> mCapture;
931 sp<SurfaceControl> mChild;
932};
933
934// Regression test b/76099859
935TEST_F(ScreenCaptureChildOnlyTest, CaptureLayerIgnoresParentVisibility) {
936 SurfaceComposerClient::Transaction().hide(mFGSurfaceControl).apply(true);
937
938 // Even though the parent is hidden we should still capture the child.
939
940 // Before and after reparenting, verify child is properly hidden
941 // when rendering full-screen.
942 verify([&] { screenshot()->expectBGColor(64, 64); });
943}
944
945TEST_F(ScreenCaptureChildOnlyTest, CaptureLayerIgnoresParentCrop) {
chaviw25714502021-02-11 10:01:08 -0800946 SurfaceComposerClient::Transaction().setCrop(mFGSurfaceControl, Rect(0, 0, 1, 1)).apply(true);
chaviw3efadb12020-07-27 10:07:15 -0700947
948 // Even though the parent is cropped out we should still capture the child.
949
950 // Before and after reparenting, verify child is cropped by parent.
951 verify([&] { screenshot()->expectBGColor(65, 65); });
952}
953
954// Regression test b/124372894
955TEST_F(ScreenCaptureChildOnlyTest, CaptureLayerIgnoresTransform) {
956 SurfaceComposerClient::Transaction().setMatrix(mFGSurfaceControl, 2, 0, 0, 2).apply(true);
957
958 // We should not inherit the parent scaling.
959
960 // Before and after reparenting, verify child is properly scaled.
961 verify([&] { screenshot()->expectChildColor(80, 80); });
962}
963
Garfield Tande619fa2020-10-02 17:13:53 -0700964} // namespace android
Marin Shalamanovbed7fd32020-12-21 20:02:20 +0100965
966// TODO(b/129481165): remove the #pragma below and fix conversion issues
Robert Carr5b3b9142021-02-22 12:27:32 -0800967#pragma clang diagnostic pop // ignored "-Wconversion"