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