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