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