Framework code for Attached Choreographer.

Allows a direct association of a Layer (via LayerHistory) to attached
choreographer.
The EventThread checks whether the vsync is in phase for a
choreographer.

Bug: 255838011
Test: atest AttachedChoreographerNativeTest
Change-Id: I9cb35bced5e6d4509609ad7698ab2902a31d5b98
diff --git a/services/surfaceflinger/Scheduler/EventThread.cpp b/services/surfaceflinger/Scheduler/EventThread.cpp
index 76e9416..5e79a5c 100644
--- a/services/surfaceflinger/Scheduler/EventThread.cpp
+++ b/services/surfaceflinger/Scheduler/EventThread.cpp
@@ -532,6 +532,12 @@
                                      const sp<EventThreadConnection>& connection) const {
     const auto throttleVsync = [&] {
         const auto& vsyncData = event.vsync.vsyncData;
+        if (connection->frameRate.isValid()) {
+            return !mVsyncSchedule->getTracker()
+                            .isVSyncInPhase(vsyncData.preferredExpectedPresentationTime(),
+                                            connection->frameRate);
+        }
+
         const auto expectedPresentTime =
                 TimePoint::fromNs(vsyncData.preferredExpectedPresentationTime());
         return !mEventThreadCallback.isVsyncTargetForUid(expectedPresentTime,
diff --git a/services/surfaceflinger/Scheduler/EventThread.h b/services/surfaceflinger/Scheduler/EventThread.h
index b86553b..aa27091 100644
--- a/services/surfaceflinger/Scheduler/EventThread.h
+++ b/services/surfaceflinger/Scheduler/EventThread.h
@@ -97,6 +97,9 @@
     const uid_t mOwnerUid;
     const EventRegistrationFlags mEventRegistration;
 
+    /** The frame rate set to the attached choreographer. */
+    Fps frameRate;
+
 private:
     virtual void onFirstRef();
     EventThread* const mEventThread;
diff --git a/services/surfaceflinger/Scheduler/LayerHistory.cpp b/services/surfaceflinger/Scheduler/LayerHistory.cpp
index 55fa402..e853833 100644
--- a/services/surfaceflinger/Scheduler/LayerHistory.cpp
+++ b/services/surfaceflinger/Scheduler/LayerHistory.cpp
@@ -32,6 +32,7 @@
 #include <utility>
 
 #include "../Layer.h"
+#include "EventThread.h"
 #include "LayerInfo.h"
 
 namespace android::scheduler {
@@ -140,6 +141,22 @@
 
     info->setLastPresentTime(presentTime, now, updateType, mModeChangePending, layerProps);
 
+    // Set frame rate to attached choreographer.
+    // TODO(b/260898223): Change to use layer hierarchy and handle frame rate vote.
+    if (updateType == LayerUpdateType::SetFrameRate) {
+        auto range = mAttachedChoreographers.equal_range(id);
+        auto it = range.first;
+        while (it != range.second) {
+            sp<EventThreadConnection> choreographerConnection = it->second.promote();
+            if (choreographerConnection) {
+                choreographerConnection->frameRate = layer->getFrameRateForLayerTree().rate;
+                it++;
+            } else {
+                it = mAttachedChoreographers.erase(it);
+            }
+        }
+    }
+
     // Activate layer if inactive.
     if (found == LayerStatus::LayerInInactiveMap) {
         mActiveLayerInfos.insert(
@@ -294,6 +311,12 @@
     return 0.f;
 }
 
+void LayerHistory::attachChoreographer(int32_t layerId,
+                                       const sp<EventThreadConnection>& choreographerConnection) {
+    std::lock_guard lock(mLock);
+    mAttachedChoreographers.insert({layerId, wp<EventThreadConnection>(choreographerConnection)});
+}
+
 auto LayerHistory::findLayer(int32_t id) -> std::pair<LayerStatus, LayerPair*> {
     // the layer could be in either the active or inactive map, try both
     auto it = mActiveLayerInfos.find(id);
diff --git a/services/surfaceflinger/Scheduler/LayerHistory.h b/services/surfaceflinger/Scheduler/LayerHistory.h
index 5022906..68e7030 100644
--- a/services/surfaceflinger/Scheduler/LayerHistory.h
+++ b/services/surfaceflinger/Scheduler/LayerHistory.h
@@ -27,6 +27,8 @@
 #include <utility>
 #include <vector>
 
+#include "EventThread.h"
+
 #include "RefreshRateSelector.h"
 
 namespace android {
@@ -80,6 +82,9 @@
     // return the frames per second of the layer with the given sequence id.
     float getLayerFramerate(nsecs_t now, int32_t id) const;
 
+    void attachChoreographer(int32_t layerId,
+                             const sp<EventThreadConnection>& choreographerConnection);
+
 private:
     friend class LayerHistoryTest;
     friend class TestableScheduler;
@@ -117,6 +122,10 @@
     LayerInfos mActiveLayerInfos GUARDED_BY(mLock);
     LayerInfos mInactiveLayerInfos GUARDED_BY(mLock);
 
+    // Map keyed by layer ID (sequence) to choreographer connections.
+    std::unordered_multimap<int32_t, wp<EventThreadConnection>> mAttachedChoreographers
+            GUARDED_BY(mLock);
+
     uint32_t mDisplayArea = 0;
 
     // Whether to emit systrace output and debug logs.
diff --git a/services/surfaceflinger/Scheduler/Scheduler.cpp b/services/surfaceflinger/Scheduler/Scheduler.cpp
index e6f4665..eed57ef 100644
--- a/services/surfaceflinger/Scheduler/Scheduler.cpp
+++ b/services/surfaceflinger/Scheduler/Scheduler.cpp
@@ -47,6 +47,7 @@
 #include "Display/DisplayMap.h"
 #include "EventThread.h"
 #include "FrameRateOverrideMappings.h"
+#include "FrontEnd/LayerHandle.h"
 #include "OneShotTimer.h"
 #include "SurfaceFlingerProperties.h"
 #include "VSyncPredictor.h"
@@ -232,15 +233,21 @@
 }
 
 sp<EventThreadConnection> Scheduler::createConnectionInternal(
-        EventThread* eventThread, EventRegistrationFlags eventRegistration) {
-    return eventThread->createEventConnection([&] { resync(); }, eventRegistration);
+        EventThread* eventThread, EventRegistrationFlags eventRegistration,
+        const sp<IBinder>& layerHandle) {
+    int32_t layerId = static_cast<int32_t>(LayerHandle::getLayerId(layerHandle));
+    auto connection = eventThread->createEventConnection([&] { resync(); }, eventRegistration);
+    mLayerHistory.attachChoreographer(layerId, connection);
+    return connection;
 }
 
 sp<IDisplayEventConnection> Scheduler::createDisplayEventConnection(
-        ConnectionHandle handle, EventRegistrationFlags eventRegistration) {
+        ConnectionHandle handle, EventRegistrationFlags eventRegistration,
+        const sp<IBinder>& layerHandle) {
     std::lock_guard<std::mutex> lock(mConnectionsLock);
     RETURN_IF_INVALID_HANDLE(handle, nullptr);
-    return createConnectionInternal(mConnections[handle].thread.get(), eventRegistration);
+    return createConnectionInternal(mConnections[handle].thread.get(), eventRegistration,
+                                    layerHandle);
 }
 
 sp<EventThreadConnection> Scheduler::getEventConnection(ConnectionHandle handle) {
diff --git a/services/surfaceflinger/Scheduler/Scheduler.h b/services/surfaceflinger/Scheduler/Scheduler.h
index 8dc2def..8c8fc21 100644
--- a/services/surfaceflinger/Scheduler/Scheduler.h
+++ b/services/surfaceflinger/Scheduler/Scheduler.h
@@ -147,7 +147,8 @@
                                        std::chrono::nanoseconds readyDuration);
 
     sp<IDisplayEventConnection> createDisplayEventConnection(
-            ConnectionHandle, EventRegistrationFlags eventRegistration = {});
+            ConnectionHandle, EventRegistrationFlags eventRegistration = {},
+            const sp<IBinder>& layerHandle = nullptr);
 
     sp<EventThreadConnection> getEventConnection(ConnectionHandle);
 
@@ -302,7 +303,8 @@
     // Create a connection on the given EventThread.
     ConnectionHandle createConnection(std::unique_ptr<EventThread>);
     sp<EventThreadConnection> createConnectionInternal(
-            EventThread*, EventRegistrationFlags eventRegistration = {});
+            EventThread*, EventRegistrationFlags eventRegistration = {},
+            const sp<IBinder>& layerHandle = nullptr);
 
     // Update feature state machine to given state when corresponding timer resets or expires.
     void kernelIdleTimerCallback(TimerState) EXCLUDES(mDisplayLock);
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 6020aba..4b3f9a1 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -1988,13 +1988,14 @@
 // ----------------------------------------------------------------------------
 
 sp<IDisplayEventConnection> SurfaceFlinger::createDisplayEventConnection(
-        gui::ISurfaceComposer::VsyncSource vsyncSource, EventRegistrationFlags eventRegistration) {
+        gui::ISurfaceComposer::VsyncSource vsyncSource, EventRegistrationFlags eventRegistration,
+        const sp<IBinder>& layerHandle) {
     const auto& handle =
             vsyncSource == gui::ISurfaceComposer::VsyncSource::eVsyncSourceSurfaceFlinger
             ? mSfConnectionHandle
             : mAppConnectionHandle;
 
-    return mScheduler->createDisplayEventConnection(handle, eventRegistration);
+    return mScheduler->createDisplayEventConnection(handle, eventRegistration, layerHandle);
 }
 
 void SurfaceFlinger::scheduleCommit(FrameHint hint) {
@@ -7455,9 +7456,9 @@
 
 binder::Status SurfaceComposerAIDL::createDisplayEventConnection(
         VsyncSource vsyncSource, EventRegistration eventRegistration,
-        sp<IDisplayEventConnection>* outConnection) {
+        const sp<IBinder>& layerHandle, sp<IDisplayEventConnection>* outConnection) {
     sp<IDisplayEventConnection> conn =
-            mFlinger->createDisplayEventConnection(vsyncSource, eventRegistration);
+            mFlinger->createDisplayEventConnection(vsyncSource, eventRegistration, layerHandle);
     if (conn == nullptr) {
         *outConnection = nullptr;
         return binderStatusFromStatusT(BAD_VALUE);
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 1eb1fda..e7d4f77 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -509,7 +509,8 @@
     sp<IDisplayEventConnection> createDisplayEventConnection(
             gui::ISurfaceComposer::VsyncSource vsyncSource =
                     gui::ISurfaceComposer::VsyncSource::eVsyncSourceApp,
-            EventRegistrationFlags eventRegistration = {});
+            EventRegistrationFlags eventRegistration = {},
+            const sp<IBinder>& layerHandle = nullptr);
 
     status_t captureDisplay(const DisplayCaptureArgs&, const sp<IScreenCaptureListener>&);
     status_t captureDisplay(DisplayId, const sp<IScreenCaptureListener>&);
@@ -1391,6 +1392,7 @@
     binder::Status bootFinished() override;
     binder::Status createDisplayEventConnection(
             VsyncSource vsyncSource, EventRegistration eventRegistration,
+            const sp<IBinder>& layerHandle,
             sp<gui::IDisplayEventConnection>* outConnection) override;
     binder::Status createConnection(sp<gui::ISurfaceComposerClient>* outClient) override;
     binder::Status createDisplay(const std::string& displayName, bool secure,