1 /*
2 * Copyright (C) 2019 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 // TODO(b/129481165): remove the #pragma below and fix conversion issues
18 #pragma clang diagnostic push
19 #pragma clang diagnostic ignored "-Wconversion"
20
21 #include <android-base/properties.h>
22 #include <common/FlagManager.h>
23 #include <gui/AidlUtil.h>
24 #include <private/android_filesystem_config.h>
25 #include "LayerTransactionTest.h"
26 #include "utils/TransactionUtils.h"
27
28 namespace android {
29
30 class MirrorLayerTest : public LayerTransactionTest {
31 protected:
SetUp()32 virtual void SetUp() {
33 LayerTransactionTest::SetUp();
34 ASSERT_EQ(NO_ERROR, mClient->initCheck());
35 const auto ids = SurfaceComposerClient::getPhysicalDisplayIds();
36 ASSERT_FALSE(ids.empty());
37
38 const auto display = SurfaceComposerClient::getPhysicalDisplayToken(ids.front());
39 ASSERT_FALSE(display == nullptr);
40
41 mParentLayer = createColorLayer("Parent layer", Color::RED);
42 mChildLayer = createColorLayer("Child layer", Color::GREEN, mParentLayer.get());
43 asTransaction([&](Transaction& t) {
44 t.setDisplayLayerStack(display, ui::DEFAULT_LAYER_STACK);
45 t.setLayer(mParentLayer, INT32_MAX - 2).show(mParentLayer);
46 t.setCrop(mChildLayer, Rect(0, 0, 400, 400)).show(mChildLayer);
47 t.setPosition(mChildLayer, 50, 50);
48 t.setFlags(mParentLayer, layer_state_t::eLayerOpaque, layer_state_t::eLayerOpaque);
49 t.setFlags(mChildLayer, layer_state_t::eLayerOpaque, layer_state_t::eLayerOpaque);
50 });
51 }
52
TearDown()53 virtual void TearDown() {
54 LayerTransactionTest::TearDown();
55 mParentLayer = 0;
56 mChildLayer = 0;
57 }
58
59 sp<SurfaceControl> mParentLayer;
60 sp<SurfaceControl> mChildLayer;
61 };
62
TEST_F(MirrorLayerTest,MirrorColorLayer)63 TEST_F(MirrorLayerTest, MirrorColorLayer) {
64 sp<SurfaceControl> grandchild =
65 createColorLayer("Grandchild layer", Color::BLUE, mChildLayer.get());
66 Transaction()
67 .setFlags(grandchild, layer_state_t::eLayerOpaque, layer_state_t::eLayerOpaque)
68 .setCrop(grandchild, Rect(0, 0, 200, 200))
69 .show(grandchild)
70 .apply();
71
72 // Mirror mChildLayer
73 sp<SurfaceControl> mirrorLayer = mClient->mirrorSurface(mChildLayer.get());
74 ASSERT_NE(mirrorLayer, nullptr);
75
76 // Add mirrorLayer as child of mParentLayer so it's shown on the display
77 Transaction()
78 .reparent(mirrorLayer, mParentLayer)
79 .setPosition(mirrorLayer, 500, 500)
80 .show(mirrorLayer)
81 .apply();
82
83 if (FlagManager::getInstance().detached_mirror()) {
84 Transaction().setPosition(mirrorLayer, 550, 550).apply();
85 }
86
87 {
88 SCOPED_TRACE("Initial Mirror");
89 auto shot = screenshot();
90 // Grandchild mirror
91 shot->expectColor(Rect(550, 550, 750, 750), Color::BLUE);
92 // Child mirror
93 shot->expectColor(Rect(750, 750, 950, 950), Color::GREEN);
94 }
95
96 // Set color to white on grandchild layer.
97 Transaction().setColor(grandchild, half3{1, 1, 1}).apply();
98 {
99 SCOPED_TRACE("Updated Grandchild Layer Color");
100 auto shot = screenshot();
101 // Grandchild mirror
102 shot->expectColor(Rect(550, 550, 750, 750), Color::WHITE);
103 // Child mirror
104 shot->expectColor(Rect(750, 750, 950, 950), Color::GREEN);
105 }
106
107 // Set color to black on child layer.
108 Transaction().setColor(mChildLayer, half3{0, 0, 0}).apply();
109 {
110 SCOPED_TRACE("Updated Child Layer Color");
111 auto shot = screenshot();
112 // Grandchild mirror
113 shot->expectColor(Rect(550, 550, 750, 750), Color::WHITE);
114 // Child mirror
115 shot->expectColor(Rect(750, 750, 950, 950), Color::BLACK);
116 }
117
118 // Remove grandchild layer
119 Transaction().reparent(grandchild, nullptr).apply();
120 {
121 SCOPED_TRACE("Removed Grandchild Layer");
122 auto shot = screenshot();
123 // Grandchild mirror
124 shot->expectColor(Rect(550, 550, 750, 750), Color::BLACK);
125 // Child mirror
126 shot->expectColor(Rect(750, 750, 950, 950), Color::BLACK);
127 }
128
129 if (base::GetBoolProperty("debug.sf.enable_legacy_frontend", true)) {
130 GTEST_SKIP() << "Skipping test because mirroring behavior changes with legacy frontend";
131 }
132
133 // Remove child layer and verify we can still mirror the layer when
134 // its offscreen.
135 Transaction().reparent(mChildLayer, nullptr).apply();
136 {
137 SCOPED_TRACE("Removed Child Layer");
138 auto shot = screenshot();
139 // Grandchild mirror
140 shot->expectColor(Rect(550, 550, 750, 750), Color::BLACK);
141 // Child mirror
142 shot->expectColor(Rect(750, 750, 950, 950), Color::BLACK);
143 }
144
145 // Add grandchild layer to offscreen layer
146 Transaction().reparent(grandchild, mChildLayer).apply();
147 {
148 SCOPED_TRACE("Added Grandchild Layer");
149 auto shot = screenshot();
150 // Grandchild mirror
151 shot->expectColor(Rect(550, 550, 750, 750), Color::WHITE);
152 // Child mirror
153 shot->expectColor(Rect(750, 750, 950, 950), Color::BLACK);
154 }
155
156 // Add child layer
157 Transaction().reparent(mChildLayer, mParentLayer).apply();
158 {
159 SCOPED_TRACE("Added Child Layer");
160 auto shot = screenshot();
161 // Grandchild mirror
162 shot->expectColor(Rect(550, 550, 750, 750), Color::WHITE);
163 // Child mirror
164 shot->expectColor(Rect(750, 750, 950, 950), Color::BLACK);
165 }
166 }
167
TEST_F(MirrorLayerTest,MirrorBufferLayer)168 TEST_F(MirrorLayerTest, MirrorBufferLayer) {
169 sp<SurfaceControl> bufferQueueLayer =
170 createLayer("BufferQueueLayer", 200, 200, 0, mChildLayer.get());
171 fillBufferQueueLayerColor(bufferQueueLayer, Color::BLUE, 200, 200);
172 Transaction().show(bufferQueueLayer).apply();
173
174 sp<SurfaceControl> mirrorLayer = mClient->mirrorSurface(mChildLayer.get());
175 Transaction()
176 .reparent(mirrorLayer, mParentLayer)
177 .setPosition(mirrorLayer, 500, 500)
178 .show(mirrorLayer)
179 .apply();
180
181 if (FlagManager::getInstance().detached_mirror()) {
182 Transaction().setPosition(mirrorLayer, 550, 550).apply();
183 }
184 {
185 SCOPED_TRACE("Initial Mirror BufferQueueLayer");
186 auto shot = screenshot();
187 // Buffer mirror
188 shot->expectColor(Rect(550, 550, 750, 750), Color::BLUE);
189 // Child mirror
190 shot->expectColor(Rect(750, 750, 950, 950), Color::GREEN);
191 }
192
193 fillBufferQueueLayerColor(bufferQueueLayer, Color::WHITE, 200, 200);
194 {
195 SCOPED_TRACE("Update BufferQueueLayer");
196 auto shot = screenshot();
197 // Buffer mirror
198 shot->expectColor(Rect(550, 550, 750, 750), Color::WHITE);
199 // Child mirror
200 shot->expectColor(Rect(750, 750, 950, 950), Color::GREEN);
201 }
202
203 Transaction().reparent(bufferQueueLayer, nullptr).apply();
204 {
205 SCOPED_TRACE("Removed BufferQueueLayer");
206 auto shot = screenshot();
207 // Buffer mirror
208 shot->expectColor(Rect(550, 550, 750, 750), Color::GREEN);
209 // Child mirror
210 shot->expectColor(Rect(750, 750, 950, 950), Color::GREEN);
211 }
212
213 sp<SurfaceControl> layer =
214 createLayer("Layer", 200, 200, ISurfaceComposerClient::eFXSurfaceBufferState,
215 mChildLayer.get());
216 fillBufferLayerColor(layer, Color::BLUE, 200, 200);
217 Transaction().show(layer).apply();
218
219 {
220 SCOPED_TRACE("Initial Mirror Layer");
221 auto shot = screenshot();
222 // Buffer mirror
223 shot->expectColor(Rect(550, 550, 750, 750), Color::BLUE);
224 // Child mirror
225 shot->expectColor(Rect(750, 750, 950, 950), Color::GREEN);
226 }
227
228 fillBufferLayerColor(layer, Color::WHITE, 200, 200);
229 {
230 SCOPED_TRACE("Update Layer");
231 auto shot = screenshot();
232 // Buffer mirror
233 shot->expectColor(Rect(550, 550, 750, 750), Color::WHITE);
234 // Child mirror
235 shot->expectColor(Rect(750, 750, 950, 950), Color::GREEN);
236 }
237
238 Transaction().reparent(layer, nullptr).apply();
239 {
240 SCOPED_TRACE("Removed Layer");
241 auto shot = screenshot();
242 // Buffer mirror
243 shot->expectColor(Rect(550, 550, 750, 750), Color::GREEN);
244 // Child mirror
245 shot->expectColor(Rect(750, 750, 950, 950), Color::GREEN);
246 }
247 }
248
249 // Test that the mirror layer is initially offscreen.
TEST_F(MirrorLayerTest,InitialMirrorState)250 TEST_F(MirrorLayerTest, InitialMirrorState) {
251 const auto ids = SurfaceComposerClient::getPhysicalDisplayIds();
252 ASSERT_FALSE(ids.empty());
253
254 const auto display = SurfaceComposerClient::getPhysicalDisplayToken(ids.front());
255 ui::DisplayMode mode;
256 SurfaceComposerClient::getActiveDisplayMode(display, &mode);
257 const ui::Size& size = mode.resolution;
258
259 sp<SurfaceControl> mirrorLayer = nullptr;
260 {
261 // Run as system to get the ACCESS_SURFACE_FLINGER permission when mirroring
262 UIDFaker f(AID_SYSTEM);
263 // Mirror mChildLayer
264 mirrorLayer = mClient->mirrorSurface(mChildLayer.get());
265 ASSERT_NE(mirrorLayer, nullptr);
266 }
267
268 // Show the mirror layer, but don't reparent to a layer on screen.
269 Transaction()
270 .setPosition(mirrorLayer, 500, 500)
271 .show(mirrorLayer)
272 .setLayer(mirrorLayer, INT32_MAX - 1)
273 .apply();
274
275 if (FlagManager::getInstance().detached_mirror()) {
276 Transaction().setPosition(mirrorLayer, 550, 550).apply();
277 }
278 {
279 SCOPED_TRACE("Offscreen Mirror");
280 auto shot = screenshot();
281 shot->expectColor(Rect(0, 0, size.getWidth(), 50), Color::RED);
282 shot->expectColor(Rect(0, 0, 50, size.getHeight()), Color::RED);
283 shot->expectColor(Rect(450, 0, size.getWidth(), size.getHeight()), Color::RED);
284 shot->expectColor(Rect(0, 450, size.getWidth(), size.getHeight()), Color::RED);
285 shot->expectColor(Rect(50, 50, 450, 450), Color::GREEN);
286 }
287
288 // Add mirrorLayer as child of mParentLayer so it's shown on the display
289 Transaction().reparent(mirrorLayer, mParentLayer).apply();
290
291 {
292 SCOPED_TRACE("On Screen Mirror");
293 auto shot = screenshot();
294 // Child mirror
295 shot->expectColor(Rect(550, 550, 950, 950), Color::GREEN);
296 }
297 }
298
299 // Test that a mirror layer can be screenshot when offscreen
TEST_F(MirrorLayerTest,OffscreenMirrorScreenshot)300 TEST_F(MirrorLayerTest, OffscreenMirrorScreenshot) {
301 const auto ids = SurfaceComposerClient::getPhysicalDisplayIds();
302 ASSERT_FALSE(ids.empty());
303 const auto display = SurfaceComposerClient::getPhysicalDisplayToken(ids.front());
304 ui::DisplayMode mode;
305 SurfaceComposerClient::getActiveDisplayMode(display, &mode);
306 const ui::Size& size = mode.resolution;
307
308 sp<SurfaceControl> grandchild =
309 createLayer("Grandchild layer", 50, 50, ISurfaceComposerClient::eFXSurfaceBufferState,
310 mChildLayer.get());
311 ASSERT_NO_FATAL_FAILURE(fillBufferLayerColor(grandchild, Color::BLUE, 50, 50));
312 Rect childBounds = Rect(50, 50, 450, 450);
313
314 asTransaction([&](Transaction& t) {
315 t.setCrop(grandchild, Rect(0, 0, 50, 50)).show(grandchild);
316 t.setFlags(grandchild, layer_state_t::eLayerOpaque, layer_state_t::eLayerOpaque);
317 });
318
319 sp<SurfaceControl> mirrorLayer = nullptr;
320 {
321 // Run as system to get the ACCESS_SURFACE_FLINGER permission when mirroring
322 UIDFaker f(AID_SYSTEM);
323 // Mirror mChildLayer
324 mirrorLayer = mClient->mirrorSurface(mChildLayer.get());
325 ASSERT_NE(mirrorLayer, nullptr);
326 }
327
328 sp<SurfaceControl> mirrorParent =
329 createLayer("Grandchild layer", 50, 50, ISurfaceComposerClient::eFXSurfaceBufferState);
330
331 // Show the mirror layer, but don't reparent to a layer on screen.
332 Transaction().reparent(mirrorLayer, mirrorParent).show(mirrorLayer).apply();
333
334 if (FlagManager::getInstance().detached_mirror()) {
335 Transaction().setPosition(mirrorLayer, 50, 50).apply();
336 }
337
338 {
339 SCOPED_TRACE("Offscreen Mirror");
340 auto shot = screenshot();
341 shot->expectColor(Rect(0, 0, size.getWidth(), 50), Color::RED);
342 shot->expectColor(Rect(0, 0, 50, size.getHeight()), Color::RED);
343 shot->expectColor(Rect(450, 0, size.getWidth(), size.getHeight()), Color::RED);
344 shot->expectColor(Rect(0, 450, size.getWidth(), size.getHeight()), Color::RED);
345 shot->expectColor(Rect(100, 100, 450, 450), Color::GREEN);
346 shot->expectColor(Rect(50, 50, 100, 100), Color::BLUE);
347 }
348
349 {
350 SCOPED_TRACE("Capture Mirror");
351 // Capture just the mirror layer and child.
352 LayerCaptureArgs captureArgs;
353 captureArgs.layerHandle = mirrorParent->getHandle();
354 captureArgs.captureArgs.sourceCrop = gui::aidl_utils::toARect(childBounds);
355 std::unique_ptr<ScreenCapture> shot;
356 ScreenCapture::captureLayers(&shot, captureArgs);
357 shot->expectSize(childBounds.width(), childBounds.height());
358 shot->expectColor(Rect(0, 0, 50, 50), Color::BLUE);
359 shot->expectColor(Rect(50, 50, 400, 400), Color::GREEN);
360 }
361 }
362
363 } // namespace android
364
365 // TODO(b/129481165): remove the #pragma below and fix conversion issues
366 #pragma clang diagnostic pop // ignored "-Wconversion"
367