SurfaceFlinger: handle high refresh rate deny list

Add visibility to SurfaceFlinger into the high refresh rate deny list
and let SurfaceFlinger handle it. Previously WM was setting the
preferredDisplayModeId on the denied app's window. The old way prevented
SurfaceFlinger to use the frame rate override feature as it didn't
know that a specific app is causing the refresh rate spec to be limited.

With this change, SurfaceFlinger will limit the display refresh rate based
on the high refresh rate deny list, and if possible, will use the frame
rate override feature to change the display rate to a multiple, allowing
other animations to be smooth while the denied app remains in the low
refresh rate.

Bug: 170502573
Test: SF unit tests
Change-Id: Idc8a5fe6bc12dbd949ad5e09ff50e339ffaeac36
Merged-In: Idc8a5fe6bc12dbd949ad5e09ff50e339ffaeac36
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 24d1b52..66ce3f1 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -1441,11 +1441,14 @@
                 layer->mCurrentState.frameRate.type == FrameRateCompatibility::Default;
         const auto layerVotedWithNoVote =
                 layer->mCurrentState.frameRate.type == FrameRateCompatibility::NoVote;
+        const auto layerVotedWithExactCompatibility =
+                layer->mCurrentState.frameRate.type == FrameRateCompatibility::Exact;
 
         // We do not count layers that are ExactOrMultiple for the same reason
         // we are allowing touch boost for those layers. See
         // RefreshRateConfigs::getBestRefreshRate for more details.
-        if (layerVotedWithDefaultCompatibility || layerVotedWithNoVote) {
+        if (layerVotedWithDefaultCompatibility || layerVotedWithNoVote ||
+            layerVotedWithExactCompatibility) {
             layersWithVote++;
         }
 
@@ -1662,6 +1665,8 @@
             return "ExactOrMultiple";
         case FrameRateCompatibility::NoVote:
             return "NoVote";
+        case FrameRateCompatibility::Exact:
+            return "Exact";
     }
 }
 
@@ -2763,6 +2768,8 @@
             return FrameRateCompatibility::Default;
         case ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_FIXED_SOURCE:
             return FrameRateCompatibility::ExactOrMultiple;
+        case ANATIVEWINDOW_FRAME_RATE_EXACT:
+            return FrameRateCompatibility::Exact;
         default:
             LOG_ALWAYS_FATAL("Invalid frame rate compatibility value %d", compatibility);
             return FrameRateCompatibility::Default;
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index f78b5f3..359340e 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -145,6 +145,8 @@
     enum class FrameRateCompatibility {
         Default, // Layer didn't specify any specific handling strategy
 
+        Exact, // Layer needs the exact frame rate.
+
         ExactOrMultiple, // Layer needs the exact frame rate (or a multiple of it) to present the
                          // content properly. Any other value will result in a pull down.
 
diff --git a/services/surfaceflinger/Scheduler/LayerHistory.cpp b/services/surfaceflinger/Scheduler/LayerHistory.cpp
index 170933d..7ef531d 100644
--- a/services/surfaceflinger/Scheduler/LayerHistory.cpp
+++ b/services/surfaceflinger/Scheduler/LayerHistory.cpp
@@ -71,6 +71,7 @@
     traceType(LayerHistory::LayerVoteType::Heuristic, fps);
     traceType(LayerHistory::LayerVoteType::ExplicitDefault, fps);
     traceType(LayerHistory::LayerVoteType::ExplicitExactOrMultiple, fps);
+    traceType(LayerHistory::LayerVoteType::ExplicitExact, fps);
     traceType(LayerHistory::LayerVoteType::Min, 1);
     traceType(LayerHistory::LayerVoteType::Max, 1);
 
@@ -172,6 +173,8 @@
                         return LayerVoteType::ExplicitExactOrMultiple;
                     case Layer::FrameRateCompatibility::NoVote:
                         return LayerVoteType::NoVote;
+                    case Layer::FrameRateCompatibility::Exact:
+                        return LayerVoteType::ExplicitExact;
                 }
             }();
 
diff --git a/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp b/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp
index 0f1e267..81ffe0f 100644
--- a/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp
+++ b/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp
@@ -83,6 +83,8 @@
             return "ExplicitDefault";
         case LayerVoteType::ExplicitExactOrMultiple:
             return "ExplicitExactOrMultiple";
+        case LayerVoteType::ExplicitExact:
+            return "ExplicitExact";
     }
 }
 
@@ -165,6 +167,18 @@
         return (1.0f / iter) * seamlessness;
     }
 
+    if (layer.vote == LayerVoteType::ExplicitExact) {
+        const int divider = getFrameRateDivider(refreshRate.getFps(), layer.desiredRefreshRate);
+        if (mSupportsFrameRateOverride) {
+            // Since we support frame rate override, allow refresh rates which are
+            // multiples of the layer's request, as those apps would be throttled
+            // down to run at the desired refresh rate.
+            return divider > 0;
+        }
+
+        return divider == 1;
+    }
+
     return 0;
 }
 
@@ -199,21 +213,34 @@
     int maxVoteLayers = 0;
     int explicitDefaultVoteLayers = 0;
     int explicitExactOrMultipleVoteLayers = 0;
+    int explicitExact = 0;
     float maxExplicitWeight = 0;
     int seamedLayers = 0;
     for (const auto& layer : layers) {
-        if (layer.vote == LayerVoteType::NoVote) {
-            noVoteLayers++;
-        } else if (layer.vote == LayerVoteType::Min) {
-            minVoteLayers++;
-        } else if (layer.vote == LayerVoteType::Max) {
-            maxVoteLayers++;
-        } else if (layer.vote == LayerVoteType::ExplicitDefault) {
-            explicitDefaultVoteLayers++;
-            maxExplicitWeight = std::max(maxExplicitWeight, layer.weight);
-        } else if (layer.vote == LayerVoteType::ExplicitExactOrMultiple) {
-            explicitExactOrMultipleVoteLayers++;
-            maxExplicitWeight = std::max(maxExplicitWeight, layer.weight);
+        switch (layer.vote) {
+            case LayerVoteType::NoVote:
+                noVoteLayers++;
+                break;
+            case LayerVoteType::Min:
+                minVoteLayers++;
+                break;
+            case LayerVoteType::Max:
+                maxVoteLayers++;
+                break;
+            case LayerVoteType::ExplicitDefault:
+                explicitDefaultVoteLayers++;
+                maxExplicitWeight = std::max(maxExplicitWeight, layer.weight);
+                break;
+            case LayerVoteType::ExplicitExactOrMultiple:
+                explicitExactOrMultipleVoteLayers++;
+                maxExplicitWeight = std::max(maxExplicitWeight, layer.weight);
+                break;
+            case LayerVoteType::ExplicitExact:
+                explicitExact++;
+                maxExplicitWeight = std::max(maxExplicitWeight, layer.weight);
+                break;
+            case LayerVoteType::Heuristic:
+                break;
         }
 
         if (layer.seamlessness == Seamlessness::SeamedAndSeamless) {
@@ -221,8 +248,8 @@
         }
     }
 
-    const bool hasExplicitVoteLayers =
-            explicitDefaultVoteLayers > 0 || explicitExactOrMultipleVoteLayers > 0;
+    const bool hasExplicitVoteLayers = explicitDefaultVoteLayers > 0 ||
+            explicitExactOrMultipleVoteLayers > 0 || explicitExact > 0;
 
     // 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.
@@ -318,7 +345,9 @@
             bool inPrimaryRange = scores[i].refreshRate->inPolicy(policy->primaryRange.min,
                                                                   policy->primaryRange.max);
             if ((primaryRangeIsSingleRate || !inPrimaryRange) &&
-                !(layer.focused && layer.vote == LayerVoteType::ExplicitDefault)) {
+                !(layer.focused &&
+                  (layer.vote == LayerVoteType::ExplicitDefault ||
+                   layer.vote == LayerVoteType::ExplicitExact))) {
                 // Only focused layers with ExplicitDefault frame rate settings are allowed to score
                 // refresh rates outside the primary range.
                 continue;
@@ -358,7 +387,8 @@
     // actually increase the refresh rate over the normal selection.
     const RefreshRate& touchRefreshRate = getMaxRefreshRateByPolicyLocked();
 
-    if (globalSignals.touch && explicitDefaultVoteLayers == 0 &&
+    bool touchBoostForExplicitExact = explicitExact == 0 || mSupportsFrameRateOverride;
+    if (globalSignals.touch && explicitDefaultVoteLayers == 0 && touchBoostForExplicitExact &&
         bestRefreshRate->fps.lessThanWithMargin(touchRefreshRate.fps)) {
         setTouchConsidered();
         ALOGV("TouchBoost - choose %s", touchRefreshRate.getName().c_str());
@@ -412,7 +442,7 @@
 }
 
 RefreshRateConfigs::UidToFrameRateOverride RefreshRateConfigs::getFrameRateOverrides(
-        const std::vector<LayerRequirement>& layers, Fps displayFrameRate) const {
+        const std::vector<LayerRequirement>& layers, Fps displayFrameRate, bool touch) const {
     ATRACE_CALL();
     if (!mSupportsFrameRateOverride) return {};
 
@@ -423,6 +453,17 @@
             groupLayersByUid(layers);
     UidToFrameRateOverride frameRateOverrides;
     for (const auto& [uid, layersWithSameUid] : layersByUid) {
+        // Layers with ExplicitExactOrMultiple expect touch boost
+        const bool hasExplicitExactOrMultiple =
+                std::any_of(layersWithSameUid.cbegin(), layersWithSameUid.cend(),
+                            [](const auto& layer) {
+                                return layer->vote == LayerVoteType::ExplicitExactOrMultiple;
+                            });
+
+        if (touch && hasExplicitExactOrMultiple) {
+            continue;
+        }
+
         for (auto& score : scores) {
             score.score = 0;
         }
@@ -433,7 +474,8 @@
             }
 
             LOG_ALWAYS_FATAL_IF(layer->vote != LayerVoteType::ExplicitDefault &&
-                                layer->vote != LayerVoteType::ExplicitExactOrMultiple);
+                                layer->vote != LayerVoteType::ExplicitExactOrMultiple &&
+                                layer->vote != LayerVoteType::ExplicitExact);
             for (RefreshRateScore& score : scores) {
                 const auto layerScore = calculateLayerScoreLocked(*layer, *score.refreshRate,
                                                                   /*isSeamlessSwitch*/ true);
@@ -559,8 +601,10 @@
     mCurrentRefreshRate = mRefreshRates.at(configId).get();
 }
 
-RefreshRateConfigs::RefreshRateConfigs(const DisplayModes& configs, DisplayModeId currentConfigId)
-      : mKnownFrameRates(constructKnownFrameRates(configs)) {
+RefreshRateConfigs::RefreshRateConfigs(const DisplayModes& configs, DisplayModeId currentConfigId,
+                                       bool enableFrameRateOverride)
+      : mKnownFrameRates(constructKnownFrameRates(configs)),
+        mEnableFrameRateOverride(enableFrameRateOverride) {
     updateDisplayConfigs(configs, currentConfigId);
 }
 
@@ -589,7 +633,7 @@
     mMaxSupportedRefreshRate = sortedConfigs.back();
 
     mSupportsFrameRateOverride = false;
-    if (android::sysprop::enable_frame_rate_override(true)) {
+    if (mEnableFrameRateOverride) {
         for (const auto& config1 : sortedConfigs) {
             for (const auto& config2 : sortedConfigs) {
                 if (getFrameRateDivider(config1->getFps(), config2->getFps()) >= 2) {
@@ -826,4 +870,4 @@
 } // namespace android::scheduler
 
 // TODO(b/129481165): remove the #pragma below and fix conversion issues
-#pragma clang diagnostic pop // ignored "-Wextra"
\ No newline at end of file
+#pragma clang diagnostic pop // ignored "-Wextra"
diff --git a/services/surfaceflinger/Scheduler/RefreshRateConfigs.h b/services/surfaceflinger/Scheduler/RefreshRateConfigs.h
index 29402f5..0c7dc05 100644
--- a/services/surfaceflinger/Scheduler/RefreshRateConfigs.h
+++ b/services/surfaceflinger/Scheduler/RefreshRateConfigs.h
@@ -211,8 +211,11 @@
         Heuristic,       // Specific refresh rate that was calculated by platform using a heuristic
         ExplicitDefault, // Specific refresh rate that was provided by the app with Default
                          // compatibility
-        ExplicitExactOrMultiple // Specific refresh rate that was provided by the app with
-                                // ExactOrMultiple compatibility
+        ExplicitExactOrMultiple, // Specific refresh rate that was provided by the app with
+                                 // ExactOrMultiple compatibility
+        ExplicitExact,           // Specific refresh rate that was provided by the app with
+                                 // Exact compatibility
+
     };
 
     // Captures the layer requirements for a refresh rate. This will be used to determine the
@@ -298,7 +301,8 @@
     // Returns a known frame rate that is the closest to frameRate
     Fps findClosestKnownFrameRate(Fps frameRate) const;
 
-    RefreshRateConfigs(const DisplayModes& configs, DisplayModeId currentConfigId);
+    RefreshRateConfigs(const DisplayModes& configs, DisplayModeId currentConfigId,
+                       bool enableFrameRateOverride = false);
 
     void updateDisplayConfigs(const DisplayModes& configs, DisplayModeId currentConfig)
             EXCLUDES(mLock);
@@ -327,10 +331,15 @@
     // Returns a divider for the current refresh rate
     int getRefreshRateDivider(Fps frameRate) const EXCLUDES(mLock);
 
-    // Returns the frame rate override for each uid
     using UidToFrameRateOverride = std::map<uid_t, Fps>;
+    // Returns the frame rate override for each uid.
+    //
+    // @param layers list of visible layers
+    // @param displayFrameRate the display frame rate
+    // @param touch whether touch timer is active (i.e. user touched the screen recently)
     UidToFrameRateOverride getFrameRateOverrides(const std::vector<LayerRequirement>& layers,
-                                                 Fps displayFrameRate) const EXCLUDES(mLock);
+                                                 Fps displayFrameRate, bool touch) const
+            EXCLUDES(mLock);
 
     void dump(std::string& result) const EXCLUDES(mLock);
 
@@ -410,6 +419,7 @@
     // from based on the closest value.
     const std::vector<Fps> mKnownFrameRates;
 
+    const bool mEnableFrameRateOverride;
     bool mSupportsFrameRateOverride;
 };
 
diff --git a/services/surfaceflinger/Scheduler/Scheduler.cpp b/services/surfaceflinger/Scheduler/Scheduler.cpp
index 588b83d..d861209 100644
--- a/services/surfaceflinger/Scheduler/Scheduler.cpp
+++ b/services/surfaceflinger/Scheduler/Scheduler.cpp
@@ -763,17 +763,11 @@
         return false;
     }
 
-    if (consideredSignals.touch) {
-        std::lock_guard lock(mFrameRateOverridesMutex);
-        const bool changed = !mFrameRateOverridesByContent.empty();
-        mFrameRateOverridesByContent.clear();
-        return changed;
-    }
-
     if (!consideredSignals.idle) {
         const auto frameRateOverrides =
                 mRefreshRateConfigs.getFrameRateOverrides(mFeatures.contentRequirements,
-                                                          displayRefreshRate);
+                                                          displayRefreshRate,
+                                                          consideredSignals.touch);
         std::lock_guard lock(mFrameRateOverridesMutex);
         if (!std::equal(mFrameRateOverridesByContent.begin(), mFrameRateOverridesByContent.end(),
                         frameRateOverrides.begin(), frameRateOverrides.end(),
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 0a51659..c1fabf8 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -2920,7 +2920,9 @@
 
     auto currentConfig = getHwComposer().getActiveMode(primaryDisplayId)->getId();
     const auto modes = getHwComposer().getModes(primaryDisplayId);
-    mRefreshRateConfigs = std::make_unique<scheduler::RefreshRateConfigs>(modes, currentConfig);
+    mRefreshRateConfigs = std::make_unique<
+            scheduler::RefreshRateConfigs>(modes, currentConfig,
+                                           android::sysprop::enable_frame_rate_override(true));
     const auto& currRefreshRate = mRefreshRateConfigs->getRefreshRateFromConfigId(currentConfig);
     mRefreshRateStats =
             std::make_unique<scheduler::RefreshRateStats>(*mTimeStats, currRefreshRate.getFps(),
@@ -3873,7 +3875,7 @@
     }
     if (what & layer_state_t::eFrameRateChanged) {
         if (ValidateFrameRate(s.frameRate, s.frameRateCompatibility,
-                              "SurfaceFlinger::setClientStateLocked") &&
+                              "SurfaceFlinger::setClientStateLocked", privileged) &&
             layer->setFrameRate(Layer::FrameRate(Fps(s.frameRate),
                                                  Layer::FrameRate::convertCompatibility(
                                                          s.frameRateCompatibility),
diff --git a/services/surfaceflinger/tests/unittests/RefreshRateConfigsTest.cpp b/services/surfaceflinger/tests/unittests/RefreshRateConfigsTest.cpp
index 0a747ab..738ded1 100644
--- a/services/surfaceflinger/tests/unittests/RefreshRateConfigsTest.cpp
+++ b/services/surfaceflinger/tests/unittests/RefreshRateConfigsTest.cpp
@@ -1506,6 +1506,89 @@
     }
 }
 
+TEST_F(RefreshRateConfigsTest, getBestRefreshRate_ExplicitExact) {
+    auto refreshRateConfigs =
+            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 = 0.5f}};
+    auto& explicitExactLayer = layers[0];
+    auto& explicitExactOrMultipleLayer = layers[1];
+
+    explicitExactOrMultipleLayer.vote = LayerVoteType::ExplicitExactOrMultiple;
+    explicitExactOrMultipleLayer.name = "ExplicitExactOrMultiple";
+    explicitExactOrMultipleLayer.desiredRefreshRate = Fps(60);
+
+    explicitExactLayer.vote = LayerVoteType::ExplicitExact;
+    explicitExactLayer.name = "ExplicitExact";
+    explicitExactLayer.desiredRefreshRate = Fps(30);
+
+    EXPECT_EQ(mExpected30Config,
+              refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
+    EXPECT_EQ(mExpected30Config,
+              refreshRateConfigs->getBestRefreshRate(layers, {.touch = true, .idle = false}));
+
+    explicitExactOrMultipleLayer.desiredRefreshRate = Fps(120);
+    explicitExactLayer.desiredRefreshRate = Fps(60);
+    EXPECT_EQ(mExpected60Config,
+              refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
+
+    explicitExactLayer.desiredRefreshRate = Fps(72);
+    EXPECT_EQ(mExpected72Config,
+              refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
+
+    explicitExactLayer.desiredRefreshRate = Fps(90);
+    EXPECT_EQ(mExpected90Config,
+              refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
+
+    explicitExactLayer.desiredRefreshRate = Fps(120);
+    EXPECT_EQ(mExpected120Config,
+              refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
+}
+
+TEST_F(RefreshRateConfigsTest, getBestRefreshRate_ExplicitExactEnableFrameRateOverride) {
+    auto refreshRateConfigs =
+            std::make_unique<RefreshRateConfigs>(m30_60_72_90_120Device,
+                                                 /*currentConfigId=*/HWC_CONFIG_ID_60,
+                                                 /*enableFrameRateOverride=*/true);
+
+    auto layers = std::vector<LayerRequirement>{LayerRequirement{.weight = 1.0f},
+                                                LayerRequirement{.weight = 0.5f}};
+    auto& explicitExactLayer = layers[0];
+    auto& explicitExactOrMultipleLayer = layers[1];
+
+    explicitExactOrMultipleLayer.vote = LayerVoteType::ExplicitExactOrMultiple;
+    explicitExactOrMultipleLayer.name = "ExplicitExactOrMultiple";
+    explicitExactOrMultipleLayer.desiredRefreshRate = Fps(60);
+
+    explicitExactLayer.vote = LayerVoteType::ExplicitExact;
+    explicitExactLayer.name = "ExplicitExact";
+    explicitExactLayer.desiredRefreshRate = Fps(30);
+
+    EXPECT_EQ(mExpected60Config,
+              refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
+    EXPECT_EQ(mExpected120Config,
+              refreshRateConfigs->getBestRefreshRate(layers, {.touch = true, .idle = false}));
+
+    explicitExactOrMultipleLayer.desiredRefreshRate = Fps(120);
+    explicitExactLayer.desiredRefreshRate = Fps(60);
+    EXPECT_EQ(mExpected120Config,
+              refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
+
+    explicitExactLayer.desiredRefreshRate = Fps(72);
+    EXPECT_EQ(mExpected72Config,
+              refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
+
+    explicitExactLayer.desiredRefreshRate = Fps(90);
+    EXPECT_EQ(mExpected90Config,
+              refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
+
+    explicitExactLayer.desiredRefreshRate = Fps(120);
+    EXPECT_EQ(mExpected120Config,
+              refreshRateConfigs->getBestRefreshRate(layers, {.touch = false, .idle = false}));
+}
+
 TEST_F(RefreshRateConfigsTest, testComparisonOperator) {
     EXPECT_TRUE(mExpected60Config < mExpected90Config);
     EXPECT_FALSE(mExpected60Config < mExpected60Config);
@@ -1537,7 +1620,7 @@
     EXPECT_EQ(KernelIdleTimerAction::TurnOff, refreshRateConfigs->getIdleTimerAction());
 }
 
-TEST_F(RefreshRateConfigsTest, RefreshRateDividerForUid) {
+TEST_F(RefreshRateConfigsTest, getRefreshRateDivider) {
     auto refreshRateConfigs =
             std::make_unique<RefreshRateConfigs>(m30_60_72_90_120Device,
                                                  /*currentConfigId=*/HWC_CONFIG_ID_30);
@@ -1562,57 +1645,66 @@
     EXPECT_EQ(4, refreshRateConfigs->getRefreshRateDivider(Fps(22.6f)));
 }
 
-TEST_F(RefreshRateConfigsTest, populatePreferredFrameRate_noLayers) {
+TEST_F(RefreshRateConfigsTest, getFrameRateOverrides_noLayers) {
     auto refreshRateConfigs =
             std::make_unique<RefreshRateConfigs>(m30_60_72_90_120Device, /*currentConfigId=*/
                                                  HWC_CONFIG_ID_120);
 
     auto layers = std::vector<LayerRequirement>{};
-    ASSERT_TRUE(refreshRateConfigs->getFrameRateOverrides(layers, Fps(120.0f)).empty());
+    ASSERT_TRUE(refreshRateConfigs->getFrameRateOverrides(layers, Fps(120.0f), /*touch=*/false)
+                        .empty());
 }
 
 TEST_F(RefreshRateConfigsTest, getFrameRateOverrides_60on120) {
     auto refreshRateConfigs =
             std::make_unique<RefreshRateConfigs>(m30_60_72_90_120Device, /*currentConfigId=*/
-                                                 HWC_CONFIG_ID_120);
+                                                 HWC_CONFIG_ID_120,
+                                                 /*enableFrameRateOverride=*/true);
 
     auto layers = std::vector<LayerRequirement>{LayerRequirement{.weight = 1.0f}};
     layers[0].name = "Test layer";
     layers[0].ownerUid = 1234;
     layers[0].desiredRefreshRate = Fps(60.0f);
     layers[0].vote = LayerVoteType::ExplicitDefault;
-    auto frameRateOverrides = refreshRateConfigs->getFrameRateOverrides(layers, Fps(120.0f));
+    auto frameRateOverrides =
+            refreshRateConfigs->getFrameRateOverrides(layers, Fps(120.0f), /*touch=*/false);
     ASSERT_EQ(1, frameRateOverrides.size());
     ASSERT_EQ(1, frameRateOverrides.count(1234));
     ASSERT_EQ(60.0f, frameRateOverrides.at(1234).getValue());
 
     layers[0].vote = LayerVoteType::ExplicitExactOrMultiple;
-    frameRateOverrides = refreshRateConfigs->getFrameRateOverrides(layers, Fps(120.0f));
+    frameRateOverrides =
+            refreshRateConfigs->getFrameRateOverrides(layers, Fps(120.0f), /*touch=*/false);
     ASSERT_EQ(1, frameRateOverrides.size());
     ASSERT_EQ(1, frameRateOverrides.count(1234));
     ASSERT_EQ(60.0f, frameRateOverrides.at(1234).getValue());
 
     layers[0].vote = LayerVoteType::NoVote;
-    frameRateOverrides = refreshRateConfigs->getFrameRateOverrides(layers, Fps(120.0f));
+    frameRateOverrides =
+            refreshRateConfigs->getFrameRateOverrides(layers, Fps(120.0f), /*touch=*/false);
     ASSERT_TRUE(frameRateOverrides.empty());
 
     layers[0].vote = LayerVoteType::Min;
-    frameRateOverrides = refreshRateConfigs->getFrameRateOverrides(layers, Fps(120.0f));
+    frameRateOverrides =
+            refreshRateConfigs->getFrameRateOverrides(layers, Fps(120.0f), /*touch=*/false);
     ASSERT_TRUE(frameRateOverrides.empty());
 
     layers[0].vote = LayerVoteType::Max;
-    frameRateOverrides = refreshRateConfigs->getFrameRateOverrides(layers, Fps(120.0f));
+    frameRateOverrides =
+            refreshRateConfigs->getFrameRateOverrides(layers, Fps(120.0f), /*touch=*/false);
     ASSERT_TRUE(frameRateOverrides.empty());
 
     layers[0].vote = LayerVoteType::Heuristic;
-    frameRateOverrides = refreshRateConfigs->getFrameRateOverrides(layers, Fps(120.0f));
+    frameRateOverrides =
+            refreshRateConfigs->getFrameRateOverrides(layers, Fps(120.0f), /*touch=*/false);
     ASSERT_TRUE(frameRateOverrides.empty());
 }
 
-TEST_F(RefreshRateConfigsTest, populatePreferredFrameRate_twoUids) {
+TEST_F(RefreshRateConfigsTest, getFrameRateOverrides_twoUids) {
     auto refreshRateConfigs =
             std::make_unique<RefreshRateConfigs>(m30_60_72_90_120Device, /*currentConfigId=*/
-                                                 HWC_CONFIG_ID_120);
+                                                 HWC_CONFIG_ID_120,
+                                                 /*enableFrameRateOverride=*/true);
 
     auto layers = std::vector<LayerRequirement>{
             LayerRequirement{.ownerUid = 1234, .weight = 1.0f},
@@ -1626,7 +1718,8 @@
     layers[1].name = "Test layer 5678";
     layers[1].desiredRefreshRate = Fps(30.0f);
     layers[1].vote = LayerVoteType::ExplicitDefault;
-    auto frameRateOverrides = refreshRateConfigs->getFrameRateOverrides(layers, Fps(120.0f));
+    auto frameRateOverrides =
+            refreshRateConfigs->getFrameRateOverrides(layers, Fps(120.0f), /*touch=*/false);
 
     ASSERT_EQ(2, frameRateOverrides.size());
     ASSERT_EQ(1, frameRateOverrides.count(1234));
@@ -1635,13 +1728,66 @@
     ASSERT_EQ(30.0f, frameRateOverrides.at(5678).getValue());
 
     layers[1].vote = LayerVoteType::Heuristic;
-    frameRateOverrides = refreshRateConfigs->getFrameRateOverrides(layers, Fps(120.0f));
+    frameRateOverrides =
+            refreshRateConfigs->getFrameRateOverrides(layers, Fps(120.0f), /*touch=*/false);
     ASSERT_EQ(1, frameRateOverrides.size());
     ASSERT_EQ(1, frameRateOverrides.count(1234));
     ASSERT_EQ(60.0f, frameRateOverrides.at(1234).getValue());
 
     layers[1].ownerUid = 1234;
-    frameRateOverrides = refreshRateConfigs->getFrameRateOverrides(layers, Fps(120.0f));
+    frameRateOverrides =
+            refreshRateConfigs->getFrameRateOverrides(layers, Fps(120.0f), /*touch=*/false);
+    ASSERT_TRUE(frameRateOverrides.empty());
+}
+
+TEST_F(RefreshRateConfigsTest, getFrameRateOverrides_touch) {
+    auto refreshRateConfigs =
+            std::make_unique<RefreshRateConfigs>(m30_60_72_90_120Device, /*currentConfigId=*/
+                                                 HWC_CONFIG_ID_120,
+                                                 /*enableFrameRateOverride=*/true);
+
+    auto layers = std::vector<LayerRequirement>{
+            LayerRequirement{.ownerUid = 1234, .weight = 1.0f},
+    };
+
+    layers[0].name = "Test layer";
+    layers[0].desiredRefreshRate = Fps(60.0f);
+    layers[0].vote = LayerVoteType::ExplicitDefault;
+
+    auto frameRateOverrides =
+            refreshRateConfigs->getFrameRateOverrides(layers, Fps(120.0f), /*touch=*/false);
+    ASSERT_EQ(1, frameRateOverrides.size());
+    ASSERT_EQ(1, frameRateOverrides.count(1234));
+    ASSERT_EQ(60.0f, frameRateOverrides.at(1234).getValue());
+
+    frameRateOverrides =
+            refreshRateConfigs->getFrameRateOverrides(layers, Fps(120.0f), /*touch=*/true);
+    ASSERT_EQ(1, frameRateOverrides.size());
+    ASSERT_EQ(1, frameRateOverrides.count(1234));
+    ASSERT_EQ(60.0f, frameRateOverrides.at(1234).getValue());
+
+    layers[0].vote = LayerVoteType::ExplicitExact;
+    frameRateOverrides =
+            refreshRateConfigs->getFrameRateOverrides(layers, Fps(120.0f), /*touch=*/false);
+    ASSERT_EQ(1, frameRateOverrides.size());
+    ASSERT_EQ(1, frameRateOverrides.count(1234));
+    ASSERT_EQ(60.0f, frameRateOverrides.at(1234).getValue());
+
+    frameRateOverrides =
+            refreshRateConfigs->getFrameRateOverrides(layers, Fps(120.0f), /*touch=*/true);
+    ASSERT_EQ(1, frameRateOverrides.size());
+    ASSERT_EQ(1, frameRateOverrides.count(1234));
+    ASSERT_EQ(60.0f, frameRateOverrides.at(1234).getValue());
+
+    layers[0].vote = LayerVoteType::ExplicitExactOrMultiple;
+    frameRateOverrides =
+            refreshRateConfigs->getFrameRateOverrides(layers, Fps(120.0f), /*touch=*/false);
+    ASSERT_EQ(1, frameRateOverrides.size());
+    ASSERT_EQ(1, frameRateOverrides.count(1234));
+    ASSERT_EQ(60.0f, frameRateOverrides.at(1234).getValue());
+
+    frameRateOverrides =
+            refreshRateConfigs->getFrameRateOverrides(layers, Fps(120.0f), /*touch=*/true);
     ASSERT_TRUE(frameRateOverrides.empty());
 }
 
diff --git a/services/surfaceflinger/tests/unittests/SetFrameRateTest.cpp b/services/surfaceflinger/tests/unittests/SetFrameRateTest.cpp
index c8f4cb4..e060df2 100644
--- a/services/surfaceflinger/tests/unittests/SetFrameRateTest.cpp
+++ b/services/surfaceflinger/tests/unittests/SetFrameRateTest.cpp
@@ -473,5 +473,20 @@
                                          std::make_shared<EffectLayerFactory>()),
                          PrintToStringParamName);
 
+TEST_F(SetFrameRateTest, ValidateFrameRate) {
+    EXPECT_TRUE(ValidateFrameRate(60.0f, ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT, ""));
+    EXPECT_TRUE(ValidateFrameRate(60.0f, ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT, ""));
+    EXPECT_TRUE(ValidateFrameRate(60.0f, ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_FIXED_SOURCE, ""));
+    EXPECT_TRUE(ValidateFrameRate(60.0f, ANATIVEWINDOW_FRAME_RATE_EXACT, "", /*privileged=*/true));
+
+    EXPECT_FALSE(ValidateFrameRate(-1, ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT, ""));
+    EXPECT_FALSE(
+            ValidateFrameRate(1.0f / 0.0f, ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT, ""));
+    EXPECT_FALSE(
+            ValidateFrameRate(0.0f / 0.0f, ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT, ""));
+
+    EXPECT_FALSE(ValidateFrameRate(60.0f, ANATIVEWINDOW_FRAME_RATE_EXACT, ""));
+}
+
 } // namespace
 } // namespace android