blob: 069f199cabb959b5feedc3da6d549c33ecc93b76 [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
Alec Mouribae67862024-08-06 14:53:46 +000023#include <gui/AidlStatusUtil.h>
chaviw70cb6a42020-07-30 13:57:36 -070024#include <private/android_filesystem_config.h>
Patrick Williams1c8d8422023-07-06 11:23:17 -050025#include <ui/DisplayState.h>
chaviw70cb6a42020-07-30 13:57:36 -070026
chaviw3efadb12020-07-27 10:07:15 -070027#include "LayerTransactionTest.h"
28
29namespace android {
30
31class ScreenCaptureTest : public LayerTransactionTest {
32protected:
33 virtual void SetUp() {
34 LayerTransactionTest::SetUp();
35 ASSERT_EQ(NO_ERROR, mClient->initCheck());
36
Melody Hsue69bb172023-10-27 13:51:17 +000037 // Root surface
38 mRootSurfaceControl =
39 createLayer(String8("RootTestSurface"), mDisplayWidth, mDisplayHeight, 0);
40 ASSERT_TRUE(mRootSurfaceControl != nullptr);
41 ASSERT_TRUE(mRootSurfaceControl->isValid());
chaviw79468ab2021-10-27 11:11:24 -050042
chaviw3efadb12020-07-27 10:07:15 -070043 // Background surface
Melody Hsue69bb172023-10-27 13:51:17 +000044 mBGSurfaceControl = createLayer(String8("BG Test Surface"), mDisplayWidth, mDisplayHeight,
45 0, mRootSurfaceControl.get());
chaviw3efadb12020-07-27 10:07:15 -070046 ASSERT_TRUE(mBGSurfaceControl != nullptr);
47 ASSERT_TRUE(mBGSurfaceControl->isValid());
48 TransactionUtils::fillSurfaceRGBA8(mBGSurfaceControl, 63, 63, 195);
49
50 // Foreground surface
Melody Hsue69bb172023-10-27 13:51:17 +000051 mFGSurfaceControl =
52 createLayer(String8("FG Test Surface"), 64, 64, 0, mRootSurfaceControl.get());
chaviw3efadb12020-07-27 10:07:15 -070053
54 ASSERT_TRUE(mFGSurfaceControl != nullptr);
55 ASSERT_TRUE(mFGSurfaceControl->isValid());
56
57 TransactionUtils::fillSurfaceRGBA8(mFGSurfaceControl, 195, 63, 63);
58
59 asTransaction([&](Transaction& t) {
Melody Hsue69bb172023-10-27 13:51:17 +000060 t.setDisplayLayerStack(mDisplay, 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 });
Melody Hsue69bb172023-10-27 13:51:17 +000068
Alec Mouribae67862024-08-06 14:53:46 +000069 mCaptureArgs.captureArgs.sourceCrop = gui::aidl_utils::toARect(mDisplayRect);
Melody Hsue69bb172023-10-27 13:51:17 +000070 mCaptureArgs.layerHandle = mRootSurfaceControl->getHandle();
chaviw3efadb12020-07-27 10:07:15 -070071 }
72
73 virtual void TearDown() {
74 LayerTransactionTest::TearDown();
75 mBGSurfaceControl = 0;
76 mFGSurfaceControl = 0;
77 }
78
Melody Hsue69bb172023-10-27 13:51:17 +000079 sp<SurfaceControl> mRootSurfaceControl;
chaviw3efadb12020-07-27 10:07:15 -070080 sp<SurfaceControl> mBGSurfaceControl;
81 sp<SurfaceControl> mFGSurfaceControl;
82 std::unique_ptr<ScreenCapture> mCapture;
Melody Hsue69bb172023-10-27 13:51:17 +000083 LayerCaptureArgs mCaptureArgs;
chaviw3efadb12020-07-27 10:07:15 -070084};
85
chaviw4b9d5e12020-08-04 18:30:35 -070086TEST_F(ScreenCaptureTest, SetFlagsSecureEUidSystem) {
87 sp<SurfaceControl> layer;
88 ASSERT_NO_FATAL_FAILURE(
89 layer = createLayer("test", 32, 32,
90 ISurfaceComposerClient::eSecure |
Melody Hsue69bb172023-10-27 13:51:17 +000091 ISurfaceComposerClient::eFXSurfaceBufferQueue,
92 mRootSurfaceControl.get()));
chaviw4b9d5e12020-08-04 18:30:35 -070093 ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(layer, Color::RED, 32, 32));
94
95 Transaction().show(layer).setLayer(layer, INT32_MAX).apply(true);
96
chaviwf5bb97b2021-04-28 15:35:37 -050097 {
98 // Ensure the UID is not root because root has all permissions
99 UIDFaker f(AID_APP_START);
Melody Hsue69bb172023-10-27 13:51:17 +0000100 ASSERT_EQ(PERMISSION_DENIED, ScreenCapture::captureLayers(mCaptureArgs, mCaptureResults));
chaviwf5bb97b2021-04-28 15:35:37 -0500101 }
chaviw4b9d5e12020-08-04 18:30:35 -0700102
chaviw4b9d5e12020-08-04 18:30:35 -0700103 {
Chavi Weingartenf5fb5b02023-11-30 17:27:52 +0000104 UIDFaker f(AID_SYSTEM);
105
106 // By default the system can capture screenshots with secure layers but they
107 // will be blacked out
108 ASSERT_EQ(NO_ERROR, ScreenCapture::captureLayers(mCaptureArgs, mCaptureResults));
109
110 {
111 SCOPED_TRACE("as system");
112 auto shot = screenshot();
113 shot->expectColor(Rect(0, 0, 32, 32), Color::BLACK);
114 }
115
Alec Mouribae67862024-08-06 14:53:46 +0000116 mCaptureArgs.captureArgs.captureSecureLayers = true;
Chavi Weingartenf5fb5b02023-11-30 17:27:52 +0000117 // AID_SYSTEM is allowed to capture secure content.
118 ASSERT_EQ(NO_ERROR, ScreenCapture::captureLayers(mCaptureArgs, mCaptureResults));
119 ASSERT_TRUE(mCaptureResults.capturedSecureLayers);
120 ScreenCapture sc(mCaptureResults.buffer, mCaptureResults.capturedHdrLayers);
121 sc.expectColor(Rect(0, 0, 32, 32), Color::RED);
chaviw4b9d5e12020-08-04 18:30:35 -0700122 }
123
Chavi Weingartenf5fb5b02023-11-30 17:27:52 +0000124 {
125 // Attempt secure screenshot from shell since it doesn't have CAPTURE_BLACKOUT_CONTENT
126 // permission, but is allowed normal screenshots.
127 UIDFaker faker(AID_SHELL);
128 ASSERT_EQ(PERMISSION_DENIED, ScreenCapture::captureLayers(mCaptureArgs, mCaptureResults));
129 }
130
131 // Remove flag secure from the layer.
132 Transaction().setFlags(layer, 0, layer_state_t::eLayerSecure).apply(true);
133 {
134 // Assert that screenshot fails without CAPTURE_BLACKOUT_CONTENT when requesting
135 // captureSecureLayers even if there are no actual secure layers on screen.
136 UIDFaker faker(AID_SHELL);
137 ASSERT_EQ(PERMISSION_DENIED, ScreenCapture::captureLayers(mCaptureArgs, mCaptureResults));
138 }
chaviw4b9d5e12020-08-04 18:30:35 -0700139}
140
Garfield Tande619fa2020-10-02 17:13:53 -0700141TEST_F(ScreenCaptureTest, CaptureChildSetParentFlagsSecureEUidSystem) {
142 sp<SurfaceControl> parentLayer;
143 ASSERT_NO_FATAL_FAILURE(
144 parentLayer = createLayer("parent-test", 32, 32,
145 ISurfaceComposerClient::eSecure |
Melody Hsue69bb172023-10-27 13:51:17 +0000146 ISurfaceComposerClient::eFXSurfaceBufferQueue,
147 mRootSurfaceControl.get()));
Garfield Tande619fa2020-10-02 17:13:53 -0700148 ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(parentLayer, Color::RED, 32, 32));
149
150 sp<SurfaceControl> childLayer;
151 ASSERT_NO_FATAL_FAILURE(childLayer = createLayer("child-test", 10, 10,
152 ISurfaceComposerClient::eFXSurfaceBufferQueue,
153 parentLayer.get()));
154 ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(childLayer, Color::BLUE, 10, 10));
155
156 Transaction().show(parentLayer).setLayer(parentLayer, INT32_MAX).show(childLayer).apply(true);
157
158 UIDFaker f(AID_SYSTEM);
159
160 {
161 SCOPED_TRACE("as system");
162 auto shot = screenshot();
163 shot->expectColor(Rect(0, 0, 10, 10), Color::BLACK);
164 }
165
166 // Here we pass captureSecureLayers = true and since we are AID_SYSTEM we should be able
167 // to receive them...we are expected to take care with the results.
Alec Mouribae67862024-08-06 14:53:46 +0000168 mCaptureArgs.captureArgs.captureSecureLayers = true;
Melody Hsue69bb172023-10-27 13:51:17 +0000169 ASSERT_EQ(NO_ERROR, ScreenCapture::captureLayers(mCaptureArgs, mCaptureResults));
Garfield Tande619fa2020-10-02 17:13:53 -0700170 ASSERT_TRUE(mCaptureResults.capturedSecureLayers);
Alec Mouri14d5b862022-04-27 21:20:04 +0000171 ScreenCapture sc(mCaptureResults.buffer, mCaptureResults.capturedHdrLayers);
Garfield Tande619fa2020-10-02 17:13:53 -0700172 sc.expectColor(Rect(0, 0, 10, 10), Color::BLUE);
173}
174
Chavi Weingarten4aa22af2023-11-17 19:37:07 +0000175/**
176 * If a parent layer sets the secure flag, but the screenshot requests is for the child hierarchy,
177 * we need to ensure the secure flag is respected from the parent even though the parent isn't
178 * in the captured sub-hierarchy
179 */
180TEST_F(ScreenCaptureTest, CaptureChildRespectsParentSecureFlag) {
181 Rect size(0, 0, 100, 100);
182 Transaction().hide(mBGSurfaceControl).hide(mFGSurfaceControl).apply();
183 sp<SurfaceControl> parentLayer;
184 ASSERT_NO_FATAL_FAILURE(parentLayer = createLayer("parent-test", 0, 0,
185 ISurfaceComposerClient::eHidden,
186 mRootSurfaceControl.get()));
187
188 sp<SurfaceControl> childLayer;
189 ASSERT_NO_FATAL_FAILURE(childLayer = createLayer("child-test", 0, 0,
190 ISurfaceComposerClient::eFXSurfaceBufferState,
191 parentLayer.get()));
192 ASSERT_NO_FATAL_FAILURE(
193 fillBufferLayerColor(childLayer, Color::GREEN, size.width(), size.height()));
194
195 // hide the parent layer to ensure secure flag is passed down to child when screenshotting
196 Transaction().setLayer(parentLayer, INT32_MAX).show(childLayer).apply(true);
197 Transaction()
198 .setFlags(parentLayer, layer_state_t::eLayerSecure, layer_state_t::eLayerSecure)
199 .apply();
200 LayerCaptureArgs captureArgs;
201 captureArgs.layerHandle = childLayer->getHandle();
Alec Mouribae67862024-08-06 14:53:46 +0000202 captureArgs.captureArgs.sourceCrop = gui::aidl_utils::toARect(size);
203 captureArgs.captureArgs.captureSecureLayers = false;
Chavi Weingarten4aa22af2023-11-17 19:37:07 +0000204 {
205 SCOPED_TRACE("parent hidden");
206 ASSERT_EQ(NO_ERROR, ScreenCapture::captureLayers(captureArgs, mCaptureResults));
207 ASSERT_TRUE(mCaptureResults.capturedSecureLayers);
208 ScreenCapture sc(mCaptureResults.buffer, mCaptureResults.capturedHdrLayers);
209 sc.expectColor(size, Color::BLACK);
210 }
211
Alec Mouribae67862024-08-06 14:53:46 +0000212 captureArgs.captureArgs.captureSecureLayers = true;
Chavi Weingarten4aa22af2023-11-17 19:37:07 +0000213 {
214 SCOPED_TRACE("capture secure parent not visible");
215 ASSERT_EQ(NO_ERROR, ScreenCapture::captureLayers(captureArgs, mCaptureResults));
216 ASSERT_TRUE(mCaptureResults.capturedSecureLayers);
217 ScreenCapture sc(mCaptureResults.buffer, mCaptureResults.capturedHdrLayers);
218 sc.expectColor(size, Color::GREEN);
219 }
220
221 Transaction().show(parentLayer).apply();
Alec Mouribae67862024-08-06 14:53:46 +0000222 captureArgs.captureArgs.captureSecureLayers = false;
Chavi Weingarten4aa22af2023-11-17 19:37:07 +0000223 {
224 SCOPED_TRACE("parent visible");
225 ASSERT_EQ(NO_ERROR, ScreenCapture::captureLayers(captureArgs, mCaptureResults));
226 ASSERT_TRUE(mCaptureResults.capturedSecureLayers);
227 ScreenCapture sc(mCaptureResults.buffer, mCaptureResults.capturedHdrLayers);
228 sc.expectColor(size, Color::BLACK);
229 }
230
Alec Mouribae67862024-08-06 14:53:46 +0000231 captureArgs.captureArgs.captureSecureLayers = true;
Chavi Weingarten4aa22af2023-11-17 19:37:07 +0000232 {
233 SCOPED_TRACE("capture secure parent visible");
234 ASSERT_EQ(NO_ERROR, ScreenCapture::captureLayers(captureArgs, mCaptureResults));
235 ASSERT_TRUE(mCaptureResults.capturedSecureLayers);
236 ScreenCapture sc(mCaptureResults.buffer, mCaptureResults.capturedHdrLayers);
237 sc.expectColor(size, Color::GREEN);
238 }
239}
240
241TEST_F(ScreenCaptureTest, CaptureOffscreenChildRespectsParentSecureFlag) {
242 Rect size(0, 0, 100, 100);
243 Transaction().hide(mBGSurfaceControl).hide(mFGSurfaceControl).apply();
244 // Parent layer should be offscreen.
245 sp<SurfaceControl> parentLayer;
246 ASSERT_NO_FATAL_FAILURE(
247 parentLayer = createLayer("parent-test", 0, 0, ISurfaceComposerClient::eHidden));
248
249 sp<SurfaceControl> childLayer;
250 ASSERT_NO_FATAL_FAILURE(childLayer = createLayer("child-test", 0, 0,
251 ISurfaceComposerClient::eFXSurfaceBufferState,
252 parentLayer.get()));
253 ASSERT_NO_FATAL_FAILURE(
254 fillBufferLayerColor(childLayer, Color::GREEN, size.width(), size.height()));
255
256 // hide the parent layer to ensure secure flag is passed down to child when screenshotting
257 Transaction().setLayer(parentLayer, INT32_MAX).show(childLayer).apply(true);
258 Transaction()
259 .setFlags(parentLayer, layer_state_t::eLayerSecure, layer_state_t::eLayerSecure)
260 .apply();
261 LayerCaptureArgs captureArgs;
262 captureArgs.layerHandle = childLayer->getHandle();
Alec Mouribae67862024-08-06 14:53:46 +0000263 captureArgs.captureArgs.sourceCrop = gui::aidl_utils::toARect(size);
264 captureArgs.captureArgs.captureSecureLayers = false;
Chavi Weingarten4aa22af2023-11-17 19:37:07 +0000265 {
266 SCOPED_TRACE("parent hidden");
267 ASSERT_EQ(NO_ERROR, ScreenCapture::captureLayers(captureArgs, mCaptureResults));
268 ASSERT_TRUE(mCaptureResults.capturedSecureLayers);
269 ScreenCapture sc(mCaptureResults.buffer, mCaptureResults.capturedHdrLayers);
270 sc.expectColor(size, Color::BLACK);
271 }
272
Alec Mouribae67862024-08-06 14:53:46 +0000273 captureArgs.captureArgs.captureSecureLayers = true;
Chavi Weingarten4aa22af2023-11-17 19:37:07 +0000274 {
275 SCOPED_TRACE("capture secure parent not visible");
276 ASSERT_EQ(NO_ERROR, ScreenCapture::captureLayers(captureArgs, mCaptureResults));
277 ASSERT_TRUE(mCaptureResults.capturedSecureLayers);
278 ScreenCapture sc(mCaptureResults.buffer, mCaptureResults.capturedHdrLayers);
279 sc.expectColor(size, Color::GREEN);
280 }
281
282 Transaction().show(parentLayer).apply();
Alec Mouribae67862024-08-06 14:53:46 +0000283 captureArgs.captureArgs.captureSecureLayers = false;
Chavi Weingarten4aa22af2023-11-17 19:37:07 +0000284 {
285 SCOPED_TRACE("parent visible");
286 ASSERT_EQ(NO_ERROR, ScreenCapture::captureLayers(captureArgs, mCaptureResults));
287 ASSERT_TRUE(mCaptureResults.capturedSecureLayers);
288 ScreenCapture sc(mCaptureResults.buffer, mCaptureResults.capturedHdrLayers);
289 sc.expectColor(size, Color::BLACK);
290 }
291
Alec Mouribae67862024-08-06 14:53:46 +0000292 captureArgs.captureArgs.captureSecureLayers = true;
Chavi Weingarten4aa22af2023-11-17 19:37:07 +0000293 {
294 SCOPED_TRACE("capture secure parent visible");
295 ASSERT_EQ(NO_ERROR, ScreenCapture::captureLayers(captureArgs, mCaptureResults));
296 ASSERT_TRUE(mCaptureResults.capturedSecureLayers);
297 ScreenCapture sc(mCaptureResults.buffer, mCaptureResults.capturedHdrLayers);
298 sc.expectColor(size, Color::GREEN);
299 }
300}
301
chaviw3efadb12020-07-27 10:07:15 -0700302TEST_F(ScreenCaptureTest, CaptureSingleLayer) {
chaviw70cb6a42020-07-30 13:57:36 -0700303 LayerCaptureArgs captureArgs;
304 captureArgs.layerHandle = mBGSurfaceControl->getHandle();
305 ScreenCapture::captureLayers(&mCapture, captureArgs);
chaviw3efadb12020-07-27 10:07:15 -0700306 mCapture->expectBGColor(0, 0);
307 // Doesn't capture FG layer which is at 64, 64
308 mCapture->expectBGColor(64, 64);
309}
310
311TEST_F(ScreenCaptureTest, CaptureLayerWithChild) {
chaviw3efadb12020-07-27 10:07:15 -0700312 sp<SurfaceControl> child = createSurface(mClient, "Child surface", 10, 10,
313 PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
314 TransactionUtils::fillSurfaceRGBA8(child, 200, 200, 200);
315
316 SurfaceComposerClient::Transaction().show(child).apply(true);
317
318 // Captures mFGSurfaceControl layer and its child.
chaviw70cb6a42020-07-30 13:57:36 -0700319 LayerCaptureArgs captureArgs;
320 captureArgs.layerHandle = mFGSurfaceControl->getHandle();
321 ScreenCapture::captureLayers(&mCapture, captureArgs);
chaviw3efadb12020-07-27 10:07:15 -0700322 mCapture->expectFGColor(10, 10);
323 mCapture->expectChildColor(0, 0);
324}
325
326TEST_F(ScreenCaptureTest, CaptureLayerChildOnly) {
327 auto fgHandle = mFGSurfaceControl->getHandle();
328
329 sp<SurfaceControl> child = createSurface(mClient, "Child surface", 10, 10,
330 PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
331 TransactionUtils::fillSurfaceRGBA8(child, 200, 200, 200);
332
333 SurfaceComposerClient::Transaction().show(child).apply(true);
334
335 // Captures mFGSurfaceControl's child
chaviw70cb6a42020-07-30 13:57:36 -0700336 LayerCaptureArgs captureArgs;
337 captureArgs.layerHandle = fgHandle;
338 captureArgs.childrenOnly = true;
339 ScreenCapture::captureLayers(&mCapture, captureArgs);
chaviw3efadb12020-07-27 10:07:15 -0700340 mCapture->checkPixel(10, 10, 0, 0, 0);
341 mCapture->expectChildColor(0, 0);
342}
343
344TEST_F(ScreenCaptureTest, CaptureLayerExclude) {
345 auto fgHandle = mFGSurfaceControl->getHandle();
346
347 sp<SurfaceControl> child = createSurface(mClient, "Child surface", 10, 10,
348 PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
349 TransactionUtils::fillSurfaceRGBA8(child, 200, 200, 200);
350 sp<SurfaceControl> child2 = createSurface(mClient, "Child surface", 10, 10,
351 PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
352 TransactionUtils::fillSurfaceRGBA8(child2, 200, 0, 200);
353
354 SurfaceComposerClient::Transaction()
355 .show(child)
356 .show(child2)
357 .setLayer(child, 1)
358 .setLayer(child2, 2)
359 .apply(true);
360
361 // Child2 would be visible but its excluded, so we should see child1 color instead.
chaviw70cb6a42020-07-30 13:57:36 -0700362 LayerCaptureArgs captureArgs;
363 captureArgs.layerHandle = fgHandle;
364 captureArgs.childrenOnly = true;
Alec Mouribae67862024-08-06 14:53:46 +0000365 captureArgs.captureArgs.excludeHandles = {child2->getHandle()};
chaviw70cb6a42020-07-30 13:57:36 -0700366 ScreenCapture::captureLayers(&mCapture, captureArgs);
chaviw3efadb12020-07-27 10:07:15 -0700367 mCapture->checkPixel(10, 10, 0, 0, 0);
368 mCapture->checkPixel(0, 0, 200, 200, 200);
369}
370
Ajinkya Chalke02844632023-03-01 12:10:14 +0000371TEST_F(ScreenCaptureTest, CaptureLayerExcludeThroughDisplayArgs) {
Alec Mouribae67862024-08-06 14:53:46 +0000372 mCaptureArgs.captureArgs.excludeHandles = {mFGSurfaceControl->getHandle()};
Melody Hsue69bb172023-10-27 13:51:17 +0000373 ScreenCapture::captureLayers(&mCapture, mCaptureArgs);
Ajinkya Chalke02844632023-03-01 12:10:14 +0000374 mCapture->expectBGColor(0, 0);
375 // Doesn't capture FG layer which is at 64, 64
376 mCapture->expectBGColor(64, 64);
377}
378
chaviw3efadb12020-07-27 10:07:15 -0700379// Like the last test but verifies that children are also exclude.
380TEST_F(ScreenCaptureTest, CaptureLayerExcludeTree) {
381 auto fgHandle = mFGSurfaceControl->getHandle();
382
383 sp<SurfaceControl> child = createSurface(mClient, "Child surface", 10, 10,
384 PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
385 TransactionUtils::fillSurfaceRGBA8(child, 200, 200, 200);
386 sp<SurfaceControl> child2 = createSurface(mClient, "Child surface", 10, 10,
387 PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
388 TransactionUtils::fillSurfaceRGBA8(child2, 200, 0, 200);
389 sp<SurfaceControl> child3 = createSurface(mClient, "Child surface", 10, 10,
390 PIXEL_FORMAT_RGBA_8888, 0, child2.get());
391 TransactionUtils::fillSurfaceRGBA8(child2, 200, 0, 200);
392
393 SurfaceComposerClient::Transaction()
394 .show(child)
395 .show(child2)
396 .show(child3)
397 .setLayer(child, 1)
398 .setLayer(child2, 2)
399 .apply(true);
400
401 // Child2 would be visible but its excluded, so we should see child1 color instead.
chaviw70cb6a42020-07-30 13:57:36 -0700402 LayerCaptureArgs captureArgs;
403 captureArgs.layerHandle = fgHandle;
404 captureArgs.childrenOnly = true;
Alec Mouribae67862024-08-06 14:53:46 +0000405 captureArgs.captureArgs.excludeHandles = {child2->getHandle()};
chaviw70cb6a42020-07-30 13:57:36 -0700406 ScreenCapture::captureLayers(&mCapture, captureArgs);
chaviw3efadb12020-07-27 10:07:15 -0700407 mCapture->checkPixel(10, 10, 0, 0, 0);
408 mCapture->checkPixel(0, 0, 200, 200, 200);
409}
410
411TEST_F(ScreenCaptureTest, CaptureTransparent) {
412 sp<SurfaceControl> child = createSurface(mClient, "Child surface", 10, 10,
413 PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
414
415 TransactionUtils::fillSurfaceRGBA8(child, 200, 200, 200);
416
417 SurfaceComposerClient::Transaction().show(child).apply(true);
418
chaviw3efadb12020-07-27 10:07:15 -0700419 // Captures child
chaviw70cb6a42020-07-30 13:57:36 -0700420 LayerCaptureArgs captureArgs;
421 captureArgs.layerHandle = child->getHandle();
Alec Mouribae67862024-08-06 14:53:46 +0000422 captureArgs.captureArgs.sourceCrop = gui::aidl_utils::toARect(10, 20);
chaviw70cb6a42020-07-30 13:57:36 -0700423 ScreenCapture::captureLayers(&mCapture, captureArgs);
chaviw3efadb12020-07-27 10:07:15 -0700424 mCapture->expectColor(Rect(0, 0, 9, 9), {200, 200, 200, 255});
425 // Area outside of child's bounds is transparent.
426 mCapture->expectColor(Rect(0, 10, 9, 19), {0, 0, 0, 0});
427}
428
429TEST_F(ScreenCaptureTest, DontCaptureRelativeOutsideTree) {
chaviw3efadb12020-07-27 10:07:15 -0700430 sp<SurfaceControl> child = createSurface(mClient, "Child surface", 10, 10,
431 PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
432 ASSERT_NE(nullptr, child.get()) << "failed to create surface";
433 sp<SurfaceControl> relative = createLayer(String8("Relative surface"), 10, 10, 0);
434 TransactionUtils::fillSurfaceRGBA8(child, 200, 200, 200);
435 TransactionUtils::fillSurfaceRGBA8(relative, 100, 100, 100);
436
437 SurfaceComposerClient::Transaction()
438 .show(child)
439 // Set relative layer above fg layer so should be shown above when computing all layers.
Pablo Gamito11dcc222020-09-12 15:49:39 +0000440 .setRelativeLayer(relative, mFGSurfaceControl, 1)
chaviw3efadb12020-07-27 10:07:15 -0700441 .show(relative)
442 .apply(true);
443
444 // Captures mFGSurfaceControl layer and its child. Relative layer shouldn't be captured.
chaviw70cb6a42020-07-30 13:57:36 -0700445 LayerCaptureArgs captureArgs;
446 captureArgs.layerHandle = mFGSurfaceControl->getHandle();
447 ScreenCapture::captureLayers(&mCapture, captureArgs);
chaviw3efadb12020-07-27 10:07:15 -0700448 mCapture->expectFGColor(10, 10);
449 mCapture->expectChildColor(0, 0);
450}
451
452TEST_F(ScreenCaptureTest, CaptureRelativeInTree) {
chaviw3efadb12020-07-27 10:07:15 -0700453 sp<SurfaceControl> child = createSurface(mClient, "Child surface", 10, 10,
454 PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
455 sp<SurfaceControl> relative = createSurface(mClient, "Relative surface", 10, 10,
456 PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
457 TransactionUtils::fillSurfaceRGBA8(child, 200, 200, 200);
458 TransactionUtils::fillSurfaceRGBA8(relative, 100, 100, 100);
459
460 SurfaceComposerClient::Transaction()
461 .show(child)
462 // Set relative layer below fg layer but relative to child layer so it should be shown
463 // above child layer.
464 .setLayer(relative, -1)
Pablo Gamito11dcc222020-09-12 15:49:39 +0000465 .setRelativeLayer(relative, child, 1)
chaviw3efadb12020-07-27 10:07:15 -0700466 .show(relative)
467 .apply(true);
468
469 // Captures mFGSurfaceControl layer and its children. Relative layer is a child of fg so its
470 // relative value should be taken into account, placing it above child layer.
chaviw70cb6a42020-07-30 13:57:36 -0700471 LayerCaptureArgs captureArgs;
472 captureArgs.layerHandle = mFGSurfaceControl->getHandle();
473 ScreenCapture::captureLayers(&mCapture, captureArgs);
chaviw3efadb12020-07-27 10:07:15 -0700474 mCapture->expectFGColor(10, 10);
475 // Relative layer is showing on top of child layer
476 mCapture->expectColor(Rect(0, 0, 9, 9), {100, 100, 100, 255});
477}
478
479TEST_F(ScreenCaptureTest, CaptureBoundlessLayerWithSourceCrop) {
480 sp<SurfaceControl> child = createColorLayer("Child layer", Color::RED, mFGSurfaceControl.get());
481 SurfaceComposerClient::Transaction().show(child).apply(true);
482
chaviw70cb6a42020-07-30 13:57:36 -0700483 LayerCaptureArgs captureArgs;
484 captureArgs.layerHandle = child->getHandle();
Alec Mouribae67862024-08-06 14:53:46 +0000485 captureArgs.captureArgs.sourceCrop = gui::aidl_utils::toARect(10, 10);
chaviw70cb6a42020-07-30 13:57:36 -0700486 ScreenCapture::captureLayers(&mCapture, captureArgs);
chaviw3efadb12020-07-27 10:07:15 -0700487
488 mCapture->expectColor(Rect(0, 0, 9, 9), Color::RED);
489}
490
491TEST_F(ScreenCaptureTest, CaptureBoundedLayerWithoutSourceCrop) {
492 sp<SurfaceControl> child = createColorLayer("Child layer", Color::RED, mFGSurfaceControl.get());
493 Rect layerCrop(0, 0, 10, 10);
chaviw25714502021-02-11 10:01:08 -0800494 SurfaceComposerClient::Transaction().setCrop(child, layerCrop).show(child).apply(true);
chaviw3efadb12020-07-27 10:07:15 -0700495
chaviw70cb6a42020-07-30 13:57:36 -0700496 LayerCaptureArgs captureArgs;
497 captureArgs.layerHandle = child->getHandle();
498 ScreenCapture::captureLayers(&mCapture, captureArgs);
chaviw3efadb12020-07-27 10:07:15 -0700499
500 mCapture->expectColor(Rect(0, 0, 9, 9), Color::RED);
501}
502
503TEST_F(ScreenCaptureTest, CaptureBoundlessLayerWithoutSourceCropFails) {
504 sp<SurfaceControl> child = createColorLayer("Child layer", Color::RED, mFGSurfaceControl.get());
505 SurfaceComposerClient::Transaction().show(child).apply(true);
506
chaviw3efadb12020-07-27 10:07:15 -0700507 LayerCaptureArgs args;
508 args.layerHandle = child->getHandle();
509
510 ScreenCaptureResults captureResults;
chaviw8ffc7b82020-08-18 11:25:37 -0700511 ASSERT_EQ(BAD_VALUE, ScreenCapture::captureLayers(args, captureResults));
chaviw3efadb12020-07-27 10:07:15 -0700512}
513
514TEST_F(ScreenCaptureTest, CaptureBufferLayerWithoutBufferFails) {
515 sp<SurfaceControl> child = createSurface(mClient, "Child surface", 10, 10,
Robert Carr5b3b9142021-02-22 12:27:32 -0800516 PIXEL_FORMAT_RGBA_8888,
517 ISurfaceComposerClient::eFXSurfaceBufferState,
518 mFGSurfaceControl.get());
519
chaviw3efadb12020-07-27 10:07:15 -0700520 SurfaceComposerClient::Transaction().show(child).apply(true);
chaviw3efadb12020-07-27 10:07:15 -0700521 sp<GraphicBuffer> outBuffer;
522
523 LayerCaptureArgs args;
524 args.layerHandle = child->getHandle();
525 args.childrenOnly = false;
526
527 ScreenCaptureResults captureResults;
chaviw8ffc7b82020-08-18 11:25:37 -0700528 ASSERT_EQ(BAD_VALUE, ScreenCapture::captureLayers(args, captureResults));
chaviw3efadb12020-07-27 10:07:15 -0700529
Patrick Williams83f36b22022-09-14 17:57:35 +0000530 ASSERT_NO_FATAL_FAILURE(fillBufferLayerColor(child, Color::RED, 32, 32));
chaviw3efadb12020-07-27 10:07:15 -0700531 SurfaceComposerClient::Transaction().apply(true);
chaviw8ffc7b82020-08-18 11:25:37 -0700532 ASSERT_EQ(NO_ERROR, ScreenCapture::captureLayers(args, captureResults));
Alec Mouri14d5b862022-04-27 21:20:04 +0000533 ScreenCapture sc(captureResults.buffer, captureResults.capturedHdrLayers);
chaviw3efadb12020-07-27 10:07:15 -0700534 sc.expectColor(Rect(0, 0, 9, 9), Color::RED);
535}
536
537TEST_F(ScreenCaptureTest, CaptureLayerWithGrandchild) {
chaviw3efadb12020-07-27 10:07:15 -0700538 sp<SurfaceControl> child = createSurface(mClient, "Child surface", 10, 10,
539 PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
540 TransactionUtils::fillSurfaceRGBA8(child, 200, 200, 200);
541
542 sp<SurfaceControl> grandchild = createSurface(mClient, "Grandchild surface", 5, 5,
543 PIXEL_FORMAT_RGBA_8888, 0, child.get());
544
545 TransactionUtils::fillSurfaceRGBA8(grandchild, 50, 50, 50);
546 SurfaceComposerClient::Transaction()
547 .show(child)
548 .setPosition(grandchild, 5, 5)
549 .show(grandchild)
550 .apply(true);
551
552 // Captures mFGSurfaceControl, its child, and the grandchild.
chaviw70cb6a42020-07-30 13:57:36 -0700553 LayerCaptureArgs captureArgs;
554 captureArgs.layerHandle = mFGSurfaceControl->getHandle();
555 ScreenCapture::captureLayers(&mCapture, captureArgs);
chaviw3efadb12020-07-27 10:07:15 -0700556 mCapture->expectFGColor(10, 10);
557 mCapture->expectChildColor(0, 0);
558 mCapture->checkPixel(5, 5, 50, 50, 50);
559}
560
561TEST_F(ScreenCaptureTest, CaptureChildOnly) {
562 sp<SurfaceControl> child = createSurface(mClient, "Child surface", 10, 10,
563 PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
564 TransactionUtils::fillSurfaceRGBA8(child, 200, 200, 200);
chaviw3efadb12020-07-27 10:07:15 -0700565
566 SurfaceComposerClient::Transaction().setPosition(child, 5, 5).show(child).apply(true);
567
568 // Captures only the child layer, and not the parent.
chaviw70cb6a42020-07-30 13:57:36 -0700569 LayerCaptureArgs captureArgs;
570 captureArgs.layerHandle = child->getHandle();
571 ScreenCapture::captureLayers(&mCapture, captureArgs);
chaviw3efadb12020-07-27 10:07:15 -0700572 mCapture->expectChildColor(0, 0);
573 mCapture->expectChildColor(9, 9);
574}
575
576TEST_F(ScreenCaptureTest, CaptureGrandchildOnly) {
577 sp<SurfaceControl> child = createSurface(mClient, "Child surface", 10, 10,
578 PIXEL_FORMAT_RGBA_8888, 0, mFGSurfaceControl.get());
579 TransactionUtils::fillSurfaceRGBA8(child, 200, 200, 200);
580 auto childHandle = child->getHandle();
581
582 sp<SurfaceControl> grandchild = createSurface(mClient, "Grandchild surface", 5, 5,
583 PIXEL_FORMAT_RGBA_8888, 0, child.get());
584 TransactionUtils::fillSurfaceRGBA8(grandchild, 50, 50, 50);
585
586 SurfaceComposerClient::Transaction()
587 .show(child)
588 .setPosition(grandchild, 5, 5)
589 .show(grandchild)
590 .apply(true);
591
chaviw3efadb12020-07-27 10:07:15 -0700592 // Captures only the grandchild.
chaviw70cb6a42020-07-30 13:57:36 -0700593 LayerCaptureArgs captureArgs;
594 captureArgs.layerHandle = grandchild->getHandle();
595 ScreenCapture::captureLayers(&mCapture, captureArgs);
chaviw3efadb12020-07-27 10:07:15 -0700596 mCapture->checkPixel(0, 0, 50, 50, 50);
597 mCapture->checkPixel(4, 4, 50, 50, 50);
598}
599
600TEST_F(ScreenCaptureTest, CaptureCrop) {
Robert Carr5b3b9142021-02-22 12:27:32 -0800601 sp<SurfaceControl> redLayer = createLayer(String8("Red surface"), 60, 60,
602 ISurfaceComposerClient::eFXSurfaceBufferState);
chaviw3efadb12020-07-27 10:07:15 -0700603 sp<SurfaceControl> blueLayer = createSurface(mClient, "Blue surface", 30, 30,
Robert Carr5b3b9142021-02-22 12:27:32 -0800604 PIXEL_FORMAT_RGBA_8888,
605 ISurfaceComposerClient::eFXSurfaceBufferState,
606 redLayer.get());
chaviw3efadb12020-07-27 10:07:15 -0700607
Patrick Williams83f36b22022-09-14 17:57:35 +0000608 ASSERT_NO_FATAL_FAILURE(fillBufferLayerColor(redLayer, Color::RED, 60, 60));
609 ASSERT_NO_FATAL_FAILURE(fillBufferLayerColor(blueLayer, Color::BLUE, 30, 30));
chaviw3efadb12020-07-27 10:07:15 -0700610
611 SurfaceComposerClient::Transaction()
612 .setLayer(redLayer, INT32_MAX - 1)
613 .show(redLayer)
614 .show(blueLayer)
615 .apply(true);
616
chaviw3efadb12020-07-27 10:07:15 -0700617 // Capturing full screen should have both red and blue are visible.
chaviw70cb6a42020-07-30 13:57:36 -0700618 LayerCaptureArgs captureArgs;
619 captureArgs.layerHandle = redLayer->getHandle();
620 ScreenCapture::captureLayers(&mCapture, captureArgs);
chaviw3efadb12020-07-27 10:07:15 -0700621 mCapture->expectColor(Rect(0, 0, 29, 29), Color::BLUE);
622 // red area below the blue area
623 mCapture->expectColor(Rect(0, 30, 59, 59), Color::RED);
624 // red area to the right of the blue area
625 mCapture->expectColor(Rect(30, 0, 59, 59), Color::RED);
626
Alec Mouribae67862024-08-06 14:53:46 +0000627 captureArgs.captureArgs.sourceCrop = gui::aidl_utils::toARect(30, 30);
chaviw70cb6a42020-07-30 13:57:36 -0700628 ScreenCapture::captureLayers(&mCapture, captureArgs);
chaviw3efadb12020-07-27 10:07:15 -0700629 // Capturing the cropped screen, cropping out the shown red area, should leave only the blue
630 // area visible.
631 mCapture->expectColor(Rect(0, 0, 29, 29), Color::BLUE);
632 mCapture->checkPixel(30, 30, 0, 0, 0);
633}
634
635TEST_F(ScreenCaptureTest, CaptureSize) {
Robert Carr5b3b9142021-02-22 12:27:32 -0800636 sp<SurfaceControl> redLayer =
637 createLayer(String8("Red surface"), 60, 60, ISurfaceComposerClient::eFXSurfaceBufferState);
chaviw3efadb12020-07-27 10:07:15 -0700638 sp<SurfaceControl> blueLayer = createSurface(mClient, "Blue surface", 30, 30,
Robert Carr5b3b9142021-02-22 12:27:32 -0800639 PIXEL_FORMAT_RGBA_8888,
640 ISurfaceComposerClient::eFXSurfaceBufferState,
641 redLayer.get());
chaviw3efadb12020-07-27 10:07:15 -0700642
Patrick Williams83f36b22022-09-14 17:57:35 +0000643 ASSERT_NO_FATAL_FAILURE(fillBufferLayerColor(redLayer, Color::RED, 60, 60));
644 ASSERT_NO_FATAL_FAILURE(fillBufferLayerColor(blueLayer, Color::BLUE, 30, 30));
chaviw3efadb12020-07-27 10:07:15 -0700645
646 SurfaceComposerClient::Transaction()
647 .setLayer(redLayer, INT32_MAX - 1)
648 .show(redLayer)
649 .show(blueLayer)
650 .apply(true);
651
chaviw3efadb12020-07-27 10:07:15 -0700652 // Capturing full screen should have both red and blue are visible.
chaviw70cb6a42020-07-30 13:57:36 -0700653 LayerCaptureArgs captureArgs;
654 captureArgs.layerHandle = redLayer->getHandle();
655 ScreenCapture::captureLayers(&mCapture, captureArgs);
chaviw3efadb12020-07-27 10:07:15 -0700656 mCapture->expectColor(Rect(0, 0, 29, 29), Color::BLUE);
657 // red area below the blue area
658 mCapture->expectColor(Rect(0, 30, 59, 59), Color::RED);
659 // red area to the right of the blue area
660 mCapture->expectColor(Rect(30, 0, 59, 59), Color::RED);
661
Alec Mouribae67862024-08-06 14:53:46 +0000662 captureArgs.captureArgs.frameScaleX = 0.5f;
663 captureArgs.captureArgs.frameScaleY = 0.5f;
Robert Carr5b3b9142021-02-22 12:27:32 -0800664 sleep(1);
chaviw17ac24b2021-01-28 18:50:05 -0800665
chaviw70cb6a42020-07-30 13:57:36 -0700666 ScreenCapture::captureLayers(&mCapture, captureArgs);
chaviw3efadb12020-07-27 10:07:15 -0700667 // Capturing the downsized area (30x30) should leave both red and blue but in a smaller area.
668 mCapture->expectColor(Rect(0, 0, 14, 14), Color::BLUE);
669 // red area below the blue area
670 mCapture->expectColor(Rect(0, 15, 29, 29), Color::RED);
671 // red area to the right of the blue area
672 mCapture->expectColor(Rect(15, 0, 29, 29), Color::RED);
673 mCapture->checkPixel(30, 30, 0, 0, 0);
674}
675
676TEST_F(ScreenCaptureTest, CaptureInvalidLayer) {
chaviw3efadb12020-07-27 10:07:15 -0700677 LayerCaptureArgs args;
Ady Abrahamd11bade2022-08-01 16:18:03 -0700678 args.layerHandle = sp<BBinder>::make();
chaviw3efadb12020-07-27 10:07:15 -0700679
680 ScreenCaptureResults captureResults;
chaviw3efadb12020-07-27 10:07:15 -0700681 // Layer was deleted so captureLayers should fail with NAME_NOT_FOUND
chaviw8ffc7b82020-08-18 11:25:37 -0700682 ASSERT_EQ(NAME_NOT_FOUND, ScreenCapture::captureLayers(args, captureResults));
chaviw3efadb12020-07-27 10:07:15 -0700683}
684
Garfield Tan9c9c1912021-07-19 12:02:16 -0700685TEST_F(ScreenCaptureTest, CaptureTooLargeLayer) {
686 sp<SurfaceControl> redLayer = createLayer(String8("Red surface"), 60, 60);
687 ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(redLayer, Color::RED, 60, 60));
688
689 Transaction().show(redLayer).setLayer(redLayer, INT32_MAX).apply(true);
690
691 LayerCaptureArgs captureArgs;
692 captureArgs.layerHandle = redLayer->getHandle();
Alec Mouribae67862024-08-06 14:53:46 +0000693 captureArgs.captureArgs.frameScaleX = INT32_MAX / 60;
694 captureArgs.captureArgs.frameScaleY = INT32_MAX / 60;
Garfield Tan9c9c1912021-07-19 12:02:16 -0700695
696 ScreenCaptureResults captureResults;
697 ASSERT_EQ(BAD_VALUE, ScreenCapture::captureLayers(captureArgs, captureResults));
698}
699
chaviwf5bb97b2021-04-28 15:35:37 -0500700TEST_F(ScreenCaptureTest, CaptureSecureLayer) {
Robert Carr5b3b9142021-02-22 12:27:32 -0800701 sp<SurfaceControl> redLayer = createLayer(String8("Red surface"), 60, 60,
702 ISurfaceComposerClient::eFXSurfaceBufferState);
chaviw70cb6a42020-07-30 13:57:36 -0700703 sp<SurfaceControl> secureLayer =
704 createLayer(String8("Secure surface"), 30, 30,
705 ISurfaceComposerClient::eSecure |
Robert Carr5b3b9142021-02-22 12:27:32 -0800706 ISurfaceComposerClient::eFXSurfaceBufferState,
chaviw70cb6a42020-07-30 13:57:36 -0700707 redLayer.get());
Patrick Williams83f36b22022-09-14 17:57:35 +0000708 ASSERT_NO_FATAL_FAILURE(fillBufferLayerColor(redLayer, Color::RED, 60, 60));
709 ASSERT_NO_FATAL_FAILURE(fillBufferLayerColor(secureLayer, Color::BLUE, 30, 30));
chaviw70cb6a42020-07-30 13:57:36 -0700710
711 auto redLayerHandle = redLayer->getHandle();
712 Transaction()
713 .show(redLayer)
714 .show(secureLayer)
Dominik Laskowski29fa1462021-04-27 15:51:50 -0700715 .setLayerStack(redLayer, ui::DEFAULT_LAYER_STACK)
chaviw70cb6a42020-07-30 13:57:36 -0700716 .setLayer(redLayer, INT32_MAX)
717 .apply();
718
chaviw70cb6a42020-07-30 13:57:36 -0700719 LayerCaptureArgs args;
720 args.layerHandle = redLayerHandle;
721 args.childrenOnly = false;
722 ScreenCaptureResults captureResults;
723
chaviwf5bb97b2021-04-28 15:35:37 -0500724 {
725 // Ensure the UID is not root because root has all permissions
726 UIDFaker f(AID_APP_START);
727 // Call from outside system with secure layers will result in permission denied
728 ASSERT_EQ(PERMISSION_DENIED, ScreenCapture::captureLayers(args, captureResults));
729 }
chaviw70cb6a42020-07-30 13:57:36 -0700730
731 UIDFaker f(AID_SYSTEM);
732
733 // From system request, only red layer will be screenshot since the blue layer is secure.
734 // Black will be present where the secure layer is.
735 ScreenCapture::captureLayers(&mCapture, args);
736 mCapture->expectColor(Rect(0, 0, 30, 30), Color::BLACK);
737 mCapture->expectColor(Rect(30, 30, 60, 60), Color::RED);
738
739 // Passing flag secure so the blue layer should be screenshot too.
Alec Mouribae67862024-08-06 14:53:46 +0000740 args.captureArgs.captureSecureLayers = true;
chaviw70cb6a42020-07-30 13:57:36 -0700741 ScreenCapture::captureLayers(&mCapture, args);
742 mCapture->expectColor(Rect(0, 0, 30, 30), Color::BLUE);
743 mCapture->expectColor(Rect(30, 30, 60, 60), Color::RED);
744}
745
Melody Hsue69bb172023-10-27 13:51:17 +0000746TEST_F(ScreenCaptureTest, ScreenshotProtectedBuffer) {
747 const uint32_t bufferWidth = 60;
748 const uint32_t bufferHeight = 60;
chaviw4b9d5e12020-08-04 18:30:35 -0700749
Melody Hsue69bb172023-10-27 13:51:17 +0000750 sp<SurfaceControl> layer =
751 createLayer(String8("Colored surface"), bufferWidth, bufferHeight,
752 ISurfaceComposerClient::eFXSurfaceBufferState, mRootSurfaceControl.get());
chaviw4b9d5e12020-08-04 18:30:35 -0700753
Melody Hsue69bb172023-10-27 13:51:17 +0000754 Transaction().show(layer).setLayer(layer, INT32_MAX).apply(true);
chaviw4b9d5e12020-08-04 18:30:35 -0700755
Melody Hsue69bb172023-10-27 13:51:17 +0000756 sp<Surface> surface = layer->getSurface();
757 ASSERT_TRUE(surface != nullptr);
758 sp<ANativeWindow> anw(surface);
chaviw4b9d5e12020-08-04 18:30:35 -0700759
Melody Hsue69bb172023-10-27 13:51:17 +0000760 ASSERT_EQ(NO_ERROR, native_window_api_connect(anw.get(), NATIVE_WINDOW_API_CPU));
761 ASSERT_EQ(NO_ERROR, native_window_set_usage(anw.get(), GRALLOC_USAGE_PROTECTED));
chaviw4b9d5e12020-08-04 18:30:35 -0700762
Melody Hsue69bb172023-10-27 13:51:17 +0000763 int fenceFd;
764 ANativeWindowBuffer* buf = nullptr;
chaviw4b9d5e12020-08-04 18:30:35 -0700765
Melody Hsue69bb172023-10-27 13:51:17 +0000766 // End test if device does not support USAGE_PROTECTED
767 // b/309965549 This check does not exit the test when running on AVDs
768 status_t err = anw->dequeueBuffer(anw.get(), &buf, &fenceFd);
769 if (err) {
770 return;
771 }
772 anw->queueBuffer(anw.get(), buf, fenceFd);
chaviw4b9d5e12020-08-04 18:30:35 -0700773
Melody Hsue69bb172023-10-27 13:51:17 +0000774 // USAGE_PROTECTED buffer is read as a black screen
775 ScreenCaptureResults captureResults;
776 ASSERT_EQ(NO_ERROR, ScreenCapture::captureLayers(mCaptureArgs, captureResults));
chaviw4b9d5e12020-08-04 18:30:35 -0700777
Melody Hsue69bb172023-10-27 13:51:17 +0000778 ScreenCapture sc(captureResults.buffer, captureResults.capturedHdrLayers);
779 sc.expectColor(Rect(0, 0, bufferWidth, bufferHeight), Color::BLACK);
780
781 // Reading color data will expectedly result in crash, only check usage bit
782 // b/309965549 Checking that the usage bit is protected does not work for
783 // devices that do not support usage protected.
Alec Mouribae67862024-08-06 14:53:46 +0000784 mCaptureArgs.captureArgs.allowProtected = true;
Melody Hsue69bb172023-10-27 13:51:17 +0000785 ASSERT_EQ(NO_ERROR, ScreenCapture::captureLayers(mCaptureArgs, captureResults));
786 // ASSERT_EQ(GRALLOC_USAGE_PROTECTED, GRALLOC_USAGE_PROTECTED &
787 // captureResults.buffer->getUsage());
chaviw4b9d5e12020-08-04 18:30:35 -0700788}
789
Melody Hsue69bb172023-10-27 13:51:17 +0000790TEST_F(ScreenCaptureTest, CaptureLayer) {
chaviwc5676c62020-09-18 15:01:04 -0700791 sp<SurfaceControl> layer;
Melody Hsue69bb172023-10-27 13:51:17 +0000792 ASSERT_NO_FATAL_FAILURE(layer = createLayer("test layer", 0, 0,
793 ISurfaceComposerClient::eFXSurfaceEffect,
794 mRootSurfaceControl.get()));
chaviwc5676c62020-09-18 15:01:04 -0700795
796 const Color layerColor = Color::RED;
797 const Rect bounds = Rect(10, 10, 40, 40);
798
799 Transaction()
800 .show(layer)
801 .hide(mFGSurfaceControl)
chaviwc5676c62020-09-18 15:01:04 -0700802 .setLayer(layer, INT32_MAX)
803 .setColor(layer, {layerColor.r / 255, layerColor.g / 255, layerColor.b / 255})
chaviw25714502021-02-11 10:01:08 -0800804 .setCrop(layer, bounds)
chaviwc5676c62020-09-18 15:01:04 -0700805 .apply();
806
chaviwc5676c62020-09-18 15:01:04 -0700807 {
Melody Hsue69bb172023-10-27 13:51:17 +0000808 ScreenCapture::captureLayers(&mCapture, mCaptureArgs);
chaviwc5676c62020-09-18 15:01:04 -0700809 mCapture->expectColor(bounds, layerColor);
810 mCapture->expectBorder(bounds, {63, 63, 195, 255});
811 }
812
813 Transaction()
814 .setFlags(layer, layer_state_t::eLayerSkipScreenshot,
815 layer_state_t::eLayerSkipScreenshot)
816 .apply();
817
818 {
819 // Can't screenshot test layer since it now has flag
820 // eLayerSkipScreenshot
Melody Hsue69bb172023-10-27 13:51:17 +0000821 ScreenCapture::captureLayers(&mCapture, mCaptureArgs);
chaviwc5676c62020-09-18 15:01:04 -0700822 mCapture->expectColor(bounds, {63, 63, 195, 255});
823 mCapture->expectBorder(bounds, {63, 63, 195, 255});
824 }
825}
826
Melody Hsue69bb172023-10-27 13:51:17 +0000827TEST_F(ScreenCaptureTest, CaptureLayerChild) {
chaviwc5676c62020-09-18 15:01:04 -0700828 sp<SurfaceControl> layer;
829 sp<SurfaceControl> childLayer;
Melody Hsue69bb172023-10-27 13:51:17 +0000830 ASSERT_NO_FATAL_FAILURE(layer = createLayer("test layer", 0, 0,
831 ISurfaceComposerClient::eFXSurfaceEffect,
832 mRootSurfaceControl.get()));
chaviwc5676c62020-09-18 15:01:04 -0700833 ASSERT_NO_FATAL_FAILURE(childLayer = createLayer("test layer", 0, 0,
834 ISurfaceComposerClient::eFXSurfaceEffect,
835 layer.get()));
836
837 const Color layerColor = Color::RED;
838 const Color childColor = Color::BLUE;
839 const Rect bounds = Rect(10, 10, 40, 40);
840 const Rect childBounds = Rect(20, 20, 30, 30);
841
842 Transaction()
843 .show(layer)
844 .show(childLayer)
845 .hide(mFGSurfaceControl)
chaviwc5676c62020-09-18 15:01:04 -0700846 .setLayer(layer, INT32_MAX)
847 .setColor(layer, {layerColor.r / 255, layerColor.g / 255, layerColor.b / 255})
848 .setColor(childLayer, {childColor.r / 255, childColor.g / 255, childColor.b / 255})
chaviw25714502021-02-11 10:01:08 -0800849 .setCrop(layer, bounds)
850 .setCrop(childLayer, childBounds)
chaviwc5676c62020-09-18 15:01:04 -0700851 .apply();
852
chaviwc5676c62020-09-18 15:01:04 -0700853 {
Melody Hsue69bb172023-10-27 13:51:17 +0000854 ScreenCapture::captureLayers(&mCapture, mCaptureArgs);
chaviwc5676c62020-09-18 15:01:04 -0700855 mCapture->expectColor(childBounds, childColor);
856 mCapture->expectBorder(childBounds, layerColor);
857 mCapture->expectBorder(bounds, {63, 63, 195, 255});
858 }
859
860 Transaction()
861 .setFlags(layer, layer_state_t::eLayerSkipScreenshot,
862 layer_state_t::eLayerSkipScreenshot)
863 .apply();
864
865 {
866 // Can't screenshot child layer since the parent has the flag
867 // eLayerSkipScreenshot
Melody Hsue69bb172023-10-27 13:51:17 +0000868 ScreenCapture::captureLayers(&mCapture, mCaptureArgs);
chaviwc5676c62020-09-18 15:01:04 -0700869 mCapture->expectColor(childBounds, {63, 63, 195, 255});
870 mCapture->expectBorder(childBounds, {63, 63, 195, 255});
871 mCapture->expectBorder(bounds, {63, 63, 195, 255});
872 }
873}
874
chaviw4b9d5e12020-08-04 18:30:35 -0700875TEST_F(ScreenCaptureTest, CaptureLayerWithUid) {
876 uid_t fakeUid = 12345;
877
878 sp<SurfaceControl> layer;
879 ASSERT_NO_FATAL_FAILURE(layer = createLayer("test layer", 32, 32,
880 ISurfaceComposerClient::eFXSurfaceBufferQueue,
881 mBGSurfaceControl.get()));
882 ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(layer, Color::RED, 32, 32));
883
884 Transaction().show(layer).setLayer(layer, INT32_MAX).apply();
885
886 LayerCaptureArgs captureArgs;
887 captureArgs.layerHandle = mBGSurfaceControl->getHandle();
888 captureArgs.childrenOnly = false;
889
890 // Make sure red layer with the background layer is screenshot.
891 ScreenCapture::captureLayers(&mCapture, captureArgs);
892 mCapture->expectColor(Rect(0, 0, 32, 32), Color::RED);
893 mCapture->expectBorder(Rect(0, 0, 32, 32), {63, 63, 195, 255});
894
895 // From non system uid, can't request screenshot without a specified uid.
896 std::unique_ptr<UIDFaker> uidFaker = std::make_unique<UIDFaker>(fakeUid);
897
chaviw8ffc7b82020-08-18 11:25:37 -0700898 ASSERT_EQ(PERMISSION_DENIED, ScreenCapture::captureLayers(captureArgs, mCaptureResults));
chaviw4b9d5e12020-08-04 18:30:35 -0700899
900 // Make screenshot request with current uid set. No layers were created with the current
901 // uid so screenshot will be black.
Alec Mouribae67862024-08-06 14:53:46 +0000902 captureArgs.captureArgs.uid = fakeUid;
chaviw4b9d5e12020-08-04 18:30:35 -0700903 ScreenCapture::captureLayers(&mCapture, captureArgs);
904 mCapture->expectColor(Rect(0, 0, 32, 32), Color::TRANSPARENT);
905 mCapture->expectBorder(Rect(0, 0, 32, 32), Color::TRANSPARENT);
906
907 sp<SurfaceControl> layerWithFakeUid;
908 // Create a new layer with the current uid
909 ASSERT_NO_FATAL_FAILURE(layerWithFakeUid =
910 createLayer("new test layer", 32, 32,
911 ISurfaceComposerClient::eFXSurfaceBufferQueue,
912 mBGSurfaceControl.get()));
913 ASSERT_NO_FATAL_FAILURE(fillBufferQueueLayerColor(layerWithFakeUid, Color::GREEN, 32, 32));
914 Transaction()
915 .show(layerWithFakeUid)
916 .setLayer(layerWithFakeUid, INT32_MAX)
917 .setPosition(layerWithFakeUid, 128, 128)
918 // reparent a layer that was created with a different uid to the new layer.
Pablo Gamito11dcc222020-09-12 15:49:39 +0000919 .reparent(layer, layerWithFakeUid)
chaviw4b9d5e12020-08-04 18:30:35 -0700920 .apply();
921
922 // Screenshot from the fakeUid caller with the uid requested allows the layer
923 // with that uid to be screenshotted. The child layer is skipped since it was created
924 // from a different uid.
925 ScreenCapture::captureLayers(&mCapture, captureArgs);
926 mCapture->expectColor(Rect(128, 128, 160, 160), Color::GREEN);
927 mCapture->expectBorder(Rect(128, 128, 160, 160), Color::TRANSPARENT);
928
929 // Clear fake calling uid so it's back to system.
930 uidFaker = nullptr;
931 // Screenshot from the test caller with the uid requested allows the layer
932 // with that uid to be screenshotted. The child layer is skipped since it was created
933 // from a different uid.
934 ScreenCapture::captureLayers(&mCapture, captureArgs);
935 mCapture->expectColor(Rect(128, 128, 160, 160), Color::GREEN);
936 mCapture->expectBorder(Rect(128, 128, 160, 160), Color::TRANSPARENT);
937
938 // Screenshot from the fakeUid caller with no uid requested allows everything to be screenshot.
Alec Mouribae67862024-08-06 14:53:46 +0000939 captureArgs.captureArgs.uid = -1;
chaviw4b9d5e12020-08-04 18:30:35 -0700940 ScreenCapture::captureLayers(&mCapture, captureArgs);
941 mCapture->expectColor(Rect(128, 128, 160, 160), Color::RED);
942 mCapture->expectBorder(Rect(128, 128, 160, 160), {63, 63, 195, 255});
943}
944
chaviw17ac24b2021-01-28 18:50:05 -0800945TEST_F(ScreenCaptureTest, CaptureWithGrayscale) {
946 sp<SurfaceControl> layer;
947 ASSERT_NO_FATAL_FAILURE(layer = createLayer("test layer", 32, 32,
948 ISurfaceComposerClient::eFXSurfaceBufferState,
949 mBGSurfaceControl.get()));
Patrick Williams83f36b22022-09-14 17:57:35 +0000950 ASSERT_NO_FATAL_FAILURE(fillBufferLayerColor(layer, Color::RED, 32, 32));
chaviw17ac24b2021-01-28 18:50:05 -0800951 Transaction().show(layer).setLayer(layer, INT32_MAX).apply();
952
953 LayerCaptureArgs captureArgs;
954 captureArgs.layerHandle = layer->getHandle();
955
956 ScreenCapture::captureLayers(&mCapture, captureArgs);
957 mCapture->expectColor(Rect(0, 0, 32, 32), Color::RED);
958
Alec Mouribae67862024-08-06 14:53:46 +0000959 captureArgs.captureArgs.grayscale = true;
chaviw17ac24b2021-01-28 18:50:05 -0800960
961 const uint8_t tolerance = 1;
962
963 // Values based on SurfaceFlinger::calculateColorMatrix
964 float3 luminance{0.213f, 0.715f, 0.072f};
965
966 ScreenCapture::captureLayers(&mCapture, captureArgs);
967
968 uint8_t expectedColor = luminance.r * 255;
969 mCapture->expectColor(Rect(0, 0, 32, 32),
970 Color{expectedColor, expectedColor, expectedColor, 255}, tolerance);
971
Patrick Williams83f36b22022-09-14 17:57:35 +0000972 ASSERT_NO_FATAL_FAILURE(fillBufferLayerColor(layer, Color::BLUE, 32, 32));
chaviw17ac24b2021-01-28 18:50:05 -0800973 ScreenCapture::captureLayers(&mCapture, captureArgs);
974
975 expectedColor = luminance.b * 255;
976 mCapture->expectColor(Rect(0, 0, 32, 32),
977 Color{expectedColor, expectedColor, expectedColor, 255}, tolerance);
978}
979
chaviw79468ab2021-10-27 11:11:24 -0500980TEST_F(ScreenCaptureTest, CaptureOffscreen) {
981 sp<SurfaceControl> layer;
982 ASSERT_NO_FATAL_FAILURE(layer = createLayer("test layer", 32, 32,
983 ISurfaceComposerClient::eFXSurfaceBufferState,
984 mBGSurfaceControl.get()));
Patrick Williams83f36b22022-09-14 17:57:35 +0000985 ASSERT_NO_FATAL_FAILURE(fillBufferLayerColor(layer, Color::RED, 32, 32));
chaviw79468ab2021-10-27 11:11:24 -0500986
987 Transaction().show(layer).hide(mFGSurfaceControl).reparent(layer, nullptr).apply();
988
chaviw79468ab2021-10-27 11:11:24 -0500989 {
990 // Validate that the red layer is not on screen
Melody Hsue69bb172023-10-27 13:51:17 +0000991 ScreenCapture::captureLayers(&mCapture, mCaptureArgs);
992 mCapture->expectColor(Rect(0, 0, mDisplayWidth, mDisplayHeight), {63, 63, 195, 255});
chaviw79468ab2021-10-27 11:11:24 -0500993 }
994
995 LayerCaptureArgs captureArgs;
996 captureArgs.layerHandle = layer->getHandle();
997
998 ScreenCapture::captureLayers(&mCapture, captureArgs);
999 mCapture->expectSize(32, 32);
1000 mCapture->expectColor(Rect(0, 0, 32, 32), Color::RED);
1001}
1002
Alec Mouri14d5b862022-04-27 21:20:04 +00001003TEST_F(ScreenCaptureTest, CaptureNonHdrLayer) {
1004 sp<SurfaceControl> layer;
1005 ASSERT_NO_FATAL_FAILURE(layer = createLayer("test layer", 32, 32,
1006 ISurfaceComposerClient::eFXSurfaceBufferState,
1007 mBGSurfaceControl.get()));
Patrick Williams83f36b22022-09-14 17:57:35 +00001008 ASSERT_NO_FATAL_FAILURE(fillBufferLayerColor(layer, Color::BLACK, 32, 32));
Alec Mouri14d5b862022-04-27 21:20:04 +00001009 Transaction()
1010 .show(layer)
1011 .setLayer(layer, INT32_MAX)
1012 .setDataspace(layer, ui::Dataspace::V0_SRGB)
1013 .apply();
1014
1015 LayerCaptureArgs captureArgs;
1016 captureArgs.layerHandle = layer->getHandle();
1017
1018 ScreenCapture::captureLayers(&mCapture, captureArgs);
1019 mCapture->expectColor(Rect(0, 0, 32, 32), Color::BLACK);
1020 ASSERT_FALSE(mCapture->capturedHdrLayers());
1021}
1022
1023TEST_F(ScreenCaptureTest, CaptureHdrLayer) {
1024 sp<SurfaceControl> layer;
1025 ASSERT_NO_FATAL_FAILURE(layer = createLayer("test layer", 32, 32,
1026 ISurfaceComposerClient::eFXSurfaceBufferState,
1027 mBGSurfaceControl.get()));
Patrick Williams83f36b22022-09-14 17:57:35 +00001028 ASSERT_NO_FATAL_FAILURE(fillBufferLayerColor(layer, Color::BLACK, 32, 32));
Alec Mouri14d5b862022-04-27 21:20:04 +00001029 Transaction()
1030 .show(layer)
1031 .setLayer(layer, INT32_MAX)
1032 .setDataspace(layer, ui::Dataspace::BT2020_ITU_PQ)
1033 .apply();
1034
1035 LayerCaptureArgs captureArgs;
1036 captureArgs.layerHandle = layer->getHandle();
1037
1038 ScreenCapture::captureLayers(&mCapture, captureArgs);
1039 mCapture->expectColor(Rect(0, 0, 32, 32), Color::BLACK);
1040 ASSERT_TRUE(mCapture->capturedHdrLayers());
1041}
1042
Melody Hsu70c2ee62024-03-29 21:58:45 +00001043TEST_F(ScreenCaptureTest, captureOffscreenNullSnapshot) {
1044 sp<SurfaceControl> layer;
1045 ASSERT_NO_FATAL_FAILURE(layer = createLayer("test layer", 32, 32,
1046 ISurfaceComposerClient::eFXSurfaceBufferState,
1047 mBGSurfaceControl.get()));
1048
1049 // A mirrored layer will not have a snapshot. Testing an offscreen mirrored layer
1050 // ensures that the screenshot path handles cases where snapshots are null.
1051 sp<SurfaceControl> mirroredLayer;
1052 ASSERT_NO_FATAL_FAILURE(mirroredLayer = mirrorSurface(layer.get()));
1053
1054 LayerCaptureArgs captureArgs;
1055 captureArgs.layerHandle = mirroredLayer->getHandle();
Alec Mouribae67862024-08-06 14:53:46 +00001056 captureArgs.captureArgs.sourceCrop = gui::aidl_utils::toARect(1, 1);
Melody Hsu70c2ee62024-03-29 21:58:45 +00001057
1058 // Screenshot path should only use the children of the layer hierarchy so
1059 // that it will not create a new snapshot. A snapshot would otherwise be
1060 // created to pass on the properties of the parent, which is not needed
1061 // for the purposes of this test since we explicitly want a null snapshot.
1062 captureArgs.childrenOnly = true;
1063 ScreenCapture::captureLayers(&mCapture, captureArgs);
1064}
1065
chaviw3efadb12020-07-27 10:07:15 -07001066// In the following tests we verify successful skipping of a parent layer,
1067// so we use the same verification logic and only change how we mutate
1068// the parent layer to verify that various properties are ignored.
1069class ScreenCaptureChildOnlyTest : public ScreenCaptureTest {
1070public:
1071 void SetUp() override {
1072 ScreenCaptureTest::SetUp();
1073
1074 mChild = createSurface(mClient, "Child surface", 10, 10, PIXEL_FORMAT_RGBA_8888, 0,
1075 mFGSurfaceControl.get());
1076 TransactionUtils::fillSurfaceRGBA8(mChild, 200, 200, 200);
1077
1078 SurfaceComposerClient::Transaction().show(mChild).apply(true);
1079 }
1080
1081 void verify(std::function<void()> verifyStartingState) {
1082 // Verify starting state before a screenshot is taken.
1083 verifyStartingState();
1084
1085 // Verify child layer does not inherit any of the properties of its
1086 // parent when its screenshot is captured.
chaviw70cb6a42020-07-30 13:57:36 -07001087 LayerCaptureArgs captureArgs;
1088 captureArgs.layerHandle = mFGSurfaceControl->getHandle();
1089 captureArgs.childrenOnly = true;
1090 ScreenCapture::captureLayers(&mCapture, captureArgs);
chaviw3efadb12020-07-27 10:07:15 -07001091 mCapture->checkPixel(10, 10, 0, 0, 0);
1092 mCapture->expectChildColor(0, 0);
1093
1094 // Verify all assumptions are still true after the screenshot is taken.
1095 verifyStartingState();
1096 }
1097
1098 std::unique_ptr<ScreenCapture> mCapture;
1099 sp<SurfaceControl> mChild;
1100};
1101
1102// Regression test b/76099859
1103TEST_F(ScreenCaptureChildOnlyTest, CaptureLayerIgnoresParentVisibility) {
1104 SurfaceComposerClient::Transaction().hide(mFGSurfaceControl).apply(true);
1105
1106 // Even though the parent is hidden we should still capture the child.
1107
1108 // Before and after reparenting, verify child is properly hidden
1109 // when rendering full-screen.
1110 verify([&] { screenshot()->expectBGColor(64, 64); });
1111}
1112
1113TEST_F(ScreenCaptureChildOnlyTest, CaptureLayerIgnoresParentCrop) {
chaviw25714502021-02-11 10:01:08 -08001114 SurfaceComposerClient::Transaction().setCrop(mFGSurfaceControl, Rect(0, 0, 1, 1)).apply(true);
chaviw3efadb12020-07-27 10:07:15 -07001115
1116 // Even though the parent is cropped out we should still capture the child.
1117
1118 // Before and after reparenting, verify child is cropped by parent.
1119 verify([&] { screenshot()->expectBGColor(65, 65); });
1120}
1121
1122// Regression test b/124372894
1123TEST_F(ScreenCaptureChildOnlyTest, CaptureLayerIgnoresTransform) {
1124 SurfaceComposerClient::Transaction().setMatrix(mFGSurfaceControl, 2, 0, 0, 2).apply(true);
1125
1126 // We should not inherit the parent scaling.
1127
1128 // Before and after reparenting, verify child is properly scaled.
1129 verify([&] { screenshot()->expectChildColor(80, 80); });
1130}
1131
Garfield Tande619fa2020-10-02 17:13:53 -07001132} // namespace android
Marin Shalamanovbed7fd32020-12-21 20:02:20 +01001133
1134// TODO(b/129481165): remove the #pragma below and fix conversion issues
Robert Carr5b3b9142021-02-22 12:27:32 -08001135#pragma clang diagnostic pop // ignored "-Wconversion"