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