Revert "Revert "Send multiple scheduler frame timelines.""

This reverts commit caaa47d60b83670206dcd3c34382719b1f247ab5.

Reason for revert: Fix the reverted CL in 2nd CL.

Bug: 198192508
Bug: 204941507
Test: See 2nd CL.

Change-Id: I15c693c2e0a82ef81a490319da11871bd74298b3
diff --git a/services/surfaceflinger/Scheduler/EventThread.cpp b/services/surfaceflinger/Scheduler/EventThread.cpp
index 2bdcaf6..e07eae7 100644
--- a/services/surfaceflinger/Scheduler/EventThread.cpp
+++ b/services/surfaceflinger/Scheduler/EventThread.cpp
@@ -355,14 +355,7 @@
     std::lock_guard<std::mutex> lock(mMutex);
 
     LOG_FATAL_IF(!mVSyncState);
-    const int64_t vsyncId = [&] {
-        if (mTokenManager != nullptr) {
-            return mTokenManager->generateTokenForPredictions(
-                    {timestamp, deadlineTimestamp, expectedVSyncTimestamp});
-        }
-        return FrameTimelineInfo::INVALID_VSYNC_ID;
-    }();
-
+    const int64_t vsyncId = generateToken(timestamp, deadlineTimestamp, expectedVSyncTimestamp);
     mPendingEvents.push_back(makeVSync(mVSyncState->displayId, timestamp, ++mVSyncState->count,
                                        expectedVSyncTimestamp, deadlineTimestamp, vsyncId));
     mCondition.notify_all();
@@ -567,12 +560,48 @@
     }
 }
 
+int64_t EventThread::generateToken(nsecs_t timestamp, nsecs_t expectedVSyncTimestamp,
+                                   nsecs_t deadlineTimestamp) const {
+    if (mTokenManager != nullptr) {
+        return mTokenManager->generateTokenForPredictions(
+                {timestamp, deadlineTimestamp, expectedVSyncTimestamp});
+    }
+    return FrameTimelineInfo::INVALID_VSYNC_ID;
+}
+
+void EventThread::generateFrameTimeline(DisplayEventReceiver::Event& event) const {
+    // Add 1 to ensure the preferredFrameTimelineIndex entry (when multiplier == 0) is included.
+    for (int multiplier = -DisplayEventReceiver::kFrameTimelinesLength + 1, currentIndex = 0;
+         currentIndex < DisplayEventReceiver::kFrameTimelinesLength; multiplier++) {
+        nsecs_t deadline = event.vsync.deadlineTimestamp + multiplier * event.vsync.frameInterval;
+        // Valid possible frame timelines must have future values.
+        if (deadline > event.header.timestamp) {
+            if (multiplier == 0) {
+                event.vsync.preferredFrameTimelineIndex = currentIndex;
+                event.vsync.frameTimelines[currentIndex] =
+                        {.vsyncId = event.vsync.vsyncId,
+                         .deadlineTimestamp = event.vsync.deadlineTimestamp,
+                         .expectedVSyncTimestamp = event.vsync.expectedVSyncTimestamp};
+            } else {
+                nsecs_t expectedVSync =
+                        event.vsync.expectedVSyncTimestamp + multiplier * event.vsync.frameInterval;
+                event.vsync.frameTimelines[currentIndex] =
+                        {.vsyncId = generateToken(event.header.timestamp, expectedVSync, deadline),
+                         .deadlineTimestamp = deadline,
+                         .expectedVSyncTimestamp = expectedVSync};
+            }
+            currentIndex++;
+        }
+    }
+}
+
 void EventThread::dispatchEvent(const DisplayEventReceiver::Event& event,
                                 const DisplayEventConsumers& consumers) {
     for (const auto& consumer : consumers) {
         DisplayEventReceiver::Event copy = event;
         if (event.header.type == DisplayEventReceiver::DISPLAY_EVENT_VSYNC) {
             copy.vsync.frameInterval = mGetVsyncPeriodFunction(consumer->mOwnerUid);
+            generateFrameTimeline(copy);
         }
         switch (consumer->postEvent(copy)) {
             case NO_ERROR:
diff --git a/services/surfaceflinger/Scheduler/EventThread.h b/services/surfaceflinger/Scheduler/EventThread.h
index 9265a25..73ae5dc 100644
--- a/services/surfaceflinger/Scheduler/EventThread.h
+++ b/services/surfaceflinger/Scheduler/EventThread.h
@@ -204,6 +204,10 @@
     void onVSyncEvent(nsecs_t timestamp, nsecs_t expectedVSyncTimestamp,
                       nsecs_t deadlineTimestamp) override;
 
+    int64_t generateToken(nsecs_t timestamp, nsecs_t expectedVSyncTimestamp,
+                          nsecs_t deadlineTimestamp) const;
+    void generateFrameTimeline(DisplayEventReceiver::Event& event) const;
+
     const std::unique_ptr<VSyncSource> mVSyncSource GUARDED_BY(mMutex);
     frametimeline::TokenManager* const mTokenManager;
 
diff --git a/services/surfaceflinger/tests/unittests/EventThreadTest.cpp b/services/surfaceflinger/tests/unittests/EventThreadTest.cpp
index 28d0222..cb690aa 100644
--- a/services/surfaceflinger/tests/unittests/EventThreadTest.cpp
+++ b/services/surfaceflinger/tests/unittests/EventThreadTest.cpp
@@ -28,6 +28,7 @@
 
 #include "AsyncCallRecorder.h"
 #include "DisplayHardware/DisplayMode.h"
+#include "FrameTimeline.h"
 #include "Scheduler/EventThread.h"
 
 using namespace std::chrono_literals;
@@ -96,6 +97,8 @@
                                               ConnectionEventRecorder& connectionEventRecorder,
                                               nsecs_t expectedTimestamp, unsigned expectedCount);
     void expectVsyncEventReceivedByConnection(nsecs_t expectedTimestamp, unsigned expectedCount);
+    void expectVsyncEventFrameTimelinesCorrect(nsecs_t expectedTimestamp,
+                                               nsecs_t preferredDeadline);
     void expectHotplugEventReceivedByConnection(PhysicalDisplayId expectedDisplayId,
                                                 bool expectedConnected);
     void expectConfigChangedEventReceivedByConnection(PhysicalDisplayId expectedDisplayId,
@@ -120,6 +123,7 @@
     std::unique_ptr<impl::EventThread> mThread;
     sp<MockEventThreadConnection> mConnection;
     sp<MockEventThreadConnection> mThrottledConnection;
+    std::unique_ptr<frametimeline::impl::TokenManager> mTokenManager;
 
     static constexpr uid_t mConnectionUid = 443;
     static constexpr uid_t mThrottledConnectionUid = 177;
@@ -173,8 +177,8 @@
         return VSYNC_PERIOD.count();
     };
 
-    mThread = std::make_unique<impl::EventThread>(std::move(source),
-                                                  /*tokenManager=*/nullptr,
+    mTokenManager = std::make_unique<frametimeline::impl::TokenManager>();
+    mThread = std::make_unique<impl::EventThread>(std::move(source), mTokenManager.get(),
                                                   mInterceptVSyncCallRecorder.getInvocable(),
                                                   throttleVsync, getVsyncPeriod);
 
@@ -247,6 +251,36 @@
                                          expectedCount);
 }
 
+void EventThreadTest::expectVsyncEventFrameTimelinesCorrect(nsecs_t expectedTimestamp,
+                                                            nsecs_t preferredDeadline) {
+    auto args = mConnectionEventCallRecorder.waitForCall();
+    ASSERT_TRUE(args.has_value()) << " did not receive an event for timestamp "
+                                  << expectedTimestamp;
+    const auto& event = std::get<0>(args.value());
+    for (int i = 0; i < DisplayEventReceiver::kFrameTimelinesLength; i++) {
+        if (i > 0) {
+            EXPECT_GT(event.vsync.frameTimelines[i].deadlineTimestamp,
+                      event.vsync.frameTimelines[i - 1].deadlineTimestamp)
+                    << "Deadline timestamp out of order for frame timeline " << i;
+            EXPECT_GT(event.vsync.frameTimelines[i].expectedVSyncTimestamp,
+                      event.vsync.frameTimelines[i - 1].expectedVSyncTimestamp)
+                    << "Expected vsync timestamp out of order for frame timeline " << i;
+        }
+        if (event.vsync.frameTimelines[i].deadlineTimestamp == preferredDeadline) {
+            EXPECT_EQ(i, event.vsync.preferredFrameTimelineIndex)
+                    << "Preferred frame timeline index should be " << i;
+            // For the platform-preferred frame timeline, the vsync ID is 0 because the first frame
+            // timeline is made before the rest.
+            EXPECT_EQ(0, event.vsync.frameTimelines[i].vsyncId)
+                    << "Vsync ID incorrect for frame timeline " << i;
+        } else {
+            // Vsync ID 0 is used for the preferred frame timeline.
+            EXPECT_EQ(i + 1, event.vsync.frameTimelines[i].vsyncId)
+                    << "Vsync ID incorrect for frame timeline " << i;
+        }
+    }
+}
+
 void EventThreadTest::expectHotplugEventReceivedByConnection(PhysicalDisplayId expectedDisplayId,
                                                              bool expectedConnected) {
     auto args = mConnectionEventCallRecorder.waitForCall();
@@ -344,6 +378,19 @@
     expectVSyncSetEnabledCallReceived(false);
 }
 
+TEST_F(EventThreadTest, requestNextVsyncEventFrameTimelinesCorrect) {
+    // Signal that we want the next vsync event to be posted to the connection
+    mThread->requestNextVsync(mConnection);
+
+    expectVSyncSetEnabledCallReceived(true);
+
+    // Use the received callback to signal a vsync event.
+    // The interceptor should receive the event, as well as the connection.
+    mCallback->onVSyncEvent(123, 456, 789);
+    expectInterceptCallReceived(123);
+    expectVsyncEventFrameTimelinesCorrect(123, 789);
+}
+
 TEST_F(EventThreadTest, setVsyncRateZeroPostsNoVSyncEventsToThatConnection) {
     // Create a first connection, register it, and request a vsync rate of zero.
     ConnectionEventRecorder firstConnectionEventRecorder{0};