xref: /aosp_15_r20/frameworks/native/services/surfaceflinger/tests/MirrorLayer_test.cpp (revision 38e8c45f13ce32b0dcecb25141ffecaf386fa17f)
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