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