Loading services/surfaceflinger/DisplayHardware/HWComposer.cpp +7 −0 Original line number Diff line number Diff line Loading @@ -673,6 +673,13 @@ void HWComposer::disconnectDisplay(HalDisplayId displayId) { mPhysicalDisplayIdMap.erase(hwcDisplayId); mDisplayData.erase(displayId); // Reset the primary display ID if we're disconnecting it. // This way isHeadless() will return false, which is necessary // because getPrimaryDisplayId() will crash. if (mPrimaryHwcDisplayId == hwcDisplayId) { mPrimaryHwcDisplayId.reset(); } } status_t HWComposer::setOutputBuffer(HalVirtualDisplayId displayId, const sp<Fence>& acquireFence, Loading services/surfaceflinger/DisplayHardware/HWComposer.h +6 −3 Original line number Diff line number Diff line Loading @@ -236,9 +236,12 @@ public: virtual Hwc2::Composer* getComposer() const = 0; // Returns the first display connected at boot. It cannot be disconnected, which implies an // internal connection type. Its connection via HWComposer::onHotplug, which in practice is // immediately after HWComposer construction, must occur before any call to this function. // Returns the first display connected at boot. Its connection via HWComposer::onHotplug, // which in practice is immediately after HWComposer construction, must occur before any // call to this function. // The primary display can be temporarily disconnected from the perspective // of this class. Callers must not call getPrimaryHwcDisplayId() or getPrimaryDisplayId() // if isHeadless(). // // TODO(b/182939859): Remove special cases for primary display. virtual hal::HWDisplayId getPrimaryHwcDisplayId() const = 0; Loading services/surfaceflinger/tests/unittests/HWComposerTest.cpp +24 −0 Original line number Diff line number Diff line Loading @@ -36,6 +36,7 @@ #include "DisplayHardware/DisplayMode.h" #include "DisplayHardware/HWComposer.h" #include "DisplayHardware/Hal.h" #include "DisplayIdentificationTest.h" #include "mock/DisplayHardware/MockComposer.h" #include "mock/DisplayHardware/MockHWC2.h" Loading @@ -57,6 +58,29 @@ using ::testing::Return; using ::testing::SetArgPointee; using ::testing::StrictMock; TEST(HWComposerTest, isHeadless) { Hwc2::mock::Composer* mHal = new StrictMock<Hwc2::mock::Composer>(); impl::HWComposer hwc{std::unique_ptr<Hwc2::Composer>(mHal)}; ASSERT_TRUE(hwc.isHeadless()); const hal::HWDisplayId hwcId = 1; EXPECT_CALL(*mHal, getDisplayIdentificationData(_, _, _)) .WillOnce(DoAll(SetArgPointee<2>(getExternalEdid()), Return(hardware::graphics::composer::V2_1::Error::NONE))); EXPECT_CALL(*mHal, setVsyncEnabled(_, _)); EXPECT_CALL(*mHal, setClientTargetSlotCount(_)); auto info = hwc.onHotplug(hwcId, hal::Connection::CONNECTED); ASSERT_TRUE(info); auto displayId = info->id; ASSERT_FALSE(hwc.isHeadless()); hwc.disconnectDisplay(displayId); ASSERT_TRUE(hwc.isHeadless()); } struct MockHWC2ComposerCallback final : StrictMock<HWC2::ComposerCallback> { MOCK_METHOD2(onComposerHalHotplug, void(hal::HWDisplayId, hal::Connection)); MOCK_METHOD1(onComposerHalRefresh, void(hal::HWDisplayId)); Loading Loading
services/surfaceflinger/DisplayHardware/HWComposer.cpp +7 −0 Original line number Diff line number Diff line Loading @@ -673,6 +673,13 @@ void HWComposer::disconnectDisplay(HalDisplayId displayId) { mPhysicalDisplayIdMap.erase(hwcDisplayId); mDisplayData.erase(displayId); // Reset the primary display ID if we're disconnecting it. // This way isHeadless() will return false, which is necessary // because getPrimaryDisplayId() will crash. if (mPrimaryHwcDisplayId == hwcDisplayId) { mPrimaryHwcDisplayId.reset(); } } status_t HWComposer::setOutputBuffer(HalVirtualDisplayId displayId, const sp<Fence>& acquireFence, Loading
services/surfaceflinger/DisplayHardware/HWComposer.h +6 −3 Original line number Diff line number Diff line Loading @@ -236,9 +236,12 @@ public: virtual Hwc2::Composer* getComposer() const = 0; // Returns the first display connected at boot. It cannot be disconnected, which implies an // internal connection type. Its connection via HWComposer::onHotplug, which in practice is // immediately after HWComposer construction, must occur before any call to this function. // Returns the first display connected at boot. Its connection via HWComposer::onHotplug, // which in practice is immediately after HWComposer construction, must occur before any // call to this function. // The primary display can be temporarily disconnected from the perspective // of this class. Callers must not call getPrimaryHwcDisplayId() or getPrimaryDisplayId() // if isHeadless(). // // TODO(b/182939859): Remove special cases for primary display. virtual hal::HWDisplayId getPrimaryHwcDisplayId() const = 0; Loading
services/surfaceflinger/tests/unittests/HWComposerTest.cpp +24 −0 Original line number Diff line number Diff line Loading @@ -36,6 +36,7 @@ #include "DisplayHardware/DisplayMode.h" #include "DisplayHardware/HWComposer.h" #include "DisplayHardware/Hal.h" #include "DisplayIdentificationTest.h" #include "mock/DisplayHardware/MockComposer.h" #include "mock/DisplayHardware/MockHWC2.h" Loading @@ -57,6 +58,29 @@ using ::testing::Return; using ::testing::SetArgPointee; using ::testing::StrictMock; TEST(HWComposerTest, isHeadless) { Hwc2::mock::Composer* mHal = new StrictMock<Hwc2::mock::Composer>(); impl::HWComposer hwc{std::unique_ptr<Hwc2::Composer>(mHal)}; ASSERT_TRUE(hwc.isHeadless()); const hal::HWDisplayId hwcId = 1; EXPECT_CALL(*mHal, getDisplayIdentificationData(_, _, _)) .WillOnce(DoAll(SetArgPointee<2>(getExternalEdid()), Return(hardware::graphics::composer::V2_1::Error::NONE))); EXPECT_CALL(*mHal, setVsyncEnabled(_, _)); EXPECT_CALL(*mHal, setClientTargetSlotCount(_)); auto info = hwc.onHotplug(hwcId, hal::Connection::CONNECTED); ASSERT_TRUE(info); auto displayId = info->id; ASSERT_FALSE(hwc.isHeadless()); hwc.disconnectDisplay(displayId); ASSERT_TRUE(hwc.isHeadless()); } struct MockHWC2ComposerCallback final : StrictMock<HWC2::ComposerCallback> { MOCK_METHOD2(onComposerHalHotplug, void(hal::HWDisplayId, hal::Connection)); MOCK_METHOD1(onComposerHalRefresh, void(hal::HWDisplayId)); Loading