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 namespace android {
23 namespace {
24
25 struct DisplayTransactionCommitTest : DisplayTransactionTest {
26 template <typename Case>
27 void setupCommonPreconditions();
28
29 template <typename Case, bool connected>
30 static void expectHotplugReceived(mock::EventThread*);
31
32 template <typename Case>
33 void setupCommonCallExpectationsForConnectProcessing();
34
35 template <typename Case>
36 void setupCommonCallExpectationsForDisconnectProcessing();
37
38 template <typename Case>
39 void processesHotplugConnectCommon();
40
41 template <typename Case>
42 void ignoresHotplugConnectCommon();
43
44 template <typename Case>
45 void processesHotplugDisconnectCommon();
46
47 template <typename Case>
48 void verifyDisplayIsConnected(const sp<IBinder>& displayToken);
49
50 template <typename Case>
51 void verifyPhysicalDisplayIsConnected();
52
53 void verifyDisplayIsNotConnected(const sp<IBinder>& displayToken);
54 };
55
56 template <typename Case>
setupCommonPreconditions()57 void DisplayTransactionCommitTest::setupCommonPreconditions() {
58 // Wide color displays support is configured appropriately
59 Case::WideColorSupport::injectConfigChange(this);
60
61 // SurfaceFlinger will use a test-controlled factory for BufferQueues
62 injectFakeBufferQueueFactory();
63
64 // SurfaceFlinger will use a test-controlled factory for native window
65 // surfaces.
66 injectFakeNativeWindowSurfaceFactory();
67 }
68
69 template <typename Case, bool connected>
expectHotplugReceived(mock::EventThread * eventThread)70 void DisplayTransactionCommitTest::expectHotplugReceived(mock::EventThread* eventThread) {
71 const auto convert = [](auto physicalDisplayId) {
72 return std::make_optional(DisplayId{physicalDisplayId});
73 };
74
75 EXPECT_CALL(*eventThread,
76 onHotplugReceived(ResultOf(convert, Case::Display::DISPLAY_ID::get()), connected))
77 .Times(1);
78 }
79
80 template <typename Case>
setupCommonCallExpectationsForConnectProcessing()81 void DisplayTransactionCommitTest::setupCommonCallExpectationsForConnectProcessing() {
82 Case::Display::setupHwcHotplugCallExpectations(this);
83
84 Case::Display::setupFramebufferConsumerBufferQueueCallExpectations(this);
85 Case::Display::setupFramebufferProducerBufferQueueCallExpectations(this);
86 Case::Display::setupNativeWindowSurfaceCreationCallExpectations(this);
87 Case::Display::setupHwcGetActiveConfigCallExpectations(this);
88
89 Case::WideColorSupport::setupComposerCallExpectations(this);
90 Case::HdrSupport::setupComposerCallExpectations(this);
91 Case::PerFrameMetadataSupport::setupComposerCallExpectations(this);
92
93 expectHotplugReceived<Case, true>(mEventThread);
94 expectHotplugReceived<Case, true>(mSFEventThread);
95 }
96
97 template <typename Case>
setupCommonCallExpectationsForDisconnectProcessing()98 void DisplayTransactionCommitTest::setupCommonCallExpectationsForDisconnectProcessing() {
99 expectHotplugReceived<Case, false>(mEventThread);
100 expectHotplugReceived<Case, false>(mSFEventThread);
101 }
102
103 template <typename Case>
verifyDisplayIsConnected(const sp<IBinder> & displayToken)104 void DisplayTransactionCommitTest::verifyDisplayIsConnected(const sp<IBinder>& displayToken) {
105 // The display device should have been set up in the list of displays.
106 ASSERT_TRUE(hasDisplayDevice(displayToken));
107 const auto& display = getDisplayDevice(displayToken);
108
109 EXPECT_EQ(static_cast<bool>(Case::Display::SECURE), display.isSecure());
110 EXPECT_EQ(static_cast<bool>(Case::Display::PRIMARY), display.isPrimary());
111
112 std::optional<DisplayDeviceState::Physical> expectedPhysical;
113 if (Case::Display::CONNECTION_TYPE::value) {
114 const auto displayId = PhysicalDisplayId::tryCast(Case::Display::DISPLAY_ID::get());
115 ASSERT_TRUE(displayId);
116 const auto hwcDisplayId = Case::Display::HWC_DISPLAY_ID_OPT::value;
117 ASSERT_TRUE(hwcDisplayId);
118 expectedPhysical = {.id = *displayId, .hwcDisplayId = *hwcDisplayId};
119 }
120
121 // The display should have been set up in the current display state
122 ASSERT_TRUE(hasCurrentDisplayState(displayToken));
123 const auto& current = getCurrentDisplayState(displayToken);
124 EXPECT_EQ(static_cast<bool>(Case::Display::VIRTUAL), current.isVirtual());
125 EXPECT_EQ(expectedPhysical, current.physical);
126
127 // The display should have been set up in the drawing display state
128 ASSERT_TRUE(hasDrawingDisplayState(displayToken));
129 const auto& draw = getDrawingDisplayState(displayToken);
130 EXPECT_EQ(static_cast<bool>(Case::Display::VIRTUAL), draw.isVirtual());
131 EXPECT_EQ(expectedPhysical, draw.physical);
132 }
133
134 template <typename Case>
verifyPhysicalDisplayIsConnected()135 void DisplayTransactionCommitTest::verifyPhysicalDisplayIsConnected() {
136 // HWComposer should have an entry for the display
137 EXPECT_TRUE(hasPhysicalHwcDisplay(Case::Display::HWC_DISPLAY_ID));
138
139 // SF should have a display token.
140 const auto displayId = Case::Display::DISPLAY_ID::get();
141 ASSERT_TRUE(PhysicalDisplayId::tryCast(displayId));
142
143 const auto displayOpt = mFlinger.mutablePhysicalDisplays().get(displayId);
144 ASSERT_TRUE(displayOpt);
145
146 const auto& display = displayOpt->get();
147 EXPECT_EQ(Case::Display::CONNECTION_TYPE::value, display.snapshot().connectionType());
148
149 verifyDisplayIsConnected<Case>(display.token());
150 }
151
verifyDisplayIsNotConnected(const sp<IBinder> & displayToken)152 void DisplayTransactionCommitTest::verifyDisplayIsNotConnected(const sp<IBinder>& displayToken) {
153 EXPECT_FALSE(hasDisplayDevice(displayToken));
154 EXPECT_FALSE(hasCurrentDisplayState(displayToken));
155 EXPECT_FALSE(hasDrawingDisplayState(displayToken));
156 }
157
158 template <typename Case>
processesHotplugConnectCommon()159 void DisplayTransactionCommitTest::processesHotplugConnectCommon() {
160 // --------------------------------------------------------------------
161 // Preconditions
162
163 setupCommonPreconditions<Case>();
164
165 // A hotplug connect event is enqueued for a display
166 Case::Display::injectPendingHotplugEvent(this, Connection::CONNECTED);
167
168 // --------------------------------------------------------------------
169 // Call Expectations
170
171 setupCommonCallExpectationsForConnectProcessing<Case>();
172
173 // --------------------------------------------------------------------
174 // Invocation
175
176 mFlinger.configureAndCommit();
177
178 // --------------------------------------------------------------------
179 // Postconditions
180
181 verifyPhysicalDisplayIsConnected<Case>();
182
183 // --------------------------------------------------------------------
184 // Cleanup conditions
185
186 EXPECT_CALL(*mComposer,
187 setVsyncEnabled(Case::Display::HWC_DISPLAY_ID, IComposerClient::Vsync::DISABLE))
188 .WillOnce(Return(Error::NONE));
189 EXPECT_CALL(*mConsumer, consumerDisconnect()).WillOnce(Return(NO_ERROR));
190 }
191
192 template <typename Case>
ignoresHotplugConnectCommon()193 void DisplayTransactionCommitTest::ignoresHotplugConnectCommon() {
194 // --------------------------------------------------------------------
195 // Preconditions
196
197 setupCommonPreconditions<Case>();
198
199 // A hotplug connect event is enqueued for a display
200 Case::Display::injectPendingHotplugEvent(this, Connection::CONNECTED);
201
202 // --------------------------------------------------------------------
203 // Invocation
204
205 mFlinger.configureAndCommit();
206
207 // --------------------------------------------------------------------
208 // Postconditions
209
210 // HWComposer should not have an entry for the display
211 EXPECT_FALSE(hasPhysicalHwcDisplay(Case::Display::HWC_DISPLAY_ID));
212 }
213
214 template <typename Case>
processesHotplugDisconnectCommon()215 void DisplayTransactionCommitTest::processesHotplugDisconnectCommon() {
216 // --------------------------------------------------------------------
217 // Preconditions
218
219 setupCommonPreconditions<Case>();
220
221 // A hotplug disconnect event is enqueued for a display
222 Case::Display::injectPendingHotplugEvent(this, Connection::DISCONNECTED);
223
224 // The display is already completely set up.
225 Case::Display::injectHwcDisplay(this);
226 auto existing = Case::Display::makeFakeExistingDisplayInjector(this);
227 existing.inject();
228
229 // --------------------------------------------------------------------
230 // Call Expectations
231
232 EXPECT_CALL(*mComposer, getDisplayIdentificationData(Case::Display::HWC_DISPLAY_ID, _, _))
233 .Times(0);
234
235 setupCommonCallExpectationsForDisconnectProcessing<Case>();
236
237 // --------------------------------------------------------------------
238 // Invocation
239
240 mFlinger.configureAndCommit();
241
242 // --------------------------------------------------------------------
243 // Postconditions
244
245 // HWComposer should not have an entry for the display
246 EXPECT_FALSE(hasPhysicalHwcDisplay(Case::Display::HWC_DISPLAY_ID));
247
248 // SF should not have a PhysicalDisplay.
249 const auto displayId = Case::Display::DISPLAY_ID::get();
250 ASSERT_TRUE(PhysicalDisplayId::tryCast(displayId));
251 ASSERT_FALSE(mFlinger.mutablePhysicalDisplays().contains(displayId));
252
253 // The existing token should have been removed.
254 verifyDisplayIsNotConnected(existing.token());
255 }
256
TEST_F(DisplayTransactionCommitTest,processesHotplugConnectPrimaryDisplay)257 TEST_F(DisplayTransactionCommitTest, processesHotplugConnectPrimaryDisplay) {
258 processesHotplugConnectCommon<SimplePrimaryDisplayCase>();
259 }
260
TEST_F(DisplayTransactionCommitTest,processesHotplugConnectExternalDisplay)261 TEST_F(DisplayTransactionCommitTest, processesHotplugConnectExternalDisplay) {
262 // Inject a primary display.
263 PrimaryDisplayVariant::injectHwcDisplay(this);
264
265 processesHotplugConnectCommon<SimpleExternalDisplayCase>();
266 }
267
TEST_F(DisplayTransactionCommitTest,ignoresHotplugConnectIfPrimaryAndExternalAlreadyConnected)268 TEST_F(DisplayTransactionCommitTest, ignoresHotplugConnectIfPrimaryAndExternalAlreadyConnected) {
269 // Inject both a primary and external display.
270 PrimaryDisplayVariant::injectHwcDisplay(this);
271 ExternalDisplayVariant::injectHwcDisplay(this);
272
273 // TODO: This is an unnecessary call.
274 EXPECT_CALL(*mComposer,
275 getDisplayIdentificationData(TertiaryDisplayVariant::HWC_DISPLAY_ID, _, _))
276 .WillOnce(DoAll(SetArgPointee<1>(TertiaryDisplay::PORT),
277 SetArgPointee<2>(TertiaryDisplay::GET_IDENTIFICATION_DATA()),
278 Return(Error::NONE)));
279
280 ignoresHotplugConnectCommon<SimpleTertiaryDisplayCase>();
281 }
282
TEST_F(DisplayTransactionCommitTest,processesHotplugDisconnectPrimaryDisplay)283 TEST_F(DisplayTransactionCommitTest, processesHotplugDisconnectPrimaryDisplay) {
284 EXPECT_EXIT(processesHotplugDisconnectCommon<SimplePrimaryDisplayCase>(),
285 testing::KilledBySignal(SIGABRT), "Primary display cannot be disconnected.");
286 }
287
TEST_F(DisplayTransactionCommitTest,processesHotplugDisconnectExternalDisplay)288 TEST_F(DisplayTransactionCommitTest, processesHotplugDisconnectExternalDisplay) {
289 processesHotplugDisconnectCommon<SimpleExternalDisplayCase>();
290 }
291
TEST_F(DisplayTransactionCommitTest,processesHotplugConnectThenDisconnectPrimary)292 TEST_F(DisplayTransactionCommitTest, processesHotplugConnectThenDisconnectPrimary) {
293 EXPECT_EXIT(
294 [this] {
295 using Case = SimplePrimaryDisplayCase;
296
297 // --------------------------------------------------------------------
298 // Preconditions
299
300 setupCommonPreconditions<Case>();
301
302 // A hotplug connect event is enqueued for a display
303 Case::Display::injectPendingHotplugEvent(this, Connection::CONNECTED);
304 // A hotplug disconnect event is also enqueued for the same display
305 Case::Display::injectPendingHotplugEvent(this, Connection::DISCONNECTED);
306
307 // --------------------------------------------------------------------
308 // Call Expectations
309
310 setupCommonCallExpectationsForConnectProcessing<Case>();
311 setupCommonCallExpectationsForDisconnectProcessing<Case>();
312
313 EXPECT_CALL(*mComposer,
314 setVsyncEnabled(Case::Display::HWC_DISPLAY_ID,
315 IComposerClient::Vsync::DISABLE))
316 .WillOnce(Return(Error::NONE));
317 EXPECT_CALL(*mConsumer, consumerDisconnect()).WillOnce(Return(NO_ERROR));
318
319 // --------------------------------------------------------------------
320 // Invocation
321
322 mFlinger.configureAndCommit();
323
324 // --------------------------------------------------------------------
325 // Postconditions
326
327 // HWComposer should not have an entry for the display
328 EXPECT_FALSE(hasPhysicalHwcDisplay(Case::Display::HWC_DISPLAY_ID));
329
330 // SF should not have a PhysicalDisplay.
331 const auto displayId = Case::Display::DISPLAY_ID::get();
332 ASSERT_TRUE(PhysicalDisplayId::tryCast(displayId));
333 ASSERT_FALSE(mFlinger.mutablePhysicalDisplays().contains(displayId));
334 }(),
335 testing::KilledBySignal(SIGABRT), "Primary display cannot be disconnected.");
336 }
337
TEST_F(DisplayTransactionCommitTest,processesHotplugDisconnectThenConnectPrimary)338 TEST_F(DisplayTransactionCommitTest, processesHotplugDisconnectThenConnectPrimary) {
339 EXPECT_EXIT(
340 [this] {
341 using Case = SimplePrimaryDisplayCase;
342
343 // --------------------------------------------------------------------
344 // Preconditions
345
346 setupCommonPreconditions<Case>();
347
348 // The display is already completely set up.
349 Case::Display::injectHwcDisplay(this);
350 auto existing = Case::Display::makeFakeExistingDisplayInjector(this);
351 existing.inject();
352
353 // A hotplug disconnect event is enqueued for a display
354 Case::Display::injectPendingHotplugEvent(this, Connection::DISCONNECTED);
355 // A hotplug connect event is also enqueued for the same display
356 Case::Display::injectPendingHotplugEvent(this, Connection::CONNECTED);
357
358 // --------------------------------------------------------------------
359 // Call Expectations
360
361 setupCommonCallExpectationsForConnectProcessing<Case>();
362 setupCommonCallExpectationsForDisconnectProcessing<Case>();
363
364 // --------------------------------------------------------------------
365 // Invocation
366
367 mFlinger.configureAndCommit();
368
369 // --------------------------------------------------------------------
370 // Postconditions
371
372 // The existing token should have been removed.
373 verifyDisplayIsNotConnected(existing.token());
374 const auto displayId = Case::Display::DISPLAY_ID::get();
375 ASSERT_TRUE(PhysicalDisplayId::tryCast(displayId));
376
377 const auto displayOpt = mFlinger.mutablePhysicalDisplays().get(displayId);
378 ASSERT_TRUE(displayOpt);
379 EXPECT_NE(existing.token(), displayOpt->get().token());
380
381 // A new display should be connected in its place.
382 verifyPhysicalDisplayIsConnected<Case>();
383
384 // --------------------------------------------------------------------
385 // Cleanup conditions
386
387 EXPECT_CALL(*mComposer,
388 setVsyncEnabled(Case::Display::HWC_DISPLAY_ID,
389 IComposerClient::Vsync::DISABLE))
390 .WillOnce(Return(Error::NONE));
391 EXPECT_CALL(*mConsumer, consumerDisconnect()).WillOnce(Return(NO_ERROR));
392 }(),
393 testing::KilledBySignal(SIGABRT), "Primary display cannot be disconnected.");
394 }
395
TEST_F(DisplayTransactionCommitTest,processesVirtualDisplayAdded)396 TEST_F(DisplayTransactionCommitTest, processesVirtualDisplayAdded) {
397 using Case = HwcVirtualDisplayCase;
398
399 // --------------------------------------------------------------------
400 // Preconditions
401
402 // The HWC supports at least one virtual display
403 injectMockComposer(1);
404
405 setupCommonPreconditions<Case>();
406
407 // A virtual display was added to the current state, and it has a
408 // surface(producer)
409 sp<BBinder> displayToken = sp<BBinder>::make();
410
411 DisplayDeviceState state;
412 state.isSecure = static_cast<bool>(Case::Display::SECURE);
413
414 sp<mock::GraphicBufferProducer> surface{sp<mock::GraphicBufferProducer>::make()};
415 state.surface = surface;
416 mFlinger.mutableCurrentState().displays.add(displayToken, state);
417
418 // --------------------------------------------------------------------
419 // Call Expectations
420
421 Case::Display::setupFramebufferConsumerBufferQueueCallExpectations(this);
422 Case::Display::setupNativeWindowSurfaceCreationCallExpectations(this);
423
424 EXPECT_CALL(*surface, query(NATIVE_WINDOW_WIDTH, _))
425 .WillRepeatedly(DoAll(SetArgPointee<1>(Case::Display::WIDTH), Return(NO_ERROR)));
426 EXPECT_CALL(*surface, query(NATIVE_WINDOW_HEIGHT, _))
427 .WillRepeatedly(DoAll(SetArgPointee<1>(Case::Display::HEIGHT), Return(NO_ERROR)));
428 EXPECT_CALL(*surface, query(NATIVE_WINDOW_FORMAT, _))
429 .WillRepeatedly(DoAll(SetArgPointee<1>(DEFAULT_VIRTUAL_DISPLAY_SURFACE_FORMAT),
430 Return(NO_ERROR)));
431 EXPECT_CALL(*surface, query(NATIVE_WINDOW_CONSUMER_USAGE_BITS, _))
432 .WillRepeatedly(DoAll(SetArgPointee<1>(0), Return(NO_ERROR)));
433
434 EXPECT_CALL(*surface, setAsyncMode(true)).Times(1);
435
436 EXPECT_CALL(*mProducer, connect(_, NATIVE_WINDOW_API_EGL, false, _)).Times(1);
437 EXPECT_CALL(*mProducer, disconnect(_, _)).Times(1);
438
439 Case::Display::setupHwcVirtualDisplayCreationCallExpectations(this);
440 Case::WideColorSupport::setupComposerCallExpectations(this);
441 Case::HdrSupport::setupComposerCallExpectations(this);
442 Case::PerFrameMetadataSupport::setupComposerCallExpectations(this);
443
444 // --------------------------------------------------------------------
445 // Invocation
446
447 mFlinger.commitTransactionsLocked(eDisplayTransactionNeeded);
448
449 // --------------------------------------------------------------------
450 // Postconditions
451
452 // The display device should have been set up in the list of displays.
453 verifyDisplayIsConnected<Case>(displayToken);
454
455 // --------------------------------------------------------------------
456 // Cleanup conditions
457
458 EXPECT_CALL(*mComposer, destroyVirtualDisplay(Case::Display::HWC_DISPLAY_ID))
459 .WillOnce(Return(Error::NONE));
460 EXPECT_CALL(*mConsumer, consumerDisconnect()).WillOnce(Return(NO_ERROR));
461
462 // Cleanup
463 mFlinger.mutableCurrentState().displays.removeItem(displayToken);
464 mFlinger.mutableDrawingState().displays.removeItem(displayToken);
465 }
466
TEST_F(DisplayTransactionCommitTest,processesVirtualDisplayAddedWithNoSurface)467 TEST_F(DisplayTransactionCommitTest, processesVirtualDisplayAddedWithNoSurface) {
468 using Case = HwcVirtualDisplayCase;
469
470 // --------------------------------------------------------------------
471 // Preconditions
472
473 // The HWC supports at least one virtual display
474 injectMockComposer(1);
475
476 setupCommonPreconditions<Case>();
477
478 // A virtual display was added to the current state, but it does not have a
479 // surface.
480 sp<BBinder> displayToken = sp<BBinder>::make();
481
482 DisplayDeviceState state;
483 state.isSecure = static_cast<bool>(Case::Display::SECURE);
484
485 mFlinger.mutableCurrentState().displays.add(displayToken, state);
486
487 // --------------------------------------------------------------------
488 // Call Expectations
489
490 // --------------------------------------------------------------------
491 // Invocation
492
493 mFlinger.commitTransactionsLocked(eDisplayTransactionNeeded);
494
495 // --------------------------------------------------------------------
496 // Postconditions
497
498 // There will not be a display device set up.
499 EXPECT_FALSE(hasDisplayDevice(displayToken));
500
501 // The drawing display state will be set from the current display state.
502 ASSERT_TRUE(hasDrawingDisplayState(displayToken));
503 const auto& draw = getDrawingDisplayState(displayToken);
504 EXPECT_EQ(static_cast<bool>(Case::Display::VIRTUAL), draw.isVirtual());
505 }
506
TEST_F(DisplayTransactionCommitTest,processesVirtualDisplayRemoval)507 TEST_F(DisplayTransactionCommitTest, processesVirtualDisplayRemoval) {
508 using Case = HwcVirtualDisplayCase;
509
510 // --------------------------------------------------------------------
511 // Preconditions
512
513 // A virtual display is set up but is removed from the current state.
514 const auto displayId = Case::Display::DISPLAY_ID::get();
515 ASSERT_TRUE(HalVirtualDisplayId::tryCast(displayId));
516 mFlinger.mutableHwcDisplayData().try_emplace(displayId);
517 Case::Display::injectHwcDisplay(this);
518 auto existing = Case::Display::makeFakeExistingDisplayInjector(this);
519 existing.inject();
520 mFlinger.mutableCurrentState().displays.removeItem(existing.token());
521
522 // --------------------------------------------------------------------
523 // Invocation
524
525 mFlinger.commitTransactionsLocked(eDisplayTransactionNeeded);
526
527 // --------------------------------------------------------------------
528 // Postconditions
529
530 // The existing token should have been removed
531 verifyDisplayIsNotConnected(existing.token());
532 }
533
TEST_F(DisplayTransactionCommitTest,processesDisplayLayerStackChanges)534 TEST_F(DisplayTransactionCommitTest, processesDisplayLayerStackChanges) {
535 using Case = NonHwcVirtualDisplayCase;
536
537 constexpr ui::LayerStack oldLayerStack = ui::DEFAULT_LAYER_STACK;
538 constexpr ui::LayerStack newLayerStack{123u};
539
540 // --------------------------------------------------------------------
541 // Preconditions
542
543 // A display is set up
544 auto display = Case::Display::makeFakeExistingDisplayInjector(this);
545 display.inject();
546
547 // There is a change to the layerStack state
548 display.mutableDrawingDisplayState().layerStack = oldLayerStack;
549 display.mutableCurrentDisplayState().layerStack = newLayerStack;
550
551 // --------------------------------------------------------------------
552 // Invocation
553
554 mFlinger.commitTransactionsLocked(eDisplayTransactionNeeded);
555
556 // --------------------------------------------------------------------
557 // Postconditions
558
559 EXPECT_EQ(newLayerStack, display.mutableDisplayDevice()->getLayerStack());
560 }
561
TEST_F(DisplayTransactionCommitTest,processesDisplayTransformChanges)562 TEST_F(DisplayTransactionCommitTest, processesDisplayTransformChanges) {
563 using Case = NonHwcVirtualDisplayCase;
564
565 constexpr ui::Rotation oldTransform = ui::ROTATION_0;
566 constexpr ui::Rotation newTransform = ui::ROTATION_180;
567
568 // --------------------------------------------------------------------
569 // Preconditions
570
571 // A display is set up
572 auto display = Case::Display::makeFakeExistingDisplayInjector(this);
573 display.inject();
574
575 // There is a change to the orientation state
576 display.mutableDrawingDisplayState().orientation = oldTransform;
577 display.mutableCurrentDisplayState().orientation = newTransform;
578
579 // --------------------------------------------------------------------
580 // Invocation
581
582 mFlinger.commitTransactionsLocked(eDisplayTransactionNeeded);
583
584 // --------------------------------------------------------------------
585 // Postconditions
586
587 EXPECT_EQ(newTransform, display.mutableDisplayDevice()->getOrientation());
588 }
589
TEST_F(DisplayTransactionCommitTest,processesDisplayLayerStackRectChanges)590 TEST_F(DisplayTransactionCommitTest, processesDisplayLayerStackRectChanges) {
591 using Case = NonHwcVirtualDisplayCase;
592
593 const Rect oldLayerStackRect(0, 0, 0, 0);
594 const Rect newLayerStackRect(0, 0, 123, 456);
595
596 // --------------------------------------------------------------------
597 // Preconditions
598
599 // A display is set up
600 auto display = Case::Display::makeFakeExistingDisplayInjector(this);
601 display.inject();
602
603 // There is a change to the layerStackSpaceRect state
604 display.mutableDrawingDisplayState().layerStackSpaceRect = oldLayerStackRect;
605 display.mutableCurrentDisplayState().layerStackSpaceRect = newLayerStackRect;
606
607 // --------------------------------------------------------------------
608 // Invocation
609
610 mFlinger.commitTransactionsLocked(eDisplayTransactionNeeded);
611
612 // --------------------------------------------------------------------
613 // Postconditions
614
615 EXPECT_EQ(newLayerStackRect, display.mutableDisplayDevice()->getLayerStackSpaceRect());
616 }
617
TEST_F(DisplayTransactionCommitTest,processesDisplayRectChanges)618 TEST_F(DisplayTransactionCommitTest, processesDisplayRectChanges) {
619 using Case = NonHwcVirtualDisplayCase;
620
621 const Rect oldDisplayRect(0, 0);
622 const Rect newDisplayRect(123, 456);
623
624 // --------------------------------------------------------------------
625 // Preconditions
626
627 // A display is set up
628 auto display = Case::Display::makeFakeExistingDisplayInjector(this);
629 display.inject();
630
631 // There is a change to the layerStackSpaceRect state
632 display.mutableDrawingDisplayState().orientedDisplaySpaceRect = oldDisplayRect;
633 display.mutableCurrentDisplayState().orientedDisplaySpaceRect = newDisplayRect;
634
635 // --------------------------------------------------------------------
636 // Invocation
637
638 mFlinger.commitTransactionsLocked(eDisplayTransactionNeeded);
639
640 // --------------------------------------------------------------------
641 // Postconditions
642
643 EXPECT_EQ(newDisplayRect, display.mutableDisplayDevice()->getOrientedDisplaySpaceRect());
644 }
645
TEST_F(DisplayTransactionCommitTest,processesDisplayWidthChanges)646 TEST_F(DisplayTransactionCommitTest, processesDisplayWidthChanges) {
647 using Case = NonHwcVirtualDisplayCase;
648
649 constexpr int oldWidth = 0;
650 constexpr int oldHeight = 10;
651 constexpr int newWidth = 123;
652
653 // --------------------------------------------------------------------
654 // Preconditions
655
656 // A display is set up
657 auto nativeWindow = sp<mock::NativeWindow>::make();
658 auto displaySurface = sp<compositionengine::mock::DisplaySurface>::make();
659 sp<GraphicBuffer> buf =
660
661 sp<GraphicBuffer>::make();
662 auto display = Case::Display::makeFakeExistingDisplayInjector(this);
663 display.setNativeWindow(nativeWindow);
664 display.setDisplaySurface(displaySurface);
665 // Setup injection expectations
666 EXPECT_CALL(*nativeWindow, query(NATIVE_WINDOW_WIDTH, _))
667 .WillOnce(DoAll(SetArgPointee<1>(oldWidth), Return(0)));
668 EXPECT_CALL(*nativeWindow, query(NATIVE_WINDOW_HEIGHT, _))
669 .WillOnce(DoAll(SetArgPointee<1>(oldHeight), Return(0)));
670 EXPECT_CALL(*nativeWindow, perform(NATIVE_WINDOW_SET_BUFFERS_FORMAT)).Times(1);
671 EXPECT_CALL(*nativeWindow, perform(NATIVE_WINDOW_API_CONNECT)).Times(1);
672 EXPECT_CALL(*nativeWindow, perform(NATIVE_WINDOW_SET_USAGE64)).Times(1);
673 EXPECT_CALL(*nativeWindow, perform(NATIVE_WINDOW_API_DISCONNECT)).Times(1);
674 display.inject();
675
676 // There is a change to the layerStackSpaceRect state
677 display.mutableDrawingDisplayState().width = oldWidth;
678 display.mutableDrawingDisplayState().height = oldHeight;
679 display.mutableCurrentDisplayState().width = newWidth;
680 display.mutableCurrentDisplayState().height = oldHeight;
681
682 // --------------------------------------------------------------------
683 // Call Expectations
684
685 EXPECT_CALL(*displaySurface, resizeBuffers(ui::Size(newWidth, oldHeight))).Times(1);
686
687 // --------------------------------------------------------------------
688 // Invocation
689
690 mFlinger.commitTransactionsLocked(eDisplayTransactionNeeded);
691 }
692
TEST_F(DisplayTransactionCommitTest,processesDisplayHeightChanges)693 TEST_F(DisplayTransactionCommitTest, processesDisplayHeightChanges) {
694 using Case = NonHwcVirtualDisplayCase;
695
696 constexpr int oldWidth = 0;
697 constexpr int oldHeight = 10;
698 constexpr int newHeight = 123;
699
700 // --------------------------------------------------------------------
701 // Preconditions
702
703 // A display is set up
704 auto nativeWindow = sp<mock::NativeWindow>::make();
705 auto displaySurface = sp<compositionengine::mock::DisplaySurface>::make();
706 sp<GraphicBuffer> buf = sp<GraphicBuffer>::make();
707 auto display = Case::Display::makeFakeExistingDisplayInjector(this);
708 display.setNativeWindow(nativeWindow);
709 display.setDisplaySurface(displaySurface);
710 // Setup injection expectations
711 EXPECT_CALL(*nativeWindow, query(NATIVE_WINDOW_WIDTH, _))
712 .WillOnce(DoAll(SetArgPointee<1>(oldWidth), Return(0)));
713 EXPECT_CALL(*nativeWindow, query(NATIVE_WINDOW_HEIGHT, _))
714 .WillOnce(DoAll(SetArgPointee<1>(oldHeight), Return(0)));
715 EXPECT_CALL(*nativeWindow, perform(NATIVE_WINDOW_SET_BUFFERS_FORMAT)).Times(1);
716 EXPECT_CALL(*nativeWindow, perform(NATIVE_WINDOW_API_CONNECT)).Times(1);
717 EXPECT_CALL(*nativeWindow, perform(NATIVE_WINDOW_SET_USAGE64)).Times(1);
718 EXPECT_CALL(*nativeWindow, perform(NATIVE_WINDOW_API_DISCONNECT)).Times(1);
719 display.inject();
720
721 // There is a change to the layerStackSpaceRect state
722 display.mutableDrawingDisplayState().width = oldWidth;
723 display.mutableDrawingDisplayState().height = oldHeight;
724 display.mutableCurrentDisplayState().width = oldWidth;
725 display.mutableCurrentDisplayState().height = newHeight;
726
727 // --------------------------------------------------------------------
728 // Call Expectations
729
730 EXPECT_CALL(*displaySurface, resizeBuffers(ui::Size(oldWidth, newHeight))).Times(1);
731
732 // --------------------------------------------------------------------
733 // Invocation
734
735 mFlinger.commitTransactionsLocked(eDisplayTransactionNeeded);
736 }
737
TEST_F(DisplayTransactionCommitTest,processesDisplaySizeDisplayRectAndLayerStackRectChanges)738 TEST_F(DisplayTransactionCommitTest, processesDisplaySizeDisplayRectAndLayerStackRectChanges) {
739 using Case = NonHwcVirtualDisplayCase;
740
741 constexpr uint32_t kOldWidth = 567;
742 constexpr uint32_t kOldHeight = 456;
743 const auto kOldSize = Rect(kOldWidth, kOldHeight);
744
745 constexpr uint32_t kNewWidth = 234;
746 constexpr uint32_t kNewHeight = 123;
747 const auto kNewSize = Rect(kNewWidth, kNewHeight);
748
749 // --------------------------------------------------------------------
750 // Preconditions
751
752 // A display is set up
753 auto nativeWindow = sp<mock::NativeWindow>::make();
754 auto displaySurface = sp<compositionengine::mock::DisplaySurface>::make();
755 sp<GraphicBuffer> buf = sp<GraphicBuffer>::make();
756 auto display = Case::Display::makeFakeExistingDisplayInjector(this);
757 display.setNativeWindow(nativeWindow);
758 display.setDisplaySurface(displaySurface);
759 // Setup injection expectations
760 EXPECT_CALL(*nativeWindow, query(NATIVE_WINDOW_WIDTH, _))
761 .WillOnce(DoAll(SetArgPointee<1>(kOldWidth), Return(0)));
762 EXPECT_CALL(*nativeWindow, query(NATIVE_WINDOW_HEIGHT, _))
763 .WillOnce(DoAll(SetArgPointee<1>(kOldHeight), Return(0)));
764 display.inject();
765
766 // There is a change to the layerStackSpaceRect state
767 display.mutableDrawingDisplayState().width = kOldWidth;
768 display.mutableDrawingDisplayState().height = kOldHeight;
769 display.mutableDrawingDisplayState().layerStackSpaceRect = kOldSize;
770 display.mutableDrawingDisplayState().orientedDisplaySpaceRect = kOldSize;
771
772 display.mutableCurrentDisplayState().width = kNewWidth;
773 display.mutableCurrentDisplayState().height = kNewHeight;
774 display.mutableCurrentDisplayState().layerStackSpaceRect = kNewSize;
775 display.mutableCurrentDisplayState().orientedDisplaySpaceRect = kNewSize;
776
777 // --------------------------------------------------------------------
778 // Call Expectations
779
780 EXPECT_CALL(*displaySurface, resizeBuffers(kNewSize.getSize())).Times(1);
781
782 // --------------------------------------------------------------------
783 // Invocation
784
785 mFlinger.commitTransactionsLocked(eDisplayTransactionNeeded);
786
787 EXPECT_EQ(display.mutableDisplayDevice()->getBounds(), kNewSize);
788 EXPECT_EQ(display.mutableDisplayDevice()->getWidth(), kNewWidth);
789 EXPECT_EQ(display.mutableDisplayDevice()->getHeight(), kNewHeight);
790 EXPECT_EQ(display.mutableDisplayDevice()->getOrientedDisplaySpaceRect(), kNewSize);
791 EXPECT_EQ(display.mutableDisplayDevice()->getLayerStackSpaceRect(), kNewSize);
792 }
793
794 } // namespace
795 } // namespace android
796