Merge "Print window flags in dumpsys input"
diff --git a/libs/binder/Android.bp b/libs/binder/Android.bp
index bc241bf..e6cfeb4 100644
--- a/libs/binder/Android.bp
+++ b/libs/binder/Android.bp
@@ -73,9 +73,9 @@
     // or dessert updates. Instead, apex users should use libbinder_ndk.
     apex_available: [
         "//apex_available:platform",
-        // TODO(b/139016109) remove these
-        "com.android.media",
+        // TODO(b/139016109) remove these three
         "com.android.media.swcodec",
+        "test_com.android.media.swcodec",
     ],
 
     srcs: [
diff --git a/libs/binder/LazyServiceRegistrar.cpp b/libs/binder/LazyServiceRegistrar.cpp
index d4f26a1..325e204 100644
--- a/libs/binder/LazyServiceRegistrar.cpp
+++ b/libs/binder/LazyServiceRegistrar.cpp
@@ -45,25 +45,31 @@
     Status onClients(const sp<IBinder>& service, bool clients) override;
 
 private:
+    struct Service {
+        sp<IBinder> service;
+        bool allowIsolated;
+        int dumpFlags;
+
+        // whether, based on onClients calls, we know we have a client for this
+        // service or not
+        bool clients = false;
+    };
+
+    /**
+     * Looks up a service guaranteed to be registered (service from onClients).
+     */
+    std::map<std::string, Service>::iterator assertRegisteredService(const sp<IBinder>& service);
+
     /**
      * Unregisters all services that we can. If we can't unregister all, re-register other
      * services.
      */
     void tryShutdown();
 
-    /**
-     * Counter of the number of services that currently have at least one client.
-     */
+    // count of services with clients
     size_t mNumConnectedServices;
 
-    struct Service {
-        sp<IBinder> service;
-        bool allowIsolated;
-        int dumpFlags;
-    };
-    /**
-     * Map of registered names and services
-     */
+    // map of registered names and services
     std::map<std::string, Service> mRegisteredServices;
 
     bool mForcePersist;
@@ -82,19 +88,35 @@
         return false;
     }
 
-    if (!manager->registerClientCallback(name, service, this).isOk()) {
-        ALOGE("Failed to add client callback for service %s", name.c_str());
-        return false;
-    }
-
     if (!reRegister) {
+        if (!manager->registerClientCallback(name, service, this).isOk()) {
+            ALOGE("Failed to add client callback for service %s", name.c_str());
+            return false;
+        }
+
         // Only add this when a service is added for the first time, as it is not removed
-        mRegisteredServices[name] = {service, allowIsolated, dumpFlags};
+        mRegisteredServices[name] = {
+              .service = service,
+              .allowIsolated = allowIsolated,
+              .dumpFlags = dumpFlags
+        };
     }
 
     return true;
 }
 
+std::map<std::string, ClientCounterCallback::Service>::iterator ClientCounterCallback::assertRegisteredService(const sp<IBinder>& service) {
+    LOG_ALWAYS_FATAL_IF(service == nullptr, "Got onClients callback for null service");
+    for (auto it = mRegisteredServices.begin(); it != mRegisteredServices.end(); ++it) {
+        auto const& [name, registered] = *it;
+        (void) name;
+        if (registered.service != service) continue;
+        return it;
+    }
+    LOG_ALWAYS_FATAL("Got callback on service which we did not register: %s", String8(service->getInterfaceDescriptor()).c_str());
+    __builtin_unreachable();
+}
+
 void ClientCounterCallback::forcePersist(bool persist) {
     mForcePersist = persist;
     if(!mForcePersist) {
@@ -108,21 +130,25 @@
  * invocations could occur on different threads however.
  */
 Status ClientCounterCallback::onClients(const sp<IBinder>& service, bool clients) {
-    if (clients) {
-        mNumConnectedServices++;
-    } else {
-        mNumConnectedServices--;
+    auto & [name, registered] = *assertRegisteredService(service);
+    if (registered.clients == clients) {
+        LOG_ALWAYS_FATAL("Process already thought %s had clients: %d but servicemanager has "
+                         "notified has clients: %d", name.c_str(), registered.clients, clients);
+    }
+    registered.clients = clients;
+
+    // update cache count of clients
+    {
+         size_t numWithClients = 0;
+         for (const auto& [name, registered] : mRegisteredServices) {
+             (void) name;
+             if (registered.clients) numWithClients++;
+         }
+         mNumConnectedServices = numWithClients;
     }
 
-    // if this fails, we should switch this to keep track of clients inside
-    // of mRegisteredServices so that we know which service is double-counted.
-    LOG_ALWAYS_FATAL_IF(mNumConnectedServices > mRegisteredServices.size(),
-                        "Invalid state: %zu services have clients, but we only know about %zu",
-                        mNumConnectedServices, mRegisteredServices.size());
-
     ALOGI("Process has %zu (of %zu available) client(s) in use after notification %s has clients: %d",
-          mNumConnectedServices, mRegisteredServices.size(),
-          String8(service->getInterfaceDescriptor()).string(), clients);
+          mNumConnectedServices, mRegisteredServices.size(), name.c_str(), clients);
 
     tryShutdown();
     return Status::ok();
@@ -198,4 +224,4 @@
 }
 
 }  // namespace hardware
-}  // namespace android
\ No newline at end of file
+}  // namespace android
diff --git a/libs/binder/Status.cpp b/libs/binder/Status.cpp
index 674f065..64ab7a9 100644
--- a/libs/binder/Status.cpp
+++ b/libs/binder/Status.cpp
@@ -193,13 +193,15 @@
     }
 
     status_t status = parcel->writeInt32(mException);
-    if (status != OK) { return status; }
+    if (status != OK) return status;
     if (mException == EX_NONE) {
         // We have no more information to write.
         return status;
     }
     status = parcel->writeString16(String16(mMessage));
+    if (status != OK) return status;
     status = parcel->writeInt32(0); // Empty remote stack trace header
+    if (status != OK) return status;
     if (mException == EX_SERVICE_SPECIFIC) {
         status = parcel->writeInt32(mErrorCode);
     } else if (mException == EX_PARCELABLE) {
diff --git a/libs/binderthreadstate/Android.bp b/libs/binderthreadstate/Android.bp
index 1643fda..c186110 100644
--- a/libs/binderthreadstate/Android.bp
+++ b/libs/binderthreadstate/Android.bp
@@ -20,11 +20,6 @@
     vendor_available: true,
     host_supported: true,
 
-    apex_available: [
-        "//apex_available:platform",
-        "com.android.media",
-    ],
-
     shared_libs: [
         "libbinder",
         "libhidlbase",  // libhwbinder is in here
diff --git a/libs/gralloc/types/include/gralloctypes/Gralloc4.h b/libs/gralloc/types/include/gralloctypes/Gralloc4.h
index 5ec4d0d..8d12754 100644
--- a/libs/gralloc/types/include/gralloctypes/Gralloc4.h
+++ b/libs/gralloc/types/include/gralloctypes/Gralloc4.h
@@ -25,6 +25,7 @@
 #include <aidl/android/hardware/graphics/common/Interlaced.h>
 #include <aidl/android/hardware/graphics/common/PlaneLayout.h>
 #include <aidl/android/hardware/graphics/common/PlaneLayoutComponentType.h>
+#include <aidl/android/hardware/graphics/common/Rect.h>
 #include <aidl/android/hardware/graphics/common/Smpte2086.h>
 #include <aidl/android/hardware/graphics/common/StandardMetadataType.h>
 #include <aidl/android/hardware/graphics/common/XyColor.h>
diff --git a/libs/gui/sysprop/Android.bp b/libs/gui/sysprop/Android.bp
index d107ad6..e7f7c1f 100644
--- a/libs/gui/sysprop/Android.bp
+++ b/libs/gui/sysprop/Android.bp
@@ -1,10 +1,5 @@
 sysprop_library {
     name: "LibGuiProperties",
-    apex_available: [
-        "//apex_available:platform",
-        "com.android.media",
-        "com.android.media.swcodec",
-    ],
     srcs: ["*.sysprop"],
     api_packages: ["android.sysprop"],
     property_owner: "Platform",
diff --git a/libs/renderengine/gl/GLESRenderEngine.cpp b/libs/renderengine/gl/GLESRenderEngine.cpp
index 1c33945..da87092 100644
--- a/libs/renderengine/gl/GLESRenderEngine.cpp
+++ b/libs/renderengine/gl/GLESRenderEngine.cpp
@@ -793,35 +793,66 @@
     // top rectangle and the bottom rectangle, and turn off blending for the middle rectangle.
     FloatRect bounds = layer.geometry.roundedCornersCrop;
 
-    // Firstly, we need to convert the coordination from layer native coordination space to
-    // device coordination space.
-    // TODO(143929254): Verify that this transformation is correct
-    const auto transformMatrix = display.globalTransform * layer.geometry.positionTransform;
-    const vec4 leftTopCoordinate(bounds.left, bounds.top, 1.0, 1.0);
-    const vec4 rightBottomCoordinate(bounds.right, bounds.bottom, 1.0, 1.0);
-    const vec4 leftTopCoordinateInBuffer = transformMatrix * leftTopCoordinate;
-    const vec4 rightBottomCoordinateInBuffer = transformMatrix * rightBottomCoordinate;
-    bounds = FloatRect(leftTopCoordinateInBuffer[0], leftTopCoordinateInBuffer[1],
-                       rightBottomCoordinateInBuffer[0], rightBottomCoordinateInBuffer[1]);
-
-    // Secondly, if the display is rotated, we need to undo the rotation on coordination and
-    // align the (left, top) and (right, bottom) coordination with the device coordination
-    // space.
+    // Explicitly compute the transform from the clip rectangle to the physical
+    // display. Normally, this is done in glViewport but we explicitly compute
+    // it here so that we can get the scissor bounds correct.
+    const Rect& source = display.clip;
+    const Rect& destination = display.physicalDisplay;
+    // Here we compute the following transform:
+    // 1. Translate the top left corner of the source clip to (0, 0)
+    // 2. Rotate the clip rectangle about the origin in accordance with the
+    // orientation flag
+    // 3. Translate the top left corner back to the origin.
+    // 4. Scale the clip rectangle to the destination rectangle dimensions
+    // 5. Translate the top left corner to the destination rectangle's top left
+    // corner.
+    const mat4 translateSource = mat4::translate(vec4(-source.left, -source.top, 0, 1));
+    mat4 rotation;
+    int displacementX = 0;
+    int displacementY = 0;
+    float destinationWidth = static_cast<float>(destination.getWidth());
+    float destinationHeight = static_cast<float>(destination.getHeight());
+    float sourceWidth = static_cast<float>(source.getWidth());
+    float sourceHeight = static_cast<float>(source.getHeight());
+    const float rot90InRadians = 2.0f * static_cast<float>(M_PI) / 4.0f;
     switch (display.orientation) {
         case ui::Transform::ROT_90:
-            std::swap(bounds.left, bounds.right);
+            rotation = mat4::rotate(rot90InRadians, vec3(0, 0, 1));
+            displacementX = source.getHeight();
+            std::swap(sourceHeight, sourceWidth);
             break;
         case ui::Transform::ROT_180:
-            std::swap(bounds.left, bounds.right);
-            std::swap(bounds.top, bounds.bottom);
+            rotation = mat4::rotate(rot90InRadians * 2.0f, vec3(0, 0, 1));
+            displacementY = source.getHeight();
+            displacementX = source.getWidth();
             break;
         case ui::Transform::ROT_270:
-            std::swap(bounds.top, bounds.bottom);
+            rotation = mat4::rotate(rot90InRadians * 3.0f, vec3(0, 0, 1));
+            displacementY = source.getWidth();
+            std::swap(sourceHeight, sourceWidth);
             break;
         default:
             break;
     }
 
+    const mat4 intermediateTranslation = mat4::translate(vec4(displacementX, displacementY, 0, 1));
+    const mat4 scale = mat4::scale(
+            vec4(destinationWidth / sourceWidth, destinationHeight / sourceHeight, 1, 1));
+    const mat4 translateDestination =
+            mat4::translate(vec4(destination.left, destination.top, 0, 1));
+    const mat4 globalTransform =
+            translateDestination * scale * intermediateTranslation * rotation * translateSource;
+
+    const mat4 transformMatrix = globalTransform * layer.geometry.positionTransform;
+    const vec4 leftTopCoordinate(bounds.left, bounds.top, 1.0, 1.0);
+    const vec4 rightBottomCoordinate(bounds.right, bounds.bottom, 1.0, 1.0);
+    const vec4 leftTopCoordinateInBuffer = transformMatrix * leftTopCoordinate;
+    const vec4 rightBottomCoordinateInBuffer = transformMatrix * rightBottomCoordinate;
+    bounds = FloatRect(std::min(leftTopCoordinateInBuffer[0], rightBottomCoordinateInBuffer[0]),
+                       std::min(leftTopCoordinateInBuffer[1], rightBottomCoordinateInBuffer[1]),
+                       std::max(leftTopCoordinateInBuffer[0], rightBottomCoordinateInBuffer[0]),
+                       std::max(leftTopCoordinateInBuffer[1], rightBottomCoordinateInBuffer[1]));
+
     // Finally, we cut the layer into 3 parts, with top and bottom parts having rounded corners
     // and the middle part without rounded corners.
     const int32_t radius = ceil(layer.geometry.roundedCornersRadius);
diff --git a/libs/renderengine/gl/filters/BlurFilter.h b/libs/renderengine/gl/filters/BlurFilter.h
index 36e5a77..7e0819f 100644
--- a/libs/renderengine/gl/filters/BlurFilter.h
+++ b/libs/renderengine/gl/filters/BlurFilter.h
@@ -38,7 +38,7 @@
     // Downsample FBO to improve performance
     static constexpr float kFboScale = 0.25f;
     // Maximum number of render passes
-    static constexpr uint32_t kMaxPasses = 6;
+    static constexpr uint32_t kMaxPasses = 4;
     // To avoid downscaling artifacts, we interpolate the blurred fbo with the full composited
     // image, up to this radius.
     static constexpr float kMaxCrossFadeRadius = 30.0f;
diff --git a/libs/renderengine/include/renderengine/DisplaySettings.h b/libs/renderengine/include/renderengine/DisplaySettings.h
index c0766ab..ca16d2c 100644
--- a/libs/renderengine/include/renderengine/DisplaySettings.h
+++ b/libs/renderengine/include/renderengine/DisplaySettings.h
@@ -40,16 +40,6 @@
     // z=1.
     Rect clip = Rect::INVALID_RECT;
 
-    // Global transform to apply to all layers.
-    // The global transform is assumed to automatically apply when projecting
-    // the clip rectangle onto the physical display; however, this should be
-    // explicitly provided to perform CPU-side optimizations such as computing
-    // scissor rectangles for rounded corners which require transformation to
-    // the phsical display space.
-    //
-    // This transform is also assumed to include the orientation flag below.
-    mat4 globalTransform = mat4();
-
     // Maximum luminance pulled from the display's HDR capabilities.
     float maxLuminance = 1.0f;
 
@@ -62,9 +52,7 @@
     mat4 colorTransform = mat4();
 
     // Region that will be cleared to (0, 0, 0, 1) prior to rendering.
-    // RenderEngine will transform the clearRegion passed in here, by
-    // globalTransform, so that it will be in the same coordinate space as the
-    // rendered layers.
+    // This is specified in layer-stack space.
     Region clearRegion = Region::INVALID_REGION;
 
     // An additional orientation flag to be applied after clipping the output.
@@ -76,8 +64,7 @@
 
 static inline bool operator==(const DisplaySettings& lhs, const DisplaySettings& rhs) {
     return lhs.physicalDisplay == rhs.physicalDisplay && lhs.clip == rhs.clip &&
-            lhs.globalTransform == rhs.globalTransform && lhs.maxLuminance == rhs.maxLuminance &&
-            lhs.outputDataspace == rhs.outputDataspace &&
+            lhs.maxLuminance == rhs.maxLuminance && lhs.outputDataspace == rhs.outputDataspace &&
             lhs.colorTransform == rhs.colorTransform &&
             lhs.clearRegion.hasSameRects(rhs.clearRegion) && lhs.orientation == rhs.orientation;
 }
@@ -89,7 +76,6 @@
     PrintTo(settings.physicalDisplay, os);
     *os << "\n    .clip = ";
     PrintTo(settings.clip, os);
-    *os << "\n    .globalTransform = " << settings.globalTransform;
     *os << "\n    .maxLuminance = " << settings.maxLuminance;
     *os << "\n    .outputDataspace = ";
     PrintTo(settings.outputDataspace, os);
diff --git a/libs/renderengine/tests/RenderEngineTest.cpp b/libs/renderengine/tests/RenderEngineTest.cpp
index 1104c87..2bf456b 100644
--- a/libs/renderengine/tests/RenderEngineTest.cpp
+++ b/libs/renderengine/tests/RenderEngineTest.cpp
@@ -924,7 +924,6 @@
     settings.physicalDisplay = fullscreenRect();
     // Here logical space is 4x4
     settings.clip = Rect(4, 4);
-    settings.globalTransform = mat4::scale(vec4(2, 4, 0, 1));
     settings.clearRegion = Region(Rect(2, 4));
     std::vector<const renderengine::LayerSettings*> layers;
     // dummy layer, without bounds should not render anything
diff --git a/libs/ui/Gralloc4.cpp b/libs/ui/Gralloc4.cpp
index d8e4059..f799ce4 100644
--- a/libs/ui/Gralloc4.cpp
+++ b/libs/ui/Gralloc4.cpp
@@ -203,7 +203,7 @@
     std::vector<ui::PlaneLayout> planeLayouts;
     status_t err = getPlaneLayouts(bufferHandle, &planeLayouts);
 
-    if (err != NO_ERROR && !planeLayouts.empty()) {
+    if (err == NO_ERROR && !planeLayouts.empty()) {
         if (outBytesPerPixel) {
             int32_t bitsPerPixel = planeLayouts.front().sampleIncrementInBits;
             for (const auto& planeLayout : planeLayouts) {
diff --git a/opengl/libs/EGL/FileBlobCache.cpp b/opengl/libs/EGL/FileBlobCache.cpp
index cc42ac7..96a29e1 100644
--- a/opengl/libs/EGL/FileBlobCache.cpp
+++ b/opengl/libs/EGL/FileBlobCache.cpp
@@ -17,11 +17,12 @@
 #include "FileBlobCache.h"
 
 #include <errno.h>
+#include <fcntl.h>
 #include <inttypes.h>
-#include <log/log.h>
 #include <sys/mman.h>
 #include <sys/stat.h>
 
+#include <log/log.h>
 
 // Cache file header
 static const char* cacheFileMagic = "EGL$";
diff --git a/services/surfaceflinger/BufferLayer.cpp b/services/surfaceflinger/BufferLayer.cpp
index 5f90566..54cd04f 100644
--- a/services/surfaceflinger/BufferLayer.cpp
+++ b/services/surfaceflinger/BufferLayer.cpp
@@ -294,6 +294,7 @@
     auto* compositionState = editCompositionState();
     if (compositionState->sidebandStream.get()) {
         compositionState->compositionType = Hwc2::IComposerClient::Composition::SIDEBAND;
+        return;
     } else {
         // Normal buffer layers
         compositionState->hdrMetadata = mBufferInfo.mHdrMetadata;
@@ -301,6 +302,12 @@
                 ? Hwc2::IComposerClient::Composition::CURSOR
                 : Hwc2::IComposerClient::Composition::DEVICE;
     }
+
+    compositionState->buffer = mBufferInfo.mBuffer;
+    compositionState->bufferSlot = (mBufferInfo.mBufferSlot == BufferQueue::INVALID_BUFFER_SLOT)
+            ? 0
+            : mBufferInfo.mBufferSlot;
+    compositionState->acquireFence = mBufferInfo.mFence;
 }
 
 bool BufferLayer::onPreComposition(nsecs_t refreshStartTime) {
diff --git a/services/surfaceflinger/BufferQueueLayer.cpp b/services/surfaceflinger/BufferQueueLayer.cpp
index c84b15d..f4e630e 100644
--- a/services/surfaceflinger/BufferQueueLayer.cpp
+++ b/services/surfaceflinger/BufferQueueLayer.cpp
@@ -365,21 +365,6 @@
     return NO_ERROR;
 }
 
-void BufferQueueLayer::preparePerFrameCompositionState() {
-    BufferLayer::preparePerFrameCompositionState();
-
-    auto* compositionState = editCompositionState();
-    if (compositionState->compositionType == Hwc2::IComposerClient::Composition::SIDEBAND) {
-        return;
-    }
-
-    compositionState->buffer = mBufferInfo.mBuffer;
-    compositionState->bufferSlot = (mBufferInfo.mBufferSlot == BufferQueue::INVALID_BUFFER_SLOT)
-            ? 0
-            : mBufferInfo.mBufferSlot;
-    compositionState->acquireFence = mBufferInfo.mFence;
-}
-
 // -----------------------------------------------------------------------
 // Interface implementation for BufferLayerConsumer::ContentsChangedListener
 // -----------------------------------------------------------------------
diff --git a/services/surfaceflinger/BufferQueueLayer.h b/services/surfaceflinger/BufferQueueLayer.h
index ea7f203..16b4b6e 100644
--- a/services/surfaceflinger/BufferQueueLayer.h
+++ b/services/surfaceflinger/BufferQueueLayer.h
@@ -82,7 +82,6 @@
     status_t updateActiveBuffer() override;
     status_t updateFrameNumber(nsecs_t latchTime) override;
 
-    void preparePerFrameCompositionState() override;
     sp<Layer> createClone() override;
 
     void onFrameAvailable(const BufferItem& item);
diff --git a/services/surfaceflinger/BufferStateLayer.cpp b/services/surfaceflinger/BufferStateLayer.cpp
index 3e65171..a121ce0 100644
--- a/services/surfaceflinger/BufferStateLayer.cpp
+++ b/services/surfaceflinger/BufferStateLayer.cpp
@@ -631,19 +631,6 @@
     return NO_ERROR;
 }
 
-void BufferStateLayer::preparePerFrameCompositionState() {
-    BufferLayer::preparePerFrameCompositionState();
-
-    auto* compositionState = editCompositionState();
-    if (compositionState->compositionType == Hwc2::IComposerClient::Composition::SIDEBAND) {
-        return;
-    }
-
-    compositionState->buffer = mBufferInfo.mBuffer;
-    compositionState->bufferSlot = mBufferInfo.mBufferSlot;
-    compositionState->acquireFence = mBufferInfo.mFence;
-}
-
 void BufferStateLayer::HwcSlotGenerator::bufferErased(const client_cache_t& clientCacheId) {
     std::lock_guard lock(mMutex);
     if (!clientCacheId.isValid()) {
diff --git a/services/surfaceflinger/BufferStateLayer.h b/services/surfaceflinger/BufferStateLayer.h
index 753a742..5873a73 100644
--- a/services/surfaceflinger/BufferStateLayer.h
+++ b/services/surfaceflinger/BufferStateLayer.h
@@ -138,7 +138,6 @@
     status_t updateActiveBuffer() override;
     status_t updateFrameNumber(nsecs_t latchTime) override;
 
-    void preparePerFrameCompositionState() override;
     sp<Layer> createClone() override;
 
     // Crop that applies to the buffer
diff --git a/services/surfaceflinger/CompositionEngine/src/Display.cpp b/services/surfaceflinger/CompositionEngine/src/Display.cpp
index c345405..308ec5a 100644
--- a/services/surfaceflinger/CompositionEngine/src/Display.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/Display.cpp
@@ -268,12 +268,9 @@
 }
 
 bool Display::getSkipColorTransform() const {
-    if (!mId) {
-        return false;
-    }
-
-    auto& hwc = getCompositionEngine().getHwComposer();
-    return hwc.hasDisplayCapability(*mId, HWC2::DisplayCapability::SkipClientColorTransform);
+    const auto& hwc = getCompositionEngine().getHwComposer();
+    return mId ? hwc.hasDisplayCapability(*mId, HWC2::DisplayCapability::SkipClientColorTransform)
+               : hwc.hasCapability(HWC2::Capability::SkipClientColorTransform);
 }
 
 bool Display::anyLayersRequireClientComposition() const {
diff --git a/services/surfaceflinger/CompositionEngine/src/Output.cpp b/services/surfaceflinger/CompositionEngine/src/Output.cpp
index 7929beb..b7ea089 100644
--- a/services/surfaceflinger/CompositionEngine/src/Output.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/Output.cpp
@@ -829,7 +829,6 @@
     renderengine::DisplaySettings clientCompositionDisplay;
     clientCompositionDisplay.physicalDisplay = outputState.destinationClip;
     clientCompositionDisplay.clip = outputState.sourceClip;
-    clientCompositionDisplay.globalTransform = outputState.transform.asMatrix4();
     clientCompositionDisplay.orientation = outputState.orientation;
     clientCompositionDisplay.outputDataspace = mDisplayColorProfile->hasWideColorGamut()
             ? outputState.dataspace
diff --git a/services/surfaceflinger/CompositionEngine/tests/DisplayTest.cpp b/services/surfaceflinger/CompositionEngine/tests/DisplayTest.cpp
index 88f2686..f73a6f7 100644
--- a/services/surfaceflinger/CompositionEngine/tests/DisplayTest.cpp
+++ b/services/surfaceflinger/CompositionEngine/tests/DisplayTest.cpp
@@ -681,15 +681,17 @@
 
 using DisplayGetSkipColorTransformTest = DisplayWithLayersTestCommon;
 
-TEST_F(DisplayGetSkipColorTransformTest, doesNothingIfNonHwcDisplay) {
+TEST_F(DisplayGetSkipColorTransformTest, checksCapabilityIfNonHwcDisplay) {
+    EXPECT_CALL(mHwComposer, hasCapability(HWC2::Capability::SkipClientColorTransform))
+            .WillOnce(Return(true));
     auto args = getDisplayCreationArgsForNonHWCVirtualDisplay();
     auto nonHwcDisplay{impl::createDisplay(mCompositionEngine, args)};
-    EXPECT_FALSE(nonHwcDisplay->getSkipColorTransform());
+    EXPECT_TRUE(nonHwcDisplay->getSkipColorTransform());
 }
 
-TEST_F(DisplayGetSkipColorTransformTest, checksHwcCapability) {
+TEST_F(DisplayGetSkipColorTransformTest, checksDisplayCapability) {
     EXPECT_CALL(mHwComposer,
-                hasDisplayCapability(std::make_optional(DEFAULT_DISPLAY_ID),
+                hasDisplayCapability(DEFAULT_DISPLAY_ID,
                                      HWC2::DisplayCapability::SkipClientColorTransform))
             .WillOnce(Return(true));
     EXPECT_TRUE(mDisplay->getSkipColorTransform());
diff --git a/services/surfaceflinger/CompositionEngine/tests/MockHWComposer.h b/services/surfaceflinger/CompositionEngine/tests/MockHWComposer.h
index 88f6649..52bd6a1 100644
--- a/services/surfaceflinger/CompositionEngine/tests/MockHWComposer.h
+++ b/services/surfaceflinger/CompositionEngine/tests/MockHWComposer.h
@@ -40,8 +40,7 @@
     MOCK_CONST_METHOD3(getDisplayIdentificationData,
                        bool(hwc2_display_t, uint8_t*, DisplayIdentificationData*));
     MOCK_CONST_METHOD1(hasCapability, bool(HWC2::Capability));
-    MOCK_CONST_METHOD2(hasDisplayCapability,
-                       bool(const std::optional<DisplayId>&, HWC2::DisplayCapability));
+    MOCK_CONST_METHOD2(hasDisplayCapability, bool(DisplayId, HWC2::DisplayCapability));
 
     MOCK_METHOD3(allocateVirtualDisplay,
                  std::optional<DisplayId>(uint32_t, uint32_t, ui::PixelFormat*));
diff --git a/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp b/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp
index 63bb459..1c9cd9c 100644
--- a/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp
+++ b/services/surfaceflinger/CompositionEngine/tests/OutputTest.cpp
@@ -3100,9 +3100,8 @@
             .andIfUsesHdr(true)
             .andIfSkipColorTransform(false)
             .thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputSourceClip,
-                                            mat4(), kDefaultMaxLuminance, kDefaultOutputDataspace,
-                                            mat4(), Region::INVALID_REGION,
-                                            kDefaultOutputOrientation})
+                                            kDefaultMaxLuminance, kDefaultOutputDataspace, mat4(),
+                                            Region::INVALID_REGION, kDefaultOutputOrientation})
             .execute()
             .expectAFenceWasReturned();
 }
@@ -3112,9 +3111,8 @@
             .andIfUsesHdr(false)
             .andIfSkipColorTransform(false)
             .thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputSourceClip,
-                                            mat4(), kDefaultMaxLuminance, kDefaultOutputDataspace,
-                                            mat4(), Region::INVALID_REGION,
-                                            kDefaultOutputOrientation})
+                                            kDefaultMaxLuminance, kDefaultOutputDataspace, mat4(),
+                                            Region::INVALID_REGION, kDefaultOutputOrientation})
             .execute()
             .expectAFenceWasReturned();
 }
@@ -3124,7 +3122,7 @@
             .andIfUsesHdr(true)
             .andIfSkipColorTransform(false)
             .thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputSourceClip,
-                                            mat4(), kDefaultMaxLuminance, kDefaultOutputDataspace,
+                                            kDefaultMaxLuminance, kDefaultOutputDataspace,
                                             kDefaultColorTransformMat, Region::INVALID_REGION,
                                             kDefaultOutputOrientation})
             .execute()
@@ -3136,7 +3134,7 @@
             .andIfUsesHdr(false)
             .andIfSkipColorTransform(false)
             .thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputSourceClip,
-                                            mat4(), kDefaultMaxLuminance, kDefaultOutputDataspace,
+                                            kDefaultMaxLuminance, kDefaultOutputDataspace,
                                             kDefaultColorTransformMat, Region::INVALID_REGION,
                                             kDefaultOutputOrientation})
             .execute()
@@ -3149,9 +3147,8 @@
             .andIfUsesHdr(true)
             .andIfSkipColorTransform(true)
             .thenExpectDisplaySettingsUsed({kDefaultOutputDestinationClip, kDefaultOutputSourceClip,
-                                            mat4(), kDefaultMaxLuminance, kDefaultOutputDataspace,
-                                            mat4(), Region::INVALID_REGION,
-                                            kDefaultOutputOrientation})
+                                            kDefaultMaxLuminance, kDefaultOutputDataspace, mat4(),
+                                            Region::INVALID_REGION, kDefaultOutputOrientation})
             .execute()
             .expectAFenceWasReturned();
 }
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
index 560299a..f30d662 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
@@ -190,17 +190,10 @@
     return mCapabilities.count(capability) > 0;
 }
 
-bool HWComposer::hasDisplayCapability(const std::optional<DisplayId>& displayId,
+bool HWComposer::hasDisplayCapability(DisplayId displayId,
                                       HWC2::DisplayCapability capability) const {
-    if (!displayId) {
-        // Checkout global capabilities for displays without a corresponding HWC display.
-        if (capability == HWC2::DisplayCapability::SkipClientColorTransform) {
-            return hasCapability(HWC2::Capability::SkipClientColorTransform);
-        }
-        return false;
-    }
-    RETURN_IF_INVALID_DISPLAY(*displayId, false);
-    return mDisplayData.at(*displayId).hwcDisplay->getCapabilities().count(capability) > 0;
+    RETURN_IF_INVALID_DISPLAY(displayId, false);
+    return mDisplayData.at(displayId).hwcDisplay->getCapabilities().count(capability) > 0;
 }
 
 std::optional<DisplayIdentificationInfo> HWComposer::onHotplug(hwc2_display_t hwcDisplayId,
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.h b/services/surfaceflinger/DisplayHardware/HWComposer.h
index 3cb40b1..e18419a 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.h
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.h
@@ -70,7 +70,7 @@
                                               DisplayIdentificationData* outData) const = 0;
 
     virtual bool hasCapability(HWC2::Capability capability) const = 0;
-    virtual bool hasDisplayCapability(const std::optional<DisplayId>& displayId,
+    virtual bool hasDisplayCapability(DisplayId displayId,
                                       HWC2::DisplayCapability capability) const = 0;
 
     // Attempts to allocate a virtual display and returns its ID if created on the HWC device.
@@ -234,7 +234,7 @@
                                       DisplayIdentificationData* outData) const override;
 
     bool hasCapability(HWC2::Capability capability) const override;
-    bool hasDisplayCapability(const std::optional<DisplayId>& displayId,
+    bool hasDisplayCapability(DisplayId displayId,
                               HWC2::DisplayCapability capability) const override;
 
     // Attempts to allocate a virtual display and returns its ID if created on the HWC device.
diff --git a/services/surfaceflinger/RefreshRateOverlay.cpp b/services/surfaceflinger/RefreshRateOverlay.cpp
index c675971..0a0f2f1 100644
--- a/services/surfaceflinger/RefreshRateOverlay.cpp
+++ b/services/surfaceflinger/RefreshRateOverlay.cpp
@@ -170,7 +170,7 @@
 void RefreshRateOverlay::primeCache() {
     auto& allRefreshRates = mFlinger.mRefreshRateConfigs->getAllRefreshRates();
     if (allRefreshRates.size() == 1) {
-        auto fps = allRefreshRates.begin()->second->fps;
+        auto fps = allRefreshRates.begin()->second->getFps();
         half4 color = {LOW_FPS_COLOR, ALPHA};
         mBufferCache.emplace(fps, SevenSegmentDrawer::drawNumber(fps, color));
         return;
@@ -179,7 +179,7 @@
     std::vector<uint32_t> supportedFps;
     supportedFps.reserve(allRefreshRates.size());
     for (auto& [ignored, refreshRate] : allRefreshRates) {
-        supportedFps.push_back(refreshRate->fps);
+        supportedFps.push_back(refreshRate->getFps());
     }
 
     std::sort(supportedFps.begin(), supportedFps.end());
@@ -207,7 +207,7 @@
     const int32_t right = left + display->getWidth() / 8;
     const int32_t buttom = top + display->getHeight() / 32;
 
-    auto buffer = mBufferCache[refreshRate.fps];
+    auto buffer = mBufferCache[refreshRate.getFps()];
     mLayer->setBuffer(buffer, Fence::NO_FENCE, 0, 0, {});
 
     mLayer->setFrame(Rect(left, top, right, buttom));
diff --git a/services/surfaceflinger/Scheduler/HwcStrongTypes.h b/services/surfaceflinger/Scheduler/HwcStrongTypes.h
index cfbbdfe..8ba4f20 100644
--- a/services/surfaceflinger/Scheduler/HwcStrongTypes.h
+++ b/services/surfaceflinger/Scheduler/HwcStrongTypes.h
@@ -22,6 +22,5 @@
 
 // Strong types for the different indexes as they are referring to a different base.
 using HwcConfigIndexType = StrongTyping<int, struct HwcConfigIndexTypeTag, Compare, Add, Hash>;
-using HwcConfigGroupType = StrongTyping<int, struct HwcConfigGroupTypeTag, Compare>;
 
 } // namespace android
\ No newline at end of file
diff --git a/services/surfaceflinger/Scheduler/PhaseOffsets.cpp b/services/surfaceflinger/Scheduler/PhaseOffsets.cpp
index 43883fb..d9aaa05 100644
--- a/services/surfaceflinger/Scheduler/PhaseOffsets.cpp
+++ b/services/surfaceflinger/Scheduler/PhaseOffsets.cpp
@@ -43,7 +43,7 @@
     refreshRates.reserve(allRefreshRates.size());
 
     for (const auto& [ignored, refreshRate] : allRefreshRates) {
-        refreshRates.emplace_back(refreshRate->fps);
+        refreshRates.emplace_back(refreshRate->getFps());
     }
 
     return refreshRates;
@@ -59,7 +59,7 @@
 
 PhaseOffsets::PhaseOffsets(const scheduler::RefreshRateConfigs& refreshRateConfigs)
       : PhaseOffsets(getRefreshRatesFromConfigs(refreshRateConfigs),
-                     refreshRateConfigs.getCurrentRefreshRate().fps,
+                     refreshRateConfigs.getCurrentRefreshRate().getFps(),
                      // Below defines the threshold when an offset is considered to be negative,
                      // i.e. targeting for the N+2 vsync instead of N+1. This means that: For offset
                      // < threshold, SF wake up (vsync_duration - offset) before HW vsync. For
@@ -275,7 +275,7 @@
 
 PhaseDurations::PhaseDurations(const scheduler::RefreshRateConfigs& refreshRateConfigs)
       : PhaseDurations(getRefreshRatesFromConfigs(refreshRateConfigs),
-                       refreshRateConfigs.getCurrentRefreshRate().fps,
+                       refreshRateConfigs.getCurrentRefreshRate().getFps(),
                        getProperty("debug.sf.late.sf.duration").value_or(-1),
                        getProperty("debug.sf.late.app.duration").value_or(-1),
                        getProperty("debug.sf.early.sf.duration").value_or(mSfDuration),
diff --git a/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp b/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp
index 14ef733..5634adb 100644
--- a/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp
+++ b/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp
@@ -53,7 +53,7 @@
     if (explicitContentFramerate != 0) {
         contentFramerate = explicitContentFramerate;
     } else if (contentFramerate == 0) {
-        contentFramerate = round<int>(mMaxSupportedRefreshRate->fps);
+        contentFramerate = round<int>(mMaxSupportedRefreshRate->getFps());
     }
     ATRACE_INT("ContentFPS", contentFramerate);
 
@@ -177,7 +177,7 @@
                 continue;
             }
 
-            const auto displayPeriod = scores[i].first->vsyncPeriod;
+            const auto displayPeriod = scores[i].first->hwcConfig->getVsyncPeriod();
             const auto layerPeriod = round<nsecs_t>(1e9f / layer.desiredRefreshRate);
             if (layer.vote == LayerVoteType::ExplicitDefault) {
                 const auto layerScore = [&]() {
@@ -309,21 +309,30 @@
     mCurrentRefreshRate = mRefreshRates.at(configId).get();
 }
 
-RefreshRateConfigs::RefreshRateConfigs(const std::vector<InputConfig>& configs,
-                                       HwcConfigIndexType currentHwcConfig) {
-    init(configs, currentHwcConfig);
-}
-
 RefreshRateConfigs::RefreshRateConfigs(
         const std::vector<std::shared_ptr<const HWC2::Display::Config>>& configs,
         HwcConfigIndexType currentConfigId) {
-    std::vector<InputConfig> inputConfigs;
-    for (size_t configId = 0; configId < configs.size(); ++configId) {
-        auto configGroup = HwcConfigGroupType(configs[configId]->getConfigGroup());
-        inputConfigs.push_back({HwcConfigIndexType(static_cast<int>(configId)), configGroup,
-                                configs[configId]->getVsyncPeriod()});
+    LOG_ALWAYS_FATAL_IF(configs.empty());
+    LOG_ALWAYS_FATAL_IF(currentConfigId.value() >= configs.size());
+
+    for (auto configId = HwcConfigIndexType(0); configId.value() < configs.size(); configId++) {
+        const auto& config = configs.at(static_cast<size_t>(configId.value()));
+        const float fps = 1e9f / config->getVsyncPeriod();
+        mRefreshRates.emplace(configId,
+                              std::make_unique<RefreshRate>(configId, config,
+                                                            base::StringPrintf("%2.ffps", fps), fps,
+                                                            RefreshRate::ConstructorTag(0)));
+        if (configId == currentConfigId) {
+            mCurrentRefreshRate = mRefreshRates.at(configId).get();
+        }
     }
-    init(inputConfigs, currentConfigId);
+
+    std::vector<const RefreshRate*> sortedConfigs;
+    getSortedRefreshRateList([](const RefreshRate&) { return true; }, &sortedConfigs);
+    mDisplayManagerPolicy.defaultConfig = currentConfigId;
+    mMinSupportedRefreshRate = sortedConfigs.front();
+    mMaxSupportedRefreshRate = sortedConfigs.back();
+    constructAvailableRefreshRates();
 }
 
 bool RefreshRateConfigs::isPolicyValid(const Policy& policy) {
@@ -406,10 +415,13 @@
 
     std::sort(outRefreshRates->begin(), outRefreshRates->end(),
               [](const auto refreshRate1, const auto refreshRate2) {
-                  if (refreshRate1->vsyncPeriod != refreshRate2->vsyncPeriod) {
-                      return refreshRate1->vsyncPeriod > refreshRate2->vsyncPeriod;
+                  if (refreshRate1->hwcConfig->getVsyncPeriod() !=
+                      refreshRate2->hwcConfig->getVsyncPeriod()) {
+                      return refreshRate1->hwcConfig->getVsyncPeriod() >
+                              refreshRate2->hwcConfig->getVsyncPeriod();
                   } else {
-                      return refreshRate1->configGroup > refreshRate2->configGroup;
+                      return refreshRate1->hwcConfig->getConfigGroup() >
+                              refreshRate2->hwcConfig->getConfigGroup();
                   }
               });
 }
@@ -417,13 +429,20 @@
 void RefreshRateConfigs::constructAvailableRefreshRates() {
     // Filter configs based on current policy and sort based on vsync period
     const Policy* policy = getCurrentPolicyLocked();
-    HwcConfigGroupType group = mRefreshRates.at(policy->defaultConfig)->configGroup;
+    const auto& defaultConfig = mRefreshRates.at(policy->defaultConfig)->hwcConfig;
     ALOGV("constructAvailableRefreshRates: default %d group %d min %.2f max %.2f",
-          policy->defaultConfig.value(), group.value(), policy->minRefreshRate,
+          policy->defaultConfig.value(), defaultConfig->getConfigGroup(), policy->minRefreshRate,
           policy->maxRefreshRate);
     getSortedRefreshRateList(
             [&](const RefreshRate& refreshRate) REQUIRES(mLock) {
-                return (policy->allowGroupSwitching || refreshRate.configGroup == group) &&
+                const auto& hwcConfig = refreshRate.hwcConfig;
+
+                return hwcConfig->getHeight() == defaultConfig->getHeight() &&
+                        hwcConfig->getWidth() == defaultConfig->getWidth() &&
+                        hwcConfig->getDpiX() == defaultConfig->getDpiX() &&
+                        hwcConfig->getDpiY() == defaultConfig->getDpiY() &&
+                        (policy->allowGroupSwitching ||
+                         hwcConfig->getConfigGroup() == defaultConfig->getConfigGroup()) &&
                         refreshRate.inPolicy(policy->minRefreshRate, policy->maxRefreshRate);
             },
             &mAvailableRefreshRates);
@@ -440,30 +459,4 @@
                         policy->maxRefreshRate);
 }
 
-// NO_THREAD_SAFETY_ANALYSIS since this is called from the constructor
-void RefreshRateConfigs::init(const std::vector<InputConfig>& configs,
-                              HwcConfigIndexType currentHwcConfig) NO_THREAD_SAFETY_ANALYSIS {
-    LOG_ALWAYS_FATAL_IF(configs.empty());
-    LOG_ALWAYS_FATAL_IF(currentHwcConfig.value() >= configs.size());
-
-    for (const auto& config : configs) {
-        const float fps = 1e9f / config.vsyncPeriod;
-        mRefreshRates.emplace(config.configId,
-                              std::make_unique<RefreshRate>(config.configId, config.vsyncPeriod,
-                                                            config.configGroup,
-                                                            base::StringPrintf("%2.ffps", fps),
-                                                            fps));
-        if (config.configId == currentHwcConfig) {
-            mCurrentRefreshRate = mRefreshRates.at(config.configId).get();
-        }
-    }
-
-    std::vector<const RefreshRate*> sortedConfigs;
-    getSortedRefreshRateList([](const RefreshRate&) { return true; }, &sortedConfigs);
-    mDisplayManagerPolicy.defaultConfig = currentHwcConfig;
-    mMinSupportedRefreshRate = sortedConfigs.front();
-    mMaxSupportedRefreshRate = sortedConfigs.back();
-    constructAvailableRefreshRates();
-}
-
 } // namespace android::scheduler
diff --git a/services/surfaceflinger/Scheduler/RefreshRateConfigs.h b/services/surfaceflinger/Scheduler/RefreshRateConfigs.h
index e749f8f..dea7e90 100644
--- a/services/surfaceflinger/Scheduler/RefreshRateConfigs.h
+++ b/services/surfaceflinger/Scheduler/RefreshRateConfigs.h
@@ -29,6 +29,8 @@
 #include "Scheduler/StrongTyping.h"
 
 namespace android::scheduler {
+class RefreshRateConfigsTest;
+
 using namespace std::chrono_literals;
 
 enum class RefreshRateConfigEvent : unsigned { None = 0b0, Changed = 0b1 };
@@ -49,30 +51,27 @@
     static constexpr nsecs_t MARGIN_FOR_PERIOD_CALCULATION =
         std::chrono::nanoseconds(800us).count();
 
-    struct RefreshRate {
-        // The tolerance within which we consider FPS approximately equals.
-        static constexpr float FPS_EPSILON = 0.001f;
+    class RefreshRate {
+    private:
+        // Effectively making the constructor private while allowing
+        // std::make_unique to create the object
+        struct ConstructorTag {
+            explicit ConstructorTag(int) {}
+        };
 
-        RefreshRate(HwcConfigIndexType configId, nsecs_t vsyncPeriod,
-                    HwcConfigGroupType configGroup, std::string name, float fps)
-              : configId(configId),
-                vsyncPeriod(vsyncPeriod),
-                configGroup(configGroup),
-                name(std::move(name)),
-                fps(fps) {}
+    public:
+        RefreshRate(HwcConfigIndexType configId,
+                    std::shared_ptr<const HWC2::Display::Config> config, std::string name,
+                    float fps, ConstructorTag)
+              : configId(configId), hwcConfig(config), name(std::move(name)), fps(fps) {}
 
         RefreshRate(const RefreshRate&) = delete;
-        // This config ID corresponds to the position of the config in the vector that is stored
-        // on the device.
-        const HwcConfigIndexType configId;
-        // Vsync period in nanoseconds.
-        const nsecs_t vsyncPeriod;
-        // This configGroup for the config.
-        const HwcConfigGroupType configGroup;
-        // Human readable name of the refresh rate.
-        const std::string name;
-        // Refresh rate in frames per second
-        const float fps = 0;
+
+        HwcConfigIndexType getConfigId() const { return configId; }
+        nsecs_t getVsyncPeriod() const { return hwcConfig->getVsyncPeriod(); }
+        int32_t getConfigGroup() const { return hwcConfig->getConfigGroup(); }
+        const std::string& getName() const { return name; }
+        float getFps() const { return fps; }
 
         // Checks whether the fps of this RefreshRate struct is within a given min and max refresh
         // rate passed in. FPS_EPSILON is applied to the boundaries for approximation.
@@ -81,11 +80,27 @@
         }
 
         bool operator!=(const RefreshRate& other) const {
-            return configId != other.configId || vsyncPeriod != other.vsyncPeriod ||
-                    configGroup != other.configGroup;
+            return configId != other.configId || hwcConfig != other.hwcConfig;
         }
 
         bool operator==(const RefreshRate& other) const { return !(*this != other); }
+
+    private:
+        friend RefreshRateConfigs;
+        friend RefreshRateConfigsTest;
+
+        // The tolerance within which we consider FPS approximately equals.
+        static constexpr float FPS_EPSILON = 0.001f;
+
+        // This config ID corresponds to the position of the config in the vector that is stored
+        // on the device.
+        const HwcConfigIndexType configId;
+        // The config itself
+        std::shared_ptr<const HWC2::Display::Config> hwcConfig;
+        // Human readable name of the refresh rate.
+        const std::string name;
+        // Refresh rate in frames per second
+        const float fps = 0;
     };
 
     using AllRefreshRatesMapType =
@@ -208,20 +223,10 @@
     // Stores the current configId the device operates at
     void setCurrentConfigId(HwcConfigIndexType configId) EXCLUDES(mLock);
 
-    struct InputConfig {
-        HwcConfigIndexType configId = HwcConfigIndexType(0);
-        HwcConfigGroupType configGroup = HwcConfigGroupType(0);
-        nsecs_t vsyncPeriod = 0;
-    };
-
-    RefreshRateConfigs(const std::vector<InputConfig>& configs,
-                       HwcConfigIndexType currentHwcConfig);
     RefreshRateConfigs(const std::vector<std::shared_ptr<const HWC2::Display::Config>>& configs,
                        HwcConfigIndexType currentConfigId);
 
 private:
-    void init(const std::vector<InputConfig>& configs, HwcConfigIndexType currentHwcConfig);
-
     void constructAvailableRefreshRates() REQUIRES(mLock);
 
     void getSortedRefreshRateList(
diff --git a/services/surfaceflinger/Scheduler/RefreshRateStats.h b/services/surfaceflinger/Scheduler/RefreshRateStats.h
index e44cd52..66d4a03 100644
--- a/services/surfaceflinger/Scheduler/RefreshRateStats.h
+++ b/services/surfaceflinger/Scheduler/RefreshRateStats.h
@@ -78,10 +78,10 @@
         // Multiple configs may map to the same name, e.g. "60fps". Add the
         // times for such configs together.
         for (const auto& [configId, time] : mConfigModesTotalTime) {
-            totalTime[mRefreshRateConfigs.getRefreshRateFromConfigId(configId).name] = 0;
+            totalTime[mRefreshRateConfigs.getRefreshRateFromConfigId(configId).getName()] = 0;
         }
         for (const auto& [configId, time] : mConfigModesTotalTime) {
-            totalTime[mRefreshRateConfigs.getRefreshRateFromConfigId(configId).name] += time;
+            totalTime[mRefreshRateConfigs.getRefreshRateFromConfigId(configId).getName()] += time;
         }
         totalTime["ScreenOff"] = mScreenOffTime;
         return totalTime;
@@ -115,7 +115,7 @@
             }
             mConfigModesTotalTime[mCurrentConfigMode] += timeElapsedMs;
             fps = static_cast<uint32_t>(std::round(
-                    mRefreshRateConfigs.getRefreshRateFromConfigId(mCurrentConfigMode).fps));
+                    mRefreshRateConfigs.getRefreshRateFromConfigId(mCurrentConfigMode).getFps()));
         } else {
             mScreenOffTime += timeElapsedMs;
         }
diff --git a/services/surfaceflinger/Scheduler/Scheduler.cpp b/services/surfaceflinger/Scheduler/Scheduler.cpp
index cd6075f..9a9523f 100644
--- a/services/surfaceflinger/Scheduler/Scheduler.cpp
+++ b/services/surfaceflinger/Scheduler/Scheduler.cpp
@@ -332,7 +332,7 @@
     const nsecs_t last = mLastResyncTime.exchange(now);
 
     if (now - last > kIgnoreDelay) {
-        resyncToHardwareVsync(false, mRefreshRateConfigs.getCurrentRefreshRate().vsyncPeriod);
+        resyncToHardwareVsync(false, mRefreshRateConfigs.getCurrentRefreshRate().getVsyncPeriod());
     }
 }
 
@@ -389,34 +389,34 @@
     // keep the layer history, since we use it for other features (like Frame Rate API), so layers
     // still need to be registered.
     if (!mUseContentDetection) {
-        mLayerHistory->registerLayer(layer, mRefreshRateConfigs.getMinRefreshRate().fps,
-                                     mRefreshRateConfigs.getMaxRefreshRate().fps,
+        mLayerHistory->registerLayer(layer, mRefreshRateConfigs.getMinRefreshRate().getFps(),
+                                     mRefreshRateConfigs.getMaxRefreshRate().getFps(),
                                      scheduler::LayerHistory::LayerVoteType::NoVote);
         return;
     }
 
     // In V1 of content detection, all layers are registered as Heuristic (unless it's wallpaper).
     if (!mUseContentDetectionV2) {
-        const auto lowFps = mRefreshRateConfigs.getMinRefreshRate().fps;
+        const auto lowFps = mRefreshRateConfigs.getMinRefreshRate().getFps();
         const auto highFps = layer->getWindowType() == InputWindowInfo::TYPE_WALLPAPER
                 ? lowFps
-                : mRefreshRateConfigs.getMaxRefreshRate().fps;
+                : mRefreshRateConfigs.getMaxRefreshRate().getFps();
 
         mLayerHistory->registerLayer(layer, lowFps, highFps,
                                      scheduler::LayerHistory::LayerVoteType::Heuristic);
     } else {
         if (layer->getWindowType() == InputWindowInfo::TYPE_WALLPAPER) {
             // Running Wallpaper at Min is considered as part of content detection.
-            mLayerHistory->registerLayer(layer, mRefreshRateConfigs.getMinRefreshRate().fps,
-                                         mRefreshRateConfigs.getMaxRefreshRate().fps,
+            mLayerHistory->registerLayer(layer, mRefreshRateConfigs.getMinRefreshRate().getFps(),
+                                         mRefreshRateConfigs.getMaxRefreshRate().getFps(),
                                          scheduler::LayerHistory::LayerVoteType::Min);
         } else if (layer->getWindowType() == InputWindowInfo::TYPE_STATUS_BAR) {
-            mLayerHistory->registerLayer(layer, mRefreshRateConfigs.getMinRefreshRate().fps,
-                                         mRefreshRateConfigs.getMaxRefreshRate().fps,
+            mLayerHistory->registerLayer(layer, mRefreshRateConfigs.getMinRefreshRate().getFps(),
+                                         mRefreshRateConfigs.getMaxRefreshRate().getFps(),
                                          scheduler::LayerHistory::LayerVoteType::NoVote);
         } else {
-            mLayerHistory->registerLayer(layer, mRefreshRateConfigs.getMinRefreshRate().fps,
-                                         mRefreshRateConfigs.getMaxRefreshRate().fps,
+            mLayerHistory->registerLayer(layer, mRefreshRateConfigs.getMinRefreshRate().getFps(),
+                                         mRefreshRateConfigs.getMaxRefreshRate().getFps(),
                                          scheduler::LayerHistory::LayerVoteType::Heuristic);
         }
     }
@@ -503,12 +503,13 @@
     // magic number
     const auto& refreshRate = mRefreshRateConfigs.getCurrentRefreshRate();
     constexpr float FPS_THRESHOLD_FOR_KERNEL_TIMER = 65.0f;
-    if (state == TimerState::Reset && refreshRate.fps > FPS_THRESHOLD_FOR_KERNEL_TIMER) {
+    if (state == TimerState::Reset && refreshRate.getFps() > FPS_THRESHOLD_FOR_KERNEL_TIMER) {
         // If we're not in performance mode then the kernel timer shouldn't do
         // anything, as the refresh rate during DPU power collapse will be the
         // same.
-        resyncToHardwareVsync(true /* makeAvailable */, refreshRate.vsyncPeriod);
-    } else if (state == TimerState::Expired && refreshRate.fps <= FPS_THRESHOLD_FOR_KERNEL_TIMER) {
+        resyncToHardwareVsync(true /* makeAvailable */, refreshRate.getVsyncPeriod());
+    } else if (state == TimerState::Expired &&
+               refreshRate.getFps() <= FPS_THRESHOLD_FOR_KERNEL_TIMER) {
         // Disable HW VSYNC if the timer expired, as we don't need it enabled if
         // we're not pushing frames, and if we're in PERFORMANCE mode then we'll
         // need to update the DispSync model anyway.
@@ -580,30 +581,31 @@
     if (mDisplayPowerTimer &&
         (!mFeatures.isDisplayPowerStateNormal ||
          mFeatures.displayPowerTimer == TimerState::Reset)) {
-        return mRefreshRateConfigs.getMaxRefreshRateByPolicy().configId;
+        return mRefreshRateConfigs.getMaxRefreshRateByPolicy().getConfigId();
     }
 
     if (!mUseContentDetectionV2) {
         // As long as touch is active we want to be in performance mode.
         if (mTouchTimer && mFeatures.touch == TouchState::Active) {
-            return mRefreshRateConfigs.getMaxRefreshRateByPolicy().configId;
+            return mRefreshRateConfigs.getMaxRefreshRateByPolicy().getConfigId();
         }
     }
 
     // If timer has expired as it means there is no new content on the screen.
     if (mIdleTimer && mFeatures.idleTimer == TimerState::Expired) {
-        return mRefreshRateConfigs.getMinRefreshRateByPolicy().configId;
+        return mRefreshRateConfigs.getMinRefreshRateByPolicy().getConfigId();
     }
 
     if (!mUseContentDetectionV2) {
         // If content detection is off we choose performance as we don't know the content fps.
         if (mFeatures.contentDetectionV1 == ContentDetectionState::Off) {
             // NOTE: V1 always calls this, but this is not a default behavior for V2.
-            return mRefreshRateConfigs.getMaxRefreshRateByPolicy().configId;
+            return mRefreshRateConfigs.getMaxRefreshRateByPolicy().getConfigId();
         }
 
         // Content detection is on, find the appropriate refresh rate with minimal error
-        return mRefreshRateConfigs.getRefreshRateForContent(mFeatures.contentRequirements).configId;
+        return mRefreshRateConfigs.getRefreshRateForContent(mFeatures.contentRequirements)
+                .getConfigId();
     }
 
     bool touchConsidered;
@@ -613,7 +615,7 @@
                                                 mTouchTimer &&
                                                         mFeatures.touch == TouchState::Active,
                                                 &touchConsidered)
-                    .configId;
+                    .getConfigId();
     if (touchConsidered) {
         // Clear layer history if refresh rate was selected based on touch to allow
         // the hueristic to pick up with the new rate.
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index badcbd0..5f1486b 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -931,7 +931,7 @@
 void SurfaceFlinger::setDesiredActiveConfig(const ActiveConfigInfo& info) {
     ATRACE_CALL();
     auto& refreshRate = mRefreshRateConfigs->getRefreshRateFromConfigId(info.configId);
-    ALOGV("setDesiredActiveConfig(%s)", refreshRate.name.c_str());
+    ALOGV("setDesiredActiveConfig(%s)", refreshRate.getName().c_str());
 
     std::lock_guard<std::mutex> lock(mActiveConfigLock);
     if (mDesiredActiveConfigChanged) {
@@ -943,7 +943,7 @@
     } else {
         // Check is we are already at the desired config
         const auto display = getDefaultDisplayDeviceLocked();
-        if (!display || display->getActiveConfig() == refreshRate.configId) {
+        if (!display || display->getActiveConfig() == refreshRate.getConfigId()) {
             return;
         }
 
@@ -955,12 +955,12 @@
         repaintEverythingForHWC();
         // Start receiving vsync samples now, so that we can detect a period
         // switch.
-        mScheduler->resyncToHardwareVsync(true, refreshRate.vsyncPeriod);
+        mScheduler->resyncToHardwareVsync(true, refreshRate.getVsyncPeriod());
         // As we called to set period, we will call to onRefreshRateChangeCompleted once
         // DispSync model is locked.
         mVSyncModulator->onRefreshRateChangeInitiated();
 
-        mPhaseConfiguration->setRefreshRateFps(refreshRate.fps);
+        mPhaseConfiguration->setRefreshRateFps(refreshRate.getFps());
         mVSyncModulator->setPhaseOffsets(mPhaseConfiguration->getCurrentOffsets());
     }
 
@@ -992,8 +992,9 @@
             const auto& refreshRate = mRefreshRateConfigs->getRefreshRateFromConfigId(config);
             result = setDesiredDisplayConfigSpecsInternal(display,
                                                           scheduler::RefreshRateConfigs::
-                                                                  Policy{config, refreshRate.fps,
-                                                                         refreshRate.fps},
+                                                                  Policy{config,
+                                                                         refreshRate.getFps(),
+                                                                         refreshRate.getFps()},
                                                           /*overridePolicy=*/false);
         }
     }));
@@ -1019,17 +1020,17 @@
 
     auto& refreshRate =
             mRefreshRateConfigs->getRefreshRateFromConfigId(mUpcomingActiveConfig.configId);
-    if (refreshRate.vsyncPeriod != oldRefreshRate.vsyncPeriod) {
+    if (refreshRate.getVsyncPeriod() != oldRefreshRate.getVsyncPeriod()) {
         mTimeStats->incrementRefreshRateSwitches();
     }
-    mPhaseConfiguration->setRefreshRateFps(refreshRate.fps);
+    mPhaseConfiguration->setRefreshRateFps(refreshRate.getFps());
     mVSyncModulator->setPhaseOffsets(mPhaseConfiguration->getCurrentOffsets());
-    ATRACE_INT("ActiveConfigFPS", refreshRate.fps);
+    ATRACE_INT("ActiveConfigFPS", refreshRate.getFps());
 
     if (mUpcomingActiveConfig.event != Scheduler::ConfigEvent::None) {
         const nsecs_t vsyncPeriod =
                 mRefreshRateConfigs->getRefreshRateFromConfigId(mUpcomingActiveConfig.configId)
-                        .vsyncPeriod;
+                        .getVsyncPeriod();
         mScheduler->onConfigChanged(mAppConnectionHandle, display->getId()->value,
                                     mUpcomingActiveConfig.configId, vsyncPeriod);
     }
@@ -1042,62 +1043,53 @@
 
     const auto& refreshRate =
             mRefreshRateConfigs->getRefreshRateFromConfigId(mDesiredActiveConfig.configId);
-    mScheduler->resyncToHardwareVsync(true, refreshRate.vsyncPeriod);
-    mPhaseConfiguration->setRefreshRateFps(refreshRate.fps);
+    mScheduler->resyncToHardwareVsync(true, refreshRate.getVsyncPeriod());
+    mPhaseConfiguration->setRefreshRateFps(refreshRate.getFps());
     mVSyncModulator->setPhaseOffsets(mPhaseConfiguration->getCurrentOffsets());
 }
 
-bool SurfaceFlinger::performSetActiveConfig() {
+void SurfaceFlinger::performSetActiveConfig() {
     ATRACE_CALL();
     ALOGV("performSetActiveConfig");
-    if (mCheckPendingFence) {
-        if (previousFramePending()) {
-            // fence has not signaled yet. wait for the next invalidate
-            mEventQueue->invalidate();
-            return true;
-        }
-
-        // We received the present fence from the HWC, so we assume it successfully updated
-        // the config, hence we update SF.
-        mCheckPendingFence = false;
-        setActiveConfigInternal();
-    }
-
     // Store the local variable to release the lock.
-    ActiveConfigInfo desiredActiveConfig;
-    {
+    const auto desiredActiveConfig = [&]() -> std::optional<ActiveConfigInfo> {
         std::lock_guard<std::mutex> lock(mActiveConfigLock);
-        if (!mDesiredActiveConfigChanged) {
-            return false;
+        if (mDesiredActiveConfigChanged) {
+            return mDesiredActiveConfig;
         }
-        desiredActiveConfig = mDesiredActiveConfig;
+        return std::nullopt;
+    }();
+
+    if (!desiredActiveConfig) {
+        // No desired active config pending to be applied
+        return;
     }
 
     auto& refreshRate =
-            mRefreshRateConfigs->getRefreshRateFromConfigId(desiredActiveConfig.configId);
-    ALOGV("performSetActiveConfig changing active config to %d(%s)", refreshRate.configId.value(),
-          refreshRate.name.c_str());
+            mRefreshRateConfigs->getRefreshRateFromConfigId(desiredActiveConfig->configId);
+    ALOGV("performSetActiveConfig changing active config to %d(%s)",
+          refreshRate.getConfigId().value(), refreshRate.getName().c_str());
     const auto display = getDefaultDisplayDeviceLocked();
-    if (!display || display->getActiveConfig() == desiredActiveConfig.configId) {
+    if (!display || display->getActiveConfig() == desiredActiveConfig->configId) {
         // display is not valid or we are already in the requested mode
         // on both cases there is nothing left to do
         desiredActiveConfigChangeDone();
-        return false;
+        return;
     }
 
     // Desired active config was set, it is different than the config currently in use, however
     // allowed configs might have change by the time we process the refresh.
     // Make sure the desired config is still allowed
-    if (!isDisplayConfigAllowed(desiredActiveConfig.configId)) {
+    if (!isDisplayConfigAllowed(desiredActiveConfig->configId)) {
         desiredActiveConfigChangeDone();
-        return false;
+        return;
     }
 
-    mUpcomingActiveConfig = desiredActiveConfig;
+    mUpcomingActiveConfig = *desiredActiveConfig;
     const auto displayId = display->getId();
     LOG_ALWAYS_FATAL_IF(!displayId);
 
-    ATRACE_INT("ActiveConfigFPS_HWC", refreshRate.fps);
+    ATRACE_INT("ActiveConfigFPS_HWC", refreshRate.getFps());
 
     // TODO(b/142753666) use constrains
     HWC2::VsyncPeriodChangeConstraints constraints;
@@ -1113,13 +1105,12 @@
         // setActiveConfigWithConstraints may fail if a hotplug event is just about
         // to be sent. We just log the error in this case.
         ALOGW("setActiveConfigWithConstraints failed: %d", status);
-        return false;
+        return;
     }
 
     mScheduler->onNewVsyncPeriodChangeTimeline(outTimeline);
     // Scheduler will submit an empty frame to HWC if needed.
-    mCheckPendingFence = true;
-    return false;
+    mSetActiveConfigPending = true;
 }
 
 status_t SurfaceFlinger::getDisplayColorModes(const sp<IBinder>& displayToken,
@@ -1221,7 +1212,7 @@
               displayToken.get());
         return NAME_NOT_FOUND;
     }
-    *outSupport = getHwComposer().hasDisplayCapability(displayId,
+    *outSupport = getHwComposer().hasDisplayCapability(*displayId,
                                                        HWC2::DisplayCapability::AutoLowLatencyMode);
     return NO_ERROR;
 }
@@ -1492,7 +1483,7 @@
         return NAME_NOT_FOUND;
     }
     *outSupport =
-            getHwComposer().hasDisplayCapability(displayId, HWC2::DisplayCapability::Brightness);
+            getHwComposer().hasDisplayCapability(*displayId, HWC2::DisplayCapability::Brightness);
     return NO_ERROR;
 }
 
@@ -1625,13 +1616,13 @@
     ATRACE_CALL();
 
     // Don't do any updating if the current fps is the same as the new one.
-    if (!isDisplayConfigAllowed(refreshRate.configId)) {
+    if (!isDisplayConfigAllowed(refreshRate.getConfigId())) {
         ALOGV("Skipping config %d as it is not part of allowed configs",
-              refreshRate.configId.value());
+              refreshRate.getConfigId().value());
         return;
     }
 
-    setDesiredActiveConfig({refreshRate.configId, event});
+    setDesiredActiveConfig({refreshRate.getConfigId(), event});
 }
 
 void SurfaceFlinger::onHotplugReceived(int32_t sequenceId, hwc2_display_t hwcDisplayId,
@@ -1904,6 +1895,20 @@
                 mGpuFrameMissedCount++;
             }
 
+            // If we are in the middle of a config change and the fence hasn't
+            // fired yet just wait for the next invalidate
+            if (mSetActiveConfigPending) {
+                if (framePending) {
+                    mEventQueue->invalidate();
+                    break;
+                }
+
+                // We received the present fence from the HWC, so we assume it successfully updated
+                // the config, hence we update SF.
+                mSetActiveConfigPending = false;
+                setActiveConfigInternal();
+            }
+
             if (framePending && mPropagateBackpressure) {
                 if ((hwcFrameMissed && !gpuFrameMissed) ||
                     mPropagateBackpressureClientComposition) {
@@ -1973,9 +1978,7 @@
                 mScheduler->chooseRefreshRateForContent();
             }
 
-            if (performSetActiveConfig()) {
-                break;
-            }
+            performSetActiveConfig();
 
             updateCursorAsync();
             updateInputFlinger();
@@ -2981,7 +2984,7 @@
     // classes from EventThread, and there should be no run-time binder cost
     // anyway since there are no connected apps at this point.
     const nsecs_t vsyncPeriod =
-            mRefreshRateConfigs->getRefreshRateFromConfigId(currentConfig).vsyncPeriod;
+            mRefreshRateConfigs->getRefreshRateFromConfigId(currentConfig).getVsyncPeriod();
     mScheduler->onConfigChanged(mAppConnectionHandle, primaryDisplayId.value, currentConfig,
                                 vsyncPeriod);
 }
@@ -5765,7 +5768,6 @@
     // buffer bounds.
     clientCompositionDisplay.physicalDisplay = Rect(reqWidth, reqHeight);
     clientCompositionDisplay.clip = sourceCrop;
-    clientCompositionDisplay.globalTransform = mat4();
     clientCompositionDisplay.orientation = rotation;
 
     clientCompositionDisplay.outputDataspace = renderArea.getReqDataSpace();
@@ -5968,7 +5970,8 @@
     // that listeners that care about a change in allowed configs can get the notification.
     // Giving current ActiveConfig so that most other listeners would just drop the event
     const nsecs_t vsyncPeriod =
-            mRefreshRateConfigs->getRefreshRateFromConfigId(display->getActiveConfig()).vsyncPeriod;
+            mRefreshRateConfigs->getRefreshRateFromConfigId(display->getActiveConfig())
+                    .getVsyncPeriod();
     mScheduler->onConfigChanged(mAppConnectionHandle, display->getId()->value,
                                 display->getActiveConfig(), vsyncPeriod);
 
@@ -5978,13 +5981,16 @@
             // NOTE: Choose the default config ID, if Scheduler doesn't have one in mind.
             : mRefreshRateConfigs->getRefreshRateFromConfigId(currentPolicy.defaultConfig);
     ALOGV("trying to switch to Scheduler preferred config %d (%s)",
-          preferredRefreshRate.configId.value(), preferredRefreshRate.name.c_str());
+          preferredRefreshRate.getConfigId().value(), preferredRefreshRate.getName().c_str());
 
-    if (isDisplayConfigAllowed(preferredRefreshRate.configId)) {
-        ALOGV("switching to Scheduler preferred config %d", preferredRefreshRate.configId.value());
-        setDesiredActiveConfig({preferredRefreshRate.configId, Scheduler::ConfigEvent::Changed});
+    if (isDisplayConfigAllowed(preferredRefreshRate.getConfigId())) {
+        ALOGV("switching to Scheduler preferred config %d",
+              preferredRefreshRate.getConfigId().value());
+        setDesiredActiveConfig(
+                {preferredRefreshRate.getConfigId(), Scheduler::ConfigEvent::Changed});
     } else {
-        LOG_ALWAYS_FATAL("Desired config not allowed: %d", preferredRefreshRate.configId.value());
+        LOG_ALWAYS_FATAL("Desired config not allowed: %d",
+                         preferredRefreshRate.getConfigId().value());
     }
 
     return NO_ERROR;
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 366874a..ec103b1 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -565,11 +565,9 @@
     // Once HWC has returned the present fence, this sets the active config and a new refresh
     // rate in SF.
     void setActiveConfigInternal() REQUIRES(mStateLock);
-    // Active config is updated on INVALIDATE call in a state machine-like manner. When the
-    // desired config was set, HWC needs to update the panel on the next refresh, and when
-    // we receive the fence back, we know that the process was complete. It returns whether
-    // we need to wait for the next invalidate
-    bool performSetActiveConfig() REQUIRES(mStateLock);
+    // Calls to setActiveConfig on the main thread if there is a pending config
+    // that needs to be applied.
+    void performSetActiveConfig() REQUIRES(mStateLock);
     // Called when active config is no longer is progress
     void desiredActiveConfigChangeDone() REQUIRES(mStateLock);
     // called on the main thread in response to setPowerMode()
@@ -1229,7 +1227,7 @@
     // below flags are set by main thread only
     TracedOrdinal<bool> mDesiredActiveConfigChanged
             GUARDED_BY(mActiveConfigLock) = {"DesiredActiveConfigChanged", false};
-    bool mCheckPendingFence = false;
+    bool mSetActiveConfigPending = false;
 
     bool mLumaSampling = true;
     sp<RegionSamplingThread> mRegionSamplingThread;
diff --git a/services/surfaceflinger/tests/hwc2/Android.bp b/services/surfaceflinger/tests/hwc2/Android.bp
index 021699d..06a9d10 100644
--- a/services/surfaceflinger/tests/hwc2/Android.bp
+++ b/services/surfaceflinger/tests/hwc2/Android.bp
@@ -44,7 +44,7 @@
         "libGLESv2",
         "libgui",
         "libhardware",
-        "libhwui",
+        "libjnigraphics",
         "liblog",
         "libsync",
         "libui",
diff --git a/services/surfaceflinger/tests/hwc2/Hwc2TestBuffer.cpp b/services/surfaceflinger/tests/hwc2/Hwc2TestBuffer.cpp
index fcd0d31..4f5c32e 100644
--- a/services/surfaceflinger/tests/hwc2/Hwc2TestBuffer.cpp
+++ b/services/surfaceflinger/tests/hwc2/Hwc2TestBuffer.cpp
@@ -28,11 +28,10 @@
 
 #include <ui/GraphicBuffer.h>
 #include <android/hardware/graphics/common/1.0/types.h>
+#include <android/bitmap.h>
 #include <math/vec4.h>
 
 #include <GLES3/gl3.h>
-#include <SkImageEncoder.h>
-#include <SkStream.h>
 #include "Hwc2TestBuffer.h"
 #include "Hwc2TestLayers.h"
 
@@ -727,21 +726,37 @@
 
 bool Hwc2TestVirtualBuffer::writeBufferToFile(std::string path)
 {
-    SkFILEWStream file(path.c_str());
-    const SkImageInfo info = SkImageInfo::Make(mBufferArea.width,
-            mBufferArea.height, SkColorType::kRGBA_8888_SkColorType,
-            SkAlphaType::kPremul_SkAlphaType);
+    int fd = open(path.c_str(), O_WRONLY | O_CREAT | O_TRUNC, 0664);
+    if (fd == -1) {
+        ALOGW("Error opening file: %s (%s)\n", path.c_str(), strerror(errno));
+        return false;
+    }
 
     uint8_t* img;
-    mGraphicBuffer->lock(static_cast<uint32_t>(BufferUsage::CPU_WRITE_OFTEN),
-            (void**)(&img));
+    mGraphicBuffer->lock(static_cast<uint32_t>(BufferUsage::CPU_WRITE_OFTEN), (void**)(&img));
 
-    SkPixmap pixmap(info, img, mGraphicBuffer->getStride());
-    bool result = file.isValid() && SkEncodeImage(&file, pixmap,
-            SkEncodedImageFormat::kPNG, 100);
+    AndroidBitmapInfo info;
+    info.format = ANDROID_BITMAP_FORMAT_RGBA_8888;
+    info.flags = ANDROID_BITMAP_FLAGS_ALPHA_PREMUL;
+    info.width = mBufferArea.width;
+    info.height = mBufferArea.height;
+    info.stride = mGraphicBuffer->getStride() * bytesPerPixel(ANDROID_BITMAP_FORMAT_RGBA_8888);
+
+    int result = AndroidBitmap_compress(&info, ADATASPACE_SRGB, img,
+                                        ANDROID_BITMAP_COMPRESS_FORMAT_PNG, 100, &fd,
+                                        [](void* fdPtr, const void* data, size_t size) -> bool {
+                                            size_t bytesWritten =
+                                                    write(*static_cast<int*>(fdPtr), data, size);
+                                            return bytesWritten == size;
+                                        });
+
+    if (result != ANDROID_BITMAP_RESULT_SUCCESS) {
+        ALOGW("Failed to compress PNG (error code: %d)\n", result);
+    }
 
     mGraphicBuffer->unlock();
-    return result;
+    close(fd);
+    return result == ANDROID_BITMAP_RESULT_SUCCESS;
 }
 
 /* Generates a buffer that holds the expected result of compositing all of our
diff --git a/services/surfaceflinger/tests/unittests/LayerHistoryTest.cpp b/services/surfaceflinger/tests/unittests/LayerHistoryTest.cpp
index 7557faf..71d17a9 100644
--- a/services/surfaceflinger/tests/unittests/LayerHistoryTest.cpp
+++ b/services/surfaceflinger/tests/unittests/LayerHistoryTest.cpp
@@ -63,14 +63,15 @@
 
     auto createLayer() { return sp<mock::MockLayer>(new mock::MockLayer(mFlinger.flinger())); }
 
-    RefreshRateConfigs mConfigs{{
-                                        RefreshRateConfigs::InputConfig{HwcConfigIndexType(0),
-                                                                        HwcConfigGroupType(0),
-                                                                        LO_FPS_PERIOD},
-                                        RefreshRateConfigs::InputConfig{HwcConfigIndexType(1),
-                                                                        HwcConfigGroupType(0),
-                                                                        HI_FPS_PERIOD},
-                                },
+    Hwc2::mock::Display mDisplay;
+    RefreshRateConfigs mConfigs{{HWC2::Display::Config::Builder(mDisplay, 0)
+                                         .setVsyncPeriod(int32_t(LO_FPS_PERIOD))
+                                         .setConfigGroup(0)
+                                         .build(),
+                                 HWC2::Display::Config::Builder(mDisplay, 1)
+                                         .setVsyncPeriod(int32_t(HI_FPS_PERIOD))
+                                         .setConfigGroup(0)
+                                         .build()},
                                 HwcConfigIndexType(0)};
     TestableScheduler* const mScheduler{new TestableScheduler(mConfigs, false)};
     TestableSurfaceFlinger mFlinger;
diff --git a/services/surfaceflinger/tests/unittests/LayerHistoryTestV2.cpp b/services/surfaceflinger/tests/unittests/LayerHistoryTestV2.cpp
index 8559a5e..71e37a8 100644
--- a/services/surfaceflinger/tests/unittests/LayerHistoryTestV2.cpp
+++ b/services/surfaceflinger/tests/unittests/LayerHistoryTestV2.cpp
@@ -72,14 +72,15 @@
 
     auto createLayer() { return sp<mock::MockLayer>(new mock::MockLayer(mFlinger.flinger())); }
 
-    RefreshRateConfigs mConfigs{{
-                                        RefreshRateConfigs::InputConfig{HwcConfigIndexType(0),
-                                                                        HwcConfigGroupType(0),
-                                                                        LO_FPS_PERIOD},
-                                        RefreshRateConfigs::InputConfig{HwcConfigIndexType(1),
-                                                                        HwcConfigGroupType(0),
-                                                                        HI_FPS_PERIOD},
-                                },
+    Hwc2::mock::Display mDisplay;
+    RefreshRateConfigs mConfigs{{HWC2::Display::Config::Builder(mDisplay, 0)
+                                         .setVsyncPeriod(int32_t(LO_FPS_PERIOD))
+                                         .setConfigGroup(0)
+                                         .build(),
+                                 HWC2::Display::Config::Builder(mDisplay, 1)
+                                         .setVsyncPeriod(int32_t(HI_FPS_PERIOD))
+                                         .setConfigGroup(0)
+                                         .build()},
                                 HwcConfigIndexType(0)};
     TestableScheduler* const mScheduler{new TestableScheduler(mConfigs, true)};
     TestableSurfaceFlinger mFlinger;
diff --git a/services/surfaceflinger/tests/unittests/RefreshRateConfigsTest.cpp b/services/surfaceflinger/tests/unittests/RefreshRateConfigsTest.cpp
index ce41291..1b8f11b 100644
--- a/services/surfaceflinger/tests/unittests/RefreshRateConfigsTest.cpp
+++ b/services/surfaceflinger/tests/unittests/RefreshRateConfigsTest.cpp
@@ -24,6 +24,7 @@
 #include "../../Scheduler/RefreshRateConfigs.h"
 #include "DisplayHardware/HWC2.h"
 #include "Scheduler/RefreshRateConfigs.h"
+#include "mock/DisplayHardware/MockDisplay.h"
 
 using namespace std::chrono_literals;
 using testing::_;
@@ -37,24 +38,95 @@
 
 class RefreshRateConfigsTest : public testing::Test {
 protected:
-    static inline const HwcConfigIndexType HWC_CONFIG_ID_60 = HwcConfigIndexType(0);
-    static inline const HwcConfigIndexType HWC_CONFIG_ID_72 = HwcConfigIndexType(1);
-    static inline const HwcConfigIndexType HWC_CONFIG_ID_90 = HwcConfigIndexType(2);
-    static inline const HwcConfigIndexType HWC_CONFIG_ID_120 = HwcConfigIndexType(3);
-    static inline const HwcConfigIndexType HWC_CONFIG_ID_30 = HwcConfigIndexType(4);
-    static inline const HwcConfigGroupType HWC_GROUP_ID_0 = HwcConfigGroupType(0);
-    static inline const HwcConfigGroupType HWC_GROUP_ID_1 = HwcConfigGroupType(1);
-    static constexpr auto VSYNC_30 = static_cast<int64_t>(1e9f / 30);
-    static constexpr auto VSYNC_60 = static_cast<int64_t>(1e9f / 60);
-    static constexpr auto VSYNC_72 = static_cast<int64_t>(1e9f / 72);
-    static constexpr auto VSYNC_90 = static_cast<int64_t>(1e9f / 90);
-    static constexpr auto VSYNC_120 = static_cast<int64_t>(1e9f / 120);
-    static constexpr int64_t VSYNC_60_POINT_4 = 16666665;
-
     RefreshRateConfigsTest();
     ~RefreshRateConfigsTest();
+
+    // Test config IDs
+    static inline const HwcConfigIndexType HWC_CONFIG_ID_60 = HwcConfigIndexType(0);
+    static inline const HwcConfigIndexType HWC_CONFIG_ID_90 = HwcConfigIndexType(1);
+    static inline const HwcConfigIndexType HWC_CONFIG_ID_72 = HwcConfigIndexType(2);
+    static inline const HwcConfigIndexType HWC_CONFIG_ID_120 = HwcConfigIndexType(3);
+    static inline const HwcConfigIndexType HWC_CONFIG_ID_30 = HwcConfigIndexType(4);
+
+    // Test configs
+    std::shared_ptr<const HWC2::Display::Config> mConfig60 =
+            createConfig(HWC_CONFIG_ID_60, 0, static_cast<int64_t>(1e9f / 60));
+    std::shared_ptr<const HWC2::Display::Config> mConfig90 =
+            createConfig(HWC_CONFIG_ID_90, 0, static_cast<int64_t>(1e9f / 90));
+    std::shared_ptr<const HWC2::Display::Config> mConfig90DifferentGroup =
+            createConfig(HWC_CONFIG_ID_90, 1, static_cast<int64_t>(1e9f / 90));
+    std::shared_ptr<const HWC2::Display::Config> mConfig90DifferentResolution =
+            createConfig(HWC_CONFIG_ID_90, 0, static_cast<int64_t>(1e9f / 90), 111, 222);
+    std::shared_ptr<const HWC2::Display::Config> mConfig72 =
+            createConfig(HWC_CONFIG_ID_72, 0, static_cast<int64_t>(1e9f / 72));
+    std::shared_ptr<const HWC2::Display::Config> mConfig72DifferentGroup =
+            createConfig(HWC_CONFIG_ID_72, 1, static_cast<int64_t>(1e9f / 72));
+    std::shared_ptr<const HWC2::Display::Config> mConfig120 =
+            createConfig(HWC_CONFIG_ID_120, 0, static_cast<int64_t>(1e9f / 120));
+    std::shared_ptr<const HWC2::Display::Config> mConfig120DifferentGroup =
+            createConfig(HWC_CONFIG_ID_120, 1, static_cast<int64_t>(1e9f / 120));
+    std::shared_ptr<const HWC2::Display::Config> mConfig30 =
+            createConfig(HWC_CONFIG_ID_30, 0, static_cast<int64_t>(1e9f / 30));
+
+    // Test device configurations
+    std::vector<std::shared_ptr<const HWC2::Display::Config>> m60OnlyConfigDevice = {mConfig60};
+    std::vector<std::shared_ptr<const HWC2::Display::Config>> m60_90Device = {mConfig60, mConfig90};
+    std::vector<std::shared_ptr<const HWC2::Display::Config>> m60_90DeviceWithDifferentGroups =
+            {mConfig60, mConfig90DifferentGroup};
+    std::vector<std::shared_ptr<const HWC2::Display::Config>> m60_90DeviceWithDifferentResolutions =
+            {mConfig60, mConfig90DifferentResolution};
+    std::vector<std::shared_ptr<const HWC2::Display::Config>> m60_72_90Device = {mConfig60,
+                                                                                 mConfig90,
+                                                                                 mConfig72};
+    std::vector<std::shared_ptr<const HWC2::Display::Config>> m60_90_72_120Device = {mConfig60,
+                                                                                     mConfig90,
+                                                                                     mConfig72,
+                                                                                     mConfig120};
+    std::vector<std::shared_ptr<const HWC2::Display::Config>> m30_60_72_90_120Device = {mConfig60,
+                                                                                        mConfig90,
+                                                                                        mConfig72,
+                                                                                        mConfig120,
+                                                                                        mConfig30};
+    std::vector<std::shared_ptr<const HWC2::Display::Config>> m30_60Device =
+            {mConfig60, mConfig90DifferentGroup, mConfig72DifferentGroup, mConfig120DifferentGroup,
+             mConfig30};
+    std::vector<std::shared_ptr<const HWC2::Display::Config>> m30_60_72_90Device =
+            {mConfig60, mConfig90, mConfig72, mConfig120DifferentGroup, mConfig30};
+    std::vector<std::shared_ptr<const HWC2::Display::Config>> m30_60_90Device =
+            {mConfig60, mConfig90, mConfig72DifferentGroup, mConfig120DifferentGroup, mConfig30};
+
+    // Expected RefreshRate objects
+    RefreshRate mExpected60Config = {HWC_CONFIG_ID_60, mConfig60, "60fps", 60,
+                                     RefreshRate::ConstructorTag(0)};
+    RefreshRate mExpectedAlmost60Config = {HWC_CONFIG_ID_60,
+                                           createConfig(HWC_CONFIG_ID_60, 0, 16666665), "60fps", 60,
+                                           RefreshRate::ConstructorTag(0)};
+    RefreshRate mExpected90Config = {HWC_CONFIG_ID_90, mConfig90, "90fps", 90,
+                                     RefreshRate::ConstructorTag(0)};
+    RefreshRate mExpected90DifferentGroupConfig = {HWC_CONFIG_ID_90, mConfig90DifferentGroup,
+                                                   "90fps", 90, RefreshRate::ConstructorTag(0)};
+    RefreshRate mExpected90DifferentResolutionConfig = {HWC_CONFIG_ID_90,
+                                                        mConfig90DifferentResolution, "90fps", 90,
+                                                        RefreshRate::ConstructorTag(0)};
+    RefreshRate mExpected72Config = {HWC_CONFIG_ID_72, mConfig72, "72fps", 72,
+                                     RefreshRate::ConstructorTag(0)};
+    RefreshRate mExpected30Config = {HWC_CONFIG_ID_30, mConfig30, "30fps", 30,
+                                     RefreshRate::ConstructorTag(0)};
+    RefreshRate mExpected120Config = {HWC_CONFIG_ID_120, mConfig120, "120fps", 120,
+                                      RefreshRate::ConstructorTag(0)};
+
+    Hwc2::mock::Display mDisplay;
+
+private:
+    std::shared_ptr<const HWC2::Display::Config> createConfig(HwcConfigIndexType configId,
+                                                              int32_t configGroup,
+                                                              int64_t vsyncPeriod,
+                                                              int32_t hight = -1,
+                                                              int32_t width = -1);
 };
 
+using Builder = HWC2::Display::Config::Builder;
+
 RefreshRateConfigsTest::RefreshRateConfigsTest() {
     const ::testing::TestInfo* const test_info =
             ::testing::UnitTest::GetInstance()->current_test_info();
@@ -67,41 +139,45 @@
     ALOGD("**** Tearing down after %s.%s\n", test_info->test_case_name(), test_info->name());
 }
 
+std::shared_ptr<const HWC2::Display::Config> RefreshRateConfigsTest::createConfig(
+        HwcConfigIndexType configId, int32_t configGroup, int64_t vsyncPeriod, int32_t hight,
+        int32_t width) {
+    return HWC2::Display::Config::Builder(mDisplay, hwc2_config_t(configId.value()))
+            .setVsyncPeriod(int32_t(vsyncPeriod))
+            .setConfigGroup(configGroup)
+            .setHeight(hight)
+            .setWidth(width)
+            .build();
+}
+
 namespace {
 /* ------------------------------------------------------------------------
  * Test cases
  */
 TEST_F(RefreshRateConfigsTest, oneDeviceConfig_SwitchingSupported) {
-    std::vector<RefreshRateConfigs::InputConfig> configs{
-            {{HWC_CONFIG_ID_60, HWC_GROUP_ID_0, VSYNC_60}}};
     auto refreshRateConfigs =
-            std::make_unique<RefreshRateConfigs>(configs, /*currentConfigId=*/HWC_CONFIG_ID_60);
+            std::make_unique<RefreshRateConfigs>(m60OnlyConfigDevice,
+                                                 /*currentConfigId=*/HWC_CONFIG_ID_60);
 }
 
 TEST_F(RefreshRateConfigsTest, invalidPolicy) {
-    std::vector<RefreshRateConfigs::InputConfig> configs{
-            {{HWC_CONFIG_ID_60, HWC_GROUP_ID_0, VSYNC_60}}};
     auto refreshRateConfigs =
-            std::make_unique<RefreshRateConfigs>(configs, /*currentConfigId=*/HWC_CONFIG_ID_60);
+            std::make_unique<RefreshRateConfigs>(m60OnlyConfigDevice,
+                                                 /*currentConfigId=*/HWC_CONFIG_ID_60);
     ASSERT_LT(refreshRateConfigs->setDisplayManagerPolicy({HwcConfigIndexType(10), 60, 60}), 0);
     ASSERT_LT(refreshRateConfigs->setDisplayManagerPolicy({HWC_CONFIG_ID_60, 20, 40}), 0);
 }
 
 TEST_F(RefreshRateConfigsTest, twoDeviceConfigs_storesFullRefreshRateMap) {
-    std::vector<RefreshRateConfigs::InputConfig> configs{
-            {{HWC_CONFIG_ID_60, HWC_GROUP_ID_0, VSYNC_60},
-             {HWC_CONFIG_ID_90, HWC_GROUP_ID_0, VSYNC_90}}};
     auto refreshRateConfigs =
-            std::make_unique<RefreshRateConfigs>(configs, /*currentConfigId=*/HWC_CONFIG_ID_60);
+            std::make_unique<RefreshRateConfigs>(m60_90Device,
+                                                 /*currentConfigId=*/HWC_CONFIG_ID_60);
 
     const auto& minRate = refreshRateConfigs->getMinRefreshRate();
     const auto& performanceRate = refreshRateConfigs->getMaxRefreshRate();
 
-    RefreshRate expectedDefaultConfig = {HWC_CONFIG_ID_60, VSYNC_60, HWC_GROUP_ID_0, "60fps", 60};
-    ASSERT_EQ(expectedDefaultConfig, minRate);
-    RefreshRate expectedPerformanceConfig = {HWC_CONFIG_ID_90, VSYNC_90, HWC_GROUP_ID_0, "90fps",
-                                             90};
-    ASSERT_EQ(expectedPerformanceConfig, performanceRate);
+    ASSERT_EQ(mExpected60Config, minRate);
+    ASSERT_EQ(mExpected90Config, performanceRate);
 
     const auto& minRateByPolicy = refreshRateConfigs->getMinRefreshRateByPolicy();
     const auto& performanceRateByPolicy = refreshRateConfigs->getMaxRefreshRateByPolicy();
@@ -110,21 +186,18 @@
 }
 
 TEST_F(RefreshRateConfigsTest, twoDeviceConfigs_storesFullRefreshRateMap_differentGroups) {
-    std::vector<RefreshRateConfigs::InputConfig> configs{
-            {{HWC_CONFIG_ID_60, HWC_GROUP_ID_0, VSYNC_60},
-             {HWC_CONFIG_ID_90, HWC_GROUP_ID_1, VSYNC_90}}};
     auto refreshRateConfigs =
-            std::make_unique<RefreshRateConfigs>(configs, /*currentConfigId=*/HWC_CONFIG_ID_60);
+            std::make_unique<RefreshRateConfigs>(m60_90DeviceWithDifferentGroups,
+                                                 /*currentConfigId=*/HWC_CONFIG_ID_60);
 
     const auto& minRate = refreshRateConfigs->getMinRefreshRateByPolicy();
     const auto& performanceRate = refreshRateConfigs->getMaxRefreshRate();
     const auto& minRate60 = refreshRateConfigs->getMinRefreshRateByPolicy();
     const auto& performanceRate60 = refreshRateConfigs->getMaxRefreshRateByPolicy();
 
-    RefreshRate expectedDefaultConfig = {HWC_CONFIG_ID_60, VSYNC_60, HWC_GROUP_ID_0, "60fps", 60};
-    ASSERT_EQ(expectedDefaultConfig, minRate);
-    ASSERT_EQ(expectedDefaultConfig, minRate60);
-    ASSERT_EQ(expectedDefaultConfig, performanceRate60);
+    ASSERT_EQ(mExpected60Config, minRate);
+    ASSERT_EQ(mExpected60Config, minRate60);
+    ASSERT_EQ(mExpected60Config, performanceRate60);
 
     ASSERT_GE(refreshRateConfigs->setDisplayManagerPolicy({HWC_CONFIG_ID_90, 60, 90}), 0);
     refreshRateConfigs->setCurrentConfigId(HWC_CONFIG_ID_90);
@@ -132,202 +205,202 @@
     const auto& minRate90 = refreshRateConfigs->getMinRefreshRateByPolicy();
     const auto& performanceRate90 = refreshRateConfigs->getMaxRefreshRateByPolicy();
 
-    RefreshRate expectedPerformanceConfig = {HWC_CONFIG_ID_90, VSYNC_90, HWC_GROUP_ID_1, "90fps",
-                                             90};
-    ASSERT_EQ(expectedPerformanceConfig, performanceRate);
-    ASSERT_EQ(expectedPerformanceConfig, minRate90);
-    ASSERT_EQ(expectedPerformanceConfig, performanceRate90);
+    ASSERT_EQ(mExpected90DifferentGroupConfig, performanceRate);
+    ASSERT_EQ(mExpected90DifferentGroupConfig, minRate90);
+    ASSERT_EQ(mExpected90DifferentGroupConfig, performanceRate90);
+}
+
+TEST_F(RefreshRateConfigsTest, twoDeviceConfigs_storesFullRefreshRateMap_differentResolutions) {
+    auto refreshRateConfigs =
+            std::make_unique<RefreshRateConfigs>(m60_90DeviceWithDifferentResolutions,
+                                                 /*currentConfigId=*/HWC_CONFIG_ID_60);
+
+    const auto& minRate = refreshRateConfigs->getMinRefreshRateByPolicy();
+    const auto& performanceRate = refreshRateConfigs->getMaxRefreshRate();
+    const auto& minRate60 = refreshRateConfigs->getMinRefreshRateByPolicy();
+    const auto& performanceRate60 = refreshRateConfigs->getMaxRefreshRateByPolicy();
+
+    ASSERT_EQ(mExpected60Config, minRate);
+    ASSERT_EQ(mExpected60Config, minRate60);
+    ASSERT_EQ(mExpected60Config, performanceRate60);
+
+    ASSERT_GE(refreshRateConfigs->setDisplayManagerPolicy({HWC_CONFIG_ID_90, 60, 90}), 0);
+    refreshRateConfigs->setCurrentConfigId(HWC_CONFIG_ID_90);
+
+    const auto& minRate90 = refreshRateConfigs->getMinRefreshRateByPolicy();
+    const auto& performanceRate90 = refreshRateConfigs->getMaxRefreshRateByPolicy();
+
+    ASSERT_EQ(mExpected90DifferentResolutionConfig, performanceRate);
+    ASSERT_EQ(mExpected90DifferentResolutionConfig, minRate90);
+    ASSERT_EQ(mExpected90DifferentResolutionConfig, performanceRate90);
 }
 
 TEST_F(RefreshRateConfigsTest, twoDeviceConfigs_policyChange) {
-    std::vector<RefreshRateConfigs::InputConfig> configs{
-            {{HWC_CONFIG_ID_60, HWC_GROUP_ID_0, VSYNC_60},
-             {HWC_CONFIG_ID_90, HWC_GROUP_ID_0, VSYNC_90}}};
     auto refreshRateConfigs =
-            std::make_unique<RefreshRateConfigs>(configs, /*currentConfigId=*/HWC_CONFIG_ID_60);
+            std::make_unique<RefreshRateConfigs>(m60_90Device,
+                                                 /*currentConfigId=*/HWC_CONFIG_ID_60);
 
     auto& minRate = refreshRateConfigs->getMinRefreshRateByPolicy();
     auto& performanceRate = refreshRateConfigs->getMaxRefreshRateByPolicy();
 
-    RefreshRate expectedDefaultConfig = {HWC_CONFIG_ID_60, VSYNC_60, HWC_GROUP_ID_0, "60fps", 60};
-    ASSERT_EQ(expectedDefaultConfig, minRate);
-    RefreshRate expectedPerformanceConfig = {HWC_CONFIG_ID_90, VSYNC_90, HWC_GROUP_ID_0, "90fps",
-                                             90};
-    ASSERT_EQ(expectedPerformanceConfig, performanceRate);
+    ASSERT_EQ(mExpected60Config, minRate);
+    ASSERT_EQ(mExpected90Config, performanceRate);
 
     ASSERT_GE(refreshRateConfigs->setDisplayManagerPolicy({HWC_CONFIG_ID_60, 60, 60}), 0);
 
     auto& minRate60 = refreshRateConfigs->getMinRefreshRateByPolicy();
     auto& performanceRate60 = refreshRateConfigs->getMaxRefreshRateByPolicy();
-    ASSERT_EQ(expectedDefaultConfig, minRate60);
-    ASSERT_EQ(expectedDefaultConfig, performanceRate60);
+    ASSERT_EQ(mExpected60Config, minRate60);
+    ASSERT_EQ(mExpected60Config, performanceRate60);
 }
 
 TEST_F(RefreshRateConfigsTest, twoDeviceConfigs_getCurrentRefreshRate) {
-    std::vector<RefreshRateConfigs::InputConfig> configs{
-            {{HWC_CONFIG_ID_60, HWC_GROUP_ID_0, VSYNC_60},
-             {HWC_CONFIG_ID_90, HWC_GROUP_ID_0, VSYNC_90}}};
     auto refreshRateConfigs =
-            std::make_unique<RefreshRateConfigs>(configs, /*currentConfigId=*/HWC_CONFIG_ID_60);
+            std::make_unique<RefreshRateConfigs>(m60_90Device,
+                                                 /*currentConfigId=*/HWC_CONFIG_ID_60);
     {
         auto& current = refreshRateConfigs->getCurrentRefreshRate();
-        EXPECT_EQ(current.configId, HWC_CONFIG_ID_60);
+        EXPECT_EQ(current.getConfigId(), HWC_CONFIG_ID_60);
     }
 
     refreshRateConfigs->setCurrentConfigId(HWC_CONFIG_ID_90);
     {
         auto& current = refreshRateConfigs->getCurrentRefreshRate();
-        EXPECT_EQ(current.configId, HWC_CONFIG_ID_90);
+        EXPECT_EQ(current.getConfigId(), HWC_CONFIG_ID_90);
     }
 
     ASSERT_GE(refreshRateConfigs->setDisplayManagerPolicy({HWC_CONFIG_ID_90, 90, 90}), 0);
     {
         auto& current = refreshRateConfigs->getCurrentRefreshRate();
-        EXPECT_EQ(current.configId, HWC_CONFIG_ID_90);
+        EXPECT_EQ(current.getConfigId(), HWC_CONFIG_ID_90);
     }
 }
 
 TEST_F(RefreshRateConfigsTest, twoDeviceConfigs_getRefreshRateForContent) {
-    std::vector<RefreshRateConfigs::InputConfig> configs{
-            {{HWC_CONFIG_ID_60, HWC_GROUP_ID_0, VSYNC_60},
-             {HWC_CONFIG_ID_90, HWC_GROUP_ID_0, VSYNC_90}}};
     auto refreshRateConfigs =
-            std::make_unique<RefreshRateConfigs>(configs, /*currentConfigId=*/HWC_CONFIG_ID_60);
-
-    RefreshRate expected60Config = {HWC_CONFIG_ID_60, VSYNC_60, HWC_GROUP_ID_0, "60fps", 60};
-    RefreshRate expected90Config = {HWC_CONFIG_ID_90, VSYNC_90, HWC_GROUP_ID_0, "90fps", 90};
+            std::make_unique<RefreshRateConfigs>(m60_90Device,
+                                                 /*currentConfigId=*/HWC_CONFIG_ID_60);
 
     const auto makeLayerRequirements = [](float refreshRate) -> std::vector<LayerRequirement> {
         return {{"testLayer", LayerVoteType::Heuristic, refreshRate, 1.0f}};
     };
 
-    EXPECT_EQ(expected90Config,
+    EXPECT_EQ(mExpected90Config,
               refreshRateConfigs->getRefreshRateForContent(makeLayerRequirements(90.0f)));
-    EXPECT_EQ(expected60Config,
+    EXPECT_EQ(mExpected60Config,
               refreshRateConfigs->getRefreshRateForContent(makeLayerRequirements(60.0f)));
-    EXPECT_EQ(expected90Config,
+    EXPECT_EQ(mExpected90Config,
               refreshRateConfigs->getRefreshRateForContent(makeLayerRequirements(45.0f)));
-    EXPECT_EQ(expected60Config,
+    EXPECT_EQ(mExpected60Config,
               refreshRateConfigs->getRefreshRateForContent(makeLayerRequirements(30.0f)));
-    EXPECT_EQ(expected60Config,
+    EXPECT_EQ(mExpected60Config,
               refreshRateConfigs->getRefreshRateForContent(makeLayerRequirements(24.0f)));
 
     ASSERT_GE(refreshRateConfigs->setDisplayManagerPolicy({HWC_CONFIG_ID_60, 60, 60}), 0);
-    EXPECT_EQ(expected60Config,
+    EXPECT_EQ(mExpected60Config,
               refreshRateConfigs->getRefreshRateForContent(makeLayerRequirements(90.0f)));
-    EXPECT_EQ(expected60Config,
+    EXPECT_EQ(mExpected60Config,
               refreshRateConfigs->getRefreshRateForContent(makeLayerRequirements(60.0f)));
-    EXPECT_EQ(expected60Config,
+    EXPECT_EQ(mExpected60Config,
               refreshRateConfigs->getRefreshRateForContent(makeLayerRequirements(45.0f)));
-    EXPECT_EQ(expected60Config,
+    EXPECT_EQ(mExpected60Config,
               refreshRateConfigs->getRefreshRateForContent(makeLayerRequirements(30.0f)));
-    EXPECT_EQ(expected60Config,
+    EXPECT_EQ(mExpected60Config,
               refreshRateConfigs->getRefreshRateForContent(makeLayerRequirements(24.0f)));
 
     ASSERT_GE(refreshRateConfigs->setDisplayManagerPolicy({HWC_CONFIG_ID_90, 90, 90}), 0);
-    EXPECT_EQ(expected90Config,
+    EXPECT_EQ(mExpected90Config,
               refreshRateConfigs->getRefreshRateForContent(makeLayerRequirements(90.0f)));
-    EXPECT_EQ(expected90Config,
+    EXPECT_EQ(mExpected90Config,
               refreshRateConfigs->getRefreshRateForContent(makeLayerRequirements(60.0f)));
-    EXPECT_EQ(expected90Config,
+    EXPECT_EQ(mExpected90Config,
               refreshRateConfigs->getRefreshRateForContent(makeLayerRequirements(45.0f)));
-    EXPECT_EQ(expected90Config,
+    EXPECT_EQ(mExpected90Config,
               refreshRateConfigs->getRefreshRateForContent(makeLayerRequirements(30.0f)));
-    EXPECT_EQ(expected90Config,
+    EXPECT_EQ(mExpected90Config,
               refreshRateConfigs->getRefreshRateForContent(makeLayerRequirements(24.0f)));
     ASSERT_GE(refreshRateConfigs->setDisplayManagerPolicy({HWC_CONFIG_ID_60, 0, 120}), 0);
-    EXPECT_EQ(expected90Config,
+    EXPECT_EQ(mExpected90Config,
               refreshRateConfigs->getRefreshRateForContent(makeLayerRequirements(90.0f)));
-    EXPECT_EQ(expected60Config,
+    EXPECT_EQ(mExpected60Config,
               refreshRateConfigs->getRefreshRateForContent(makeLayerRequirements(60.0f)));
-    EXPECT_EQ(expected90Config,
+    EXPECT_EQ(mExpected90Config,
               refreshRateConfigs->getRefreshRateForContent(makeLayerRequirements(45.0f)));
-    EXPECT_EQ(expected60Config,
+    EXPECT_EQ(mExpected60Config,
               refreshRateConfigs->getRefreshRateForContent(makeLayerRequirements(30.0f)));
-    EXPECT_EQ(expected60Config,
+    EXPECT_EQ(mExpected60Config,
               refreshRateConfigs->getRefreshRateForContent(makeLayerRequirements(24.0f)));
 }
 
 TEST_F(RefreshRateConfigsTest, getRefreshRateForContentV2_noLayers) {
     bool ignored;
-    std::vector<RefreshRateConfigs::InputConfig> configs{
-            {{HWC_CONFIG_ID_60, HWC_GROUP_ID_0, VSYNC_60},
-             {HWC_CONFIG_ID_72, HWC_GROUP_ID_0, VSYNC_72},
-             {HWC_CONFIG_ID_90, HWC_GROUP_ID_0, VSYNC_90}}};
-    auto refreshRateConfigs = std::make_unique<RefreshRateConfigs>(configs, /*currentConfigId=*/
-                                                                   HWC_CONFIG_ID_72);
-
-    RefreshRate expected60Config = {HWC_CONFIG_ID_60, VSYNC_60, HWC_GROUP_ID_0, "60fps", 60};
-    RefreshRate expected72Config = {HWC_CONFIG_ID_72, VSYNC_72, HWC_GROUP_ID_0, "72fps", 72};
+    auto refreshRateConfigs =
+            std::make_unique<RefreshRateConfigs>(m60_72_90Device, /*currentConfigId=*/
+                                                 HWC_CONFIG_ID_72);
 
     // If there are not layers, there is not content detection, so return the current
     // refresh rate.
     auto layers = std::vector<LayerRequirement>{};
-    EXPECT_EQ(expected72Config,
+    EXPECT_EQ(mExpected72Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/
                                                              false, &ignored));
 
     // Current refresh rate can always be changed.
     refreshRateConfigs->setCurrentConfigId(HWC_CONFIG_ID_60);
-    EXPECT_EQ(expected60Config,
+    EXPECT_EQ(mExpected60Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/
                                                              false, &ignored));
 }
 
 TEST_F(RefreshRateConfigsTest, getRefreshRateForContentV2_60_90) {
     bool ignored;
-    std::vector<RefreshRateConfigs::InputConfig> configs{
-            {{HWC_CONFIG_ID_60, HWC_GROUP_ID_0, VSYNC_60},
-             {HWC_CONFIG_ID_90, HWC_GROUP_ID_0, VSYNC_90}}};
     auto refreshRateConfigs =
-            std::make_unique<RefreshRateConfigs>(configs, /*currentConfigId=*/HWC_CONFIG_ID_60);
-
-    RefreshRate expected60Config = {HWC_CONFIG_ID_60, VSYNC_60, HWC_GROUP_ID_0, "60fps", 60};
-    RefreshRate expected90Config = {HWC_CONFIG_ID_90, VSYNC_90, HWC_GROUP_ID_0, "90fps", 90};
+            std::make_unique<RefreshRateConfigs>(m60_90Device,
+                                                 /*currentConfigId=*/HWC_CONFIG_ID_60);
 
     auto layers = std::vector<LayerRequirement>{LayerRequirement{.weight = 1.0f}};
     auto& lr = layers[0];
 
     lr.vote = LayerVoteType::Min;
     lr.name = "Min";
-    EXPECT_EQ(expected60Config,
+    EXPECT_EQ(mExpected60Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                              &ignored));
 
     lr.vote = LayerVoteType::Max;
     lr.name = "Max";
-    EXPECT_EQ(expected90Config,
+    EXPECT_EQ(mExpected90Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                              &ignored));
 
     lr.desiredRefreshRate = 90.0f;
     lr.vote = LayerVoteType::Heuristic;
     lr.name = "90Hz Heuristic";
-    EXPECT_EQ(expected90Config,
+    EXPECT_EQ(mExpected90Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                              &ignored));
 
     lr.desiredRefreshRate = 60.0f;
     lr.name = "60Hz Heuristic";
-    EXPECT_EQ(expected60Config,
+    EXPECT_EQ(mExpected60Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                              &ignored));
 
     lr.desiredRefreshRate = 45.0f;
     lr.name = "45Hz Heuristic";
-    EXPECT_EQ(expected90Config,
+    EXPECT_EQ(mExpected90Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                              &ignored));
 
     lr.desiredRefreshRate = 30.0f;
     lr.name = "30Hz Heuristic";
-    EXPECT_EQ(expected60Config,
+    EXPECT_EQ(mExpected60Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                              &ignored));
 
     lr.desiredRefreshRate = 24.0f;
     lr.name = "24Hz Heuristic";
-    EXPECT_EQ(expected60Config,
+    EXPECT_EQ(mExpected60Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                              &ignored));
 
@@ -335,186 +408,168 @@
     ASSERT_GE(refreshRateConfigs->setDisplayManagerPolicy({HWC_CONFIG_ID_60, 60, 60}), 0);
 
     lr.vote = LayerVoteType::Min;
-    EXPECT_EQ(expected60Config,
+    EXPECT_EQ(mExpected60Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                              &ignored));
 
     lr.vote = LayerVoteType::Max;
-    EXPECT_EQ(expected60Config,
+    EXPECT_EQ(mExpected60Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                              &ignored));
 
     lr.desiredRefreshRate = 90.0f;
     lr.vote = LayerVoteType::Heuristic;
-    EXPECT_EQ(expected60Config,
+    EXPECT_EQ(mExpected60Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                              &ignored));
 
     lr.desiredRefreshRate = 60.0f;
-    EXPECT_EQ(expected60Config,
+    EXPECT_EQ(mExpected60Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                              &ignored));
 
     lr.desiredRefreshRate = 45.0f;
-    EXPECT_EQ(expected60Config,
+    EXPECT_EQ(mExpected60Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                              &ignored));
 
     lr.desiredRefreshRate = 30.0f;
-    EXPECT_EQ(expected60Config,
+    EXPECT_EQ(mExpected60Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                              &ignored));
 
     lr.desiredRefreshRate = 24.0f;
-    EXPECT_EQ(expected60Config,
+    EXPECT_EQ(mExpected60Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                              &ignored));
 
     ASSERT_GE(refreshRateConfigs->setDisplayManagerPolicy({HWC_CONFIG_ID_90, 90, 90}), 0);
 
     lr.vote = LayerVoteType::Min;
-    EXPECT_EQ(expected90Config,
+    EXPECT_EQ(mExpected90Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                              &ignored));
 
     lr.vote = LayerVoteType::Max;
-    EXPECT_EQ(expected90Config,
+    EXPECT_EQ(mExpected90Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                              &ignored));
 
     lr.desiredRefreshRate = 90.0f;
     lr.vote = LayerVoteType::Heuristic;
-    EXPECT_EQ(expected90Config,
+    EXPECT_EQ(mExpected90Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                              &ignored));
 
     lr.desiredRefreshRate = 60.0f;
-    EXPECT_EQ(expected90Config,
+    EXPECT_EQ(mExpected90Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                              &ignored));
 
     lr.desiredRefreshRate = 45.0f;
-    EXPECT_EQ(expected90Config,
+    EXPECT_EQ(mExpected90Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                              &ignored));
 
     lr.desiredRefreshRate = 30.0f;
-    EXPECT_EQ(expected90Config,
+    EXPECT_EQ(mExpected90Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                              &ignored));
 
     lr.desiredRefreshRate = 24.0f;
-    EXPECT_EQ(expected90Config,
+    EXPECT_EQ(mExpected90Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                              &ignored));
 
     ASSERT_GE(refreshRateConfigs->setDisplayManagerPolicy({HWC_CONFIG_ID_60, 0, 120}), 0);
     lr.vote = LayerVoteType::Min;
-    EXPECT_EQ(expected60Config,
+    EXPECT_EQ(mExpected60Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                              &ignored));
 
     lr.vote = LayerVoteType::Max;
-    EXPECT_EQ(expected90Config,
+    EXPECT_EQ(mExpected90Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                              &ignored));
 
     lr.desiredRefreshRate = 90.0f;
     lr.vote = LayerVoteType::Heuristic;
-    EXPECT_EQ(expected90Config,
+    EXPECT_EQ(mExpected90Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                              &ignored));
 
     lr.desiredRefreshRate = 60.0f;
-    EXPECT_EQ(expected60Config,
+    EXPECT_EQ(mExpected60Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                              &ignored));
 
     lr.desiredRefreshRate = 45.0f;
-    EXPECT_EQ(expected90Config,
+    EXPECT_EQ(mExpected90Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                              &ignored));
 
     lr.desiredRefreshRate = 30.0f;
-    EXPECT_EQ(expected60Config,
+    EXPECT_EQ(mExpected60Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                              &ignored));
 
     lr.desiredRefreshRate = 24.0f;
-    EXPECT_EQ(expected60Config,
+    EXPECT_EQ(mExpected60Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                              &ignored));
 }
 
 TEST_F(RefreshRateConfigsTest, getRefreshRateForContentV2_60_72_90) {
     bool ignored;
-    std::vector<RefreshRateConfigs::InputConfig> configs{
-            {{HWC_CONFIG_ID_60, HWC_GROUP_ID_0, VSYNC_60},
-             {HWC_CONFIG_ID_72, HWC_GROUP_ID_0, VSYNC_72},
-             {HWC_CONFIG_ID_90, HWC_GROUP_ID_0, VSYNC_90}}};
     auto refreshRateConfigs =
-            std::make_unique<RefreshRateConfigs>(configs, /*currentConfigId=*/HWC_CONFIG_ID_60);
-
-    RefreshRate expected60Config = {HWC_CONFIG_ID_60, VSYNC_60, HWC_GROUP_ID_0, "60fps", 60};
-    RefreshRate expected72Config = {HWC_CONFIG_ID_72, VSYNC_72, HWC_GROUP_ID_0, "72fps", 70};
-    RefreshRate expected90Config = {HWC_CONFIG_ID_90, VSYNC_90, HWC_GROUP_ID_0, "90fps", 90};
+            std::make_unique<RefreshRateConfigs>(m60_72_90Device,
+                                                 /*currentConfigId=*/HWC_CONFIG_ID_60);
 
     auto layers = std::vector<LayerRequirement>{LayerRequirement{.weight = 1.0f}};
     auto& lr = layers[0];
 
     lr.vote = LayerVoteType::Min;
-    EXPECT_EQ(expected60Config,
+    EXPECT_EQ(mExpected60Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                              &ignored));
 
     lr.vote = LayerVoteType::Max;
-    EXPECT_EQ(expected90Config,
+    EXPECT_EQ(mExpected90Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                              &ignored));
 
     lr.desiredRefreshRate = 90.0f;
     lr.vote = LayerVoteType::Heuristic;
-    EXPECT_EQ(expected90Config,
+    EXPECT_EQ(mExpected90Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                              &ignored));
 
     lr.desiredRefreshRate = 60.0f;
-    EXPECT_EQ(expected60Config,
+    EXPECT_EQ(mExpected60Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                              &ignored));
 
     lr.desiredRefreshRate = 45.0f;
-    EXPECT_EQ(expected90Config,
+    EXPECT_EQ(mExpected90Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                              &ignored));
 
     lr.desiredRefreshRate = 30.0f;
-    EXPECT_EQ(expected60Config,
+    EXPECT_EQ(mExpected60Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                              &ignored));
 
     lr.desiredRefreshRate = 24.0f;
-    EXPECT_EQ(expected72Config,
+    EXPECT_EQ(mExpected72Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                              &ignored));
 }
 
 TEST_F(RefreshRateConfigsTest, getRefreshRateForContentV2_30_60_72_90_120) {
     bool ignored;
-    std::vector<RefreshRateConfigs::InputConfig> configs{
-            {{HWC_CONFIG_ID_30, HWC_GROUP_ID_0, VSYNC_30},
-             {HWC_CONFIG_ID_60, HWC_GROUP_ID_0, VSYNC_60},
-             {HWC_CONFIG_ID_72, HWC_GROUP_ID_0, VSYNC_72},
-             {HWC_CONFIG_ID_90, HWC_GROUP_ID_0, VSYNC_90},
-             {HWC_CONFIG_ID_120, HWC_GROUP_ID_0, VSYNC_120}}};
     auto refreshRateConfigs =
-            std::make_unique<RefreshRateConfigs>(configs, /*currentConfigId=*/HWC_CONFIG_ID_60);
-
-    RefreshRate expected30Config = {HWC_CONFIG_ID_30, VSYNC_30, HWC_GROUP_ID_0, "30fps", 30};
-    RefreshRate expected60Config = {HWC_CONFIG_ID_60, VSYNC_60, HWC_GROUP_ID_0, "60fps", 60};
-    RefreshRate expected72Config = {HWC_CONFIG_ID_72, VSYNC_72, HWC_GROUP_ID_0, "72fps", 70};
-    RefreshRate expected90Config = {HWC_CONFIG_ID_90, VSYNC_90, HWC_GROUP_ID_0, "90fps", 90};
-    RefreshRate expected120Config = {HWC_CONFIG_ID_120, VSYNC_120, HWC_GROUP_ID_0, "120fps", 120};
+            std::make_unique<RefreshRateConfigs>(m30_60_72_90_120Device,
+                                                 /*currentConfigId=*/HWC_CONFIG_ID_60);
 
     auto layers = std::vector<LayerRequirement>{LayerRequirement{.weight = 1.0f},
                                                 LayerRequirement{.weight = 1.0f}};
@@ -525,7 +580,7 @@
     lr1.vote = LayerVoteType::Heuristic;
     lr2.desiredRefreshRate = 60.0f;
     lr2.vote = LayerVoteType::Heuristic;
-    EXPECT_EQ(expected120Config,
+    EXPECT_EQ(mExpected120Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                              &ignored));
 
@@ -533,7 +588,7 @@
     lr1.vote = LayerVoteType::Heuristic;
     lr2.desiredRefreshRate = 48.0f;
     lr2.vote = LayerVoteType::Heuristic;
-    EXPECT_EQ(expected72Config,
+    EXPECT_EQ(mExpected72Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                              &ignored));
 
@@ -541,27 +596,16 @@
     lr1.vote = LayerVoteType::Heuristic;
     lr2.desiredRefreshRate = 48.0f;
     lr2.vote = LayerVoteType::Heuristic;
-    EXPECT_EQ(expected72Config,
+    EXPECT_EQ(mExpected72Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                              &ignored));
 }
 
 TEST_F(RefreshRateConfigsTest, getRefreshRateForContentV2_30_60_90_120_DifferentTypes) {
     bool ignored;
-    std::vector<RefreshRateConfigs::InputConfig> configs{
-            {{HWC_CONFIG_ID_30, HWC_GROUP_ID_0, VSYNC_30},
-             {HWC_CONFIG_ID_60, HWC_GROUP_ID_0, VSYNC_60},
-             {HWC_CONFIG_ID_72, HWC_GROUP_ID_0, VSYNC_72},
-             {HWC_CONFIG_ID_90, HWC_GROUP_ID_0, VSYNC_90},
-             {HWC_CONFIG_ID_120, HWC_GROUP_ID_0, VSYNC_120}}};
     auto refreshRateConfigs =
-            std::make_unique<RefreshRateConfigs>(configs, /*currentConfigId=*/HWC_CONFIG_ID_60);
-
-    RefreshRate expected30Config = {HWC_CONFIG_ID_30, VSYNC_30, HWC_GROUP_ID_0, "30fps", 30};
-    RefreshRate expected60Config = {HWC_CONFIG_ID_60, VSYNC_60, HWC_GROUP_ID_0, "60fps", 60};
-    RefreshRate expected72Config = {HWC_CONFIG_ID_72, VSYNC_72, HWC_GROUP_ID_0, "72fps", 72};
-    RefreshRate expected90Config = {HWC_CONFIG_ID_90, VSYNC_90, HWC_GROUP_ID_0, "90fps", 90};
-    RefreshRate expected120Config = {HWC_CONFIG_ID_120, VSYNC_120, HWC_GROUP_ID_0, "120fps", 120};
+            std::make_unique<RefreshRateConfigs>(m30_60_72_90_120Device,
+                                                 /*currentConfigId=*/HWC_CONFIG_ID_60);
 
     auto layers = std::vector<LayerRequirement>{LayerRequirement{.weight = 1.0f},
                                                 LayerRequirement{.weight = 1.0f}};
@@ -574,7 +618,7 @@
     lr2.desiredRefreshRate = 60.0f;
     lr2.vote = LayerVoteType::Heuristic;
     lr2.name = "60Hz Heuristic";
-    EXPECT_EQ(expected120Config,
+    EXPECT_EQ(mExpected120Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                              &ignored));
 
@@ -584,7 +628,7 @@
     lr2.desiredRefreshRate = 60.0f;
     lr2.vote = LayerVoteType::Heuristic;
     lr2.name = "60Hz Heuristic";
-    EXPECT_EQ(expected120Config,
+    EXPECT_EQ(mExpected120Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                              &ignored));
 
@@ -594,7 +638,7 @@
     lr2.desiredRefreshRate = 60.0f;
     lr2.vote = LayerVoteType::ExplicitDefault;
     lr2.name = "60Hz ExplicitDefault";
-    EXPECT_EQ(expected120Config,
+    EXPECT_EQ(mExpected120Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                              &ignored));
 
@@ -604,7 +648,7 @@
     lr2.desiredRefreshRate = 90.0f;
     lr2.vote = LayerVoteType::Heuristic;
     lr2.name = "90Hz Heuristic";
-    EXPECT_EQ(expected90Config,
+    EXPECT_EQ(mExpected90Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                              &ignored));
 
@@ -614,7 +658,7 @@
     lr2.desiredRefreshRate = 90.0f;
     lr2.vote = LayerVoteType::ExplicitDefault;
     lr2.name = "90Hz Heuristic";
-    EXPECT_EQ(expected72Config,
+    EXPECT_EQ(mExpected72Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                              &ignored));
 
@@ -624,7 +668,7 @@
     lr2.desiredRefreshRate = 90.0f;
     lr2.vote = LayerVoteType::Heuristic;
     lr2.name = "90Hz Heuristic";
-    EXPECT_EQ(expected90Config,
+    EXPECT_EQ(mExpected90Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                              &ignored));
 
@@ -634,7 +678,7 @@
     lr2.desiredRefreshRate = 90.0f;
     lr2.vote = LayerVoteType::ExplicitDefault;
     lr2.name = "90Hz ExplicitDefault";
-    EXPECT_EQ(expected72Config,
+    EXPECT_EQ(mExpected72Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                              &ignored));
 
@@ -644,7 +688,7 @@
     lr2.desiredRefreshRate = 90.0f;
     lr2.vote = LayerVoteType::ExplicitDefault;
     lr2.name = "90Hz ExplicitDefault";
-    EXPECT_EQ(expected72Config,
+    EXPECT_EQ(mExpected72Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                              &ignored));
 
@@ -654,158 +698,137 @@
     lr2.desiredRefreshRate = 90.0f;
     lr2.vote = LayerVoteType::ExplicitExactOrMultiple;
     lr2.name = "90Hz ExplicitExactOrMultiple";
-    EXPECT_EQ(expected90Config,
+    EXPECT_EQ(mExpected90Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                              &ignored));
 }
 
 TEST_F(RefreshRateConfigsTest, getRefreshRateForContentV2_30_60) {
     bool ignored;
-    std::vector<RefreshRateConfigs::InputConfig> configs{
-            {{HWC_CONFIG_ID_60, HWC_GROUP_ID_0, VSYNC_60},
-             {HWC_CONFIG_ID_30, HWC_GROUP_ID_0, VSYNC_30}}};
     auto refreshRateConfigs =
-            std::make_unique<RefreshRateConfigs>(configs, /*currentConfigId=*/HWC_CONFIG_ID_60);
-
-    RefreshRate expected60Config = {HWC_CONFIG_ID_60, VSYNC_60, HWC_GROUP_ID_0, "60fps", 60};
-    RefreshRate expected30Config = {HWC_CONFIG_ID_30, VSYNC_30, HWC_GROUP_ID_0, "30fps", 30};
+            std::make_unique<RefreshRateConfigs>(m30_60Device,
+                                                 /*currentConfigId=*/HWC_CONFIG_ID_60);
 
     auto layers = std::vector<LayerRequirement>{LayerRequirement{.weight = 1.0f}};
     auto& lr = layers[0];
 
     lr.vote = LayerVoteType::Min;
-    EXPECT_EQ(expected30Config,
+    EXPECT_EQ(mExpected30Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                              &ignored));
 
     lr.vote = LayerVoteType::Max;
-    EXPECT_EQ(expected60Config,
+    EXPECT_EQ(mExpected60Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                              &ignored));
 
     lr.desiredRefreshRate = 90.0f;
     lr.vote = LayerVoteType::Heuristic;
-    EXPECT_EQ(expected60Config,
+    EXPECT_EQ(mExpected60Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                              &ignored));
 
     lr.desiredRefreshRate = 60.0f;
-    EXPECT_EQ(expected60Config,
+    EXPECT_EQ(mExpected60Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                              &ignored));
 
     lr.desiredRefreshRate = 45.0f;
-    EXPECT_EQ(expected60Config,
+    EXPECT_EQ(mExpected60Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                              &ignored));
 
     lr.desiredRefreshRate = 30.0f;
-    EXPECT_EQ(expected30Config,
+    EXPECT_EQ(mExpected30Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                              &ignored));
 
     lr.desiredRefreshRate = 24.0f;
-    EXPECT_EQ(expected60Config,
+    EXPECT_EQ(mExpected60Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                              &ignored));
 }
 
 TEST_F(RefreshRateConfigsTest, getRefreshRateForContentV2_30_60_72_90) {
     bool ignored;
-    std::vector<RefreshRateConfigs::InputConfig> configs{
-            {{HWC_CONFIG_ID_30, HWC_GROUP_ID_0, VSYNC_30},
-             {HWC_CONFIG_ID_60, HWC_GROUP_ID_0, VSYNC_60},
-             {HWC_CONFIG_ID_72, HWC_GROUP_ID_0, VSYNC_72},
-             {HWC_CONFIG_ID_90, HWC_GROUP_ID_0, VSYNC_90}}};
     auto refreshRateConfigs =
-            std::make_unique<RefreshRateConfigs>(configs, /*currentConfigId=*/HWC_CONFIG_ID_60);
-
-    RefreshRate expected30Config = {HWC_CONFIG_ID_30, VSYNC_30, HWC_GROUP_ID_0, "30fps", 30};
-    RefreshRate expected60Config = {HWC_CONFIG_ID_60, VSYNC_60, HWC_GROUP_ID_0, "60fps", 60};
-    RefreshRate expected72Config = {HWC_CONFIG_ID_72, VSYNC_72, HWC_GROUP_ID_0, "72fps", 70};
-    RefreshRate expected90Config = {HWC_CONFIG_ID_90, VSYNC_90, HWC_GROUP_ID_0, "90fps", 90};
+            std::make_unique<RefreshRateConfigs>(m30_60_72_90Device,
+                                                 /*currentConfigId=*/HWC_CONFIG_ID_60);
 
     auto layers = std::vector<LayerRequirement>{LayerRequirement{.weight = 1.0f}};
     auto& lr = layers[0];
 
     lr.vote = LayerVoteType::Min;
     lr.name = "Min";
-    EXPECT_EQ(expected30Config,
+    EXPECT_EQ(mExpected30Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                              &ignored));
 
     lr.vote = LayerVoteType::Max;
     lr.name = "Max";
-    EXPECT_EQ(expected90Config,
+    EXPECT_EQ(mExpected90Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                              &ignored));
 
     lr.desiredRefreshRate = 90.0f;
     lr.vote = LayerVoteType::Heuristic;
     lr.name = "90Hz Heuristic";
-    EXPECT_EQ(expected90Config,
+    EXPECT_EQ(mExpected90Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                              &ignored));
 
     lr.desiredRefreshRate = 60.0f;
     lr.name = "60Hz Heuristic";
-    EXPECT_EQ(expected60Config,
+    EXPECT_EQ(mExpected60Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                              &ignored));
-    EXPECT_EQ(expected90Config,
+    EXPECT_EQ(mExpected90Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ true,
                                                              &ignored));
 
     lr.desiredRefreshRate = 45.0f;
     lr.name = "45Hz Heuristic";
-    EXPECT_EQ(expected90Config,
+    EXPECT_EQ(mExpected90Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                              &ignored));
-    EXPECT_EQ(expected90Config,
+    EXPECT_EQ(mExpected90Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ true,
                                                              &ignored));
 
     lr.desiredRefreshRate = 30.0f;
     lr.name = "30Hz Heuristic";
-    EXPECT_EQ(expected30Config,
+    EXPECT_EQ(mExpected30Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                              &ignored));
-    EXPECT_EQ(expected90Config,
+    EXPECT_EQ(mExpected90Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ true,
                                                              &ignored));
 
     lr.desiredRefreshRate = 24.0f;
     lr.name = "24Hz Heuristic";
-    EXPECT_EQ(expected72Config,
+    EXPECT_EQ(mExpected72Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                              &ignored));
-    EXPECT_EQ(expected90Config,
+    EXPECT_EQ(mExpected90Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ true,
                                                              &ignored));
 
     lr.desiredRefreshRate = 24.0f;
     lr.vote = LayerVoteType::ExplicitExactOrMultiple;
     lr.name = "24Hz ExplicitExactOrMultiple";
-    EXPECT_EQ(expected72Config,
+    EXPECT_EQ(mExpected72Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                              &ignored));
-    EXPECT_EQ(expected90Config,
+    EXPECT_EQ(mExpected90Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ true,
                                                              &ignored));
 }
 
 TEST_F(RefreshRateConfigsTest, getRefreshRateForContentV2_PriorityTest) {
     bool ignored;
-    std::vector<RefreshRateConfigs::InputConfig> configs{
-            {{HWC_CONFIG_ID_30, HWC_GROUP_ID_0, VSYNC_30},
-             {HWC_CONFIG_ID_60, HWC_GROUP_ID_0, VSYNC_60},
-             {HWC_CONFIG_ID_90, HWC_GROUP_ID_0, VSYNC_90}}};
     auto refreshRateConfigs =
-            std::make_unique<RefreshRateConfigs>(configs, /*currentConfigId=*/HWC_CONFIG_ID_60);
-
-    RefreshRate expected30Config = {HWC_CONFIG_ID_30, VSYNC_30, HWC_GROUP_ID_0, "30fps", 30};
-    RefreshRate expected60Config = {HWC_CONFIG_ID_60, VSYNC_60, HWC_GROUP_ID_0, "60fps", 60};
-    RefreshRate expected90Config = {HWC_CONFIG_ID_90, VSYNC_90, HWC_GROUP_ID_0, "90fps", 90};
+            std::make_unique<RefreshRateConfigs>(m30_60_90Device,
+                                                 /*currentConfigId=*/HWC_CONFIG_ID_60);
 
     auto layers = std::vector<LayerRequirement>{LayerRequirement{.weight = 1.0f},
                                                 LayerRequirement{.weight = 1.0f}};
@@ -814,35 +837,35 @@
 
     lr1.vote = LayerVoteType::Min;
     lr2.vote = LayerVoteType::Max;
-    EXPECT_EQ(expected90Config,
+    EXPECT_EQ(mExpected90Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                              &ignored));
 
     lr1.vote = LayerVoteType::Min;
     lr2.vote = LayerVoteType::Heuristic;
     lr2.desiredRefreshRate = 24.0f;
-    EXPECT_EQ(expected60Config,
+    EXPECT_EQ(mExpected60Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                              &ignored));
 
     lr1.vote = LayerVoteType::Min;
     lr2.vote = LayerVoteType::ExplicitExactOrMultiple;
     lr2.desiredRefreshRate = 24.0f;
-    EXPECT_EQ(expected60Config,
+    EXPECT_EQ(mExpected60Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                              &ignored));
 
     lr1.vote = LayerVoteType::Max;
     lr2.vote = LayerVoteType::Heuristic;
     lr2.desiredRefreshRate = 60.0f;
-    EXPECT_EQ(expected90Config,
+    EXPECT_EQ(mExpected90Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                              &ignored));
 
     lr1.vote = LayerVoteType::Max;
     lr2.vote = LayerVoteType::ExplicitExactOrMultiple;
     lr2.desiredRefreshRate = 60.0f;
-    EXPECT_EQ(expected90Config,
+    EXPECT_EQ(mExpected90Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                              &ignored));
 
@@ -850,7 +873,7 @@
     lr1.desiredRefreshRate = 15.0f;
     lr2.vote = LayerVoteType::Heuristic;
     lr2.desiredRefreshRate = 45.0f;
-    EXPECT_EQ(expected90Config,
+    EXPECT_EQ(mExpected90Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                              &ignored));
 
@@ -858,22 +881,16 @@
     lr1.desiredRefreshRate = 30.0f;
     lr2.vote = LayerVoteType::ExplicitExactOrMultiple;
     lr2.desiredRefreshRate = 45.0f;
-    EXPECT_EQ(expected90Config,
+    EXPECT_EQ(mExpected90Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                              &ignored));
 }
 
 TEST_F(RefreshRateConfigsTest, getRefreshRateForContentV2_24FpsVideo) {
     bool ignored;
-    std::vector<RefreshRateConfigs::InputConfig> configs{
-            {{HWC_CONFIG_ID_60, HWC_GROUP_ID_0, VSYNC_60},
-             {HWC_CONFIG_ID_90, HWC_GROUP_ID_0, VSYNC_90}}};
     auto refreshRateConfigs =
-            std::make_unique<RefreshRateConfigs>(configs, /*currentConfigId=*/HWC_CONFIG_ID_60);
-
-    RefreshRate expected30Config = {HWC_CONFIG_ID_30, VSYNC_30, HWC_GROUP_ID_0, "30fps", 30};
-    RefreshRate expected60Config = {HWC_CONFIG_ID_60, VSYNC_60, HWC_GROUP_ID_0, "60fps", 60};
-    RefreshRate expected90Config = {HWC_CONFIG_ID_90, VSYNC_90, HWC_GROUP_ID_0, "90fps", 90};
+            std::make_unique<RefreshRateConfigs>(m60_90Device,
+                                                 /*currentConfigId=*/HWC_CONFIG_ID_60);
 
     auto layers = std::vector<LayerRequirement>{LayerRequirement{.weight = 1.0f}};
     auto& lr = layers[0];
@@ -884,20 +901,15 @@
         const auto& refreshRate =
                 refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                                &ignored);
-        printf("%.2fHz chooses %s\n", fps, refreshRate.name.c_str());
-        EXPECT_EQ(expected60Config, refreshRate);
+        printf("%.2fHz chooses %s\n", fps, refreshRate.getName().c_str());
+        EXPECT_EQ(mExpected60Config, refreshRate);
     }
 }
 
 TEST_F(RefreshRateConfigsTest, twoDeviceConfigs_getRefreshRateForContent_Explicit) {
-    std::vector<RefreshRateConfigs::InputConfig> configs{
-            {{HWC_CONFIG_ID_60, HWC_GROUP_ID_0, VSYNC_60},
-             {HWC_CONFIG_ID_90, HWC_GROUP_ID_0, VSYNC_90}}};
     auto refreshRateConfigs =
-            std::make_unique<RefreshRateConfigs>(configs, /*currentConfigId=*/HWC_CONFIG_ID_60);
-
-    RefreshRate expected60Config = {HWC_CONFIG_ID_60, VSYNC_60, HWC_GROUP_ID_0, "60fps", 60};
-    RefreshRate expected90Config = {HWC_CONFIG_ID_90, VSYNC_90, HWC_GROUP_ID_0, "90fps", 90};
+            std::make_unique<RefreshRateConfigs>(m60_90Device,
+                                                 /*currentConfigId=*/HWC_CONFIG_ID_60);
 
     auto layers = std::vector<LayerRequirement>{LayerRequirement{.weight = 1.0f},
                                                 LayerRequirement{.weight = 1.0f}};
@@ -908,25 +920,20 @@
     lr1.desiredRefreshRate = 60.0f;
     lr2.vote = LayerVoteType::ExplicitExactOrMultiple;
     lr2.desiredRefreshRate = 90.0f;
-    EXPECT_EQ(expected90Config, refreshRateConfigs->getRefreshRateForContent(layers));
+    EXPECT_EQ(mExpected90Config, refreshRateConfigs->getRefreshRateForContent(layers));
 
     lr1.vote = LayerVoteType::Heuristic;
     lr1.desiredRefreshRate = 90.0f;
     lr2.vote = LayerVoteType::ExplicitExactOrMultiple;
     lr2.desiredRefreshRate = 60.0f;
-    EXPECT_EQ(expected60Config, refreshRateConfigs->getRefreshRateForContent(layers));
+    EXPECT_EQ(mExpected60Config, refreshRateConfigs->getRefreshRateForContent(layers));
 }
 
 TEST_F(RefreshRateConfigsTest, twoDeviceConfigs_getRefreshRateForContentV2_Explicit) {
     bool ignored;
-    std::vector<RefreshRateConfigs::InputConfig> configs{
-            {{HWC_CONFIG_ID_60, HWC_GROUP_ID_0, VSYNC_60},
-             {HWC_CONFIG_ID_90, HWC_GROUP_ID_0, VSYNC_90}}};
     auto refreshRateConfigs =
-            std::make_unique<RefreshRateConfigs>(configs, /*currentConfigId=*/HWC_CONFIG_ID_60);
-
-    RefreshRate expected60Config = {HWC_CONFIG_ID_60, VSYNC_60, HWC_GROUP_ID_0, "60fps", 60};
-    RefreshRate expected90Config = {HWC_CONFIG_ID_90, VSYNC_90, HWC_GROUP_ID_0, "90fps", 90};
+            std::make_unique<RefreshRateConfigs>(m60_90Device,
+                                                 /*currentConfigId=*/HWC_CONFIG_ID_60);
 
     auto layers = std::vector<LayerRequirement>{LayerRequirement{.weight = 1.0f},
                                                 LayerRequirement{.weight = 1.0f}};
@@ -937,7 +944,7 @@
     lr1.desiredRefreshRate = 60.0f;
     lr2.vote = LayerVoteType::ExplicitExactOrMultiple;
     lr2.desiredRefreshRate = 90.0f;
-    EXPECT_EQ(expected90Config,
+    EXPECT_EQ(mExpected90Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                              &ignored));
 
@@ -945,7 +952,7 @@
     lr1.desiredRefreshRate = 90.0f;
     lr2.vote = LayerVoteType::ExplicitExactOrMultiple;
     lr2.desiredRefreshRate = 60.0f;
-    EXPECT_EQ(expected60Config,
+    EXPECT_EQ(mExpected60Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                              &ignored));
 
@@ -953,32 +960,24 @@
     lr1.desiredRefreshRate = 90.0f;
     lr2.vote = LayerVoteType::ExplicitExactOrMultiple;
     lr2.desiredRefreshRate = 60.0f;
-    EXPECT_EQ(expected90Config,
+    EXPECT_EQ(mExpected90Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                              &ignored));
 }
 
 TEST_F(RefreshRateConfigsTest, testInPolicy) {
-    RefreshRate expectedDefaultConfig = {HWC_CONFIG_ID_60, VSYNC_60_POINT_4, HWC_GROUP_ID_0,
-                                         "60fps", 60};
-    ASSERT_TRUE(expectedDefaultConfig.inPolicy(60.000004f, 60.000004f));
-    ASSERT_TRUE(expectedDefaultConfig.inPolicy(59.0f, 60.1f));
-    ASSERT_FALSE(expectedDefaultConfig.inPolicy(75.0f, 90.0f));
-    ASSERT_FALSE(expectedDefaultConfig.inPolicy(60.0011f, 90.0f));
-    ASSERT_FALSE(expectedDefaultConfig.inPolicy(50.0f, 59.998f));
+    ASSERT_TRUE(mExpectedAlmost60Config.inPolicy(60.000004f, 60.000004f));
+    ASSERT_TRUE(mExpectedAlmost60Config.inPolicy(59.0f, 60.1f));
+    ASSERT_FALSE(mExpectedAlmost60Config.inPolicy(75.0f, 90.0f));
+    ASSERT_FALSE(mExpectedAlmost60Config.inPolicy(60.0011f, 90.0f));
+    ASSERT_FALSE(mExpectedAlmost60Config.inPolicy(50.0f, 59.998f));
 }
 
 TEST_F(RefreshRateConfigsTest, getRefreshRateForContentV2_75HzContent) {
     bool ignored;
-    std::vector<RefreshRateConfigs::InputConfig> configs{
-            {{HWC_CONFIG_ID_60, HWC_GROUP_ID_0, VSYNC_60},
-             {HWC_CONFIG_ID_90, HWC_GROUP_ID_0, VSYNC_90}}};
     auto refreshRateConfigs =
-            std::make_unique<RefreshRateConfigs>(configs, /*currentConfigId=*/HWC_CONFIG_ID_60);
-
-    RefreshRate expected30Config = {HWC_CONFIG_ID_30, VSYNC_30, HWC_GROUP_ID_0, "30fps", 30};
-    RefreshRate expected60Config = {HWC_CONFIG_ID_60, VSYNC_60, HWC_GROUP_ID_0, "60fps", 60};
-    RefreshRate expected90Config = {HWC_CONFIG_ID_90, VSYNC_90, HWC_GROUP_ID_0, "90fps", 90};
+            std::make_unique<RefreshRateConfigs>(m60_90Device,
+                                                 /*currentConfigId=*/HWC_CONFIG_ID_60);
 
     auto layers = std::vector<LayerRequirement>{LayerRequirement{.weight = 1.0f}};
     auto& lr = layers[0];
@@ -989,21 +988,16 @@
         const auto& refreshRate =
                 refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                                &ignored);
-        printf("%.2fHz chooses %s\n", fps, refreshRate.name.c_str());
-        EXPECT_EQ(expected90Config, refreshRate);
+        printf("%.2fHz chooses %s\n", fps, refreshRate.getName().c_str());
+        EXPECT_EQ(mExpected90Config, refreshRate);
     }
 }
 
 TEST_F(RefreshRateConfigsTest, getRefreshRateForContentV2_Multiples) {
     bool ignored;
-    std::vector<RefreshRateConfigs::InputConfig> configs{
-            {{HWC_CONFIG_ID_60, HWC_GROUP_ID_0, VSYNC_60},
-             {HWC_CONFIG_ID_90, HWC_GROUP_ID_0, VSYNC_90}}};
     auto refreshRateConfigs =
-            std::make_unique<RefreshRateConfigs>(configs, /*currentConfigId=*/HWC_CONFIG_ID_60);
-
-    RefreshRate expected60Config = {HWC_CONFIG_ID_60, VSYNC_60, HWC_GROUP_ID_0, "60fps", 60};
-    RefreshRate expected90Config = {HWC_CONFIG_ID_90, VSYNC_90, HWC_GROUP_ID_0, "90fps", 90};
+            std::make_unique<RefreshRateConfigs>(m60_90Device,
+                                                 /*currentConfigId=*/HWC_CONFIG_ID_60);
 
     auto layers = std::vector<LayerRequirement>{LayerRequirement{.weight = 1.0f},
                                                 LayerRequirement{.weight = 1.0f}};
@@ -1016,7 +1010,7 @@
     lr2.vote = LayerVoteType::Heuristic;
     lr2.desiredRefreshRate = 90.0f;
     lr2.name = "90Hz Heuristic";
-    EXPECT_EQ(expected90Config,
+    EXPECT_EQ(mExpected90Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                              &ignored));
 
@@ -1026,7 +1020,7 @@
     lr2.vote = LayerVoteType::ExplicitDefault;
     lr2.desiredRefreshRate = 90.0f;
     lr2.name = "90Hz ExplicitDefault";
-    EXPECT_EQ(expected60Config,
+    EXPECT_EQ(mExpected60Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                              &ignored));
 
@@ -1035,7 +1029,7 @@
     lr1.name = "60Hz ExplicitExactOrMultiple";
     lr2.vote = LayerVoteType::Max;
     lr2.name = "Max";
-    EXPECT_EQ(expected90Config,
+    EXPECT_EQ(mExpected90Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                              &ignored));
 
@@ -1045,7 +1039,7 @@
     lr2.vote = LayerVoteType::Heuristic;
     lr2.desiredRefreshRate = 90.0f;
     lr2.name = "90Hz Heuristic";
-    EXPECT_EQ(expected90Config,
+    EXPECT_EQ(mExpected90Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                              &ignored));
 
@@ -1054,21 +1048,16 @@
     lr1.name = "30Hz ExplicitExactOrMultiple";
     lr2.vote = LayerVoteType::Max;
     lr2.name = "Max";
-    EXPECT_EQ(expected90Config,
+    EXPECT_EQ(mExpected90Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, /*touchActive*/ false,
                                                              &ignored));
 }
 
 TEST_F(RefreshRateConfigsTest, scrollWhileWatching60fps_60_90) {
     bool ignored;
-    std::vector<RefreshRateConfigs::InputConfig> configs{
-            {{HWC_CONFIG_ID_60, HWC_GROUP_ID_0, VSYNC_60},
-             {HWC_CONFIG_ID_90, HWC_GROUP_ID_0, VSYNC_90}}};
     auto refreshRateConfigs =
-            std::make_unique<RefreshRateConfigs>(configs, /*currentConfigId=*/HWC_CONFIG_ID_60);
-
-    RefreshRate expected60Config = {HWC_CONFIG_ID_60, VSYNC_60, HWC_GROUP_ID_0, "60fps", 60};
-    RefreshRate expected90Config = {HWC_CONFIG_ID_90, VSYNC_90, HWC_GROUP_ID_0, "90fps", 90};
+            std::make_unique<RefreshRateConfigs>(m60_90Device,
+                                                 /*currentConfigId=*/HWC_CONFIG_ID_60);
 
     auto layers = std::vector<LayerRequirement>{LayerRequirement{.weight = 1.0f},
                                                 LayerRequirement{.weight = 1.0f}};
@@ -1080,7 +1069,7 @@
     lr1.name = "60Hz ExplicitExactOrMultiple";
     lr2.vote = LayerVoteType::NoVote;
     lr2.name = "NoVote";
-    EXPECT_EQ(expected60Config,
+    EXPECT_EQ(mExpected60Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, false, &ignored));
 
     lr1.vote = LayerVoteType::ExplicitExactOrMultiple;
@@ -1088,7 +1077,7 @@
     lr1.name = "60Hz ExplicitExactOrMultiple";
     lr2.vote = LayerVoteType::NoVote;
     lr2.name = "NoVote";
-    EXPECT_EQ(expected90Config,
+    EXPECT_EQ(mExpected90Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, true, &ignored));
 
     lr1.vote = LayerVoteType::ExplicitExactOrMultiple;
@@ -1096,7 +1085,7 @@
     lr1.name = "60Hz ExplicitExactOrMultiple";
     lr2.vote = LayerVoteType::Max;
     lr2.name = "Max";
-    EXPECT_EQ(expected90Config,
+    EXPECT_EQ(mExpected90Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, true, &ignored));
 
     lr1.vote = LayerVoteType::ExplicitExactOrMultiple;
@@ -1104,7 +1093,7 @@
     lr1.name = "60Hz ExplicitExactOrMultiple";
     lr2.vote = LayerVoteType::Max;
     lr2.name = "Max";
-    EXPECT_EQ(expected90Config,
+    EXPECT_EQ(mExpected90Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, false, &ignored));
 
     // The other layer starts to provide buffers
@@ -1114,17 +1103,15 @@
     lr2.vote = LayerVoteType::Heuristic;
     lr2.desiredRefreshRate = 90.0f;
     lr2.name = "90Hz Heuristic";
-    EXPECT_EQ(expected90Config,
+    EXPECT_EQ(mExpected90Config,
               refreshRateConfigs->getRefreshRateForContentV2(layers, false, &ignored));
 }
 
 TEST_F(RefreshRateConfigsTest, touchConsidered) {
     bool touchConsidered;
-    std::vector<RefreshRateConfigs::InputConfig> configs{
-            {{HWC_CONFIG_ID_60, HWC_GROUP_ID_0, VSYNC_60},
-             {HWC_CONFIG_ID_90, HWC_GROUP_ID_0, VSYNC_90}}};
     auto refreshRateConfigs =
-            std::make_unique<RefreshRateConfigs>(configs, /*currentConfigId=*/HWC_CONFIG_ID_60);
+            std::make_unique<RefreshRateConfigs>(m60_90Device,
+                                                 /*currentConfigId=*/HWC_CONFIG_ID_60);
 
     refreshRateConfigs->getRefreshRateForContentV2({}, false, &touchConsidered);
     EXPECT_EQ(false, touchConsidered);
@@ -1172,14 +1159,9 @@
 
 TEST_F(RefreshRateConfigsTest, getRefreshRateForContentV2_ExplicitDefault) {
     bool ignored;
-    std::vector<RefreshRateConfigs::InputConfig> configs{
-            {{HWC_CONFIG_ID_60, HWC_GROUP_ID_0, VSYNC_60},
-             {HWC_CONFIG_ID_72, HWC_GROUP_ID_0, VSYNC_72},
-             {HWC_CONFIG_ID_90, HWC_GROUP_ID_0, VSYNC_90},
-             {HWC_CONFIG_ID_120, HWC_GROUP_ID_0, VSYNC_120}}};
-
-    auto refreshRateConfigs = std::make_unique<RefreshRateConfigs>(configs, /*currentConfigId=*/
-                                                                   HWC_CONFIG_ID_60);
+    auto refreshRateConfigs =
+            std::make_unique<RefreshRateConfigs>(m60_90_72_120Device, /*currentConfigId=*/
+                                                 HWC_CONFIG_ID_60);
 
     auto layers = std::vector<LayerRequirement>{LayerRequirement{.weight = 1.0f}};
     auto& lr = layers[0];
@@ -1213,17 +1195,15 @@
 
         const auto& refreshRate =
                 refreshRateConfigs->getRefreshRateForContentV2(layers, false, &ignored);
-        EXPECT_FLOAT_EQ(refreshRate.fps, test.second)
+        EXPECT_FLOAT_EQ(refreshRate.getFps(), test.second)
                 << "Expecting " << test.first << "fps => " << test.second << "Hz";
     }
 }
 
 TEST_F(RefreshRateConfigsTest, groupSwitching) {
-    std::vector<RefreshRateConfigs::InputConfig> configs{
-            {{HWC_CONFIG_ID_60, HWC_GROUP_ID_0, VSYNC_60},
-             {HWC_CONFIG_ID_90, HWC_GROUP_ID_1, VSYNC_90}}};
     auto refreshRateConfigs =
-            std::make_unique<RefreshRateConfigs>(configs, /*currentConfigId=*/HWC_CONFIG_ID_60);
+            std::make_unique<RefreshRateConfigs>(m60_90DeviceWithDifferentGroups,
+                                                 /*currentConfigId=*/HWC_CONFIG_ID_60);
 
     auto layers = std::vector<LayerRequirement>{LayerRequirement{.weight = 1.0f}};
     auto& layer = layers[0];
@@ -1234,7 +1214,7 @@
     bool touchConsidered;
     ASSERT_EQ(HWC_CONFIG_ID_60,
               refreshRateConfigs->getRefreshRateForContentV2(layers, false, &touchConsidered)
-                      .configId);
+                      .getConfigId());
 
     RefreshRateConfigs::Policy policy;
     policy.defaultConfig = refreshRateConfigs->getCurrentPolicy().defaultConfig;
@@ -1242,7 +1222,7 @@
     ASSERT_GE(refreshRateConfigs->setDisplayManagerPolicy(policy), 0);
     ASSERT_EQ(HWC_CONFIG_ID_90,
               refreshRateConfigs->getRefreshRateForContentV2(layers, false, &touchConsidered)
-                      .configId);
+                      .getConfigId());
 }
 
 } // namespace
diff --git a/services/surfaceflinger/tests/unittests/RefreshRateStatsTest.cpp b/services/surfaceflinger/tests/unittests/RefreshRateStatsTest.cpp
index 18d6bd2..038e6e6 100644
--- a/services/surfaceflinger/tests/unittests/RefreshRateStatsTest.cpp
+++ b/services/surfaceflinger/tests/unittests/RefreshRateStatsTest.cpp
@@ -26,6 +26,7 @@
 #include <thread>
 
 #include "Scheduler/RefreshRateStats.h"
+#include "mock/DisplayHardware/MockDisplay.h"
 #include "mock/MockTimeStats.h"
 
 using namespace std::chrono_literals;
@@ -39,14 +40,14 @@
 protected:
     static inline const auto CONFIG_ID_0 = HwcConfigIndexType(0);
     static inline const auto CONFIG_ID_1 = HwcConfigIndexType(1);
-    static inline const auto CONFIG_GROUP_0 = HwcConfigGroupType(0);
+    static inline const auto CONFIG_GROUP_0 = 0;
     static constexpr int64_t VSYNC_90 = 11111111;
     static constexpr int64_t VSYNC_60 = 16666667;
 
     RefreshRateStatsTest();
     ~RefreshRateStatsTest();
 
-    void init(const std::vector<RefreshRateConfigs::InputConfig>& configs) {
+    void init(const std::vector<std::shared_ptr<const HWC2::Display::Config>>& configs) {
         mRefreshRateConfigs =
                 std::make_unique<RefreshRateConfigs>(configs, /*currentConfig=*/CONFIG_ID_0);
         mRefreshRateStats =
@@ -55,9 +56,14 @@
                                                    /*currentPowerMode=*/HWC_POWER_MODE_OFF);
     }
 
+    Hwc2::mock::Display mDisplay;
     mock::TimeStats mTimeStats;
     std::unique_ptr<RefreshRateConfigs> mRefreshRateConfigs;
     std::unique_ptr<RefreshRateStats> mRefreshRateStats;
+
+    std::shared_ptr<const HWC2::Display::Config> createConfig(HwcConfigIndexType configId,
+                                                              int32_t configGroup,
+                                                              int64_t vsyncPeriod);
 };
 
 RefreshRateStatsTest::RefreshRateStatsTest() {
@@ -72,12 +78,20 @@
     ALOGD("**** Tearing down after %s.%s\n", test_info->test_case_name(), test_info->name());
 }
 
+std::shared_ptr<const HWC2::Display::Config> RefreshRateStatsTest::createConfig(
+        HwcConfigIndexType configId, int32_t configGroup, int64_t vsyncPeriod) {
+    return HWC2::Display::Config::Builder(mDisplay, hwc2_config_t(configId.value()))
+            .setVsyncPeriod(int32_t(vsyncPeriod))
+            .setConfigGroup(configGroup)
+            .build();
+}
+
 namespace {
 /* ------------------------------------------------------------------------
  * Test cases
  */
 TEST_F(RefreshRateStatsTest, oneConfigTest) {
-    init({{{CONFIG_ID_0, CONFIG_GROUP_0, VSYNC_90}}});
+    init({createConfig(CONFIG_ID_0, CONFIG_GROUP_0, VSYNC_90)});
 
     EXPECT_CALL(mTimeStats, recordRefreshRate(0, _)).Times(AtLeast(1));
     EXPECT_CALL(mTimeStats, recordRefreshRate(90, _)).Times(AtLeast(1));
@@ -123,7 +137,8 @@
 }
 
 TEST_F(RefreshRateStatsTest, twoConfigsTest) {
-    init({{{CONFIG_ID_0, CONFIG_GROUP_0, VSYNC_90}, {CONFIG_ID_1, CONFIG_GROUP_0, VSYNC_60}}});
+    init({createConfig(CONFIG_ID_0, CONFIG_GROUP_0, VSYNC_90),
+          createConfig(CONFIG_ID_1, CONFIG_GROUP_0, VSYNC_60)});
 
     EXPECT_CALL(mTimeStats, recordRefreshRate(0, _)).Times(AtLeast(1));
     EXPECT_CALL(mTimeStats, recordRefreshRate(60, _)).Times(AtLeast(1));
diff --git a/services/surfaceflinger/tests/unittests/SchedulerTest.cpp b/services/surfaceflinger/tests/unittests/SchedulerTest.cpp
index 5db11ec..1aa7320 100644
--- a/services/surfaceflinger/tests/unittests/SchedulerTest.cpp
+++ b/services/surfaceflinger/tests/unittests/SchedulerTest.cpp
@@ -31,6 +31,7 @@
 #include "Scheduler/EventThread.h"
 #include "Scheduler/RefreshRateConfigs.h"
 #include "TestableScheduler.h"
+#include "mock/DisplayHardware/MockDisplay.h"
 #include "mock/MockEventThread.h"
 
 using testing::_;
@@ -63,6 +64,7 @@
     Scheduler::ConnectionHandle mConnectionHandle;
     mock::EventThread* mEventThread;
     sp<MockEventThreadConnection> mEventThreadConnection;
+    Hwc2::mock::Display mDisplay;
 };
 
 SchedulerTest::SchedulerTest() {
@@ -70,8 +72,11 @@
             ::testing::UnitTest::GetInstance()->current_test_info();
     ALOGD("**** Setting up for %s.%s\n", test_info->test_case_name(), test_info->name());
 
-    std::vector<scheduler::RefreshRateConfigs::InputConfig> configs{
-            {{HwcConfigIndexType(0), HwcConfigGroupType(0), 16666667}}};
+    std::vector<std::shared_ptr<const HWC2::Display::Config>> configs{
+            HWC2::Display::Config::Builder(mDisplay, 0)
+                    .setVsyncPeriod(int32_t(16666667))
+                    .setConfigGroup(0)
+                    .build()};
     mRefreshRateConfigs = std::make_unique<
             scheduler::RefreshRateConfigs>(configs, /*currentConfig=*/HwcConfigIndexType(0));
 
diff --git a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
index baca1df..47bc24e 100644
--- a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
+++ b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
@@ -39,6 +39,7 @@
 #include "SurfaceFlingerDefaultFactory.h"
 #include "SurfaceInterceptor.h"
 #include "TestableScheduler.h"
+#include "mock/DisplayHardware/MockDisplay.h"
 
 namespace android {
 
@@ -198,8 +199,12 @@
                         std::unique_ptr<EventThread> appEventThread,
                         std::unique_ptr<EventThread> sfEventThread,
                         bool useContentDetectionV2 = false) {
-        std::vector<scheduler::RefreshRateConfigs::InputConfig> configs{
-                {{HwcConfigIndexType(0), HwcConfigGroupType(0), 16666667}}};
+        std::vector<std::shared_ptr<const HWC2::Display::Config>> configs{
+                HWC2::Display::Config::Builder(mDisplay, 0)
+                        .setVsyncPeriod(int32_t(16666667))
+                        .setConfigGroup(0)
+                        .build()};
+
         mFlinger->mRefreshRateConfigs = std::make_unique<
                 scheduler::RefreshRateConfigs>(configs, /*currentConfig=*/HwcConfigIndexType(0));
         mFlinger->mRefreshRateStats = std::make_unique<
@@ -649,6 +654,7 @@
     surfaceflinger::test::Factory mFactory;
     sp<SurfaceFlinger> mFlinger = new SurfaceFlinger(mFactory, SurfaceFlinger::SkipInitialization);
     TestableScheduler* mScheduler = nullptr;
+    Hwc2::mock::Display mDisplay;
 };
 
 } // namespace android
diff --git a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockComposer.h b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockComposer.h
index 5cbba81..2a31078 100644
--- a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockComposer.h
+++ b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockComposer.h
@@ -45,6 +45,7 @@
 
 class Composer : public Hwc2::Composer {
 public:
+    using Display = android::hardware::graphics::composer::V2_1::Display;
     Composer();
     ~Composer() override;
 
diff --git a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockDisplay.h b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockDisplay.h
index 6dc28bc..3968035 100644
--- a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockDisplay.h
+++ b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockDisplay.h
@@ -29,6 +29,9 @@
 
 class Display : public HWC2::Display {
 public:
+    using Error = ::Error;
+    using Layer = ::Layer;
+
     Display();
     ~Display();
 
@@ -80,6 +83,16 @@
     MOCK_METHOD4(presentOrValidate,
                  Error(uint32_t*, uint32_t*, android::sp<android::Fence>*, uint32_t*));
     MOCK_CONST_METHOD1(setDisplayBrightness, Error(float));
+    MOCK_CONST_METHOD1(getDisplayVsyncPeriod, Error(nsecs_t*));
+    MOCK_METHOD3(setActiveConfigWithConstraints,
+                 Error(const std::shared_ptr<const HWC2::Display::Config>&,
+                       const HWC2::VsyncPeriodChangeConstraints&,
+                       HWC2::VsyncPeriodChangeTimeline*));
+    MOCK_CONST_METHOD1(setAutoLowLatencyMode, Error(bool on));
+    MOCK_CONST_METHOD1(getSupportedContentTypes, Error(std::vector<HWC2::ContentType>*));
+    MOCK_CONST_METHOD1(setContentType, Error(HWC2::ContentType));
+    MOCK_CONST_METHOD1(getConnectionType, Error(android::DisplayConnectionType*));
+    MOCK_CONST_METHOD0(isVsyncPeriodSwitchSupported, bool());
 };
 
 } // namespace mock