Unify hwc2_device_t and HWComposer.

HWComposer can already represent the built-in hardware composer capabilities, a
device notation is not needed. HWComposer now directly manages all displays and
owns the lifetime of all displays.  The next step is to explore whether we can
safely deprecate all hwcomposer2.h types inside SurfaceFlinger, move to HIDL
types and eventually use AIDL types.

BUG: b/77585359
Test: build, boot.
Change-Id: Id0f77b49aa441bdbf578302a04ae03b5573eb2aa
diff --git a/services/surfaceflinger/DisplayHardware/HWC2.cpp b/services/surfaceflinger/DisplayHardware/HWC2.cpp
index c4f91be..12b0ddd 100644
--- a/services/surfaceflinger/DisplayHardware/HWC2.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWC2.cpp
@@ -42,8 +42,6 @@
 using android::Rect;
 using android::Region;
 using android::sp;
-using android::hardware::Return;
-using android::hardware::Void;
 
 namespace HWC2 {
 
@@ -60,188 +58,8 @@
     return keys.find(key) != keys.end();
 }
 
-class ComposerCallbackBridge : public Hwc2::IComposerCallback {
-public:
-    ComposerCallbackBridge(ComposerCallback* callback, int32_t sequenceId,
-                           bool vsyncSwitchingSupported)
-          : mCallback(callback),
-            mSequenceId(sequenceId),
-            mVsyncSwitchingSupported(vsyncSwitchingSupported) {}
-
-    Return<void> onHotplug(Hwc2::Display display,
-                           IComposerCallback::Connection conn) override
-    {
-        HWC2::Connection connection = static_cast<HWC2::Connection>(conn);
-        mCallback->onHotplugReceived(mSequenceId, display, connection);
-        return Void();
-    }
-
-    Return<void> onRefresh(Hwc2::Display display) override
-    {
-        mCallback->onRefreshReceived(mSequenceId, display);
-        return Void();
-    }
-
-    Return<void> onVsync(Hwc2::Display display, int64_t timestamp) override
-    {
-        if (!mVsyncSwitchingSupported) {
-            mCallback->onVsyncReceived(mSequenceId, display, timestamp, std::nullopt);
-        } else {
-            ALOGW("Unexpected onVsync callback on composer >= 2.4, ignoring.");
-        }
-        return Void();
-    }
-
-    Return<void> onVsync_2_4(Hwc2::Display display, int64_t timestamp,
-                             Hwc2::VsyncPeriodNanos vsyncPeriodNanos) override {
-        if (mVsyncSwitchingSupported) {
-            // TODO(b/140201379): use vsyncPeriodNanos in the new DispSync
-            mCallback->onVsyncReceived(mSequenceId, display, timestamp,
-                                       std::make_optional(vsyncPeriodNanos));
-        } else {
-            ALOGW("Unexpected onVsync_2_4 callback on composer <= 2.3, ignoring.");
-        }
-        return Void();
-    }
-
-    Return<void> onVsyncPeriodTimingChanged(
-            Hwc2::Display display,
-            const Hwc2::VsyncPeriodChangeTimeline& updatedTimeline) override {
-        hwc_vsync_period_change_timeline_t timeline;
-        timeline.newVsyncAppliedTimeNanos = updatedTimeline.newVsyncAppliedTimeNanos;
-        timeline.refreshRequired = updatedTimeline.refreshRequired;
-        timeline.refreshTimeNanos = updatedTimeline.refreshTimeNanos;
-        mCallback->onVsyncPeriodTimingChangedReceived(mSequenceId, display, timeline);
-        return Void();
-    }
-
-private:
-    ComposerCallback* mCallback;
-    int32_t mSequenceId;
-    const bool mVsyncSwitchingSupported;
-};
-
 } // namespace anonymous
 
-
-// Device methods
-
-Device::Device(std::unique_ptr<android::Hwc2::Composer> composer) : mComposer(std::move(composer)) {
-    loadCapabilities();
-}
-
-void Device::registerCallback(ComposerCallback* callback, int32_t sequenceId) {
-    if (mRegisteredCallback) {
-        ALOGW("Callback already registered. Ignored extra registration "
-                "attempt.");
-        return;
-    }
-    mRegisteredCallback = true;
-    sp<ComposerCallbackBridge> callbackBridge(
-            new ComposerCallbackBridge(callback, sequenceId,
-                                       mComposer->isVsyncPeriodSwitchSupported()));
-    mComposer->registerCallback(callbackBridge);
-}
-
-// Required by HWC2 device
-
-std::string Device::dump() const
-{
-    return mComposer->dumpDebugInfo();
-}
-
-uint32_t Device::getMaxVirtualDisplayCount() const
-{
-    return mComposer->getMaxVirtualDisplayCount();
-}
-
-Error Device::getDisplayIdentificationData(hwc2_display_t hwcDisplayId, uint8_t* outPort,
-                                           std::vector<uint8_t>* outData) const {
-    auto intError = mComposer->getDisplayIdentificationData(hwcDisplayId, outPort, outData);
-    return static_cast<Error>(intError);
-}
-
-Error Device::createVirtualDisplay(uint32_t width, uint32_t height,
-        PixelFormat* format, Display** outDisplay)
-{
-    ALOGI("Creating virtual display");
-
-    hwc2_display_t displayId = 0;
-    auto intError = mComposer->createVirtualDisplay(width, height,
-            format, &displayId);
-    auto error = static_cast<Error>(intError);
-    if (error != Error::None) {
-        return error;
-    }
-
-    auto display = std::make_unique<impl::Display>(*mComposer.get(), mCapabilities, displayId,
-                                                   DisplayType::Virtual);
-    display->setConnected(true);
-    *outDisplay = display.get();
-    mDisplays.emplace(displayId, std::move(display));
-    ALOGI("Created virtual display");
-    return Error::None;
-}
-
-void Device::destroyDisplay(hwc2_display_t displayId)
-{
-    ALOGI("Destroying display %" PRIu64, displayId);
-    mDisplays.erase(displayId);
-}
-
-void Device::onHotplug(hwc2_display_t displayId, Connection connection) {
-    if (connection == Connection::Connected) {
-        // If we get a hotplug connected event for a display we already have,
-        // destroy the display and recreate it. This will force us to requery
-        // the display params and recreate all layers on that display.
-        auto oldDisplay = getDisplayById(displayId);
-        if (oldDisplay != nullptr && oldDisplay->isConnected()) {
-            ALOGI("Hotplug connecting an already connected display."
-                    " Clearing old display state.");
-        }
-        mDisplays.erase(displayId);
-
-        auto newDisplay = std::make_unique<impl::Display>(*mComposer.get(), mCapabilities,
-                                                          displayId, DisplayType::Physical);
-        newDisplay->setConnected(true);
-        mDisplays.emplace(displayId, std::move(newDisplay));
-    } else if (connection == Connection::Disconnected) {
-        // The display will later be destroyed by a call to
-        // destroyDisplay(). For now we just mark it disconnected.
-        auto display = getDisplayById(displayId);
-        if (display) {
-            display->setConnected(false);
-        } else {
-            ALOGW("Attempted to disconnect unknown display %" PRIu64,
-                  displayId);
-        }
-    }
-}
-
-// Other Device methods
-
-Display* Device::getDisplayById(hwc2_display_t id) {
-    auto iter = mDisplays.find(id);
-    return iter == mDisplays.end() ? nullptr : iter->second.get();
-}
-
-// Device initialization methods
-
-void Device::loadCapabilities()
-{
-    static_assert(sizeof(Capability) == sizeof(int32_t),
-            "Capability size has changed");
-    auto capabilities = mComposer->getCapabilities();
-    for (auto capability : capabilities) {
-        mCapabilities.emplace(static_cast<Capability>(capability));
-    }
-}
-
-Error Device::flushCommands()
-{
-    return static_cast<Error>(mComposer->executeCommands());
-}
-
 // Display methods
 Display::~Display() = default;
 
diff --git a/services/surfaceflinger/DisplayHardware/HWC2.h b/services/surfaceflinger/DisplayHardware/HWC2.h
index 59f36d0..8b532e3 100644
--- a/services/surfaceflinger/DisplayHardware/HWC2.h
+++ b/services/surfaceflinger/DisplayHardware/HWC2.h
@@ -52,7 +52,6 @@
 
 namespace HWC2 {
 
-class Display;
 class Layer;
 using VsyncPeriodChangeConstraints = hwc_vsync_period_change_constraints_t;
 using VsyncPeriodChangeTimeline = hwc_vsync_period_change_timeline_t;
@@ -81,56 +80,6 @@
     virtual ~ComposerCallback() = default;
 };
 
-// C++ Wrapper around hwc2_device_t. Load all functions pointers
-// and handle callback registration.
-class Device
-{
-public:
-    explicit Device(std::unique_ptr<android::Hwc2::Composer> composer);
-
-    void registerCallback(ComposerCallback* callback, int32_t sequenceId);
-
-    // Required by HWC2
-
-    std::string dump() const;
-
-    const std::unordered_set<Capability>& getCapabilities() const {
-        return mCapabilities;
-    };
-
-    uint32_t getMaxVirtualDisplayCount() const;
-    Error getDisplayIdentificationData(hwc2_display_t hwcDisplayId, uint8_t* outPort,
-                                       std::vector<uint8_t>* outData) const;
-
-    Error createVirtualDisplay(uint32_t width, uint32_t height,
-            android::ui::PixelFormat* format, Display** outDisplay);
-    void destroyDisplay(hwc2_display_t displayId);
-
-    void onHotplug(hwc2_display_t displayId, Connection connection);
-
-    // Other Device methods
-
-    Display* getDisplayById(hwc2_display_t id);
-
-    android::Hwc2::Composer* getComposer() { return mComposer.get(); }
-
-    // We buffer most state changes and flush them implicitly with
-    // Display::validate, Display::present, and Display::presentOrValidate.
-    // This method provides an explicit way to flush state changes to HWC.
-    Error flushCommands();
-
-private:
-    // Initialization methods
-
-    void loadCapabilities();
-
-    // Member variables
-    std::unique_ptr<android::Hwc2::Composer> mComposer;
-    std::unordered_set<Capability> mCapabilities;
-    std::unordered_map<hwc2_display_t, std::unique_ptr<Display>> mDisplays;
-    bool mRegisteredCallback = false;
-};
-
 // Convenience C++ class to access hwc2_device_t Display functions directly.
 class Display {
 public:
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
index 9accefb..0a7009b 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
@@ -65,14 +65,88 @@
 #define RETURN_IF_HWC_ERROR(error, displayId, ...) \
     RETURN_IF_HWC_ERROR_FOR(__FUNCTION__, error, displayId, __VA_ARGS__)
 
+namespace {
+
+using android::hardware::Return;
+using android::hardware::Void;
+
+class ComposerCallbackBridge : public android::Hwc2::IComposerCallback {
+public:
+    ComposerCallbackBridge(HWC2::ComposerCallback* callback, int32_t sequenceId,
+                           bool vsyncSwitchingSupported)
+          : mCallback(callback),
+            mSequenceId(sequenceId),
+            mVsyncSwitchingSupported(vsyncSwitchingSupported) {}
+
+    android::hardware::Return<void> onHotplug(
+            android::Hwc2::Display display,
+            android::Hwc2::IComposerCallback::Connection conn) override {
+        HWC2::Connection connection = static_cast<HWC2::Connection>(conn);
+        mCallback->onHotplugReceived(mSequenceId, display, connection);
+        return android::hardware::Void();
+    }
+
+    android::hardware::Return<void> onRefresh(android::Hwc2::Display display) override {
+        mCallback->onRefreshReceived(mSequenceId, display);
+        return android::hardware::Void();
+    }
+
+    android::hardware::Return<void> onVsync(android::Hwc2::Display display,
+                                            int64_t timestamp) override {
+        if (!mVsyncSwitchingSupported) {
+            mCallback->onVsyncReceived(mSequenceId, display, timestamp, std::nullopt);
+        } else {
+            ALOGW("Unexpected onVsync callback on composer >= 2.4, ignoring.");
+        }
+        return android::hardware::Void();
+    }
+
+    android::hardware::Return<void> onVsync_2_4(
+            android::Hwc2::Display display, int64_t timestamp,
+            android::Hwc2::VsyncPeriodNanos vsyncPeriodNanos) override {
+        if (mVsyncSwitchingSupported) {
+            // TODO(b/140201379): use vsyncPeriodNanos in the new DispSync
+            mCallback->onVsyncReceived(mSequenceId, display, timestamp,
+                                       std::make_optional(vsyncPeriodNanos));
+        } else {
+            ALOGW("Unexpected onVsync_2_4 callback on composer <= 2.3, ignoring.");
+        }
+        return android::hardware::Void();
+    }
+
+    android::hardware::Return<void> onVsyncPeriodTimingChanged(
+            android::Hwc2::Display display,
+            const android::Hwc2::VsyncPeriodChangeTimeline& updatedTimeline) override {
+        hwc_vsync_period_change_timeline_t timeline;
+        timeline.newVsyncAppliedTimeNanos = updatedTimeline.newVsyncAppliedTimeNanos;
+        timeline.refreshRequired = updatedTimeline.refreshRequired;
+        timeline.refreshTimeNanos = updatedTimeline.refreshTimeNanos;
+        mCallback->onVsyncPeriodTimingChangedReceived(mSequenceId, display, timeline);
+        return android::hardware::Void();
+    }
+
+private:
+    HWC2::ComposerCallback* mCallback;
+    const int32_t mSequenceId;
+    const bool mVsyncSwitchingSupported;
+};
+
+} // namespace
+
 namespace android {
 
 HWComposer::~HWComposer() = default;
 
 namespace impl {
 
-HWComposer::HWComposer(std::unique_ptr<Hwc2::Composer> composer)
-      : mHwcDevice(std::make_unique<HWC2::Device>(std::move(composer))) {}
+HWComposer::HWComposer(std::unique_ptr<Hwc2::Composer> composer) : mComposer(std::move(composer)) {
+    loadCapabilities();
+}
+
+HWComposer::HWComposer(const std::string& composerServiceName)
+      : mComposer(std::make_unique<Hwc2::impl::Composer>(composerServiceName)) {
+    loadCapabilities();
+}
 
 HWComposer::~HWComposer() {
     mDisplayData.clear();
@@ -80,12 +154,21 @@
 
 void HWComposer::registerCallback(HWC2::ComposerCallback* callback,
                                   int32_t sequenceId) {
-    mHwcDevice->registerCallback(callback, sequenceId);
+    if (mRegisteredCallback) {
+        ALOGW("Callback already registered. Ignored extra registration attempt.");
+        return;
+    }
+    mRegisteredCallback = true;
+    sp<ComposerCallbackBridge> callbackBridge(
+            new ComposerCallbackBridge(callback, sequenceId,
+                                       mComposer->isVsyncPeriodSwitchSupported()));
+    mComposer->registerCallback(callbackBridge);
 }
 
 bool HWComposer::getDisplayIdentificationData(hwc2_display_t hwcDisplayId, uint8_t* outPort,
                                               DisplayIdentificationData* outData) const {
-    const auto error = mHwcDevice->getDisplayIdentificationData(hwcDisplayId, outPort, outData);
+    const auto error = static_cast<HWC2::Error>(
+            mComposer->getDisplayIdentificationData(hwcDisplayId, outPort, outData));
     if (error != HWC2::Error::None) {
         if (error != HWC2::Error::Unsupported) {
             LOG_HWC_DISPLAY_ERROR(hwcDisplayId, to_string(error).c_str());
@@ -95,9 +178,8 @@
     return true;
 }
 
-bool HWComposer::hasCapability(HWC2::Capability capability) const
-{
-    return mHwcDevice->getCapabilities().count(capability) > 0;
+bool HWComposer::hasCapability(HWC2::Capability capability) const {
+    return mCapabilities.count(capability) > 0;
 }
 
 bool HWComposer::hasDisplayCapability(const std::optional<DisplayId>& displayId,
@@ -133,13 +215,33 @@
           hwcDisplayId == mInternalHwcDisplayId ? "internal" : "external",
           to_string(info->id).c_str(), hwcDisplayId);
 
-    mHwcDevice->onHotplug(hwcDisplayId, connection);
-
-    // Disconnect is handled through HWComposer::disconnectDisplay via
-    // SurfaceFlinger's onHotplugReceived callback handling
     if (connection == HWC2::Connection::Connected) {
-        mDisplayData[info->id].hwcDisplay = mHwcDevice->getDisplayById(hwcDisplayId);
+        auto& displayData = mDisplayData[info->id];
+        // If we get a hotplug connected event for a display we already have,
+        // destroy the display and recreate it. This will force us to requery
+        // the display params and recreate all layers on that display.
+        if (displayData.hwcDisplay != nullptr && displayData.hwcDisplay->isConnected()) {
+            ALOGI("Hotplug connecting an already connected display."
+                  " Clearing old display state.");
+        }
+        displayData.hwcDisplay.reset();
+        auto newDisplay =
+                std::make_unique<HWC2::impl::Display>(*mComposer.get(), mCapabilities, hwcDisplayId,
+                                                      HWC2::DisplayType::Physical);
+        newDisplay->setConnected(true);
+        displayData.hwcDisplay = std::move(newDisplay);
         mPhysicalDisplayIdMap[hwcDisplayId] = info->id;
+    } else if (connection == HWC2::Connection::Disconnected) {
+        // The display will later be destroyed by a call to
+        // destroyDisplay(). For now we just mark it disconnected.
+        auto& displayData = mDisplayData[info->id];
+        if (displayData.hwcDisplay) {
+            displayData.hwcDisplay->setConnected(false);
+        } else {
+            ALOGW("Attempted to disconnect unknown display %" PRIu64, hwcDisplayId);
+        }
+        // The cleanup of Disconnect is handled through HWComposer::disconnectDisplay
+        // via SurfaceFlinger's onHotplugReceived callback handling
     }
 
     return info;
@@ -197,14 +299,18 @@
               height, SurfaceFlinger::maxVirtualDisplaySize);
         return {};
     }
-    HWC2::Display* display;
-    auto error = mHwcDevice->createVirtualDisplay(width, height, format,
-            &display);
+    hwc2_display_t hwcDisplayId = 0;
+    const auto error = static_cast<HWC2::Error>(
+            mComposer->createVirtualDisplay(width, height, format, &hwcDisplayId));
     if (error != HWC2::Error::None) {
         ALOGE("%s: Failed to create HWC virtual display", __FUNCTION__);
         return {};
     }
 
+    auto display = std::make_unique<HWC2::impl::Display>(*mComposer.get(), mCapabilities,
+                                                         hwcDisplayId, HWC2::DisplayType::Virtual);
+    display->setConnected(true);
+
     DisplayId displayId;
     if (mFreeVirtualDisplayIds.empty()) {
         displayId = getVirtualDisplayId(mNextVirtualDisplayId++);
@@ -214,7 +320,7 @@
     }
 
     auto& displayData = mDisplayData[displayId];
-    displayData.hwcDisplay = display;
+    displayData.hwcDisplay = std::move(display);
     displayData.isVirtual = true;
 
     --mRemainingHwcVirtualDisplays;
@@ -224,9 +330,8 @@
 HWC2::Layer* HWComposer::createLayer(DisplayId displayId) {
     RETURN_IF_INVALID_DISPLAY(displayId, nullptr);
 
-    auto display = mDisplayData[displayId].hwcDisplay;
     HWC2::Layer* layer;
-    auto error = display->createLayer(&layer);
+    auto error = mDisplayData[displayId].hwcDisplay->createLayer(&layer);
     RETURN_IF_HWC_ERROR(error, displayId, nullptr);
     return layer;
 }
@@ -234,8 +339,7 @@
 void HWComposer::destroyLayer(DisplayId displayId, HWC2::Layer* layer) {
     RETURN_IF_INVALID_DISPLAY(displayId);
 
-    auto display = mDisplayData[displayId].hwcDisplay;
-    auto error = display->destroyLayer(layer);
+    auto error = mDisplayData[displayId].hwcDisplay->destroyLayer(layer);
     RETURN_IF_HWC_ERROR(error, displayId);
 }
 
@@ -484,8 +588,8 @@
 
     if (displayData.validateWasSkipped) {
         // explicitly flush all pending commands
-        auto error = mHwcDevice->flushCommands();
-        RETURN_IF_HWC_ERROR_FOR("flushCommands", error, displayId, UNKNOWN_ERROR);
+        auto error = static_cast<HWC2::Error>(mComposer->executeCommands());
+        RETURN_IF_HWC_ERROR_FOR("executeCommands", error, displayId, UNKNOWN_ERROR);
         RETURN_IF_HWC_ERROR_FOR("present", displayData.presentError, displayId, UNKNOWN_ERROR);
         return NO_ERROR;
     }
@@ -600,8 +704,6 @@
     }
 
     const auto hwcDisplayId = displayData.hwcDisplay->getId();
-    mPhysicalDisplayIdMap.erase(hwcDisplayId);
-    mDisplayData.erase(displayId);
 
     // TODO(b/74619554): Select internal/external display from remaining displays.
     if (hwcDisplayId == mInternalHwcDisplayId) {
@@ -609,8 +711,8 @@
     } else if (hwcDisplayId == mExternalHwcDisplayId) {
         mExternalHwcDisplayId.reset();
     }
-
-    mHwcDevice->destroyDisplay(hwcDisplayId);
+    mPhysicalDisplayIdMap.erase(hwcDisplayId);
+    mDisplayData.erase(displayId);
 }
 
 status_t HWComposer::setOutputBuffer(DisplayId displayId, const sp<Fence>& acquireFence,
@@ -761,10 +863,7 @@
 }
 
 void HWComposer::dump(std::string& result) const {
-    // TODO: In order to provide a dump equivalent to HWC1, we need to shadow
-    // all the state going into the layers. This is probably better done in
-    // Layer itself, but it's going to take a bit of work to get there.
-    result.append(mHwcDevice->dump());
+    result.append(mComposer->dumpDebugInfo());
 }
 
 std::optional<DisplayId> HWComposer::toPhysicalDisplayId(hwc2_display_t hwcDisplayId) const {
@@ -830,5 +929,17 @@
                                                                            : "External display"};
 }
 
+void HWComposer::loadCapabilities() {
+    static_assert(sizeof(HWC2::Capability) == sizeof(int32_t), "Capability size has changed");
+    auto capabilities = mComposer->getCapabilities();
+    for (auto capability : capabilities) {
+        mCapabilities.emplace(static_cast<HWC2::Capability>(capability));
+    }
+}
+
+uint32_t HWComposer::getMaxVirtualDisplayCount() const {
+    return mComposer->getMaxVirtualDisplayCount();
+}
+
 } // namespace impl
 } // namespace android
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.h b/services/surfaceflinger/DisplayHardware/HWComposer.h
index c51002c..a0dabb4 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.h
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.h
@@ -207,6 +207,7 @@
 class HWComposer final : public android::HWComposer {
 public:
     explicit HWComposer(std::unique_ptr<Hwc2::Composer> composer);
+    explicit HWComposer(const std::string& composerServiceName);
 
     ~HWComposer() override;
 
@@ -325,7 +326,7 @@
     // for debugging ----------------------------------------------------------
     void dump(std::string& out) const override;
 
-    Hwc2::Composer* getComposer() const override { return mHwcDevice->getComposer(); }
+    Hwc2::Composer* getComposer() const override { return mComposer.get(); }
 
     // TODO(b/74619554): Remove special cases for internal/external display.
     std::optional<hwc2_display_t> getInternalHwcDisplayId() const override {
@@ -343,11 +344,12 @@
     friend TestableSurfaceFlinger;
 
     std::optional<DisplayIdentificationInfo> onHotplugConnect(hwc2_display_t hwcDisplayId);
+    void loadCapabilities();
+    uint32_t getMaxVirtualDisplayCount() const;
 
     struct DisplayData {
         bool isVirtual = false;
-
-        HWC2::Display* hwcDisplay = nullptr;
+        std::unique_ptr<HWC2::Display> hwcDisplay;
         sp<Fence> lastPresentFence = Fence::NO_FENCE; // signals when the last set op retires
         std::unordered_map<HWC2::Layer*, sp<Fence>> releaseFences;
         buffer_handle_t outbufHandle = nullptr;
@@ -369,9 +371,9 @@
 
     std::unordered_map<DisplayId, DisplayData> mDisplayData;
 
-    // This must be destroyed before mDisplayData, because destructor may call back into HWComposer
-    // and look up DisplayData.
-    std::unique_ptr<HWC2::Device> mHwcDevice;
+    std::unique_ptr<android::Hwc2::Composer> mComposer;
+    std::unordered_set<HWC2::Capability> mCapabilities;
+    bool mRegisteredCallback = false;
 
     std::unordered_map<hwc2_display_t, DisplayId> mPhysicalDisplayIdMap;
     std::optional<hwc2_display_t> mInternalHwcDisplayId;
@@ -380,7 +382,7 @@
 
     std::unordered_set<DisplayId> mFreeVirtualDisplayIds;
     uint32_t mNextVirtualDisplayId = 0;
-    uint32_t mRemainingHwcVirtualDisplays{mHwcDevice->getMaxVirtualDisplayCount()};
+    uint32_t mRemainingHwcVirtualDisplays{getMaxVirtualDisplayCount()};
 };
 
 } // namespace impl