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