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