Receive refresh rate callbacks from DMS

AChoreographer will use DMS as the source of truth for these callbacks
instead of SurfaceFlinger.

Bug: 154874011
Test: ChoreographerNativeTest
Tes: Manually verify that HWUI is processing refresh rate callbacks
Change-Id: I961a7d1ab335800d3e260ba7564ddca9c0595cfc
diff --git a/services/surfaceflinger/Scheduler/EventThread.cpp b/services/surfaceflinger/Scheduler/EventThread.cpp
index 5dedb6a..cee36a1 100644
--- a/services/surfaceflinger/Scheduler/EventThread.cpp
+++ b/services/surfaceflinger/Scheduler/EventThread.cpp
@@ -152,16 +152,9 @@
     mEventThread->requestNextVsync(this);
 }
 
-void EventThreadConnection::toggleConfigEvents(ISurfaceComposer::ConfigChanged configChangeFlag) {
-    ATRACE_NAME("enableConfigEvents");
-    mConfigChanged = configChangeFlag;
-
-    // In principle it's possible for rapidly toggling config events to drop an
-    // event here, but it's unlikely in practice.
-    if (configChangeFlag == ISurfaceComposer::eConfigChangedDispatch) {
-        mForcedConfigChangeDispatch = true;
-        mEventThread->requestLatestConfig();
-    }
+void EventThreadConnection::requestLatestConfig() {
+    ATRACE_NAME("requestLatestConfig");
+    mEventThread->requestLatestConfig(this);
 }
 
 status_t EventThreadConnection::postEvent(const DisplayEventReceiver::Event& event) {
@@ -276,8 +269,12 @@
     }
 }
 
-void EventThread::requestLatestConfig() {
+void EventThread::requestLatestConfig(const sp<EventThreadConnection>& connection) {
     std::lock_guard<std::mutex> lock(mMutex);
+    if (connection->mForcedConfigChangeDispatch) {
+        return;
+    }
+    connection->mForcedConfigChangeDispatch = true;
     auto pendingConfigChange =
             std::find_if(std::begin(mPendingEvents), std::end(mPendingEvents),
                          [&](const DisplayEventReceiver::Event& event) {
@@ -384,6 +381,10 @@
                 vsyncRequested |= connection->vsyncRequest != VSyncRequest::None;
 
                 if (event && shouldConsumeEvent(*event, connection)) {
+                    if (event->header.type == DisplayEventReceiver::DISPLAY_EVENT_CONFIG_CHANGED &&
+                        connection->mForcedConfigChangeDispatch) {
+                        connection->mForcedConfigChangeDispatch = false;
+                    }
                     consumers.push_back(connection);
                 }
 
@@ -459,8 +460,8 @@
             return true;
 
         case DisplayEventReceiver::DISPLAY_EVENT_CONFIG_CHANGED: {
-            const bool forcedDispatch = connection->mForcedConfigChangeDispatch.exchange(false);
-            return forcedDispatch ||
+            const bool oneTimeDispatch = connection->mForcedConfigChangeDispatch;
+            return oneTimeDispatch ||
                     connection->mConfigChanged == ISurfaceComposer::eConfigChangedDispatch;
         }
 
diff --git a/services/surfaceflinger/Scheduler/EventThread.h b/services/surfaceflinger/Scheduler/EventThread.h
index 9e7086e..64acbd7 100644
--- a/services/surfaceflinger/Scheduler/EventThread.h
+++ b/services/surfaceflinger/Scheduler/EventThread.h
@@ -81,19 +81,19 @@
     status_t stealReceiveChannel(gui::BitTube* outChannel) override;
     status_t setVsyncRate(uint32_t rate) override;
     void requestNextVsync() override; // asynchronous
-    void toggleConfigEvents(ISurfaceComposer::ConfigChanged configChangeFlag) override;
+    void requestLatestConfig() override; // asynchronous
 
     // Called in response to requestNextVsync.
     const ResyncCallback resyncCallback;
 
     VSyncRequest vsyncRequest = VSyncRequest::None;
-    std::atomic<ISurfaceComposer::ConfigChanged> mConfigChanged =
+    ISurfaceComposer::ConfigChanged mConfigChanged =
             ISurfaceComposer::ConfigChanged::eConfigChangedSuppress;
     // Store whether we need to force dispatching a config change separately -
     // if mConfigChanged ever changes before the config change is dispatched
     // then we still need to propagate an initial config to the app if we
     // haven't already.
-    std::atomic<bool> mForcedConfigChangeDispatch = false;
+    bool mForcedConfigChangeDispatch = false;
 
 private:
     virtual void onFirstRef();
@@ -129,11 +129,10 @@
     virtual void setVsyncRate(uint32_t rate, const sp<EventThreadConnection>& connection) = 0;
     // Requests the next vsync. If resetIdleTimer is set to true, it resets the idle timer.
     virtual void requestNextVsync(const sp<EventThreadConnection>& connection) = 0;
-
     // Dispatches the most recent configuration
     // Usage of this method assumes that only the primary internal display
     // supports multiple display configurations.
-    virtual void requestLatestConfig() = 0;
+    virtual void requestLatestConfig(const sp<EventThreadConnection>& connection) = 0;
 
     // Retrieves the number of event connections tracked by this EventThread.
     virtual size_t getEventThreadConnectionCount() = 0;
@@ -154,7 +153,7 @@
     status_t registerDisplayEventConnection(const sp<EventThreadConnection>& connection) override;
     void setVsyncRate(uint32_t rate, const sp<EventThreadConnection>& connection) override;
     void requestNextVsync(const sp<EventThreadConnection>& connection) override;
-    void requestLatestConfig() override;
+    void requestLatestConfig(const sp<EventThreadConnection>& connection) override;
 
     // called before the screen is turned off from main thread
     void onScreenReleased() override;