Revert "[SF] Introduce VirtualDisplayId"

Revert "CE-ARC: Track changes to DisplayId conversions"

Revert submission 12319471-virtual-display-id

Reason for revert: Breaks build on crosshatch-userdebug
Reverted Changes:
I7d9a3062c:CE-ARC: Track changes to DisplayId conversions
I550b1f471:[SF] Introduce VirtualDisplayId

Change-Id: Ife6b6b51babdc0566801f1c7d2db6239f6f926bd
diff --git a/libs/ui/include/ui/DisplayId.h b/libs/ui/include/ui/DisplayId.h
index f196ab9..9eb5483 100644
--- a/libs/ui/include/ui/DisplayId.h
+++ b/libs/ui/include/ui/DisplayId.h
@@ -17,20 +17,13 @@
 #pragma once
 
 #include <cstdint>
-#include <optional>
+#include <functional>
 #include <string>
 
 namespace android {
 
 // ID of a physical or a virtual display. This class acts as a type safe wrapper around uint64_t.
-// The encoding of the ID is type-specific for bits 0 to 61.
 struct DisplayId {
-    // Flag indicating that the display is virtual.
-    static constexpr uint64_t FLAG_VIRTUAL = 1ULL << 63;
-
-    // Flag indicating that the ID is stable across reboots.
-    static constexpr uint64_t FLAG_STABLE = 1ULL << 62;
-
     // TODO(b/162612135) Remove default constructor
     DisplayId() = default;
     constexpr DisplayId(const DisplayId&) = default;
@@ -58,12 +51,8 @@
 
 // DisplayId of a physical display, such as the internal display or externally connected display.
 struct PhysicalDisplayId : DisplayId {
-    static constexpr std::optional<PhysicalDisplayId> tryCast(DisplayId id) {
-        if (id.value & FLAG_VIRTUAL) {
-            return std::nullopt;
-        }
-        return {PhysicalDisplayId(id)};
-    }
+    // Flag indicating that the ID is stable across reboots.
+    static constexpr uint64_t FLAG_STABLE = 1ULL << 62;
 
     // Returns a stable ID based on EDID information.
     static constexpr PhysicalDisplayId fromEdid(uint8_t port, uint16_t manufacturerId,
@@ -80,8 +69,8 @@
 
     // TODO(b/162612135) Remove default constructor
     PhysicalDisplayId() = default;
-    // TODO(b/162612135) Remove constructor
     explicit constexpr PhysicalDisplayId(uint64_t id) : DisplayId(id) {}
+    explicit constexpr PhysicalDisplayId(DisplayId other) : DisplayId(other.value) {}
 
     constexpr uint16_t getManufacturerId() const { return static_cast<uint16_t>(value >> 40); }
 
@@ -92,82 +81,10 @@
                                 uint32_t modelHash)
           : DisplayId(flags | (static_cast<uint64_t>(manufacturerId) << 40) |
                       (static_cast<uint64_t>(modelHash) << 8) | port) {}
-
-    explicit constexpr PhysicalDisplayId(DisplayId other) : DisplayId(other) {}
 };
 
 static_assert(sizeof(PhysicalDisplayId) == sizeof(uint64_t));
 
-struct VirtualDisplayId : DisplayId {
-    using BaseId = uint32_t;
-    // Flag indicating that this virtual display is backed by the GPU.
-    static constexpr uint64_t FLAG_GPU = 1ULL << 61;
-
-    static constexpr std::optional<VirtualDisplayId> tryCast(DisplayId id) {
-        if (id.value & FLAG_VIRTUAL) {
-            return {VirtualDisplayId(id)};
-        }
-        return std::nullopt;
-    }
-
-protected:
-    constexpr VirtualDisplayId(uint64_t flags, BaseId baseId)
-          : DisplayId(DisplayId::FLAG_VIRTUAL | flags | baseId) {}
-
-    explicit constexpr VirtualDisplayId(DisplayId other) : DisplayId(other) {}
-};
-
-struct HalVirtualDisplayId : VirtualDisplayId {
-    explicit constexpr HalVirtualDisplayId(BaseId baseId) : VirtualDisplayId(0, baseId) {}
-
-    static constexpr std::optional<HalVirtualDisplayId> tryCast(DisplayId id) {
-        if ((id.value & FLAG_VIRTUAL) && !(id.value & VirtualDisplayId::FLAG_GPU)) {
-            return {HalVirtualDisplayId(id)};
-        }
-        return std::nullopt;
-    }
-
-private:
-    explicit constexpr HalVirtualDisplayId(DisplayId other) : VirtualDisplayId(other) {}
-};
-
-struct GpuVirtualDisplayId : VirtualDisplayId {
-    explicit constexpr GpuVirtualDisplayId(BaseId baseId)
-          : VirtualDisplayId(VirtualDisplayId::FLAG_GPU, baseId) {}
-
-    static constexpr std::optional<GpuVirtualDisplayId> tryCast(DisplayId id) {
-        if ((id.value & FLAG_VIRTUAL) && (id.value & VirtualDisplayId::FLAG_GPU)) {
-            return {GpuVirtualDisplayId(id)};
-        }
-        return std::nullopt;
-    }
-
-private:
-    explicit constexpr GpuVirtualDisplayId(DisplayId other) : VirtualDisplayId(other) {}
-};
-
-// HalDisplayId is the ID of a display which is managed by HWC.
-// PhysicalDisplayId and HalVirtualDisplayId are implicitly convertible to HalDisplayId.
-struct HalDisplayId : DisplayId {
-    constexpr HalDisplayId(HalVirtualDisplayId other) : DisplayId(other) {}
-    constexpr HalDisplayId(PhysicalDisplayId other) : DisplayId(other) {}
-
-    static constexpr std::optional<HalDisplayId> tryCast(DisplayId id) {
-        if (GpuVirtualDisplayId::tryCast(id)) {
-            return std::nullopt;
-        }
-        return {HalDisplayId(id)};
-    }
-
-private:
-    explicit constexpr HalDisplayId(DisplayId other) : DisplayId(other) {}
-};
-
-static_assert(sizeof(VirtualDisplayId) == sizeof(uint64_t));
-static_assert(sizeof(HalVirtualDisplayId) == sizeof(uint64_t));
-static_assert(sizeof(GpuVirtualDisplayId) == sizeof(uint64_t));
-static_assert(sizeof(HalDisplayId) == sizeof(uint64_t));
-
 } // namespace android
 
 namespace std {
@@ -182,13 +99,4 @@
 template <>
 struct hash<android::PhysicalDisplayId> : hash<android::DisplayId> {};
 
-template <>
-struct hash<android::HalVirtualDisplayId> : hash<android::DisplayId> {};
-
-template <>
-struct hash<android::GpuVirtualDisplayId> : hash<android::DisplayId> {};
-
-template <>
-struct hash<android::HalDisplayId> : hash<android::DisplayId> {};
-
 } // namespace std
diff --git a/libs/ui/tests/Android.bp b/libs/ui/tests/Android.bp
index d005ce8..032dd4c 100644
--- a/libs/ui/tests/Android.bp
+++ b/libs/ui/tests/Android.bp
@@ -29,13 +29,6 @@
 }
 
 cc_test {
-    name: "DisplayId_test",
-    shared_libs: ["libui"],
-    srcs: ["DisplayId_test.cpp"],
-    cflags: ["-Wall", "-Werror"],
-}
-
-cc_test {
     name: "FlattenableHelpers_test",
     shared_libs: ["libui"],
     srcs: ["FlattenableHelpers_test.cpp"],
diff --git a/libs/ui/tests/DisplayId_test.cpp b/libs/ui/tests/DisplayId_test.cpp
deleted file mode 100644
index 1d908b8..0000000
--- a/libs/ui/tests/DisplayId_test.cpp
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <ui/DisplayId.h>
-
-#include <gtest/gtest.h>
-
-namespace android::ui {
-
-TEST(DisplayIdTest, createPhysicalIdFromEdid) {
-    constexpr uint8_t port = 1;
-    constexpr uint16_t manufacturerId = 13;
-    constexpr uint32_t modelHash = 42;
-    PhysicalDisplayId id = PhysicalDisplayId::fromEdid(port, manufacturerId, modelHash);
-    EXPECT_EQ(port, id.getPort());
-    EXPECT_EQ(manufacturerId, id.getManufacturerId());
-    EXPECT_FALSE(VirtualDisplayId::tryCast(id));
-    EXPECT_FALSE(HalVirtualDisplayId::tryCast(id));
-    EXPECT_FALSE(GpuVirtualDisplayId::tryCast(id));
-    EXPECT_TRUE(PhysicalDisplayId::tryCast(id));
-    EXPECT_TRUE(HalDisplayId::tryCast(id));
-}
-
-TEST(DisplayIdTest, createPhysicalIdFromPort) {
-    constexpr uint8_t port = 3;
-    PhysicalDisplayId id = PhysicalDisplayId::fromPort(port);
-    EXPECT_EQ(port, id.getPort());
-    EXPECT_FALSE(VirtualDisplayId::tryCast(id));
-    EXPECT_FALSE(HalVirtualDisplayId::tryCast(id));
-    EXPECT_FALSE(GpuVirtualDisplayId::tryCast(id));
-    EXPECT_TRUE(PhysicalDisplayId::tryCast(id));
-    EXPECT_TRUE(HalDisplayId::tryCast(id));
-}
-
-TEST(DisplayIdTest, createGpuVirtualId) {
-    GpuVirtualDisplayId id(42);
-    EXPECT_TRUE(VirtualDisplayId::tryCast(id));
-    EXPECT_TRUE(GpuVirtualDisplayId::tryCast(id));
-    EXPECT_FALSE(HalVirtualDisplayId::tryCast(id));
-    EXPECT_FALSE(PhysicalDisplayId::tryCast(id));
-    EXPECT_FALSE(HalDisplayId::tryCast(id));
-}
-
-TEST(DisplayIdTest, createHalVirtualId) {
-    HalVirtualDisplayId id(42);
-    EXPECT_TRUE(VirtualDisplayId::tryCast(id));
-    EXPECT_TRUE(HalVirtualDisplayId::tryCast(id));
-    EXPECT_FALSE(GpuVirtualDisplayId::tryCast(id));
-    EXPECT_FALSE(PhysicalDisplayId::tryCast(id));
-    EXPECT_TRUE(HalDisplayId::tryCast(id));
-}
-
-} // namespace android::ui
diff --git a/services/surfaceflinger/BufferLayer.cpp b/services/surfaceflinger/BufferLayer.cpp
index c77298e..cf60b71 100644
--- a/services/surfaceflinger/BufferLayer.cpp
+++ b/services/surfaceflinger/BufferLayer.cpp
@@ -366,7 +366,7 @@
         mFrameTracker.setActualPresentFence(std::shared_ptr<FenceTime>(presentFence));
     } else if (!display) {
         // Do nothing.
-    } else if (const auto displayId = PhysicalDisplayId::tryCast(display->getId());
+    } else if (const auto displayId = display->getId();
                displayId && mFlinger->getHwComposer().isConnected(*displayId)) {
         // The HWC doesn't support present fences, so use the refresh
         // timestamp instead.
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/Display.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/Display.h
index 01dd534..a38d1f3 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/Display.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/Display.h
@@ -34,8 +34,8 @@
  */
 class Display : public virtual Output {
 public:
-    // Gets the DisplayId for the display
-    virtual DisplayId getId() const = 0;
+    // Gets the HWC DisplayId for the display if there is one
+    virtual const std::optional<DisplayId>& getId() const = 0;
 
     // True if the display is secure
     virtual bool isSecure() const = 0;
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/DisplayCreationArgs.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/DisplayCreationArgs.h
index 95ba9f0..6bc677d 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/DisplayCreationArgs.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/DisplayCreationArgs.h
@@ -20,14 +20,12 @@
 #include <optional>
 #include <string>
 
-#include <ui/DisplayId.h>
 #include <ui/DisplayInfo.h>
 #include <ui/PixelFormat.h>
 #include <ui/Size.h>
 
 #include "DisplayHardware/DisplayIdentification.h"
 #include "DisplayHardware/PowerAdvisor.h"
-#include "DisplayIdGenerator.h"
 
 namespace android::compositionengine {
 
@@ -67,9 +65,6 @@
 
     // Debugging. Human readable name for the display.
     std::string name;
-
-    // Generator for IDs of virtual displays, which are backed by the GPU.
-    DisplayIdGenerator<GpuVirtualDisplayId>* gpuVirtualDisplayIdGenerator;
 };
 
 /**
@@ -100,12 +95,6 @@
         return *this;
     }
 
-    DisplayCreationArgsBuilder& setGpuVirtualDisplayIdGenerator(
-            DisplayIdGenerator<GpuVirtualDisplayId>& generator) {
-        mArgs.gpuVirtualDisplayIdGenerator = &generator;
-        return *this;
-    }
-
     DisplayCreationArgsBuilder& setIsSecure(bool isSecure) {
         mArgs.isSecure = isSecure;
         return *this;
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Display.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Display.h
index 54e91ae..7a4f738 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Display.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/impl/Display.h
@@ -57,7 +57,7 @@
     void finishFrame(const CompositionRefreshArgs&) override;
 
     // compositionengine::Display overrides
-    DisplayId getId() const override;
+    const std::optional<DisplayId>& getId() const override;
     bool isSecure() const override;
     bool isVirtual() const override;
     void disconnect() override;
@@ -85,14 +85,12 @@
     std::unique_ptr<compositionengine::OutputLayer> createOutputLayer(const sp<LayerFE>&) const;
 
     // Testing
-    void setDisplayIdForTesting(DisplayId displayId);
+    void setDisplayIdForTesting(std::optional<DisplayId> displayId);
 
 private:
     bool mIsVirtual = false;
-    bool mIsDisconnected = false;
-    DisplayId mId;
+    std::optional<DisplayId> mId;
     Hwc2::PowerAdvisor* mPowerAdvisor = nullptr;
-    DisplayIdGenerator<GpuVirtualDisplayId>* mGpuVirtualDisplayIdGenerator;
 };
 
 // This template factory function standardizes the implementation details of the
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/Display.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/Display.h
index 08a8b84..3a4c70f 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/Display.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/Display.h
@@ -32,7 +32,7 @@
     Display();
     virtual ~Display();
 
-    MOCK_CONST_METHOD0(getId, DisplayId());
+    MOCK_CONST_METHOD0(getId, const std::optional<DisplayId>&());
     MOCK_CONST_METHOD0(isSecure, bool());
     MOCK_CONST_METHOD0(isVirtual, bool());
 
diff --git a/services/surfaceflinger/CompositionEngine/src/Display.cpp b/services/surfaceflinger/CompositionEngine/src/Display.cpp
index 0b0b8d5..5459861 100644
--- a/services/surfaceflinger/CompositionEngine/src/Display.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/Display.cpp
@@ -51,26 +51,19 @@
 
 void Display::setConfiguration(const compositionengine::DisplayCreationArgs& args) {
     mIsVirtual = !args.physical;
+    mId = args.physical ? std::make_optional(args.physical->id) : std::nullopt;
     mPowerAdvisor = args.powerAdvisor;
+
     editState().isSecure = args.isSecure;
     editState().displaySpace.bounds = Rect(args.pixels);
-    setLayerStackFilter(args.layerStackId,
-                        args.physical && args.physical->type == DisplayConnectionType::Internal);
-    setName(args.name);
-    mGpuVirtualDisplayIdGenerator = args.gpuVirtualDisplayIdGenerator;
 
-    if (args.physical) {
-        mId = args.physical->id;
-    } else {
-        std::optional<DisplayId> id;
-        if (args.useHwcVirtualDisplays) {
-            id = maybeAllocateDisplayIdForVirtualDisplay(args.pixels, args.pixelFormat);
-        }
-        if (!id) {
-            id = mGpuVirtualDisplayIdGenerator->nextId();
-        }
-        LOG_ALWAYS_FATAL_IF(!id, "Failed to generate display ID");
-        mId = *id;
+    setLayerStackFilter(args.layerStackId,
+                        args.physical ? args.physical->type == DisplayConnectionType::Internal
+                                      : false);
+    setName(args.name);
+
+    if (!args.physical && args.useHwcVirtualDisplays) {
+        mId = maybeAllocateDisplayIdForVirtualDisplay(args.pixels, args.pixelFormat);
     }
 }
 
@@ -85,7 +78,7 @@
     return Output::isValid() && mPowerAdvisor;
 }
 
-DisplayId Display::getId() const {
+const std::optional<DisplayId>& Display::getId() const {
     return mId;
 }
 
@@ -101,36 +94,31 @@
     return mId;
 }
 
-void Display::setDisplayIdForTesting(DisplayId displayId) {
+void Display::setDisplayIdForTesting(std::optional<DisplayId> displayId) {
     mId = displayId;
 }
 
 void Display::disconnect() {
-    if (mIsDisconnected) {
-        return;
-    }
-
-    mIsDisconnected = true;
-    if (const auto id = GpuVirtualDisplayId::tryCast(mId)) {
-        mGpuVirtualDisplayIdGenerator->markUnused(*id);
-        return;
-    }
-    const auto halDisplayId = HalDisplayId::tryCast(mId);
-    LOG_FATAL_IF(!halDisplayId);
-    getCompositionEngine().getHwComposer().disconnectDisplay(*halDisplayId);
-}
-
-void Display::setColorTransform(const compositionengine::CompositionRefreshArgs& args) {
-    Output::setColorTransform(args);
-    const auto halDisplayId = HalDisplayId::tryCast(mId);
-    if (mIsDisconnected || !halDisplayId || CC_LIKELY(!args.colorTransformMatrix)) {
+    if (!mId) {
         return;
     }
 
     auto& hwc = getCompositionEngine().getHwComposer();
-    status_t result = hwc.setColorTransform(*halDisplayId, *args.colorTransformMatrix);
+    hwc.disconnectDisplay(*mId);
+    mId.reset();
+}
+
+void Display::setColorTransform(const compositionengine::CompositionRefreshArgs& args) {
+    Output::setColorTransform(args);
+
+    if (!mId || CC_LIKELY(!args.colorTransformMatrix)) {
+        return;
+    }
+
+    auto& hwc = getCompositionEngine().getHwComposer();
+    status_t result = hwc.setColorTransform(*mId, *args.colorTransformMatrix);
     ALOGE_IF(result != NO_ERROR, "Failed to set color transform on display \"%s\": %d",
-             to_string(mId).c_str(), result);
+             mId ? to_string(*mId).c_str() : "", result);
 }
 
 void Display::setColorProfile(const ColorProfile& colorProfile) {
@@ -152,10 +140,8 @@
 
     Output::setColorProfile(colorProfile);
 
-    const auto physicalId = PhysicalDisplayId::tryCast(mId);
-    LOG_FATAL_IF(!physicalId);
-    getCompositionEngine().getHwComposer().setActiveColorMode(*physicalId, colorProfile.mode,
-                                                              colorProfile.renderIntent);
+    auto& hwc = getCompositionEngine().getHwComposer();
+    hwc.setActiveColorMode(*mId, colorProfile.mode, colorProfile.renderIntent);
 }
 
 void Display::dump(std::string& out) const {
@@ -164,8 +150,14 @@
     StringAppendF(&out, "   Composition Display State: [\"%s\"]", getName().c_str());
 
     out.append("\n   ");
+
     dumpVal(out, "isVirtual", mIsVirtual);
-    dumpVal(out, "DisplayId", to_string(mId));
+    if (mId) {
+        dumpVal(out, "hwcId", to_string(*mId));
+    } else {
+        StringAppendF(&out, "no hwcId, ");
+    }
+
     out.append("\n");
 
     Output::dumpBase(out);
@@ -186,33 +178,31 @@
 
 std::unique_ptr<compositionengine::OutputLayer> Display::createOutputLayer(
         const sp<compositionengine::LayerFE>& layerFE) const {
-    auto outputLayer = impl::createOutputLayer(*this, layerFE);
+    auto result = impl::createOutputLayer(*this, layerFE);
 
-    if (const auto halDisplayId = HalDisplayId::tryCast(mId);
-        outputLayer && !mIsDisconnected && halDisplayId) {
+    if (result && mId) {
         auto& hwc = getCompositionEngine().getHwComposer();
+        auto displayId = *mId;
         // Note: For the moment we ensure it is safe to take a reference to the
         // HWComposer implementation by destroying all the OutputLayers (and
         // hence the HWC2::Layers they own) before setting a new HWComposer. See
         // for example SurfaceFlinger::updateVrFlinger().
         // TODO(b/121291683): Make this safer.
-        auto hwcLayer =
-                std::shared_ptr<HWC2::Layer>(hwc.createLayer(*halDisplayId),
-                                             [&hwc, id = *halDisplayId](HWC2::Layer* layer) {
-                                                 hwc.destroyLayer(id, layer);
-                                             });
+        auto hwcLayer = std::shared_ptr<HWC2::Layer>(hwc.createLayer(displayId),
+                                                     [&hwc, displayId](HWC2::Layer* layer) {
+                                                         hwc.destroyLayer(displayId, layer);
+                                                     });
         ALOGE_IF(!hwcLayer, "Failed to create a HWC layer for a HWC supported display %s",
                  getName().c_str());
-        outputLayer->setHwcLayer(std::move(hwcLayer));
+        result->setHwcLayer(std::move(hwcLayer));
     }
-    return outputLayer;
+    return result;
 }
 
 void Display::setReleasedLayers(const compositionengine::CompositionRefreshArgs& refreshArgs) {
     Output::setReleasedLayers(refreshArgs);
 
-    if (mIsDisconnected || GpuVirtualDisplayId::tryCast(mId) ||
-        refreshArgs.layersWithQueuedFrames.empty()) {
+    if (!mId || refreshArgs.layersWithQueuedFrames.empty()) {
         return;
     }
 
@@ -248,25 +238,19 @@
     ATRACE_CALL();
     ALOGV(__FUNCTION__);
 
-    if (mIsDisconnected) {
-        return;
-    }
-
     // Default to the base settings -- client composition only.
     Output::chooseCompositionStrategy();
 
-    // If we don't have a HWC display, then we are done.
-    const auto halDisplayId = HalDisplayId::tryCast(mId);
-    if (!halDisplayId) {
+    // If we don't have a HWC display, then we are done
+    if (!mId) {
         return;
     }
 
     // Get any composition changes requested by the HWC device, and apply them.
     std::optional<android::HWComposer::DeviceRequestedChanges> changes;
     auto& hwc = getCompositionEngine().getHwComposer();
-    if (status_t result =
-                hwc.getDeviceCompositionChanges(*halDisplayId, anyLayersRequireClientComposition(),
-                                                &changes);
+    if (status_t result = hwc.getDeviceCompositionChanges(*mId, anyLayersRequireClientComposition(),
+                                                          &changes);
         result != NO_ERROR) {
         ALOGE("chooseCompositionStrategy failed for %s: %d (%s)", getName().c_str(), result,
               strerror(-result));
@@ -287,12 +271,8 @@
 
 bool Display::getSkipColorTransform() const {
     const auto& hwc = getCompositionEngine().getHwComposer();
-    if (const auto halDisplayId = HalDisplayId::tryCast(mId)) {
-        return hwc.hasDisplayCapability(*halDisplayId,
-                                        hal::DisplayCapability::SKIP_CLIENT_COLOR_TRANSFORM);
-    }
-
-    return hwc.hasCapability(hal::Capability::SKIP_CLIENT_COLOR_TRANSFORM);
+    return mId ? hwc.hasDisplayCapability(*mId, hal::DisplayCapability::SKIP_CLIENT_COLOR_TRANSFORM)
+               : hwc.hasCapability(hal::Capability::SKIP_CLIENT_COLOR_TRANSFORM);
 }
 
 bool Display::anyLayersRequireClientComposition() const {
@@ -359,17 +339,16 @@
 }
 
 compositionengine::Output::FrameFences Display::presentAndGetFrameFences() {
-    auto fences = impl::Output::presentAndGetFrameFences();
+    auto result = impl::Output::presentAndGetFrameFences();
 
-    const auto halDisplayIdOpt = HalDisplayId::tryCast(mId);
-    if (mIsDisconnected || !halDisplayIdOpt) {
-        return fences;
+    if (!mId) {
+        return result;
     }
 
     auto& hwc = getCompositionEngine().getHwComposer();
-    hwc.presentAndGetReleaseFences(*halDisplayIdOpt);
+    hwc.presentAndGetReleaseFences(*mId);
 
-    fences.presentFence = hwc.getPresentFence(*halDisplayIdOpt);
+    result.presentFence = hwc.getPresentFence(*mId);
 
     // TODO(b/121291683): Change HWComposer call to return entire map
     for (const auto* layer : getOutputLayersOrderedByZ()) {
@@ -378,19 +357,19 @@
             continue;
         }
 
-        fences.layerFences.emplace(hwcLayer, hwc.getLayerReleaseFence(*halDisplayIdOpt, hwcLayer));
+        result.layerFences.emplace(hwcLayer, hwc.getLayerReleaseFence(*mId, hwcLayer));
     }
 
-    hwc.clearReleaseFences(*halDisplayIdOpt);
+    hwc.clearReleaseFences(*mId);
 
-    return fences;
+    return result;
 }
 
 void Display::setExpensiveRenderingExpected(bool enabled) {
     Output::setExpensiveRenderingExpected(enabled);
 
-    if (mPowerAdvisor && !GpuVirtualDisplayId::tryCast(mId)) {
-        mPowerAdvisor->setExpensiveRenderingExpected(mId, enabled);
+    if (mPowerAdvisor && mId) {
+        mPowerAdvisor->setExpensiveRenderingExpected(*mId, enabled);
     }
 }
 
@@ -399,10 +378,11 @@
     // 1) It is being handled by hardware composer, which may need this to
     //    keep its virtual display state machine in sync, or
     // 2) There is work to be done (the dirty region isn't empty)
-    if (GpuVirtualDisplayId::tryCast(mId) &&
-        getDirtyRegion(refreshArgs.repaintEverything).isEmpty()) {
-        ALOGV("Skipping display composition");
-        return;
+    if (!mId) {
+        if (getDirtyRegion(refreshArgs.repaintEverything).isEmpty()) {
+            ALOGV("Skipping display composition");
+            return;
+        }
     }
 
     impl::Output::finishFrame(refreshArgs);
diff --git a/services/surfaceflinger/CompositionEngine/tests/DisplayTest.cpp b/services/surfaceflinger/CompositionEngine/tests/DisplayTest.cpp
index 6d01bf1..4519a9d 100644
--- a/services/surfaceflinger/CompositionEngine/tests/DisplayTest.cpp
+++ b/services/surfaceflinger/CompositionEngine/tests/DisplayTest.cpp
@@ -176,7 +176,6 @@
     DisplayCreationArgs getDisplayCreationArgsForNonHWCVirtualDisplay() {
         return DisplayCreationArgsBuilder()
                 .setUseHwcVirtualDisplays(false)
-                .setGpuVirtualDisplayIdGenerator(mGpuDisplayIdGenerator)
                 .setPixels({DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT})
                 .setPixelFormat(static_cast<ui::PixelFormat>(PIXEL_FORMAT_RGBA_8888))
                 .setIsSecure(false)
@@ -190,7 +189,6 @@
     StrictMock<renderengine::mock::RenderEngine> mRenderEngine;
     StrictMock<mock::CompositionEngine> mCompositionEngine;
     sp<mock::NativeWindow> mNativeWindow = new StrictMock<mock::NativeWindow>();
-    RandomDisplayIdGenerator<GpuVirtualDisplayId> mGpuDisplayIdGenerator;
 };
 
 struct PartialMockDisplayTestCommon : public DisplayTestCommon {
@@ -247,7 +245,7 @@
                                        getDisplayCreationArgsForNonHWCVirtualDisplay());
     EXPECT_FALSE(display->isSecure());
     EXPECT_TRUE(display->isVirtual());
-    EXPECT_TRUE(GpuVirtualDisplayId::tryCast(display->getId()));
+    EXPECT_EQ(std::nullopt, display->getId());
 }
 
 /*
@@ -334,7 +332,6 @@
     mDisplay->setConfiguration(
             DisplayCreationArgsBuilder()
                     .setUseHwcVirtualDisplays(true)
-                    .setGpuVirtualDisplayIdGenerator(mGpuDisplayIdGenerator)
                     .setPixels(ui::Size(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_WIDTH))
                     .setPixelFormat(static_cast<ui::PixelFormat>(PIXEL_FORMAT_RGBA_8888))
                     .setIsSecure(false)
@@ -343,7 +340,7 @@
                     .setName(getDisplayNameFromCurrentTest())
                     .build());
 
-    EXPECT_TRUE(GpuVirtualDisplayId::tryCast(mDisplay->getId()));
+    EXPECT_EQ(std::nullopt, mDisplay->getId());
     EXPECT_FALSE(mDisplay->isSecure());
     EXPECT_TRUE(mDisplay->isVirtual());
     EXPECT_EQ(DEFAULT_LAYER_STACK, mDisplay->getState().layerStackId);
@@ -355,7 +352,6 @@
     mDisplay->setConfiguration(
             DisplayCreationArgsBuilder()
                     .setUseHwcVirtualDisplays(false)
-                    .setGpuVirtualDisplayIdGenerator(mGpuDisplayIdGenerator)
                     .setPixels(ui::Size(DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_WIDTH))
                     .setPixelFormat(static_cast<ui::PixelFormat>(PIXEL_FORMAT_RGBA_8888))
                     .setIsSecure(false)
@@ -364,7 +360,7 @@
                     .setName(getDisplayNameFromCurrentTest())
                     .build());
 
-    EXPECT_TRUE(GpuVirtualDisplayId::tryCast(mDisplay->getId()));
+    EXPECT_EQ(std::nullopt, mDisplay->getId());
     EXPECT_FALSE(mDisplay->isSecure());
     EXPECT_TRUE(mDisplay->isVirtual());
     EXPECT_EQ(DEFAULT_LAYER_STACK, mDisplay->getState().layerStackId);
@@ -379,13 +375,16 @@
 using DisplayDisconnectTest = PartialMockDisplayTestCommon;
 
 TEST_F(DisplayDisconnectTest, disconnectsDisplay) {
-    // The first call to disconnect will disconnect the display with the HWC.
-    EXPECT_CALL(mHwComposer, disconnectDisplay(HalDisplayId(DEFAULT_DISPLAY_ID))).Times(1);
+    // The first call to disconnect will disconnect the display with the HWC and
+    // set mHwcId to -1.
+    EXPECT_CALL(mHwComposer, disconnectDisplay(DEFAULT_DISPLAY_ID)).Times(1);
     mDisplay->disconnect();
+    EXPECT_FALSE(mDisplay->getId());
 
     // Subsequent calls will do nothing,
-    EXPECT_CALL(mHwComposer, disconnectDisplay(HalDisplayId(DEFAULT_DISPLAY_ID))).Times(0);
+    EXPECT_CALL(mHwComposer, disconnectDisplay(DEFAULT_DISPLAY_ID)).Times(0);
     mDisplay->disconnect();
+    EXPECT_FALSE(mDisplay->getId());
 }
 
 /*
@@ -403,8 +402,7 @@
     // Identity matrix sets an identity state value
     const mat4 kIdentity;
 
-    EXPECT_CALL(mHwComposer, setColorTransform(HalDisplayId(DEFAULT_DISPLAY_ID), kIdentity))
-            .Times(1);
+    EXPECT_CALL(mHwComposer, setColorTransform(DEFAULT_DISPLAY_ID, kIdentity)).Times(1);
 
     refreshArgs.colorTransformMatrix = kIdentity;
     mDisplay->setColorTransform(refreshArgs);
@@ -412,8 +410,7 @@
     // Non-identity matrix sets a non-identity state value
     const mat4 kNonIdentity = mat4() * 2;
 
-    EXPECT_CALL(mHwComposer, setColorTransform(HalDisplayId(DEFAULT_DISPLAY_ID), kNonIdentity))
-            .Times(1);
+    EXPECT_CALL(mHwComposer, setColorTransform(DEFAULT_DISPLAY_ID, kNonIdentity)).Times(1);
 
     refreshArgs.colorTransformMatrix = kNonIdentity;
     mDisplay->setColorTransform(refreshArgs);
@@ -530,14 +527,13 @@
     sp<mock::LayerFE> layerFE = new StrictMock<mock::LayerFE>();
     StrictMock<HWC2::mock::Layer> hwcLayer;
 
-    EXPECT_CALL(mHwComposer, createLayer(HalDisplayId(DEFAULT_DISPLAY_ID)))
-            .WillOnce(Return(&hwcLayer));
+    EXPECT_CALL(mHwComposer, createLayer(DEFAULT_DISPLAY_ID)).WillOnce(Return(&hwcLayer));
 
     auto outputLayer = mDisplay->createOutputLayer(layerFE);
 
     EXPECT_EQ(&hwcLayer, outputLayer->getHwcLayer());
 
-    EXPECT_CALL(mHwComposer, destroyLayer(HalDisplayId(DEFAULT_DISPLAY_ID), &hwcLayer));
+    EXPECT_CALL(mHwComposer, destroyLayer(DEFAULT_DISPLAY_ID, &hwcLayer));
     outputLayer.reset();
 }
 
@@ -610,7 +606,7 @@
     auto args = getDisplayCreationArgsForNonHWCVirtualDisplay();
     std::shared_ptr<Display> nonHwcDisplay =
             createPartialMockDisplay<Display>(mCompositionEngine, args);
-    EXPECT_TRUE(GpuVirtualDisplayId::tryCast(nonHwcDisplay->getId()));
+    EXPECT_FALSE(nonHwcDisplay->getId());
 
     nonHwcDisplay->chooseCompositionStrategy();
 
@@ -621,8 +617,7 @@
 
 TEST_F(DisplayChooseCompositionStrategyTest, takesEarlyOutOnHwcError) {
     EXPECT_CALL(*mDisplay, anyLayersRequireClientComposition()).WillOnce(Return(false));
-    EXPECT_CALL(mHwComposer,
-                getDeviceCompositionChanges(HalDisplayId(DEFAULT_DISPLAY_ID), false, _))
+    EXPECT_CALL(mHwComposer, getDeviceCompositionChanges(DEFAULT_DISPLAY_ID, false, _))
             .WillOnce(Return(INVALID_OPERATION));
 
     mDisplay->chooseCompositionStrategy();
@@ -644,7 +639,7 @@
             .InSequence(s)
             .WillOnce(Return(false));
 
-    EXPECT_CALL(mHwComposer, getDeviceCompositionChanges(HalDisplayId(DEFAULT_DISPLAY_ID), true, _))
+    EXPECT_CALL(mHwComposer, getDeviceCompositionChanges(DEFAULT_DISPLAY_ID, true, _))
             .WillOnce(Return(NO_ERROR));
     EXPECT_CALL(*mDisplay, allLayersRequireClientComposition()).WillOnce(Return(false));
 
@@ -674,7 +669,7 @@
             .InSequence(s)
             .WillOnce(Return(false));
 
-    EXPECT_CALL(mHwComposer, getDeviceCompositionChanges(HalDisplayId(DEFAULT_DISPLAY_ID), true, _))
+    EXPECT_CALL(mHwComposer, getDeviceCompositionChanges(DEFAULT_DISPLAY_ID, true, _))
             .WillOnce(DoAll(SetArgPointee<2>(changes), Return(NO_ERROR)));
     EXPECT_CALL(*mDisplay, applyChangedTypesToLayers(changes.changedTypes)).Times(1);
     EXPECT_CALL(*mDisplay, applyDisplayRequests(changes.displayRequests)).Times(1);
@@ -704,7 +699,7 @@
 
 TEST_F(DisplayGetSkipColorTransformTest, checksDisplayCapability) {
     EXPECT_CALL(mHwComposer,
-                hasDisplayCapability(HalDisplayId(DEFAULT_DISPLAY_ID),
+                hasDisplayCapability(DEFAULT_DISPLAY_ID,
                                      hal::DisplayCapability::SKIP_CLIENT_COLOR_TRANSFORM))
             .WillOnce(Return(true));
     EXPECT_TRUE(mDisplay->getSkipColorTransform());
@@ -862,16 +857,13 @@
     sp<Fence> layer1Fence = new Fence();
     sp<Fence> layer2Fence = new Fence();
 
-    EXPECT_CALL(mHwComposer, presentAndGetReleaseFences(HalDisplayId(DEFAULT_DISPLAY_ID))).Times(1);
-    EXPECT_CALL(mHwComposer, getPresentFence(HalDisplayId(DEFAULT_DISPLAY_ID)))
-            .WillOnce(Return(presentFence));
-    EXPECT_CALL(mHwComposer,
-                getLayerReleaseFence(HalDisplayId(DEFAULT_DISPLAY_ID), &mLayer1.hwc2Layer))
+    EXPECT_CALL(mHwComposer, presentAndGetReleaseFences(DEFAULT_DISPLAY_ID)).Times(1);
+    EXPECT_CALL(mHwComposer, getPresentFence(DEFAULT_DISPLAY_ID)).WillOnce(Return(presentFence));
+    EXPECT_CALL(mHwComposer, getLayerReleaseFence(DEFAULT_DISPLAY_ID, &mLayer1.hwc2Layer))
             .WillOnce(Return(layer1Fence));
-    EXPECT_CALL(mHwComposer,
-                getLayerReleaseFence(HalDisplayId(DEFAULT_DISPLAY_ID), &mLayer2.hwc2Layer))
+    EXPECT_CALL(mHwComposer, getLayerReleaseFence(DEFAULT_DISPLAY_ID, &mLayer2.hwc2Layer))
             .WillOnce(Return(layer2Fence));
-    EXPECT_CALL(mHwComposer, clearReleaseFences(HalDisplayId(DEFAULT_DISPLAY_ID))).Times(1);
+    EXPECT_CALL(mHwComposer, clearReleaseFences(DEFAULT_DISPLAY_ID)).Times(1);
 
     auto result = mDisplay->presentAndGetFrameFences();
 
diff --git a/services/surfaceflinger/CompositionEngine/tests/MockHWComposer.h b/services/surfaceflinger/CompositionEngine/tests/MockHWComposer.h
index b5cda68..1dd5df4 100644
--- a/services/surfaceflinger/CompositionEngine/tests/MockHWComposer.h
+++ b/services/surfaceflinger/CompositionEngine/tests/MockHWComposer.h
@@ -42,68 +42,63 @@
     MOCK_CONST_METHOD3(getDisplayIdentificationData,
                        bool(hal::HWDisplayId, uint8_t*, DisplayIdentificationData*));
     MOCK_CONST_METHOD1(hasCapability, bool(hal::Capability));
-    MOCK_CONST_METHOD2(hasDisplayCapability, bool(HalDisplayId, hal::DisplayCapability));
+    MOCK_CONST_METHOD2(hasDisplayCapability, bool(DisplayId, hal::DisplayCapability));
 
     MOCK_METHOD3(allocateVirtualDisplay,
                  std::optional<DisplayId>(uint32_t, uint32_t, ui::PixelFormat*));
     MOCK_METHOD2(allocatePhysicalDisplay, void(hal::HWDisplayId, PhysicalDisplayId));
-    MOCK_METHOD1(createLayer, HWC2::Layer*(HalDisplayId));
-    MOCK_METHOD2(destroyLayer, void(HalDisplayId, HWC2::Layer*));
+    MOCK_METHOD1(createLayer, HWC2::Layer*(DisplayId));
+    MOCK_METHOD2(destroyLayer, void(DisplayId, HWC2::Layer*));
     MOCK_METHOD3(getDeviceCompositionChanges,
-                 status_t(HalDisplayId, bool,
+                 status_t(DisplayId, bool,
                           std::optional<android::HWComposer::DeviceRequestedChanges>*));
     MOCK_METHOD5(setClientTarget,
-                 status_t(HalDisplayId, uint32_t, const sp<Fence>&, const sp<GraphicBuffer>&,
+                 status_t(DisplayId, uint32_t, const sp<Fence>&, const sp<GraphicBuffer>&,
                           ui::Dataspace));
-    MOCK_METHOD1(presentAndGetReleaseFences, status_t(HalDisplayId));
-    MOCK_METHOD2(setPowerMode, status_t(PhysicalDisplayId, hal::PowerMode));
-    MOCK_METHOD2(setActiveConfig, status_t(HalDisplayId, size_t));
-    MOCK_METHOD2(setColorTransform, status_t(HalDisplayId, const mat4&));
-    MOCK_METHOD1(disconnectDisplay, void(HalDisplayId));
+    MOCK_METHOD1(presentAndGetReleaseFences, status_t(DisplayId));
+    MOCK_METHOD2(setPowerMode, status_t(DisplayId, hal::PowerMode));
+    MOCK_METHOD2(setActiveConfig, status_t(DisplayId, size_t));
+    MOCK_METHOD2(setColorTransform, status_t(DisplayId, const mat4&));
+    MOCK_METHOD1(disconnectDisplay, void(DisplayId));
     MOCK_CONST_METHOD1(hasDeviceComposition, bool(const std::optional<DisplayId>&));
-    MOCK_CONST_METHOD1(getPresentFence, sp<Fence>(HalDisplayId));
-    MOCK_CONST_METHOD2(getLayerReleaseFence, sp<Fence>(HalDisplayId, HWC2::Layer*));
-    MOCK_METHOD3(setOutputBuffer,
-                 status_t(HalVirtualDisplayId, const sp<Fence>&, const sp<GraphicBuffer>&));
-    MOCK_METHOD1(clearReleaseFences, void(HalDisplayId));
-    MOCK_METHOD2(getHdrCapabilities, status_t(HalDisplayId, HdrCapabilities*));
-    MOCK_CONST_METHOD1(getSupportedPerFrameMetadata, int32_t(HalDisplayId));
-    MOCK_CONST_METHOD2(getRenderIntents,
-                       std::vector<ui::RenderIntent>(HalDisplayId, ui::ColorMode));
-    MOCK_METHOD2(getDataspaceSaturationMatrix, mat4(HalDisplayId, ui::Dataspace));
+    MOCK_CONST_METHOD1(getPresentFence, sp<Fence>(DisplayId));
+    MOCK_CONST_METHOD2(getLayerReleaseFence, sp<Fence>(DisplayId, HWC2::Layer*));
+    MOCK_METHOD3(setOutputBuffer, status_t(DisplayId, const sp<Fence>&, const sp<GraphicBuffer>&));
+    MOCK_METHOD1(clearReleaseFences, void(DisplayId));
+    MOCK_METHOD2(getHdrCapabilities, status_t(DisplayId, HdrCapabilities*));
+    MOCK_CONST_METHOD1(getSupportedPerFrameMetadata, int32_t(DisplayId));
+    MOCK_CONST_METHOD2(getRenderIntents, std::vector<ui::RenderIntent>(DisplayId, ui::ColorMode));
+    MOCK_METHOD2(getDataspaceSaturationMatrix, mat4(DisplayId, ui::Dataspace));
     MOCK_METHOD4(getDisplayedContentSamplingAttributes,
-                 status_t(HalDisplayId, ui::PixelFormat*, ui::Dataspace*, uint8_t*));
-    MOCK_METHOD4(setDisplayContentSamplingEnabled, status_t(HalDisplayId, bool, uint8_t, uint64_t));
+                 status_t(DisplayId, ui::PixelFormat*, ui::Dataspace*, uint8_t*));
+    MOCK_METHOD4(setDisplayContentSamplingEnabled, status_t(DisplayId, bool, uint8_t, uint64_t));
     MOCK_METHOD4(getDisplayedContentSample,
-                 status_t(HalDisplayId, uint64_t, uint64_t, DisplayedFrameStats*));
-    MOCK_METHOD2(setDisplayBrightness, std::future<status_t>(PhysicalDisplayId, float));
-    MOCK_METHOD2(getDisplayBrightnessSupport, status_t(PhysicalDisplayId, bool*));
+                 status_t(DisplayId, uint64_t, uint64_t, DisplayedFrameStats*));
+    MOCK_METHOD2(setDisplayBrightness, std::future<status_t>(DisplayId, float));
+    MOCK_METHOD2(getDisplayBrightnessSupport, status_t(DisplayId, bool*));
 
     MOCK_METHOD2(onHotplug,
                  std::optional<DisplayIdentificationInfo>(hal::HWDisplayId, hal::Connection));
     MOCK_METHOD2(onVsync, bool(hal::HWDisplayId, int64_t));
-    MOCK_METHOD2(setVsyncEnabled, void(PhysicalDisplayId, hal::Vsync));
-    MOCK_CONST_METHOD1(getRefreshTimestamp, nsecs_t(PhysicalDisplayId));
-    MOCK_CONST_METHOD1(isConnected, bool(PhysicalDisplayId));
-    MOCK_CONST_METHOD1(
-            getConfigs,
-            std::vector<std::shared_ptr<const HWC2::Display::Config>>(PhysicalDisplayId));
-    MOCK_CONST_METHOD1(getActiveConfig,
-                       std::shared_ptr<const HWC2::Display::Config>(PhysicalDisplayId));
-    MOCK_CONST_METHOD1(getActiveConfigIndex, int(PhysicalDisplayId));
-    MOCK_CONST_METHOD1(getColorModes, std::vector<ui::ColorMode>(PhysicalDisplayId));
-    MOCK_METHOD3(setActiveColorMode, status_t(PhysicalDisplayId, ui::ColorMode, ui::RenderIntent));
+    MOCK_METHOD2(setVsyncEnabled, void(DisplayId, hal::Vsync));
+    MOCK_CONST_METHOD1(getRefreshTimestamp, nsecs_t(DisplayId));
+    MOCK_CONST_METHOD1(isConnected, bool(DisplayId));
+    MOCK_CONST_METHOD1(getConfigs,
+                       std::vector<std::shared_ptr<const HWC2::Display::Config>>(DisplayId));
+    MOCK_CONST_METHOD1(getActiveConfig, std::shared_ptr<const HWC2::Display::Config>(DisplayId));
+    MOCK_CONST_METHOD1(getActiveConfigIndex, int(DisplayId));
+    MOCK_CONST_METHOD1(getColorModes, std::vector<ui::ColorMode>(DisplayId));
+    MOCK_METHOD3(setActiveColorMode, status_t(DisplayId, ui::ColorMode, ui::RenderIntent));
     MOCK_CONST_METHOD0(isUsingVrComposer, bool());
-    MOCK_CONST_METHOD1(getDisplayConnectionType, DisplayConnectionType(PhysicalDisplayId));
-    MOCK_CONST_METHOD1(isVsyncPeriodSwitchSupported, bool(PhysicalDisplayId));
-    MOCK_CONST_METHOD1(getDisplayVsyncPeriod, nsecs_t(PhysicalDisplayId));
+    MOCK_CONST_METHOD1(getDisplayConnectionType, DisplayConnectionType(DisplayId));
+    MOCK_CONST_METHOD1(isVsyncPeriodSwitchSupported, bool(DisplayId));
+    MOCK_CONST_METHOD1(getDisplayVsyncPeriod, nsecs_t(DisplayId));
     MOCK_METHOD4(setActiveConfigWithConstraints,
-                 status_t(PhysicalDisplayId, size_t, const hal::VsyncPeriodChangeConstraints&,
+                 status_t(DisplayId, size_t, const hal::VsyncPeriodChangeConstraints&,
                           hal::VsyncPeriodChangeTimeline*));
-    MOCK_METHOD2(setAutoLowLatencyMode, status_t(PhysicalDisplayId, bool));
-    MOCK_METHOD2(getSupportedContentTypes,
-                 status_t(PhysicalDisplayId, std::vector<hal::ContentType>*));
-    MOCK_METHOD2(setContentType, status_t(PhysicalDisplayId, hal::ContentType));
+    MOCK_METHOD2(setAutoLowLatencyMode, status_t(DisplayId, bool));
+    MOCK_METHOD2(getSupportedContentTypes, status_t(DisplayId, std::vector<hal::ContentType>*));
+    MOCK_METHOD2(setContentType, status_t(DisplayId, hal::ContentType));
     MOCK_CONST_METHOD0(getSupportedLayerGenericMetadata,
                        const std::unordered_map<std::string, bool>&());
 
diff --git a/services/surfaceflinger/CompositionEngine/tests/RenderSurfaceTest.cpp b/services/surfaceflinger/CompositionEngine/tests/RenderSurfaceTest.cpp
index 6ce8a6b..8d1eb36 100644
--- a/services/surfaceflinger/CompositionEngine/tests/RenderSurfaceTest.cpp
+++ b/services/surfaceflinger/CompositionEngine/tests/RenderSurfaceTest.cpp
@@ -33,7 +33,7 @@
 
 constexpr int32_t DEFAULT_DISPLAY_WIDTH = 1920;
 constexpr int32_t DEFAULT_DISPLAY_HEIGHT = 1080;
-constexpr DisplayId DEFAULT_DISPLAY_ID = PhysicalDisplayId(123u);
+constexpr std::optional<DisplayId> DEFAULT_DISPLAY_ID = {PhysicalDisplayId(123u)};
 const std::string DEFAULT_DISPLAY_NAME = "Mock Display";
 
 using testing::_;
@@ -48,7 +48,7 @@
 class RenderSurfaceTest : public testing::Test {
 public:
     RenderSurfaceTest() {
-        EXPECT_CALL(mDisplay, getId()).WillRepeatedly(Return(DEFAULT_DISPLAY_ID));
+        EXPECT_CALL(mDisplay, getId()).WillRepeatedly(ReturnRef(DEFAULT_DISPLAY_ID));
         EXPECT_CALL(mDisplay, getName()).WillRepeatedly(ReturnRef(DEFAULT_DISPLAY_NAME));
         EXPECT_CALL(mCompositionEngine, getRenderEngine).WillRepeatedly(ReturnRef(mRenderEngine));
         EXPECT_CALL(*mNativeWindow, disconnect(NATIVE_WINDOW_API_EGL))
diff --git a/services/surfaceflinger/DisplayDevice.cpp b/services/surfaceflinger/DisplayDevice.cpp
index 8aca713..a1ccaad 100644
--- a/services/surfaceflinger/DisplayDevice.cpp
+++ b/services/surfaceflinger/DisplayDevice.cpp
@@ -201,12 +201,17 @@
 }
 
 std::string DisplayDevice::getDebugName() const {
+    std::string displayId;
+    if (const auto id = getId()) {
+        displayId = to_string(*id) + ", ";
+    }
+
     const char* type = "virtual";
     if (mConnectionType) {
         type = *mConnectionType == DisplayConnectionType::Internal ? "internal" : "external";
     }
 
-    return base::StringPrintf("DisplayDevice{%s, %s%s, \"%s\"}", to_string(getId()).c_str(), type,
+    return base::StringPrintf("DisplayDevice{%s%s%s, \"%s\"}", displayId.c_str(), type,
                               isPrimary() ? ", primary" : "", mDisplayName.c_str());
 }
 
@@ -230,7 +235,9 @@
     return mCompositionDisplay->getDisplayColorProfile()->hasRenderIntent(intent);
 }
 
-DisplayId DisplayDevice::getId() const {
+// ----------------------------------------------------------------------------
+
+const std::optional<DisplayId>& DisplayDevice::getId() const {
     return mCompositionDisplay->getId();
 }
 
diff --git a/services/surfaceflinger/DisplayDevice.h b/services/surfaceflinger/DisplayDevice.h
index fa684c0..35a8b62 100644
--- a/services/surfaceflinger/DisplayDevice.h
+++ b/services/surfaceflinger/DisplayDevice.h
@@ -27,7 +27,6 @@
 #include <math/mat4.h>
 #include <renderengine/RenderEngine.h>
 #include <system/window.h>
-#include <ui/DisplayId.h>
 #include <ui/DisplayInfo.h>
 #include <ui/DisplayState.h>
 #include <ui/GraphicTypes.h>
@@ -105,15 +104,7 @@
     bool needsFiltering() const;
     ui::LayerStack getLayerStack() const;
 
-    // Returns the physical ID of this display. This function asserts the ID is physical and it
-    // shouldn't be called for other display types, e.g. virtual.
-    PhysicalDisplayId getPhysicalId() const {
-        const auto displayIdOpt = PhysicalDisplayId::tryCast(getId());
-        LOG_FATAL_IF(!displayIdOpt);
-        return *displayIdOpt;
-    }
-
-    DisplayId getId() const;
+    const std::optional<DisplayId>& getId() const;
     const wp<IBinder>& getDisplayToken() const { return mDisplayToken; }
     int32_t getSequenceId() const { return mSequenceId; }
 
diff --git a/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp b/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp
index 14b54cd..4c3b3e5 100644
--- a/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp
+++ b/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp
@@ -56,7 +56,7 @@
  *
  */
 
-FramebufferSurface::FramebufferSurface(HWComposer& hwc, PhysicalDisplayId displayId,
+FramebufferSurface::FramebufferSurface(HWComposer& hwc, DisplayId displayId,
                                        const sp<IGraphicBufferConsumer>& consumer,
                                        uint32_t maxWidth, uint32_t maxHeight)
       : ConsumerBase(consumer),
diff --git a/services/surfaceflinger/DisplayHardware/FramebufferSurface.h b/services/surfaceflinger/DisplayHardware/FramebufferSurface.h
index 759943a..a1859f3 100644
--- a/services/surfaceflinger/DisplayHardware/FramebufferSurface.h
+++ b/services/surfaceflinger/DisplayHardware/FramebufferSurface.h
@@ -23,7 +23,6 @@
 #include <compositionengine/DisplaySurface.h>
 #include <compositionengine/impl/HwcBufferCache.h>
 #include <gui/ConsumerBase.h>
-#include <ui/DisplayId.h>
 #include <ui/Size.h>
 
 #include "DisplayIdentification.h"
@@ -40,7 +39,7 @@
 
 class FramebufferSurface : public ConsumerBase, public compositionengine::DisplaySurface {
 public:
-    FramebufferSurface(HWComposer& hwc, PhysicalDisplayId displayId,
+    FramebufferSurface(HWComposer& hwc, DisplayId displayId,
                        const sp<IGraphicBufferConsumer>& consumer, uint32_t maxWidth,
                        uint32_t maxHeight);
 
@@ -70,7 +69,7 @@
     status_t nextBuffer(uint32_t& outSlot, sp<GraphicBuffer>& outBuffer,
             sp<Fence>& outFence, ui::Dataspace& outDataspace);
 
-    const PhysicalDisplayId mDisplayId;
+    const DisplayId mDisplayId;
 
     // Framebuffer size has a dimension limitation in pixels based on the graphics capabilities of
     // the device.
diff --git a/services/surfaceflinger/DisplayHardware/HWC2.h b/services/surfaceflinger/DisplayHardware/HWC2.h
index 89df84b..1f03787 100644
--- a/services/surfaceflinger/DisplayHardware/HWC2.h
+++ b/services/surfaceflinger/DisplayHardware/HWC2.h
@@ -240,14 +240,15 @@
 
 class Display : public HWC2::Display {
 public:
-    Display(android::Hwc2::Composer&, const std::unordered_set<hal::Capability>&, hal::HWDisplayId,
-            hal::DisplayType);
+    Display(android::Hwc2::Composer& composer,
+            const std::unordered_set<hal::Capability>& capabilities, hal::HWDisplayId id,
+            hal::DisplayType type);
     ~Display() override;
 
     // Required by HWC2
     hal::Error acceptChanges() override;
     hal::Error createLayer(Layer** outLayer) override;
-    hal::Error destroyLayer(Layer*) override;
+    hal::Error destroyLayer(Layer* layer) override;
     hal::Error getActiveConfig(std::shared_ptr<const Config>* outConfig) const override;
     hal::Error getActiveConfigIndex(int* outIndex) const override;
     hal::Error getChangedCompositionTypes(
@@ -257,7 +258,8 @@
     int32_t getSupportedPerFrameMetadata() const override;
     hal::Error getRenderIntents(hal::ColorMode colorMode,
                                 std::vector<hal::RenderIntent>* outRenderIntents) const override;
-    hal::Error getDataspaceSaturationMatrix(hal::Dataspace, android::mat4* outMatrix) override;
+    hal::Error getDataspaceSaturationMatrix(hal::Dataspace dataspace,
+                                            android::mat4* outMatrix) override;
 
     // Doesn't call into the HWC2 device, so no errors are possible
     std::vector<std::shared_ptr<const Config>> getConfigs() const override;
@@ -283,11 +285,11 @@
     hal::Error setClientTarget(uint32_t slot, const android::sp<android::GraphicBuffer>& target,
                                const android::sp<android::Fence>& acquireFence,
                                hal::Dataspace dataspace) override;
-    hal::Error setColorMode(hal::ColorMode, hal::RenderIntent) override;
+    hal::Error setColorMode(hal::ColorMode mode, hal::RenderIntent renderIntent) override;
     hal::Error setColorTransform(const android::mat4& matrix, hal::ColorTransform hint) override;
-    hal::Error setOutputBuffer(const android::sp<android::GraphicBuffer>&,
+    hal::Error setOutputBuffer(const android::sp<android::GraphicBuffer>& buffer,
                                const android::sp<android::Fence>& releaseFence) override;
-    hal::Error setPowerMode(hal::PowerMode) override;
+    hal::Error setPowerMode(hal::PowerMode mode) override;
     hal::Error setVsyncEnabled(hal::Vsync enabled) override;
     hal::Error validate(uint32_t* outNumTypes, uint32_t* outNumRequests) override;
     hal::Error presentOrValidate(uint32_t* outNumTypes, uint32_t* outNumRequests,
@@ -315,13 +317,13 @@
     virtual bool isVsyncPeriodSwitchSupported() const override;
 
 private:
-    int32_t getAttribute(hal::HWConfigId, hal::Attribute);
-    void loadConfig(hal::HWConfigId);
+    int32_t getAttribute(hal::HWConfigId configId, hal::Attribute attribute);
+    void loadConfig(hal::HWConfigId configId);
     void loadConfigs();
 
     // This may fail (and return a null pointer) if no layer with this ID exists
     // on this display
-    Layer* getLayerById(hal::HWLayerId) const;
+    Layer* getLayerById(hal::HWLayerId id) const;
 
     friend android::TestableSurfaceFlinger;
 
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
index 2379e6e..195182a 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
@@ -186,7 +186,7 @@
     return mCapabilities.count(capability) > 0;
 }
 
-bool HWComposer::hasDisplayCapability(HalDisplayId displayId,
+bool HWComposer::hasDisplayCapability(DisplayId displayId,
                                       hal::DisplayCapability capability) const {
     RETURN_IF_INVALID_DISPLAY(displayId, false);
     return mDisplayData.at(displayId).hwcDisplay->getCapabilities().count(capability) > 0;
@@ -214,8 +214,10 @@
     RETURN_IF_INVALID_DISPLAY(*displayId, false);
 
     auto& displayData = mDisplayData[*displayId];
-    LOG_FATAL_IF(displayData.isVirtual, "%s: Invalid operation on virtual display with ID %s",
-                 __FUNCTION__, to_string(*displayId));
+    if (displayData.isVirtual) {
+        LOG_DISPLAY_ERROR(*displayId, "Invalid operation on virtual display");
+        return false;
+    }
 
     {
         std::lock_guard lock(displayData.lastHwVsyncLock);
@@ -242,6 +244,11 @@
 
 std::optional<DisplayId> HWComposer::allocateVirtualDisplay(uint32_t width, uint32_t height,
                                                             ui::PixelFormat* format) {
+    if (mRemainingHwcVirtualDisplays == 0) {
+        ALOGE("%s: No remaining virtual displays", __FUNCTION__);
+        return {};
+    }
+
     if (SurfaceFlinger::maxVirtualDisplaySize != 0 &&
         (width > SurfaceFlinger::maxVirtualDisplaySize ||
          height > SurfaceFlinger::maxVirtualDisplaySize)) {
@@ -249,28 +256,31 @@
               height, SurfaceFlinger::maxVirtualDisplaySize);
         return {};
     }
-
-    const auto displayId = mVirtualIdGenerator.nextId();
-    if (!displayId) {
-        ALOGE("%s: No remaining virtual displays", __FUNCTION__);
-        return {};
-    }
-
     hal::HWDisplayId hwcDisplayId = 0;
     const auto error = static_cast<hal::Error>(
             mComposer->createVirtualDisplay(width, height, format, &hwcDisplayId));
     if (error != hal::Error::NONE) {
         ALOGE("%s: Failed to create HWC virtual display", __FUNCTION__);
-        mVirtualIdGenerator.markUnused(*displayId);
         return {};
     }
 
     auto display = std::make_unique<HWC2::impl::Display>(*mComposer.get(), mCapabilities,
                                                          hwcDisplayId, hal::DisplayType::VIRTUAL);
     display->setConnected(true);
-    auto& displayData = mDisplayData[*displayId];
+
+    DisplayId displayId;
+    if (mFreeVirtualDisplayIds.empty()) {
+        displayId = getVirtualDisplayId(mNextVirtualDisplayId++);
+    } else {
+        displayId = *mFreeVirtualDisplayIds.begin();
+        mFreeVirtualDisplayIds.erase(displayId);
+    }
+
+    auto& displayData = mDisplayData[displayId];
     displayData.hwcDisplay = std::move(display);
     displayData.isVirtual = true;
+
+    --mRemainingHwcVirtualDisplays;
     return displayId;
 }
 
@@ -291,7 +301,7 @@
     mPhysicalDisplayIdMap[hwcDisplayId] = displayId;
 }
 
-HWC2::Layer* HWComposer::createLayer(HalDisplayId displayId) {
+HWC2::Layer* HWComposer::createLayer(DisplayId displayId) {
     RETURN_IF_INVALID_DISPLAY(displayId, nullptr);
 
     HWC2::Layer* layer;
@@ -300,14 +310,14 @@
     return layer;
 }
 
-void HWComposer::destroyLayer(HalDisplayId displayId, HWC2::Layer* layer) {
+void HWComposer::destroyLayer(DisplayId displayId, HWC2::Layer* layer) {
     RETURN_IF_INVALID_DISPLAY(displayId);
 
     auto error = mDisplayData[displayId].hwcDisplay->destroyLayer(layer);
     RETURN_IF_HWC_ERROR(error, displayId);
 }
 
-nsecs_t HWComposer::getRefreshTimestamp(PhysicalDisplayId displayId) const {
+nsecs_t HWComposer::getRefreshTimestamp(DisplayId displayId) const {
     RETURN_IF_INVALID_DISPLAY(displayId, 0);
     const auto& displayData = mDisplayData.at(displayId);
     // this returns the last refresh timestamp.
@@ -319,13 +329,13 @@
     return now - ((now - displayData.lastHwVsync) % vsyncPeriodNanos);
 }
 
-bool HWComposer::isConnected(PhysicalDisplayId displayId) const {
+bool HWComposer::isConnected(DisplayId displayId) const {
     RETURN_IF_INVALID_DISPLAY(displayId, false);
     return mDisplayData.at(displayId).hwcDisplay->isConnected();
 }
 
 std::vector<std::shared_ptr<const HWC2::Display::Config>> HWComposer::getConfigs(
-        PhysicalDisplayId displayId) const {
+        DisplayId displayId) const {
     RETURN_IF_INVALID_DISPLAY(displayId, {});
 
     const auto& displayData = mDisplayData.at(displayId);
@@ -339,7 +349,7 @@
 }
 
 std::shared_ptr<const HWC2::Display::Config> HWComposer::getActiveConfig(
-        PhysicalDisplayId displayId) const {
+        DisplayId displayId) const {
     RETURN_IF_INVALID_DISPLAY(displayId, nullptr);
 
     std::shared_ptr<const HWC2::Display::Config> config;
@@ -361,7 +371,7 @@
 
 // Composer 2.4
 
-DisplayConnectionType HWComposer::getDisplayConnectionType(PhysicalDisplayId displayId) const {
+DisplayConnectionType HWComposer::getDisplayConnectionType(DisplayId displayId) const {
     RETURN_IF_INVALID_DISPLAY(displayId, DisplayConnectionType::Internal);
     const auto& hwcDisplay = mDisplayData.at(displayId).hwcDisplay;
 
@@ -376,12 +386,12 @@
     return type;
 }
 
-bool HWComposer::isVsyncPeriodSwitchSupported(PhysicalDisplayId displayId) const {
+bool HWComposer::isVsyncPeriodSwitchSupported(DisplayId displayId) const {
     RETURN_IF_INVALID_DISPLAY(displayId, false);
     return mDisplayData.at(displayId).hwcDisplay->isVsyncPeriodSwitchSupported();
 }
 
-nsecs_t HWComposer::getDisplayVsyncPeriod(PhysicalDisplayId displayId) const {
+nsecs_t HWComposer::getDisplayVsyncPeriod(DisplayId displayId) const {
     RETURN_IF_INVALID_DISPLAY(displayId, 0);
 
     nsecs_t vsyncPeriodNanos;
@@ -390,7 +400,7 @@
     return vsyncPeriodNanos;
 }
 
-int HWComposer::getActiveConfigIndex(PhysicalDisplayId displayId) const {
+int HWComposer::getActiveConfigIndex(DisplayId displayId) const {
     RETURN_IF_INVALID_DISPLAY(displayId, -1);
 
     int index;
@@ -410,7 +420,7 @@
     return index;
 }
 
-std::vector<ui::ColorMode> HWComposer::getColorModes(PhysicalDisplayId displayId) const {
+std::vector<ui::ColorMode> HWComposer::getColorModes(DisplayId displayId) const {
     RETURN_IF_INVALID_DISPLAY(displayId, {});
 
     std::vector<ui::ColorMode> modes;
@@ -419,7 +429,7 @@
     return modes;
 }
 
-status_t HWComposer::setActiveColorMode(PhysicalDisplayId displayId, ui::ColorMode mode,
+status_t HWComposer::setActiveColorMode(DisplayId displayId, ui::ColorMode mode,
                                         ui::RenderIntent renderIntent) {
     RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
 
@@ -433,12 +443,14 @@
     return NO_ERROR;
 }
 
-void HWComposer::setVsyncEnabled(PhysicalDisplayId displayId, hal::Vsync enabled) {
+void HWComposer::setVsyncEnabled(DisplayId displayId, hal::Vsync enabled) {
     RETURN_IF_INVALID_DISPLAY(displayId);
     auto& displayData = mDisplayData[displayId];
 
-    LOG_FATAL_IF(displayData.isVirtual, "%s: Invalid operation on virtual display with ID %s",
-                 __FUNCTION__, to_string(*displayId));
+    if (displayData.isVirtual) {
+        LOG_DISPLAY_ERROR(displayId, "Invalid operation on virtual display");
+        return;
+    }
 
     // NOTE: we use our own internal lock here because we have to call
     // into the HWC with the lock held, and we want to make sure
@@ -459,7 +471,7 @@
     ATRACE_INT(tag.c_str(), enabled == hal::Vsync::ENABLE ? 1 : 0);
 }
 
-status_t HWComposer::setClientTarget(HalDisplayId displayId, uint32_t slot,
+status_t HWComposer::setClientTarget(DisplayId displayId, uint32_t slot,
                                      const sp<Fence>& acquireFence, const sp<GraphicBuffer>& target,
                                      ui::Dataspace dataspace) {
     RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
@@ -472,7 +484,7 @@
 }
 
 status_t HWComposer::getDeviceCompositionChanges(
-        HalDisplayId displayId, bool frameUsesClientComposition,
+        DisplayId displayId, bool frameUsesClientComposition,
         std::optional<android::HWComposer::DeviceRequestedChanges>* outChanges) {
     ATRACE_CALL();
 
@@ -542,12 +554,12 @@
     return NO_ERROR;
 }
 
-sp<Fence> HWComposer::getPresentFence(HalDisplayId displayId) const {
+sp<Fence> HWComposer::getPresentFence(DisplayId displayId) const {
     RETURN_IF_INVALID_DISPLAY(displayId, Fence::NO_FENCE);
     return mDisplayData.at(displayId).lastPresentFence;
 }
 
-sp<Fence> HWComposer::getLayerReleaseFence(HalDisplayId displayId, HWC2::Layer* layer) const {
+sp<Fence> HWComposer::getLayerReleaseFence(DisplayId displayId, HWC2::Layer* layer) const {
     RETURN_IF_INVALID_DISPLAY(displayId, Fence::NO_FENCE);
     const auto& displayFences = mDisplayData.at(displayId).releaseFences;
     auto fence = displayFences.find(layer);
@@ -558,7 +570,7 @@
     return fence->second;
 }
 
-status_t HWComposer::presentAndGetReleaseFences(HalDisplayId displayId) {
+status_t HWComposer::presentAndGetReleaseFences(DisplayId displayId) {
     ATRACE_CALL();
 
     RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
@@ -586,12 +598,14 @@
     return NO_ERROR;
 }
 
-status_t HWComposer::setPowerMode(PhysicalDisplayId displayId, hal::PowerMode mode) {
+status_t HWComposer::setPowerMode(DisplayId displayId, hal::PowerMode mode) {
     RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
 
     const auto& displayData = mDisplayData[displayId];
-    LOG_FATAL_IF(displayData.isVirtual, "%s: Invalid operation on virtual display with ID %s",
-                 __FUNCTION__, to_string(*displayId));
+    if (displayData.isVirtual) {
+        LOG_DISPLAY_ERROR(displayId, "Invalid operation on virtual display");
+        return INVALID_OPERATION;
+    }
 
     if (mode == hal::PowerMode::OFF) {
         setVsyncEnabled(displayId, hal::Vsync::DISABLE);
@@ -640,8 +654,7 @@
 }
 
 status_t HWComposer::setActiveConfigWithConstraints(
-        PhysicalDisplayId displayId, size_t configId,
-        const hal::VsyncPeriodChangeConstraints& constraints,
+        DisplayId displayId, size_t configId, const hal::VsyncPeriodChangeConstraints& constraints,
         hal::VsyncPeriodChangeTimeline* outTimeline) {
     RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
 
@@ -658,7 +671,7 @@
     return NO_ERROR;
 }
 
-status_t HWComposer::setColorTransform(HalDisplayId displayId, const mat4& transform) {
+status_t HWComposer::setColorTransform(DisplayId displayId, const mat4& transform) {
     RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
 
     auto& displayData = mDisplayData[displayId];
@@ -671,14 +684,15 @@
     return NO_ERROR;
 }
 
-void HWComposer::disconnectDisplay(HalDisplayId displayId) {
+void HWComposer::disconnectDisplay(DisplayId displayId) {
     RETURN_IF_INVALID_DISPLAY(displayId);
     auto& displayData = mDisplayData[displayId];
 
     // If this was a virtual display, add its slot back for reuse by future
     // virtual displays
     if (displayData.isVirtual) {
-        mVirtualIdGenerator.markUnused(*HalVirtualDisplayId::tryCast(displayId));
+        mFreeVirtualDisplayIds.insert(displayId);
+        ++mRemainingHwcVirtualDisplays;
     }
 
     const auto hwcDisplayId = displayData.hwcDisplay->getId();
@@ -693,25 +707,27 @@
     mDisplayData.erase(displayId);
 }
 
-status_t HWComposer::setOutputBuffer(HalVirtualDisplayId displayId, const sp<Fence>& acquireFence,
+status_t HWComposer::setOutputBuffer(DisplayId displayId, const sp<Fence>& acquireFence,
                                      const sp<GraphicBuffer>& buffer) {
     RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
     const auto& displayData = mDisplayData[displayId];
 
-    LOG_FATAL_IF(!displayData.isVirtual, "%s: Invalid operation on physical display with ID %s",
-                 __FUNCTION__, to_string(*displayId));
+    if (!displayData.isVirtual) {
+        LOG_DISPLAY_ERROR(displayId, "Invalid operation on physical display");
+        return INVALID_OPERATION;
+    }
 
     auto error = displayData.hwcDisplay->setOutputBuffer(buffer, acquireFence);
     RETURN_IF_HWC_ERROR(error, displayId, UNKNOWN_ERROR);
     return NO_ERROR;
 }
 
-void HWComposer::clearReleaseFences(HalDisplayId displayId) {
+void HWComposer::clearReleaseFences(DisplayId displayId) {
     RETURN_IF_INVALID_DISPLAY(displayId);
     mDisplayData[displayId].releaseFences.clear();
 }
 
-status_t HWComposer::getHdrCapabilities(HalDisplayId displayId, HdrCapabilities* outCapabilities) {
+status_t HWComposer::getHdrCapabilities(DisplayId displayId, HdrCapabilities* outCapabilities) {
     RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
 
     auto& hwcDisplay = mDisplayData[displayId].hwcDisplay;
@@ -720,12 +736,12 @@
     return NO_ERROR;
 }
 
-int32_t HWComposer::getSupportedPerFrameMetadata(HalDisplayId displayId) const {
+int32_t HWComposer::getSupportedPerFrameMetadata(DisplayId displayId) const {
     RETURN_IF_INVALID_DISPLAY(displayId, 0);
     return mDisplayData.at(displayId).hwcDisplay->getSupportedPerFrameMetadata();
 }
 
-std::vector<ui::RenderIntent> HWComposer::getRenderIntents(HalDisplayId displayId,
+std::vector<ui::RenderIntent> HWComposer::getRenderIntents(DisplayId displayId,
                                                            ui::ColorMode colorMode) const {
     RETURN_IF_INVALID_DISPLAY(displayId, {});
 
@@ -735,7 +751,7 @@
     return renderIntents;
 }
 
-mat4 HWComposer::getDataspaceSaturationMatrix(HalDisplayId displayId, ui::Dataspace dataspace) {
+mat4 HWComposer::getDataspaceSaturationMatrix(DisplayId displayId, ui::Dataspace dataspace) {
     RETURN_IF_INVALID_DISPLAY(displayId, {});
 
     mat4 matrix;
@@ -745,7 +761,7 @@
     return matrix;
 }
 
-status_t HWComposer::getDisplayedContentSamplingAttributes(HalDisplayId displayId,
+status_t HWComposer::getDisplayedContentSamplingAttributes(DisplayId displayId,
                                                            ui::PixelFormat* outFormat,
                                                            ui::Dataspace* outDataspace,
                                                            uint8_t* outComponentMask) {
@@ -759,7 +775,7 @@
     return NO_ERROR;
 }
 
-status_t HWComposer::setDisplayContentSamplingEnabled(HalDisplayId displayId, bool enabled,
+status_t HWComposer::setDisplayContentSamplingEnabled(DisplayId displayId, bool enabled,
                                                       uint8_t componentMask, uint64_t maxFrames) {
     RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
     const auto error =
@@ -773,7 +789,7 @@
     return NO_ERROR;
 }
 
-status_t HWComposer::getDisplayedContentSample(HalDisplayId displayId, uint64_t maxFrames,
+status_t HWComposer::getDisplayedContentSample(DisplayId displayId, uint64_t maxFrames,
                                                uint64_t timestamp, DisplayedFrameStats* outStats) {
     RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
     const auto error =
@@ -783,8 +799,7 @@
     return NO_ERROR;
 }
 
-std::future<status_t> HWComposer::setDisplayBrightness(PhysicalDisplayId displayId,
-                                                       float brightness) {
+std::future<status_t> HWComposer::setDisplayBrightness(DisplayId displayId, float brightness) {
     RETURN_IF_INVALID_DISPLAY(displayId, promise::yield<status_t>(BAD_INDEX));
     auto& display = mDisplayData[displayId].hwcDisplay;
 
@@ -801,7 +816,7 @@
             });
 }
 
-status_t HWComposer::setAutoLowLatencyMode(PhysicalDisplayId displayId, bool on) {
+status_t HWComposer::setAutoLowLatencyMode(DisplayId displayId, bool on) {
     RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
     const auto error = mDisplayData[displayId].hwcDisplay->setAutoLowLatencyMode(on);
     if (error == hal::Error::UNSUPPORTED) {
@@ -815,7 +830,7 @@
 }
 
 status_t HWComposer::getSupportedContentTypes(
-        PhysicalDisplayId displayId, std::vector<hal::ContentType>* outSupportedContentTypes) {
+        DisplayId displayId, std::vector<hal::ContentType>* outSupportedContentTypes) {
     RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
     const auto error =
             mDisplayData[displayId].hwcDisplay->getSupportedContentTypes(outSupportedContentTypes);
@@ -825,7 +840,7 @@
     return NO_ERROR;
 }
 
-status_t HWComposer::setContentType(PhysicalDisplayId displayId, hal::ContentType contentType) {
+status_t HWComposer::setContentType(DisplayId displayId, hal::ContentType contentType) {
     RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
     const auto error = mDisplayData[displayId].hwcDisplay->setContentType(contentType);
     if (error == hal::Error::UNSUPPORTED) {
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.h b/services/surfaceflinger/DisplayHardware/HWComposer.h
index 028a9a4..488cdc5 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.h
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.h
@@ -38,7 +38,6 @@
 #include <utils/StrongPointer.h>
 #include <utils/Timers.h>
 
-#include "DisplayIdGenerator.h"
 #include "DisplayIdentification.h"
 #include "HWC2.h"
 #include "Hal.h"
@@ -89,7 +88,7 @@
                                               DisplayIdentificationData* outData) const = 0;
 
     virtual bool hasCapability(hal::Capability) const = 0;
-    virtual bool hasDisplayCapability(HalDisplayId, hal::DisplayCapability) const = 0;
+    virtual bool hasDisplayCapability(DisplayId, hal::DisplayCapability) const = 0;
 
     // Attempts to allocate a virtual display and returns its ID if created on the HWC device.
     virtual std::optional<DisplayId> allocateVirtualDisplay(uint32_t width, uint32_t height,
@@ -98,9 +97,9 @@
     virtual void allocatePhysicalDisplay(hal::HWDisplayId, PhysicalDisplayId) = 0;
 
     // Attempts to create a new layer on this display
-    virtual HWC2::Layer* createLayer(HalDisplayId) = 0;
+    virtual HWC2::Layer* createLayer(DisplayId) = 0;
     // Destroy a previously created layer
-    virtual void destroyLayer(HalDisplayId, HWC2::Layer*) = 0;
+    virtual void destroyLayer(DisplayId, HWC2::Layer*) = 0;
 
     // Gets any required composition change requests from the HWC device.
     //
@@ -110,60 +109,61 @@
     // with fewer handshakes, but this does not work if client composition is
     // expected.
     virtual status_t getDeviceCompositionChanges(
-            HalDisplayId, bool frameUsesClientComposition,
+            DisplayId, bool frameUsesClientComposition,
             std::optional<DeviceRequestedChanges>* outChanges) = 0;
 
-    virtual status_t setClientTarget(HalDisplayId, uint32_t slot, const sp<Fence>& acquireFence,
+    virtual status_t setClientTarget(DisplayId, uint32_t slot, const sp<Fence>& acquireFence,
                                      const sp<GraphicBuffer>& target, ui::Dataspace) = 0;
 
     // Present layers to the display and read releaseFences.
-    virtual status_t presentAndGetReleaseFences(HalDisplayId) = 0;
+    virtual status_t presentAndGetReleaseFences(DisplayId) = 0;
 
     // set power mode
-    virtual status_t setPowerMode(PhysicalDisplayId, hal::PowerMode) = 0;
+    virtual status_t setPowerMode(DisplayId, hal::PowerMode) = 0;
 
     // Sets a color transform to be applied to the result of composition
-    virtual status_t setColorTransform(HalDisplayId, const mat4& transform) = 0;
+    virtual status_t setColorTransform(DisplayId, const mat4& transform) = 0;
 
-    // reset state when a display is disconnected
-    virtual void disconnectDisplay(HalDisplayId) = 0;
+    // reset state when an external, non-virtual display is disconnected
+    virtual void disconnectDisplay(DisplayId) = 0;
 
     // get the present fence received from the last call to present.
-    virtual sp<Fence> getPresentFence(HalDisplayId) const = 0;
+    virtual sp<Fence> getPresentFence(DisplayId) const = 0;
 
     // Get last release fence for the given layer
-    virtual sp<Fence> getLayerReleaseFence(HalDisplayId, HWC2::Layer*) const = 0;
+    virtual sp<Fence> getLayerReleaseFence(DisplayId, HWC2::Layer*) const = 0;
 
     // Set the output buffer and acquire fence for a virtual display.
-    virtual status_t setOutputBuffer(HalVirtualDisplayId, const sp<Fence>& acquireFence,
+    // Returns INVALID_OPERATION if displayId is not a virtual display.
+    virtual status_t setOutputBuffer(DisplayId, const sp<Fence>& acquireFence,
                                      const sp<GraphicBuffer>& buffer) = 0;
 
     // After SurfaceFlinger has retrieved the release fences for all the frames,
     // it can call this to clear the shared pointers in the release fence map
-    virtual void clearReleaseFences(HalDisplayId) = 0;
+    virtual void clearReleaseFences(DisplayId) = 0;
 
     // Fetches the HDR capabilities of the given display
-    virtual status_t getHdrCapabilities(HalDisplayId, HdrCapabilities* outCapabilities) = 0;
+    virtual status_t getHdrCapabilities(DisplayId, HdrCapabilities* outCapabilities) = 0;
 
-    virtual int32_t getSupportedPerFrameMetadata(HalDisplayId) const = 0;
+    virtual int32_t getSupportedPerFrameMetadata(DisplayId) const = 0;
 
     // Returns the available RenderIntent of the given display.
-    virtual std::vector<ui::RenderIntent> getRenderIntents(HalDisplayId, ui::ColorMode) const = 0;
+    virtual std::vector<ui::RenderIntent> getRenderIntents(DisplayId, ui::ColorMode) const = 0;
 
-    virtual mat4 getDataspaceSaturationMatrix(HalDisplayId, ui::Dataspace) = 0;
+    virtual mat4 getDataspaceSaturationMatrix(DisplayId, ui::Dataspace) = 0;
 
     // Returns the attributes of the color sampling engine.
-    virtual status_t getDisplayedContentSamplingAttributes(HalDisplayId, ui::PixelFormat* outFormat,
+    virtual status_t getDisplayedContentSamplingAttributes(DisplayId, ui::PixelFormat* outFormat,
                                                            ui::Dataspace* outDataspace,
                                                            uint8_t* outComponentMask) = 0;
-    virtual status_t setDisplayContentSamplingEnabled(HalDisplayId, bool enabled,
+    virtual status_t setDisplayContentSamplingEnabled(DisplayId, bool enabled,
                                                       uint8_t componentMask,
                                                       uint64_t maxFrames) = 0;
-    virtual status_t getDisplayedContentSample(HalDisplayId, uint64_t maxFrames, uint64_t timestamp,
+    virtual status_t getDisplayedContentSample(DisplayId, uint64_t maxFrames, uint64_t timestamp,
                                                DisplayedFrameStats* outStats) = 0;
 
     // Sets the brightness of a display.
-    virtual std::future<status_t> setDisplayBrightness(PhysicalDisplayId, float brightness) = 0;
+    virtual std::future<status_t> setDisplayBrightness(DisplayId, float brightness) = 0;
 
     // Events handling ---------------------------------------------------------
 
@@ -174,35 +174,33 @@
                                                                hal::Connection) = 0;
 
     virtual bool onVsync(hal::HWDisplayId, int64_t timestamp) = 0;
-    virtual void setVsyncEnabled(PhysicalDisplayId, hal::Vsync enabled) = 0;
+    virtual void setVsyncEnabled(DisplayId, hal::Vsync enabled) = 0;
 
-    virtual nsecs_t getRefreshTimestamp(PhysicalDisplayId) const = 0;
-    virtual bool isConnected(PhysicalDisplayId) const = 0;
+    virtual nsecs_t getRefreshTimestamp(DisplayId) const = 0;
+    virtual bool isConnected(DisplayId) const = 0;
 
     // Non-const because it can update configMap inside of mDisplayData
     virtual std::vector<std::shared_ptr<const HWC2::Display::Config>> getConfigs(
-            PhysicalDisplayId) const = 0;
+            DisplayId) const = 0;
 
-    virtual std::shared_ptr<const HWC2::Display::Config> getActiveConfig(
-            PhysicalDisplayId) const = 0;
-    virtual int getActiveConfigIndex(PhysicalDisplayId) const = 0;
+    virtual std::shared_ptr<const HWC2::Display::Config> getActiveConfig(DisplayId) const = 0;
+    virtual int getActiveConfigIndex(DisplayId) const = 0;
 
-    virtual std::vector<ui::ColorMode> getColorModes(PhysicalDisplayId) const = 0;
+    virtual std::vector<ui::ColorMode> getColorModes(DisplayId) const = 0;
 
-    virtual status_t setActiveColorMode(PhysicalDisplayId, ui::ColorMode mode,
-                                        ui::RenderIntent) = 0;
+    virtual status_t setActiveColorMode(DisplayId, ui::ColorMode mode, ui::RenderIntent) = 0;
 
     // Composer 2.4
-    virtual DisplayConnectionType getDisplayConnectionType(PhysicalDisplayId) const = 0;
-    virtual bool isVsyncPeriodSwitchSupported(PhysicalDisplayId) const = 0;
-    virtual nsecs_t getDisplayVsyncPeriod(PhysicalDisplayId) const = 0;
+    virtual DisplayConnectionType getDisplayConnectionType(DisplayId) const = 0;
+    virtual bool isVsyncPeriodSwitchSupported(DisplayId) const = 0;
+    virtual nsecs_t getDisplayVsyncPeriod(DisplayId) const = 0;
     virtual status_t setActiveConfigWithConstraints(
-            PhysicalDisplayId, size_t configId, const hal::VsyncPeriodChangeConstraints&,
+            DisplayId, size_t configId, const hal::VsyncPeriodChangeConstraints&,
             hal::VsyncPeriodChangeTimeline* outTimeline) = 0;
-    virtual status_t setAutoLowLatencyMode(PhysicalDisplayId, bool on) = 0;
+    virtual status_t setAutoLowLatencyMode(DisplayId, bool on) = 0;
     virtual status_t getSupportedContentTypes(
-            PhysicalDisplayId, std::vector<hal::ContentType>* outSupportedContentTypes) = 0;
-    virtual status_t setContentType(PhysicalDisplayId, hal::ContentType) = 0;
+            DisplayId, std::vector<hal::ContentType>* outSupportedContentTypes) = 0;
+    virtual status_t setContentType(DisplayId, hal::ContentType) = 0;
     virtual const std::unordered_map<std::string, bool>& getSupportedLayerGenericMetadata()
             const = 0;
 
@@ -234,7 +232,7 @@
                                       DisplayIdentificationData* outData) const override;
 
     bool hasCapability(hal::Capability) const override;
-    bool hasDisplayCapability(HalDisplayId, hal::DisplayCapability) const override;
+    bool hasDisplayCapability(DisplayId, hal::DisplayCapability) const override;
 
     // Attempts to allocate a virtual display and returns its ID if created on the HWC device.
     std::optional<DisplayId> allocateVirtualDisplay(uint32_t width, uint32_t height,
@@ -244,62 +242,63 @@
     void allocatePhysicalDisplay(hal::HWDisplayId, PhysicalDisplayId) override;
 
     // Attempts to create a new layer on this display
-    HWC2::Layer* createLayer(HalDisplayId) override;
+    HWC2::Layer* createLayer(DisplayId) override;
     // Destroy a previously created layer
-    void destroyLayer(HalDisplayId, HWC2::Layer*) override;
+    void destroyLayer(DisplayId, HWC2::Layer*) override;
 
     status_t getDeviceCompositionChanges(
-            HalDisplayId, bool frameUsesClientComposition,
+            DisplayId, bool frameUsesClientComposition,
             std::optional<DeviceRequestedChanges>* outChanges) override;
 
-    status_t setClientTarget(HalDisplayId, uint32_t slot, const sp<Fence>& acquireFence,
+    status_t setClientTarget(DisplayId, uint32_t slot, const sp<Fence>& acquireFence,
                              const sp<GraphicBuffer>& target, ui::Dataspace) override;
 
     // Present layers to the display and read releaseFences.
-    status_t presentAndGetReleaseFences(HalDisplayId) override;
+    status_t presentAndGetReleaseFences(DisplayId) override;
 
     // set power mode
-    status_t setPowerMode(PhysicalDisplayId, hal::PowerMode mode) override;
+    status_t setPowerMode(DisplayId, hal::PowerMode mode) override;
 
     // Sets a color transform to be applied to the result of composition
-    status_t setColorTransform(HalDisplayId, const mat4& transform) override;
+    status_t setColorTransform(DisplayId, const mat4& transform) override;
 
-    // reset state when a display is disconnected
-    void disconnectDisplay(HalDisplayId) override;
+    // reset state when an external, non-virtual display is disconnected
+    void disconnectDisplay(DisplayId) override;
 
     // get the present fence received from the last call to present.
-    sp<Fence> getPresentFence(HalDisplayId) const override;
+    sp<Fence> getPresentFence(DisplayId) const override;
 
     // Get last release fence for the given layer
-    sp<Fence> getLayerReleaseFence(HalDisplayId, HWC2::Layer*) const override;
+    sp<Fence> getLayerReleaseFence(DisplayId, HWC2::Layer*) const override;
 
     // Set the output buffer and acquire fence for a virtual display.
-    status_t setOutputBuffer(HalVirtualDisplayId, const sp<Fence>& acquireFence,
+    // Returns INVALID_OPERATION if displayId is not a virtual display.
+    status_t setOutputBuffer(DisplayId, const sp<Fence>& acquireFence,
                              const sp<GraphicBuffer>& buffer) override;
 
     // After SurfaceFlinger has retrieved the release fences for all the frames,
     // it can call this to clear the shared pointers in the release fence map
-    void clearReleaseFences(HalDisplayId) override;
+    void clearReleaseFences(DisplayId) override;
 
     // Fetches the HDR capabilities of the given display
-    status_t getHdrCapabilities(HalDisplayId, HdrCapabilities* outCapabilities) override;
+    status_t getHdrCapabilities(DisplayId, HdrCapabilities* outCapabilities) override;
 
-    int32_t getSupportedPerFrameMetadata(HalDisplayId) const override;
+    int32_t getSupportedPerFrameMetadata(DisplayId) const override;
 
     // Returns the available RenderIntent of the given display.
-    std::vector<ui::RenderIntent> getRenderIntents(HalDisplayId, ui::ColorMode) const override;
+    std::vector<ui::RenderIntent> getRenderIntents(DisplayId, ui::ColorMode) const override;
 
-    mat4 getDataspaceSaturationMatrix(HalDisplayId, ui::Dataspace) override;
+    mat4 getDataspaceSaturationMatrix(DisplayId, ui::Dataspace) override;
 
     // Returns the attributes of the color sampling engine.
-    status_t getDisplayedContentSamplingAttributes(HalDisplayId, ui::PixelFormat* outFormat,
+    status_t getDisplayedContentSamplingAttributes(DisplayId, ui::PixelFormat* outFormat,
                                                    ui::Dataspace* outDataspace,
                                                    uint8_t* outComponentMask) override;
-    status_t setDisplayContentSamplingEnabled(HalDisplayId, bool enabled, uint8_t componentMask,
+    status_t setDisplayContentSamplingEnabled(DisplayId, bool enabled, uint8_t componentMask,
                                               uint64_t maxFrames) override;
-    status_t getDisplayedContentSample(HalDisplayId, uint64_t maxFrames, uint64_t timestamp,
+    status_t getDisplayedContentSample(DisplayId, uint64_t maxFrames, uint64_t timestamp,
                                        DisplayedFrameStats* outStats) override;
-    std::future<status_t> setDisplayBrightness(PhysicalDisplayId, float brightness) override;
+    std::future<status_t> setDisplayBrightness(DisplayId, float brightness) override;
 
     // Events handling ---------------------------------------------------------
 
@@ -308,32 +307,31 @@
     std::optional<DisplayIdentificationInfo> onHotplug(hal::HWDisplayId, hal::Connection) override;
 
     bool onVsync(hal::HWDisplayId, int64_t timestamp) override;
-    void setVsyncEnabled(PhysicalDisplayId, hal::Vsync enabled) override;
+    void setVsyncEnabled(DisplayId, hal::Vsync enabled) override;
 
-    nsecs_t getRefreshTimestamp(PhysicalDisplayId) const override;
-    bool isConnected(PhysicalDisplayId) const override;
+    nsecs_t getRefreshTimestamp(DisplayId) const override;
+    bool isConnected(DisplayId) const override;
 
     // Non-const because it can update configMap inside of mDisplayData
-    std::vector<std::shared_ptr<const HWC2::Display::Config>> getConfigs(
-            PhysicalDisplayId) const override;
+    std::vector<std::shared_ptr<const HWC2::Display::Config>> getConfigs(DisplayId) const override;
 
-    std::shared_ptr<const HWC2::Display::Config> getActiveConfig(PhysicalDisplayId) const override;
-    int getActiveConfigIndex(PhysicalDisplayId) const override;
+    std::shared_ptr<const HWC2::Display::Config> getActiveConfig(DisplayId) const override;
+    int getActiveConfigIndex(DisplayId) const override;
 
-    std::vector<ui::ColorMode> getColorModes(PhysicalDisplayId) const override;
+    std::vector<ui::ColorMode> getColorModes(DisplayId) const override;
 
-    status_t setActiveColorMode(PhysicalDisplayId, ui::ColorMode, ui::RenderIntent) override;
+    status_t setActiveColorMode(DisplayId, ui::ColorMode, ui::RenderIntent) override;
 
     // Composer 2.4
-    DisplayConnectionType getDisplayConnectionType(PhysicalDisplayId) const override;
-    bool isVsyncPeriodSwitchSupported(PhysicalDisplayId) const override;
-    nsecs_t getDisplayVsyncPeriod(PhysicalDisplayId) const override;
-    status_t setActiveConfigWithConstraints(PhysicalDisplayId, size_t configId,
+    DisplayConnectionType getDisplayConnectionType(DisplayId) const override;
+    bool isVsyncPeriodSwitchSupported(DisplayId) const override;
+    nsecs_t getDisplayVsyncPeriod(DisplayId) const override;
+    status_t setActiveConfigWithConstraints(DisplayId, size_t configId,
                                             const hal::VsyncPeriodChangeConstraints&,
                                             hal::VsyncPeriodChangeTimeline* outTimeline) override;
-    status_t setAutoLowLatencyMode(PhysicalDisplayId, bool) override;
-    status_t getSupportedContentTypes(PhysicalDisplayId, std::vector<hal::ContentType>*) override;
-    status_t setContentType(PhysicalDisplayId, hal::ContentType) override;
+    status_t setAutoLowLatencyMode(DisplayId, bool) override;
+    status_t getSupportedContentTypes(DisplayId, std::vector<hal::ContentType>*) override;
+    status_t setContentType(DisplayId, hal::ContentType) override;
 
     const std::unordered_map<std::string, bool>& getSupportedLayerGenericMetadata() const override;
 
@@ -387,7 +385,7 @@
         nsecs_t lastHwVsync GUARDED_BY(lastHwVsyncLock) = 0;
     };
 
-    std::unordered_map<HalDisplayId, DisplayData> mDisplayData;
+    std::unordered_map<DisplayId, DisplayData> mDisplayData;
 
     std::unique_ptr<android::Hwc2::Composer> mComposer;
     std::unordered_set<hal::Capability> mCapabilities;
@@ -399,7 +397,9 @@
     std::optional<hal::HWDisplayId> mExternalHwcDisplayId;
     bool mHasMultiDisplaySupport = false;
 
-    RandomDisplayIdGenerator<HalVirtualDisplayId> mVirtualIdGenerator{getMaxVirtualDisplayCount()};
+    std::unordered_set<DisplayId> mFreeVirtualDisplayIds;
+    uint32_t mNextVirtualDisplayId = 0;
+    uint32_t mRemainingHwcVirtualDisplays{getMaxVirtualDisplayCount()};
 };
 
 } // namespace impl
diff --git a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp
index 247ee23..fba3261 100644
--- a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp
+++ b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp
@@ -57,7 +57,8 @@
     }
 }
 
-VirtualDisplaySurface::VirtualDisplaySurface(HWComposer& hwc, VirtualDisplayId displayId,
+VirtualDisplaySurface::VirtualDisplaySurface(HWComposer& hwc,
+                                             const std::optional<DisplayId>& displayId,
                                              const sp<IGraphicBufferProducer>& sink,
                                              const sp<IGraphicBufferProducer>& bqProducer,
                                              const sp<IGraphicBufferConsumer>& bqConsumer,
@@ -124,7 +125,7 @@
 }
 
 status_t VirtualDisplaySurface::beginFrame(bool mustRecompose) {
-    if (GpuVirtualDisplayId::tryCast(mDisplayId)) {
+    if (!mDisplayId) {
         return NO_ERROR;
     }
 
@@ -138,7 +139,7 @@
 }
 
 status_t VirtualDisplaySurface::prepareFrame(CompositionType compositionType) {
-    if (GpuVirtualDisplayId::tryCast(mDisplayId)) {
+    if (!mDisplayId) {
         return NO_ERROR;
     }
 
@@ -186,7 +187,7 @@
 }
 
 status_t VirtualDisplaySurface::advanceFrame() {
-    if (GpuVirtualDisplayId::tryCast(mDisplayId)) {
+    if (!mDisplayId) {
         return NO_ERROR;
     }
 
@@ -218,11 +219,9 @@
             mFbProducerSlot, fbBuffer.get(),
             mOutputProducerSlot, outBuffer.get());
 
-    const auto halDisplayId = HalVirtualDisplayId::tryCast(mDisplayId);
-    LOG_FATAL_IF(!halDisplayId);
     // At this point we know the output buffer acquire fence,
     // so update HWC state with it.
-    mHwc.setOutputBuffer(*halDisplayId, mOutputFence, outBuffer);
+    mHwc.setOutputBuffer(*mDisplayId, mOutputFence, outBuffer);
 
     status_t result = NO_ERROR;
     if (fbBuffer != nullptr) {
@@ -231,7 +230,7 @@
         mHwcBufferCache.getHwcBuffer(mFbProducerSlot, fbBuffer, &hwcSlot, &hwcBuffer);
 
         // TODO: Correctly propagate the dataspace from GL composition
-        result = mHwc.setClientTarget(*halDisplayId, hwcSlot, mFbFence, hwcBuffer,
+        result = mHwc.setClientTarget(*mDisplayId, hwcSlot, mFbFence, hwcBuffer,
                                       ui::Dataspace::UNKNOWN);
     }
 
@@ -239,8 +238,7 @@
 }
 
 void VirtualDisplaySurface::onFrameCommitted() {
-    const auto halDisplayId = HalVirtualDisplayId::tryCast(mDisplayId);
-    if (!halDisplayId) {
+    if (!mDisplayId) {
         return;
     }
 
@@ -248,7 +246,7 @@
             "Unexpected onFrameCommitted() in %s state", dbgStateStr());
     mDbgState = DBG_STATE_IDLE;
 
-    sp<Fence> retireFence = mHwc.getPresentFence(*halDisplayId);
+    sp<Fence> retireFence = mHwc.getPresentFence(*mDisplayId);
     if (mCompositionType == COMPOSITION_MIXED && mFbProducerSlot >= 0) {
         // release the scratch buffer back to the pool
         Mutex::Autolock lock(mMutex);
@@ -303,7 +301,7 @@
 
 status_t VirtualDisplaySurface::requestBuffer(int pslot,
         sp<GraphicBuffer>* outBuf) {
-    if (GpuVirtualDisplayId::tryCast(mDisplayId)) {
+    if (!mDisplayId) {
         return mSource[SOURCE_SINK]->requestBuffer(pslot, outBuf);
     }
 
@@ -325,7 +323,7 @@
 
 status_t VirtualDisplaySurface::dequeueBuffer(Source source,
         PixelFormat format, uint64_t usage, int* sslot, sp<Fence>* fence) {
-    LOG_FATAL_IF(GpuVirtualDisplayId::tryCast(mDisplayId));
+    LOG_FATAL_IF(!mDisplayId);
 
     status_t result =
             mSource[source]->dequeueBuffer(sslot, fence, mSinkBufferWidth, mSinkBufferHeight,
@@ -371,7 +369,7 @@
                                               PixelFormat format, uint64_t usage,
                                               uint64_t* outBufferAge,
                                               FrameEventHistoryDelta* outTimestamps) {
-    if (GpuVirtualDisplayId::tryCast(mDisplayId)) {
+    if (!mDisplayId) {
         return mSource[SOURCE_SINK]->dequeueBuffer(pslot, fence, w, h, format, usage, outBufferAge,
                                                    outTimestamps);
     }
@@ -458,7 +456,7 @@
 
 status_t VirtualDisplaySurface::queueBuffer(int pslot,
         const QueueBufferInput& input, QueueBufferOutput* output) {
-    if (GpuVirtualDisplayId::tryCast(mDisplayId)) {
+    if (!mDisplayId) {
         return mSource[SOURCE_SINK]->queueBuffer(pslot, input, output);
     }
 
@@ -516,7 +514,7 @@
 
 status_t VirtualDisplaySurface::cancelBuffer(int pslot,
         const sp<Fence>& fence) {
-    if (GpuVirtualDisplayId::tryCast(mDisplayId)) {
+    if (!mDisplayId) {
         return mSource[SOURCE_SINK]->cancelBuffer(mapProducer2SourceSlot(SOURCE_SINK, pslot), fence);
     }
 
@@ -628,7 +626,7 @@
 }
 
 status_t VirtualDisplaySurface::refreshOutputBuffer() {
-    LOG_FATAL_IF(GpuVirtualDisplayId::tryCast(mDisplayId));
+    LOG_FATAL_IF(!mDisplayId);
 
     if (mOutputProducerSlot >= 0) {
         mSource[SOURCE_SINK]->cancelBuffer(
@@ -647,9 +645,7 @@
     // until after GPU calls queueBuffer(). So here we just set the buffer
     // (for use in HWC prepare) but not the fence; we'll call this again with
     // the proper fence once we have it.
-    const auto halDisplayId = HalVirtualDisplayId::tryCast(mDisplayId);
-    LOG_FATAL_IF(!halDisplayId);
-    result = mHwc.setOutputBuffer(*halDisplayId, Fence::NO_FENCE,
+    result = mHwc.setOutputBuffer(*mDisplayId, Fence::NO_FENCE,
                                   mProducerBuffers[mOutputProducerSlot]);
 
     return result;
diff --git a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h
index 1974625..3cbad8f 100644
--- a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h
+++ b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h
@@ -24,7 +24,6 @@
 #include <compositionengine/impl/HwcBufferCache.h>
 #include <gui/ConsumerBase.h>
 #include <gui/IGraphicBufferProducer.h>
-#include <ui/DisplayId.h>
 
 #include "DisplayIdentification.h"
 
@@ -78,7 +77,8 @@
                               public BnGraphicBufferProducer,
                               private ConsumerBase {
 public:
-    VirtualDisplaySurface(HWComposer&, VirtualDisplayId, const sp<IGraphicBufferProducer>& sink,
+    VirtualDisplaySurface(HWComposer& hwc, const std::optional<DisplayId>& displayId,
+                          const sp<IGraphicBufferProducer>& sink,
                           const sp<IGraphicBufferProducer>& bqProducer,
                           const sp<IGraphicBufferConsumer>& bqConsumer, const std::string& name);
 
@@ -86,7 +86,7 @@
     // DisplaySurface interface
     //
     virtual status_t beginFrame(bool mustRecompose);
-    virtual status_t prepareFrame(CompositionType);
+    virtual status_t prepareFrame(CompositionType compositionType);
     virtual status_t advanceFrame();
     virtual void onFrameCommitted();
     virtual void dumpAsString(String8& result) const;
@@ -104,22 +104,25 @@
     virtual status_t requestBuffer(int pslot, sp<GraphicBuffer>* outBuf);
     virtual status_t setMaxDequeuedBufferCount(int maxDequeuedBuffers);
     virtual status_t setAsyncMode(bool async);
-    virtual status_t dequeueBuffer(int* pslot, sp<Fence>*, uint32_t w, uint32_t h, PixelFormat,
-                                   uint64_t usage, uint64_t* outBufferAge,
+    virtual status_t dequeueBuffer(int* pslot, sp<Fence>* fence, uint32_t w, uint32_t h,
+                                   PixelFormat format, uint64_t usage, uint64_t* outBufferAge,
                                    FrameEventHistoryDelta* outTimestamps);
     virtual status_t detachBuffer(int slot);
-    virtual status_t detachNextBuffer(sp<GraphicBuffer>* outBuffer, sp<Fence>* outFence);
-    virtual status_t attachBuffer(int* slot, const sp<GraphicBuffer>&);
-    virtual status_t queueBuffer(int pslot, const QueueBufferInput&, QueueBufferOutput*);
-    virtual status_t cancelBuffer(int pslot, const sp<Fence>&);
+    virtual status_t detachNextBuffer(sp<GraphicBuffer>* outBuffer,
+            sp<Fence>* outFence);
+    virtual status_t attachBuffer(int* slot, const sp<GraphicBuffer>& buffer);
+    virtual status_t queueBuffer(int pslot,
+            const QueueBufferInput& input, QueueBufferOutput* output);
+    virtual status_t cancelBuffer(int pslot, const sp<Fence>& fence);
     virtual int query(int what, int* value);
-    virtual status_t connect(const sp<IProducerListener>&, int api, bool producerControlledByApp,
-                             QueueBufferOutput*);
-    virtual status_t disconnect(int api, DisconnectMode);
+    virtual status_t connect(const sp<IProducerListener>& listener,
+            int api, bool producerControlledByApp, QueueBufferOutput* output);
+    virtual status_t disconnect(int api, DisconnectMode mode);
     virtual status_t setSidebandStream(const sp<NativeHandle>& stream);
-    virtual void allocateBuffers(uint32_t width, uint32_t height, PixelFormat, uint64_t usage);
+    virtual void allocateBuffers(uint32_t width, uint32_t height,
+            PixelFormat format, uint64_t usage);
     virtual status_t allowAllocation(bool allow);
-    virtual status_t setGenerationNumber(uint32_t);
+    virtual status_t setGenerationNumber(uint32_t generationNumber);
     virtual String8 getConsumerName() const override;
     virtual status_t setSharedBufferMode(bool sharedBufferMode) override;
     virtual status_t setAutoRefresh(bool autoRefresh) override;
@@ -132,9 +135,10 @@
     //
     // Utility methods
     //
-    static Source fbSourceForCompositionType(CompositionType);
-    status_t dequeueBuffer(Source, PixelFormat, uint64_t usage, int* sslot, sp<Fence>*);
-    void updateQueueBufferOutput(QueueBufferOutput&&);
+    static Source fbSourceForCompositionType(CompositionType type);
+    status_t dequeueBuffer(Source source, PixelFormat format, uint64_t usage,
+            int* sslot, sp<Fence>* fence);
+    void updateQueueBufferOutput(QueueBufferOutput&& qbo);
     void resetPerFrameState();
     status_t refreshOutputBuffer();
 
@@ -144,14 +148,14 @@
     // internally in the VirtualDisplaySurface. To minimize the number of times
     // a producer slot switches which source it comes from, we map source slot
     // numbers to producer slot numbers differently for each source.
-    static int mapSource2ProducerSlot(Source, int sslot);
-    static int mapProducer2SourceSlot(Source, int pslot);
+    static int mapSource2ProducerSlot(Source source, int sslot);
+    static int mapProducer2SourceSlot(Source source, int pslot);
 
     //
     // Immutable after construction
     //
     HWComposer& mHwc;
-    const VirtualDisplayId mDisplayId;
+    const std::optional<DisplayId> mDisplayId;
     const std::string mDisplayName;
     sp<IGraphicBufferProducer> mSource[2]; // indexed by SOURCE_*
     uint32_t mDefaultOutputFormat;
diff --git a/services/surfaceflinger/DisplayIdGenerator.h b/services/surfaceflinger/DisplayIdGenerator.h
deleted file mode 100644
index e7c69a8..0000000
--- a/services/surfaceflinger/DisplayIdGenerator.h
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Copyright 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <ui/DisplayId.h>
-
-#include <limits>
-#include <optional>
-#include <random>
-#include <unordered_set>
-
-#include <log/log.h>
-
-namespace android {
-
-template <typename T>
-class DisplayIdGenerator {
-public:
-    virtual std::optional<T> nextId() = 0;
-    virtual void markUnused(T id) = 0;
-
-protected:
-    ~DisplayIdGenerator() {}
-};
-
-template <typename T>
-class RandomDisplayIdGenerator final : public DisplayIdGenerator<T> {
-public:
-    explicit RandomDisplayIdGenerator(size_t maxIdsCount = std::numeric_limits<size_t>::max())
-          : mMaxIdsCount(maxIdsCount) {}
-
-    std::optional<T> nextId() override {
-        if (mUsedIds.size() >= mMaxIdsCount) {
-            return std::nullopt;
-        }
-
-        constexpr int kMaxAttempts = 1000;
-
-        for (int attempts = 0; attempts < kMaxAttempts; attempts++) {
-            const auto baseId = mDistribution(mGenerator);
-            const T id(baseId);
-            if (mUsedIds.count(id) == 0) {
-                mUsedIds.insert(id);
-                return id;
-            }
-        }
-
-        LOG_ALWAYS_FATAL("Couldn't generate ID after %d attempts", kMaxAttempts);
-    }
-
-    void markUnused(T id) override { mUsedIds.erase(id); }
-
-private:
-    const size_t mMaxIdsCount;
-
-    std::unordered_set<T> mUsedIds;
-    std::default_random_engine mGenerator{std::random_device()()};
-    std::uniform_int_distribution<typename T::BaseId> mDistribution;
-};
-
-} // namespace android
\ No newline at end of file
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index b4868a9..9bfc63a 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -717,8 +717,7 @@
     processDisplayHotplugEventsLocked();
     const auto display = getDefaultDisplayDeviceLocked();
     LOG_ALWAYS_FATAL_IF(!display, "Missing internal display after registering composer callback.");
-    const auto displayId = display->getPhysicalId();
-    LOG_ALWAYS_FATAL_IF(!getHwComposer().isConnected(displayId),
+    LOG_ALWAYS_FATAL_IF(!getHwComposer().isConnected(*display->getId()),
                         "Internal display is disconnected.");
 
     // initialize our drawing state
@@ -1079,8 +1078,8 @@
         const nsecs_t vsyncPeriod =
                 mRefreshRateConfigs->getRefreshRateFromConfigId(mUpcomingActiveConfig.configId)
                         .getVsyncPeriod();
-        const auto physicalId = display->getPhysicalId();
-        mScheduler->onPrimaryDisplayConfigChanged(mAppConnectionHandle, physicalId,
+        mScheduler->onPrimaryDisplayConfigChanged(mAppConnectionHandle,
+                                                  static_cast<PhysicalDisplayId>(*display->getId()),
                                                   mUpcomingActiveConfig.configId, vsyncPeriod);
     }
 }
@@ -1129,7 +1128,8 @@
     }
 
     mUpcomingActiveConfig = *desiredActiveConfig;
-    const auto displayId = display->getPhysicalId();
+    const auto displayId = display->getId();
+    LOG_ALWAYS_FATAL_IF(!displayId);
 
     ATRACE_INT("ActiveConfigFPS_HWC", refreshRate.getFps());
 
@@ -1140,7 +1140,7 @@
 
     hal::VsyncPeriodChangeTimeline outTimeline;
     auto status =
-            getHwComposer().setActiveConfigWithConstraints(displayId,
+            getHwComposer().setActiveConfigWithConstraints(*displayId,
                                                            mUpcomingActiveConfig.configId.value(),
                                                            constraints, &outTimeline);
     if (status != NO_ERROR) {
@@ -1665,7 +1665,7 @@
 
         if (const auto display = getDefaultDisplayDeviceLocked();
             display && display->isPoweredOn()) {
-            getHwComposer().setVsyncEnabled(display->getPhysicalId(), mHWCVsyncPendingState);
+            getHwComposer().setVsyncEnabled(*display->getId(), mHWCVsyncPendingState);
         }
     }));
 }
@@ -2120,7 +2120,7 @@
     getBE().mDisplayTimeline.updateSignalTimes();
     mPreviousPresentFences[1] = mPreviousPresentFences[0];
     mPreviousPresentFences[0] =
-            display ? getHwComposer().getPresentFence(display->getPhysicalId()) : Fence::NO_FENCE;
+            display ? getHwComposer().getPresentFence(*display->getId()) : Fence::NO_FENCE;
     auto presentFenceTime = std::make_shared<FenceTime>(mPreviousPresentFences[0]);
     getBE().mDisplayTimeline.push(presentFenceTime);
 
@@ -2154,8 +2154,7 @@
         mScheduler->addPresentFence(presentFenceTime);
     }
 
-    const bool isDisplayConnected =
-            display && getHwComposer().isConnected(display->getPhysicalId());
+    const bool isDisplayConnected = display && getHwComposer().isConnected(*display->getId());
 
     if (!hasSyncFramework) {
         if (isDisplayConnected && display->isPoweredOn()) {
@@ -2172,8 +2171,7 @@
         } else if (isDisplayConnected) {
             // The HWC doesn't support present fences, so use the refresh
             // timestamp instead.
-            const nsecs_t presentTime =
-                    getHwComposer().getRefreshTimestamp(display->getPhysicalId());
+            const nsecs_t presentTime = getHwComposer().getRefreshTimestamp(*display->getId());
             mAnimFrameTracker.setActualPresentTime(presentTime);
         }
         mAnimFrameTracker.advanceFrame();
@@ -2275,7 +2273,7 @@
 
 void SurfaceFlinger::postFrame() {
     const auto display = ON_MAIN_THREAD(getDefaultDisplayDeviceLocked());
-    if (display && getHwComposer().isConnected(display->getPhysicalId())) {
+    if (display && getHwComposer().isConnected(*display->getId())) {
         uint32_t flipCount = display->getPageFlipCount();
         if (flipCount % LOG_FRAME_STATS_PERIOD == 0) {
             logFrameStats();
@@ -2380,6 +2378,7 @@
         const DisplayDeviceState& state,
         const sp<compositionengine::DisplaySurface>& displaySurface,
         const sp<IGraphicBufferProducer>& producer) {
+    auto displayId = compositionDisplay->getDisplayId();
     DisplayDeviceCreationArgs creationArgs(this, displayToken, compositionDisplay);
     creationArgs.sequenceId = state.sequenceId;
     creationArgs.isSecure = state.isSecure;
@@ -2391,26 +2390,26 @@
         creationArgs.connectionType = physical->type;
     }
 
-    if (const auto id = PhysicalDisplayId::tryCast(compositionDisplay->getId())) {
-        creationArgs.isPrimary = id == getInternalDisplayIdLocked();
+    const bool isInternalDisplay = displayId && displayId == getInternalDisplayIdLocked();
+    creationArgs.isPrimary = isInternalDisplay;
 
-        if (useColorManagement) {
-            std::vector<ColorMode> modes = getHwComposer().getColorModes(*id);
-            for (ColorMode colorMode : modes) {
-                if (isWideColorMode(colorMode)) {
-                    creationArgs.hasWideColorGamut = true;
-                }
-
-                std::vector<RenderIntent> renderIntents =
-                        getHwComposer().getRenderIntents(*id, colorMode);
-                creationArgs.hwcColorModes.emplace(colorMode, renderIntents);
+    if (useColorManagement && displayId) {
+        std::vector<ColorMode> modes = getHwComposer().getColorModes(*displayId);
+        for (ColorMode colorMode : modes) {
+            if (isWideColorMode(colorMode)) {
+                creationArgs.hasWideColorGamut = true;
             }
+
+            std::vector<RenderIntent> renderIntents =
+                    getHwComposer().getRenderIntents(*displayId, colorMode);
+            creationArgs.hwcColorModes.emplace(colorMode, renderIntents);
         }
     }
 
-    if (const auto id = HalDisplayId::tryCast(compositionDisplay->getId())) {
-        getHwComposer().getHdrCapabilities(*id, &creationArgs.hdrCapabilities);
-        creationArgs.supportedPerFrameMetadata = getHwComposer().getSupportedPerFrameMetadata(*id);
+    if (displayId) {
+        getHwComposer().getHdrCapabilities(*displayId, &creationArgs.hdrCapabilities);
+        creationArgs.supportedPerFrameMetadata =
+                getHwComposer().getSupportedPerFrameMetadata(*displayId);
     }
 
     auto nativeWindowSurface = getFactory().createNativeWindowSurface(producer);
@@ -2425,7 +2424,7 @@
     }
 
     creationArgs.physicalOrientation =
-            creationArgs.isPrimary ? internalDisplayOrientation : ui::ROTATION_0;
+            isInternalDisplay ? internalDisplayOrientation : ui::ROTATION_0;
 
     // virtual displays are always considered enabled
     creationArgs.initialPowerMode = state.isVirtual() ? hal::PowerMode::ON : hal::PowerMode::OFF;
@@ -2447,8 +2446,8 @@
                                                     RenderIntent::COLORIMETRIC,
                                                     Dataspace::UNKNOWN});
     if (!state.isVirtual()) {
-        const auto physicalId = display->getPhysicalId();
-        auto activeConfigId = HwcConfigIndexType(getHwComposer().getActiveConfigIndex(physicalId));
+        LOG_ALWAYS_FATAL_IF(!displayId);
+        auto activeConfigId = HwcConfigIndexType(getHwComposer().getActiveConfigIndex(*displayId));
         display->setActiveConfig(activeConfigId);
         display->setDeviceProductInfo(state.physical->deviceProductInfo);
     }
@@ -2498,7 +2497,6 @@
     builder.setLayerStackId(state.layerStack);
     builder.setPowerAdvisor(&mPowerAdvisor);
     builder.setUseHwcVirtualDisplays(mUseHwcVirtualDisplays);
-    builder.setGpuVirtualDisplayIdGenerator(mGpuVirtualDisplayIdGenerator);
     builder.setName(state.displayName);
     const auto compositionDisplay = getCompositionEngine().createDisplay(builder.build());
 
@@ -2508,13 +2506,11 @@
     sp<IGraphicBufferConsumer> bqConsumer;
     getFactory().createBufferQueue(&bqProducer, &bqConsumer, /*consumerIsSurfaceFlinger =*/false);
 
-    DisplayId displayId = compositionDisplay->getId();
+    std::optional<DisplayId> displayId = compositionDisplay->getId();
 
     if (state.isVirtual()) {
-        const auto virtualId = VirtualDisplayId::tryCast(displayId);
-        LOG_FATAL_IF(!virtualId);
         sp<VirtualDisplaySurface> vds =
-                new VirtualDisplaySurface(getHwComposer(), *virtualId, state.surface, bqProducer,
+                new VirtualDisplaySurface(getHwComposer(), displayId, state.surface, bqProducer,
                                           bqConsumer, state.displayName);
 
         displaySurface = vds;
@@ -2524,9 +2520,9 @@
                  "adding a supported display, but rendering "
                  "surface is provided (%p), ignoring it",
                  state.surface.get());
-        const auto physicalId = PhysicalDisplayId::tryCast(displayId);
-        LOG_FATAL_IF(!physicalId);
-        displaySurface = new FramebufferSurface(getHwComposer(), *physicalId, bqConsumer,
+
+        LOG_ALWAYS_FATAL_IF(!displayId);
+        displaySurface = new FramebufferSurface(getHwComposer(), *displayId, bqConsumer,
                                                 maxGraphicsWidth, maxGraphicsHeight);
         producer = bqProducer;
     }
@@ -2536,7 +2532,8 @@
                                                        displaySurface, producer);
     mDisplays.emplace(displayToken, display);
     if (!state.isVirtual()) {
-        dispatchDisplayHotplugEvent(display->getPhysicalId(), true);
+        LOG_FATAL_IF(!displayId);
+        dispatchDisplayHotplugEvent(static_cast<PhysicalDisplayId>(*displayId), true);
     }
 
     if (display->isPrimary()) {
@@ -2546,9 +2543,13 @@
 
 void SurfaceFlinger::processDisplayRemoved(const wp<IBinder>& displayToken) {
     if (const auto display = getDisplayDeviceLocked(displayToken)) {
+        // Save display ID before disconnecting.
+        const auto displayId = display->getId();
         display->disconnect();
+
         if (!display->isVirtual()) {
-            dispatchDisplayHotplugEvent(display->getPhysicalId(), false);
+            LOG_FATAL_IF(!displayId);
+            dispatchDisplayHotplugEvent(static_cast<PhysicalDisplayId>(*displayId), false);
         }
     }
 
@@ -2824,7 +2825,7 @@
 void SurfaceFlinger::updateCursorAsync() {
     compositionengine::CompositionRefreshArgs refreshArgs;
     for (const auto& [_, display] : ON_MAIN_THREAD(mDisplays)) {
-        if (HalDisplayId::tryCast(display->getId())) {
+        if (display->getId()) {
             refreshArgs.outputs.push_back(display->getCompositionDisplay());
         }
     }
@@ -4110,8 +4111,10 @@
         return;
     }
 
-    const auto displayId = display->getPhysicalId();
-    ALOGD("Setting power mode %d on display %s", mode, to_string(displayId).c_str());
+    const auto displayId = display->getId();
+    LOG_ALWAYS_FATAL_IF(!displayId);
+
+    ALOGD("Setting power mode %d on display %s", mode, to_string(*displayId).c_str());
 
     const hal::PowerMode currentMode = display->getPowerMode();
     if (mode == currentMode) {
@@ -4128,9 +4131,9 @@
         if (SurfaceFlinger::setSchedFifo(true) != NO_ERROR) {
             ALOGW("Couldn't set SCHED_FIFO on display on: %s\n", strerror(errno));
         }
-        getHwComposer().setPowerMode(displayId, mode);
+        getHwComposer().setPowerMode(*displayId, mode);
         if (display->isPrimary() && mode != hal::PowerMode::DOZE_SUSPEND) {
-            getHwComposer().setVsyncEnabled(displayId, mHWCVsyncPendingState);
+            getHwComposer().setVsyncEnabled(*displayId, mHWCVsyncPendingState);
             mScheduler->onScreenAcquired(mAppConnectionHandle);
             mScheduler->resyncToHardwareVsync(true, vsyncPeriod);
         }
@@ -4149,14 +4152,14 @@
         }
 
         // Make sure HWVsync is disabled before turning off the display
-        getHwComposer().setVsyncEnabled(displayId, hal::Vsync::DISABLE);
+        getHwComposer().setVsyncEnabled(*displayId, hal::Vsync::DISABLE);
 
-        getHwComposer().setPowerMode(displayId, mode);
+        getHwComposer().setPowerMode(*displayId, mode);
         mVisibleRegionsDirty = true;
         // from this point on, SF will stop drawing on this display
     } else if (mode == hal::PowerMode::DOZE || mode == hal::PowerMode::ON) {
         // Update display while dozing
-        getHwComposer().setPowerMode(displayId, mode);
+        getHwComposer().setPowerMode(*displayId, mode);
         if (display->isPrimary() && currentMode == hal::PowerMode::DOZE_SUSPEND) {
             mScheduler->onScreenAcquired(mAppConnectionHandle);
             mScheduler->resyncToHardwareVsync(true, vsyncPeriod);
@@ -4167,10 +4170,10 @@
             mScheduler->disableHardwareVsync(true);
             mScheduler->onScreenReleased(mAppConnectionHandle);
         }
-        getHwComposer().setPowerMode(displayId, mode);
+        getHwComposer().setPowerMode(*displayId, mode);
     } else {
         ALOGE("Attempting to set unknown power mode: %d\n", mode);
-        getHwComposer().setPowerMode(displayId, mode);
+        getHwComposer().setPowerMode(*displayId, mode);
     }
 
     if (display->isPrimary()) {
@@ -4179,7 +4182,7 @@
         mScheduler->setDisplayPowerState(mode == hal::PowerMode::ON);
     }
 
-    ALOGD("Finished setting power mode %d on display %s", mode, to_string(displayId).c_str());
+    ALOGD("Finished setting power mode %d on display %s", mode, to_string(*displayId).c_str());
 }
 
 void SurfaceFlinger::setPowerMode(const sp<IBinder>& displayToken, int mode) {
@@ -4438,11 +4441,12 @@
 
 void SurfaceFlinger::dumpDisplayIdentificationData(std::string& result) const {
     for (const auto& [token, display] : mDisplays) {
-        const auto displayId = PhysicalDisplayId::tryCast(display->getId());
+        const auto displayId = display->getId();
         if (!displayId) {
             continue;
         }
-        const auto hwcDisplayId = getHwComposer().fromPhysicalDisplayId(*displayId);
+        const auto hwcDisplayId =
+                getHwComposer().fromPhysicalDisplayId(static_cast<PhysicalDisplayId>(*displayId));
         if (!hwcDisplayId) {
             continue;
         }
@@ -4495,7 +4499,7 @@
     // TODO: print out if wide-color mode is active or not
 
     for (const auto& [token, display] : mDisplays) {
-        const auto displayId = PhysicalDisplayId::tryCast(display->getId());
+        const auto displayId = display->getId();
         if (!displayId) {
             continue;
         }
@@ -4709,7 +4713,7 @@
      * HWC layer minidump
      */
     for (const auto& [token, display] : mDisplays) {
-        const auto displayId = HalDisplayId::tryCast(display->getId());
+        const auto displayId = display->getId();
         if (!displayId) {
             continue;
         }
@@ -5228,12 +5232,18 @@
             // Inject a hotplug connected event for the primary display. This will deallocate and
             // reallocate the display state including framebuffers.
             case 1037: {
-                std::optional<hal::HWDisplayId> hwcId;
+                const auto token = getInternalDisplayToken();
+
+                sp<DisplayDevice> display;
                 {
                     Mutex::Autolock lock(mStateLock);
-                    hwcId = getHwComposer().getInternalHwcDisplayId();
+                    display = getDisplayDeviceLocked(token);
                 }
+                const auto hwcId =
+                        getHwComposer().fromPhysicalDisplayId(PhysicalDisplayId(*display->getId()));
+
                 onHotplugReceived(getBE().mComposerSequenceId, *hwcId, hal::Connection::CONNECTED);
+
                 return NO_ERROR;
             }
         }
@@ -5840,14 +5850,16 @@
         // as well. For now, just call directly to setActiveConfigWithConstraints but ideally
         // it should go thru setDesiredActiveConfig, similar to primary display.
         ALOGV("setAllowedDisplayConfigsInternal for non-primary display");
-        const auto displayId = display->getPhysicalId();
+        const auto displayId = display->getId();
+        LOG_ALWAYS_FATAL_IF(!displayId);
 
         hal::VsyncPeriodChangeConstraints constraints;
         constraints.desiredTimeNanos = systemTime();
         constraints.seamlessRequired = false;
 
         hal::VsyncPeriodChangeTimeline timeline = {0, 0, 0};
-        if (getHwComposer().setActiveConfigWithConstraints(displayId, policy->defaultConfig.value(),
+        if (getHwComposer().setActiveConfigWithConstraints(*displayId,
+                                                           policy->defaultConfig.value(),
                                                            constraints, &timeline) < 0) {
             return BAD_VALUE;
         }
@@ -5857,9 +5869,11 @@
 
         display->setActiveConfig(policy->defaultConfig);
         const nsecs_t vsyncPeriod = getHwComposer()
-                                            .getConfigs(displayId)[policy->defaultConfig.value()]
+                                            .getConfigs(*displayId)[policy->defaultConfig.value()]
                                             ->getVsyncPeriod();
-        mScheduler->onNonPrimaryDisplayConfigChanged(mAppConnectionHandle, displayId,
+        mScheduler->onNonPrimaryDisplayConfigChanged(mAppConnectionHandle,
+                                                     static_cast<PhysicalDisplayId>(
+                                                             *display->getId()),
                                                      policy->defaultConfig, vsyncPeriod);
         return NO_ERROR;
     }
@@ -5891,8 +5905,8 @@
     const nsecs_t vsyncPeriod =
             mRefreshRateConfigs->getRefreshRateFromConfigId(display->getActiveConfig())
                     .getVsyncPeriod();
-    const auto physicalId = display->getPhysicalId();
-    mScheduler->onPrimaryDisplayConfigChanged(mAppConnectionHandle, physicalId,
+    mScheduler->onPrimaryDisplayConfigChanged(mAppConnectionHandle,
+                                              static_cast<PhysicalDisplayId>(*display->getId()),
                                               display->getActiveConfig(), vsyncPeriod);
     toggleKernelIdleTimer();
 
@@ -5983,9 +5997,11 @@
     } else if (display->isVirtual()) {
         return INVALID_OPERATION;
     } else {
-        const auto displayId = display->getPhysicalId();
-        *outDefaultConfig = getHwComposer().getActiveConfigIndex(displayId);
-        auto vsyncPeriod = getHwComposer().getActiveConfig(displayId)->getVsyncPeriod();
+        const auto displayId = display->getId();
+        LOG_FATAL_IF(!displayId);
+
+        *outDefaultConfig = getHwComposer().getActiveConfigIndex(*displayId);
+        auto vsyncPeriod = getHwComposer().getActiveConfig(*displayId)->getVsyncPeriod();
         *outPrimaryRefreshRateMin = 1e9f / vsyncPeriod;
         *outPrimaryRefreshRateMax = 1e9f / vsyncPeriod;
         *outAppRequestRefreshRateMin = 1e9f / vsyncPeriod;
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 981c60d..0fd17d1 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -52,7 +52,6 @@
 #include "DisplayDevice.h"
 #include "DisplayHardware/HWC2.h"
 #include "DisplayHardware/PowerAdvisor.h"
-#include "DisplayIdGenerator.h"
 #include "Effects/Daltonizer.h"
 #include "FrameTracker.h"
 #include "LayerVector.h"
@@ -946,8 +945,8 @@
         return it != mPhysicalDisplayTokens.end() ? it->second : nullptr;
     }
 
-    std::optional<PhysicalDisplayId> getPhysicalDisplayIdLocked(
-            const sp<IBinder>& displayToken) const REQUIRES(mStateLock) {
+    std::optional<DisplayId> getPhysicalDisplayIdLocked(const sp<IBinder>& displayToken) const
+            REQUIRES(mStateLock) {
         for (const auto& [id, token] : mPhysicalDisplayTokens) {
             if (token == displayToken) {
                 return id;
@@ -1110,8 +1109,6 @@
     std::unordered_map<PhysicalDisplayId, sp<IBinder>> mPhysicalDisplayTokens
             GUARDED_BY(mStateLock);
 
-    RandomDisplayIdGenerator<GpuVirtualDisplayId> mGpuVirtualDisplayIdGenerator;
-
     std::unordered_map<BBinder*, wp<Layer>> mLayersByLocalBinderToken GUARDED_BY(mStateLock);
 
     // don't use a lock for these, we don't care
diff --git a/services/surfaceflinger/tests/unittests/Android.bp b/services/surfaceflinger/tests/unittests/Android.bp
index a4a60d5..6f1f1f2 100644
--- a/services/surfaceflinger/tests/unittests/Android.bp
+++ b/services/surfaceflinger/tests/unittests/Android.bp
@@ -39,7 +39,6 @@
         "CompositionTest.cpp",
         "DispSyncSourceTest.cpp",
         "DisplayIdentificationTest.cpp",
-        "DisplayIdGeneratorTest.cpp",
         "DisplayTransactionTest.cpp",
         "EventThreadTest.cpp",
         "FrameTimelineTest.cpp",
diff --git a/services/surfaceflinger/tests/unittests/DisplayIdGeneratorTest.cpp b/services/surfaceflinger/tests/unittests/DisplayIdGeneratorTest.cpp
deleted file mode 100644
index be7609a..0000000
--- a/services/surfaceflinger/tests/unittests/DisplayIdGeneratorTest.cpp
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <gtest/gtest.h>
-
-#include <vector>
-
-#include <ui/DisplayId.h>
-#include "DisplayIdGenerator.h"
-
-namespace android {
-
-template <typename T>
-void testNextId(DisplayIdGenerator<T>& generator) {
-    constexpr int kNumIds = 5;
-    std::vector<T> ids;
-    for (int i = 0; i < kNumIds; i++) {
-        const auto id = generator.nextId();
-        ASSERT_TRUE(id);
-        ids.push_back(*id);
-    }
-
-    // All IDs should be different.
-    for (size_t i = 0; i < kNumIds; i++) {
-        for (size_t j = i + 1; j < kNumIds; j++) {
-            EXPECT_NE(ids[i], ids[j]);
-        }
-    }
-}
-
-TEST(DisplayIdGeneratorTest, nextIdGpuVirtual) {
-    RandomDisplayIdGenerator<GpuVirtualDisplayId> generator;
-    testNextId(generator);
-}
-
-TEST(DisplayIdGeneratorTest, nextIdHalVirtual) {
-    RandomDisplayIdGenerator<HalVirtualDisplayId> generator;
-    testNextId(generator);
-}
-
-TEST(DisplayIdGeneratorTest, markUnused) {
-    constexpr size_t kMaxIdsCount = 5;
-    RandomDisplayIdGenerator<GpuVirtualDisplayId> generator(kMaxIdsCount);
-
-    const auto id = generator.nextId();
-    EXPECT_TRUE(id);
-
-    for (int i = 1; i < kMaxIdsCount; i++) {
-        EXPECT_TRUE(generator.nextId());
-    }
-
-    EXPECT_FALSE(generator.nextId());
-
-    generator.markUnused(*id);
-    EXPECT_TRUE(generator.nextId());
-}
-
-TEST(DisplayIdGeneratorTest, maxIdsCount) {
-    constexpr size_t kMaxIdsCount = 5;
-    RandomDisplayIdGenerator<GpuVirtualDisplayId> generator(kMaxIdsCount);
-
-    for (int i = 0; i < kMaxIdsCount; i++) {
-        EXPECT_TRUE(generator.nextId());
-    }
-
-    EXPECT_FALSE(generator.nextId());
-}
-
-} // namespace android
diff --git a/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp b/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp
index a81d216..b750d6b 100644
--- a/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp
+++ b/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp
@@ -338,9 +338,9 @@
 struct PhysicalDisplayIdType {};
 
 template <uint64_t displayId>
-using HalVirtualDisplayIdType = std::integral_constant<uint64_t, displayId>;
+using VirtualDisplayIdType = std::integral_constant<uint64_t, displayId>;
 
-struct GpuVirtualDisplayIdType {};
+struct NoDisplayId {};
 
 template <typename>
 struct IsPhysicalDisplayId : std::bool_constant<false> {};
@@ -353,7 +353,7 @@
 
 template <typename PhysicalDisplay>
 struct DisplayIdGetter<PhysicalDisplayIdType<PhysicalDisplay>> {
-    static PhysicalDisplayId get() {
+    static std::optional<PhysicalDisplayId> get() {
         if (!PhysicalDisplay::HAS_IDENTIFICATION_DATA) {
             return PhysicalDisplayId::fromPort(static_cast<bool>(PhysicalDisplay::PRIMARY)
                                                        ? LEGACY_DISPLAY_TYPE_PRIMARY
@@ -363,18 +363,19 @@
         const auto info =
                 parseDisplayIdentificationData(PhysicalDisplay::PORT,
                                                PhysicalDisplay::GET_IDENTIFICATION_DATA());
-        return info ? info->id : PhysicalDisplayId::fromPort(PhysicalDisplay::PORT);
+        return info ? std::make_optional(info->id) : std::nullopt;
     }
 };
 
 template <uint64_t displayId>
-struct DisplayIdGetter<HalVirtualDisplayIdType<displayId>> {
-    static HalVirtualDisplayId get() { return HalVirtualDisplayId(displayId); }
+struct DisplayIdGetter<VirtualDisplayIdType<displayId>> {
+    // TODO(b/160679868) Use VirtualDisplayId
+    static std::optional<PhysicalDisplayId> get() { return PhysicalDisplayId{displayId}; }
 };
 
 template <>
-struct DisplayIdGetter<GpuVirtualDisplayIdType> {
-    static GpuVirtualDisplayId get() { return GpuVirtualDisplayId(0); }
+struct DisplayIdGetter<NoDisplayId> {
+    static std::optional<DisplayId> get() { return {}; }
 };
 
 template <typename>
@@ -395,7 +396,7 @@
 constexpr HWDisplayId HWC_VIRTUAL_DISPLAY_HWC_DISPLAY_ID = 1010;
 
 template <uint64_t displayId>
-struct HwcDisplayIdGetter<HalVirtualDisplayIdType<displayId>> {
+struct HwcDisplayIdGetter<VirtualDisplayIdType<displayId>> {
     static constexpr std::optional<HWDisplayId> value = HWC_VIRTUAL_DISPLAY_HWC_DISPLAY_ID;
 };
 
@@ -406,8 +407,8 @@
 
 // DisplayIdType can be:
 //     1) PhysicalDisplayIdType<...> for generated ID of physical display backed by HWC.
-//     2) HalVirtualDisplayIdType<...> for hard-coded ID of virtual display backed by HWC.
-//     3) GpuVirtualDisplayIdType for virtual display without HWC backing.
+//     2) VirtualDisplayIdType<...> for hard-coded ID of virtual display backed by HWC.
+//     3) NoDisplayId for virtual display without HWC backing.
 template <typename DisplayIdType, int width, int height, Critical critical, Async async,
           Secure secure, Primary primary, int grallocUsage>
 struct DisplayVariant {
@@ -439,36 +440,17 @@
 
     static auto makeFakeExistingDisplayInjector(DisplayTransactionTest* test) {
         auto ceDisplayArgs = compositionengine::DisplayCreationArgsBuilder();
-        if (auto displayId = PhysicalDisplayId::tryCast(DISPLAY_ID::get())) {
+        if (auto displayId = DISPLAY_ID::get()) {
             ceDisplayArgs.setPhysical({*displayId, DisplayConnectionType::Internal});
         } else {
-            // We turn off the use of HwcVirtualDisplays, to prevent Composition Engine
-            // from calling into HWComposer. This way all virtual displays will get
-            // a GpuVirtualDisplayId, even if we are in the HwcVirtualDisplayVariant.
-            // In this case we later override it by calling display.setDisplayIdForTesting().
             ceDisplayArgs.setUseHwcVirtualDisplays(false);
-
-            GpuVirtualDisplayId desiredDisplayId = GpuVirtualDisplayId::tryCast(DISPLAY_ID::get())
-                                                           .value_or(GpuVirtualDisplayId(0));
-
-            ON_CALL(test->mFlinger.gpuVirtualDisplayIdGenerator(), nextId())
-                    .WillByDefault(Return(desiredDisplayId));
-
-            auto& generator = test->mFlinger.gpuVirtualDisplayIdGenerator();
-            ceDisplayArgs.setGpuVirtualDisplayIdGenerator(generator);
         }
-        ceDisplayArgs.setPixels({WIDTH, HEIGHT}).setPowerAdvisor(&test->mPowerAdvisor);
+        ceDisplayArgs.setPixels({WIDTH, HEIGHT}).setPowerAdvisor(&test->mPowerAdvisor).build();
 
         auto compositionDisplay =
                 compositionengine::impl::createDisplay(test->mFlinger.getCompositionEngine(),
                                                        ceDisplayArgs.build());
 
-        if (HalVirtualDisplayId::tryCast(DISPLAY_ID::get())) {
-            // CompositionEngine has assigned a placeholder GpuVirtualDisplayId and we need to
-            // override it with the correct HalVirtualDisplayId.
-            compositionDisplay->setDisplayIdForTesting(DISPLAY_ID::get());
-        }
-
         auto injector = FakeDisplayDeviceInjector(test->mFlinger, compositionDisplay,
                                                   CONNECTION_TYPE::value, HWC_DISPLAY_ID_OPT::value,
                                                   static_cast<bool>(PRIMARY));
@@ -550,8 +532,8 @@
     // Called by tests to inject a HWC display setup
     static void injectHwcDisplayWithNoDefaultCapabilities(DisplayTransactionTest* test) {
         const auto displayId = DisplayVariant::DISPLAY_ID::get();
-        ASSERT_FALSE(GpuVirtualDisplayId::tryCast(displayId));
-        FakeHwcDisplayInjector(displayId, HWC_DISPLAY_TYPE,
+        ASSERT_TRUE(displayId);
+        FakeHwcDisplayInjector(*displayId, HWC_DISPLAY_TYPE,
                                static_cast<bool>(DisplayVariant::PRIMARY))
                 .setHwcDisplayId(HWC_DISPLAY_ID)
                 .setWidth(DisplayVariant::WIDTH)
@@ -577,7 +559,7 @@
                 ::testing::UnitTest::GetInstance()->current_test_info();
 
         auto ceDisplayArgs = compositionengine::DisplayCreationArgsBuilder()
-                                     .setPhysical({DisplayVariant::DISPLAY_ID::get(),
+                                     .setPhysical({*DisplayVariant::DISPLAY_ID::get(),
                                                    PhysicalDisplay::CONNECTION_TYPE})
                                      .setPixels({DisplayVariant::WIDTH, DisplayVariant::HEIGHT})
                                      .setIsSecure(static_cast<bool>(DisplayVariant::SECURE))
@@ -704,11 +686,10 @@
 
 template <int width, int height, Secure secure>
 struct NonHwcVirtualDisplayVariant
-      : DisplayVariant<GpuVirtualDisplayIdType, width, height, Critical::FALSE, Async::TRUE, secure,
+      : DisplayVariant<NoDisplayId, width, height, Critical::FALSE, Async::TRUE, secure,
                        Primary::FALSE, GRALLOC_USAGE_NONHWC_VIRTUAL_DISPLAY> {
-    using Base =
-            DisplayVariant<GpuVirtualDisplayIdType, width, height, Critical::FALSE, Async::TRUE,
-                           secure, Primary::FALSE, GRALLOC_USAGE_NONHWC_VIRTUAL_DISPLAY>;
+    using Base = DisplayVariant<NoDisplayId, width, height, Critical::FALSE, Async::TRUE, secure,
+                                Primary::FALSE, GRALLOC_USAGE_NONHWC_VIRTUAL_DISPLAY>;
 
     static void injectHwcDisplay(DisplayTransactionTest*) {}
 
@@ -717,17 +698,12 @@
         const ::testing::TestInfo* const test_info =
                 ::testing::UnitTest::GetInstance()->current_test_info();
 
-        ON_CALL(test->mFlinger.gpuVirtualDisplayIdGenerator(), nextId())
-                .WillByDefault(Return(Base::DISPLAY_ID::get()));
-
         auto ceDisplayArgs = compositionengine::DisplayCreationArgsBuilder()
                                      .setPixels({Base::WIDTH, Base::HEIGHT})
                                      .setIsSecure(static_cast<bool>(Base::SECURE))
                                      .setPowerAdvisor(&test->mPowerAdvisor)
                                      .setName(std::string("Injected display for ") +
                                               test_info->test_case_name() + "." + test_info->name())
-                                     .setGpuVirtualDisplayIdGenerator(
-                                             test->mFlinger.gpuVirtualDisplayIdGenerator())
                                      .build();
 
         return compositionengine::impl::createDisplay(test->mFlinger.getCompositionEngine(),
@@ -749,13 +725,13 @@
 
 template <int width, int height, Secure secure>
 struct HwcVirtualDisplayVariant
-      : DisplayVariant<HalVirtualDisplayIdType<42>, width, height, Critical::FALSE, Async::TRUE,
+      : DisplayVariant<VirtualDisplayIdType<42>, width, height, Critical::FALSE, Async::TRUE,
                        secure, Primary::FALSE, GRALLOC_USAGE_HWC_VIRTUAL_DISPLAY>,
         HwcDisplayVariant<HWC_VIRTUAL_DISPLAY_HWC_DISPLAY_ID, DisplayType::VIRTUAL,
-                          DisplayVariant<HalVirtualDisplayIdType<42>, width, height,
-                                         Critical::FALSE, Async::TRUE, secure, Primary::FALSE,
+                          DisplayVariant<VirtualDisplayIdType<42>, width, height, Critical::FALSE,
+                                         Async::TRUE, secure, Primary::FALSE,
                                          GRALLOC_USAGE_HWC_VIRTUAL_DISPLAY>> {
-    using Base = DisplayVariant<HalVirtualDisplayIdType<42>, width, height, Critical::FALSE,
+    using Base = DisplayVariant<VirtualDisplayIdType<42>, width, height, Critical::FALSE,
                                 Async::TRUE, secure, Primary::FALSE, GRALLOC_USAGE_HW_COMPOSER>;
     using Self = HwcVirtualDisplayVariant<width, height, secure>;
 
@@ -764,14 +740,6 @@
         const ::testing::TestInfo* const test_info =
                 ::testing::UnitTest::GetInstance()->current_test_info();
 
-        // In order to prevent compostition engine calling into HWComposer, we
-        // 1. turn off the use of HWC virtual displays,
-        // 2. provide a GpuVirtualDisplayIdGenerator which always returns some fake ID
-        // 3. override the ID by calling setDisplayIdForTesting()
-
-        ON_CALL(test->mFlinger.gpuVirtualDisplayIdGenerator(), nextId())
-                .WillByDefault(Return(GpuVirtualDisplayId(0)));
-
         auto ceDisplayArgs = compositionengine::DisplayCreationArgsBuilder()
                                      .setUseHwcVirtualDisplays(false)
                                      .setPixels({Base::WIDTH, Base::HEIGHT})
@@ -779,8 +747,6 @@
                                      .setPowerAdvisor(&test->mPowerAdvisor)
                                      .setName(std::string("Injected display for ") +
                                               test_info->test_case_name() + "." + test_info->name())
-                                     .setGpuVirtualDisplayIdGenerator(
-                                             test->mFlinger.gpuVirtualDisplayIdGenerator())
                                      .build();
 
         auto compositionDisplay =
@@ -789,9 +755,8 @@
         compositionDisplay->setDisplayIdForTesting(Base::DISPLAY_ID::get());
 
         // Insert display data so that the HWC thinks it created the virtual display.
-        if (const auto displayId = Base::DISPLAY_ID::get();
-            HalVirtualDisplayId::tryCast(displayId)) {
-            test->mFlinger.mutableHwcDisplayData().try_emplace(displayId);
+        if (const auto displayId = Base::DISPLAY_ID::get()) {
+            test->mFlinger.mutableHwcDisplayData().try_emplace(*displayId);
         }
 
         return compositionDisplay;
@@ -1811,11 +1776,13 @@
 
     DisplayDeviceState state;
     if (const auto connectionType = Case::Display::CONNECTION_TYPE::value) {
-        const auto displayId = PhysicalDisplayId::tryCast(Case::Display::DISPLAY_ID::get());
+        const auto displayId = Case::Display::DISPLAY_ID::get();
         ASSERT_TRUE(displayId);
         const auto hwcDisplayId = Case::Display::HWC_DISPLAY_ID_OPT::value;
         ASSERT_TRUE(hwcDisplayId);
-        state.physical = {.id = *displayId, .type = *connectionType, .hwcDisplayId = *hwcDisplayId};
+        state.physical = {.id = static_cast<PhysicalDisplayId>(*displayId),
+                          .type = *connectionType,
+                          .hwcDisplayId = *hwcDisplayId};
     }
 
     state.isSecure = static_cast<bool>(Case::Display::SECURE);
@@ -1987,11 +1954,11 @@
 
     std::optional<DisplayDeviceState::Physical> expectedPhysical;
     if (const auto connectionType = Case::Display::CONNECTION_TYPE::value) {
-        const auto displayId = PhysicalDisplayId::tryCast(Case::Display::DISPLAY_ID::get());
+        const auto displayId = Case::Display::DISPLAY_ID::get();
         ASSERT_TRUE(displayId);
         const auto hwcDisplayId = Case::Display::HWC_DISPLAY_ID_OPT::value;
         ASSERT_TRUE(hwcDisplayId);
-        expectedPhysical = {.id = *displayId,
+        expectedPhysical = {.id = static_cast<PhysicalDisplayId>(*displayId),
                             .type = *connectionType,
                             .hwcDisplayId = *hwcDisplayId};
     }
@@ -2016,9 +1983,9 @@
 
     // SF should have a display token.
     const auto displayId = Case::Display::DISPLAY_ID::get();
-    ASSERT_TRUE(PhysicalDisplayId::tryCast(displayId));
-    ASSERT_TRUE(mFlinger.mutablePhysicalDisplayTokens().count(displayId) == 1);
-    auto& displayToken = mFlinger.mutablePhysicalDisplayTokens()[displayId];
+    ASSERT_TRUE(displayId);
+    ASSERT_TRUE(mFlinger.mutablePhysicalDisplayTokens().count(*displayId) == 1);
+    auto& displayToken = mFlinger.mutablePhysicalDisplayTokens()[*displayId];
 
     verifyDisplayIsConnected<Case>(displayToken);
 }
@@ -2121,8 +2088,8 @@
 
     // SF should not have a display token.
     const auto displayId = Case::Display::DISPLAY_ID::get();
-    ASSERT_TRUE(PhysicalDisplayId::tryCast(displayId));
-    ASSERT_TRUE(mFlinger.mutablePhysicalDisplayTokens().count(displayId) == 0);
+    ASSERT_TRUE(displayId);
+    ASSERT_TRUE(mFlinger.mutablePhysicalDisplayTokens().count(*displayId) == 0);
 
     // The existing token should have been removed
     verifyDisplayIsNotConnected(existing.token());
@@ -2207,8 +2174,8 @@
 
     // SF should not have a display token.
     const auto displayId = Case::Display::DISPLAY_ID::get();
-    ASSERT_TRUE(PhysicalDisplayId::tryCast(displayId));
-    ASSERT_TRUE(mFlinger.mutablePhysicalDisplayTokens().count(displayId) == 0);
+    ASSERT_TRUE(displayId);
+    ASSERT_TRUE(mFlinger.mutablePhysicalDisplayTokens().count(*displayId) == 0);
 }
 
 TEST_F(HandleTransactionLockedTest, processesHotplugDisconnectThenConnectPrimary) {
@@ -2246,9 +2213,9 @@
     // The existing token should have been removed
     verifyDisplayIsNotConnected(existing.token());
     const auto displayId = Case::Display::DISPLAY_ID::get();
-    ASSERT_TRUE(PhysicalDisplayId::tryCast(displayId));
-    ASSERT_TRUE(mFlinger.mutablePhysicalDisplayTokens().count(displayId) == 1);
-    EXPECT_NE(existing.token(), mFlinger.mutablePhysicalDisplayTokens()[displayId]);
+    ASSERT_TRUE(displayId);
+    ASSERT_TRUE(mFlinger.mutablePhysicalDisplayTokens().count(*displayId) == 1);
+    EXPECT_NE(existing.token(), mFlinger.mutablePhysicalDisplayTokens()[*displayId]);
 
     // A new display should be connected in its place
 
@@ -2382,8 +2349,8 @@
 
     // A virtual display is set up but is removed from the current state.
     const auto displayId = Case::Display::DISPLAY_ID::get();
-    ASSERT_TRUE(HalVirtualDisplayId::tryCast(displayId));
-    mFlinger.mutableHwcDisplayData().try_emplace(displayId);
+    ASSERT_TRUE(displayId);
+    mFlinger.mutableHwcDisplayData().try_emplace(*displayId);
     Case::Display::injectHwcDisplay(this);
     auto existing = Case::Display::makeFakeExistingDisplayInjector(this);
     existing.inject();
@@ -3518,8 +3485,8 @@
 
     // Insert display data so that the HWC thinks it created the virtual display.
     const auto displayId = Case::Display::DISPLAY_ID::get();
-    ASSERT_TRUE(HalVirtualDisplayId::tryCast(displayId));
-    mFlinger.mutableHwcDisplayData().try_emplace(displayId);
+    ASSERT_TRUE(displayId);
+    mFlinger.mutableHwcDisplayData().try_emplace(*displayId);
 
     // A virtual display device is set up
     Case::Display::injectHwcDisplay(this);
diff --git a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
index 0ea5ddc..37f159c 100644
--- a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
+++ b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
@@ -40,7 +40,6 @@
 #include "SurfaceInterceptor.h"
 #include "TestableScheduler.h"
 #include "mock/DisplayHardware/MockDisplay.h"
-#include "mock/MockDisplayIdGenerator.h"
 
 namespace android {
 
@@ -172,9 +171,6 @@
 
     SurfaceFlinger* flinger() { return mFlinger.get(); }
     TestableScheduler* scheduler() { return mScheduler; }
-    mock::DisplayIdGenerator<GpuVirtualDisplayId>& gpuVirtualDisplayIdGenerator() {
-        return mGpuVirtualDisplayIdGenerator;
-    }
 
     // Extend this as needed for accessing SurfaceFlinger private (and public)
     // functions.
@@ -467,8 +463,7 @@
         static constexpr hal::HWConfigId DEFAULT_ACTIVE_CONFIG = 0;
         static constexpr hal::PowerMode DEFAULT_POWER_MODE = hal::PowerMode::ON;
 
-        FakeHwcDisplayInjector(HalDisplayId displayId, hal::DisplayType hwcDisplayType,
-                               bool isPrimary)
+        FakeHwcDisplayInjector(DisplayId displayId, hal::DisplayType hwcDisplayType, bool isPrimary)
               : mDisplayId(displayId), mHwcDisplayType(hwcDisplayType), mIsPrimary(isPrimary) {}
 
         auto& setHwcDisplayId(hal::HWDisplayId displayId) {
@@ -541,16 +536,14 @@
             flinger->mutableHwcDisplayData()[mDisplayId].hwcDisplay = std::move(display);
 
             if (mHwcDisplayType == hal::DisplayType::PHYSICAL) {
-                const auto physicalId = PhysicalDisplayId::tryCast(mDisplayId);
-                LOG_ALWAYS_FATAL_IF(!physicalId);
-                flinger->mutableHwcPhysicalDisplayIdMap().emplace(mHwcDisplayId, *physicalId);
+                flinger->mutableHwcPhysicalDisplayIdMap().emplace(mHwcDisplayId, mDisplayId);
                 (mIsPrimary ? flinger->mutableInternalHwcDisplayId()
                             : flinger->mutableExternalHwcDisplayId()) = mHwcDisplayId;
             }
         }
 
     private:
-        const HalDisplayId mDisplayId;
+        const DisplayId mDisplayId;
         const hal::DisplayType mHwcDisplayType;
         const bool mIsPrimary;
 
@@ -642,10 +635,10 @@
             DisplayDeviceState state;
             if (const auto type = mCreationArgs.connectionType) {
                 LOG_ALWAYS_FATAL_IF(!displayId);
-                const auto physicalId = PhysicalDisplayId::tryCast(*displayId);
-                LOG_ALWAYS_FATAL_IF(!physicalId);
                 LOG_ALWAYS_FATAL_IF(!mHwcDisplayId);
-                state.physical = {.id = *physicalId, .type = *type, .hwcDisplayId = *mHwcDisplayId};
+                state.physical = {.id = static_cast<PhysicalDisplayId>(*displayId),
+                                  .type = *type,
+                                  .hwcDisplayId = *mHwcDisplayId};
             }
 
             state.isSecure = mCreationArgs.isSecure;
@@ -679,7 +672,6 @@
     sp<SurfaceFlinger> mFlinger = new SurfaceFlinger(mFactory, SurfaceFlinger::SkipInitialization);
     TestableScheduler* mScheduler = nullptr;
     Hwc2::mock::Display mDisplay;
-    mock::DisplayIdGenerator<GpuVirtualDisplayId> mGpuVirtualDisplayIdGenerator;
 };
 
 } // namespace android
diff --git a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockComposer.cpp b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockComposer.cpp
index 251ab36..0780af1 100644
--- a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockComposer.cpp
+++ b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockComposer.cpp
@@ -20,13 +20,17 @@
 
 #include "mock/DisplayHardware/MockComposer.h"
 
-namespace android::Hwc2::mock {
+namespace android {
+namespace Hwc2 {
+namespace mock {
 
 // Explicit default instantiation is recommended.
 Composer::Composer() = default;
 Composer::~Composer() = default;
 
-} // namespace android::Hwc2::mock
+} // namespace mock
+} // namespace Hwc2
+} // namespace android
 
 // TODO(b/129481165): remove the #pragma below and fix conversion issues
 #pragma clang diagnostic pop // ignored "-Wconversion"
diff --git a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockComposer.h b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockComposer.h
index 1ba3c0f..cd9b87a 100644
--- a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockComposer.h
+++ b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockComposer.h
@@ -24,7 +24,8 @@
 
 class GraphicBuffer;
 
-namespace Hwc2::mock {
+namespace Hwc2 {
+namespace mock {
 
 using android::hardware::graphics::common::V1_0::ColorTransform;
 using android::hardware::graphics::common::V1_0::Transform;
@@ -139,5 +140,6 @@
     MOCK_METHOD2(getClientTargetProperty, Error(Display, IComposerClient::ClientTargetProperty*));
 };
 
-} // namespace Hwc2::mock
+} // namespace mock
+} // namespace Hwc2
 } // namespace android
diff --git a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockDisplay.cpp b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockDisplay.cpp
index c9788af..2ec37c1 100644
--- a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockDisplay.cpp
+++ b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockDisplay.cpp
@@ -16,10 +16,14 @@
 
 #include "mock/DisplayHardware/MockDisplay.h"
 
-namespace android::Hwc2::mock {
+namespace android {
+namespace Hwc2 {
+namespace mock {
 
 // Explicit default instantiation is recommended.
 Display::Display() = default;
 Display::~Display() = default;
 
-} // namespace android::Hwc2::mock
\ No newline at end of file
+} // namespace mock
+} // namespace Hwc2
+} // namespace android
\ No newline at end of file
diff --git a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockDisplay.h b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockDisplay.h
index a96d9db..fe99e77 100644
--- a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockDisplay.h
+++ b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockDisplay.h
@@ -22,7 +22,9 @@
 
 using android::HWC2::Layer;
 
-namespace android::Hwc2::mock {
+namespace android {
+namespace Hwc2 {
+namespace mock {
 
 namespace hal = android::hardware::graphics::composer::hal;
 
@@ -96,4 +98,6 @@
     MOCK_CONST_METHOD0(isVsyncPeriodSwitchSupported, bool());
 };
 
-} // namespace android::Hwc2::mock
+} // namespace mock
+} // namespace Hwc2
+} // namespace android
diff --git a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockPowerAdvisor.cpp b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockPowerAdvisor.cpp
index 1ba38a8..8be7077 100644
--- a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockPowerAdvisor.cpp
+++ b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockPowerAdvisor.cpp
@@ -16,10 +16,14 @@
 
 #include "MockPowerAdvisor.h"
 
-namespace android::Hwc2::mock {
+namespace android {
+namespace Hwc2 {
+namespace mock {
 
 // Explicit default instantiation is recommended.
 PowerAdvisor::PowerAdvisor() = default;
 PowerAdvisor::~PowerAdvisor() = default;
 
-} // namespace android::Hwc2::mock
+} // namespace mock
+} // namespace Hwc2
+} // namespace android
diff --git a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockPowerAdvisor.h b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockPowerAdvisor.h
index 7450b5d..e22d0cf 100644
--- a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockPowerAdvisor.h
+++ b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockPowerAdvisor.h
@@ -20,7 +20,9 @@
 
 #include "DisplayHardware/PowerAdvisor.h"
 
-namespace android::Hwc2::mock {
+namespace android {
+namespace Hwc2 {
+namespace mock {
 
 class PowerAdvisor : public android::Hwc2::PowerAdvisor {
 public:
@@ -32,4 +34,6 @@
     MOCK_METHOD0(notifyDisplayUpdateImminent, void());
 };
 
-} // namespace android::Hwc2::mock
+} // namespace mock
+} // namespace Hwc2
+} // namespace android
diff --git a/services/surfaceflinger/tests/unittests/mock/MockDisplayIdGenerator.h b/services/surfaceflinger/tests/unittests/mock/MockDisplayIdGenerator.h
deleted file mode 100644
index cfc37ea..0000000
--- a/services/surfaceflinger/tests/unittests/mock/MockDisplayIdGenerator.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <gmock/gmock.h>
-
-#include "DisplayIdGenerator.h"
-
-namespace android::mock {
-
-template <typename T>
-class DisplayIdGenerator : public android::DisplayIdGenerator<T> {
-public:
-    // Explicit default instantiation is recommended.
-    DisplayIdGenerator() = default;
-    virtual ~DisplayIdGenerator() = default;
-
-    MOCK_METHOD0(nextId, std::optional<T>());
-    MOCK_METHOD1(markUnused, void(T));
-};
-
-} // namespace android::mock
diff --git a/services/surfaceflinger/tests/unittests/mock/MockEventThread.cpp b/services/surfaceflinger/tests/unittests/mock/MockEventThread.cpp
index 302dc01..408cd35 100644
--- a/services/surfaceflinger/tests/unittests/mock/MockEventThread.cpp
+++ b/services/surfaceflinger/tests/unittests/mock/MockEventThread.cpp
@@ -16,10 +16,12 @@
 
 #include "mock/MockEventThread.h"
 
-namespace android::mock {
+namespace android {
+namespace mock {
 
 // Explicit default instantiation is recommended.
 EventThread::EventThread() = default;
 EventThread::~EventThread() = default;
 
-} // namespace android::mock
+} // namespace mock
+} // namespace android
diff --git a/services/surfaceflinger/tests/unittests/mock/MockEventThread.h b/services/surfaceflinger/tests/unittests/mock/MockEventThread.h
index b4594c1..eefdec1 100644
--- a/services/surfaceflinger/tests/unittests/mock/MockEventThread.h
+++ b/services/surfaceflinger/tests/unittests/mock/MockEventThread.h
@@ -20,7 +20,8 @@
 
 #include "Scheduler/EventThread.h"
 
-namespace android::mock {
+namespace android {
+namespace mock {
 
 class EventThread : public android::EventThread {
 public:
@@ -46,4 +47,5 @@
     MOCK_METHOD0(getEventThreadConnectionCount, size_t());
 };
 
-} // namespace android::mock
+} // namespace mock
+} // namespace android
diff --git a/services/surfaceflinger/tests/unittests/mock/MockFrameTracer.cpp b/services/surfaceflinger/tests/unittests/mock/MockFrameTracer.cpp
index 417dcb0..358dfdb 100644
--- a/services/surfaceflinger/tests/unittests/mock/MockFrameTracer.cpp
+++ b/services/surfaceflinger/tests/unittests/mock/MockFrameTracer.cpp
@@ -16,10 +16,12 @@
 
 #include "mock/MockFrameTracer.h"
 
-namespace android::mock {
+namespace android {
+namespace mock {
 
 // Explicit default instantiation is recommended.
 FrameTracer::FrameTracer() = default;
 FrameTracer::~FrameTracer() = default;
 
-} // namespace android::mock
+} // namespace mock
+} // namespace android
diff --git a/services/surfaceflinger/tests/unittests/mock/MockFrameTracer.h b/services/surfaceflinger/tests/unittests/mock/MockFrameTracer.h
index 305cb1c..f768b81 100644
--- a/services/surfaceflinger/tests/unittests/mock/MockFrameTracer.h
+++ b/services/surfaceflinger/tests/unittests/mock/MockFrameTracer.h
@@ -20,7 +20,8 @@
 
 #include "FrameTracer/FrameTracer.h"
 
-namespace android::mock {
+namespace android {
+namespace mock {
 
 class FrameTracer : public android::FrameTracer {
 public:
@@ -38,4 +39,5 @@
     MOCK_METHOD0(miniDump, std::string());
 };
 
-} // namespace android::mock
+} // namespace mock
+} // namespace android
diff --git a/services/surfaceflinger/tests/unittests/mock/MockSurfaceInterceptor.cpp b/services/surfaceflinger/tests/unittests/mock/MockSurfaceInterceptor.cpp
index 0a0e7b5..7e925b9 100644
--- a/services/surfaceflinger/tests/unittests/mock/MockSurfaceInterceptor.cpp
+++ b/services/surfaceflinger/tests/unittests/mock/MockSurfaceInterceptor.cpp
@@ -20,13 +20,15 @@
 
 #include "mock/MockSurfaceInterceptor.h"
 
-namespace android::mock {
+namespace android {
+namespace mock {
 
 // Explicit default instantiation is recommended.
 SurfaceInterceptor::SurfaceInterceptor() = default;
 SurfaceInterceptor::~SurfaceInterceptor() = default;
 
-} // namespace android::mock
+} // namespace mock
+} // namespace android
 
 // TODO(b/129481165): remove the #pragma below and fix conversion issues
 #pragma clang diagnostic pop // ignored "-Wconversion"
diff --git a/services/surfaceflinger/tests/unittests/mock/MockSurfaceInterceptor.h b/services/surfaceflinger/tests/unittests/mock/MockSurfaceInterceptor.h
index b085027..03a04a9 100644
--- a/services/surfaceflinger/tests/unittests/mock/MockSurfaceInterceptor.h
+++ b/services/surfaceflinger/tests/unittests/mock/MockSurfaceInterceptor.h
@@ -20,7 +20,8 @@
 
 #include "SurfaceInterceptor.h"
 
-namespace android::mock {
+namespace android {
+namespace mock {
 
 class SurfaceInterceptor : public android::SurfaceInterceptor {
 public:
@@ -47,4 +48,5 @@
     MOCK_METHOD1(saveVSyncEvent, void(nsecs_t));
 };
 
-} // namespace android::mock
+} // namespace mock
+} // namespace android
diff --git a/services/surfaceflinger/tests/unittests/mock/MockTimeStats.cpp b/services/surfaceflinger/tests/unittests/mock/MockTimeStats.cpp
index f8e76b2..d686939 100644
--- a/services/surfaceflinger/tests/unittests/mock/MockTimeStats.cpp
+++ b/services/surfaceflinger/tests/unittests/mock/MockTimeStats.cpp
@@ -16,10 +16,12 @@
 
 #include "mock/MockTimeStats.h"
 
-namespace android::mock {
+namespace android {
+namespace mock {
 
 // Explicit default instantiation is recommended.
 TimeStats::TimeStats() = default;
 TimeStats::~TimeStats() = default;
 
-} // namespace android::mock
+} // namespace mock
+} // namespace android
diff --git a/services/surfaceflinger/tests/unittests/mock/MockTimeStats.h b/services/surfaceflinger/tests/unittests/mock/MockTimeStats.h
index ff37ec8..4186e2b 100644
--- a/services/surfaceflinger/tests/unittests/mock/MockTimeStats.h
+++ b/services/surfaceflinger/tests/unittests/mock/MockTimeStats.h
@@ -20,7 +20,8 @@
 
 #include "TimeStats/TimeStats.h"
 
-namespace android::mock {
+namespace android {
+namespace mock {
 
 class TimeStats : public android::TimeStats {
 public:
@@ -58,4 +59,5 @@
     MOCK_METHOD1(setPresentFenceGlobal, void(const std::shared_ptr<FenceTime>&));
 };
 
-} // namespace android::mock
+} // namespace mock
+} // namespace android
diff --git a/services/surfaceflinger/tests/unittests/mock/MockVSyncTracker.cpp b/services/surfaceflinger/tests/unittests/mock/MockVSyncTracker.cpp
index bcccae5..8a18123 100644
--- a/services/surfaceflinger/tests/unittests/mock/MockVSyncTracker.cpp
+++ b/services/surfaceflinger/tests/unittests/mock/MockVSyncTracker.cpp
@@ -15,11 +15,15 @@
  */
 
 #include "mock/MockVSyncTracker.h"
+#include <thread>
 
-namespace android::mock {
+using namespace std::chrono_literals;
+namespace android {
+namespace mock {
 
 // Explicit default instantiation is recommended.
 VSyncTracker::VSyncTracker() = default;
 VSyncTracker::~VSyncTracker() = default;
 
-} // namespace android::mock
+} // namespace mock
+} // namespace android
diff --git a/services/surfaceflinger/tests/unittests/mock/MockVsyncController.h b/services/surfaceflinger/tests/unittests/mock/MockVsyncController.h
index 94d9966..1d87546 100644
--- a/services/surfaceflinger/tests/unittests/mock/MockVsyncController.h
+++ b/services/surfaceflinger/tests/unittests/mock/MockVsyncController.h
@@ -20,7 +20,8 @@
 
 #include "Scheduler/VsyncController.h"
 
-namespace android::mock {
+namespace android {
+namespace mock {
 
 class VsyncController : public android::scheduler::VsyncController {
 public:
@@ -35,4 +36,5 @@
     MOCK_CONST_METHOD1(dump, void(std::string&));
 };
 
-} // namespace android::mock
+} // namespace mock
+} // namespace android