SF: Unify data types for display modes

Remove the RefreshRateConfigs::RefreshRate wrapper around DisplayMode.
Store DisplayModes as a SmallMap, so that RefreshRateConfigs uses the
same data structure for lookup by ID. Use iterators into that map for
all bookkeeping in RefreshRateConfigs.

Bug: 182939859
Bug: 185535769
Test: libsurfaceflinger_unittest
Change-Id: I7708fa997089802c45d906b17b7a073f5c82105e
diff --git a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
index fe0564e..aff4d83 100644
--- a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
+++ b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
@@ -45,6 +45,7 @@
 #include "SurfaceInterceptor.h"
 #include "TestableScheduler.h"
 #include "mock/DisplayHardware/MockComposer.h"
+#include "mock/DisplayHardware/MockDisplayMode.h"
 #include "mock/MockFrameTimeline.h"
 #include "mock/MockFrameTracer.h"
 #include "mock/MockSchedulerCallback.h"
@@ -227,31 +228,24 @@
         if (std::holds_alternative<RefreshRateConfigsPtr>(modesVariant)) {
             configs = std::move(std::get<RefreshRateConfigsPtr>(modesVariant));
         } else {
-            DisplayModes modes = {DisplayMode::Builder(0)
-                                          .setId(DisplayModeId(0))
-                                          .setPhysicalDisplayId(PhysicalDisplayId::fromPort(0))
-                                          .setVsyncPeriod(16'666'667)
-                                          .setGroup(0)
-                                          .build()};
+            constexpr DisplayModeId kModeId60{0};
+            DisplayModes modes = makeModes(mock::createDisplayMode(kModeId60, 60_Hz));
 
             if (std::holds_alternative<TwoDisplayModes>(modesVariant)) {
-                modes.emplace_back(DisplayMode::Builder(1)
-                                           .setId(DisplayModeId(1))
-                                           .setPhysicalDisplayId(PhysicalDisplayId::fromPort(0))
-                                           .setVsyncPeriod(11'111'111)
-                                           .setGroup(0)
-                                           .build());
+                constexpr DisplayModeId kModeId90{1};
+                modes.try_emplace(kModeId90, mock::createDisplayMode(kModeId90, 90_Hz));
             }
 
-            configs = std::make_shared<scheduler::RefreshRateConfigs>(modes, DisplayModeId(0));
+            configs = std::make_shared<scheduler::RefreshRateConfigs>(modes, kModeId60);
         }
 
-        const auto currFps = configs->getCurrentRefreshRate().getFps();
-        mFlinger->mVsyncConfiguration = mFactory.createVsyncConfiguration(currFps);
+        const auto fps = configs->getActiveMode()->getFps();
+        mFlinger->mVsyncConfiguration = mFactory.createVsyncConfiguration(fps);
         mFlinger->mVsyncModulator = sp<scheduler::VsyncModulator>::make(
                 mFlinger->mVsyncConfiguration->getCurrentConfigs());
+
         mFlinger->mRefreshRateStats =
-                std::make_unique<scheduler::RefreshRateStats>(*mFlinger->mTimeStats, currFps,
+                std::make_unique<scheduler::RefreshRateStats>(*mFlinger->mTimeStats, fps,
                                                               hal::PowerMode::OFF);
 
         using Callback = scheduler::ISchedulerCallback;
@@ -572,8 +566,7 @@
     class FakeHwcDisplayInjector {
     public:
         static constexpr hal::HWDisplayId DEFAULT_HWC_DISPLAY_ID = 1000;
-        static constexpr int32_t DEFAULT_WIDTH = 1920;
-        static constexpr int32_t DEFAULT_HEIGHT = 1280;
+        static constexpr ui::Size DEFAULT_RESOLUTION{1920, 1280};
         static constexpr int32_t DEFAULT_VSYNC_PERIOD = 16'666'667;
         static constexpr int32_t DEFAULT_CONFIG_GROUP = 7;
         static constexpr int32_t DEFAULT_DPI = 320;
@@ -589,17 +582,12 @@
             return *this;
         }
 
-        auto& setWidth(int32_t width) {
-            mWidth = width;
+        auto& setResolution(ui::Size resolution) {
+            mResolution = resolution;
             return *this;
         }
 
-        auto& setHeight(int32_t height) {
-            mHeight = height;
-            return *this;
-        }
-
-        auto& setVsyncPeriod(int32_t vsyncPeriod) {
+        auto& setVsyncPeriod(nsecs_t vsyncPeriod) {
             mVsyncPeriod = vsyncPeriod;
             return *this;
         }
@@ -660,18 +648,20 @@
 
             EXPECT_CALL(*composer,
                         getDisplayAttribute(mHwcDisplayId, mActiveConfig, hal::Attribute::WIDTH, _))
-                    .WillRepeatedly(DoAll(SetArgPointee<3>(mWidth), Return(hal::Error::NONE)));
+                    .WillRepeatedly(DoAll(SetArgPointee<3>(mResolution.getWidth()),
+                                          Return(hal::Error::NONE)));
 
             EXPECT_CALL(*composer,
                         getDisplayAttribute(mHwcDisplayId, mActiveConfig, hal::Attribute::HEIGHT,
                                             _))
-                    .WillRepeatedly(DoAll(SetArgPointee<3>(mHeight), Return(hal::Error::NONE)));
+                    .WillRepeatedly(DoAll(SetArgPointee<3>(mResolution.getHeight()),
+                                          Return(hal::Error::NONE)));
 
             EXPECT_CALL(*composer,
                         getDisplayAttribute(mHwcDisplayId, mActiveConfig,
                                             hal::Attribute::VSYNC_PERIOD, _))
-                    .WillRepeatedly(
-                            DoAll(SetArgPointee<3>(mVsyncPeriod), Return(hal::Error::NONE)));
+                    .WillRepeatedly(DoAll(SetArgPointee<3>(static_cast<int32_t>(mVsyncPeriod)),
+                                          Return(hal::Error::NONE)));
 
             EXPECT_CALL(*composer,
                         getDisplayAttribute(mHwcDisplayId, mActiveConfig, hal::Attribute::DPI_X, _))
@@ -708,9 +698,8 @@
         const bool mIsPrimary;
 
         hal::HWDisplayId mHwcDisplayId = DEFAULT_HWC_DISPLAY_ID;
-        int32_t mWidth = DEFAULT_WIDTH;
-        int32_t mHeight = DEFAULT_HEIGHT;
-        int32_t mVsyncPeriod = DEFAULT_VSYNC_PERIOD;
+        ui::Size mResolution = DEFAULT_RESOLUTION;
+        nsecs_t mVsyncPeriod = DEFAULT_VSYNC_PERIOD;
         int32_t mDpiX = DEFAULT_DPI;
         int32_t mDpiY = DEFAULT_DPI;
         int32_t mConfigGroup = DEFAULT_CONFIG_GROUP;
@@ -723,12 +712,12 @@
     class FakeDisplayDeviceInjector {
     public:
         FakeDisplayDeviceInjector(TestableSurfaceFlinger& flinger,
-                                  std::shared_ptr<compositionengine::Display> compositionDisplay,
+                                  std::shared_ptr<compositionengine::Display> display,
                                   std::optional<ui::DisplayConnectionType> connectionType,
                                   std::optional<hal::HWDisplayId> hwcDisplayId, bool isPrimary)
               : mFlinger(flinger),
                 mCreationArgs(flinger.mFlinger.get(), flinger.mFlinger->getHwComposer(),
-                              mDisplayToken, compositionDisplay),
+                              mDisplayToken, display),
                 mHwcDisplayId(hwcDisplayId) {
             mCreationArgs.connectionType = connectionType;
             mCreationArgs.isPrimary = isPrimary;
@@ -805,49 +794,52 @@
         }
 
         sp<DisplayDevice> inject() NO_THREAD_SAFETY_ANALYSIS {
+            const auto displayId = mCreationArgs.compositionDisplay->getDisplayId();
+
             auto& modes = mCreationArgs.supportedModes;
             auto& activeModeId = mCreationArgs.activeModeId;
 
-            if (!mCreationArgs.refreshRateConfigs) {
-                if (modes.empty()) {
-                    activeModeId = DisplayModeId(0);
-                    modes.emplace_back(
-                            DisplayMode::Builder(FakeHwcDisplayInjector::DEFAULT_ACTIVE_CONFIG)
-                                    .setId(activeModeId)
-                                    .setPhysicalDisplayId(PhysicalDisplayId::fromPort(0))
-                                    .setWidth(FakeHwcDisplayInjector::DEFAULT_WIDTH)
-                                    .setHeight(FakeHwcDisplayInjector::DEFAULT_HEIGHT)
-                                    .setVsyncPeriod(FakeHwcDisplayInjector::DEFAULT_VSYNC_PERIOD)
-                                    .setDpiX(FakeHwcDisplayInjector::DEFAULT_DPI)
-                                    .setDpiY(FakeHwcDisplayInjector::DEFAULT_DPI)
-                                    .setGroup(0)
-                                    .build());
-                }
+            if (displayId && !mCreationArgs.refreshRateConfigs) {
+                if (const auto physicalId = PhysicalDisplayId::tryCast(*displayId)) {
+                    if (modes.empty()) {
+                        constexpr DisplayModeId kModeId{0};
+                        DisplayModePtr mode =
+                                DisplayMode::Builder(FakeHwcDisplayInjector::DEFAULT_ACTIVE_CONFIG)
+                                        .setId(kModeId)
+                                        .setPhysicalDisplayId(*physicalId)
+                                        .setResolution(FakeHwcDisplayInjector::DEFAULT_RESOLUTION)
+                                        .setVsyncPeriod(
+                                                FakeHwcDisplayInjector::DEFAULT_VSYNC_PERIOD)
+                                        .setDpiX(FakeHwcDisplayInjector::DEFAULT_DPI)
+                                        .setDpiY(FakeHwcDisplayInjector::DEFAULT_DPI)
+                                        .setGroup(FakeHwcDisplayInjector::DEFAULT_CONFIG_GROUP)
+                                        .build();
 
-                mCreationArgs.refreshRateConfigs =
-                        std::make_shared<scheduler::RefreshRateConfigs>(modes, activeModeId);
+                        modes = ftl::init::map(kModeId, std::move(mode));
+                        activeModeId = kModeId;
+                    }
+
+                    mCreationArgs.refreshRateConfigs =
+                            std::make_shared<scheduler::RefreshRateConfigs>(modes, activeModeId);
+                }
             }
 
             DisplayDeviceState state;
             if (const auto type = mCreationArgs.connectionType) {
-                const auto displayId = mCreationArgs.compositionDisplay->getDisplayId();
                 LOG_ALWAYS_FATAL_IF(!displayId);
                 const auto physicalId = PhysicalDisplayId::tryCast(*displayId);
                 LOG_ALWAYS_FATAL_IF(!physicalId);
                 LOG_ALWAYS_FATAL_IF(!mHwcDisplayId);
 
-                const auto it = std::find_if(modes.begin(), modes.end(),
-                                             [&activeModeId](const DisplayModePtr& mode) {
-                                                 return mode->getId() == activeModeId;
-                                             });
-                LOG_ALWAYS_FATAL_IF(it == modes.end());
+                const auto activeMode = modes.get(activeModeId);
+                LOG_ALWAYS_FATAL_IF(!activeMode);
 
                 state.physical = {.id = *physicalId,
                                   .type = *type,
                                   .hwcDisplayId = *mHwcDisplayId,
                                   .deviceProductInfo = {},
                                   .supportedModes = modes,
-                                  .activeMode = *it};
+                                  .activeMode = activeMode->get()};
             }
 
             state.isSecure = mCreationArgs.isSecure;