Use a separate hwcomposer hidl instance for vr flinger

Improve robustness of vr flinger <--> surface flinger switching by
having vr flinger use a separate hardware composer hidl instance instead
of sharing the instance with surface flinger. Sharing the hardware
composer instance has proven to be error prone, with situations where
both the vr flinger thread and surface flinger main thread would write
to the composer at the same time, causing hard to diagnose
crashes (b/62925812).

Instead of sharing the hardware composer instance, when switching to vr
flinger we now delete the existing instance, create a new instance
directed to the vr hardware composer shim, and vr flinger creates its
own composer instance connected to the real hardware composer. By
creating a separate composer instance for vr flinger, crashes like the
ones found in b/62925812 are no longer impossible.

Most of the changes in this commit are related to enabling surface
flinger to delete HWComposer instances cleanly. In particular:

- Previously the hardware composer callbacks (which come in on a
  hwbinder thread) would land in HWC2::Device and bubble up to the
  SurfaceFlinger object. But with the new behavior the HWC2::Device
  might be dead or in the process of being destroyed, so instead we have
  SurfaceFlinger receive the composer callbacks directly, and forward
  them to HWComposer and HWC2::Device. We include a composer id field in
  the callbacks so surface flinger can ignore stale callbacks from dead
  composer instances.

- Object ownership for HWC2::Display and HWC2::Layer was shared by
  passing around shared_ptrs to these objects. This was problematic
  because they referenced and used the HWC2::Device, which can now be
  destroyed when switching to vr flinger. Simplify the ownership model
  by having HWC2::Device own (via unique_ptr<>) instances of
  HWC2::Display, which owns (again via unique_ptr<>) instances of
  HWC2::Layer. In cases where we previously passed std::shared_ptr<> to
  HWC2::Display or HWC2::Layer, instead pass non-owning HWC2::Display*
  and HWC2::Layer* pointers. This ensures clean composer instance
  teardown with no stale references to the deleted HWC2::Device.

- When the hardware composer instance is destroyed and the HWC2::Layers
  are removed, notify the android::Layer via a callback, so it can
  remove the HWC2::Layer from its internal table of hardware composer
  layers. This removes the burden to explicitly clear out all hardware
  composer layers when switching to vr flinger, which has been a source
  of bugs.

- We were missing an mStateLock lock in
  SurfaceFlinger::setVsyncEnabled(), which was necessary to ensure we
  were setting vsync on the correct hardware composer instance. Once
  that lock was added, surface flinger would sometimes deadlock when
  transitioning to vr flinger, because the surface flinger main thread
  would acquire mStateLock and then EventControlThread::mMutex, whereas
  the event control thread would acquire the locks in the opposite
  order. The changes in EventControlThread.cpp are to ensure it doesn't
  hold a lock on EventControlThread::mMutex while calling
  setVsyncEnabled(), to avoid the deadlock.

I found that without a composer callback registered in vr flinger the
vsync_event file wasn't getting vsync timestamps written, so vr flinger
would get stuck in an infinite loop trying to parse a vsync
timestamp. Since we need to have a callback anyway I changed the code in
hardware_composer.cpp to get the vsync timestamp from the callback, as
surface flinger does. I confirmed the timestamps are the same with
either method, and this lets us remove some extra code for extracting
the vsync timestamp that (probably) wasn't compatible with all devices
we want to run on anyway. I also added a timeout to the vysnc wait so
we'll see an error message in the log if we fail to wait for vsync,
instead of looping forever.

Bug: 62925812

Test: - Confirmed surface flinger <--> vr flinger switching is robust by
        switching devices on and off hundreds of times and observing no
        hardware composer related issues, surface flinger crashes, or
        hardware composer service crashes.

- Confirmed 2d in vr works as before by going through the OOBE flow on a
  standalone. This also exercises virtual display creation and usage
  through surface flinger.

- Added logs to confirm perfect layer/display cleanup when destroying
  hardware composer instances.

- Tested normal 2d phone usage to confirm basic layer create/destroy
  functionality works as before.

- Monitored surface flinger file descriptor usage across dozens of
  surface flinger <--> vr flinger transitions and observed no file
  descriptor leaks.

- Confirmed the HWC1 code path still compiles.

- Ran the surface flinger tests and confirmed there are no new test
  failures.

- Ran the hardware composer hidl in passthrough mode on a Marlin and
  confirmed it works.

- Ran CTS tests for virtual displays and confirmed they all pass.

- Tested Android Auto and confirmed basic graphics functionality still
  works.

Change-Id: I17dc0e060bfb5cb447ffbaa573b279fc6d2d8bd1
diff --git a/services/surfaceflinger/DisplayHardware/ComposerHal.cpp b/services/surfaceflinger/DisplayHardware/ComposerHal.cpp
index 704b17e..433a224 100644
--- a/services/surfaceflinger/DisplayHardware/ComposerHal.cpp
+++ b/services/surfaceflinger/DisplayHardware/ComposerHal.cpp
@@ -215,6 +215,10 @@
     }
 }
 
+bool Composer::isRemote() {
+    return mClient->isRemote();
+}
+
 void Composer::resetCommands() {
     mWriter.reset();
 }
diff --git a/services/surfaceflinger/DisplayHardware/ComposerHal.h b/services/surfaceflinger/DisplayHardware/ComposerHal.h
index 40d2a4c..31a3c1d 100644
--- a/services/surfaceflinger/DisplayHardware/ComposerHal.h
+++ b/services/surfaceflinger/DisplayHardware/ComposerHal.h
@@ -143,6 +143,11 @@
 
     void registerCallback(const sp<IComposerCallback>& callback);
 
+    // Returns true if the connected composer service is running in a remote
+    // process, false otherwise. This will return false if the service is
+    // configured in passthrough mode, for example.
+    bool isRemote();
+
     // Reset all pending commands in the command buffer. Useful if you want to
     // skip a frame but have already queued some commands.
     void resetCommands();
diff --git a/services/surfaceflinger/DisplayHardware/HWC2.cpp b/services/surfaceflinger/DisplayHardware/HWC2.cpp
index b749ce6..78c0c85 100644
--- a/services/surfaceflinger/DisplayHardware/HWC2.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWC2.cpp
@@ -33,45 +33,6 @@
 #include <algorithm>
 #include <inttypes.h>
 
-extern "C" {
-    static void hotplug_hook(hwc2_callback_data_t callbackData,
-            hwc2_display_t displayId, int32_t intConnected) {
-        auto device = static_cast<HWC2::Device*>(callbackData);
-        auto display = device->getDisplayById(displayId);
-        if (display) {
-            auto connected = static_cast<HWC2::Connection>(intConnected);
-            device->callHotplug(std::move(display), connected);
-        } else {
-            ALOGE("Hotplug callback called with unknown display %" PRIu64,
-                    displayId);
-        }
-    }
-
-    static void refresh_hook(hwc2_callback_data_t callbackData,
-            hwc2_display_t displayId) {
-        auto device = static_cast<HWC2::Device*>(callbackData);
-        auto display = device->getDisplayById(displayId);
-        if (display) {
-            device->callRefresh(std::move(display));
-        } else {
-            ALOGE("Refresh callback called with unknown display %" PRIu64,
-                    displayId);
-        }
-    }
-
-    static void vsync_hook(hwc2_callback_data_t callbackData,
-            hwc2_display_t displayId, int64_t timestamp) {
-        auto device = static_cast<HWC2::Device*>(callbackData);
-        auto display = device->getDisplayById(displayId);
-        if (display) {
-            device->callVsync(std::move(display), timestamp);
-        } else {
-            ALOGE("Vsync callback called with unknown display %" PRIu64,
-                    displayId);
-        }
-    }
-}
-
 using android::Fence;
 using android::FloatRect;
 using android::GraphicBuffer;
@@ -86,51 +47,78 @@
 
 namespace Hwc2 = android::Hwc2;
 
+namespace {
+
+class ComposerCallbackBridge : public Hwc2::IComposerCallback {
+public:
+    ComposerCallbackBridge(ComposerCallback* callback, int32_t sequenceId)
+            : mCallback(callback), mSequenceId(sequenceId),
+              mHasPrimaryDisplay(false) {}
+
+    Return<void> onHotplug(Hwc2::Display display,
+                           IComposerCallback::Connection conn) override
+    {
+        HWC2::Connection connection = static_cast<HWC2::Connection>(conn);
+        if (!mHasPrimaryDisplay) {
+            LOG_ALWAYS_FATAL_IF(connection != HWC2::Connection::Connected,
+                    "Initial onHotplug callback should be "
+                    "primary display connected");
+            mHasPrimaryDisplay = true;
+            mCallback->onHotplugReceived(mSequenceId, display,
+                                         connection, true);
+        } else {
+            mCallback->onHotplugReceived(mSequenceId, display,
+                                         connection, false);
+        }
+        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
+    {
+        mCallback->onVsyncReceived(mSequenceId, display, timestamp);
+        return Void();
+    }
+
+    bool HasPrimaryDisplay() { return mHasPrimaryDisplay; }
+
+private:
+    ComposerCallback* mCallback;
+    int32_t mSequenceId;
+    bool mHasPrimaryDisplay;
+};
+
+} // namespace anonymous
+
+
 // Device methods
 
 Device::Device(const std::string& serviceName)
   : mComposer(std::make_unique<Hwc2::Composer>(serviceName)),
     mCapabilities(),
     mDisplays(),
-    mHotplug(),
-    mPendingHotplugs(),
-    mRefresh(),
-    mPendingRefreshes(),
-    mVsync(),
-    mPendingVsyncs()
+    mRegisteredCallback(false)
 {
     loadCapabilities();
-    registerCallbacks();
 }
 
-Device::~Device()
-{
-    for (auto element : mDisplays) {
-        auto display = element.second.lock();
-        if (!display) {
-            ALOGE("~Device: Found a display (%" PRId64 " that has already been"
-                    " destroyed", element.first);
-            continue;
-        }
-
-        DisplayType displayType = HWC2::DisplayType::Invalid;
-        auto error = display->getType(&displayType);
-        if (error != Error::None) {
-            ALOGE("~Device: Failed to determine type of display %" PRIu64
-                    ": %s (%d)", display->getId(), to_string(error).c_str(),
-                    static_cast<int32_t>(error));
-            continue;
-        }
-
-        if (displayType == HWC2::DisplayType::Physical) {
-            error = display->setVsyncEnabled(HWC2::Vsync::Disable);
-            if (error != Error::None) {
-                ALOGE("~Device: Failed to disable vsync for display %" PRIu64
-                        ": %s (%d)", display->getId(), to_string(error).c_str(),
-                        static_cast<int32_t>(error));
-            }
-        }
+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->registerCallback(callbackBridge);
+    LOG_ALWAYS_FATAL_IF(!callbackBridge->HasPrimaryDisplay(),
+            "Registered composer callback but didn't get primary display");
 }
 
 // Required by HWC2 device
@@ -146,7 +134,7 @@
 }
 
 Error Device::createVirtualDisplay(uint32_t width, uint32_t height,
-        android_pixel_format_t* format, std::shared_ptr<Display>* outDisplay)
+        android_pixel_format_t* format, Display** outDisplay)
 {
     ALOGI("Creating virtual display");
 
@@ -159,104 +147,66 @@
         return error;
     }
 
-    ALOGI("Created virtual display");
+    auto display = std::make_unique<Display>(
+            *mComposer.get(), mCapabilities, displayId, DisplayType::Virtual);
+    *outDisplay = display.get();
     *format = static_cast<android_pixel_format_t>(intFormat);
-    *outDisplay = getDisplayById(displayId);
-    if (!*outDisplay) {
-        ALOGE("Failed to get display by id");
-        return Error::BadDisplay;
-    }
-    (*outDisplay)->setConnected(true);
+    mDisplays.emplace(displayId, std::move(display));
+    ALOGI("Created virtual display");
     return Error::None;
 }
 
-void Device::registerHotplugCallback(HotplugCallback hotplug)
+void Device::destroyDisplay(hwc2_display_t displayId)
 {
-    ALOGV("registerHotplugCallback");
-    mHotplug = hotplug;
-    for (auto& pending : mPendingHotplugs) {
-        auto& display = pending.first;
-        auto connected = pending.second;
-        ALOGV("Sending pending hotplug(%" PRIu64 ", %s)", display->getId(),
-                to_string(connected).c_str());
-        mHotplug(std::move(display), connected);
-    }
+    ALOGI("Destroying display %" PRIu64, displayId);
+    mDisplays.erase(displayId);
 }
 
-void Device::registerRefreshCallback(RefreshCallback refresh)
-{
-    mRefresh = refresh;
-    for (auto& pending : mPendingRefreshes) {
-        mRefresh(std::move(pending));
-    }
-}
+void Device::onHotplug(hwc2_display_t displayId, Connection connection) {
+    if (connection == Connection::Connected) {
+        auto display = getDisplayById(displayId);
+        if (display) {
+            if (display->isConnected()) {
+                ALOGW("Attempt to hotplug connect display %" PRIu64
+                        " , which is already connected.", displayId);
+            } else {
+                display->setConnected(true);
+            }
+        } else {
+            DisplayType displayType;
+            auto intError = mComposer->getDisplayType(displayId,
+                    reinterpret_cast<Hwc2::IComposerClient::DisplayType *>(
+                            &displayType));
+            auto error = static_cast<Error>(intError);
+            if (error != Error::None) {
+                ALOGE("getDisplayType(%" PRIu64 ") failed: %s (%d). "
+                        "Aborting hotplug attempt.",
+                        displayId, to_string(error).c_str(), intError);
+                return;
+            }
 
-void Device::registerVsyncCallback(VsyncCallback vsync)
-{
-    mVsync = vsync;
-    for (auto& pending : mPendingVsyncs) {
-        auto& display = pending.first;
-        auto timestamp = pending.second;
-        mVsync(std::move(display), timestamp);
-    }
-}
-
-// For use by Device callbacks
-
-void Device::callHotplug(std::shared_ptr<Display> display, Connection connected)
-{
-    if (connected == Connection::Connected) {
-        if (!display->isConnected()) {
-            mComposer->setClientTargetSlotCount(display->getId());
-            display->loadConfigs();
-            display->setConnected(true);
+            auto newDisplay = std::make_unique<Display>(
+                    *mComposer.get(), mCapabilities, displayId, displayType);
+            mDisplays.emplace(displayId, std::move(newDisplay));
         }
-    } else {
-        display->setConnected(false);
-        mDisplays.erase(display->getId());
-    }
-
-    if (mHotplug) {
-        mHotplug(std::move(display), connected);
-    } else {
-        ALOGV("callHotplug called, but no valid callback registered, storing");
-        mPendingHotplugs.emplace_back(std::move(display), connected);
-    }
-}
-
-void Device::callRefresh(std::shared_ptr<Display> display)
-{
-    if (mRefresh) {
-        mRefresh(std::move(display));
-    } else {
-        ALOGV("callRefresh called, but no valid callback registered, storing");
-        mPendingRefreshes.emplace_back(std::move(display));
-    }
-}
-
-void Device::callVsync(std::shared_ptr<Display> display, nsecs_t timestamp)
-{
-    if (mVsync) {
-        mVsync(std::move(display), timestamp);
-    } else {
-        ALOGV("callVsync called, but no valid callback registered, storing");
-        mPendingVsyncs.emplace_back(std::move(display), timestamp);
+    } 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
 
-std::shared_ptr<Display> Device::getDisplayById(hwc2_display_t id) {
-    if (mDisplays.count(id) != 0) {
-        auto strongDisplay = mDisplays[id].lock();
-        ALOGE_IF(!strongDisplay, "Display %" PRId64 " is in mDisplays but is no"
-                " longer alive", id);
-        return strongDisplay;
-    }
-
-    auto display = std::make_shared<Display>(*this, id);
-    mDisplays.emplace(id, display);
-    return display;
+Display* Device::getDisplayById(hwc2_display_t id) {
+    auto iter = mDisplays.find(id);
+    return iter == mDisplays.end() ? nullptr : iter->second.get();
 }
 
 // Device initialization methods
@@ -271,84 +221,37 @@
     }
 }
 
-bool Device::hasCapability(HWC2::Capability capability) const
-{
-    return std::find(mCapabilities.cbegin(), mCapabilities.cend(),
-            capability) != mCapabilities.cend();
-}
-
-namespace {
-class ComposerCallback : public Hwc2::IComposerCallback {
-public:
-    ComposerCallback(Device* device) : mDevice(device) {}
-
-    Return<void> onHotplug(Hwc2::Display display,
-            Connection connected) override
-    {
-        hotplug_hook(mDevice, display, static_cast<int32_t>(connected));
-        return Void();
-    }
-
-    Return<void> onRefresh(Hwc2::Display display) override
-    {
-        refresh_hook(mDevice, display);
-        return Void();
-    }
-
-    Return<void> onVsync(Hwc2::Display display, int64_t timestamp) override
-    {
-        vsync_hook(mDevice, display, timestamp);
-        return Void();
-    }
-
-private:
-    Device* mDevice;
-};
-} // namespace anonymous
-
-void Device::registerCallbacks()
-{
-    sp<ComposerCallback> callback = new ComposerCallback(this);
-    mComposer->registerCallback(callback);
-}
-
-
-// For use by Display
-
-void Device::destroyVirtualDisplay(hwc2_display_t display)
-{
-    ALOGI("Destroying virtual display");
-    auto intError = mComposer->destroyVirtualDisplay(display);
-    auto error = static_cast<Error>(intError);
-    ALOGE_IF(error != Error::None, "destroyVirtualDisplay(%" PRIu64 ") failed:"
-            " %s (%d)", display, to_string(error).c_str(), intError);
-    mDisplays.erase(display);
-}
-
 // Display methods
 
-Display::Display(Device& device, hwc2_display_t id)
-  : mDevice(device),
+Display::Display(android::Hwc2::Composer& composer,
+                 const std::unordered_set<Capability>& capabilities,
+                 hwc2_display_t id, DisplayType type)
+  : mComposer(composer),
+    mCapabilities(capabilities),
     mId(id),
     mIsConnected(false),
-    mType(DisplayType::Invalid)
+    mType(type)
 {
     ALOGV("Created display %" PRIu64, id);
-
-    auto intError = mDevice.mComposer->getDisplayType(mId,
-            reinterpret_cast<Hwc2::IComposerClient::DisplayType *>(&mType));
-    auto error = static_cast<Error>(intError);
-    if (error != Error::None) {
-        ALOGE("getDisplayType(%" PRIu64 ") failed: %s (%d)",
-              id, to_string(error).c_str(), intError);
-    }
+    setConnected(true);
 }
 
-Display::~Display()
-{
-    ALOGV("Destroyed display %" PRIu64, mId);
+Display::~Display() {
+    mLayers.clear();
+
     if (mType == DisplayType::Virtual) {
-        mDevice.destroyVirtualDisplay(mId);
+        ALOGV("Destroying virtual display");
+        auto intError = mComposer.destroyVirtualDisplay(mId);
+        auto error = static_cast<Error>(intError);
+        ALOGE_IF(error != Error::None, "destroyVirtualDisplay(%" PRIu64
+                ") failed: %s (%d)", mId, to_string(error).c_str(), intError);
+    } else if (mType == DisplayType::Physical) {
+        auto error = setVsyncEnabled(HWC2::Vsync::Disable);
+        if (error != Error::None) {
+            ALOGE("~Display: Failed to disable vsync for display %" PRIu64
+                    ": %s (%d)", mId, to_string(error).c_str(),
+                    static_cast<int32_t>(error));
+        }
     }
 }
 
@@ -383,22 +286,35 @@
 
 Error Display::acceptChanges()
 {
-    auto intError = mDevice.mComposer->acceptDisplayChanges(mId);
+    auto intError = mComposer.acceptDisplayChanges(mId);
     return static_cast<Error>(intError);
 }
 
-Error Display::createLayer(std::shared_ptr<Layer>* outLayer)
+Error Display::createLayer(Layer** outLayer)
 {
+    if (!outLayer) {
+        return Error::BadParameter;
+    }
     hwc2_layer_t layerId = 0;
-    auto intError = mDevice.mComposer->createLayer(mId, &layerId);
+    auto intError = mComposer.createLayer(mId, &layerId);
     auto error = static_cast<Error>(intError);
     if (error != Error::None) {
         return error;
     }
 
-    auto layer = std::make_shared<Layer>(shared_from_this(), layerId);
-    mLayers.emplace(layerId, layer);
-    *outLayer = std::move(layer);
+    auto layer = std::make_unique<Layer>(
+            mComposer, mCapabilities, mId, layerId);
+    *outLayer = layer.get();
+    mLayers.emplace(layerId, std::move(layer));
+    return Error::None;
+}
+
+Error Display::destroyLayer(Layer* layer)
+{
+    if (!layer) {
+        return Error::BadParameter;
+    }
+    mLayers.erase(layer->getId());
     return Error::None;
 }
 
@@ -407,7 +323,7 @@
 {
     ALOGV("[%" PRIu64 "] getActiveConfig", mId);
     hwc2_config_t configId = 0;
-    auto intError = mDevice.mComposer->getActiveConfig(mId, &configId);
+    auto intError = mComposer.getActiveConfig(mId, &configId);
     auto error = static_cast<Error>(intError);
 
     if (error != Error::None) {
@@ -430,12 +346,12 @@
 }
 
 Error Display::getChangedCompositionTypes(
-        std::unordered_map<std::shared_ptr<Layer>, Composition>* outTypes)
+        std::unordered_map<Layer*, Composition>* outTypes)
 {
     std::vector<Hwc2::Layer> layerIds;
     std::vector<Hwc2::IComposerClient::Composition> types;
-    auto intError = mDevice.mComposer->getChangedCompositionTypes(mId,
-            &layerIds, &types);
+    auto intError = mComposer.getChangedCompositionTypes(
+            mId, &layerIds, &types);
     uint32_t numElements = layerIds.size();
     auto error = static_cast<Error>(intError);
     error = static_cast<Error>(intError);
@@ -464,7 +380,7 @@
 Error Display::getColorModes(std::vector<android_color_mode_t>* outModes) const
 {
     std::vector<Hwc2::ColorMode> modes;
-    auto intError = mDevice.mComposer->getColorModes(mId, &modes);
+    auto intError = mComposer.getColorModes(mId, &modes);
     uint32_t numModes = modes.size();
     auto error = static_cast<Error>(intError);
     if (error != Error::None) {
@@ -489,19 +405,18 @@
 
 Error Display::getName(std::string* outName) const
 {
-    auto intError = mDevice.mComposer->getDisplayName(mId, outName);
+    auto intError = mComposer.getDisplayName(mId, outName);
     return static_cast<Error>(intError);
 }
 
 Error Display::getRequests(HWC2::DisplayRequest* outDisplayRequests,
-        std::unordered_map<std::shared_ptr<Layer>, LayerRequest>*
-                outLayerRequests)
+        std::unordered_map<Layer*, LayerRequest>* outLayerRequests)
 {
     uint32_t intDisplayRequests;
     std::vector<Hwc2::Layer> layerIds;
     std::vector<uint32_t> layerRequests;
-    auto intError = mDevice.mComposer->getDisplayRequests(mId,
-            &intDisplayRequests, &layerIds, &layerRequests);
+    auto intError = mComposer.getDisplayRequests(
+            mId, &intDisplayRequests, &layerIds, &layerRequests);
     uint32_t numElements = layerIds.size();
     auto error = static_cast<Error>(intError);
     if (error != Error::None) {
@@ -535,7 +450,7 @@
 Error Display::supportsDoze(bool* outSupport) const
 {
     bool intSupport = false;
-    auto intError = mDevice.mComposer->getDozeSupport(mId, &intSupport);
+    auto intError = mComposer.getDozeSupport(mId, &intSupport);
     auto error = static_cast<Error>(intError);
     if (error != Error::None) {
         return error;
@@ -552,7 +467,7 @@
     float maxAverageLuminance = -1.0f;
     float minLuminance = -1.0f;
     std::vector<Hwc2::Hdr> intTypes;
-    auto intError = mDevice.mComposer->getHdrCapabilities(mId, &intTypes,
+    auto intError = mComposer.getHdrCapabilities(mId, &intTypes,
             &maxLuminance, &maxAverageLuminance, &minLuminance);
     auto error = static_cast<HWC2::Error>(intError);
 
@@ -571,25 +486,24 @@
 }
 
 Error Display::getReleaseFences(
-        std::unordered_map<std::shared_ptr<Layer>, sp<Fence>>* outFences) const
+        std::unordered_map<Layer*, sp<Fence>>* outFences) const
 {
     std::vector<Hwc2::Layer> layerIds;
     std::vector<int> fenceFds;
-    auto intError = mDevice.mComposer->getReleaseFences(mId,
-            &layerIds, &fenceFds);
+    auto intError = mComposer.getReleaseFences(mId, &layerIds, &fenceFds);
     auto error = static_cast<Error>(intError);
     uint32_t numElements = layerIds.size();
     if (error != Error::None) {
         return error;
     }
 
-    std::unordered_map<std::shared_ptr<Layer>, sp<Fence>> releaseFences;
+    std::unordered_map<Layer*, sp<Fence>> releaseFences;
     releaseFences.reserve(numElements);
     for (uint32_t element = 0; element < numElements; ++element) {
         auto layer = getLayerById(layerIds[element]);
         if (layer) {
             sp<Fence> fence(new Fence(fenceFds[element]));
-            releaseFences.emplace(std::move(layer), fence);
+            releaseFences.emplace(layer, fence);
         } else {
             ALOGE("getReleaseFences: invalid layer %" PRIu64
                     " found on display %" PRIu64, layerIds[element], mId);
@@ -607,7 +521,7 @@
 Error Display::present(sp<Fence>* outPresentFence)
 {
     int32_t presentFenceFd = -1;
-    auto intError = mDevice.mComposer->presentDisplay(mId, &presentFenceFd);
+    auto intError = mComposer.presentDisplay(mId, &presentFenceFd);
     auto error = static_cast<Error>(intError);
     if (error != Error::None) {
         return error;
@@ -625,7 +539,7 @@
                 config->getDisplayId(), mId);
         return Error::BadConfig;
     }
-    auto intError = mDevice.mComposer->setActiveConfig(mId, config->getId());
+    auto intError = mComposer.setActiveConfig(mId, config->getId());
     return static_cast<Error>(intError);
 }
 
@@ -634,7 +548,7 @@
 {
     // TODO: Properly encode client target surface damage
     int32_t fenceFd = acquireFence->dup();
-    auto intError = mDevice.mComposer->setClientTarget(mId, slot, target,
+    auto intError = mComposer.setClientTarget(mId, slot, target,
             fenceFd, static_cast<Hwc2::Dataspace>(dataspace),
             std::vector<Hwc2::IComposerClient::Rect>());
     return static_cast<Error>(intError);
@@ -642,15 +556,15 @@
 
 Error Display::setColorMode(android_color_mode_t mode)
 {
-    auto intError = mDevice.mComposer->setColorMode(mId,
-            static_cast<Hwc2::ColorMode>(mode));
+    auto intError = mComposer.setColorMode(
+            mId, static_cast<Hwc2::ColorMode>(mode));
     return static_cast<Error>(intError);
 }
 
 Error Display::setColorTransform(const android::mat4& matrix,
         android_color_transform_t hint)
 {
-    auto intError = mDevice.mComposer->setColorTransform(mId,
+    auto intError = mComposer.setColorTransform(mId,
             matrix.asArray(), static_cast<Hwc2::ColorTransform>(hint));
     return static_cast<Error>(intError);
 }
@@ -660,7 +574,7 @@
 {
     int32_t fenceFd = releaseFence->dup();
     auto handle = buffer->getNativeBuffer()->handle;
-    auto intError = mDevice.mComposer->setOutputBuffer(mId, handle, fenceFd);
+    auto intError = mComposer.setOutputBuffer(mId, handle, fenceFd);
     close(fenceFd);
     return static_cast<Error>(intError);
 }
@@ -668,14 +582,14 @@
 Error Display::setPowerMode(PowerMode mode)
 {
     auto intMode = static_cast<Hwc2::IComposerClient::PowerMode>(mode);
-    auto intError = mDevice.mComposer->setPowerMode(mId, intMode);
+    auto intError = mComposer.setPowerMode(mId, intMode);
     return static_cast<Error>(intError);
 }
 
 Error Display::setVsyncEnabled(Vsync enabled)
 {
     auto intEnabled = static_cast<Hwc2::IComposerClient::Vsync>(enabled);
-    auto intError = mDevice.mComposer->setVsyncEnabled(mId, intEnabled);
+    auto intError = mComposer.setVsyncEnabled(mId, intEnabled);
     return static_cast<Error>(intError);
 }
 
@@ -683,8 +597,7 @@
 {
     uint32_t numTypes = 0;
     uint32_t numRequests = 0;
-    auto intError = mDevice.mComposer->validateDisplay(mId,
-            &numTypes, &numRequests);
+    auto intError = mComposer.validateDisplay(mId, &numTypes, &numRequests);
     auto error = static_cast<Error>(intError);
     if (error != Error::None && error != Error::HasChanges) {
         return error;
@@ -701,7 +614,8 @@
     uint32_t numTypes = 0;
     uint32_t numRequests = 0;
     int32_t presentFenceFd = -1;
-    auto intError = mDevice.mComposer->presentOrValidateDisplay(mId, &numTypes, &numRequests, &presentFenceFd, state);
+    auto intError = mComposer.presentOrValidateDisplay(
+            mId, &numTypes, &numRequests, &presentFenceFd, state);
     auto error = static_cast<Error>(intError);
     if (error != Error::None && error != Error::HasChanges) {
         return error;
@@ -720,15 +634,23 @@
 
 void Display::discardCommands()
 {
-    mDevice.mComposer->resetCommands();
+    mComposer.resetCommands();
 }
 
 // For use by Device
 
+void Display::setConnected(bool connected) {
+    if (!mIsConnected && connected && mType == DisplayType::Physical) {
+        mComposer.setClientTargetSlotCount(mId);
+        loadConfigs();
+    }
+    mIsConnected = connected;
+}
+
 int32_t Display::getAttribute(hwc2_config_t configId, Attribute attribute)
 {
     int32_t value = 0;
-    auto intError = mDevice.mComposer->getDisplayAttribute(mId, configId,
+    auto intError = mComposer.getDisplayAttribute(mId, configId,
             static_cast<Hwc2::IComposerClient::Attribute>(attribute),
             &value);
     auto error = static_cast<Error>(intError);
@@ -760,7 +682,7 @@
     ALOGV("[%" PRIu64 "] loadConfigs", mId);
 
     std::vector<Hwc2::Config> configIds;
-    auto intError = mDevice.mComposer->getDisplayConfigs(mId, &configIds);
+    auto intError = mComposer.getDisplayConfigs(mId, &configIds);
     auto error = static_cast<Error>(intError);
     if (error != Error::None) {
         ALOGE("[%" PRIu64 "] getDisplayConfigs [2] failed: %s (%d)", mId,
@@ -773,54 +695,51 @@
     }
 }
 
-// For use by Layer
-
-void Display::destroyLayer(hwc2_layer_t layerId)
-{
-    auto intError =mDevice.mComposer->destroyLayer(mId, layerId);
-    auto error = static_cast<Error>(intError);
-    ALOGE_IF(error != Error::None, "destroyLayer(%" PRIu64 ", %" PRIu64 ")"
-            " failed: %s (%d)", mId, layerId, to_string(error).c_str(),
-            intError);
-    mLayers.erase(layerId);
-}
-
 // Other Display methods
 
-std::shared_ptr<Layer> Display::getLayerById(hwc2_layer_t id) const
+Layer* Display::getLayerById(hwc2_layer_t id) const
 {
     if (mLayers.count(id) == 0) {
         return nullptr;
     }
 
-    auto layer = mLayers.at(id).lock();
-    return layer;
+    return mLayers.at(id).get();
 }
 
 // Layer methods
 
-Layer::Layer(const std::shared_ptr<Display>& display, hwc2_layer_t id)
-  : mDisplay(display),
-    mDisplayId(display->getId()),
-    mDevice(display->getDevice()),
-    mId(id)
+Layer::Layer(android::Hwc2::Composer& composer,
+             const std::unordered_set<Capability>& capabilities,
+             hwc2_display_t displayId, hwc2_layer_t layerId)
+  : mComposer(composer),
+    mCapabilities(capabilities),
+    mDisplayId(displayId),
+    mId(layerId)
 {
-    ALOGV("Created layer %" PRIu64 " on display %" PRIu64, id,
-            display->getId());
+    ALOGV("Created layer %" PRIu64 " on display %" PRIu64, layerId, displayId);
 }
 
 Layer::~Layer()
 {
-    auto display = mDisplay.lock();
-    if (display) {
-        display->destroyLayer(mId);
+    auto intError = mComposer.destroyLayer(mDisplayId, mId);
+    auto error = static_cast<Error>(intError);
+    ALOGE_IF(error != Error::None, "destroyLayer(%" PRIu64 ", %" PRIu64 ")"
+            " failed: %s (%d)", mDisplayId, mId, to_string(error).c_str(),
+            intError);
+    if (mLayerDestroyedListener) {
+        mLayerDestroyedListener(this);
     }
 }
 
+void Layer::setLayerDestroyedListener(std::function<void(Layer*)> listener) {
+    LOG_ALWAYS_FATAL_IF(mLayerDestroyedListener && listener,
+            "Attempt to set layer destroyed listener multiple times");
+    mLayerDestroyedListener = listener;
+}
+
 Error Layer::setCursorPosition(int32_t x, int32_t y)
 {
-    auto intError = mDevice.mComposer->setCursorPosition(mDisplayId,
-            mId, x, y);
+    auto intError = mComposer.setCursorPosition(mDisplayId, mId, x, y);
     return static_cast<Error>(intError);
 }
 
@@ -828,8 +747,8 @@
         const sp<Fence>& acquireFence)
 {
     int32_t fenceFd = acquireFence->dup();
-    auto intError = mDevice.mComposer->setLayerBuffer(mDisplayId,
-            mId, slot, buffer, fenceFd);
+    auto intError = mComposer.setLayerBuffer(mDisplayId, mId, slot, buffer,
+                                             fenceFd);
     return static_cast<Error>(intError);
 }
 
@@ -839,7 +758,7 @@
     // rects for HWC
     Hwc2::Error intError = Hwc2::Error::NONE;
     if (damage.isRect() && damage.getBounds() == Rect::INVALID_RECT) {
-        intError = mDevice.mComposer->setLayerSurfaceDamage(mDisplayId,
+        intError = mComposer.setLayerSurfaceDamage(mDisplayId,
                 mId, std::vector<Hwc2::IComposerClient::Rect>());
     } else {
         size_t rectCount = 0;
@@ -851,8 +770,7 @@
                     rectArray[rect].right, rectArray[rect].bottom});
         }
 
-        intError = mDevice.mComposer->setLayerSurfaceDamage(mDisplayId,
-                mId, hwcRects);
+        intError = mComposer.setLayerSurfaceDamage(mDisplayId, mId, hwcRects);
     }
 
     return static_cast<Error>(intError);
@@ -861,24 +779,22 @@
 Error Layer::setBlendMode(BlendMode mode)
 {
     auto intMode = static_cast<Hwc2::IComposerClient::BlendMode>(mode);
-    auto intError = mDevice.mComposer->setLayerBlendMode(mDisplayId,
-            mId, intMode);
+    auto intError = mComposer.setLayerBlendMode(mDisplayId, mId, intMode);
     return static_cast<Error>(intError);
 }
 
 Error Layer::setColor(hwc_color_t color)
 {
     Hwc2::IComposerClient::Color hwcColor{color.r, color.g, color.b, color.a};
-    auto intError = mDevice.mComposer->setLayerColor(mDisplayId,
-            mId, hwcColor);
+    auto intError = mComposer.setLayerColor(mDisplayId, mId, hwcColor);
     return static_cast<Error>(intError);
 }
 
 Error Layer::setCompositionType(Composition type)
 {
     auto intType = static_cast<Hwc2::IComposerClient::Composition>(type);
-    auto intError = mDevice.mComposer->setLayerCompositionType(mDisplayId,
-            mId, intType);
+    auto intError = mComposer.setLayerCompositionType(
+            mDisplayId, mId, intType);
     return static_cast<Error>(intError);
 }
 
@@ -889,8 +805,7 @@
     }
     mDataSpace = dataspace;
     auto intDataspace = static_cast<Hwc2::Dataspace>(dataspace);
-    auto intError = mDevice.mComposer->setLayerDataspace(mDisplayId,
-            mId, intDataspace);
+    auto intError = mComposer.setLayerDataspace(mDisplayId, mId, intDataspace);
     return static_cast<Error>(intError);
 }
 
@@ -898,27 +813,24 @@
 {
     Hwc2::IComposerClient::Rect hwcRect{frame.left, frame.top,
         frame.right, frame.bottom};
-    auto intError = mDevice.mComposer->setLayerDisplayFrame(mDisplayId,
-            mId, hwcRect);
+    auto intError = mComposer.setLayerDisplayFrame(mDisplayId, mId, hwcRect);
     return static_cast<Error>(intError);
 }
 
 Error Layer::setPlaneAlpha(float alpha)
 {
-    auto intError = mDevice.mComposer->setLayerPlaneAlpha(mDisplayId,
-            mId, alpha);
+    auto intError = mComposer.setLayerPlaneAlpha(mDisplayId, mId, alpha);
     return static_cast<Error>(intError);
 }
 
 Error Layer::setSidebandStream(const native_handle_t* stream)
 {
-    if (!mDevice.hasCapability(Capability::SidebandStream)) {
+    if (mCapabilities.count(Capability::SidebandStream) == 0) {
         ALOGE("Attempted to call setSidebandStream without checking that the "
                 "device supports sideband streams");
         return Error::Unsupported;
     }
-    auto intError = mDevice.mComposer->setLayerSidebandStream(mDisplayId,
-            mId, stream);
+    auto intError = mComposer.setLayerSidebandStream(mDisplayId, mId, stream);
     return static_cast<Error>(intError);
 }
 
@@ -926,16 +838,14 @@
 {
     Hwc2::IComposerClient::FRect hwcRect{
         crop.left, crop.top, crop.right, crop.bottom};
-    auto intError = mDevice.mComposer->setLayerSourceCrop(mDisplayId,
-            mId, hwcRect);
+    auto intError = mComposer.setLayerSourceCrop(mDisplayId, mId, hwcRect);
     return static_cast<Error>(intError);
 }
 
 Error Layer::setTransform(Transform transform)
 {
     auto intTransform = static_cast<Hwc2::Transform>(transform);
-    auto intError = mDevice.mComposer->setLayerTransform(mDisplayId,
-            mId, intTransform);
+    auto intError = mComposer.setLayerTransform(mDisplayId, mId, intTransform);
     return static_cast<Error>(intError);
 }
 
@@ -950,20 +860,19 @@
                 rectArray[rect].right, rectArray[rect].bottom});
     }
 
-    auto intError = mDevice.mComposer->setLayerVisibleRegion(mDisplayId,
-            mId, hwcRects);
+    auto intError = mComposer.setLayerVisibleRegion(mDisplayId, mId, hwcRects);
     return static_cast<Error>(intError);
 }
 
 Error Layer::setZOrder(uint32_t z)
 {
-    auto intError = mDevice.mComposer->setLayerZOrder(mDisplayId, mId, z);
+    auto intError = mComposer.setLayerZOrder(mDisplayId, mId, z);
     return static_cast<Error>(intError);
 }
 
 Error Layer::setInfo(uint32_t type, uint32_t appId)
 {
-  auto intError = mDevice.mComposer->setLayerInfo(mDisplayId, mId, type, appId);
+  auto intError = mComposer.setLayerInfo(mDisplayId, mId, type, appId);
   return static_cast<Error>(intError);
 }
 
diff --git a/services/surfaceflinger/DisplayHardware/HWC2.h b/services/surfaceflinger/DisplayHardware/HWC2.h
index 9bcda1e..fbe4c7e 100644
--- a/services/surfaceflinger/DisplayHardware/HWC2.h
+++ b/services/surfaceflinger/DisplayHardware/HWC2.h
@@ -53,10 +53,26 @@
 class Display;
 class Layer;
 
-typedef std::function<void(std::shared_ptr<Display>, Connection)>
-        HotplugCallback;
-typedef std::function<void(std::shared_ptr<Display>)> RefreshCallback;
-typedef std::function<void(std::shared_ptr<Display>, nsecs_t)> VsyncCallback;
+// Implement this interface to receive hardware composer events.
+//
+// These callback functions will generally be called on a hwbinder thread, but
+// when first registering the callback the onHotplugReceived() function will
+// immediately be called on the thread calling registerCallback().
+//
+// All calls receive a sequenceId, which will be the value that was supplied to
+// HWC2::Device::registerCallback(). It's used to help differentiate callbacks
+// from different hardware composer instances.
+class ComposerCallback {
+ public:
+    virtual void onHotplugReceived(int32_t sequenceId, hwc2_display_t display,
+                                   Connection connection,
+                                   bool primaryDisplay) = 0;
+    virtual void onRefreshReceived(int32_t sequenceId,
+                                   hwc2_display_t display) = 0;
+    virtual void onVsyncReceived(int32_t sequenceId, hwc2_display_t display,
+                                 int64_t timestamp) = 0;
+    virtual ~ComposerCallback() = default;
+};
 
 // C++ Wrapper around hwc2_device_t. Load all functions pointers
 // and handle callback registration.
@@ -66,10 +82,8 @@
     // Service name is expected to be 'default' or 'vr' for normal use.
     // 'vr' will slightly modify the behavior of the mComposer.
     Device(const std::string& serviceName);
-    ~Device();
 
-    friend class HWC2::Display;
-    friend class HWC2::Layer;
+    void registerCallback(ComposerCallback* callback, int32_t sequenceId);
 
     // Required by HWC2
 
@@ -81,27 +95,14 @@
 
     uint32_t getMaxVirtualDisplayCount() const;
     Error createVirtualDisplay(uint32_t width, uint32_t height,
-            android_pixel_format_t* format,
-            std::shared_ptr<Display>* outDisplay);
+            android_pixel_format_t* format, Display** outDisplay);
+    void destroyDisplay(hwc2_display_t displayId);
 
-    void registerHotplugCallback(HotplugCallback hotplug);
-    void registerRefreshCallback(RefreshCallback refresh);
-    void registerVsyncCallback(VsyncCallback vsync);
-
-    // For use by callbacks
-
-    void callHotplug(std::shared_ptr<Display> display, Connection connected);
-    void callRefresh(std::shared_ptr<Display> display);
-    void callVsync(std::shared_ptr<Display> display, nsecs_t timestamp);
+    void onHotplug(hwc2_display_t displayId, Connection connection);
 
     // Other Device methods
 
-    // This will create a Display if one is not found, but it will not be marked
-    // as connected. This Display may be null if the display has been torn down
-    // but has not been removed from the map yet.
-    std::shared_ptr<Display> getDisplayById(hwc2_display_t id);
-
-    bool hasCapability(HWC2::Capability capability) const;
+    Display* getDisplayById(hwc2_display_t id);
 
     android::Hwc2::Composer* getComposer() { return mComposer.get(); }
 
@@ -109,37 +110,23 @@
     // Initialization methods
 
     void loadCapabilities();
-    void registerCallbacks();
-
-    // For use by Display
-
-    void destroyVirtualDisplay(hwc2_display_t display);
 
     // Member variables
     std::unique_ptr<android::Hwc2::Composer> mComposer;
-
     std::unordered_set<Capability> mCapabilities;
-    std::unordered_map<hwc2_display_t, std::weak_ptr<Display>> mDisplays;
-
-    HotplugCallback mHotplug;
-    std::vector<std::pair<std::shared_ptr<Display>, Connection>>
-            mPendingHotplugs;
-    RefreshCallback mRefresh;
-    std::vector<std::shared_ptr<Display>> mPendingRefreshes;
-    VsyncCallback mVsync;
-    std::vector<std::pair<std::shared_ptr<Display>, nsecs_t>> mPendingVsyncs;
+    std::unordered_map<hwc2_display_t, std::unique_ptr<Display>> mDisplays;
+    bool mRegisteredCallback;
 };
 
 // Convenience C++ class to access hwc2_device_t Display functions directly.
-class Display : public std::enable_shared_from_this<Display>
+class Display
 {
 public:
-    Display(Device& device, hwc2_display_t id);
+    Display(android::Hwc2::Composer& composer,
+            const std::unordered_set<Capability>& capabilities,
+            hwc2_display_t id, DisplayType type);
     ~Display();
 
-    friend class HWC2::Device;
-    friend class HWC2::Layer;
-
     class Config
     {
     public:
@@ -212,12 +199,12 @@
     // Required by HWC2
 
     [[clang::warn_unused_result]] Error acceptChanges();
-    [[clang::warn_unused_result]] Error createLayer(
-            std::shared_ptr<Layer>* outLayer);
+    [[clang::warn_unused_result]] Error createLayer(Layer** outLayer);
+    [[clang::warn_unused_result]] Error destroyLayer(Layer* layer);
     [[clang::warn_unused_result]] Error getActiveConfig(
             std::shared_ptr<const Config>* outConfig) const;
     [[clang::warn_unused_result]] Error getChangedCompositionTypes(
-            std::unordered_map<std::shared_ptr<Layer>, Composition>* outTypes);
+            std::unordered_map<Layer*, Composition>* outTypes);
     [[clang::warn_unused_result]] Error getColorModes(
             std::vector<android_color_mode_t>* outModes) const;
 
@@ -227,14 +214,13 @@
     [[clang::warn_unused_result]] Error getName(std::string* outName) const;
     [[clang::warn_unused_result]] Error getRequests(
             DisplayRequest* outDisplayRequests,
-            std::unordered_map<std::shared_ptr<Layer>, LayerRequest>*
-                    outLayerRequests);
+            std::unordered_map<Layer*, LayerRequest>* outLayerRequests);
     [[clang::warn_unused_result]] Error getType(DisplayType* outType) const;
     [[clang::warn_unused_result]] Error supportsDoze(bool* outSupport) const;
     [[clang::warn_unused_result]] Error getHdrCapabilities(
             std::unique_ptr<android::HdrCapabilities>* outCapabilities) const;
     [[clang::warn_unused_result]] Error getReleaseFences(
-            std::unordered_map<std::shared_ptr<Layer>,
+            std::unordered_map<Layer*,
                     android::sp<android::Fence>>* outFences) const;
     [[clang::warn_unused_result]] Error present(
             android::sp<android::Fence>* outPresentFence);
@@ -266,32 +252,31 @@
 
     // Other Display methods
 
-    Device& getDevice() const { return mDevice; }
     hwc2_display_t getId() const { return mId; }
     bool isConnected() const { return mIsConnected; }
+    void setConnected(bool connected);  // For use by Device only
 
 private:
-    // For use by Device
-
-    void setConnected(bool connected) { mIsConnected = connected; }
     int32_t getAttribute(hwc2_config_t configId, Attribute attribute);
     void loadConfig(hwc2_config_t configId);
     void loadConfigs();
 
-    // For use by Layer
-    void destroyLayer(hwc2_layer_t layerId);
-
     // This may fail (and return a null pointer) if no layer with this ID exists
     // on this display
-    std::shared_ptr<Layer> getLayerById(hwc2_layer_t id) const;
+    Layer* getLayerById(hwc2_layer_t id) const;
 
     // Member variables
 
-    Device& mDevice;
+    // These are references to data owned by HWC2::Device, which will outlive
+    // this HWC2::Display, so these references are guaranteed to be valid for
+    // the lifetime of this object.
+    android::Hwc2::Composer& mComposer;
+    const std::unordered_set<Capability>& mCapabilities;
+
     hwc2_display_t mId;
     bool mIsConnected;
     DisplayType mType;
-    std::unordered_map<hwc2_layer_t, std::weak_ptr<Layer>> mLayers;
+    std::unordered_map<hwc2_layer_t, std::unique_ptr<Layer>> mLayers;
     // The ordering in this map matters, for getConfigs(), when it is
     // converted to a vector
     std::map<hwc2_config_t, std::shared_ptr<const Config>> mConfigs;
@@ -301,12 +286,18 @@
 class Layer
 {
 public:
-    Layer(const std::shared_ptr<Display>& display, hwc2_layer_t id);
+    Layer(android::Hwc2::Composer& composer,
+          const std::unordered_set<Capability>& capabilities,
+          hwc2_display_t displayId, hwc2_layer_t layerId);
     ~Layer();
 
-    bool isAbandoned() const { return mDisplay.expired(); }
     hwc2_layer_t getId() const { return mId; }
 
+    // Register a listener to be notified when the layer is destroyed. When the
+    // listener function is called, the Layer will be in the process of being
+    // destroyed, so it's not safe to call methods on it.
+    void setLayerDestroyedListener(std::function<void(Layer*)> listener);
+
     [[clang::warn_unused_result]] Error setCursorPosition(int32_t x, int32_t y);
     [[clang::warn_unused_result]] Error setBuffer(uint32_t slot,
             const android::sp<android::GraphicBuffer>& buffer,
@@ -333,11 +324,16 @@
     [[clang::warn_unused_result]] Error setInfo(uint32_t type, uint32_t appId);
 
 private:
-    std::weak_ptr<Display> mDisplay;
+    // These are references to data owned by HWC2::Device, which will outlive
+    // this HWC2::Layer, so these references are guaranteed to be valid for
+    // the lifetime of this object.
+    android::Hwc2::Composer& mComposer;
+    const std::unordered_set<Capability>& mCapabilities;
+
     hwc2_display_t mDisplayId;
-    Device& mDevice;
     hwc2_layer_t mId;
     android_dataspace mDataSpace = HAL_DATASPACE_UNKNOWN;
+    std::function<void(Layer*)> mLayerDestroyedListener;
 };
 
 } // namespace HWC2
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
index abf7dd1..b096a3a 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
@@ -65,7 +65,6 @@
       mFreeDisplaySlots(),
       mHwcDisplaySlots(),
       mCBContext(),
-      mEventHandler(nullptr),
       mVSyncCounts(),
       mRemainingHwcVirtualDisplays(0)
 {
@@ -74,41 +73,15 @@
         mVSyncCounts[i] = 0;
     }
 
-    loadHwcModule(serviceName);
+    mHwcDevice = std::make_unique<HWC2::Device>(serviceName);
+    mRemainingHwcVirtualDisplays = mHwcDevice->getMaxVirtualDisplayCount();
 }
 
 HWComposer::~HWComposer() {}
 
-void HWComposer::setEventHandler(EventHandler* handler)
-{
-    if (handler == nullptr) {
-        ALOGE("setEventHandler: Rejected attempt to clear handler");
-        return;
-    }
-
-    bool wasNull = (mEventHandler == nullptr);
-    mEventHandler = handler;
-
-    if (wasNull) {
-        auto hotplugHook = std::bind(&HWComposer::hotplug, this,
-                std::placeholders::_1, std::placeholders::_2);
-        mHwcDevice->registerHotplugCallback(hotplugHook);
-        auto invalidateHook = std::bind(&HWComposer::invalidate, this,
-                std::placeholders::_1);
-        mHwcDevice->registerRefreshCallback(invalidateHook);
-        auto vsyncHook = std::bind(&HWComposer::vsync, this,
-                std::placeholders::_1, std::placeholders::_2);
-        mHwcDevice->registerVsyncCallback(vsyncHook);
-    }
-}
-
-// Load and prepare the hardware composer module.  Sets mHwc.
-void HWComposer::loadHwcModule(const std::string& serviceName)
-{
-    ALOGV("loadHwcModule");
-    mHwcDevice = std::make_unique<HWC2::Device>(serviceName);
-
-    mRemainingHwcVirtualDisplays = mHwcDevice->getMaxVirtualDisplayCount();
+void HWComposer::registerCallback(HWC2::ComposerCallback* callback,
+                                  int32_t sequenceId) {
+    mHwcDevice->registerCallback(callback, sequenceId);
 }
 
 bool HWComposer::hasCapability(HWC2::Capability capability) const
@@ -146,54 +119,51 @@
     }
 }
 
-void HWComposer::hotplug(const std::shared_ptr<HWC2::Display>& display,
-        HWC2::Connection connected) {
-    ALOGV("hotplug: %" PRIu64 ", %s", display->getId(),
-            to_string(connected).c_str());
-    int32_t disp = 0;
+void HWComposer::onHotplug(hwc2_display_t displayId,
+                           HWC2::Connection connection) {
+    ALOGV("hotplug: %" PRIu64 ", %s", displayId,
+            to_string(connection).c_str());
+    mHwcDevice->onHotplug(displayId, connection);
     if (!mDisplayData[0].hwcDisplay) {
-        ALOGE_IF(connected != HWC2::Connection::Connected, "Assumed primary"
+        ALOGE_IF(connection != HWC2::Connection::Connected, "Assumed primary"
                 " display would be connected");
-        mDisplayData[0].hwcDisplay = display;
-        mHwcDisplaySlots[display->getId()] = 0;
-        disp = DisplayDevice::DISPLAY_PRIMARY;
+        mDisplayData[0].hwcDisplay = mHwcDevice->getDisplayById(displayId);
+        mHwcDisplaySlots[displayId] = 0;
     } else {
         // Disconnect is handled through HWComposer::disconnectDisplay via
         // SurfaceFlinger's onHotplugReceived callback handling
-        if (connected == HWC2::Connection::Connected) {
-            mDisplayData[1].hwcDisplay = display;
-            mHwcDisplaySlots[display->getId()] = 1;
+        if (connection == HWC2::Connection::Connected) {
+            mDisplayData[1].hwcDisplay = mHwcDevice->getDisplayById(displayId);
+            mHwcDisplaySlots[displayId] = 1;
         }
-        disp = DisplayDevice::DISPLAY_EXTERNAL;
     }
-    mEventHandler->onHotplugReceived(this, disp,
-            connected == HWC2::Connection::Connected);
 }
 
-void HWComposer::invalidate(const std::shared_ptr<HWC2::Display>& /*display*/) {
-    mEventHandler->onInvalidateReceived(this);
-}
-
-void HWComposer::vsync(const std::shared_ptr<HWC2::Display>& display,
-        int64_t timestamp) {
+bool HWComposer::onVsync(hwc2_display_t displayId, int64_t timestamp,
+                         int32_t* outDisplay) {
+    auto display = mHwcDevice->getDisplayById(displayId);
+    if (!display) {
+        ALOGE("onVsync Failed to find display %" PRIu64, displayId);
+        return false;
+    }
     auto displayType = HWC2::DisplayType::Invalid;
     auto error = display->getType(&displayType);
     if (error != HWC2::Error::None) {
-        ALOGE("vsync: Failed to determine type of display %" PRIu64,
+        ALOGE("onVsync: Failed to determine type of display %" PRIu64,
                 display->getId());
-        return;
+        return false;
     }
 
     if (displayType == HWC2::DisplayType::Virtual) {
         ALOGE("Virtual display %" PRIu64 " passed to vsync callback",
                 display->getId());
-        return;
+        return false;
     }
 
     if (mHwcDisplaySlots.count(display->getId()) == 0) {
         ALOGE("Unknown physical display %" PRIu64 " passed to vsync callback",
                 display->getId());
-        return;
+        return false;
     }
 
     int32_t disp = mHwcDisplaySlots[display->getId()];
@@ -207,17 +177,21 @@
         if (timestamp == mLastHwVSync[disp]) {
             ALOGW("Ignoring duplicate VSYNC event from HWC (t=%" PRId64 ")",
                     timestamp);
-            return;
+            return false;
         }
 
         mLastHwVSync[disp] = timestamp;
     }
 
+    if (outDisplay) {
+        *outDisplay = disp;
+    }
+
     char tag[16];
     snprintf(tag, sizeof(tag), "HW_VSYNC_%1u", disp);
     ATRACE_INT(tag, ++mVSyncCounts[disp] & 1);
 
-    mEventHandler->onVSyncReceived(this, disp, timestamp);
+    return true;
 }
 
 status_t HWComposer::allocateVirtualDisplay(uint32_t width, uint32_t height,
@@ -236,7 +210,7 @@
         return INVALID_OPERATION;
     }
 
-    std::shared_ptr<HWC2::Display> display;
+    HWC2::Display* display;
     auto error = mHwcDevice->createVirtualDisplay(width, height, format,
             &display);
     if (error != HWC2::Error::None) {
@@ -265,13 +239,13 @@
     return NO_ERROR;
 }
 
-std::shared_ptr<HWC2::Layer> HWComposer::createLayer(int32_t displayId) {
+HWC2::Layer* HWComposer::createLayer(int32_t displayId) {
     if (!isValidDisplay(displayId)) {
         ALOGE("Failed to create layer on invalid display %d", displayId);
         return nullptr;
     }
     auto display = mDisplayData[displayId].hwcDisplay;
-    std::shared_ptr<HWC2::Layer> layer;
+    HWC2::Layer* layer;
     auto error = display->createLayer(&layer);
     if (error != HWC2::Error::None) {
         ALOGE("Failed to create layer on display %d: %s (%d)", displayId,
@@ -281,6 +255,19 @@
     return layer;
 }
 
+void HWComposer::destroyLayer(int32_t displayId, HWC2::Layer* layer) {
+    if (!isValidDisplay(displayId)) {
+        ALOGE("Failed to destroy layer on invalid display %d", displayId);
+        return;
+    }
+    auto display = mDisplayData[displayId].hwcDisplay;
+    auto error = display->destroyLayer(layer);
+    if (error != HWC2::Error::None) {
+        ALOGE("Failed to destroy layer on display %d: %s (%d)", displayId,
+                to_string(error).c_str(), static_cast<int32_t>(error));
+    }
+}
+
 nsecs_t HWComposer::getRefreshTimestamp(int32_t displayId) const {
     // this returns the last refresh timestamp.
     // if the last one is not available, we estimate it based on
@@ -348,10 +335,8 @@
                 displayId);
         return modes;
     }
-    const std::shared_ptr<HWC2::Display>& hwcDisplay =
-            mDisplayData[displayId].hwcDisplay;
 
-    auto error = hwcDisplay->getColorModes(&modes);
+    auto error = mDisplayData[displayId].hwcDisplay->getColorModes(&modes);
     if (error != HWC2::Error::None) {
         ALOGE("getColorModes failed for display %d: %s (%d)", displayId,
                 to_string(error).c_str(), static_cast<int32_t>(error));
@@ -471,7 +456,7 @@
             return UNKNOWN_ERROR;
         }
         if (state == 1) { //Present Succeeded.
-            std::unordered_map<std::shared_ptr<HWC2::Layer>, sp<Fence>> releaseFences;
+            std::unordered_map<HWC2::Layer*, sp<Fence>> releaseFences;
             error = hwcDisplay->getReleaseFences(&releaseFences);
             displayData.releaseFences = std::move(releaseFences);
             displayData.lastPresentFence = outPresentFence;
@@ -490,8 +475,7 @@
         return BAD_INDEX;
     }
 
-    std::unordered_map<std::shared_ptr<HWC2::Layer>, HWC2::Composition>
-        changedTypes;
+    std::unordered_map<HWC2::Layer*, HWC2::Composition> changedTypes;
     changedTypes.reserve(numTypes);
     error = hwcDisplay->getChangedCompositionTypes(&changedTypes);
     if (error != HWC2::Error::None) {
@@ -503,8 +487,7 @@
 
 
     displayData.displayRequests = static_cast<HWC2::DisplayRequest>(0);
-    std::unordered_map<std::shared_ptr<HWC2::Layer>, HWC2::LayerRequest>
-        layerRequests;
+    std::unordered_map<HWC2::Layer*, HWC2::LayerRequest> layerRequests;
     layerRequests.reserve(numRequests);
     error = hwcDisplay->getRequests(&displayData.displayRequests,
             &layerRequests);
@@ -598,7 +581,7 @@
 }
 
 sp<Fence> HWComposer::getLayerReleaseFence(int32_t displayId,
-        const std::shared_ptr<HWC2::Layer>& layer) const {
+        HWC2::Layer* layer) const {
     if (!isValidDisplay(displayId)) {
         ALOGE("getLayerReleaseFence: Invalid display");
         return Fence::NO_FENCE;
@@ -639,7 +622,7 @@
         return UNKNOWN_ERROR;
     }
 
-    std::unordered_map<std::shared_ptr<HWC2::Layer>, sp<Fence>> releaseFences;
+    std::unordered_map<HWC2::Layer*, sp<Fence>> releaseFences;
     error = hwcDisplay->getReleaseFences(&releaseFences);
     if (error != HWC2::Error::None) {
         ALOGE("presentAndGetReleaseFences: Failed to get release fences "
@@ -787,6 +770,8 @@
     auto hwcId = displayData.hwcDisplay->getId();
     mHwcDisplaySlots.erase(hwcId);
     displayData.reset();
+
+    mHwcDevice->destroyDisplay(hwcId);
 }
 
 status_t HWComposer::setOutputBuffer(int32_t displayId,
@@ -885,7 +870,7 @@
 HWComposer::DisplayData::DisplayData()
   : hasClientComposition(false),
     hasDeviceComposition(false),
-    hwcDisplay(),
+    hwcDisplay(nullptr),
     lastPresentFence(Fence::NO_FENCE),
     outbufHandle(nullptr),
     outbufAcquireFence(Fence::NO_FENCE),
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.h b/services/surfaceflinger/DisplayHardware/HWComposer.h
index 3dfb65b..3640bb5 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.h
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.h
@@ -65,23 +65,14 @@
 class HWComposer
 {
 public:
-    class EventHandler {
-        friend class HWComposer;
-        virtual void onVSyncReceived(
-            HWComposer* composer, int32_t disp, nsecs_t timestamp) = 0;
-        virtual void onHotplugReceived(HWComposer* composer, int32_t disp, bool connected) = 0;
-        virtual void onInvalidateReceived(HWComposer* composer) = 0;
-    protected:
-        virtual ~EventHandler() {}
-    };
-
     // Uses the named composer service. Valid choices for normal use
     // are 'default' and 'vr'.
     HWComposer(const std::string& serviceName);
 
     ~HWComposer();
 
-    void setEventHandler(EventHandler* handler);
+    void registerCallback(HWC2::ComposerCallback* callback,
+                          int32_t sequenceId);
 
     bool hasCapability(HWC2::Capability capability) const;
 
@@ -91,7 +82,9 @@
             android_pixel_format_t* format, int32_t* outId);
 
     // Attempts to create a new layer on this display
-    std::shared_ptr<HWC2::Layer> createLayer(int32_t displayId);
+    HWC2::Layer* createLayer(int32_t displayId);
+    // Destroy a previously created layer
+    void destroyLayer(int32_t displayId, HWC2::Layer* layer);
 
     // Asks the HAL what it can do
     status_t prepare(DisplayDevice& displayDevice);
@@ -126,7 +119,7 @@
 
     // Get last release fence for the given layer
     sp<Fence> getLayerReleaseFence(int32_t displayId,
-            const std::shared_ptr<HWC2::Layer>& layer) const;
+            HWC2::Layer* layer) const;
 
     // Set the output buffer and acquire fence for a virtual display.
     // Returns INVALID_OPERATION if displayId is not a virtual display.
@@ -142,6 +135,12 @@
 
     // Events handling ---------------------------------------------------------
 
+    // Returns true if successful, false otherwise. The
+    // DisplayDevice::DisplayType of the display is returned as an output param.
+    bool onVsync(hwc2_display_t displayId, int64_t timestamp,
+                 int32_t* outDisplay);
+    void onHotplug(hwc2_display_t displayId, HWC2::Connection connection);
+
     void setVsyncEnabled(int32_t displayId, HWC2::Vsync enabled);
 
     // Query display parameters.  Pass in a display index (e.g.
@@ -169,19 +168,11 @@
 private:
     static const int32_t VIRTUAL_DISPLAY_ID_BASE = 2;
 
-    void loadHwcModule(const std::string& serviceName);
-
     bool isValidDisplay(int32_t displayId) const;
     static void validateChange(HWC2::Composition from, HWC2::Composition to);
 
     struct cb_context;
 
-    void invalidate(const std::shared_ptr<HWC2::Display>& display);
-    void vsync(const std::shared_ptr<HWC2::Display>& display,
-            int64_t timestamp);
-    void hotplug(const std::shared_ptr<HWC2::Display>& display,
-            HWC2::Connection connected);
-
     struct DisplayData {
         DisplayData();
         ~DisplayData();
@@ -189,11 +180,10 @@
 
         bool hasClientComposition;
         bool hasDeviceComposition;
-        std::shared_ptr<HWC2::Display> hwcDisplay;
+        HWC2::Display* hwcDisplay;
         HWC2::DisplayRequest displayRequests;
         sp<Fence> lastPresentFence;  // signals when the last set op retires
-        std::unordered_map<std::shared_ptr<HWC2::Layer>, sp<Fence>>
-                releaseFences;
+        std::unordered_map<HWC2::Layer*, sp<Fence>> releaseFences;
         buffer_handle_t outbufHandle;
         sp<Fence> outbufAcquireFence;
         mutable std::unordered_map<int32_t,
@@ -214,7 +204,6 @@
     mutable Mutex mDisplayLock;
 
     cb_context*                     mCBContext;
-    EventHandler*                   mEventHandler;
     size_t                          mVSyncCounts[HWC_NUM_PHYSICAL_DISPLAY_TYPES];
     uint32_t                        mRemainingHwcVirtualDisplays;