• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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