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/libs/gui/Choreographer.cpp b/libs/gui/Choreographer.cpp
index 6b25b26..99bf6ba 100644
--- a/libs/gui/Choreographer.cpp
+++ b/libs/gui/Choreographer.cpp
@@ -101,8 +101,9 @@
     return gChoreographer;
 }
 
-Choreographer::Choreographer(const sp<Looper>& looper)
-      : DisplayEventDispatcher(looper, gui::ISurfaceComposer::VsyncSource::eVsyncSourceApp),
+Choreographer::Choreographer(const sp<Looper>& looper, const sp<IBinder>& layerHandle)
+      : DisplayEventDispatcher(looper, gui::ISurfaceComposer::VsyncSource::eVsyncSourceApp, {},
+                               layerHandle),
         mLooper(looper),
         mThreadId(std::this_thread::get_id()) {
     std::lock_guard<std::mutex> _l(gChoreographers.lock);
diff --git a/libs/gui/DisplayEventDispatcher.cpp b/libs/gui/DisplayEventDispatcher.cpp
index 501e69a..8a88377 100644
--- a/libs/gui/DisplayEventDispatcher.cpp
+++ b/libs/gui/DisplayEventDispatcher.cpp
@@ -37,9 +37,10 @@
 
 DisplayEventDispatcher::DisplayEventDispatcher(const sp<Looper>& looper,
                                                gui::ISurfaceComposer::VsyncSource vsyncSource,
-                                               EventRegistrationFlags eventRegistration)
+                                               EventRegistrationFlags eventRegistration,
+                                               const sp<IBinder>& layerHandle)
       : mLooper(looper),
-        mReceiver(vsyncSource, eventRegistration),
+        mReceiver(vsyncSource, eventRegistration, layerHandle),
         mWaitingForVsync(false),
         mLastVsyncCount(0),
         mLastScheduleVsyncTime(0) {
diff --git a/libs/gui/DisplayEventReceiver.cpp b/libs/gui/DisplayEventReceiver.cpp
index c52fb6b..6849a95 100644
--- a/libs/gui/DisplayEventReceiver.cpp
+++ b/libs/gui/DisplayEventReceiver.cpp
@@ -14,6 +14,8 @@
  * limitations under the License.
  */
 
+#define LOG_TAG "DisplayEventReceiver"
+
 #include <string.h>
 
 #include <utils/Errors.h>
@@ -32,7 +34,8 @@
 // ---------------------------------------------------------------------------
 
 DisplayEventReceiver::DisplayEventReceiver(gui::ISurfaceComposer::VsyncSource vsyncSource,
-                                           EventRegistrationFlags eventRegistration) {
+                                           EventRegistrationFlags eventRegistration,
+                                           const sp<IBinder>& layerHandle) {
     sp<gui::ISurfaceComposer> sf(ComposerServiceAIDL::getComposerService());
     if (sf != nullptr) {
         mEventConnection = nullptr;
@@ -41,8 +44,8 @@
                                                  static_cast<
                                                          gui::ISurfaceComposer::EventRegistration>(
                                                          eventRegistration.get()),
-                                                 &mEventConnection);
-        if (mEventConnection != nullptr) {
+                                                 layerHandle, &mEventConnection);
+        if (status.isOk() && mEventConnection != nullptr) {
             mDataChannel = std::make_unique<gui::BitTube>();
             status = mEventConnection->stealReceiveChannel(mDataChannel.get());
             if (!status.isOk()) {
@@ -51,6 +54,8 @@
                 mDataChannel.reset();
                 mEventConnection.clear();
             }
+        } else {
+            ALOGE("DisplayEventConnection creation failed: status=%s", status.toString8().c_str());
         }
     }
 }
diff --git a/libs/gui/SurfaceControl.cpp b/libs/gui/SurfaceControl.cpp
index 7aee882..c5f9c38 100644
--- a/libs/gui/SurfaceControl.cpp
+++ b/libs/gui/SurfaceControl.cpp
@@ -26,6 +26,7 @@
 #include <utils/Errors.h>
 #include <utils/KeyedVector.h>
 #include <utils/Log.h>
+#include <utils/Looper.h>
 #include <utils/threads.h>
 
 #include <binder/IPCThreadState.h>
@@ -34,8 +35,9 @@
 #include <ui/Rect.h>
 #include <ui/StaticDisplayInfo.h>
 
-#include <gui/BufferQueueCore.h>
 #include <gui/BLASTBufferQueue.h>
+#include <gui/BufferQueueCore.h>
+#include <gui/Choreographer.h>
 #include <gui/ISurfaceComposer.h>
 #include <gui/Surface.h>
 #include <gui/SurfaceComposerClient.h>
@@ -191,6 +193,24 @@
     return mName;
 }
 
+std::shared_ptr<Choreographer> SurfaceControl::getChoreographer() {
+    if (mChoreographer) {
+        return mChoreographer;
+    }
+    sp<Looper> looper = Looper::getForThread();
+    if (!looper.get()) {
+        ALOGE("%s: No looper prepared for thread", __func__);
+        return nullptr;
+    }
+    mChoreographer = std::make_shared<Choreographer>(looper, getHandle());
+    status_t result = mChoreographer->initialize();
+    if (result != OK) {
+        ALOGE("Failed to initialize choreographer");
+        mChoreographer = nullptr;
+    }
+    return mChoreographer;
+}
+
 sp<IGraphicBufferProducer> SurfaceControl::getIGraphicBufferProducer()
 {
     getSurface();
diff --git a/libs/gui/aidl/android/gui/ISurfaceComposer.aidl b/libs/gui/aidl/android/gui/ISurfaceComposer.aidl
index 597749a..9812142 100644
--- a/libs/gui/aidl/android/gui/ISurfaceComposer.aidl
+++ b/libs/gui/aidl/android/gui/ISurfaceComposer.aidl
@@ -68,9 +68,15 @@
 
     /**
      * Create a display event connection
+     *
+     * layerHandle
+     *     Optional binder handle representing a Layer in SF to associate the new
+     *     DisplayEventConnection with. This handle can be found inside a surface control after
+     *     surface creation, see ISurfaceComposerClient::createSurface. Set to null if no layer
+     *     association should be made.
      */
     @nullable IDisplayEventConnection createDisplayEventConnection(VsyncSource vsyncSource,
-            EventRegistration eventRegistration);
+            EventRegistration eventRegistration, @nullable IBinder layerHandle);
 
     /**
      * Create a connection with SurfaceFlinger.
diff --git a/libs/gui/fuzzer/libgui_fuzzer_utils.h b/libs/gui/fuzzer/libgui_fuzzer_utils.h
index 14a0e39..f01c2a9 100644
--- a/libs/gui/fuzzer/libgui_fuzzer_utils.h
+++ b/libs/gui/fuzzer/libgui_fuzzer_utils.h
@@ -64,7 +64,7 @@
     MOCK_METHOD(binder::Status, bootFinished, (), (override));
     MOCK_METHOD(binder::Status, createDisplayEventConnection,
                 (gui::ISurfaceComposer::VsyncSource, gui::ISurfaceComposer::EventRegistration,
-                 sp<gui::IDisplayEventConnection>*),
+                 const sp<IBinder>& /*layerHandle*/, sp<gui::IDisplayEventConnection>*),
                 (override));
     MOCK_METHOD(binder::Status, createConnection, (sp<gui::ISurfaceComposerClient>*), (override));
     MOCK_METHOD(binder::Status, createDisplay, (const std::string&, bool, float, sp<IBinder>*),
diff --git a/libs/gui/include/gui/Choreographer.h b/libs/gui/include/gui/Choreographer.h
index 89a7058..1df9b11 100644
--- a/libs/gui/include/gui/Choreographer.h
+++ b/libs/gui/include/gui/Choreographer.h
@@ -73,7 +73,8 @@
     };
     static Context gChoreographers;
 
-    explicit Choreographer(const sp<Looper>& looper) EXCLUDES(gChoreographers.lock);
+    explicit Choreographer(const sp<Looper>& looper, const sp<IBinder>& layerHandle = nullptr)
+            EXCLUDES(gChoreographers.lock);
     void postFrameCallbackDelayed(AChoreographer_frameCallback cb,
                                   AChoreographer_frameCallback64 cb64,
                                   AChoreographer_vsyncCallback vsyncCallback, void* data,
diff --git a/libs/gui/include/gui/DisplayEventDispatcher.h b/libs/gui/include/gui/DisplayEventDispatcher.h
index bf3a07b..140efa6 100644
--- a/libs/gui/include/gui/DisplayEventDispatcher.h
+++ b/libs/gui/include/gui/DisplayEventDispatcher.h
@@ -26,7 +26,8 @@
     explicit DisplayEventDispatcher(const sp<Looper>& looper,
                                     gui::ISurfaceComposer::VsyncSource vsyncSource =
                                             gui::ISurfaceComposer::VsyncSource::eVsyncSourceApp,
-                                    EventRegistrationFlags eventRegistration = {});
+                                    EventRegistrationFlags eventRegistration = {},
+                                    const sp<IBinder>& layerHandle = nullptr);
 
     status_t initialize();
     void dispose();
diff --git a/libs/gui/include/gui/DisplayEventReceiver.h b/libs/gui/include/gui/DisplayEventReceiver.h
index 0f4907f..7fd6c35 100644
--- a/libs/gui/include/gui/DisplayEventReceiver.h
+++ b/libs/gui/include/gui/DisplayEventReceiver.h
@@ -119,7 +119,8 @@
      */
     explicit DisplayEventReceiver(gui::ISurfaceComposer::VsyncSource vsyncSource =
                                           gui::ISurfaceComposer::VsyncSource::eVsyncSourceApp,
-                                  EventRegistrationFlags eventRegistration = {});
+                                  EventRegistrationFlags eventRegistration = {},
+                                  const sp<IBinder>& layerHandle = nullptr);
 
     /*
      * ~DisplayEventReceiver severs the connection with SurfaceFlinger, new events
diff --git a/libs/gui/include/gui/SurfaceControl.h b/libs/gui/include/gui/SurfaceControl.h
index 1d4fc7f..344b957 100644
--- a/libs/gui/include/gui/SurfaceControl.h
+++ b/libs/gui/include/gui/SurfaceControl.h
@@ -36,6 +36,7 @@
 
 // ---------------------------------------------------------------------------
 
+class Choreographer;
 class IGraphicBufferProducer;
 class Surface;
 class SurfaceComposerClient;
@@ -80,6 +81,9 @@
     int32_t getLayerId() const;
     const std::string& getName() const;
 
+    // TODO(b/267195698): Consider renaming.
+    std::shared_ptr<Choreographer> getChoreographer();
+
     sp<IGraphicBufferProducer> getIGraphicBufferProducer();
 
     status_t clearLayerFrameStats() const;
@@ -130,6 +134,7 @@
     PixelFormat mFormat = PIXEL_FORMAT_NONE;
     uint32_t mCreateFlags = 0;
     uint64_t mFallbackFrameNumber = 100;
+    std::shared_ptr<Choreographer> mChoreographer;
 };
 
 }; // namespace android
diff --git a/libs/gui/tests/Surface_test.cpp b/libs/gui/tests/Surface_test.cpp
index 9b2bf7f..babc197 100644
--- a/libs/gui/tests/Surface_test.cpp
+++ b/libs/gui/tests/Surface_test.cpp
@@ -725,6 +725,7 @@
 
     binder::Status createDisplayEventConnection(
             VsyncSource /*vsyncSource*/, EventRegistration /*eventRegistration*/,
+            const sp<IBinder>& /*layerHandle*/,
             sp<gui::IDisplayEventConnection>* outConnection) override {
         *outConnection = nullptr;
         return binder::Status::ok();