SurfaceFlinger: more aggressive infrequent layer detection

Change the algorithm that chooses the refresh rate to treat layers as
infrequent unless proven otherwise. This change helps with multiple
switches during scenarios of blinking cursor where the detection of
infrequent layer is too long. The down side on this change is that
animations will be considered infrequent as well for the first few frames.
However the touch boost is a good mitigation of this.

Test: Typing in Messages and observe refresh rate
Test: Settings->About->up time and observe refresh rate
Bug: 155062712
Bug: 156654519
Change-Id: I317c69bd063df5d70f2d5705163cf61c1c9b1fff
diff --git a/services/surfaceflinger/Scheduler/Scheduler.cpp b/services/surfaceflinger/Scheduler/Scheduler.cpp
index f87c1f8..00f87bb 100644
--- a/services/surfaceflinger/Scheduler/Scheduler.cpp
+++ b/services/surfaceflinger/Scheduler/Scheduler.cpp
@@ -526,7 +526,9 @@
 
 void Scheduler::touchTimerCallback(TimerState state) {
     const TouchState touch = state == TimerState::Reset ? TouchState::Active : TouchState::Inactive;
-    handleTimerStateChanged(&mFeatures.touch, touch, true /* eventOnContentDetection */);
+    if (handleTimerStateChanged(&mFeatures.touch, touch, true /* eventOnContentDetection */)) {
+        mLayerHistory->clear();
+    }
     ATRACE_INT("TouchState", static_cast<int>(touch));
 }
 
@@ -549,18 +551,19 @@
 }
 
 template <class T>
-void Scheduler::handleTimerStateChanged(T* currentState, T newState, bool eventOnContentDetection) {
+bool Scheduler::handleTimerStateChanged(T* currentState, T newState, bool eventOnContentDetection) {
     ConfigEvent event = ConfigEvent::None;
     HwcConfigIndexType newConfigId;
+    bool touchConsidered = false;
     {
         std::lock_guard<std::mutex> lock(mFeatureStateLock);
         if (*currentState == newState) {
-            return;
+            return touchConsidered;
         }
         *currentState = newState;
-        newConfigId = calculateRefreshRateConfigIndexType();
+        newConfigId = calculateRefreshRateConfigIndexType(&touchConsidered);
         if (mFeatures.configId == newConfigId) {
-            return;
+            return touchConsidered;
         }
         mFeatures.configId = newConfigId;
         if (eventOnContentDetection && !mFeatures.contentRequirements.empty()) {
@@ -569,10 +572,12 @@
     }
     const RefreshRate& newRefreshRate = mRefreshRateConfigs.getRefreshRateFromConfigId(newConfigId);
     mSchedulerCallback.changeRefreshRate(newRefreshRate, event);
+    return touchConsidered;
 }
 
-HwcConfigIndexType Scheduler::calculateRefreshRateConfigIndexType() {
+HwcConfigIndexType Scheduler::calculateRefreshRateConfigIndexType(bool* touchConsidered) {
     ATRACE_CALL();
+    if (touchConsidered) *touchConsidered = false;
 
     // 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.
@@ -607,18 +612,9 @@
                 .getConfigId();
     }
 
-    bool touchConsidered;
-    const auto& ret = mRefreshRateConfigs
-                              .getBestRefreshRate(mFeatures.contentRequirements, touchActive, idle,
-                                                  &touchConsidered)
-                              .getConfigId();
-    if (touchConsidered) {
-        // Clear layer history if refresh rate was selected based on touch to allow
-        // the hueristic to pick up with the new rate.
-        mLayerHistory->clear();
-    }
-
-    return ret;
+    return mRefreshRateConfigs
+            .getBestRefreshRate(mFeatures.contentRequirements, touchActive, idle, touchConsidered)
+            .getConfigId();
 }
 
 std::optional<HwcConfigIndexType> Scheduler::getPreferredConfigId() {