SF: Remove StrongTyping in favor of FTL mixins

Bug: 185536303
Test: presubmit
Change-Id: I1a14abc565c5995c36fdd98c9fd35502b2ccceee
diff --git a/services/surfaceflinger/DisplayHardware/DisplayMode.h b/services/surfaceflinger/DisplayHardware/DisplayMode.h
index ba0825c..224f50e 100644
--- a/services/surfaceflinger/DisplayHardware/DisplayMode.h
+++ b/services/surfaceflinger/DisplayHardware/DisplayMode.h
@@ -21,17 +21,17 @@
 
 #include <android-base/stringprintf.h>
 #include <android/configuration.h>
+#include <ftl/mixins.h>
 #include <ftl/small_map.h>
 #include <ui/DisplayId.h>
 #include <ui/DisplayMode.h>
 #include <ui/Size.h>
 #include <utils/Timers.h>
 
+#include <common/FlagManager.h>
 #include <scheduler/Fps.h>
 
-#include <common/FlagManager.h>
 #include "DisplayHardware/Hal.h"
-#include "Scheduler/StrongTyping.h"
 
 namespace android {
 
@@ -46,7 +46,12 @@
 bool operator<=(const DisplayModePtr&, const DisplayModePtr&) = delete;
 bool operator>=(const DisplayModePtr&, const DisplayModePtr&) = delete;
 
-using DisplayModeId = StrongTyping<ui::DisplayModeId, struct DisplayModeIdTag, Compare>;
+struct DisplayModeId : ftl::DefaultConstructible<DisplayModeId, ui::DisplayModeId>,
+                       ftl::Incrementable<DisplayModeId>,
+                       ftl::Equatable<DisplayModeId>,
+                       ftl::Orderable<DisplayModeId> {
+    using DefaultConstructible::DefaultConstructible;
+};
 
 using DisplayModes = ftl::SmallMap<DisplayModeId, DisplayModePtr, 3>;
 using DisplayModeIterator = DisplayModes::const_iterator;
@@ -185,7 +190,7 @@
 inline std::string to_string(const DisplayMode& mode) {
     return base::StringPrintf("{id=%d, hwcId=%d, resolution=%dx%d, vsyncRate=%s, "
                               "dpi=%.2fx%.2f, group=%d, vrrConfig=%s}",
-                              mode.getId().value(), mode.getHwcId(), mode.getWidth(),
+                              ftl::to_underlying(mode.getId()), mode.getHwcId(), mode.getWidth(),
                               mode.getHeight(), to_string(mode.getVsyncRate()).c_str(),
                               mode.getDpi().x, mode.getDpi().y, mode.getGroup(),
                               to_string(mode.getVrrConfig()).c_str());
diff --git a/services/surfaceflinger/Scheduler/EventThread.cpp b/services/surfaceflinger/Scheduler/EventThread.cpp
index ccd1c0f..96eccf2 100644
--- a/services/surfaceflinger/Scheduler/EventThread.cpp
+++ b/services/surfaceflinger/Scheduler/EventThread.cpp
@@ -148,7 +148,7 @@
     DisplayEventReceiver::Event event;
     event.header = {DisplayEventReceiver::DISPLAY_EVENT_MODE_CHANGE,
                     mode.modePtr->getPhysicalDisplayId(), systemTime()};
-    event.modeChange.modeId = mode.modePtr->getId().value();
+    event.modeChange.modeId = ftl::to_underlying(mode.modePtr->getId());
     event.modeChange.vsyncPeriod = mode.fps.getPeriodNsecs();
     return event;
 }
diff --git a/services/surfaceflinger/Scheduler/RefreshRateSelector.cpp b/services/surfaceflinger/Scheduler/RefreshRateSelector.cpp
index 7614453..eeca6be 100644
--- a/services/surfaceflinger/Scheduler/RefreshRateSelector.cpp
+++ b/services/surfaceflinger/Scheduler/RefreshRateSelector.cpp
@@ -286,7 +286,8 @@
 std::string RefreshRateSelector::Policy::toString() const {
     return base::StringPrintf("{defaultModeId=%d, allowGroupSwitching=%s"
                               ", primaryRanges=%s, appRequestRanges=%s}",
-                              defaultMode.value(), allowGroupSwitching ? "true" : "false",
+                              ftl::to_underlying(defaultMode),
+                              allowGroupSwitching ? "true" : "false",
                               to_string(primaryRanges).c_str(),
                               to_string(appRequestRanges).c_str());
 }
diff --git a/services/surfaceflinger/Scheduler/RefreshRateSelector.h b/services/surfaceflinger/Scheduler/RefreshRateSelector.h
index a1a7c28..6051e89 100644
--- a/services/surfaceflinger/Scheduler/RefreshRateSelector.h
+++ b/services/surfaceflinger/Scheduler/RefreshRateSelector.h
@@ -31,7 +31,6 @@
 
 #include "DisplayHardware/DisplayMode.h"
 #include "Scheduler/OneShotTimer.h"
-#include "Scheduler/StrongTyping.h"
 #include "ThreadContext.h"
 #include "Utils/Dumper.h"
 
diff --git a/services/surfaceflinger/Scheduler/StrongTyping.h b/services/surfaceflinger/Scheduler/StrongTyping.h
deleted file mode 100644
index a05c123..0000000
--- a/services/surfaceflinger/Scheduler/StrongTyping.h
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Copyright 2019 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
-namespace android {
-
-template <typename T, template <typename> class AbilityType>
-struct Ability {
-    T& base() { return static_cast<T&>(*this); }
-    T const& base() const { return static_cast<T const&>(*this); }
-};
-
-template <typename T>
-struct Add : Ability<T, Add> {
-    inline T operator+(T const& other) const { return T(this->base().value() + other.value()); }
-    inline T& operator++() {
-        ++this->base().value();
-        return this->base();
-    };
-    inline T operator++(int) {
-        T tmp(this->base());
-        operator++();
-        return tmp;
-    };
-    inline T& operator+=(T const& other) {
-        this->base().value() += other.value();
-        return this->base();
-    };
-};
-
-template <typename T>
-struct Compare : Ability<T, Compare> {
-    inline bool operator==(T const& other) const { return this->base().value() == other.value(); };
-    inline bool operator<(T const& other) const { return this->base().value() < other.value(); }
-    inline bool operator<=(T const& other) const { return (*this < other) || (*this == other); }
-    inline bool operator!=(T const& other) const { return !(*this == other); }
-    inline bool operator>=(T const& other) const { return !(*this < other); }
-    inline bool operator>(T const& other) const { return !(*this < other || *this == other); }
-};
-
-template <typename T>
-struct Hash : Ability<T, Hash> {
-    [[nodiscard]] std::size_t hash() const {
-        return std::hash<typename std::remove_const<
-                typename std::remove_reference<decltype(this->base().value())>::type>::type>{}(
-                this->base().value());
-    }
-};
-
-template <typename T, typename W, template <typename> class... Ability>
-struct StrongTyping : Ability<StrongTyping<T, W, Ability...>>... {
-    constexpr StrongTyping() = default;
-    constexpr explicit StrongTyping(T const& value) : mValue(value) {}
-    StrongTyping(StrongTyping const&) = default;
-    StrongTyping& operator=(StrongTyping const&) = default;
-    explicit inline operator T() const { return mValue; }
-    T const& value() const { return mValue; }
-    T& value() { return mValue; }
-
-    friend std::ostream& operator<<(std::ostream& os, const StrongTyping<T, W, Ability...>& value) {
-        return os << value.value();
-    }
-
-private:
-    T mValue{0};
-};
-} // namespace android
-
-namespace std {
-template <typename T, typename W, template <typename> class... Ability>
-struct hash<android::StrongTyping<T, W, Ability...>> {
-    std::size_t operator()(android::StrongTyping<T, W, Ability...> const& k) const {
-        return k.hash();
-    }
-};
-} // namespace std
diff --git a/services/surfaceflinger/Scheduler/VSyncDispatch.h b/services/surfaceflinger/Scheduler/VSyncDispatch.h
index 434fc36..ed8f8fe 100644
--- a/services/surfaceflinger/Scheduler/VSyncDispatch.h
+++ b/services/surfaceflinger/Scheduler/VSyncDispatch.h
@@ -20,10 +20,9 @@
 #include <optional>
 #include <string>
 
+#include <ftl/mixins.h>
 #include <utils/Timers.h>
 
-#include "StrongTyping.h"
-
 namespace android::scheduler {
 
 using ScheduleResult = std::optional<nsecs_t>;
@@ -35,7 +34,11 @@
  */
 class VSyncDispatch {
 public:
-    using CallbackToken = StrongTyping<size_t, class CallbackTokenTag, Compare>;
+    struct CallbackToken : ftl::DefaultConstructible<CallbackToken, size_t>,
+                           ftl::Equatable<CallbackToken>,
+                           ftl::Incrementable<CallbackToken> {
+        using DefaultConstructible::DefaultConstructible;
+    };
 
     virtual ~VSyncDispatch();
 
diff --git a/services/surfaceflinger/Scheduler/VSyncDispatchTimerQueue.cpp b/services/surfaceflinger/Scheduler/VSyncDispatchTimerQueue.cpp
index 98aa533..963f9e9 100644
--- a/services/surfaceflinger/Scheduler/VSyncDispatchTimerQueue.cpp
+++ b/services/surfaceflinger/Scheduler/VSyncDispatchTimerQueue.cpp
@@ -352,7 +352,7 @@
         Callback callback, std::string callbackName) {
     std::lock_guard lock(mMutex);
     return mCallbacks
-            .try_emplace(CallbackToken{++mCallbackToken},
+            .try_emplace(++mCallbackToken,
                          std::make_shared<VSyncDispatchTimerQueueEntry>(std::move(callbackName),
                                                                         std::move(callback),
                                                                         mMinVsyncDistance))
diff --git a/services/surfaceflinger/Scheduler/VSyncDispatchTimerQueue.h b/services/surfaceflinger/Scheduler/VSyncDispatchTimerQueue.h
index 30e5242..81c746e 100644
--- a/services/surfaceflinger/Scheduler/VSyncDispatchTimerQueue.h
+++ b/services/surfaceflinger/Scheduler/VSyncDispatchTimerQueue.h
@@ -158,7 +158,7 @@
     nsecs_t const mTimerSlack;
     nsecs_t const mMinVsyncDistance;
 
-    size_t mCallbackToken GUARDED_BY(mMutex) = 0;
+    CallbackToken mCallbackToken GUARDED_BY(mMutex);
 
     CallbackMap mCallbacks GUARDED_BY(mMutex);
     nsecs_t mIntendedWakeupTime GUARDED_BY(mMutex) = kInvalidTime;
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 589ef99..d354e4b 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -1083,7 +1083,7 @@
 
     for (const auto& [id, mode] : displayModes) {
         ui::DisplayMode outMode;
-        outMode.id = static_cast<int32_t>(id.value());
+        outMode.id = ftl::to_underlying(id);
 
         auto [width, height] = mode->getResolution();
         auto [xDpi, yDpi] = mode->getDpi();
@@ -1132,7 +1132,7 @@
     const PhysicalDisplayId displayId = snapshot.displayId();
 
     const auto mode = display->refreshRateSelector().getActiveMode();
-    info->activeDisplayModeId = mode.modePtr->getId().value();
+    info->activeDisplayModeId = ftl::to_underlying(mode.modePtr->getId());
     info->renderFrameRate = mode.fps.getValue();
     info->activeColorMode = display->getCompositionDisplay()->getState().colorMode;
     info->hdrCapabilities = filterOut4k30(display->getHdrCapabilities());
@@ -1148,7 +1148,7 @@
     if (getHwComposer().hasCapability(Capability::BOOT_DISPLAY_CONFIG)) {
         if (const auto hwcId = getHwComposer().getPreferredBootDisplayMode(displayId)) {
             if (const auto modeId = snapshot.translateModeId(*hwcId)) {
-                info->preferredBootDisplayMode = modeId->value();
+                info->preferredBootDisplayMode = ftl::to_underlying(*modeId);
             }
         }
     }
@@ -1312,7 +1312,7 @@
                 [](const DisplayModePtr& mode) { return mode->getPeakFps(); });
 
         if (!fpsOpt) {
-            ALOGE("%s: Invalid mode %d for display %s", whence, modeId.value(),
+            ALOGE("%s: Invalid mode %d for display %s", whence, ftl::to_underlying(modeId),
                   to_string(snapshot.displayId()).c_str());
             return BAD_VALUE;
         }
@@ -1421,12 +1421,12 @@
 
         if (!displayModePtrOpt) {
             ALOGW("Desired display mode is no longer supported. Mode ID = %d",
-                  desiredModeId.value());
-            dropModeRequest(display);
+                  ftl::to_underlying(desiredModeId));
             continue;
         }
 
-        ALOGV("%s changing active mode to %d(%s) for display %s", __func__, desiredModeId.value(),
+        ALOGV("%s changing active mode to %d(%s) for display %s", __func__,
+              ftl::to_underlying(desiredModeId),
               to_string(displayModePtrOpt->get()->getVsyncRate()).c_str(),
               to_string(display->getId()).c_str());
 
@@ -1619,7 +1619,7 @@
                 [](const DisplayModePtr& mode) { return mode->getHwcId(); });
 
         if (!hwcIdOpt) {
-            ALOGE("%s: Invalid mode %d for display %s", whence, modeId.value(),
+            ALOGE("%s: Invalid mode %d for display %s", whence, ftl::to_underlying(modeId),
                   to_string(snapshot.displayId()).c_str());
             return BAD_VALUE;
         }
@@ -3393,15 +3393,15 @@
                                           })
                                           .value_or(DisplayModes{});
 
-    ui::DisplayModeId nextModeId = 1 +
-            std::accumulate(oldModes.begin(), oldModes.end(), static_cast<ui::DisplayModeId>(-1),
-                            [](ui::DisplayModeId max, const auto& pair) {
-                                return std::max(max, pair.first.value());
-                            });
+    DisplayModeId nextModeId = std::accumulate(oldModes.begin(), oldModes.end(), DisplayModeId(-1),
+                                               [](DisplayModeId max, const auto& pair) {
+                                                   return std::max(max, pair.first);
+                                               });
+    ++nextModeId;
 
     DisplayModes newModes;
     for (const auto& hwcMode : hwcModes) {
-        const DisplayModeId id{nextModeId++};
+        const auto id = nextModeId++;
         newModes.try_emplace(id,
                              DisplayMode::Builder(hwcMode.hwcId)
                                      .setId(id)
@@ -4182,8 +4182,8 @@
         if (display->refreshRateSelector().isModeAllowed(request.mode)) {
             setDesiredMode(std::move(request));
         } else {
-            ALOGV("%s: Mode %d is disallowed for display %s", __func__, modePtr->getId().value(),
-                  to_string(displayId).c_str());
+            ALOGV("%s: Mode %d is disallowed for display %s", __func__,
+                  ftl::to_underlying(modePtr->getId()), to_string(displayId).c_str());
         }
     }
 }
@@ -8477,11 +8477,11 @@
     const auto preferredModeId = preferredMode.modePtr->getId();
 
     const Fps preferredFps = preferredMode.fps;
-    ALOGV("Switching to Scheduler preferred mode %d (%s)", preferredModeId.value(),
+    ALOGV("Switching to Scheduler preferred mode %d (%s)", ftl::to_underlying(preferredModeId),
           to_string(preferredFps).c_str());
 
     if (!selector.isModeAllowed(preferredMode)) {
-        ALOGE("%s: Preferred mode %d is disallowed", __func__, preferredModeId.value());
+        ALOGE("%s: Preferred mode %d is disallowed", __func__, ftl::to_underlying(preferredModeId));
         return INVALID_OPERATION;
     }
 
@@ -8569,7 +8569,7 @@
 
     scheduler::RefreshRateSelector::Policy policy =
             display->refreshRateSelector().getDisplayManagerPolicy();
-    outSpecs->defaultMode = policy.defaultMode.value();
+    outSpecs->defaultMode = ftl::to_underlying(policy.defaultMode);
     outSpecs->allowGroupSwitching = policy.allowGroupSwitching;
     outSpecs->primaryRanges = translate(policy.primaryRanges);
     outSpecs->appRequestRanges = translate(policy.appRequestRanges);
diff --git a/services/surfaceflinger/tests/unittests/Android.bp b/services/surfaceflinger/tests/unittests/Android.bp
index 7c191a5..da4e47f 100644
--- a/services/surfaceflinger/tests/unittests/Android.bp
+++ b/services/surfaceflinger/tests/unittests/Android.bp
@@ -129,7 +129,6 @@
         "TransactionTraceWriterTest.cpp",
         "TransactionTracingTest.cpp",
         "TunnelModeEnabledReporterTest.cpp",
-        "StrongTypingTest.cpp",
         "VSyncCallbackRegistrationTest.cpp",
         "VSyncDispatchTimerQueueTest.cpp",
         "VSyncDispatchRealtimeTest.cpp",
diff --git a/services/surfaceflinger/tests/unittests/StrongTypingTest.cpp b/services/surfaceflinger/tests/unittests/StrongTypingTest.cpp
deleted file mode 100644
index 45b7610..0000000
--- a/services/surfaceflinger/tests/unittests/StrongTypingTest.cpp
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright 2019 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 <gmock/gmock.h>
-#include <gtest/gtest.h>
-#include "Scheduler/StrongTyping.h"
-
-using namespace testing;
-
-namespace android {
-
-TEST(StrongTypeTest, comparison) {
-    using SpunkyType = StrongTyping<int, struct SpunkyTypeTag, Compare>;
-    SpunkyType f1(10);
-
-    EXPECT_TRUE(f1 == f1);
-    EXPECT_TRUE(SpunkyType(10) != SpunkyType(11));
-    EXPECT_FALSE(SpunkyType(31) != SpunkyType(31));
-
-    EXPECT_TRUE(SpunkyType(10) < SpunkyType(11));
-    EXPECT_TRUE(SpunkyType(-1) < SpunkyType(0));
-    EXPECT_FALSE(SpunkyType(-10) < SpunkyType(-20));
-
-    EXPECT_TRUE(SpunkyType(10) <= SpunkyType(11));
-    EXPECT_TRUE(SpunkyType(10) <= SpunkyType(10));
-    EXPECT_TRUE(SpunkyType(-10) <= SpunkyType(1));
-    EXPECT_FALSE(SpunkyType(10) <= SpunkyType(9));
-
-    EXPECT_TRUE(SpunkyType(11) >= SpunkyType(11));
-    EXPECT_TRUE(SpunkyType(12) >= SpunkyType(11));
-    EXPECT_FALSE(SpunkyType(11) >= SpunkyType(12));
-
-    EXPECT_FALSE(SpunkyType(11) > SpunkyType(12));
-    EXPECT_TRUE(SpunkyType(-11) < SpunkyType(7));
-}
-
-TEST(StrongTypeTest, addition) {
-    using FunkyType = StrongTyping<int, struct FunkyTypeTag, Compare, Add>;
-    FunkyType f2(22);
-    FunkyType f1(10);
-
-    EXPECT_THAT(f1 + f2, Eq(FunkyType(32)));
-    EXPECT_THAT(f2 + f1, Eq(FunkyType(32)));
-
-    EXPECT_THAT(++f1.value(), Eq(11));
-    EXPECT_THAT(f1.value(), Eq(11));
-    EXPECT_THAT(f1++.value(), Eq(11));
-    EXPECT_THAT(f1++.value(), Eq(12));
-    EXPECT_THAT(f1.value(), Eq(13));
-
-    auto f3 = f1;
-    EXPECT_THAT(f1, Eq(f3));
-    EXPECT_THAT(f1, Lt(f2));
-
-    f3 += f1;
-    EXPECT_THAT(f1.value(), Eq(13));
-    EXPECT_THAT(f3.value(), Eq(26));
-}
-} // namespace android
diff --git a/services/surfaceflinger/tests/unittests/SurfaceFlinger_DisplayModeSwitching.cpp b/services/surfaceflinger/tests/unittests/SurfaceFlinger_DisplayModeSwitching.cpp
index 82b4ad0..15a6db6 100644
--- a/services/surfaceflinger/tests/unittests/SurfaceFlinger_DisplayModeSwitching.cpp
+++ b/services/surfaceflinger/tests/unittests/SurfaceFlinger_DisplayModeSwitching.cpp
@@ -28,6 +28,14 @@
 
 using namespace com::android::graphics::surfaceflinger;
 
+#define EXPECT_SET_ACTIVE_CONFIG(displayId, modeId)                                 \
+    EXPECT_CALL(*mComposer,                                                         \
+                setActiveConfigWithConstraints(displayId,                           \
+                                               static_cast<hal::HWConfigId>(        \
+                                                       ftl::to_underlying(modeId)), \
+                                               _, _))                               \
+            .WillOnce(DoAll(SetArgPointee<3>(timeline), Return(Error::NONE)))
+
 namespace android {
 namespace {
 
@@ -165,8 +173,7 @@
     mFlinger.onActiveDisplayChanged(nullptr, *mDisplay);
 
     mFlinger.setDesiredDisplayModeSpecs(mDisplay->getDisplayToken().promote(),
-                                        mock::createDisplayModeSpecs(kModeId90.value(), false, 0,
-                                                                     120));
+                                        mock::createDisplayModeSpecs(kModeId90, false, 0, 120));
 
     ASSERT_TRUE(mDisplay->getDesiredMode());
     EXPECT_EQ(mDisplay->getDesiredMode()->mode.modePtr->getId(), kModeId90);
@@ -174,10 +181,7 @@
 
     // Verify that next commit will call setActiveConfigWithConstraints in HWC
     const VsyncPeriodChangeTimeline timeline{.refreshRequired = true};
-    EXPECT_CALL(*mComposer,
-                setActiveConfigWithConstraints(PrimaryDisplayVariant::HWC_DISPLAY_ID,
-                                               hal::HWConfigId(kModeId90.value()), _, _))
-            .WillOnce(DoAll(SetArgPointee<3>(timeline), Return(Error::NONE)));
+    EXPECT_SET_ACTIVE_CONFIG(PrimaryDisplayVariant::HWC_DISPLAY_ID, kModeId90);
 
     mFlinger.commit();
 
@@ -206,8 +210,7 @@
     mFlinger.onActiveDisplayChanged(nullptr, *mDisplay);
 
     mFlinger.setDesiredDisplayModeSpecs(mDisplay->getDisplayToken().promote(),
-                                        mock::createDisplayModeSpecs(kModeId90.value(), true, 0,
-                                                                     120));
+                                        mock::createDisplayModeSpecs(kModeId90, true, 0, 120));
 
     ASSERT_TRUE(mDisplay->getDesiredMode());
     EXPECT_EQ(mDisplay->getDesiredMode()->mode.modePtr->getId(), kModeId90);
@@ -216,10 +219,7 @@
     // Verify that next commit will call setActiveConfigWithConstraints in HWC
     // and complete the mode change.
     const VsyncPeriodChangeTimeline timeline{.refreshRequired = false};
-    EXPECT_CALL(*mComposer,
-                setActiveConfigWithConstraints(PrimaryDisplayVariant::HWC_DISPLAY_ID,
-                                               hal::HWConfigId(kModeId90.value()), _, _))
-            .WillOnce(DoAll(SetArgPointee<3>(timeline), Return(Error::NONE)));
+    EXPECT_SET_ACTIVE_CONFIG(PrimaryDisplayVariant::HWC_DISPLAY_ID, kModeId90);
 
     EXPECT_CALL(*mAppEventThread,
                 onModeChanged(scheduler::FrameRateMode{90_Hz, ftl::as_non_null(kMode90)}));
@@ -242,28 +242,20 @@
     mFlinger.onActiveDisplayChanged(nullptr, *mDisplay);
 
     mFlinger.setDesiredDisplayModeSpecs(mDisplay->getDisplayToken().promote(),
-                                        mock::createDisplayModeSpecs(kModeId90.value(), false, 0,
-                                                                     120));
+                                        mock::createDisplayModeSpecs(kModeId90, false, 0, 120));
 
     const VsyncPeriodChangeTimeline timeline{.refreshRequired = true};
-    EXPECT_CALL(*mComposer,
-                setActiveConfigWithConstraints(PrimaryDisplayVariant::HWC_DISPLAY_ID,
-                                               hal::HWConfigId(kModeId90.value()), _, _))
-            .WillOnce(DoAll(SetArgPointee<3>(timeline), Return(Error::NONE)));
+    EXPECT_SET_ACTIVE_CONFIG(PrimaryDisplayVariant::HWC_DISPLAY_ID, kModeId90);
 
     mFlinger.commit();
 
     mFlinger.setDesiredDisplayModeSpecs(mDisplay->getDisplayToken().promote(),
-                                        mock::createDisplayModeSpecs(kModeId120.value(), false, 0,
-                                                                     180));
+                                        mock::createDisplayModeSpecs(kModeId120, false, 0, 180));
 
     ASSERT_TRUE(mDisplay->getDesiredMode());
     EXPECT_EQ(mDisplay->getDesiredMode()->mode.modePtr->getId(), kModeId120);
 
-    EXPECT_CALL(*mComposer,
-                setActiveConfigWithConstraints(PrimaryDisplayVariant::HWC_DISPLAY_ID,
-                                               hal::HWConfigId(kModeId120.value()), _, _))
-            .WillOnce(DoAll(SetArgPointee<3>(timeline), Return(Error::NONE)));
+    EXPECT_SET_ACTIVE_CONFIG(PrimaryDisplayVariant::HWC_DISPLAY_ID, kModeId120);
 
     mFlinger.commit();
 
@@ -285,8 +277,7 @@
     mFlinger.onActiveDisplayChanged(nullptr, *mDisplay);
 
     mFlinger.setDesiredDisplayModeSpecs(mDisplay->getDisplayToken().promote(),
-                                        mock::createDisplayModeSpecs(kModeId90_4K.value(), false, 0,
-                                                                     120));
+                                        mock::createDisplayModeSpecs(kModeId90_4K, false, 0, 120));
 
     ASSERT_TRUE(mDisplay->getDesiredMode());
     EXPECT_EQ(mDisplay->getDesiredMode()->mode.modePtr->getId(), kModeId90_4K);
@@ -295,10 +286,7 @@
     // Verify that next commit will call setActiveConfigWithConstraints in HWC
     // and complete the mode change.
     const VsyncPeriodChangeTimeline timeline{.refreshRequired = false};
-    EXPECT_CALL(*mComposer,
-                setActiveConfigWithConstraints(PrimaryDisplayVariant::HWC_DISPLAY_ID,
-                                               hal::HWConfigId(kModeId90_4K.value()), _, _))
-            .WillOnce(DoAll(SetArgPointee<3>(timeline), Return(Error::NONE)));
+    EXPECT_SET_ACTIVE_CONFIG(PrimaryDisplayVariant::HWC_DISPLAY_ID, kModeId90_4K);
 
     EXPECT_CALL(*mAppEventThread, onHotplugReceived(mDisplay->getPhysicalId(), true));
 
@@ -335,7 +323,7 @@
     }
 
     if (arg->getDesiredMode()->mode.modePtr->getId() != modeId) {
-        *result_listener << "Unexpected desired mode " << modeId;
+        *result_listener << "Unexpected desired mode " << ftl::to_underlying(modeId);
         return false;
     }
 
@@ -349,14 +337,15 @@
 
 MATCHER_P(ModeSettledTo, modeId, "") {
     if (const auto desiredOpt = arg->getDesiredMode()) {
-        *result_listener << "Unsettled desired mode " << desiredOpt->mode.modePtr->getId();
+        *result_listener << "Unsettled desired mode "
+                         << ftl::to_underlying(desiredOpt->mode.modePtr->getId());
         return false;
     }
 
     ftl::FakeGuard guard(kMainThreadContext);
 
     if (arg->getActiveMode().modePtr->getId() != modeId) {
-        *result_listener << "Settled to unexpected active mode " << modeId;
+        *result_listener << "Settled to unexpected active mode " << ftl::to_underlying(modeId);
         return false;
     }
 
@@ -387,22 +376,19 @@
 
     EXPECT_EQ(NO_ERROR,
               mFlinger.setDesiredDisplayModeSpecs(innerDisplay->getDisplayToken().promote(),
-                                                  mock::createDisplayModeSpecs(kModeId90.value(),
-                                                                               false, 0.f, 120.f)));
+                                                  mock::createDisplayModeSpecs(kModeId90, false,
+                                                                               0.f, 120.f)));
 
     EXPECT_EQ(NO_ERROR,
               mFlinger.setDesiredDisplayModeSpecs(outerDisplay->getDisplayToken().promote(),
-                                                  mock::createDisplayModeSpecs(kModeId60.value(),
-                                                                               false, 0.f, 120.f)));
+                                                  mock::createDisplayModeSpecs(kModeId60, false,
+                                                                               0.f, 120.f)));
 
     EXPECT_THAT(innerDisplay, ModeSwitchingTo(&mFlinger, kModeId90));
     EXPECT_THAT(outerDisplay, ModeSettledTo(kModeId120));
 
     const VsyncPeriodChangeTimeline timeline{.refreshRequired = true};
-    EXPECT_CALL(*mComposer,
-                setActiveConfigWithConstraints(kInnerDisplayHwcId,
-                                               hal::HWConfigId(kModeId90.value()), _, _))
-            .WillOnce(DoAll(SetArgPointee<3>(timeline), Return(Error::NONE)));
+    EXPECT_SET_ACTIVE_CONFIG(kInnerDisplayHwcId, kModeId90);
 
     mFlinger.commit();
 
@@ -423,10 +409,7 @@
     EXPECT_THAT(innerDisplay, ModeSettledTo(kModeId90));
     EXPECT_THAT(outerDisplay, ModeSwitchingTo(&mFlinger, kModeId60));
 
-    EXPECT_CALL(*mComposer,
-                setActiveConfigWithConstraints(kOuterDisplayHwcId,
-                                               hal::HWConfigId(kModeId60.value()), _, _))
-            .WillOnce(DoAll(SetArgPointee<3>(timeline), Return(Error::NONE)));
+    EXPECT_SET_ACTIVE_CONFIG(kOuterDisplayHwcId, kModeId60);
 
     mFlinger.commit();
 
@@ -464,27 +447,20 @@
 
     EXPECT_EQ(NO_ERROR,
               mFlinger.setDesiredDisplayModeSpecs(innerDisplay->getDisplayToken().promote(),
-                                                  mock::createDisplayModeSpecs(kModeId90.value(),
-                                                                               false, 0.f, 120.f)));
+                                                  mock::createDisplayModeSpecs(kModeId90, false,
+                                                                               0.f, 120.f)));
 
     EXPECT_EQ(NO_ERROR,
               mFlinger.setDesiredDisplayModeSpecs(outerDisplay->getDisplayToken().promote(),
-                                                  mock::createDisplayModeSpecs(kModeId60.value(),
-                                                                               false, 0.f, 120.f)));
+                                                  mock::createDisplayModeSpecs(kModeId60, false,
+                                                                               0.f, 120.f)));
 
     EXPECT_THAT(innerDisplay, ModeSwitchingTo(&mFlinger, kModeId90));
     EXPECT_THAT(outerDisplay, ModeSwitchingTo(&mFlinger, kModeId60));
 
     const VsyncPeriodChangeTimeline timeline{.refreshRequired = true};
-    EXPECT_CALL(*mComposer,
-                setActiveConfigWithConstraints(kInnerDisplayHwcId,
-                                               hal::HWConfigId(kModeId90.value()), _, _))
-            .WillOnce(DoAll(SetArgPointee<3>(timeline), Return(Error::NONE)));
-
-    EXPECT_CALL(*mComposer,
-                setActiveConfigWithConstraints(kOuterDisplayHwcId,
-                                               hal::HWConfigId(kModeId60.value()), _, _))
-            .WillOnce(DoAll(SetArgPointee<3>(timeline), Return(Error::NONE)));
+    EXPECT_SET_ACTIVE_CONFIG(kInnerDisplayHwcId, kModeId90);
+    EXPECT_SET_ACTIVE_CONFIG(kOuterDisplayHwcId, kModeId60);
 
     mFlinger.commit();
 
@@ -503,8 +479,8 @@
 
     EXPECT_EQ(NO_ERROR,
               mFlinger.setDesiredDisplayModeSpecs(mDisplay->getDisplayToken().promote(),
-                                                  mock::createDisplayModeSpecs(kModeId90.value(),
-                                                                               false, 0.f, 120.f)));
+                                                  mock::createDisplayModeSpecs(kModeId90, false,
+                                                                               0.f, 120.f)));
 
     EXPECT_THAT(mDisplay, ModeSwitchingTo(&mFlinger, kModeId90));
 
@@ -512,10 +488,7 @@
     mDisplay->setPowerMode(hal::PowerMode::OFF);
 
     const VsyncPeriodChangeTimeline timeline{.refreshRequired = true};
-    EXPECT_CALL(*mComposer,
-                setActiveConfigWithConstraints(kInnerDisplayHwcId,
-                                               hal::HWConfigId(kModeId90.value()), _, _))
-            .WillOnce(DoAll(SetArgPointee<3>(timeline), Return(Error::NONE)));
+    EXPECT_SET_ACTIVE_CONFIG(kInnerDisplayHwcId, kModeId90);
 
     mFlinger.commit();
 
@@ -554,13 +527,13 @@
 
     EXPECT_EQ(NO_ERROR,
               mFlinger.setDesiredDisplayModeSpecs(innerDisplay->getDisplayToken().promote(),
-                                                  mock::createDisplayModeSpecs(kModeId90.value(),
-                                                                               false, 0.f, 120.f)));
+                                                  mock::createDisplayModeSpecs(kModeId90, false,
+                                                                               0.f, 120.f)));
 
     EXPECT_EQ(NO_ERROR,
               mFlinger.setDesiredDisplayModeSpecs(outerDisplay->getDisplayToken().promote(),
-                                                  mock::createDisplayModeSpecs(kModeId60.value(),
-                                                                               false, 0.f, 120.f)));
+                                                  mock::createDisplayModeSpecs(kModeId60, false,
+                                                                               0.f, 120.f)));
 
     EXPECT_THAT(innerDisplay, ModeSwitchingTo(&mFlinger, kModeId90));
     EXPECT_THAT(outerDisplay, ModeSwitchingTo(&mFlinger, kModeId60));
@@ -569,10 +542,7 @@
     outerDisplay->setPowerMode(hal::PowerMode::OFF);
 
     const VsyncPeriodChangeTimeline timeline{.refreshRequired = true};
-    EXPECT_CALL(*mComposer,
-                setActiveConfigWithConstraints(kInnerDisplayHwcId,
-                                               hal::HWConfigId(kModeId90.value()), _, _))
-            .WillOnce(DoAll(SetArgPointee<3>(timeline), Return(Error::NONE)));
+    EXPECT_SET_ACTIVE_CONFIG(kInnerDisplayHwcId, kModeId90);
 
     mFlinger.commit();
 
@@ -591,10 +561,7 @@
     // Only the outer display is powered on.
     mFlinger.onActiveDisplayChanged(innerDisplay.get(), *outerDisplay);
 
-    EXPECT_CALL(*mComposer,
-                setActiveConfigWithConstraints(kOuterDisplayHwcId,
-                                               hal::HWConfigId(kModeId60.value()), _, _))
-            .WillOnce(DoAll(SetArgPointee<3>(timeline), Return(Error::NONE)));
+    EXPECT_SET_ACTIVE_CONFIG(kOuterDisplayHwcId, kModeId60);
 
     mFlinger.commit();
 
diff --git a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockDisplayMode.h b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockDisplayMode.h
index e298e7c..685d8f9 100644
--- a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockDisplayMode.h
+++ b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockDisplayMode.h
@@ -24,7 +24,7 @@
         DisplayModeId modeId, Fps displayRefreshRate, int32_t group = 0,
         ui::Size resolution = ui::Size(1920, 1080),
         PhysicalDisplayId displayId = PhysicalDisplayId::fromPort(0)) {
-    return DisplayMode::Builder(hal::HWConfigId(modeId.value()))
+    return DisplayMode::Builder(hal::HWConfigId(ftl::to_underlying(modeId)))
             .setId(modeId)
             .setPhysicalDisplayId(displayId)
             .setVsyncPeriod(displayRefreshRate.getPeriodNsecs())
diff --git a/services/surfaceflinger/tests/unittests/mock/MockDisplayModeSpecs.h b/services/surfaceflinger/tests/unittests/mock/MockDisplayModeSpecs.h
index a71e82c..7b18a82 100644
--- a/services/surfaceflinger/tests/unittests/mock/MockDisplayModeSpecs.h
+++ b/services/surfaceflinger/tests/unittests/mock/MockDisplayModeSpecs.h
@@ -18,12 +18,15 @@
 
 #include <android/gui/DisplayModeSpecs.h>
 
+#include "DisplayHardware/DisplayMode.h"
+
 namespace android::mock {
 
-inline gui::DisplayModeSpecs createDisplayModeSpecs(int32_t defaultMode, bool allowGroupSwitching,
-                                                    float minFps, float maxFps) {
+inline gui::DisplayModeSpecs createDisplayModeSpecs(DisplayModeId defaultMode,
+                                                    bool allowGroupSwitching, float minFps,
+                                                    float maxFps) {
     gui::DisplayModeSpecs specs;
-    specs.defaultMode = defaultMode;
+    specs.defaultMode = ftl::to_underlying(defaultMode);
     specs.allowGroupSwitching = allowGroupSwitching;
     specs.primaryRanges.physical.min = minFps;
     specs.primaryRanges.physical.max = maxFps;