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