SF: Introduce a configure stage

Decouple hotplug processing from commit of display transactions, as a
step toward per-display commit/composite. The configure stage will be
responsible for mode setting as well.

Bug: 241285876
Test: libsurfaceflinger_unittest
Change-Id: I72b7223760fa5896debb046f158845a0b4f4599a
diff --git a/services/surfaceflinger/Scheduler/MessageQueue.cpp b/services/surfaceflinger/Scheduler/MessageQueue.cpp
index e1ac301..e4e65b4 100644
--- a/services/surfaceflinger/Scheduler/MessageQueue.cpp
+++ b/services/surfaceflinger/Scheduler/MessageQueue.cpp
@@ -158,6 +158,19 @@
     mLooper->sendMessage(handler, Message());
 }
 
+void MessageQueue::scheduleConfigure() {
+    struct ConfigureHandler : MessageHandler {
+        explicit ConfigureHandler(ICompositor& compositor) : compositor(compositor) {}
+
+        void handleMessage(const Message&) override { compositor.configure(); }
+
+        ICompositor& compositor;
+    };
+
+    // TODO(b/241285876): Batch configure tasks that happen within some duration.
+    postMessage(sp<ConfigureHandler>::make(mCompositor));
+}
+
 void MessageQueue::scheduleFrame() {
     ATRACE_CALL();
 
diff --git a/services/surfaceflinger/Scheduler/MessageQueue.h b/services/surfaceflinger/Scheduler/MessageQueue.h
index 506f27b..899233a 100644
--- a/services/surfaceflinger/Scheduler/MessageQueue.h
+++ b/services/surfaceflinger/Scheduler/MessageQueue.h
@@ -38,6 +38,7 @@
 namespace android {
 
 struct ICompositor {
+    virtual void configure() = 0;
     virtual bool commit(TimePoint frameTime, VsyncId, TimePoint expectedVsyncTime) = 0;
     virtual void composite(TimePoint frameTime, VsyncId) = 0;
     virtual void sample() = 0;
@@ -78,6 +79,7 @@
     virtual void setInjector(sp<EventThreadConnection>) = 0;
     virtual void waitMessage() = 0;
     virtual void postMessage(sp<MessageHandler>&&) = 0;
+    virtual void scheduleConfigure() = 0;
     virtual void scheduleFrame() = 0;
 
     using Clock = std::chrono::steady_clock;
@@ -152,6 +154,7 @@
     void waitMessage() override;
     void postMessage(sp<MessageHandler>&&) override;
 
+    void scheduleConfigure() override;
     void scheduleFrame() override;
 
     std::optional<Clock::time_point> getScheduledFrameTime() const override;
diff --git a/services/surfaceflinger/Scheduler/Scheduler.h b/services/surfaceflinger/Scheduler/Scheduler.h
index 4730493..eb3856d 100644
--- a/services/surfaceflinger/Scheduler/Scheduler.h
+++ b/services/surfaceflinger/Scheduler/Scheduler.h
@@ -116,6 +116,7 @@
     using Impl::getScheduledFrameTime;
     using Impl::setDuration;
 
+    using Impl::scheduleConfigure;
     using Impl::scheduleFrame;
 
     // Schedule an asynchronous or synchronous task on the main thread.