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