SF: configure idle timer based on display id

Use the DisplayId when reading the timer configuration from system
properties.

Bug: 188838426
Test: check idle timer can be set separately for each display based
      on display id
Change-Id: I9051374a78d99676ace7f1ded6accc8a50b17c79
diff --git a/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp b/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp
index 011229e..ee1d730 100644
--- a/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp
+++ b/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp
@@ -685,19 +685,16 @@
 }
 
 void RefreshRateConfigs::initializeIdleTimer() {
-    const int setIdleTimerMs = base::GetIntProperty("debug.sf.set_idle_timer_ms", 0);
-
-    if (const auto millis = setIdleTimerMs ? setIdleTimerMs : sysprop::set_idle_timer_ms(0);
-        millis > 0) {
+    if (mConfig.idleTimerTimeoutMs > 0) {
         const auto getCallback = [this]() -> std::optional<IdleTimerCallbacks::Callbacks> {
             std::scoped_lock lock(mIdleTimerCallbacksMutex);
             if (!mIdleTimerCallbacks.has_value()) return {};
-            return mConfig.supportKernelTimer ? mIdleTimerCallbacks->kernel
-                                              : mIdleTimerCallbacks->platform;
+            return mConfig.supportKernelIdleTimer ? mIdleTimerCallbacks->kernel
+                                                  : mIdleTimerCallbacks->platform;
         };
 
         mIdleTimer.emplace(
-                "IdleTimer", std::chrono::milliseconds(millis),
+                "IdleTimer", std::chrono::milliseconds(mConfig.idleTimerTimeoutMs),
                 [getCallback] {
                     if (const auto callback = getCallback()) callback->onReset();
                 },
@@ -970,7 +967,8 @@
 
     base::StringAppendF(&result, "Supports Frame Rate Override: %s\n",
                         mSupportsFrameRateOverride ? "yes" : "no");
-    base::StringAppendF(&result, "Idle timer: %s\n",
+    base::StringAppendF(&result, "Idle timer: (%s) %s\n",
+                        mConfig.supportKernelIdleTimer ? "kernel" : "platform",
                         mIdleTimer ? mIdleTimer->dump().c_str() : "off");
     result.append("\n");
 }
diff --git a/services/surfaceflinger/Scheduler/RefreshRateConfigs.h b/services/surfaceflinger/Scheduler/RefreshRateConfigs.h
index 0f0fe22..2addc83 100644
--- a/services/surfaceflinger/Scheduler/RefreshRateConfigs.h
+++ b/services/surfaceflinger/Scheduler/RefreshRateConfigs.h
@@ -307,14 +307,18 @@
         // no threshold is set.
         int frameRateMultipleThreshold = 0;
 
+        // The Idle Timer timeout. 0 timeout means no idle timer.
+        int32_t idleTimerTimeoutMs = 0;
+
         // Whether to use idle timer callbacks that support the kernel timer.
-        bool supportKernelTimer = false;
+        bool supportKernelIdleTimer = false;
     };
 
-    RefreshRateConfigs(const DisplayModes& modes, DisplayModeId currentModeId,
+    RefreshRateConfigs(const DisplayModes&, DisplayModeId,
                        Config config = {.enableFrameRateOverride = false,
                                         .frameRateMultipleThreshold = 0,
-                                        .supportKernelTimer = false});
+                                        .idleTimerTimeoutMs = 0,
+                                        .supportKernelIdleTimer = false});
 
     // Returns whether switching modes (refresh rate or resolution) is possible.
     // TODO(b/158780872): Consider HAL support, and skip frame rate detection if the modes only
@@ -350,7 +354,7 @@
                                                  Fps displayFrameRate, bool touch) const
             EXCLUDES(mLock);
 
-    bool supportsKernelIdleTimer() const { return mConfig.supportKernelTimer; }
+    bool supportsKernelIdleTimer() const { return mConfig.supportKernelIdleTimer; }
 
     void setIdleTimerCallbacks(std::function<void()> platformTimerReset,
                                std::function<void()> platformTimerExpired,
@@ -368,7 +372,7 @@
         if (!mIdleTimer) {
             return;
         }
-        if (kernelOnly && !mConfig.supportKernelTimer) {
+        if (kernelOnly && !mConfig.supportKernelIdleTimer) {
             return;
         }
         mIdleTimer->reset();
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index a7092ab..b55ea4f 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -275,6 +275,40 @@
     ROTATE_SURFACE_FLINGER = 0x2,
 };
 
+struct IdleTimerConfig {
+    int32_t timeoutMs;
+    bool supportKernelIdleTimer;
+};
+
+IdleTimerConfig getIdleTimerConfiguration(DisplayId displayId) {
+    // TODO(adyabr): use ro.surface_flinger.* namespace
+
+    const auto displayIdleTimerMsKey = [displayId] {
+        std::stringstream ss;
+        ss << "debug.sf.set_idle_timer_ms_" << displayId.value;
+        return ss.str();
+    }();
+
+    const auto displaySupportKernelIdleTimerKey = [displayId] {
+        std::stringstream ss;
+        ss << "debug.sf.support_kernel_idle_timer_" << displayId.value;
+        return ss.str();
+    }();
+
+    const int32_t displayIdleTimerMs = base::GetIntProperty(displayIdleTimerMsKey, 0);
+    const auto displaySupportKernelIdleTimer =
+            base::GetBoolProperty(displaySupportKernelIdleTimerKey, false);
+
+    if (displayIdleTimerMs > 0) {
+        return {displayIdleTimerMs, displaySupportKernelIdleTimer};
+    }
+
+    const int32_t setIdleTimerMs = base::GetIntProperty("debug.sf.set_idle_timer_ms", 0);
+    const int32_t millis = setIdleTimerMs ? setIdleTimerMs : sysprop::set_idle_timer_ms(0);
+
+    return {millis, sysprop::support_kernel_idle_timer(false)};
+}
+
 }  // namespace anonymous
 
 // ---------------------------------------------------------------------------
@@ -2643,11 +2677,14 @@
         creationArgs.connectionType = physical->type;
         creationArgs.supportedModes = physical->supportedModes;
         creationArgs.activeModeId = physical->activeMode->getId();
+        const auto [idleTimerTimeoutMs, supportKernelIdleTimer] =
+                getIdleTimerConfiguration(compositionDisplay->getId());
         scheduler::RefreshRateConfigs::Config config =
                 {.enableFrameRateOverride = android::sysprop::enable_frame_rate_override(false),
                  .frameRateMultipleThreshold =
                          base::GetIntProperty("debug.sf.frame_rate_multiple_threshold", 0),
-                 .supportKernelTimer = sysprop::support_kernel_idle_timer(false)};
+                 .idleTimerTimeoutMs = idleTimerTimeoutMs,
+                 .supportKernelIdleTimer = supportKernelIdleTimer};
         creationArgs.refreshRateConfigs =
                 std::make_shared<scheduler::RefreshRateConfigs>(creationArgs.supportedModes,
                                                                 creationArgs.activeModeId, config);