SF: Fix VSYNC injection

Disabling VSYNC injection causes the main thread to destroy the injected
EventThreadConnection, while it might be accessed by a Binder thread via
MessageQueue::invalidate.

Also, fix injection itself:

    - The EventThread did not dispatch injected events, falling back to
      fake VSYNC after timeout.
    - The MessageQueue would try listening to invalid FDs when enabling
      injection more than once.
    - Injection was not disabled after each test.

Finally, rename MessageQueue members only used for injection since S.

Bug: 150226265
Test: Toggle VSYNC injection in a tight loop while using phone.
Test: sffakehwc_test --gtest_repeat=-1 --gtest_break_on_failure
                     --gtest_filter='*VsyncInjection'
Change-Id: Ia58859cd8a36749bf56bb94fa724efe7c1b27b46
diff --git a/services/surfaceflinger/Scheduler/MessageQueue.cpp b/services/surfaceflinger/Scheduler/MessageQueue.cpp
index 47a4f42..7ff0ddf 100644
--- a/services/surfaceflinger/Scheduler/MessageQueue.cpp
+++ b/services/surfaceflinger/Scheduler/MessageQueue.cpp
@@ -69,17 +69,33 @@
 
 // TODO(b/169865816): refactor VSyncInjections to use MessageQueue directly
 // and remove the EventThread from MessageQueue
-void MessageQueue::setEventConnection(const sp<EventThreadConnection>& connection) {
-    if (mEventTube.getFd() >= 0) {
-        mLooper->removeFd(mEventTube.getFd());
+void MessageQueue::setInjector(sp<EventThreadConnection> connection) {
+    auto& tube = mInjector.tube;
+
+    if (const int fd = tube.getFd(); fd >= 0) {
+        mLooper->removeFd(fd);
     }
 
-    mEvents = connection;
-    if (mEvents) {
-        mEvents->stealReceiveChannel(&mEventTube);
-        mLooper->addFd(mEventTube.getFd(), 0, Looper::EVENT_INPUT, MessageQueue::cb_eventReceiver,
-                       this);
+    if (connection) {
+        // The EventThreadConnection is retained when disabling injection, so avoid subsequently
+        // stealing invalid FDs. Note that the stolen FDs are kept open.
+        if (tube.getFd() < 0) {
+            connection->stealReceiveChannel(&tube);
+        } else {
+            ALOGW("Recycling channel for VSYNC injection.");
+        }
+
+        mLooper->addFd(
+                tube.getFd(), 0, Looper::EVENT_INPUT,
+                [](int, int, void* data) {
+                    reinterpret_cast<MessageQueue*>(data)->injectorCallback();
+                    return 1; // Keep registration.
+                },
+                this);
     }
+
+    std::lock_guard lock(mInjector.mutex);
+    mInjector.connection = std::move(connection);
 }
 
 void MessageQueue::vsyncCallback(nsecs_t vsyncTime, nsecs_t targetWakeupTime, nsecs_t readyTime) {
@@ -149,29 +165,31 @@
 
 void MessageQueue::invalidate() {
     ATRACE_CALL();
-    if (mEvents) {
-        mEvents->requestNextVsync();
-    } else {
-        std::lock_guard lock(mVsync.mutex);
-        mVsync.mScheduled = true;
-        mVsync.registration->schedule({mVsync.workDuration.get().count(), /*readyDuration=*/0,
-                                       mVsync.lastCallbackTime.count()});
+
+    {
+        std::lock_guard lock(mInjector.mutex);
+        if (CC_UNLIKELY(mInjector.connection)) {
+            ALOGD("%s while injecting VSYNC", __FUNCTION__);
+            mInjector.connection->requestNextVsync();
+            return;
+        }
     }
+
+    std::lock_guard lock(mVsync.mutex);
+    mVsync.mScheduled = true;
+    mVsync.registration->schedule({.workDuration = mVsync.workDuration.get().count(),
+                                   .readyDuration = 0,
+                                   .earliestVsync = mVsync.lastCallbackTime.count()});
 }
 
 void MessageQueue::refresh() {
     mHandler->dispatchRefresh();
 }
 
-int MessageQueue::cb_eventReceiver(int fd, int events, void* data) {
-    MessageQueue* queue = reinterpret_cast<MessageQueue*>(data);
-    return queue->eventReceiver(fd, events);
-}
-
-int MessageQueue::eventReceiver(int /*fd*/, int /*events*/) {
+void MessageQueue::injectorCallback() {
     ssize_t n;
     DisplayEventReceiver::Event buffer[8];
-    while ((n = DisplayEventReceiver::getEvents(&mEventTube, buffer, 8)) > 0) {
+    while ((n = DisplayEventReceiver::getEvents(&mInjector.tube, buffer, 8)) > 0) {
         for (int i = 0; i < n; i++) {
             if (buffer[i].header.type == DisplayEventReceiver::DISPLAY_EVENT_VSYNC) {
                 mHandler->dispatchInvalidate(buffer[i].vsync.vsyncId,
@@ -180,8 +198,6 @@
             }
         }
     }
-    return 1;
 }
 
 } // namespace android::impl
-