@@ -66,7 +66,7 @@ TEST_F(HotplugTest, createsDisplaySnapshotsForDisplaysWithIdentificationData) {
6666 PrimaryDisplay::setupHwcGetActiveConfigCallExpectations (this );
6767 PrimaryDisplay::injectPendingHotplugEvent (this , HWComposer::HotplugEvent::Connected);
6868
69- // TODO( b/241286146): Remove this unnecessary call.
69+ // TODO: b/241286146 - Remove this unnecessary call.
7070 EXPECT_CALL (*mComposer ,
7171 setVsyncEnabled (PrimaryDisplay::HWC_DISPLAY_ID, IComposerClient::Vsync::DISABLE))
7272 .WillOnce (Return (Error::NONE));
@@ -77,12 +77,12 @@ TEST_F(HotplugTest, createsDisplaySnapshotsForDisplaysWithIdentificationData) {
7777 mFlinger .configure ();
7878
7979 // Configure an external display with identification info.
80- using ExternalDisplay = ExternalDisplayWithIdentificationVariant;
80+ using ExternalDisplay = ExternalDisplayWithIdentificationVariant<> ;
8181 ExternalDisplay::setupHwcHotplugCallExpectations (this );
8282 ExternalDisplay::setupHwcGetActiveConfigCallExpectations (this );
8383 ExternalDisplay::injectPendingHotplugEvent (this , HWComposer::HotplugEvent::Connected);
8484
85- // TODO( b/241286146): Remove this unnecessary call.
85+ // TODO: b/241286146 - Remove this unnecessary call.
8686 EXPECT_CALL (*mComposer ,
8787 setVsyncEnabled (ExternalDisplay::HWC_DISPLAY_ID, IComposerClient::Vsync::DISABLE))
8888 .WillOnce (Return (Error::NONE));
@@ -125,7 +125,7 @@ TEST_F(HotplugTest, createsDisplaySnapshotsForDisplaysWithoutIdentificationData)
125125 PrimaryDisplay::setupHwcGetActiveConfigCallExpectations (this );
126126 PrimaryDisplay::injectPendingHotplugEvent (this , HWComposer::HotplugEvent::Connected);
127127
128- // TODO( b/241286146): Remove this unnecessary call.
128+ // TODO: b/241286146 - Remove this unnecessary call.
129129 EXPECT_CALL (*mComposer ,
130130 setVsyncEnabled (PrimaryDisplay::HWC_DISPLAY_ID, IComposerClient::Vsync::DISABLE))
131131 .WillOnce (Return (Error::NONE));
@@ -136,12 +136,12 @@ TEST_F(HotplugTest, createsDisplaySnapshotsForDisplaysWithoutIdentificationData)
136136 mFlinger .configure ();
137137
138138 // Configure an external display with identification info.
139- using ExternalDisplay = ExternalDisplayWithIdentificationVariant;
139+ using ExternalDisplay = ExternalDisplayWithIdentificationVariant<> ;
140140 ExternalDisplay::setupHwcHotplugCallExpectations (this );
141141 ExternalDisplay::setupHwcGetActiveConfigCallExpectations (this );
142142 ExternalDisplay::injectPendingHotplugEvent (this , HWComposer::HotplugEvent::Connected);
143143
144- // TODO( b/241286146): Remove this unnecessary call.
144+ // TODO: b/241286146 - Remove this unnecessary call.
145145 EXPECT_CALL (*mComposer ,
146146 setVsyncEnabled (ExternalDisplay::HWC_DISPLAY_ID, IComposerClient::Vsync::DISABLE))
147147 .WillOnce (Return (Error::NONE));
@@ -198,7 +198,7 @@ TEST_F(HotplugTest, ignoresDuplicateDisconnection) {
198198 ExternalDisplay::setupHwcHotplugCallExpectations (this );
199199 ExternalDisplay::setupHwcGetActiveConfigCallExpectations (this );
200200
201- // TODO( b/241286146): Remove this unnecessary call.
201+ // TODO: b/241286146 - Remove this unnecessary call.
202202 EXPECT_CALL (*mComposer ,
203203 setVsyncEnabled (ExternalDisplay::HWC_DISPLAY_ID, IComposerClient::Vsync::DISABLE))
204204 .WillOnce (Return (Error::NONE));
@@ -242,7 +242,7 @@ TEST_F(HotplugTest, rejectsHotplugIfFailedToLoadDisplayModes) {
242242 EXPECT_CALL (*mComposer , getActiveConfig (ExternalDisplay::HWC_DISPLAY_ID, _))
243243 .WillRepeatedly (Return (Error::BAD_DISPLAY));
244244
245- // TODO( b/241286146): Remove this unnecessary call.
245+ // TODO: b/241286146 - Remove this unnecessary call.
246246 EXPECT_CALL (*mComposer ,
247247 setVsyncEnabled (ExternalDisplay::HWC_DISPLAY_ID, IComposerClient::Vsync::DISABLE))
248248 .WillOnce (Return (Error::NONE));
@@ -262,4 +262,53 @@ TEST_F(HotplugTest, rejectsHotplugIfFailedToLoadDisplayModes) {
262262 EXPECT_FALSE (hasPhysicalHwcDisplay (ExternalDisplay::HWC_DISPLAY_ID));
263263}
264264
265+ TEST_F (HotplugTest, rejectsHotplugOnActivePortsDuplicate) {
266+ SET_FLAG_FOR_TEST (flags::connected_display, true );
267+
268+ // Inject a primary display.
269+ PrimaryDisplayVariant::injectHwcDisplay (this );
270+
271+ // Second display should come up properly.
272+ using SecondDisplay = ExternalDisplayWithIdentificationVariant<>;
273+ SecondDisplay::setupHwcHotplugCallExpectations (this );
274+ SecondDisplay::setupHwcGetActiveConfigCallExpectations (this );
275+
276+ // TODO: b/241286146 - Remove this unnecessary call.
277+ EXPECT_CALL (*mComposer ,
278+ setVsyncEnabled (SecondDisplay::HWC_DISPLAY_ID, IComposerClient::Vsync::DISABLE))
279+ .WillOnce (Return (Error::NONE));
280+
281+ EXPECT_CALL (*mFlinger .scheduler (), scheduleFrame (_)).Times (1 );
282+
283+ SecondDisplay::injectPendingHotplugEvent (this , HWComposer::HotplugEvent::Connected);
284+ mFlinger .configure ();
285+
286+ EXPECT_TRUE (hasPhysicalHwcDisplay (SecondDisplay::HWC_DISPLAY_ID));
287+
288+ // Third display will return the same port ID as the second, and the hotplug
289+ // should fail.
290+ constexpr HWDisplayId kHwDisplayId = 1234 ;
291+ using DuplicatePortDisplay = ExternalDisplayWithIdentificationVariant<kHwDisplayId >;
292+
293+ // We expect display identification to be fetched correctly, since EDID and
294+ // port are available and successfully retrieved from HAL.
295+ EXPECT_CALL (*mComposer ,
296+ getDisplayIdentificationData (DuplicatePortDisplay::HWC_DISPLAY_ID, _, _))
297+ .WillOnce (DoAll (SetArgPointee<1 >(*DuplicatePortDisplay::PORT::value),
298+ SetArgPointee<2 >(getExternalEedid ()), Return (Error::NONE)));
299+
300+ DuplicatePortDisplay::injectPendingHotplugEvent (this , HWComposer::HotplugEvent::Connected);
301+ mFlinger .configure ();
302+
303+ // The hotplug should be rejected due to an attempt to connect a display to an already active
304+ // port. No HWComposer::DisplayData should be created.
305+ EXPECT_FALSE (hasPhysicalHwcDisplay (DuplicatePortDisplay::HWC_DISPLAY_ID));
306+
307+ // Disconnecting a display that was not successfully configured should be a no-op.
308+ DuplicatePortDisplay::injectPendingHotplugEvent (this , HWComposer::HotplugEvent::Disconnected);
309+ mFlinger .configure ();
310+
311+ EXPECT_FALSE (hasPhysicalHwcDisplay (DuplicatePortDisplay::HWC_DISPLAY_ID));
312+ }
313+
265314} // namespace android
0 commit comments