SurfaceFlinger: missing configChanged event on idle

This change fixes a condition where a configChanged event
will be dropped due to idle timer.

Change-Id: I803f478c261be9fceb3495526576b495d7d0f385
Bug: 155367075
Test: CtsGraphicsTestCases
diff --git a/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp b/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp
index ea27955..6dbff14 100644
--- a/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp
+++ b/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp
@@ -115,12 +115,24 @@
 }
 
 const RefreshRate& RefreshRateConfigs::getBestRefreshRate(
-        const std::vector<LayerRequirement>& layers, bool touchActive, bool idle,
-        bool* touchConsidered) const {
+        const std::vector<LayerRequirement>& layers, const GlobalSignals& globalSignals,
+        GlobalSignals* outSignalsConsidered) const {
     ATRACE_CALL();
     ALOGV("getRefreshRateForContent %zu layers", layers.size());
 
-    if (touchConsidered) *touchConsidered = false;
+    if (outSignalsConsidered) *outSignalsConsidered = {};
+    const auto setTouchConsidered = [&] {
+        if (outSignalsConsidered) {
+            outSignalsConsidered->touch = true;
+        }
+    };
+
+    const auto setIdleConsidered = [&] {
+        if (outSignalsConsidered) {
+            outSignalsConsidered->idle = true;
+        }
+    };
+
     std::lock_guard lock(mLock);
 
     int noVoteLayers = 0;
@@ -150,9 +162,9 @@
 
     // Consider the touch event if there are no Explicit* layers. Otherwise wait until after we've
     // selected a refresh rate to see if we should apply touch boost.
-    if (touchActive && !hasExplicitVoteLayers) {
+    if (globalSignals.touch && !hasExplicitVoteLayers) {
         ALOGV("TouchBoost - choose %s", getMaxRefreshRateByPolicyLocked().getName().c_str());
-        if (touchConsidered) *touchConsidered = true;
+        setTouchConsidered();
         return getMaxRefreshRateByPolicyLocked();
     }
 
@@ -162,8 +174,10 @@
     const Policy* policy = getCurrentPolicyLocked();
     const bool primaryRangeIsSingleRate = policy->primaryRange.min == policy->primaryRange.max;
 
-    if (!touchActive && idle && !(primaryRangeIsSingleRate && hasExplicitVoteLayers)) {
+    if (!globalSignals.touch && globalSignals.idle &&
+        !(primaryRangeIsSingleRate && hasExplicitVoteLayers)) {
         ALOGV("Idle - choose %s", getMinRefreshRateByPolicyLocked().getName().c_str());
+        setIdleConsidered();
         return getMinRefreshRateByPolicyLocked();
     }
 
@@ -307,9 +321,9 @@
     // actually increase the refresh rate over the normal selection.
     const RefreshRate& touchRefreshRate = getMaxRefreshRateByPolicyLocked();
 
-    if (touchActive && explicitDefaultVoteLayers == 0 &&
+    if (globalSignals.touch && explicitDefaultVoteLayers == 0 &&
         bestRefreshRate->fps < touchRefreshRate.fps) {
-        if (touchConsidered) *touchConsidered = true;
+        setTouchConsidered();
         ALOGV("TouchBoost - choose %s", touchRefreshRate.getName().c_str());
         return touchRefreshRate;
     }
diff --git a/services/surfaceflinger/Scheduler/RefreshRateConfigs.h b/services/surfaceflinger/Scheduler/RefreshRateConfigs.h
index 88e4eb5..584a5e7 100644
--- a/services/surfaceflinger/Scheduler/RefreshRateConfigs.h
+++ b/services/surfaceflinger/Scheduler/RefreshRateConfigs.h
@@ -211,14 +211,22 @@
     const RefreshRate& getRefreshRateForContent(const std::vector<LayerRequirement>& layers) const
             EXCLUDES(mLock);
 
+    // Global state describing signals that affect refresh rate choice.
+    struct GlobalSignals {
+        // Whether the user touched the screen recently. Used to apply touch boost.
+        bool touch = false;
+        // True if the system hasn't seen any buffers posted to layers recently.
+        bool idle = false;
+    };
+
     // Returns the refresh rate that fits best to the given layers.
     //   layers - The layer requirements to consider.
-    //   touchActive - Whether the user touched the screen recently. Used to apply touch boost.
-    //   idle - True if the system hasn't seen any buffers posted to layers recently.
-    //   touchConsidered - An output param that tells the caller whether the refresh rate was chosen
-    //                     based on touch boost.
+    //   globalSignals - global state of touch and idle
+    //   outSignalsConsidered - An output param that tells the caller whether the refresh rate was
+    //                          chosen based on touch boost and/or idle timer.
     const RefreshRate& getBestRefreshRate(const std::vector<LayerRequirement>& layers,
-                                          bool touchActive, bool idle, bool* touchConsidered) const
+                                          const GlobalSignals& globalSignals,
+                                          GlobalSignals* outSignalsConsidered = nullptr) const
             EXCLUDES(mLock);
 
     // Returns all the refresh rates supported by the device. This won't change at runtime.
diff --git a/services/surfaceflinger/Scheduler/Scheduler.cpp b/services/surfaceflinger/Scheduler/Scheduler.cpp
index bfa7493..5c0ba01 100644
--- a/services/surfaceflinger/Scheduler/Scheduler.cpp
+++ b/services/surfaceflinger/Scheduler/Scheduler.cpp
@@ -228,8 +228,36 @@
     mConnections[handle].thread->onScreenReleased();
 }
 
-void Scheduler::onConfigChanged(ConnectionHandle handle, PhysicalDisplayId displayId,
-                                HwcConfigIndexType configId, nsecs_t vsyncPeriod) {
+void Scheduler::onPrimaryDisplayConfigChanged(ConnectionHandle handle, PhysicalDisplayId displayId,
+                                              HwcConfigIndexType configId, nsecs_t vsyncPeriod) {
+    std::lock_guard<std::mutex> lock(mFeatureStateLock);
+    // Cache the last reported config for primary display.
+    mFeatures.cachedConfigChangedParams = {handle, displayId, configId, vsyncPeriod};
+    onNonPrimaryDisplayConfigChanged(handle, displayId, configId, vsyncPeriod);
+}
+
+void Scheduler::dispatchCachedReportedConfig() {
+    const auto configId = *mFeatures.configId;
+    const auto vsyncPeriod =
+            mRefreshRateConfigs.getRefreshRateFromConfigId(configId).getVsyncPeriod();
+
+    // If there is no change from cached config, there is no need to dispatch an event
+    if (configId == mFeatures.cachedConfigChangedParams->configId &&
+        vsyncPeriod == mFeatures.cachedConfigChangedParams->vsyncPeriod) {
+        return;
+    }
+
+    mFeatures.cachedConfigChangedParams->configId = configId;
+    mFeatures.cachedConfigChangedParams->vsyncPeriod = vsyncPeriod;
+    onNonPrimaryDisplayConfigChanged(mFeatures.cachedConfigChangedParams->handle,
+                                     mFeatures.cachedConfigChangedParams->displayId,
+                                     mFeatures.cachedConfigChangedParams->configId,
+                                     mFeatures.cachedConfigChangedParams->vsyncPeriod);
+}
+
+void Scheduler::onNonPrimaryDisplayConfigChanged(ConnectionHandle handle,
+                                                 PhysicalDisplayId displayId,
+                                                 HwcConfigIndexType configId, nsecs_t vsyncPeriod) {
     RETURN_IF_INVALID_HANDLE(handle);
     mConnections[handle].thread->onConfigChanged(displayId, configId, vsyncPeriod);
 }
@@ -446,13 +474,21 @@
         mFeatures.contentDetectionV1 =
                 !summary.empty() ? ContentDetectionState::On : ContentDetectionState::Off;
 
-        newConfigId = calculateRefreshRateConfigIndexType();
+        scheduler::RefreshRateConfigs::GlobalSignals consideredSignals;
+        newConfigId = calculateRefreshRateConfigIndexType(&consideredSignals);
         if (mFeatures.configId == newConfigId) {
+            // We don't need to change the config, but we might need to send an event
+            // about a config change, since it was suppressed due to a previous idleConsidered
+            if (!consideredSignals.idle) {
+                dispatchCachedReportedConfig();
+            }
             return;
         }
         mFeatures.configId = newConfigId;
         auto& newRefreshRate = mRefreshRateConfigs.getRefreshRateFromConfigId(newConfigId);
-        mSchedulerCallback.changeRefreshRate(newRefreshRate, ConfigEvent::Changed);
+        mSchedulerCallback.changeRefreshRate(newRefreshRate,
+                                             consideredSignals.idle ? ConfigEvent::None
+                                                                    : ConfigEvent::Changed);
     }
 }
 
@@ -522,21 +558,20 @@
 }
 
 void Scheduler::idleTimerCallback(TimerState state) {
-    handleTimerStateChanged(&mFeatures.idleTimer, state, false /* eventOnContentDetection */);
+    handleTimerStateChanged(&mFeatures.idleTimer, state);
     ATRACE_INT("ExpiredIdleTimer", static_cast<int>(state));
 }
 
 void Scheduler::touchTimerCallback(TimerState state) {
     const TouchState touch = state == TimerState::Reset ? TouchState::Active : TouchState::Inactive;
-    if (handleTimerStateChanged(&mFeatures.touch, touch, true /* eventOnContentDetection */)) {
+    if (handleTimerStateChanged(&mFeatures.touch, touch)) {
         mLayerHistory->clear();
     }
     ATRACE_INT("TouchState", static_cast<int>(touch));
 }
 
 void Scheduler::displayPowerTimerCallback(TimerState state) {
-    handleTimerStateChanged(&mFeatures.displayPowerTimer, state,
-                            true /* eventOnContentDetection */);
+    handleTimerStateChanged(&mFeatures.displayPowerTimer, state);
     ATRACE_INT("ExpiredDisplayPowerTimer", static_cast<int>(state));
 }
 
@@ -553,33 +588,37 @@
 }
 
 template <class T>
-bool Scheduler::handleTimerStateChanged(T* currentState, T newState, bool eventOnContentDetection) {
-    ConfigEvent event = ConfigEvent::None;
+bool Scheduler::handleTimerStateChanged(T* currentState, T newState) {
     HwcConfigIndexType newConfigId;
-    bool touchConsidered = false;
+    scheduler::RefreshRateConfigs::GlobalSignals consideredSignals;
     {
         std::lock_guard<std::mutex> lock(mFeatureStateLock);
         if (*currentState == newState) {
-            return touchConsidered;
+            return false;
         }
         *currentState = newState;
-        newConfigId = calculateRefreshRateConfigIndexType(&touchConsidered);
+        newConfigId = calculateRefreshRateConfigIndexType(&consideredSignals);
         if (mFeatures.configId == newConfigId) {
-            return touchConsidered;
+            // We don't need to change the config, but we might need to send an event
+            // about a config change, since it was suppressed due to a previous idleConsidered
+            if (!consideredSignals.idle) {
+                dispatchCachedReportedConfig();
+            }
+            return consideredSignals.touch;
         }
         mFeatures.configId = newConfigId;
-        if (eventOnContentDetection && !mFeatures.contentRequirements.empty()) {
-            event = ConfigEvent::Changed;
-        }
     }
     const RefreshRate& newRefreshRate = mRefreshRateConfigs.getRefreshRateFromConfigId(newConfigId);
-    mSchedulerCallback.changeRefreshRate(newRefreshRate, event);
-    return touchConsidered;
+    mSchedulerCallback.changeRefreshRate(newRefreshRate,
+                                         consideredSignals.idle ? ConfigEvent::None
+                                                                : ConfigEvent::Changed);
+    return consideredSignals.touch;
 }
 
-HwcConfigIndexType Scheduler::calculateRefreshRateConfigIndexType(bool* touchConsidered) {
+HwcConfigIndexType Scheduler::calculateRefreshRateConfigIndexType(
+        scheduler::RefreshRateConfigs::GlobalSignals* consideredSignals) {
     ATRACE_CALL();
-    if (touchConsidered) *touchConsidered = false;
+    if (consideredSignals) *consideredSignals = {};
 
     // If Display Power is not in normal operation we want to be in performance mode. When coming
     // back to normal mode, a grace period is given with DisplayPowerTimer.
@@ -600,6 +639,7 @@
 
         // If timer has expired as it means there is no new content on the screen.
         if (idle) {
+            if (consideredSignals) consideredSignals->idle = true;
             return mRefreshRateConfigs.getMinRefreshRateByPolicy().getConfigId();
         }
 
@@ -615,7 +655,8 @@
     }
 
     return mRefreshRateConfigs
-            .getBestRefreshRate(mFeatures.contentRequirements, touchActive, idle, touchConsidered)
+            .getBestRefreshRate(mFeatures.contentRequirements, {.touch = touchActive, .idle = idle},
+                                consideredSignals)
             .getConfigId();
 }
 
diff --git a/services/surfaceflinger/Scheduler/Scheduler.h b/services/surfaceflinger/Scheduler/Scheduler.h
index ebee9e3..9e24f909 100644
--- a/services/surfaceflinger/Scheduler/Scheduler.h
+++ b/services/surfaceflinger/Scheduler/Scheduler.h
@@ -81,9 +81,11 @@
     sp<EventThreadConnection> getEventConnection(ConnectionHandle);
 
     void onHotplugReceived(ConnectionHandle, PhysicalDisplayId, bool connected);
-    void onConfigChanged(ConnectionHandle, PhysicalDisplayId, HwcConfigIndexType configId,
-                         nsecs_t vsyncPeriod);
-
+    void onPrimaryDisplayConfigChanged(ConnectionHandle, PhysicalDisplayId,
+                                       HwcConfigIndexType configId, nsecs_t vsyncPeriod)
+            EXCLUDES(mFeatureStateLock);
+    void onNonPrimaryDisplayConfigChanged(ConnectionHandle, PhysicalDisplayId,
+                                          HwcConfigIndexType configId, nsecs_t vsyncPeriod);
     void onScreenAcquired(ConnectionHandle);
     void onScreenReleased(ConnectionHandle);
 
@@ -179,16 +181,19 @@
 
     // handles various timer features to change the refresh rate.
     template <class T>
-    bool handleTimerStateChanged(T* currentState, T newState, bool eventOnContentDetection);
+    bool handleTimerStateChanged(T* currentState, T newState);
 
     void setVsyncPeriod(nsecs_t period);
 
     // This function checks whether individual features that are affecting the refresh rate
     // selection were initialized, prioritizes them, and calculates the HwcConfigIndexType
     // for the suggested refresh rate.
-    HwcConfigIndexType calculateRefreshRateConfigIndexType(bool* touchConsidered = nullptr)
+    HwcConfigIndexType calculateRefreshRateConfigIndexType(
+            scheduler::RefreshRateConfigs::GlobalSignals* consideredSignals = nullptr)
             REQUIRES(mFeatureStateLock);
 
+    void dispatchCachedReportedConfig() REQUIRES(mFeatureStateLock);
+
     // Stores EventThread associated with a given VSyncSource, and an initial EventThreadConnection.
     struct Connection {
         sp<EventThreadConnection> connection;
@@ -240,6 +245,16 @@
         LayerHistory::Summary contentRequirements;
 
         bool isDisplayPowerStateNormal = true;
+
+        // Used to cache the last parameters of onPrimaryDisplayConfigChanged
+        struct ConfigChangedParams {
+            ConnectionHandle handle;
+            PhysicalDisplayId displayId;
+            HwcConfigIndexType configId;
+            nsecs_t vsyncPeriod;
+        };
+
+        std::optional<ConfigChangedParams> cachedConfigChangedParams;
     } mFeatures GUARDED_BY(mFeatureStateLock);
 
     const scheduler::RefreshRateConfigs& mRefreshRateConfigs;
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 68dec66..5ba7839 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -1077,8 +1077,8 @@
         const nsecs_t vsyncPeriod =
                 mRefreshRateConfigs->getRefreshRateFromConfigId(mUpcomingActiveConfig.configId)
                         .getVsyncPeriod();
-        mScheduler->onConfigChanged(mAppConnectionHandle, display->getId()->value,
-                                    mUpcomingActiveConfig.configId, vsyncPeriod);
+        mScheduler->onPrimaryDisplayConfigChanged(mAppConnectionHandle, display->getId()->value,
+                                                  mUpcomingActiveConfig.configId, vsyncPeriod);
     }
 }
 
@@ -2991,8 +2991,8 @@
     // anyway since there are no connected apps at this point.
     const nsecs_t vsyncPeriod =
             mRefreshRateConfigs->getRefreshRateFromConfigId(currentConfig).getVsyncPeriod();
-    mScheduler->onConfigChanged(mAppConnectionHandle, primaryDisplayId.value, currentConfig,
-                                vsyncPeriod);
+    mScheduler->onPrimaryDisplayConfigChanged(mAppConnectionHandle, primaryDisplayId.value,
+                                              currentConfig, vsyncPeriod);
 }
 
 void SurfaceFlinger::commitTransaction()
@@ -5939,8 +5939,8 @@
         const nsecs_t vsyncPeriod = getHwComposer()
                                             .getConfigs(*displayId)[policy->defaultConfig.value()]
                                             ->getVsyncPeriod();
-        mScheduler->onConfigChanged(mAppConnectionHandle, display->getId()->value,
-                                    policy->defaultConfig, vsyncPeriod);
+        mScheduler->onNonPrimaryDisplayConfigChanged(mAppConnectionHandle, display->getId()->value,
+                                                     policy->defaultConfig, vsyncPeriod);
         return NO_ERROR;
     }
 
@@ -5972,8 +5972,8 @@
     const nsecs_t vsyncPeriod =
             mRefreshRateConfigs->getRefreshRateFromConfigId(display->getActiveConfig())
                     .getVsyncPeriod();
-    mScheduler->onConfigChanged(mAppConnectionHandle, display->getId()->value,
-                                display->getActiveConfig(), vsyncPeriod);
+    mScheduler->onPrimaryDisplayConfigChanged(mAppConnectionHandle, display->getId()->value,
+                                              display->getActiveConfig(), vsyncPeriod);
 
     auto configId = mScheduler->getPreferredConfigId();
     auto& preferredRefreshRate = configId
diff --git a/services/surfaceflinger/tests/unittests/RefreshRateConfigsTest.cpp b/services/surfaceflinger/tests/unittests/RefreshRateConfigsTest.cpp
index 4fa8455..f24575e 100644
--- a/services/surfaceflinger/tests/unittests/RefreshRateConfigsTest.cpp
+++ b/services/surfaceflinger/tests/unittests/RefreshRateConfigsTest.cpp
@@ -343,7 +343,6 @@
 }
 
 TEST_F(RefreshRateConfigsTest, getBestRefreshRate_noLayers) {
-    bool ignored;
     auto refreshRateConfigs =
             std::make_unique<RefreshRateConfigs>(m60_72_90Device, /*currentConfigId=*/
                                                  HWC_CONFIG_ID_72);
@@ -352,17 +351,14 @@
     // range.
     auto layers = std::vector<LayerRequirement>{};
     EXPECT_EQ(mExpected90Config,
-              refreshRateConfigs->getBestRefreshRate(layers, /*touchActive*/
-                                                     false, /*idle*/ false, &ignored));
+              refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
 
     ASSERT_GE(refreshRateConfigs->setDisplayManagerPolicy({HWC_CONFIG_ID_60, {60, 60}}), 0);
     EXPECT_EQ(mExpected60Config,
-              refreshRateConfigs->getBestRefreshRate(layers, /*touchActive*/
-                                                     false, /*idle*/ false, &ignored));
+              refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
 }
 
 TEST_F(RefreshRateConfigsTest, getBestRefreshRate_60_90) {
-    bool ignored;
     auto refreshRateConfigs =
             std::make_unique<RefreshRateConfigs>(m60_90Device,
                                                  /*currentConfigId=*/HWC_CONFIG_ID_60);
@@ -373,163 +369,134 @@
     lr.vote = LayerVoteType::Min;
     lr.name = "Min";
     EXPECT_EQ(mExpected60Config,
-              refreshRateConfigs->getBestRefreshRate(layers, /*touchActive*/ false,
-                                                     /*idle*/ false, &ignored));
+              refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
 
     lr.vote = LayerVoteType::Max;
     lr.name = "Max";
     EXPECT_EQ(mExpected90Config,
-              refreshRateConfigs->getBestRefreshRate(layers, /*touchActive*/ false,
-                                                     /*idle*/ false, &ignored));
+              refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
 
     lr.desiredRefreshRate = 90.0f;
     lr.vote = LayerVoteType::Heuristic;
     lr.name = "90Hz Heuristic";
     EXPECT_EQ(mExpected90Config,
-              refreshRateConfigs->getBestRefreshRate(layers, /*touchActive*/ false,
-                                                     /*idle*/ false, &ignored));
+              refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
 
     lr.desiredRefreshRate = 60.0f;
     lr.name = "60Hz Heuristic";
     EXPECT_EQ(mExpected60Config,
-              refreshRateConfigs->getBestRefreshRate(layers, /*touchActive*/ false,
-                                                     /*idle*/ false, &ignored));
+              refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
 
     lr.desiredRefreshRate = 45.0f;
     lr.name = "45Hz Heuristic";
     EXPECT_EQ(mExpected90Config,
-              refreshRateConfigs->getBestRefreshRate(layers, /*touchActive*/ false,
-                                                     /*idle*/ false, &ignored));
+              refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
 
     lr.desiredRefreshRate = 30.0f;
     lr.name = "30Hz Heuristic";
     EXPECT_EQ(mExpected60Config,
-              refreshRateConfigs->getBestRefreshRate(layers, /*touchActive*/ false,
-                                                     /*idle*/ false, &ignored));
+              refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
 
     lr.desiredRefreshRate = 24.0f;
     lr.name = "24Hz Heuristic";
     EXPECT_EQ(mExpected60Config,
-              refreshRateConfigs->getBestRefreshRate(layers, /*touchActive*/ false,
-                                                     /*idle*/ false, &ignored));
+              refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
 
     lr.name = "";
     ASSERT_GE(refreshRateConfigs->setDisplayManagerPolicy({HWC_CONFIG_ID_60, {60, 60}}), 0);
 
     lr.vote = LayerVoteType::Min;
     EXPECT_EQ(mExpected60Config,
-              refreshRateConfigs->getBestRefreshRate(layers, /*touchActive*/ false,
-                                                     /*idle*/ false, &ignored));
+              refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
 
     lr.vote = LayerVoteType::Max;
     EXPECT_EQ(mExpected60Config,
-              refreshRateConfigs->getBestRefreshRate(layers, /*touchActive*/ false,
-                                                     /*idle*/ false, &ignored));
+              refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
 
     lr.desiredRefreshRate = 90.0f;
     lr.vote = LayerVoteType::Heuristic;
     EXPECT_EQ(mExpected60Config,
-              refreshRateConfigs->getBestRefreshRate(layers, /*touchActive*/ false,
-                                                     /*idle*/ false, &ignored));
+              refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
 
     lr.desiredRefreshRate = 60.0f;
     EXPECT_EQ(mExpected60Config,
-              refreshRateConfigs->getBestRefreshRate(layers, /*touchActive*/ false,
-                                                     /*idle*/ false, &ignored));
+              refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
 
     lr.desiredRefreshRate = 45.0f;
     EXPECT_EQ(mExpected60Config,
-              refreshRateConfigs->getBestRefreshRate(layers, /*touchActive*/ false,
-                                                     /*idle*/ false, &ignored));
+              refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
 
     lr.desiredRefreshRate = 30.0f;
     EXPECT_EQ(mExpected60Config,
-              refreshRateConfigs->getBestRefreshRate(layers, /*touchActive*/ false,
-                                                     /*idle*/ false, &ignored));
+              refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
 
     lr.desiredRefreshRate = 24.0f;
     EXPECT_EQ(mExpected60Config,
-              refreshRateConfigs->getBestRefreshRate(layers, /*touchActive*/ false,
-                                                     /*idle*/ false, &ignored));
+              refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
 
     ASSERT_GE(refreshRateConfigs->setDisplayManagerPolicy({HWC_CONFIG_ID_90, {90, 90}}), 0);
 
     lr.vote = LayerVoteType::Min;
     EXPECT_EQ(mExpected90Config,
-              refreshRateConfigs->getBestRefreshRate(layers, /*touchActive*/ false,
-                                                     /*idle*/ false, &ignored));
+              refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
 
     lr.vote = LayerVoteType::Max;
     EXPECT_EQ(mExpected90Config,
-              refreshRateConfigs->getBestRefreshRate(layers, /*touchActive*/ false,
-                                                     /*idle*/ false, &ignored));
+              refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
 
     lr.desiredRefreshRate = 90.0f;
     lr.vote = LayerVoteType::Heuristic;
     EXPECT_EQ(mExpected90Config,
-              refreshRateConfigs->getBestRefreshRate(layers, /*touchActive*/ false,
-                                                     /*idle*/ false, &ignored));
+              refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
 
     lr.desiredRefreshRate = 60.0f;
     EXPECT_EQ(mExpected90Config,
-              refreshRateConfigs->getBestRefreshRate(layers, /*touchActive*/ false,
-                                                     /*idle*/ false, &ignored));
+              refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
 
     lr.desiredRefreshRate = 45.0f;
     EXPECT_EQ(mExpected90Config,
-              refreshRateConfigs->getBestRefreshRate(layers, /*touchActive*/ false,
-                                                     /*idle*/ false, &ignored));
+              refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
 
     lr.desiredRefreshRate = 30.0f;
     EXPECT_EQ(mExpected90Config,
-              refreshRateConfigs->getBestRefreshRate(layers, /*touchActive*/ false,
-                                                     /*idle*/ false, &ignored));
+              refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
 
     lr.desiredRefreshRate = 24.0f;
     EXPECT_EQ(mExpected90Config,
-              refreshRateConfigs->getBestRefreshRate(layers, /*touchActive*/ false,
-                                                     /*idle*/ false, &ignored));
+              refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
 
     ASSERT_GE(refreshRateConfigs->setDisplayManagerPolicy({HWC_CONFIG_ID_60, {0, 120}}), 0);
     lr.vote = LayerVoteType::Min;
     EXPECT_EQ(mExpected60Config,
-              refreshRateConfigs->getBestRefreshRate(layers, /*touchActive*/ false,
-                                                     /*idle*/ false, &ignored));
+              refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
 
     lr.vote = LayerVoteType::Max;
     EXPECT_EQ(mExpected90Config,
-              refreshRateConfigs->getBestRefreshRate(layers, /*touchActive*/ false,
-                                                     /*idle*/ false, &ignored));
+              refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
 
     lr.desiredRefreshRate = 90.0f;
     lr.vote = LayerVoteType::Heuristic;
     EXPECT_EQ(mExpected90Config,
-              refreshRateConfigs->getBestRefreshRate(layers, /*touchActive*/ false,
-                                                     /*idle*/ false, &ignored));
+              refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
 
     lr.desiredRefreshRate = 60.0f;
     EXPECT_EQ(mExpected60Config,
-              refreshRateConfigs->getBestRefreshRate(layers, /*touchActive*/ false,
-                                                     /*idle*/ false, &ignored));
+              refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
 
     lr.desiredRefreshRate = 45.0f;
     EXPECT_EQ(mExpected90Config,
-              refreshRateConfigs->getBestRefreshRate(layers, /*touchActive*/ false,
-                                                     /*idle*/ false, &ignored));
+              refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
 
     lr.desiredRefreshRate = 30.0f;
     EXPECT_EQ(mExpected60Config,
-              refreshRateConfigs->getBestRefreshRate(layers, /*touchActive*/ false,
-                                                     /*idle*/ false, &ignored));
+              refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
 
     lr.desiredRefreshRate = 24.0f;
     EXPECT_EQ(mExpected60Config,
-              refreshRateConfigs->getBestRefreshRate(layers, /*touchActive*/ false,
-                                                     /*idle*/ false, &ignored));
+              refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
 }
 
 TEST_F(RefreshRateConfigsTest, getBestRefreshRate_60_72_90) {
-    bool ignored;
     auto refreshRateConfigs =
             std::make_unique<RefreshRateConfigs>(m60_72_90Device,
                                                  /*currentConfigId=*/HWC_CONFIG_ID_60);
@@ -539,43 +506,35 @@
 
     lr.vote = LayerVoteType::Min;
     EXPECT_EQ(mExpected60Config,
-              refreshRateConfigs->getBestRefreshRate(layers, /*touchActive*/ false,
-                                                     /*idle*/ false, &ignored));
+              refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
 
     lr.vote = LayerVoteType::Max;
     EXPECT_EQ(mExpected90Config,
-              refreshRateConfigs->getBestRefreshRate(layers, /*touchActive*/ false,
-                                                     /*idle*/ false, &ignored));
+              refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
 
     lr.desiredRefreshRate = 90.0f;
     lr.vote = LayerVoteType::Heuristic;
     EXPECT_EQ(mExpected90Config,
-              refreshRateConfigs->getBestRefreshRate(layers, /*touchActive*/ false,
-                                                     /*idle*/ false, &ignored));
+              refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
 
     lr.desiredRefreshRate = 60.0f;
     EXPECT_EQ(mExpected60Config,
-              refreshRateConfigs->getBestRefreshRate(layers, /*touchActive*/ false,
-                                                     /*idle*/ false, &ignored));
+              refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
 
     lr.desiredRefreshRate = 45.0f;
     EXPECT_EQ(mExpected90Config,
-              refreshRateConfigs->getBestRefreshRate(layers, /*touchActive*/ false,
-                                                     /*idle*/ false, &ignored));
+              refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
 
     lr.desiredRefreshRate = 30.0f;
     EXPECT_EQ(mExpected60Config,
-              refreshRateConfigs->getBestRefreshRate(layers, /*touchActive*/ false,
-                                                     /*idle*/ false, &ignored));
+              refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
 
     lr.desiredRefreshRate = 24.0f;
     EXPECT_EQ(mExpected72Config,
-              refreshRateConfigs->getBestRefreshRate(layers, /*touchActive*/ false,
-                                                     /*idle*/ false, &ignored));
+              refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
 }
 
 TEST_F(RefreshRateConfigsTest, getBestRefreshRate_30_60_72_90_120) {
-    bool ignored;
     auto refreshRateConfigs =
             std::make_unique<RefreshRateConfigs>(m30_60_72_90_120Device,
                                                  /*currentConfigId=*/HWC_CONFIG_ID_60);
@@ -590,28 +549,24 @@
     lr2.desiredRefreshRate = 60.0f;
     lr2.vote = LayerVoteType::Heuristic;
     EXPECT_EQ(mExpected120Config,
-              refreshRateConfigs->getBestRefreshRate(layers, /*touchActive*/ false,
-                                                     /*idle*/ false, &ignored));
+              refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
 
     lr1.desiredRefreshRate = 24.0f;
     lr1.vote = LayerVoteType::Heuristic;
     lr2.desiredRefreshRate = 48.0f;
     lr2.vote = LayerVoteType::Heuristic;
     EXPECT_EQ(mExpected72Config,
-              refreshRateConfigs->getBestRefreshRate(layers, /*touchActive*/ false,
-                                                     /*idle*/ false, &ignored));
+              refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
 
     lr1.desiredRefreshRate = 24.0f;
     lr1.vote = LayerVoteType::Heuristic;
     lr2.desiredRefreshRate = 48.0f;
     lr2.vote = LayerVoteType::Heuristic;
     EXPECT_EQ(mExpected72Config,
-              refreshRateConfigs->getBestRefreshRate(layers, /*touchActive*/ false,
-                                                     /*idle*/ false, &ignored));
+              refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
 }
 
 TEST_F(RefreshRateConfigsTest, getBestRefreshRate_30_60_90_120_DifferentTypes) {
-    bool ignored;
     auto refreshRateConfigs =
             std::make_unique<RefreshRateConfigs>(m30_60_72_90_120Device,
                                                  /*currentConfigId=*/HWC_CONFIG_ID_60);
@@ -628,8 +583,7 @@
     lr2.vote = LayerVoteType::Heuristic;
     lr2.name = "60Hz Heuristic";
     EXPECT_EQ(mExpected120Config,
-              refreshRateConfigs->getBestRefreshRate(layers, /*touchActive*/ false,
-                                                     /*idle*/ false, &ignored));
+              refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
 
     lr1.desiredRefreshRate = 24.0f;
     lr1.vote = LayerVoteType::ExplicitExactOrMultiple;
@@ -638,8 +592,7 @@
     lr2.vote = LayerVoteType::Heuristic;
     lr2.name = "60Hz Heuristic";
     EXPECT_EQ(mExpected120Config,
-              refreshRateConfigs->getBestRefreshRate(layers, /*touchActive*/ false,
-                                                     /*idle*/ false, &ignored));
+              refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
 
     lr1.desiredRefreshRate = 24.0f;
     lr1.vote = LayerVoteType::ExplicitExactOrMultiple;
@@ -648,8 +601,7 @@
     lr2.vote = LayerVoteType::ExplicitDefault;
     lr2.name = "60Hz ExplicitDefault";
     EXPECT_EQ(mExpected120Config,
-              refreshRateConfigs->getBestRefreshRate(layers, /*touchActive*/ false,
-                                                     /*idle*/ false, &ignored));
+              refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
 
     lr1.desiredRefreshRate = 24.0f;
     lr1.vote = LayerVoteType::ExplicitExactOrMultiple;
@@ -658,8 +610,7 @@
     lr2.vote = LayerVoteType::Heuristic;
     lr2.name = "90Hz Heuristic";
     EXPECT_EQ(mExpected90Config,
-              refreshRateConfigs->getBestRefreshRate(layers, /*touchActive*/ false,
-                                                     /*idle*/ false, &ignored));
+              refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
 
     lr1.desiredRefreshRate = 24.0f;
     lr1.vote = LayerVoteType::ExplicitExactOrMultiple;
@@ -668,8 +619,7 @@
     lr2.vote = LayerVoteType::ExplicitDefault;
     lr2.name = "90Hz Heuristic";
     EXPECT_EQ(mExpected72Config,
-              refreshRateConfigs->getBestRefreshRate(layers, /*touchActive*/ false,
-                                                     /*idle*/ false, &ignored));
+              refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
 
     lr1.desiredRefreshRate = 24.0f;
     lr1.vote = LayerVoteType::ExplicitDefault;
@@ -678,8 +628,7 @@
     lr2.vote = LayerVoteType::Heuristic;
     lr2.name = "90Hz Heuristic";
     EXPECT_EQ(mExpected90Config,
-              refreshRateConfigs->getBestRefreshRate(layers, /*touchActive*/ false,
-                                                     /*idle*/ false, &ignored));
+              refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
 
     lr1.desiredRefreshRate = 24.0f;
     lr1.vote = LayerVoteType::Heuristic;
@@ -688,8 +637,7 @@
     lr2.vote = LayerVoteType::ExplicitDefault;
     lr2.name = "90Hz ExplicitDefault";
     EXPECT_EQ(mExpected72Config,
-              refreshRateConfigs->getBestRefreshRate(layers, /*touchActive*/ false,
-                                                     /*idle*/ false, &ignored));
+              refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
 
     lr1.desiredRefreshRate = 24.0f;
     lr1.vote = LayerVoteType::ExplicitExactOrMultiple;
@@ -698,8 +646,7 @@
     lr2.vote = LayerVoteType::ExplicitDefault;
     lr2.name = "90Hz ExplicitDefault";
     EXPECT_EQ(mExpected72Config,
-              refreshRateConfigs->getBestRefreshRate(layers, /*touchActive*/ false,
-                                                     /*idle*/ false, &ignored));
+              refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
 
     lr1.desiredRefreshRate = 24.0f;
     lr1.vote = LayerVoteType::ExplicitDefault;
@@ -708,12 +655,10 @@
     lr2.vote = LayerVoteType::ExplicitExactOrMultiple;
     lr2.name = "90Hz ExplicitExactOrMultiple";
     EXPECT_EQ(mExpected90Config,
-              refreshRateConfigs->getBestRefreshRate(layers, /*touchActive*/ false,
-                                                     /*idle*/ false, &ignored));
+              refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
 }
 
 TEST_F(RefreshRateConfigsTest, getBestRefreshRate_30_60) {
-    bool ignored;
     auto refreshRateConfigs =
             std::make_unique<RefreshRateConfigs>(m30_60Device,
                                                  /*currentConfigId=*/HWC_CONFIG_ID_60);
@@ -723,43 +668,35 @@
 
     lr.vote = LayerVoteType::Min;
     EXPECT_EQ(mExpected30Config,
-              refreshRateConfigs->getBestRefreshRate(layers, /*touchActive*/ false,
-                                                     /*idle*/ false, &ignored));
+              refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
 
     lr.vote = LayerVoteType::Max;
     EXPECT_EQ(mExpected60Config,
-              refreshRateConfigs->getBestRefreshRate(layers, /*touchActive*/ false,
-                                                     /*idle*/ false, &ignored));
+              refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
 
     lr.desiredRefreshRate = 90.0f;
     lr.vote = LayerVoteType::Heuristic;
     EXPECT_EQ(mExpected60Config,
-              refreshRateConfigs->getBestRefreshRate(layers, /*touchActive*/ false,
-                                                     /*idle*/ false, &ignored));
+              refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
 
     lr.desiredRefreshRate = 60.0f;
     EXPECT_EQ(mExpected60Config,
-              refreshRateConfigs->getBestRefreshRate(layers, /*touchActive*/ false,
-                                                     /*idle*/ false, &ignored));
+              refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
 
     lr.desiredRefreshRate = 45.0f;
     EXPECT_EQ(mExpected60Config,
-              refreshRateConfigs->getBestRefreshRate(layers, /*touchActive*/ false,
-                                                     /*idle*/ false, &ignored));
+              refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
 
     lr.desiredRefreshRate = 30.0f;
     EXPECT_EQ(mExpected30Config,
-              refreshRateConfigs->getBestRefreshRate(layers, /*touchActive*/ false,
-                                                     /*idle*/ false, &ignored));
+              refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
 
     lr.desiredRefreshRate = 24.0f;
     EXPECT_EQ(mExpected60Config,
-              refreshRateConfigs->getBestRefreshRate(layers, /*touchActive*/ false,
-                                                     /*idle*/ false, &ignored));
+              refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
 }
 
 TEST_F(RefreshRateConfigsTest, getBestRefreshRate_30_60_72_90) {
-    bool ignored;
     auto refreshRateConfigs =
             std::make_unique<RefreshRateConfigs>(m30_60_72_90Device,
                                                  /*currentConfigId=*/HWC_CONFIG_ID_60);
@@ -770,71 +707,57 @@
     lr.vote = LayerVoteType::Min;
     lr.name = "Min";
     EXPECT_EQ(mExpected30Config,
-              refreshRateConfigs->getBestRefreshRate(layers, /*touchActive*/ false,
-                                                     /*idle*/ false, &ignored));
+              refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
 
     lr.vote = LayerVoteType::Max;
     lr.name = "Max";
     EXPECT_EQ(mExpected90Config,
-              refreshRateConfigs->getBestRefreshRate(layers, /*touchActive*/ false,
-                                                     /*idle*/ false, &ignored));
+              refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
 
     lr.desiredRefreshRate = 90.0f;
     lr.vote = LayerVoteType::Heuristic;
     lr.name = "90Hz Heuristic";
     EXPECT_EQ(mExpected90Config,
-              refreshRateConfigs->getBestRefreshRate(layers, /*touchActive*/ false,
-                                                     /*idle*/ false, &ignored));
+              refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
 
     lr.desiredRefreshRate = 60.0f;
     lr.name = "60Hz Heuristic";
     EXPECT_EQ(mExpected60Config,
-              refreshRateConfigs->getBestRefreshRate(layers, /*touchActive*/ false,
-                                                     /*idle*/ false, &ignored));
+              refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
     EXPECT_EQ(mExpected90Config,
-              refreshRateConfigs->getBestRefreshRate(layers, /*touchActive*/ true,
-                                                     /*idle*/ false, &ignored));
+              refreshRateConfigs->getBestRefreshRate(layers, {.touch = true, .idle = false}));
 
     lr.desiredRefreshRate = 45.0f;
     lr.name = "45Hz Heuristic";
     EXPECT_EQ(mExpected90Config,
-              refreshRateConfigs->getBestRefreshRate(layers, /*touchActive*/ false,
-                                                     /*idle*/ false, &ignored));
+              refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
     EXPECT_EQ(mExpected90Config,
-              refreshRateConfigs->getBestRefreshRate(layers, /*touchActive*/ true,
-                                                     /*idle*/ false, &ignored));
+              refreshRateConfigs->getBestRefreshRate(layers, {.touch = true, .idle = false}));
 
     lr.desiredRefreshRate = 30.0f;
     lr.name = "30Hz Heuristic";
     EXPECT_EQ(mExpected30Config,
-              refreshRateConfigs->getBestRefreshRate(layers, /*touchActive*/ false,
-                                                     /*idle*/ false, &ignored));
+              refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
     EXPECT_EQ(mExpected90Config,
-              refreshRateConfigs->getBestRefreshRate(layers, /*touchActive*/ true,
-                                                     /*idle*/ false, &ignored));
+              refreshRateConfigs->getBestRefreshRate(layers, {.touch = true, .idle = false}));
 
     lr.desiredRefreshRate = 24.0f;
     lr.name = "24Hz Heuristic";
     EXPECT_EQ(mExpected72Config,
-              refreshRateConfigs->getBestRefreshRate(layers, /*touchActive*/ false,
-                                                     /*idle*/ false, &ignored));
+              refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
     EXPECT_EQ(mExpected90Config,
-              refreshRateConfigs->getBestRefreshRate(layers, /*touchActive*/ true,
-                                                     /*idle*/ false, &ignored));
+              refreshRateConfigs->getBestRefreshRate(layers, {.touch = true, .idle = false}));
 
     lr.desiredRefreshRate = 24.0f;
     lr.vote = LayerVoteType::ExplicitExactOrMultiple;
     lr.name = "24Hz ExplicitExactOrMultiple";
     EXPECT_EQ(mExpected72Config,
-              refreshRateConfigs->getBestRefreshRate(layers, /*touchActive*/ false,
-                                                     /*idle*/ false, &ignored));
+              refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
     EXPECT_EQ(mExpected90Config,
-              refreshRateConfigs->getBestRefreshRate(layers, /*touchActive*/ true,
-                                                     /*idle*/ false, &ignored));
+              refreshRateConfigs->getBestRefreshRate(layers, {.touch = true, .idle = false}));
 }
 
 TEST_F(RefreshRateConfigsTest, getBestRefreshRate_PriorityTest) {
-    bool ignored;
     auto refreshRateConfigs =
             std::make_unique<RefreshRateConfigs>(m30_60_90Device,
                                                  /*currentConfigId=*/HWC_CONFIG_ID_60);
@@ -847,56 +770,48 @@
     lr1.vote = LayerVoteType::Min;
     lr2.vote = LayerVoteType::Max;
     EXPECT_EQ(mExpected90Config,
-              refreshRateConfigs->getBestRefreshRate(layers, /*touchActive*/ false,
-                                                     /*idle*/ false, &ignored));
+              refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
 
     lr1.vote = LayerVoteType::Min;
     lr2.vote = LayerVoteType::Heuristic;
     lr2.desiredRefreshRate = 24.0f;
     EXPECT_EQ(mExpected60Config,
-              refreshRateConfigs->getBestRefreshRate(layers, /*touchActive*/ false,
-                                                     /*idle*/ false, &ignored));
+              refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
 
     lr1.vote = LayerVoteType::Min;
     lr2.vote = LayerVoteType::ExplicitExactOrMultiple;
     lr2.desiredRefreshRate = 24.0f;
     EXPECT_EQ(mExpected60Config,
-              refreshRateConfigs->getBestRefreshRate(layers, /*touchActive*/ false,
-                                                     /*idle*/ false, &ignored));
+              refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
 
     lr1.vote = LayerVoteType::Max;
     lr2.vote = LayerVoteType::Heuristic;
     lr2.desiredRefreshRate = 60.0f;
     EXPECT_EQ(mExpected90Config,
-              refreshRateConfigs->getBestRefreshRate(layers, /*touchActive*/ false,
-                                                     /*idle*/ false, &ignored));
+              refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
 
     lr1.vote = LayerVoteType::Max;
     lr2.vote = LayerVoteType::ExplicitExactOrMultiple;
     lr2.desiredRefreshRate = 60.0f;
     EXPECT_EQ(mExpected90Config,
-              refreshRateConfigs->getBestRefreshRate(layers, /*touchActive*/ false,
-                                                     /*idle*/ false, &ignored));
+              refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
 
     lr1.vote = LayerVoteType::Heuristic;
     lr1.desiredRefreshRate = 15.0f;
     lr2.vote = LayerVoteType::Heuristic;
     lr2.desiredRefreshRate = 45.0f;
     EXPECT_EQ(mExpected90Config,
-              refreshRateConfigs->getBestRefreshRate(layers, /*touchActive*/ false,
-                                                     /*idle*/ false, &ignored));
+              refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
 
     lr1.vote = LayerVoteType::Heuristic;
     lr1.desiredRefreshRate = 30.0f;
     lr2.vote = LayerVoteType::ExplicitExactOrMultiple;
     lr2.desiredRefreshRate = 45.0f;
     EXPECT_EQ(mExpected90Config,
-              refreshRateConfigs->getBestRefreshRate(layers, /*touchActive*/ false,
-                                                     /*idle*/ false, &ignored));
+              refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
 }
 
 TEST_F(RefreshRateConfigsTest, getBestRefreshRate_24FpsVideo) {
-    bool ignored;
     auto refreshRateConfigs =
             std::make_unique<RefreshRateConfigs>(m60_90Device,
                                                  /*currentConfigId=*/HWC_CONFIG_ID_60);
@@ -908,8 +823,7 @@
     for (float fps = 23.0f; fps < 25.0f; fps += 0.1f) {
         lr.desiredRefreshRate = fps;
         const auto& refreshRate =
-                refreshRateConfigs->getBestRefreshRate(layers, /*touchActive*/ false,
-                                                       /*idle*/ false, &ignored);
+                refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false});
         EXPECT_EQ(mExpected60Config, refreshRate) << fps << "Hz chooses " << refreshRate.getName();
     }
 }
@@ -938,7 +852,6 @@
 }
 
 TEST_F(RefreshRateConfigsTest, twoDeviceConfigs_getBestRefreshRate_Explicit) {
-    bool ignored;
     auto refreshRateConfigs =
             std::make_unique<RefreshRateConfigs>(m60_90Device,
                                                  /*currentConfigId=*/HWC_CONFIG_ID_60);
@@ -953,24 +866,21 @@
     lr2.vote = LayerVoteType::ExplicitExactOrMultiple;
     lr2.desiredRefreshRate = 90.0f;
     EXPECT_EQ(mExpected90Config,
-              refreshRateConfigs->getBestRefreshRate(layers, /*touchActive*/ false,
-                                                     /*idle*/ false, &ignored));
+              refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
 
     lr1.vote = LayerVoteType::ExplicitDefault;
     lr1.desiredRefreshRate = 90.0f;
     lr2.vote = LayerVoteType::ExplicitExactOrMultiple;
     lr2.desiredRefreshRate = 60.0f;
     EXPECT_EQ(mExpected60Config,
-              refreshRateConfigs->getBestRefreshRate(layers, /*touchActive*/ false,
-                                                     /*idle*/ false, &ignored));
+              refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
 
     lr1.vote = LayerVoteType::Heuristic;
     lr1.desiredRefreshRate = 90.0f;
     lr2.vote = LayerVoteType::ExplicitExactOrMultiple;
     lr2.desiredRefreshRate = 60.0f;
     EXPECT_EQ(mExpected90Config,
-              refreshRateConfigs->getBestRefreshRate(layers, /*touchActive*/ false,
-                                                     /*idle*/ false, &ignored));
+              refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
 }
 
 TEST_F(RefreshRateConfigsTest, testInPolicy) {
@@ -982,7 +892,6 @@
 }
 
 TEST_F(RefreshRateConfigsTest, getBestRefreshRate_75HzContent) {
-    bool ignored;
     auto refreshRateConfigs =
             std::make_unique<RefreshRateConfigs>(m60_90Device,
                                                  /*currentConfigId=*/HWC_CONFIG_ID_60);
@@ -994,14 +903,12 @@
     for (float fps = 75.0f; fps < 100.0f; fps += 0.1f) {
         lr.desiredRefreshRate = fps;
         const auto& refreshRate =
-                refreshRateConfigs->getBestRefreshRate(layers, /*touchActive*/ false,
-                                                       /*idle*/ false, &ignored);
+                refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false});
         EXPECT_EQ(mExpected90Config, refreshRate) << fps << "Hz chooses " << refreshRate.getName();
     }
 }
 
 TEST_F(RefreshRateConfigsTest, getBestRefreshRate_Multiples) {
-    bool ignored;
     auto refreshRateConfigs =
             std::make_unique<RefreshRateConfigs>(m60_90Device,
                                                  /*currentConfigId=*/HWC_CONFIG_ID_60);
@@ -1018,8 +925,7 @@
     lr2.desiredRefreshRate = 90.0f;
     lr2.name = "90Hz Heuristic";
     EXPECT_EQ(mExpected90Config,
-              refreshRateConfigs->getBestRefreshRate(layers, /*touchActive*/ false,
-                                                     /*idle*/ false, &ignored));
+              refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
 
     lr1.vote = LayerVoteType::ExplicitExactOrMultiple;
     lr1.desiredRefreshRate = 60.0f;
@@ -1028,8 +934,7 @@
     lr2.desiredRefreshRate = 90.0f;
     lr2.name = "90Hz ExplicitDefault";
     EXPECT_EQ(mExpected60Config,
-              refreshRateConfigs->getBestRefreshRate(layers, /*touchActive*/ false,
-                                                     /*idle*/ false, &ignored));
+              refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
 
     lr1.vote = LayerVoteType::ExplicitExactOrMultiple;
     lr1.desiredRefreshRate = 60.0f;
@@ -1037,8 +942,7 @@
     lr2.vote = LayerVoteType::Max;
     lr2.name = "Max";
     EXPECT_EQ(mExpected90Config,
-              refreshRateConfigs->getBestRefreshRate(layers, /*touchActive*/ false,
-                                                     /*idle*/ false, &ignored));
+              refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
 
     lr1.vote = LayerVoteType::ExplicitExactOrMultiple;
     lr1.desiredRefreshRate = 30.0f;
@@ -1047,8 +951,7 @@
     lr2.desiredRefreshRate = 90.0f;
     lr2.name = "90Hz Heuristic";
     EXPECT_EQ(mExpected90Config,
-              refreshRateConfigs->getBestRefreshRate(layers, /*touchActive*/ false,
-                                                     /*idle*/ false, &ignored));
+              refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
 
     lr1.vote = LayerVoteType::ExplicitExactOrMultiple;
     lr1.desiredRefreshRate = 30.0f;
@@ -1056,12 +959,10 @@
     lr2.vote = LayerVoteType::Max;
     lr2.name = "Max";
     EXPECT_EQ(mExpected90Config,
-              refreshRateConfigs->getBestRefreshRate(layers, /*touchActive*/ false,
-                                                     /*idle*/ false, &ignored));
+              refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
 }
 
 TEST_F(RefreshRateConfigsTest, scrollWhileWatching60fps_60_90) {
-    bool ignored;
     auto refreshRateConfigs =
             std::make_unique<RefreshRateConfigs>(m60_90Device,
                                                  /*currentConfigId=*/HWC_CONFIG_ID_60);
@@ -1077,7 +978,7 @@
     lr2.vote = LayerVoteType::NoVote;
     lr2.name = "NoVote";
     EXPECT_EQ(mExpected60Config,
-              refreshRateConfigs->getBestRefreshRate(layers, false, /*idle*/ false, &ignored));
+              refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
 
     lr1.vote = LayerVoteType::ExplicitExactOrMultiple;
     lr1.desiredRefreshRate = 60.0f;
@@ -1085,7 +986,7 @@
     lr2.vote = LayerVoteType::NoVote;
     lr2.name = "NoVote";
     EXPECT_EQ(mExpected90Config,
-              refreshRateConfigs->getBestRefreshRate(layers, true, /*idle*/ false, &ignored));
+              refreshRateConfigs->getBestRefreshRate(layers, {.touch = true, .idle = false}));
 
     lr1.vote = LayerVoteType::ExplicitExactOrMultiple;
     lr1.desiredRefreshRate = 60.0f;
@@ -1093,7 +994,7 @@
     lr2.vote = LayerVoteType::Max;
     lr2.name = "Max";
     EXPECT_EQ(mExpected90Config,
-              refreshRateConfigs->getBestRefreshRate(layers, true, /*idle*/ false, &ignored));
+              refreshRateConfigs->getBestRefreshRate(layers, {.touch = true, .idle = false}));
 
     lr1.vote = LayerVoteType::ExplicitExactOrMultiple;
     lr1.desiredRefreshRate = 60.0f;
@@ -1101,7 +1002,7 @@
     lr2.vote = LayerVoteType::Max;
     lr2.name = "Max";
     EXPECT_EQ(mExpected90Config,
-              refreshRateConfigs->getBestRefreshRate(layers, false, /*idle*/ false, &ignored));
+              refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
 
     // The other layer starts to provide buffers
     lr1.vote = LayerVoteType::ExplicitExactOrMultiple;
@@ -1111,20 +1012,20 @@
     lr2.desiredRefreshRate = 90.0f;
     lr2.name = "90Hz Heuristic";
     EXPECT_EQ(mExpected90Config,
-              refreshRateConfigs->getBestRefreshRate(layers, false, /*idle*/ false, &ignored));
+              refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
 }
 
 TEST_F(RefreshRateConfigsTest, touchConsidered) {
-    bool touchConsidered;
+    RefreshRateConfigs::GlobalSignals consideredSignals;
     auto refreshRateConfigs =
             std::make_unique<RefreshRateConfigs>(m60_90Device,
                                                  /*currentConfigId=*/HWC_CONFIG_ID_60);
 
-    refreshRateConfigs->getBestRefreshRate({}, false, /*idle*/ false, &touchConsidered);
-    EXPECT_EQ(false, touchConsidered);
+    refreshRateConfigs->getBestRefreshRate({}, {.touch = false, .idle = false}, &consideredSignals);
+    EXPECT_EQ(false, consideredSignals.touch);
 
-    refreshRateConfigs->getBestRefreshRate({}, true, /*idle*/ false, &touchConsidered);
-    EXPECT_EQ(true, touchConsidered);
+    refreshRateConfigs->getBestRefreshRate({}, {.touch = true, .idle = false}, &consideredSignals);
+    EXPECT_EQ(true, consideredSignals.touch);
 
     auto layers = std::vector<LayerRequirement>{LayerRequirement{.weight = 1.0f},
                                                 LayerRequirement{.weight = 1.0f}};
@@ -1137,8 +1038,9 @@
     lr2.vote = LayerVoteType::Heuristic;
     lr2.desiredRefreshRate = 60.0f;
     lr2.name = "60Hz Heuristic";
-    refreshRateConfigs->getBestRefreshRate(layers, true, /*idle*/ false, &touchConsidered);
-    EXPECT_EQ(true, touchConsidered);
+    refreshRateConfigs->getBestRefreshRate(layers, {.touch = true, .idle = false},
+                                           &consideredSignals);
+    EXPECT_EQ(true, consideredSignals.touch);
 
     lr1.vote = LayerVoteType::ExplicitDefault;
     lr1.desiredRefreshRate = 60.0f;
@@ -1146,8 +1048,9 @@
     lr2.vote = LayerVoteType::Heuristic;
     lr2.desiredRefreshRate = 60.0f;
     lr2.name = "60Hz Heuristic";
-    refreshRateConfigs->getBestRefreshRate(layers, true, /*idle*/ false, &touchConsidered);
-    EXPECT_EQ(false, touchConsidered);
+    refreshRateConfigs->getBestRefreshRate(layers, {.touch = true, .idle = false},
+                                           &consideredSignals);
+    EXPECT_EQ(false, consideredSignals.touch);
 
     lr1.vote = LayerVoteType::ExplicitExactOrMultiple;
     lr1.desiredRefreshRate = 60.0f;
@@ -1155,8 +1058,9 @@
     lr2.vote = LayerVoteType::Heuristic;
     lr2.desiredRefreshRate = 60.0f;
     lr2.name = "60Hz Heuristic";
-    refreshRateConfigs->getBestRefreshRate(layers, true, /*idle*/ false, &touchConsidered);
-    EXPECT_EQ(true, touchConsidered);
+    refreshRateConfigs->getBestRefreshRate(layers, {.touch = true, .idle = false},
+                                           &consideredSignals);
+    EXPECT_EQ(true, consideredSignals.touch);
 
     lr1.vote = LayerVoteType::ExplicitDefault;
     lr1.desiredRefreshRate = 60.0f;
@@ -1164,12 +1068,12 @@
     lr2.vote = LayerVoteType::Heuristic;
     lr2.desiredRefreshRate = 60.0f;
     lr2.name = "60Hz Heuristic";
-    refreshRateConfigs->getBestRefreshRate(layers, true, /*idle*/ false, &touchConsidered);
-    EXPECT_EQ(false, touchConsidered);
+    refreshRateConfigs->getBestRefreshRate(layers, {.touch = true, .idle = false},
+                                           &consideredSignals);
+    EXPECT_EQ(false, consideredSignals.touch);
 }
 
 TEST_F(RefreshRateConfigsTest, getBestRefreshRate_ExplicitDefault) {
-    bool ignored;
     auto refreshRateConfigs =
             std::make_unique<RefreshRateConfigs>(m60_90_72_120Device, /*currentConfigId=*/
                                                  HWC_CONFIG_ID_60);
@@ -1205,7 +1109,7 @@
         lr.name = ss.str();
 
         const auto& refreshRate =
-                refreshRateConfigs->getBestRefreshRate(layers, false, /*idle*/ false, &ignored);
+                refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false});
         EXPECT_FLOAT_EQ(refreshRate.getFps(), test.second)
                 << "Expecting " << test.first << "fps => " << test.second << "Hz";
     }
@@ -1224,22 +1128,22 @@
     auto layers = std::vector<LayerRequirement>{LayerRequirement{.weight = 1.0f}};
     auto& lr = layers[0];
 
-    bool touchConsidered = false;
+    RefreshRateConfigs::GlobalSignals consideredSignals;
     lr.vote = LayerVoteType::ExplicitExactOrMultiple;
     lr.desiredRefreshRate = 60.0f;
     lr.name = "60Hz ExplicitExactOrMultiple";
     EXPECT_EQ(mExpected60Config,
-              refreshRateConfigs->getBestRefreshRate(layers, /*touchActive*/ true, /*idle*/ false,
-                                                     &touchConsidered));
-    EXPECT_EQ(false, touchConsidered);
+              refreshRateConfigs->getBestRefreshRate(layers, {.touch = true, .idle = true},
+                                                     &consideredSignals));
+    EXPECT_EQ(false, consideredSignals.touch);
 
     lr.vote = LayerVoteType::ExplicitDefault;
     lr.desiredRefreshRate = 60.0f;
     lr.name = "60Hz ExplicitDefault";
     EXPECT_EQ(mExpected60Config,
-              refreshRateConfigs->getBestRefreshRate(layers, /*touchActive*/ true, /*idle*/ false,
-                                                     &touchConsidered));
-    EXPECT_EQ(false, touchConsidered);
+              refreshRateConfigs->getBestRefreshRate(layers, {.touch = true, .idle = true},
+                                                     &consideredSignals));
+    EXPECT_EQ(false, consideredSignals.touch);
 }
 
 TEST_F(RefreshRateConfigsTest,
@@ -1255,20 +1159,17 @@
     auto layers = std::vector<LayerRequirement>{LayerRequirement{.weight = 1.0f}};
     auto& lr = layers[0];
 
-    bool touchConsidered = false;
     lr.vote = LayerVoteType::ExplicitExactOrMultiple;
     lr.desiredRefreshRate = 90.0f;
     lr.name = "90Hz ExplicitExactOrMultiple";
     EXPECT_EQ(mExpected90Config,
-              refreshRateConfigs->getBestRefreshRate(layers, /*touchActive*/ false, /*idle*/ true,
-                                                     &touchConsidered));
+              refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = true}));
 
     lr.vote = LayerVoteType::ExplicitDefault;
     lr.desiredRefreshRate = 90.0f;
     lr.name = "90Hz ExplicitDefault";
     EXPECT_EQ(mExpected90Config,
-              refreshRateConfigs->getBestRefreshRate(layers, /*touchActive*/ false, /*idle*/ true,
-                                                     &touchConsidered));
+              refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = true}));
 }
 
 TEST_F(RefreshRateConfigsTest,
@@ -1281,11 +1182,11 @@
                       {HWC_CONFIG_ID_90, {90.f, 90.f}, {60.f, 90.f}}),
               0);
 
-    bool touchConsidered = false;
+    RefreshRateConfigs::GlobalSignals consideredSignals;
     EXPECT_EQ(mExpected90Config,
-              refreshRateConfigs->getBestRefreshRate({}, /*touchActive*/ false, /*idle*/ false,
-                                                     &touchConsidered));
-    EXPECT_EQ(false, touchConsidered);
+              refreshRateConfigs->getBestRefreshRate({}, {.touch = false, .idle = false},
+                                                     &consideredSignals));
+    EXPECT_EQ(false, consideredSignals.touch);
 
     auto layers = std::vector<LayerRequirement>{LayerRequirement{.weight = 1.0f}};
     auto& lr = layers[0];
@@ -1294,36 +1195,31 @@
     lr.desiredRefreshRate = 60.0f;
     lr.name = "60Hz ExplicitExactOrMultiple";
     EXPECT_EQ(mExpected60Config,
-              refreshRateConfigs->getBestRefreshRate(layers, /*touchActive*/ false, /*idle*/ false,
-                                                     &touchConsidered));
+              refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
 
     lr.vote = LayerVoteType::ExplicitDefault;
     lr.desiredRefreshRate = 60.0f;
     lr.name = "60Hz ExplicitDefault";
     EXPECT_EQ(mExpected60Config,
-              refreshRateConfigs->getBestRefreshRate(layers, /*touchActive*/ false, /*idle*/ false,
-                                                     &touchConsidered));
+              refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
 
     lr.vote = LayerVoteType::Heuristic;
     lr.desiredRefreshRate = 60.0f;
     lr.name = "60Hz Heuristic";
     EXPECT_EQ(mExpected90Config,
-              refreshRateConfigs->getBestRefreshRate(layers, /*touchActive*/ false, /*idle*/ false,
-                                                     &touchConsidered));
+              refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
 
     lr.vote = LayerVoteType::Max;
     lr.desiredRefreshRate = 60.0f;
     lr.name = "60Hz Max";
     EXPECT_EQ(mExpected90Config,
-              refreshRateConfigs->getBestRefreshRate(layers, /*touchActive*/ false, /*idle*/ false,
-                                                     &touchConsidered));
+              refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
 
     lr.vote = LayerVoteType::Min;
     lr.desiredRefreshRate = 60.0f;
     lr.name = "60Hz Min";
     EXPECT_EQ(mExpected90Config,
-              refreshRateConfigs->getBestRefreshRate(layers, /*touchActive*/ false, /*idle*/ false,
-                                                     &touchConsidered));
+              refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
 }
 
 TEST_F(RefreshRateConfigsTest, groupSwitching) {
@@ -1337,10 +1233,8 @@
     layer.desiredRefreshRate = 90.0f;
     layer.name = "90Hz ExplicitDefault";
 
-    bool touchConsidered;
     ASSERT_EQ(HWC_CONFIG_ID_60,
-              refreshRateConfigs
-                      ->getBestRefreshRate(layers, false, /*idle*/ false, &touchConsidered)
+              refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})
                       .getConfigId());
 
     RefreshRateConfigs::Policy policy;
@@ -1348,8 +1242,7 @@
     policy.allowGroupSwitching = true;
     ASSERT_GE(refreshRateConfigs->setDisplayManagerPolicy(policy), 0);
     ASSERT_EQ(HWC_CONFIG_ID_90,
-              refreshRateConfigs
-                      ->getBestRefreshRate(layers, false, /*idle*/ false, &touchConsidered)
+              refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false})
                       .getConfigId());
 }
 
@@ -1367,20 +1260,15 @@
                             bool touchActive = false) -> HwcConfigIndexType {
         layers[0].vote = voteType;
         layers[0].desiredRefreshRate = fps;
-        bool touchConsidered;
-        return refreshRateConfigs
-                ->getBestRefreshRate(layers, touchActive, /*idle*/ false, &touchConsidered)
+        return refreshRateConfigs->getBestRefreshRate(layers, {.touch = touchActive, .idle = false})
                 .getConfigId();
     };
 
     ASSERT_GE(refreshRateConfigs->setDisplayManagerPolicy(
                       {HWC_CONFIG_ID_60, {30.f, 60.f}, {30.f, 90.f}}),
               0);
-    bool touchConsidered;
     EXPECT_EQ(HWC_CONFIG_ID_60,
-              refreshRateConfigs
-                      ->getBestRefreshRate({}, /*touchActive=*/false, /*idle*/ false,
-                                           &touchConsidered)
+              refreshRateConfigs->getBestRefreshRate({}, {.touch = false, .idle = false})
                       .getConfigId());
     EXPECT_EQ(HWC_CONFIG_ID_60, getFrameRate(LayerVoteType::NoVote, 90.f));
     EXPECT_EQ(HWC_CONFIG_ID_30, getFrameRate(LayerVoteType::Min, 90.f));
@@ -1416,13 +1304,19 @@
     auto layers = std::vector<LayerRequirement>{LayerRequirement{.weight = 1.0f}};
     layers[0].name = "Test layer";
 
-    auto getIdleFrameRate = [&](LayerVoteType voteType, bool touchActive) -> HwcConfigIndexType {
+    const auto getIdleFrameRate = [&](LayerVoteType voteType,
+                                      bool touchActive) -> HwcConfigIndexType {
         layers[0].vote = voteType;
         layers[0].desiredRefreshRate = 90.f;
-        bool touchConsidered;
-        return refreshRateConfigs
-                ->getBestRefreshRate(layers, touchActive, /*idle=*/true, &touchConsidered)
-                .getConfigId();
+        RefreshRateConfigs::GlobalSignals consideredSignals;
+        const auto configId =
+                refreshRateConfigs
+                        ->getBestRefreshRate(layers, {.touch = touchActive, .idle = true},
+                                             &consideredSignals)
+                        .getConfigId();
+        // Refresh rate will be chosen by either touch state or idle state
+        EXPECT_EQ(!touchActive, consideredSignals.idle);
+        return configId;
     };
 
     ASSERT_GE(refreshRateConfigs->setDisplayManagerPolicy(
@@ -1430,35 +1324,34 @@
               0);
 
     // Idle should be lower priority than touch boost.
-    EXPECT_EQ(HWC_CONFIG_ID_90, getIdleFrameRate(LayerVoteType::NoVote, true));
-    EXPECT_EQ(HWC_CONFIG_ID_90, getIdleFrameRate(LayerVoteType::Min, true));
-    EXPECT_EQ(HWC_CONFIG_ID_90, getIdleFrameRate(LayerVoteType::Max, true));
-    EXPECT_EQ(HWC_CONFIG_ID_90, getIdleFrameRate(LayerVoteType::Heuristic, true));
-    EXPECT_EQ(HWC_CONFIG_ID_90, getIdleFrameRate(LayerVoteType::ExplicitDefault, true));
-    EXPECT_EQ(HWC_CONFIG_ID_90, getIdleFrameRate(LayerVoteType::ExplicitExactOrMultiple, true));
+    EXPECT_EQ(HWC_CONFIG_ID_90, getIdleFrameRate(LayerVoteType::NoVote, /*touchActive=*/true));
+    EXPECT_EQ(HWC_CONFIG_ID_90, getIdleFrameRate(LayerVoteType::Min, /*touchActive=*/true));
+    EXPECT_EQ(HWC_CONFIG_ID_90, getIdleFrameRate(LayerVoteType::Max, /*touchActive=*/true));
+    EXPECT_EQ(HWC_CONFIG_ID_90, getIdleFrameRate(LayerVoteType::Heuristic, /*touchActive=*/true));
+    EXPECT_EQ(HWC_CONFIG_ID_90,
+              getIdleFrameRate(LayerVoteType::ExplicitDefault, /*touchActive=*/true));
+    EXPECT_EQ(HWC_CONFIG_ID_90,
+              getIdleFrameRate(LayerVoteType::ExplicitExactOrMultiple, /*touchActive=*/true));
 
     // With no layers, idle should still be lower priority than touch boost.
-    bool touchConsidered;
     EXPECT_EQ(HWC_CONFIG_ID_90,
-              refreshRateConfigs
-                      ->getBestRefreshRate({}, /*touchActive=*/true, /*idle=*/true,
-                                           &touchConsidered)
+              refreshRateConfigs->getBestRefreshRate({}, {.touch = true, .idle = true})
                       .getConfigId());
 
     // Idle should be higher precedence than other layer frame rate considerations.
     refreshRateConfigs->setCurrentConfigId(HWC_CONFIG_ID_90);
-    EXPECT_EQ(HWC_CONFIG_ID_60, getIdleFrameRate(LayerVoteType::NoVote, false));
-    EXPECT_EQ(HWC_CONFIG_ID_60, getIdleFrameRate(LayerVoteType::Min, false));
-    EXPECT_EQ(HWC_CONFIG_ID_60, getIdleFrameRate(LayerVoteType::Max, false));
-    EXPECT_EQ(HWC_CONFIG_ID_60, getIdleFrameRate(LayerVoteType::Heuristic, false));
-    EXPECT_EQ(HWC_CONFIG_ID_60, getIdleFrameRate(LayerVoteType::ExplicitDefault, false));
-    EXPECT_EQ(HWC_CONFIG_ID_60, getIdleFrameRate(LayerVoteType::ExplicitExactOrMultiple, false));
+    EXPECT_EQ(HWC_CONFIG_ID_60, getIdleFrameRate(LayerVoteType::NoVote, /*touchActive=*/false));
+    EXPECT_EQ(HWC_CONFIG_ID_60, getIdleFrameRate(LayerVoteType::Min, /*touchActive=*/false));
+    EXPECT_EQ(HWC_CONFIG_ID_60, getIdleFrameRate(LayerVoteType::Max, /*touchActive=*/false));
+    EXPECT_EQ(HWC_CONFIG_ID_60, getIdleFrameRate(LayerVoteType::Heuristic, /*touchActive=*/false));
+    EXPECT_EQ(HWC_CONFIG_ID_60,
+              getIdleFrameRate(LayerVoteType::ExplicitDefault, /*touchActive=*/false));
+    EXPECT_EQ(HWC_CONFIG_ID_60,
+              getIdleFrameRate(LayerVoteType::ExplicitExactOrMultiple, /*touchActive=*/false));
 
     // Idle should be applied rather than the current config when there are no layers.
     EXPECT_EQ(HWC_CONFIG_ID_60,
-              refreshRateConfigs
-                      ->getBestRefreshRate({}, /*touchActive=*/false, /*idle=*/true,
-                                           &touchConsidered)
+              refreshRateConfigs->getBestRefreshRate({}, {.touch = false, .idle = true})
                       .getConfigId());
 }
 
@@ -1489,7 +1382,6 @@
 }
 
 TEST_F(RefreshRateConfigsTest, getBestRefreshRate_KnownFrameRate) {
-    bool ignored;
     auto refreshRateConfigs =
             std::make_unique<RefreshRateConfigs>(m60_90Device,
                                                  /*currentConfigId=*/HWC_CONFIG_ID_60);
@@ -1522,9 +1414,8 @@
     layer.vote = LayerVoteType::Heuristic;
     for (const auto& expectedRate : knownFrameRatesExpectations) {
         layer.desiredRefreshRate = expectedRate.rate;
-        const auto& refreshRate = refreshRateConfigs->getBestRefreshRate(layers,
-                                                                         /*touchActive*/ false,
-                                                                         /*idle*/ false, &ignored);
+        const auto& refreshRate =
+                refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false});
         EXPECT_EQ(expectedRate.expected, refreshRate);
     }
 }