SF: Define DisplayId as struct type

This prevents accidental mix-up with HWC display IDs, which have the
same backing type, as well as other implicitly convertible integers,
e.g. EDID manufacturer IDs. This CL also fixes misuses detected by
type checking:

1) Recycling of virtual display IDs.
2) Skipping composition for non-HWC virtual displays.
3) Unit tests for fallback/virtual display IDs.

Bug: 74619554
Bug: 119412688
Test: libsurfaceflinger_unittest
Test: vrflinger_test on walleye_xr
Change-Id: I0be41cc93c82860e859f1adf427430436c926595
diff --git a/services/surfaceflinger/BufferLayer.cpp b/services/surfaceflinger/BufferLayer.cpp
index 641bd8d..6ef3aef 100644
--- a/services/surfaceflinger/BufferLayer.cpp
+++ b/services/surfaceflinger/BufferLayer.cpp
@@ -231,15 +231,12 @@
 
 void BufferLayer::setPerFrameData(DisplayId displayId, const ui::Transform& transform,
                                   const Rect& viewport, int32_t supportedPerFrameMetadata) {
+    RETURN_IF_NO_HWC_LAYER(displayId);
+
     // Apply this display's projection's viewport to the visible region
     // before giving it to the HWC HAL.
     Region visible = transform.transform(visibleRegion.intersect(viewport));
 
-    if (!hasHwcLayer(displayId)) {
-        ALOGE("[%s] failed to setPerFrameData: no HWC layer found for display %" PRIu64,
-              mName.string(), displayId);
-        return;
-    }
     auto& hwcInfo = getBE().mHwcLayers[displayId];
     auto& hwcLayer = hwcInfo.layer;
     auto error = hwcLayer->setVisibleRegion(visible);
diff --git a/services/surfaceflinger/ColorLayer.cpp b/services/surfaceflinger/ColorLayer.cpp
index ad716ef..9c34308 100644
--- a/services/surfaceflinger/ColorLayer.cpp
+++ b/services/surfaceflinger/ColorLayer.cpp
@@ -59,13 +59,10 @@
 
 void ColorLayer::setPerFrameData(DisplayId displayId, const ui::Transform& transform,
                                  const Rect& viewport, int32_t /* supportedPerFrameMetadata */) {
+    RETURN_IF_NO_HWC_LAYER(displayId);
+
     Region visible = transform.transform(visibleRegion.intersect(viewport));
 
-    if (!hasHwcLayer(displayId)) {
-        ALOGE("[%s] failed to setPerFrameData: no HWC layer found for display %" PRIu64,
-              mName.string(), displayId);
-        return;
-    }
     auto& hwcInfo = getBE().mHwcLayers[displayId];
     auto& hwcLayer = hwcInfo.layer;
     auto error = hwcLayer->setVisibleRegion(visible);
diff --git a/services/surfaceflinger/DisplayDevice.cpp b/services/surfaceflinger/DisplayDevice.cpp
index 7c5c1bc..071f07d 100644
--- a/services/surfaceflinger/DisplayDevice.cpp
+++ b/services/surfaceflinger/DisplayDevice.cpp
@@ -647,7 +647,7 @@
 }
 
 std::string DisplayDevice::getDebugName() const {
-    const auto id = mId ? base::StringPrintf("%" PRIu64 ", ", *mId) : std::string();
+    const auto id = mId ? to_string(*mId) + ", " : std::string();
     return base::StringPrintf("DisplayDevice{%s%s%s\"%s\"}", id.c_str(),
                               isPrimary() ? "primary, " : "", isVirtual() ? "virtual, " : "",
                               mDisplayName.c_str());
diff --git a/services/surfaceflinger/DisplayHardware/DisplayIdentification.cpp b/services/surfaceflinger/DisplayHardware/DisplayIdentification.cpp
index ec240f3..ba7818d 100644
--- a/services/surfaceflinger/DisplayHardware/DisplayIdentification.cpp
+++ b/services/surfaceflinger/DisplayHardware/DisplayIdentification.cpp
@@ -64,12 +64,16 @@
     return letter < 'A' || letter > 'Z' ? '\0' : letter;
 }
 
-DisplayId getEdidDisplayId(uint8_t port, uint16_t manufacturerId, uint32_t displayNameHash) {
-    return (static_cast<DisplayId>(manufacturerId) << 40) |
-            (static_cast<DisplayId>(displayNameHash) << 8) | port;
+} // namespace
+
+uint16_t DisplayId::manufacturerId() const {
+    return static_cast<uint16_t>(value >> 40);
 }
 
-} // namespace
+DisplayId DisplayId::fromEdid(uint8_t port, uint16_t manufacturerId, uint32_t displayNameHash) {
+    return {(static_cast<Type>(manufacturerId) << 40) | (static_cast<Type>(displayNameHash) << 8) |
+            port};
+}
 
 bool isEdid(const DisplayIdentificationData& data) {
     const uint8_t kMagic[] = {0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0};
@@ -168,6 +172,10 @@
     return a && b && c ? std::make_optional(PnpId{a, b, c}) : std::nullopt;
 }
 
+std::optional<PnpId> getPnpId(DisplayId displayId) {
+    return getPnpId(displayId.manufacturerId());
+}
+
 std::optional<DisplayIdentificationInfo> parseDisplayIdentificationData(
         uint8_t port, const DisplayIdentificationData& data) {
     if (!isEdid(data)) {
@@ -183,16 +191,16 @@
     // Hash display name instead of using product code or serial number, since the latter have been
     // observed to change on some displays with multiple inputs.
     const auto hash = static_cast<uint32_t>(std::hash<std::string_view>()(edid->displayName));
-    return DisplayIdentificationInfo{getEdidDisplayId(port, edid->manufacturerId, hash),
+    return DisplayIdentificationInfo{DisplayId::fromEdid(port, edid->manufacturerId, hash),
                                      std::string(edid->displayName)};
 }
 
 DisplayId getFallbackDisplayId(uint8_t port) {
-    return getEdidDisplayId(port, kFallbackEdidManufacturerId, 0);
+    return DisplayId::fromEdid(port, kFallbackEdidManufacturerId, 0);
 }
 
 DisplayId getVirtualDisplayId(uint32_t id) {
-    return getEdidDisplayId(0, kVirtualEdidManufacturerId, id);
+    return DisplayId::fromEdid(0, kVirtualEdidManufacturerId, id);
 }
 
 } // namespace android
diff --git a/services/surfaceflinger/DisplayHardware/DisplayIdentification.h b/services/surfaceflinger/DisplayHardware/DisplayIdentification.h
index 1f2e789..1599995 100644
--- a/services/surfaceflinger/DisplayHardware/DisplayIdentification.h
+++ b/services/surfaceflinger/DisplayHardware/DisplayIdentification.h
@@ -25,7 +25,27 @@
 
 namespace android {
 
-using DisplayId = uint64_t;
+struct DisplayId {
+    using Type = uint64_t;
+    Type value;
+
+    uint16_t manufacturerId() const;
+
+    static DisplayId fromEdid(uint8_t port, uint16_t manufacturerId, uint32_t displayNameHash);
+};
+
+inline bool operator==(DisplayId lhs, DisplayId rhs) {
+    return lhs.value == rhs.value;
+}
+
+inline bool operator!=(DisplayId lhs, DisplayId rhs) {
+    return !(lhs == rhs);
+}
+
+inline std::string to_string(DisplayId displayId) {
+    return std::to_string(displayId.value);
+}
+
 using DisplayIdentificationData = std::vector<uint8_t>;
 
 struct DisplayIdentificationInfo {
@@ -45,6 +65,7 @@
 bool isEdid(const DisplayIdentificationData&);
 std::optional<Edid> parseEdid(const DisplayIdentificationData&);
 std::optional<PnpId> getPnpId(uint16_t manufacturerId);
+std::optional<PnpId> getPnpId(DisplayId);
 
 std::optional<DisplayIdentificationInfo> parseDisplayIdentificationData(
         uint8_t port, const DisplayIdentificationData&);
@@ -53,3 +74,14 @@
 DisplayId getVirtualDisplayId(uint32_t id);
 
 } // namespace android
+
+namespace std {
+
+template <>
+struct hash<android::DisplayId> {
+    size_t operator()(android::DisplayId displayId) const {
+        return hash<android::DisplayId::Type>()(displayId.value);
+    }
+};
+
+} // namespace std
diff --git a/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp b/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp
index f3f8d9d..27812f7 100644
--- a/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp
+++ b/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp
@@ -63,7 +63,7 @@
         mHasPendingRelease(false),
         mPreviousBufferSlot(BufferQueue::INVALID_BUFFER_SLOT),
         mPreviousBuffer() {
-    ALOGV("Creating for display %" PRIu64, displayId);
+    ALOGV("Creating for display %s", to_string(displayId).c_str());
 
     mName = "FramebufferSurface";
     mConsumer->setConsumerName(mName);
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
index 4c472b8..0f25b52 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
@@ -58,11 +58,11 @@
     ALOGE("%s failed for HWC display %" PRIu64 ": %s", __FUNCTION__, hwcDisplayId, msg)
 
 #define LOG_DISPLAY_ERROR(displayId, msg) \
-    ALOGE("%s failed for display %" PRIu64 ": %s", __FUNCTION__, displayId, msg)
+    ALOGE("%s failed for display %s: %s", __FUNCTION__, to_string(displayId).c_str(), msg)
 
-#define LOG_HWC_ERROR(what, error, displayId)                                              \
-    ALOGE("%s: %s failed for display %" PRIu64 ": %s (%d)", __FUNCTION__, what, displayId, \
-          to_string(error).c_str(), static_cast<int32_t>(error))
+#define LOG_HWC_ERROR(what, error, displayId)                          \
+    ALOGE("%s: %s failed for display %s: %s (%d)", __FUNCTION__, what, \
+          to_string(displayId).c_str(), to_string(error).c_str(), static_cast<int32_t>(error))
 
 #define RETURN_IF_INVALID_DISPLAY(displayId, ...)            \
     do {                                                     \
@@ -159,9 +159,9 @@
         if (!info) return {};
     }
 
-    ALOGV("%s: %s %s display %" PRIu64 " with HWC ID %" PRIu64, __FUNCTION__,
-          to_string(connection).c_str(),
-          hwcDisplayId == mInternalHwcDisplayId ? "internal" : "external", info->id, hwcDisplayId);
+    ALOGV("%s: %s %s display %s with HWC ID %" PRIu64, __FUNCTION__, to_string(connection).c_str(),
+          hwcDisplayId == mInternalHwcDisplayId ? "internal" : "external",
+          to_string(info->id).c_str(), hwcDisplayId);
 
     mHwcDevice->onHotplug(hwcDisplayId, connection);
 
@@ -198,15 +198,15 @@
         // is a bug in the HWC implementation, but filter the extra events
         // out here so they don't cause havoc downstream.
         if (timestamp == mLastHwVSync[*displayId]) {
-            ALOGW("Ignoring duplicate VSYNC event from HWC for display %" PRIu64 " (t=%" PRId64 ")",
-                  *displayId, timestamp);
+            ALOGW("Ignoring duplicate VSYNC event from HWC for display %s (t=%" PRId64 ")",
+                  to_string(*displayId).c_str(), timestamp);
             return false;
         }
 
         mLastHwVSync[*displayId] = timestamp;
     }
 
-    const auto tag = "HW_VSYNC_" + std::to_string(*displayId);
+    const auto tag = "HW_VSYNC_" + to_string(*displayId);
     ATRACE_INT(tag.c_str(), ++mVSyncCounts[*displayId] & 1);
 
     return true;
@@ -383,7 +383,7 @@
 
         displayData.vsyncEnabled = enabled;
 
-        const auto tag = "HW_VSYNC_ON_" + std::to_string(displayId);
+        const auto tag = "HW_VSYNC_ON_" + to_string(displayId);
         ATRACE_INT(tag.c_str(), enabled == HWC2::Vsync::Enable ? 1 : 0);
     }
 }
@@ -393,7 +393,7 @@
                                      ui::Dataspace dataspace) {
     RETURN_IF_INVALID_DISPLAY(displayId, BAD_INDEX);
 
-    ALOGV("setClientTarget for display %" PRIu64, displayId);
+    ALOGV("%s for display %s", __FUNCTION__, to_string(displayId).c_str());
     auto& hwcDisplay = mDisplayData[displayId].hwcDisplay;
     auto error = hwcDisplay->setClientTarget(slot, target, acquireFence, dataspace);
     RETURN_IF_HWC_ERROR(error, displayId, BAD_VALUE);
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.h b/services/surfaceflinger/DisplayHardware/HWComposer.h
index 5074c2c..b78433d 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.h
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.h
@@ -233,7 +233,7 @@
     cb_context* mCBContext = nullptr;
     std::unordered_map<DisplayId, size_t> mVSyncCounts;
 
-    std::unordered_set<uint32_t> mFreeVirtualDisplayIds;
+    std::unordered_set<DisplayId> mFreeVirtualDisplayIds;
     uint32_t mNextVirtualDisplayId = 0;
     uint32_t mRemainingHwcVirtualDisplays{mHwcDevice->getMaxVirtualDisplayCount()};
 
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index f41a753..010a339 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -197,8 +197,8 @@
 // ---------------------------------------------------------------------------
 
 bool Layer::createHwcLayer(HWComposer* hwc, DisplayId displayId) {
-    LOG_ALWAYS_FATAL_IF(getBE().mHwcLayers.count(displayId) != 0,
-                        "Already have a layer for display %" PRIu64, displayId);
+    LOG_ALWAYS_FATAL_IF(hasHwcLayer(displayId), "Already have a layer for display %s",
+                        to_string(displayId).c_str());
     auto layer = std::shared_ptr<HWC2::Layer>(
             hwc->createLayer(displayId),
             [hwc, displayId](HWC2::Layer* layer) {
@@ -215,7 +215,7 @@
 }
 
 bool Layer::destroyHwcLayer(DisplayId displayId) {
-    if (getBE().mHwcLayers.count(displayId) == 0) {
+    if (!hasHwcLayer(displayId)) {
         return false;
     }
     auto& hwcInfo = getBE().mHwcLayers[displayId];
@@ -462,11 +462,7 @@
 void Layer::setGeometry(const sp<const DisplayDevice>& display, uint32_t z) {
     const auto displayId = display->getId();
     LOG_ALWAYS_FATAL_IF(!displayId);
-    if (!hasHwcLayer(*displayId)) {
-        ALOGE("[%s] failed to setGeometry: no HWC layer found for display %" PRIu64, mName.string(),
-              *displayId);
-        return;
-    }
+    RETURN_IF_NO_HWC_LAYER(*displayId);
     auto& hwcInfo = getBE().mHwcLayers[*displayId];
 
     // enable this layer
@@ -634,27 +630,19 @@
 }
 
 void Layer::forceClientComposition(DisplayId displayId) {
-    if (getBE().mHwcLayers.count(displayId) == 0) {
-        ALOGE("forceClientComposition: no HWC layer found (display %" PRIu64 ")", displayId);
-        return;
-    }
-
+    RETURN_IF_NO_HWC_LAYER(displayId);
     getBE().mHwcLayers[displayId].forceClientComposition = true;
 }
 
 bool Layer::getForceClientComposition(DisplayId displayId) {
-    if (getBE().mHwcLayers.count(displayId) == 0) {
-        ALOGE("getForceClientComposition: no HWC layer found (display %" PRIu64 ")", displayId);
-        return false;
-    }
-
+    RETURN_IF_NO_HWC_LAYER(displayId, false);
     return getBE().mHwcLayers[displayId].forceClientComposition;
 }
 
 void Layer::updateCursorPosition(const sp<const DisplayDevice>& display) {
     const auto displayId = display->getId();
-    if (getBE().mHwcLayers.count(*displayId) == 0 ||
-        getCompositionType(displayId) != HWC2::Composition::Cursor) {
+    LOG_ALWAYS_FATAL_IF(!displayId);
+    if (!hasHwcLayer(*displayId) || getCompositionType(displayId) != HWC2::Composition::Cursor) {
         return;
     }
 
@@ -1422,7 +1410,7 @@
 }
 
 void Layer::miniDump(String8& result, DisplayId displayId) const {
-    if (getBE().mHwcLayers.count(displayId) == 0) {
+    if (!hasHwcLayer(displayId)) {
         return;
     }
 
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index ced6532..8ce67c3 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -499,7 +499,7 @@
     bool destroyHwcLayer(DisplayId displayId);
     void destroyAllHwcLayers();
 
-    bool hasHwcLayer(DisplayId displayId) { return getBE().mHwcLayers.count(displayId) > 0; }
+    bool hasHwcLayer(DisplayId displayId) const { return getBE().mHwcLayers.count(displayId) > 0; }
 
     HWC2::Layer* getHwcLayer(DisplayId displayId) {
         if (!hasHwcLayer(displayId)) {
@@ -784,8 +784,15 @@
                                           const std::vector<Layer*>& layersInTree);
 };
 
-// ---------------------------------------------------------------------------
+} // namespace android
 
-}; // namespace android
+#define RETURN_IF_NO_HWC_LAYER(displayId, ...)                                         \
+    do {                                                                               \
+        if (!hasHwcLayer(displayId)) {                                                 \
+            ALOGE("[%s] %s failed: no HWC layer found for display %s", mName.string(), \
+                  __FUNCTION__, to_string(displayId).c_str());                         \
+            return __VA_ARGS__;                                                        \
+        }                                                                              \
+    } while (false)
 
 #endif // ANDROID_LAYER_H
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 368b9b8..26de754 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -1043,9 +1043,9 @@
     LOG_ALWAYS_FATAL_IF(!displayId);
     getHwComposer().setActiveColorMode(*displayId, mode, renderIntent);
 
-    ALOGV("Set active color mode: %s (%d), active render intent: %s (%d), display=%" PRIu64,
+    ALOGV("Set active color mode: %s (%d), active render intent: %s (%d), display=%s",
           decodeColorMode(mode).c_str(), mode, decodeRenderIntent(renderIntent).c_str(),
-          renderIntent, *displayId);
+          renderIntent, to_string(*displayId).c_str());
 }
 
 status_t SurfaceFlinger::setActiveColorMode(const sp<IBinder>& displayToken, ColorMode mode) {
@@ -1640,8 +1640,8 @@
             display->setColorTransform(mDrawingState.colorMatrix);
             status_t result =
                     getHwComposer().setColorTransform(*displayId, mDrawingState.colorMatrix);
-            ALOGE_IF(result != NO_ERROR, "Failed to set color transform on display %" PRIu64 ": %d",
-                     *displayId, result);
+            ALOGE_IF(result != NO_ERROR, "Failed to set color transform on display %s: %d",
+                     to_string(*displayId).c_str(), result);
         }
         for (auto& layer : display->getVisibleLayersSortedByZ()) {
             if (layer->isHdrY410()) {
@@ -2275,7 +2275,7 @@
 
         if (event.connection == HWC2::Connection::Connected) {
             if (!mPhysicalDisplayTokens.count(info->id)) {
-                ALOGV("Creating display %" PRIu64, info->id);
+                ALOGV("Creating display %s", to_string(info->id).c_str());
                 mPhysicalDisplayTokens[info->id] = new BBinder();
                 DisplayDeviceState state;
                 state.displayId = info->id;
@@ -2285,7 +2285,7 @@
                 mInterceptor->saveDisplayCreation(state);
             }
         } else {
-            ALOGV("Removing display %" PRIu64, info->id);
+            ALOGV("Removing display %s", to_string(info->id).c_str());
 
             ssize_t index = mCurrentState.displays.indexOfKey(mPhysicalDisplayTokens[info->id]);
             if (index >= 0) {
@@ -2978,8 +2978,7 @@
     // 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)
-    bool isHwcDisplay = display->getId() >= 0;
-    if (!isHwcDisplay && inDirtyRegion.isEmpty()) {
+    if (!display->getId() && inDirtyRegion.isEmpty()) {
         ALOGV("Skipping display composition");
         return;
     }
@@ -3854,7 +3853,7 @@
     const auto displayId = display->getId();
     LOG_ALWAYS_FATAL_IF(!displayId);
 
-    ALOGD("Setting power mode %d on display %" PRIu64, mode, *displayId);
+    ALOGD("Setting power mode %d on display %s", mode, to_string(*displayId).c_str());
 
     int currentMode = display->getPowerMode();
     if (mode == currentMode) {
@@ -3953,7 +3952,7 @@
         mTimeStats.setPowerMode(mode);
     }
 
-    ALOGD("Finished setting power mode %d on display %" PRIu64, mode, *displayId);
+    ALOGD("Finished setting power mode %d on display %s", mode, to_string(*displayId).c_str());
 }
 
 void SurfaceFlinger::setPowerMode(const sp<IBinder>& displayToken, int mode) {
@@ -4284,7 +4283,7 @@
             continue;
         }
 
-        result.appendFormat("Display %" PRIu64 " (HWC display %" PRIu64 "): ", *displayId,
+        result.appendFormat("Display %s (HWC display %" PRIu64 "): ", to_string(*displayId).c_str(),
                             *hwcDisplayId);
         uint8_t port;
         DisplayIdentificationData data;
@@ -4332,7 +4331,7 @@
             continue;
         }
 
-        result.appendFormat("Display %" PRIu64 " color modes:\n", *displayId);
+        result.appendFormat("Display %s color modes:\n", to_string(*displayId).c_str());
         std::vector<ColorMode> modes = getHwComposer().getColorModes(*displayId);
         for (auto&& mode : modes) {
             result.appendFormat("    %s (%d)\n", decodeColorMode(mode).c_str(), mode);
@@ -4451,15 +4450,15 @@
     if (const auto displayId = getInternalDisplayId();
         displayId && getHwComposer().isConnected(*displayId)) {
         const auto activeConfig = getHwComposer().getActiveConfig(*displayId);
-        result.appendFormat("Display %" PRIu64 ": app phase %" PRId64 " ns, "
+        result.appendFormat("Display %s: app phase %" PRId64 " ns, "
                             "sf phase %" PRId64 " ns, "
                             "early app phase %" PRId64 " ns, "
                             "early sf phase %" PRId64 " ns, "
                             "early app gl phase %" PRId64 " ns, "
                             "early sf gl phase %" PRId64 " ns, "
                             "present offset %" PRId64 " ns (refresh %" PRId64 " ns)",
-                            *displayId, vsyncPhaseOffsetNs, sfVsyncPhaseOffsetNs, appEarlyOffset,
-                            sfEarlyOffset, appEarlyGlOffset, sfEarlyGlOffset,
+                            to_string(*displayId).c_str(), vsyncPhaseOffsetNs, sfVsyncPhaseOffsetNs,
+                            appEarlyOffset, sfEarlyOffset, appEarlyGlOffset, sfEarlyGlOffset,
                             dispSyncPresentTimeOffset, activeConfig->getVsyncPeriod());
     }
     result.append("\n");
@@ -4563,7 +4562,7 @@
             continue;
         }
 
-        result.appendFormat("Display %" PRIu64 " HWC layers:\n", *displayId);
+        result.appendFormat("Display %s HWC layers:\n", to_string(*displayId).c_str());
         Layer::miniDumpHeader(result);
         mCurrentState.traverseInZOrder([&](Layer* layer) { layer->miniDump(result, *displayId); });
         result.append("\n");
@@ -4604,7 +4603,7 @@
         }
     }
 
-    ALOGE("%s: Invalid display %" PRIu64, __FUNCTION__, displayId);
+    ALOGE("%s: Invalid display %s", __FUNCTION__, to_string(displayId).c_str());
     static const Vector<sp<Layer>> empty;
     return empty;
 }
diff --git a/services/surfaceflinger/SurfaceInterceptor.cpp b/services/surfaceflinger/SurfaceInterceptor.cpp
index 7faaff6..55cfa4b 100644
--- a/services/surfaceflinger/SurfaceInterceptor.cpp
+++ b/services/surfaceflinger/SurfaceInterceptor.cpp
@@ -497,7 +497,7 @@
     creation->set_name(info.displayName);
     creation->set_is_secure(info.isSecure);
     if (info.displayId) {
-        creation->set_display_id(*info.displayId);
+        creation->set_display_id(info.displayId->value);
     }
 }
 
diff --git a/services/surfaceflinger/tests/unittests/CompositionTest.cpp b/services/surfaceflinger/tests/unittests/CompositionTest.cpp
index 09bb8c5..de6420e 100644
--- a/services/surfaceflinger/tests/unittests/CompositionTest.cpp
+++ b/services/surfaceflinger/tests/unittests/CompositionTest.cpp
@@ -65,7 +65,7 @@
 constexpr hwc2_layer_t HWC_LAYER = 5000;
 constexpr Transform DEFAULT_TRANSFORM = static_cast<Transform>(0);
 
-constexpr DisplayId DEFAULT_DISPLAY_ID = 42;
+constexpr DisplayId DEFAULT_DISPLAY_ID = DisplayId{42};
 constexpr int DEFAULT_DISPLAY_WIDTH = 1920;
 constexpr int DEFAULT_DISPLAY_HEIGHT = 1024;
 
diff --git a/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp b/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp
index 2e90a59..9d17ef4 100644
--- a/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp
+++ b/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp
@@ -249,8 +249,8 @@
 template <typename PhysicalDisplay>
 struct PhysicalDisplayId {};
 
-template <DisplayId displayId>
-using VirtualDisplayId = std::integral_constant<DisplayId, displayId>;
+template <DisplayId::Type displayId>
+using VirtualDisplayId = std::integral_constant<DisplayId::Type, displayId>;
 
 struct NoDisplayId {};
 
@@ -279,9 +279,9 @@
     }
 };
 
-template <DisplayId displayId>
+template <DisplayId::Type displayId>
 struct DisplayIdGetter<VirtualDisplayId<displayId>> {
-    static std::optional<DisplayId> get() { return displayId; }
+    static std::optional<DisplayId> get() { return DisplayId{displayId}; }
 };
 
 template <>
@@ -1090,7 +1090,7 @@
  */
 class GetBestColorModeTest : public DisplayTransactionTest {
 public:
-    static constexpr DisplayId DEFAULT_DISPLAY_ID = 777;
+    static constexpr DisplayId DEFAULT_DISPLAY_ID = DisplayId{777};
 
     GetBestColorModeTest()
           : DisplayTransactionTest(),