1 /*
2  * Copyright 2020 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 #undef LOG_TAG
18 #define LOG_TAG "LibSurfaceFlingerUnittests"
19 
20 #include "DisplayTransactionTestHelpers.h"
21 
22 #include <gmock/gmock.h>
23 #include <gtest/gtest.h>
24 
25 namespace android {
26 namespace {
27 
28 constexpr ui::LayerStack LAYER_STACK{456u};
29 
30 class SetDisplayStateLockedTest : public DisplayTransactionTest {};
31 
TEST_F(SetDisplayStateLockedTest,setDisplayStateLockedDoesNothingWithUnknownDisplay)32 TEST_F(SetDisplayStateLockedTest, setDisplayStateLockedDoesNothingWithUnknownDisplay) {
33     // --------------------------------------------------------------------
34     // Preconditions
35 
36     // We have an unknown display token not associated with a known display
37     sp<BBinder> displayToken = sp<BBinder>::make();
38 
39     // The requested display state references the unknown display.
40     DisplayState state;
41     state.what = DisplayState::eLayerStackChanged;
42     state.token = displayToken;
43     state.layerStack = LAYER_STACK;
44 
45     // --------------------------------------------------------------------
46     // Invocation
47 
48     uint32_t flags = mFlinger.setDisplayStateLocked(state);
49 
50     // --------------------------------------------------------------------
51     // Postconditions
52 
53     // The returned flags are empty
54     EXPECT_EQ(0u, flags);
55 
56     // The display token still doesn't match anything known.
57     EXPECT_FALSE(hasCurrentDisplayState(displayToken));
58 }
59 
TEST_F(SetDisplayStateLockedTest,setDisplayStateLockedDoesNothingWhenNoChanges)60 TEST_F(SetDisplayStateLockedTest, setDisplayStateLockedDoesNothingWhenNoChanges) {
61     using Case = SimplePrimaryDisplayCase;
62 
63     // --------------------------------------------------------------------
64     // Preconditions
65 
66     // A display is already set up
67     auto display = Case::Display::makeFakeExistingDisplayInjector(this);
68     display.inject();
69 
70     // No changes are made to the display
71     DisplayState state;
72     state.what = 0;
73     state.token = display.token();
74 
75     // --------------------------------------------------------------------
76     // Invocation
77 
78     uint32_t flags = mFlinger.setDisplayStateLocked(state);
79 
80     // --------------------------------------------------------------------
81     // Postconditions
82 
83     // The returned flags are empty
84     EXPECT_EQ(0u, flags);
85 }
86 
TEST_F(SetDisplayStateLockedTest,setDisplayStateLockedDoesNothingIfSurfaceDidNotChange)87 TEST_F(SetDisplayStateLockedTest, setDisplayStateLockedDoesNothingIfSurfaceDidNotChange) {
88     using Case = SimplePrimaryDisplayCase;
89 
90     // --------------------------------------------------------------------
91     // Preconditions
92 
93     // A display is already set up
94     auto display = Case::Display::makeFakeExistingDisplayInjector(this);
95     display.inject();
96 
97     // There is a surface that can be set.
98     sp<mock::GraphicBufferProducer> surface = sp<mock::GraphicBufferProducer>::make();
99 
100     // The current display state has the surface set
101     display.mutableCurrentDisplayState().surface = surface;
102 
103     // The incoming request sets the same surface
104     DisplayState state;
105     state.what = DisplayState::eSurfaceChanged;
106     state.token = display.token();
107     state.surface = surface;
108 
109     // --------------------------------------------------------------------
110     // Invocation
111 
112     uint32_t flags = mFlinger.setDisplayStateLocked(state);
113 
114     // --------------------------------------------------------------------
115     // Postconditions
116 
117     // The returned flags are empty
118     EXPECT_EQ(0u, flags);
119 
120     // The current display state is unchanged.
121     EXPECT_EQ(surface.get(), display.getCurrentDisplayState().surface.get());
122 }
123 
TEST_F(SetDisplayStateLockedTest,setDisplayStateLockedRequestsUpdateIfSurfaceChanged)124 TEST_F(SetDisplayStateLockedTest, setDisplayStateLockedRequestsUpdateIfSurfaceChanged) {
125     using Case = SimplePrimaryDisplayCase;
126 
127     // --------------------------------------------------------------------
128     // Preconditions
129 
130     // A display is already set up
131     auto display = Case::Display::makeFakeExistingDisplayInjector(this);
132     display.inject();
133 
134     // There is a surface that can be set.
135     sp<mock::GraphicBufferProducer> surface = sp<mock::GraphicBufferProducer>::make();
136 
137     // The current display state does not have a surface
138     display.mutableCurrentDisplayState().surface = nullptr;
139 
140     // The incoming request sets a surface
141     DisplayState state;
142     state.what = DisplayState::eSurfaceChanged;
143     state.token = display.token();
144     state.surface = surface;
145 
146     // --------------------------------------------------------------------
147     // Invocation
148 
149     uint32_t flags = mFlinger.setDisplayStateLocked(state);
150 
151     // --------------------------------------------------------------------
152     // Postconditions
153 
154     // The returned flags indicate a transaction is needed
155     EXPECT_EQ(eDisplayTransactionNeeded, flags);
156 
157     // The current display layer stack state is set to the new value
158     EXPECT_EQ(surface.get(), display.getCurrentDisplayState().surface.get());
159 }
160 
TEST_F(SetDisplayStateLockedTest,setDisplayStateLockedDoesNothingIfLayerStackDidNotChange)161 TEST_F(SetDisplayStateLockedTest, setDisplayStateLockedDoesNothingIfLayerStackDidNotChange) {
162     using Case = SimplePrimaryDisplayCase;
163 
164     // --------------------------------------------------------------------
165     // Preconditions
166 
167     // A display is already set up
168     auto display = Case::Display::makeFakeExistingDisplayInjector(this);
169     display.inject();
170 
171     // The display has a layer stack set
172     display.mutableCurrentDisplayState().layerStack = LAYER_STACK;
173 
174     // The incoming request sets the same layer stack
175     DisplayState state;
176     state.what = DisplayState::eLayerStackChanged;
177     state.token = display.token();
178     state.layerStack = LAYER_STACK;
179 
180     // --------------------------------------------------------------------
181     // Invocation
182 
183     uint32_t flags = mFlinger.setDisplayStateLocked(state);
184 
185     // --------------------------------------------------------------------
186     // Postconditions
187 
188     // The returned flags are empty
189     EXPECT_EQ(0u, flags);
190 
191     // The current display state is unchanged
192     EXPECT_EQ(LAYER_STACK, display.getCurrentDisplayState().layerStack);
193 }
194 
TEST_F(SetDisplayStateLockedTest,setDisplayStateLockedRequestsUpdateIfLayerStackChanged)195 TEST_F(SetDisplayStateLockedTest, setDisplayStateLockedRequestsUpdateIfLayerStackChanged) {
196     using Case = SimplePrimaryDisplayCase;
197 
198     // --------------------------------------------------------------------
199     // Preconditions
200 
201     // A display is set up
202     auto display = Case::Display::makeFakeExistingDisplayInjector(this);
203     display.inject();
204 
205     // The display has a layer stack set
206     display.mutableCurrentDisplayState().layerStack = ui::LayerStack{LAYER_STACK.id + 1};
207 
208     // The incoming request sets a different layer stack
209     DisplayState state;
210     state.what = DisplayState::eLayerStackChanged;
211     state.token = display.token();
212     state.layerStack = LAYER_STACK;
213 
214     // --------------------------------------------------------------------
215     // Invocation
216 
217     uint32_t flags = mFlinger.setDisplayStateLocked(state);
218 
219     // --------------------------------------------------------------------
220     // Postconditions
221 
222     // The returned flags indicate a transaction is needed
223     EXPECT_EQ(eDisplayTransactionNeeded, flags);
224 
225     // The desired display state has been set to the new value.
226     EXPECT_EQ(LAYER_STACK, display.getCurrentDisplayState().layerStack);
227 }
228 
TEST_F(SetDisplayStateLockedTest,setDisplayStateLockedDoesNothingIfFlagsNotChanged)229 TEST_F(SetDisplayStateLockedTest, setDisplayStateLockedDoesNothingIfFlagsNotChanged) {
230     using Case = SimplePrimaryDisplayCase;
231 
232     // --------------------------------------------------------------------
233     // Preconditions
234 
235     // A display is set up
236     auto display = Case::Display::makeFakeExistingDisplayInjector(this);
237     display.inject();
238 
239     // The display has flags set
240     display.mutableCurrentDisplayState().flags = 1u;
241 
242     // The incoming request sets a different layer stack
243     DisplayState state;
244     state.what = DisplayState::eFlagsChanged;
245     state.token = display.token();
246     state.flags = 1u;
247 
248     // --------------------------------------------------------------------
249     // Invocation
250 
251     uint32_t flags = mFlinger.setDisplayStateLocked(state);
252 
253     // --------------------------------------------------------------------
254     // Postconditions
255 
256     // The returned flags are empty
257     EXPECT_EQ(0u, flags);
258 
259     // The desired display state has been set to the new value.
260     EXPECT_EQ(1u, display.getCurrentDisplayState().flags);
261 }
262 
TEST_F(SetDisplayStateLockedTest,setDisplayStateLockedRequestsUpdateIfFlagsChanged)263 TEST_F(SetDisplayStateLockedTest, setDisplayStateLockedRequestsUpdateIfFlagsChanged) {
264     using Case = SimplePrimaryDisplayCase;
265 
266     // --------------------------------------------------------------------
267     // Preconditions
268 
269     // A display is set up
270     auto display = Case::Display::makeFakeExistingDisplayInjector(this);
271     display.inject();
272 
273     // The display has a layer stack set
274     display.mutableCurrentDisplayState().flags = 0u;
275 
276     // The incoming request sets a different layer stack
277     DisplayState state;
278     state.what = DisplayState::eFlagsChanged;
279     state.token = display.token();
280     state.flags = 1u;
281 
282     // --------------------------------------------------------------------
283     // Invocation
284 
285     uint32_t flags = mFlinger.setDisplayStateLocked(state);
286 
287     // --------------------------------------------------------------------
288     // Postconditions
289 
290     // The returned flags indicate a transaction is needed
291     EXPECT_EQ(eDisplayTransactionNeeded, flags);
292 
293     // The desired display state has been set to the new value.
294     EXPECT_EQ(1u, display.getCurrentDisplayState().flags);
295 }
296 
TEST_F(SetDisplayStateLockedTest,setDisplayStateLockedDoesNothingIfProjectionDidNotChange)297 TEST_F(SetDisplayStateLockedTest, setDisplayStateLockedDoesNothingIfProjectionDidNotChange) {
298     using Case = SimplePrimaryDisplayCase;
299     constexpr ui::Rotation initialOrientation = ui::ROTATION_180;
300     const Rect initialOrientedDisplayRect = {1, 2, 3, 4};
301     const Rect initialLayerStackRect = {5, 6, 7, 8};
302 
303     // --------------------------------------------------------------------
304     // Preconditions
305 
306     // A display is set up
307     auto display = Case::Display::makeFakeExistingDisplayInjector(this);
308     display.inject();
309 
310     // The current display state projection state is all set
311     display.mutableCurrentDisplayState().orientation = initialOrientation;
312     display.mutableCurrentDisplayState().orientedDisplaySpaceRect = initialOrientedDisplayRect;
313     display.mutableCurrentDisplayState().layerStackSpaceRect = initialLayerStackRect;
314 
315     // The incoming request sets the same projection state
316     DisplayState state;
317     state.what = DisplayState::eDisplayProjectionChanged;
318     state.token = display.token();
319     state.orientation = initialOrientation;
320     state.orientedDisplaySpaceRect = initialOrientedDisplayRect;
321     state.layerStackSpaceRect = initialLayerStackRect;
322 
323     // --------------------------------------------------------------------
324     // Invocation
325 
326     uint32_t flags = mFlinger.setDisplayStateLocked(state);
327 
328     // --------------------------------------------------------------------
329     // Postconditions
330 
331     // The returned flags are empty
332     EXPECT_EQ(0u, flags);
333 
334     // The current display state is unchanged
335     EXPECT_EQ(initialOrientation, display.getCurrentDisplayState().orientation);
336 
337     EXPECT_EQ(initialOrientedDisplayRect,
338               display.getCurrentDisplayState().orientedDisplaySpaceRect);
339     EXPECT_EQ(initialLayerStackRect, display.getCurrentDisplayState().layerStackSpaceRect);
340 }
341 
TEST_F(SetDisplayStateLockedTest,setDisplayStateLockedRequestsUpdateIfOrientationChanged)342 TEST_F(SetDisplayStateLockedTest, setDisplayStateLockedRequestsUpdateIfOrientationChanged) {
343     using Case = SimplePrimaryDisplayCase;
344     constexpr ui::Rotation initialOrientation = ui::ROTATION_90;
345     constexpr ui::Rotation desiredOrientation = ui::ROTATION_180;
346 
347     // --------------------------------------------------------------------
348     // Preconditions
349 
350     // A display is set up
351     auto display = Case::Display::makeFakeExistingDisplayInjector(this);
352     display.inject();
353 
354     // The current display state has an orientation set
355     display.mutableCurrentDisplayState().orientation = initialOrientation;
356 
357     // The incoming request sets a different orientation
358     DisplayState state;
359     state.what = DisplayState::eDisplayProjectionChanged;
360     state.token = display.token();
361     state.orientation = desiredOrientation;
362 
363     // --------------------------------------------------------------------
364     // Invocation
365 
366     uint32_t flags = mFlinger.setDisplayStateLocked(state);
367 
368     // --------------------------------------------------------------------
369     // Postconditions
370 
371     // The returned flags indicate a transaction is needed
372     EXPECT_EQ(eDisplayTransactionNeeded, flags);
373 
374     // The current display state has the new value.
375     EXPECT_EQ(desiredOrientation, display.getCurrentDisplayState().orientation);
376 }
377 
TEST_F(SetDisplayStateLockedTest,setDisplayStateLockedRequestsUpdateIfFrameChanged)378 TEST_F(SetDisplayStateLockedTest, setDisplayStateLockedRequestsUpdateIfFrameChanged) {
379     using Case = SimplePrimaryDisplayCase;
380     const Rect initialOrientedDisplayRect = {0, 0, 0, 0};
381     const Rect desiredOrientedDisplayRect = {5, 6, 7, 8};
382 
383     // --------------------------------------------------------------------
384     // Preconditions
385 
386     // A display is set up
387     auto display = Case::Display::makeFakeExistingDisplayInjector(this);
388     display.inject();
389 
390     // The current display state does not have a orientedDisplaySpaceRect
391     display.mutableCurrentDisplayState().orientedDisplaySpaceRect = initialOrientedDisplayRect;
392 
393     // The incoming request sets a orientedDisplaySpaceRect
394     DisplayState state;
395     state.what = DisplayState::eDisplayProjectionChanged;
396     state.token = display.token();
397     state.orientedDisplaySpaceRect = desiredOrientedDisplayRect;
398 
399     // --------------------------------------------------------------------
400     // Invocation
401 
402     uint32_t flags = mFlinger.setDisplayStateLocked(state);
403 
404     // --------------------------------------------------------------------
405     // Postconditions
406 
407     // The returned flags indicate a transaction is needed
408     EXPECT_EQ(eDisplayTransactionNeeded, flags);
409 
410     // The current display state has the new value.
411     EXPECT_EQ(desiredOrientedDisplayRect,
412               display.getCurrentDisplayState().orientedDisplaySpaceRect);
413 }
414 
TEST_F(SetDisplayStateLockedTest,setDisplayStateLockedRequestsUpdateIfLayerStackRectChanged)415 TEST_F(SetDisplayStateLockedTest, setDisplayStateLockedRequestsUpdateIfLayerStackRectChanged) {
416     using Case = SimplePrimaryDisplayCase;
417     const Rect initialLayerStackRect = {0, 0, 0, 0};
418     const Rect desiredLayerStackRect = {5, 6, 7, 8};
419 
420     // --------------------------------------------------------------------
421     // Preconditions
422 
423     // A display is set up
424     auto display = Case::Display::makeFakeExistingDisplayInjector(this);
425     display.inject();
426 
427     // The current display state does not have a layerStackSpaceRect
428     display.mutableCurrentDisplayState().layerStackSpaceRect = initialLayerStackRect;
429 
430     // The incoming request sets a layerStackSpaceRect
431     DisplayState state;
432     state.what = DisplayState::eDisplayProjectionChanged;
433     state.token = display.token();
434     state.layerStackSpaceRect = desiredLayerStackRect;
435 
436     // --------------------------------------------------------------------
437     // Invocation
438 
439     uint32_t flags = mFlinger.setDisplayStateLocked(state);
440 
441     // --------------------------------------------------------------------
442     // Postconditions
443 
444     // The returned flags indicate a transaction is needed
445     EXPECT_EQ(eDisplayTransactionNeeded, flags);
446 
447     // The current display state has the new value.
448     EXPECT_EQ(desiredLayerStackRect, display.getCurrentDisplayState().layerStackSpaceRect);
449 }
450 
TEST_F(SetDisplayStateLockedTest,setDisplayStateLockedDoesNothingIfSizeDidNotChange)451 TEST_F(SetDisplayStateLockedTest, setDisplayStateLockedDoesNothingIfSizeDidNotChange) {
452     using Case = SimplePrimaryDisplayCase;
453     constexpr uint32_t initialWidth = 1024;
454     constexpr uint32_t initialHeight = 768;
455 
456     // --------------------------------------------------------------------
457     // Preconditions
458 
459     // A display is set up
460     auto display = Case::Display::makeFakeExistingDisplayInjector(this);
461     display.inject();
462 
463     // The current display state has a size set
464     display.mutableCurrentDisplayState().width = initialWidth;
465     display.mutableCurrentDisplayState().height = initialHeight;
466 
467     // The incoming request sets the same display size
468     DisplayState state;
469     state.what = DisplayState::eDisplaySizeChanged;
470     state.token = display.token();
471     state.width = initialWidth;
472     state.height = initialHeight;
473 
474     // --------------------------------------------------------------------
475     // Invocation
476 
477     uint32_t flags = mFlinger.setDisplayStateLocked(state);
478 
479     // --------------------------------------------------------------------
480     // Postconditions
481 
482     // The returned flags are empty
483     EXPECT_EQ(0u, flags);
484 
485     // The current display state is unchanged
486     EXPECT_EQ(initialWidth, display.getCurrentDisplayState().width);
487     EXPECT_EQ(initialHeight, display.getCurrentDisplayState().height);
488 }
489 
TEST_F(SetDisplayStateLockedTest,setDisplayStateLockedRequestsUpdateIfWidthChanged)490 TEST_F(SetDisplayStateLockedTest, setDisplayStateLockedRequestsUpdateIfWidthChanged) {
491     using Case = SimplePrimaryDisplayCase;
492     constexpr uint32_t initialWidth = 0;
493     constexpr uint32_t desiredWidth = 1024;
494 
495     // --------------------------------------------------------------------
496     // Preconditions
497 
498     // A display is set up
499     auto display = Case::Display::makeFakeExistingDisplayInjector(this);
500     display.inject();
501 
502     // The display does not yet have a width
503     display.mutableCurrentDisplayState().width = initialWidth;
504 
505     // The incoming request sets a display width
506     DisplayState state;
507     state.what = DisplayState::eDisplaySizeChanged;
508     state.token = display.token();
509     state.width = desiredWidth;
510 
511     // --------------------------------------------------------------------
512     // Invocation
513 
514     uint32_t flags = mFlinger.setDisplayStateLocked(state);
515 
516     // --------------------------------------------------------------------
517     // Postconditions
518 
519     // The returned flags indicate a transaction is needed
520     EXPECT_EQ(eDisplayTransactionNeeded, flags);
521 
522     // The current display state has the new value.
523     EXPECT_EQ(desiredWidth, display.getCurrentDisplayState().width);
524 }
525 
TEST_F(SetDisplayStateLockedTest,setDisplayStateLockedRequestsUpdateIfHeightChanged)526 TEST_F(SetDisplayStateLockedTest, setDisplayStateLockedRequestsUpdateIfHeightChanged) {
527     using Case = SimplePrimaryDisplayCase;
528     constexpr uint32_t initialHeight = 0;
529     constexpr uint32_t desiredHeight = 768;
530 
531     // --------------------------------------------------------------------
532     // Preconditions
533 
534     // A display is set up
535     auto display = Case::Display::makeFakeExistingDisplayInjector(this);
536     display.inject();
537 
538     // The display does not yet have a height
539     display.mutableCurrentDisplayState().height = initialHeight;
540 
541     // The incoming request sets a display height
542     DisplayState state;
543     state.what = DisplayState::eDisplaySizeChanged;
544     state.token = display.token();
545     state.height = desiredHeight;
546 
547     // --------------------------------------------------------------------
548     // Invocation
549 
550     uint32_t flags = mFlinger.setDisplayStateLocked(state);
551 
552     // --------------------------------------------------------------------
553     // Postconditions
554 
555     // The returned flags indicate a transaction is needed
556     EXPECT_EQ(eDisplayTransactionNeeded, flags);
557 
558     // The current display state has the new value.
559     EXPECT_EQ(desiredHeight, display.getCurrentDisplayState().height);
560 }
561 
562 } // namespace
563 } // namespace android
564