SF: Avoid registering DisplayDevice with Scheduler

The Scheduler should only care about the RefreshRateSelector part, and
should not needlessly extend the compositionengine::Display's lifetime
until the DisplayDevice is unregistered.

Make Scheduler::registerDisplay infallible, such that SurfaceFlinger::
processDisplayChanged does not need to unregister before registering.

Bug: 241285191
Test: libsurfaceflinger_unittest
Change-Id: I12b3855167e98f48ae368d39264edcb456efb293
diff --git a/services/surfaceflinger/Scheduler/Scheduler.cpp b/services/surfaceflinger/Scheduler/Scheduler.cpp
index 499cee6..0e1b775 100644
--- a/services/surfaceflinger/Scheduler/Scheduler.cpp
+++ b/services/surfaceflinger/Scheduler/Scheduler.cpp
@@ -94,7 +94,7 @@
     }
 }
 
-void Scheduler::setRefreshRateSelector(std::shared_ptr<RefreshRateSelector> selectorPtr) {
+void Scheduler::setRefreshRateSelector(RefreshRateSelectorPtr selectorPtr) {
     // The current RefreshRateSelector instance may outlive this call, so unbind its idle timer.
     {
         // mRefreshRateSelectorLock is not locked here to avoid the deadlock
@@ -126,13 +126,12 @@
     mRefreshRateSelector->startIdleTimer();
 }
 
-void Scheduler::registerDisplay(sp<const DisplayDevice> display) {
-    if (display->isPrimary()) {
-        mLeaderDisplayId = display->getPhysicalId();
+void Scheduler::registerDisplay(PhysicalDisplayId displayId, RefreshRateSelectorPtr selectorPtr) {
+    if (!mLeaderDisplayId) {
+        mLeaderDisplayId = displayId;
     }
 
-    const bool ok = mDisplays.try_emplace(display->getPhysicalId(), std::move(display)).second;
-    ALOGE_IF(!ok, "%s: Duplicate display", __func__);
+    mRefreshRateSelectors.emplace_or_replace(displayId, std::move(selectorPtr));
 }
 
 void Scheduler::unregisterDisplay(PhysicalDisplayId displayId) {
@@ -140,7 +139,7 @@
         mLeaderDisplayId.reset();
     }
 
-    mDisplays.erase(displayId);
+    mRefreshRateSelectors.erase(displayId);
 }
 
 void Scheduler::run() {
@@ -711,10 +710,9 @@
 
     const auto globalSignals = makeGlobalSignals();
 
-    for (const auto& [id, display] : mDisplays) {
+    for (const auto& [id, selectorPtr] : mRefreshRateSelectors) {
         auto rankedRefreshRates =
-                display->holdRefreshRateSelector()
-                        ->getRankedRefreshRates(mPolicy.contentRequirements, globalSignals);
+                selectorPtr->getRankedRefreshRates(mPolicy.contentRequirements, globalSignals);
 
         for (const auto& [modePtr, score] : rankedRefreshRates.ranking) {
             const auto [it, inserted] = refreshRateTallies.try_emplace(modePtr->getFps(), score);
@@ -733,7 +731,7 @@
 
     // Find the first refresh rate common to all displays.
     while (maxScoreIt != refreshRateTallies.cend() &&
-           maxScoreIt->second.displayCount != mDisplays.size()) {
+           maxScoreIt->second.displayCount != mRefreshRateSelectors.size()) {
         ++maxScoreIt;
     }
 
@@ -742,7 +740,8 @@
         for (auto it = maxScoreIt + 1; it != refreshRateTallies.cend(); ++it) {
             const auto [fps, tally] = *it;
 
-            if (tally.displayCount == mDisplays.size() && tally.score > maxScoreIt->second.score) {
+            if (tally.displayCount == mRefreshRateSelectors.size() &&
+                tally.score > maxScoreIt->second.score) {
                 maxScoreIt = it;
             }
         }
diff --git a/services/surfaceflinger/Scheduler/Scheduler.h b/services/surfaceflinger/Scheduler/Scheduler.h
index 39c41b9..901cf74 100644
--- a/services/surfaceflinger/Scheduler/Scheduler.h
+++ b/services/surfaceflinger/Scheduler/Scheduler.h
@@ -39,7 +39,6 @@
 
 #include "Display/DisplayMap.h"
 #include "Display/DisplayModeRequest.h"
-#include "DisplayDevice.h"
 #include "EventThread.h"
 #include "FrameRateOverrideMappings.h"
 #include "LayerHistory.h"
@@ -107,10 +106,11 @@
     virtual ~Scheduler();
 
     void startTimers();
-    void setRefreshRateSelector(std::shared_ptr<RefreshRateSelector>)
-            EXCLUDES(mRefreshRateSelectorLock);
 
-    void registerDisplay(sp<const DisplayDevice>);
+    using RefreshRateSelectorPtr = std::shared_ptr<RefreshRateSelector>;
+    void setRefreshRateSelector(RefreshRateSelectorPtr) EXCLUDES(mRefreshRateSelectorLock);
+
+    void registerDisplay(PhysicalDisplayId, RefreshRateSelectorPtr);
     void unregisterDisplay(PhysicalDisplayId);
 
     void run();
@@ -299,8 +299,7 @@
             EXCLUDES(mRefreshRateSelectorLock);
     android::impl::EventThread::GetVsyncPeriodFunction makeGetVsyncPeriodFunction() const;
 
-    std::shared_ptr<RefreshRateSelector> holdRefreshRateSelector() const
-            EXCLUDES(mRefreshRateSelectorLock) {
+    RefreshRateSelectorPtr holdRefreshRateSelector() const EXCLUDES(mRefreshRateSelectorLock) {
         std::scoped_lock lock(mRefreshRateSelectorLock);
         return mRefreshRateSelector;
     }
@@ -336,7 +335,7 @@
 
     mutable std::mutex mPolicyLock;
 
-    display::PhysicalDisplayMap<PhysicalDisplayId, sp<const DisplayDevice>> mDisplays;
+    display::PhysicalDisplayMap<PhysicalDisplayId, RefreshRateSelectorPtr> mRefreshRateSelectors;
     std::optional<PhysicalDisplayId> mLeaderDisplayId;
 
     struct Policy {
@@ -359,8 +358,9 @@
         std::optional<ModeChangedParams> cachedModeChangedParams;
     } mPolicy GUARDED_BY(mPolicyLock);
 
+    // TODO(b/255635821): Remove this by instead looking up the `mLeaderDisplayId` selector.
     mutable std::mutex mRefreshRateSelectorLock;
-    std::shared_ptr<RefreshRateSelector> mRefreshRateSelector GUARDED_BY(mRefreshRateSelectorLock);
+    RefreshRateSelectorPtr mRefreshRateSelector GUARDED_BY(mRefreshRateSelectorLock);
 
     std::mutex mVsyncTimelineLock;
     std::optional<hal::VsyncPeriodChangeTimeline> mLastVsyncPeriodChangeTimeline