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,setDisplayStateLockedDoesNothingIfProjectionDidNotChange)227 TEST_F(SetDisplayStateLockedTest, setDisplayStateLockedDoesNothingIfProjectionDidNotChange) {
228 using Case = SimplePrimaryDisplayCase;
229 constexpr ui::Rotation initialOrientation = ui::ROTATION_180;
230 const Rect initialOrientedDisplayRect = {1, 2, 3, 4};
231 const Rect initialLayerStackRect = {5, 6, 7, 8};
232
233 // --------------------------------------------------------------------
234 // Preconditions
235
236 // A display is set up
237 auto display = Case::Display::makeFakeExistingDisplayInjector(this);
238 display.inject();
239
240 // The current display state projection state is all set
241 display.mutableCurrentDisplayState().orientation = initialOrientation;
242 display.mutableCurrentDisplayState().orientedDisplaySpaceRect = initialOrientedDisplayRect;
243 display.mutableCurrentDisplayState().layerStackSpaceRect = initialLayerStackRect;
244
245 // The incoming request sets the same projection state
246 DisplayState state;
247 state.what = DisplayState::eDisplayProjectionChanged;
248 state.token = display.token();
249 state.orientation = initialOrientation;
250 state.orientedDisplaySpaceRect = initialOrientedDisplayRect;
251 state.layerStackSpaceRect = initialLayerStackRect;
252
253 // --------------------------------------------------------------------
254 // Invocation
255
256 uint32_t flags = mFlinger.setDisplayStateLocked(state);
257
258 // --------------------------------------------------------------------
259 // Postconditions
260
261 // The returned flags are empty
262 EXPECT_EQ(0u, flags);
263
264 // The current display state is unchanged
265 EXPECT_EQ(initialOrientation, display.getCurrentDisplayState().orientation);
266
267 EXPECT_EQ(initialOrientedDisplayRect,
268 display.getCurrentDisplayState().orientedDisplaySpaceRect);
269 EXPECT_EQ(initialLayerStackRect, display.getCurrentDisplayState().layerStackSpaceRect);
270 }
271
TEST_F(SetDisplayStateLockedTest,setDisplayStateLockedRequestsUpdateIfOrientationChanged)272 TEST_F(SetDisplayStateLockedTest, setDisplayStateLockedRequestsUpdateIfOrientationChanged) {
273 using Case = SimplePrimaryDisplayCase;
274 constexpr ui::Rotation initialOrientation = ui::ROTATION_90;
275 constexpr ui::Rotation desiredOrientation = ui::ROTATION_180;
276
277 // --------------------------------------------------------------------
278 // Preconditions
279
280 // A display is set up
281 auto display = Case::Display::makeFakeExistingDisplayInjector(this);
282 display.inject();
283
284 // The current display state has an orientation set
285 display.mutableCurrentDisplayState().orientation = initialOrientation;
286
287 // The incoming request sets a different orientation
288 DisplayState state;
289 state.what = DisplayState::eDisplayProjectionChanged;
290 state.token = display.token();
291 state.orientation = desiredOrientation;
292
293 // --------------------------------------------------------------------
294 // Invocation
295
296 uint32_t flags = mFlinger.setDisplayStateLocked(state);
297
298 // --------------------------------------------------------------------
299 // Postconditions
300
301 // The returned flags indicate a transaction is needed
302 EXPECT_EQ(eDisplayTransactionNeeded, flags);
303
304 // The current display state has the new value.
305 EXPECT_EQ(desiredOrientation, display.getCurrentDisplayState().orientation);
306 }
307
TEST_F(SetDisplayStateLockedTest,setDisplayStateLockedRequestsUpdateIfFrameChanged)308 TEST_F(SetDisplayStateLockedTest, setDisplayStateLockedRequestsUpdateIfFrameChanged) {
309 using Case = SimplePrimaryDisplayCase;
310 const Rect initialOrientedDisplayRect = {0, 0, 0, 0};
311 const Rect desiredOrientedDisplayRect = {5, 6, 7, 8};
312
313 // --------------------------------------------------------------------
314 // Preconditions
315
316 // A display is set up
317 auto display = Case::Display::makeFakeExistingDisplayInjector(this);
318 display.inject();
319
320 // The current display state does not have a orientedDisplaySpaceRect
321 display.mutableCurrentDisplayState().orientedDisplaySpaceRect = initialOrientedDisplayRect;
322
323 // The incoming request sets a orientedDisplaySpaceRect
324 DisplayState state;
325 state.what = DisplayState::eDisplayProjectionChanged;
326 state.token = display.token();
327 state.orientedDisplaySpaceRect = desiredOrientedDisplayRect;
328
329 // --------------------------------------------------------------------
330 // Invocation
331
332 uint32_t flags = mFlinger.setDisplayStateLocked(state);
333
334 // --------------------------------------------------------------------
335 // Postconditions
336
337 // The returned flags indicate a transaction is needed
338 EXPECT_EQ(eDisplayTransactionNeeded, flags);
339
340 // The current display state has the new value.
341 EXPECT_EQ(desiredOrientedDisplayRect,
342 display.getCurrentDisplayState().orientedDisplaySpaceRect);
343 }
344
TEST_F(SetDisplayStateLockedTest,setDisplayStateLockedRequestsUpdateIfLayerStackRectChanged)345 TEST_F(SetDisplayStateLockedTest, setDisplayStateLockedRequestsUpdateIfLayerStackRectChanged) {
346 using Case = SimplePrimaryDisplayCase;
347 const Rect initialLayerStackRect = {0, 0, 0, 0};
348 const Rect desiredLayerStackRect = {5, 6, 7, 8};
349
350 // --------------------------------------------------------------------
351 // Preconditions
352
353 // A display is set up
354 auto display = Case::Display::makeFakeExistingDisplayInjector(this);
355 display.inject();
356
357 // The current display state does not have a layerStackSpaceRect
358 display.mutableCurrentDisplayState().layerStackSpaceRect = initialLayerStackRect;
359
360 // The incoming request sets a layerStackSpaceRect
361 DisplayState state;
362 state.what = DisplayState::eDisplayProjectionChanged;
363 state.token = display.token();
364 state.layerStackSpaceRect = desiredLayerStackRect;
365
366 // --------------------------------------------------------------------
367 // Invocation
368
369 uint32_t flags = mFlinger.setDisplayStateLocked(state);
370
371 // --------------------------------------------------------------------
372 // Postconditions
373
374 // The returned flags indicate a transaction is needed
375 EXPECT_EQ(eDisplayTransactionNeeded, flags);
376
377 // The current display state has the new value.
378 EXPECT_EQ(desiredLayerStackRect, display.getCurrentDisplayState().layerStackSpaceRect);
379 }
380
TEST_F(SetDisplayStateLockedTest,setDisplayStateLockedDoesNothingIfSizeDidNotChange)381 TEST_F(SetDisplayStateLockedTest, setDisplayStateLockedDoesNothingIfSizeDidNotChange) {
382 using Case = SimplePrimaryDisplayCase;
383 constexpr uint32_t initialWidth = 1024;
384 constexpr uint32_t initialHeight = 768;
385
386 // --------------------------------------------------------------------
387 // Preconditions
388
389 // A display is set up
390 auto display = Case::Display::makeFakeExistingDisplayInjector(this);
391 display.inject();
392
393 // The current display state has a size set
394 display.mutableCurrentDisplayState().width = initialWidth;
395 display.mutableCurrentDisplayState().height = initialHeight;
396
397 // The incoming request sets the same display size
398 DisplayState state;
399 state.what = DisplayState::eDisplaySizeChanged;
400 state.token = display.token();
401 state.width = initialWidth;
402 state.height = initialHeight;
403
404 // --------------------------------------------------------------------
405 // Invocation
406
407 uint32_t flags = mFlinger.setDisplayStateLocked(state);
408
409 // --------------------------------------------------------------------
410 // Postconditions
411
412 // The returned flags are empty
413 EXPECT_EQ(0u, flags);
414
415 // The current display state is unchanged
416 EXPECT_EQ(initialWidth, display.getCurrentDisplayState().width);
417 EXPECT_EQ(initialHeight, display.getCurrentDisplayState().height);
418 }
419
TEST_F(SetDisplayStateLockedTest,setDisplayStateLockedRequestsUpdateIfWidthChanged)420 TEST_F(SetDisplayStateLockedTest, setDisplayStateLockedRequestsUpdateIfWidthChanged) {
421 using Case = SimplePrimaryDisplayCase;
422 constexpr uint32_t initialWidth = 0;
423 constexpr uint32_t desiredWidth = 1024;
424
425 // --------------------------------------------------------------------
426 // Preconditions
427
428 // A display is set up
429 auto display = Case::Display::makeFakeExistingDisplayInjector(this);
430 display.inject();
431
432 // The display does not yet have a width
433 display.mutableCurrentDisplayState().width = initialWidth;
434
435 // The incoming request sets a display width
436 DisplayState state;
437 state.what = DisplayState::eDisplaySizeChanged;
438 state.token = display.token();
439 state.width = desiredWidth;
440
441 // --------------------------------------------------------------------
442 // Invocation
443
444 uint32_t flags = mFlinger.setDisplayStateLocked(state);
445
446 // --------------------------------------------------------------------
447 // Postconditions
448
449 // The returned flags indicate a transaction is needed
450 EXPECT_EQ(eDisplayTransactionNeeded, flags);
451
452 // The current display state has the new value.
453 EXPECT_EQ(desiredWidth, display.getCurrentDisplayState().width);
454 }
455
TEST_F(SetDisplayStateLockedTest,setDisplayStateLockedRequestsUpdateIfHeightChanged)456 TEST_F(SetDisplayStateLockedTest, setDisplayStateLockedRequestsUpdateIfHeightChanged) {
457 using Case = SimplePrimaryDisplayCase;
458 constexpr uint32_t initialHeight = 0;
459 constexpr uint32_t desiredHeight = 768;
460
461 // --------------------------------------------------------------------
462 // Preconditions
463
464 // A display is set up
465 auto display = Case::Display::makeFakeExistingDisplayInjector(this);
466 display.inject();
467
468 // The display does not yet have a height
469 display.mutableCurrentDisplayState().height = initialHeight;
470
471 // The incoming request sets a display height
472 DisplayState state;
473 state.what = DisplayState::eDisplaySizeChanged;
474 state.token = display.token();
475 state.height = desiredHeight;
476
477 // --------------------------------------------------------------------
478 // Invocation
479
480 uint32_t flags = mFlinger.setDisplayStateLocked(state);
481
482 // --------------------------------------------------------------------
483 // Postconditions
484
485 // The returned flags indicate a transaction is needed
486 EXPECT_EQ(eDisplayTransactionNeeded, flags);
487
488 // The current display state has the new value.
489 EXPECT_EQ(desiredHeight, display.getCurrentDisplayState().height);
490 }
491
492 } // namespace
493 } // namespace android
494