SF: fix a bug when FpsRange is Infinity

Bug: 260874985
Test: adb shell /data/nativetest64/libsurfaceflinger_unittest/libsurfaceflinger_unittest
Change-Id: I2bd5eeb023cbabc55febaf1fd2ced3e7b8ec0bc5
diff --git a/services/surfaceflinger/Scheduler/RefreshRateSelector.cpp b/services/surfaceflinger/Scheduler/RefreshRateSelector.cpp
index 4be1ac7..c781a6d 100644
--- a/services/surfaceflinger/Scheduler/RefreshRateSelector.cpp
+++ b/services/surfaceflinger/Scheduler/RefreshRateSelector.cpp
@@ -107,7 +107,8 @@
     }
 
     using fps_approx_ops::operator/;
-    const auto start = std::max(1u, fps / range.max - 1);
+    // use signed type as `fps / range.max` might be 0
+    const auto start = std::max(1, static_cast<int>(fps / range.max) - 1);
     const auto end = fps /
             std::max(range.min, RefreshRateSelector::kMinSupportedFrameRate,
                      fps_approx_ops::operator<);
@@ -1053,8 +1054,12 @@
     const auto& primaryRanges = policy.primaryRanges;
     const auto& appRequestRanges = policy.appRequestRanges;
     ALOGE_IF(!appRequestRanges.physical.includes(primaryRanges.physical),
-             "Physical range is invalid");
-    ALOGE_IF(!appRequestRanges.render.includes(primaryRanges.render), "Render range is invalid");
+             "Physical range is invalid: primary: %s appRequest: %s",
+             to_string(primaryRanges.physical).c_str(),
+             to_string(appRequestRanges.physical).c_str());
+    ALOGE_IF(!appRequestRanges.render.includes(primaryRanges.render),
+             "Render range is invalid: primary: %s appRequest: %s",
+             to_string(primaryRanges.render).c_str(), to_string(appRequestRanges.render).c_str());
 
     return primaryRanges.valid() && appRequestRanges.valid();
 }
@@ -1156,8 +1161,8 @@
 
         const auto frameRateModes = createFrameRateModes(filterModes, ranges.render);
         LOG_ALWAYS_FATAL_IF(frameRateModes.empty(),
-                            "No matching frame rate modes for %s physicalRange %s", rangeName,
-                            to_string(ranges.physical).c_str());
+                            "No matching frame rate modes for %s range. policy: %s", rangeName,
+                            policy->toString().c_str());
 
         const auto stringifyModes = [&] {
             std::string str;
diff --git a/services/surfaceflinger/tests/unittests/RefreshRateSelectorTest.cpp b/services/surfaceflinger/tests/unittests/RefreshRateSelectorTest.cpp
index fdf2ffe..a3b3c4c 100644
--- a/services/surfaceflinger/tests/unittests/RefreshRateSelectorTest.cpp
+++ b/services/surfaceflinger/tests/unittests/RefreshRateSelectorTest.cpp
@@ -2943,5 +2943,18 @@
     EXPECT_EQ(kModeId35, selector.getBestFrameRateMode({}, {.idle = true})->getId());
 }
 
+TEST_P(RefreshRateSelectorTest, policyCanBeInfinity) {
+    auto selector = createSelector(kModes_60_120, kModeId120);
+
+    constexpr Fps inf = Fps::fromValue(std::numeric_limits<float>::infinity());
+
+    using namespace fps_approx_ops;
+    selector.setDisplayManagerPolicy({kModeId60, {0_Hz, inf}});
+
+    // With no layers, idle should still be lower priority than touch boost.
+    EXPECT_EQ(kMode120, selector.getMaxRefreshRateByPolicy());
+    EXPECT_EQ(kMode60, selector.getMinRefreshRateByPolicy());
+}
+
 } // namespace
 } // namespace android::scheduler