Add inputEventId to SurfaceFrame

SurfaceFrame will now be aware of the id of the input event that caused
the current frame.

The flow of input event id is inputflinger -> app -> surfaceflinger.
Here, we are adding the 'inputEventId' parameter to the
'setFrameTimelineVsync' call. This call will now be responsible for
setting two pieces of information: the vsync id, and the input event id.
Since it will no longer be limited to the vsync id, we rename this call
to "setFrameTimelineInfo".

Once the inputEventId is stored in SurfaceFrame, we will add a binder
call to send the frame timing information to inputflinger (separate,
future CL). This will allow input to reconstruct the entire sequence of
events (at what time was input event getting processed in system_server,
app, and surfaceflinger) and will provide the ability to measure
end-to-end touch latency.

In a separate change, we will also add ATRACE calls to allow manual /
script-based latency analysis for local debugging. We will now know
which input event is being processed in surfaceflinger.

Bug: 169866723
Bug: 129481165
Design doc: https://docs.google.com/document/d/1G3bLaZYSmbe6AKcL-6ZChvrw_B_LXEz29Z6Ed9QoYXY/edit#
Test: atest WMShellUnitTests SurfaceParcelable_test libgui_test IPC_test SurfaceFlinger_test

Change-Id: If7e0eee82603b38b396b53ad7ced660973efcb50
Merged-In: If7e0eee82603b38b396b53ad7ced660973efcb50
diff --git a/libs/gui/Android.bp b/libs/gui/Android.bp
index 38ae353..fa5044c 100644
--- a/libs/gui/Android.bp
+++ b/libs/gui/Android.bp
@@ -49,6 +49,7 @@
 
     srcs: [
         ":framework_native_aidl",
+        ":inputconstants_aidl",
         ":libgui_aidl",
         ":libgui_bufferqueue_sources",
 
@@ -62,6 +63,7 @@
         "DebugEGLImageTracker.cpp",
         "DisplayEventDispatcher.cpp",
         "DisplayEventReceiver.cpp",
+        "FrameTimelineInfo.cpp",
         "GLConsumer.cpp",
         "IConsumerListener.cpp",
         "IDisplayEventConnection.cpp",
@@ -154,6 +156,7 @@
     defaults: ["libgui_bufferqueue-defaults"],
 
     srcs: [
+        ":inputconstants_aidl",
         ":libgui_aidl",
         ":libgui_bufferqueue_sources",
     ],
diff --git a/libs/gui/BLASTBufferQueue.cpp b/libs/gui/BLASTBufferQueue.cpp
index 42d2895..c62d9ad 100644
--- a/libs/gui/BLASTBufferQueue.cpp
+++ b/libs/gui/BLASTBufferQueue.cpp
@@ -370,9 +370,9 @@
     }
     t->setFrameNumber(mSurfaceControl, bufferItem.mFrameNumber);
 
-    if (!mNextFrameTimelineVsyncIdQueue.empty()) {
-        t->setFrameTimelineVsync(mSurfaceControl, mNextFrameTimelineVsyncIdQueue.front());
-        mNextFrameTimelineVsyncIdQueue.pop();
+    if (!mNextFrameTimelineInfoQueue.empty()) {
+        t->setFrameTimelineInfo(mSurfaceControl, mNextFrameTimelineInfoQueue.front());
+        mNextFrameTimelineInfoQueue.pop();
     }
 
     if (mAutoRefresh != bufferItem.mAutoRefresh) {
@@ -534,8 +534,8 @@
         return mBbq->setFrameRate(frameRate, compatibility, shouldBeSeamless);
     }
 
-    status_t setFrameTimelineVsync(int64_t frameTimelineVsyncId) override {
-        return mBbq->setFrameTimelineVsync(frameTimelineVsyncId);
+    status_t setFrameTimelineInfo(const FrameTimelineInfo& frameTimelineInfo) override {
+        return mBbq->setFrameTimelineInfo(frameTimelineInfo);
     }
 };
 
@@ -549,9 +549,9 @@
     return t.setFrameRate(mSurfaceControl, frameRate, compatibility, shouldBeSeamless).apply();
 }
 
-status_t BLASTBufferQueue::setFrameTimelineVsync(int64_t frameTimelineVsyncId) {
+status_t BLASTBufferQueue::setFrameTimelineInfo(const FrameTimelineInfo& frameTimelineInfo) {
     std::unique_lock _lock{mMutex};
-    mNextFrameTimelineVsyncIdQueue.push(frameTimelineVsyncId);
+    mNextFrameTimelineInfoQueue.push(frameTimelineInfo);
     return OK;
 }
 
diff --git a/libs/gui/FrameTimelineInfo.cpp b/libs/gui/FrameTimelineInfo.cpp
new file mode 100644
index 0000000..f400774
--- /dev/null
+++ b/libs/gui/FrameTimelineInfo.cpp
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "FrameTimelineInfo"
+
+#include <inttypes.h>
+
+#include <android/os/IInputConstants.h>
+#include <gui/FrameTimelineInfo.h>
+#include <gui/LayerState.h>
+#include <utils/Errors.h>
+
+#include <cmath>
+
+using android::os::IInputConstants;
+
+namespace android {
+
+status_t FrameTimelineInfo::write(Parcel& output) const {
+    SAFE_PARCEL(output.writeInt64, vsyncId);
+    SAFE_PARCEL(output.writeInt32, inputEventId);
+    return NO_ERROR;
+}
+
+status_t FrameTimelineInfo::read(const Parcel& input) {
+    SAFE_PARCEL(input.readInt64, &vsyncId);
+    SAFE_PARCEL(input.readInt32, &inputEventId);
+    return NO_ERROR;
+}
+
+void FrameTimelineInfo::merge(const FrameTimelineInfo& other) {
+    // When merging vsync Ids we take the oldest valid one
+    if (vsyncId != INVALID_VSYNC_ID && other.vsyncId != INVALID_VSYNC_ID) {
+        if (other.vsyncId > vsyncId) {
+            vsyncId = other.vsyncId;
+            inputEventId = other.inputEventId;
+        }
+    } else if (vsyncId == INVALID_VSYNC_ID) {
+        vsyncId = other.vsyncId;
+        inputEventId = other.inputEventId;
+    }
+}
+
+void FrameTimelineInfo::clear() {
+    vsyncId = INVALID_VSYNC_ID;
+    inputEventId = IInputConstants::INVALID_INPUT_EVENT_ID;
+}
+
+}; // namespace android
diff --git a/libs/gui/ISurfaceComposer.cpp b/libs/gui/ISurfaceComposer.cpp
index a8d6832..f68f3e1 100644
--- a/libs/gui/ISurfaceComposer.cpp
+++ b/libs/gui/ISurfaceComposer.cpp
@@ -68,16 +68,19 @@
         return interface_cast<ISurfaceComposerClient>(reply.readStrongBinder());
     }
 
-    virtual status_t setTransactionState(
-            int64_t frameTimelineVsyncId, const Vector<ComposerState>& state,
-            const Vector<DisplayState>& displays, uint32_t flags, const sp<IBinder>& applyToken,
-            const InputWindowCommands& commands, int64_t desiredPresentTime, bool isAutoTimestamp,
-            const client_cache_t& uncacheBuffer, bool hasListenerCallbacks,
-            const std::vector<ListenerCallbacks>& listenerCallbacks, uint64_t transactionId) {
+    status_t setTransactionState(const FrameTimelineInfo& frameTimelineInfo,
+                                 const Vector<ComposerState>& state,
+                                 const Vector<DisplayState>& displays, uint32_t flags,
+                                 const sp<IBinder>& applyToken, const InputWindowCommands& commands,
+                                 int64_t desiredPresentTime, bool isAutoTimestamp,
+                                 const client_cache_t& uncacheBuffer, bool hasListenerCallbacks,
+                                 const std::vector<ListenerCallbacks>& listenerCallbacks,
+                                 uint64_t transactionId) override {
         Parcel data, reply;
         data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
 
-        SAFE_PARCEL(data.writeInt64, frameTimelineVsyncId);
+        SAFE_PARCEL(frameTimelineInfo.write, data);
+
         SAFE_PARCEL(data.writeUint32, static_cast<uint32_t>(state.size()));
         for (const auto& s : state) {
             SAFE_PARCEL(s.write, data);
@@ -108,15 +111,14 @@
         return remote()->transact(BnSurfaceComposer::SET_TRANSACTION_STATE, data, &reply);
     }
 
-    virtual void bootFinished()
-    {
+    void bootFinished() override {
         Parcel data, reply;
         data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
         remote()->transact(BnSurfaceComposer::BOOT_FINISHED, data, &reply);
     }
 
-    virtual status_t captureDisplay(const DisplayCaptureArgs& args,
-                                    const sp<IScreenCaptureListener>& captureListener) {
+    status_t captureDisplay(const DisplayCaptureArgs& args,
+                            const sp<IScreenCaptureListener>& captureListener) override {
         Parcel data, reply;
         data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
         SAFE_PARCEL(args.write, data);
@@ -125,8 +127,8 @@
         return remote()->transact(BnSurfaceComposer::CAPTURE_DISPLAY, data, &reply);
     }
 
-    virtual status_t captureDisplay(uint64_t displayOrLayerStack,
-                                    const sp<IScreenCaptureListener>& captureListener) {
+    status_t captureDisplay(uint64_t displayOrLayerStack,
+                            const sp<IScreenCaptureListener>& captureListener) override {
         Parcel data, reply;
         data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
         SAFE_PARCEL(data.writeUint64, displayOrLayerStack);
@@ -135,8 +137,8 @@
         return remote()->transact(BnSurfaceComposer::CAPTURE_DISPLAY_BY_ID, data, &reply);
     }
 
-    virtual status_t captureLayers(const LayerCaptureArgs& args,
-                                   const sp<IScreenCaptureListener>& captureListener) {
+    status_t captureLayers(const LayerCaptureArgs& args,
+                           const sp<IScreenCaptureListener>& captureListener) override {
         Parcel data, reply;
         data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
         SAFE_PARCEL(args.write, data);
@@ -145,9 +147,8 @@
         return remote()->transact(BnSurfaceComposer::CAPTURE_LAYERS, data, &reply);
     }
 
-    virtual bool authenticateSurfaceTexture(
-            const sp<IGraphicBufferProducer>& bufferProducer) const
-    {
+    bool authenticateSurfaceTexture(
+            const sp<IGraphicBufferProducer>& bufferProducer) const override {
         Parcel data, reply;
         int err = NO_ERROR;
         err = data.writeInterfaceToken(
@@ -180,8 +181,7 @@
         return result != 0;
     }
 
-    virtual status_t getSupportedFrameTimestamps(
-            std::vector<FrameEvent>* outSupported) const {
+    status_t getSupportedFrameTimestamps(std::vector<FrameEvent>* outSupported) const override {
         if (!outSupported) {
             return UNEXPECTED_NULL;
         }
@@ -224,8 +224,8 @@
         return NO_ERROR;
     }
 
-    virtual sp<IDisplayEventConnection> createDisplayEventConnection(
-            VsyncSource vsyncSource, EventRegistrationFlags eventRegistration) {
+    sp<IDisplayEventConnection> createDisplayEventConnection(
+            VsyncSource vsyncSource, EventRegistrationFlags eventRegistration) override {
         Parcel data, reply;
         sp<IDisplayEventConnection> result;
         int err = data.writeInterfaceToken(
@@ -247,8 +247,7 @@
         return result;
     }
 
-    virtual sp<IBinder> createDisplay(const String8& displayName, bool secure)
-    {
+    sp<IBinder> createDisplay(const String8& displayName, bool secure) override {
         Parcel data, reply;
         data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
         status_t status = data.writeString8(displayName);
@@ -272,15 +271,14 @@
         return display;
     }
 
-    virtual void destroyDisplay(const sp<IBinder>& display)
-    {
+    void destroyDisplay(const sp<IBinder>& display) override {
         Parcel data, reply;
         data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
         data.writeStrongBinder(display);
         remote()->transact(BnSurfaceComposer::DESTROY_DISPLAY, data, &reply);
     }
 
-    virtual std::vector<PhysicalDisplayId> getPhysicalDisplayIds() const {
+    std::vector<PhysicalDisplayId> getPhysicalDisplayIds() const override {
         Parcel data, reply;
         data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
         if (remote()->transact(BnSurfaceComposer::GET_PHYSICAL_DISPLAY_IDS, data, &reply) ==
@@ -297,7 +295,7 @@
         return {};
     }
 
-    virtual sp<IBinder> getPhysicalDisplayToken(PhysicalDisplayId displayId) const {
+    sp<IBinder> getPhysicalDisplayToken(PhysicalDisplayId displayId) const override {
         Parcel data, reply;
         data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
         data.writeUint64(displayId.value);
@@ -305,8 +303,7 @@
         return reply.readStrongBinder();
     }
 
-    virtual void setPowerMode(const sp<IBinder>& display, int mode)
-    {
+    void setPowerMode(const sp<IBinder>& display, int mode) override {
         Parcel data, reply;
         data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
         data.writeStrongBinder(display);
@@ -314,7 +311,7 @@
         remote()->transact(BnSurfaceComposer::SET_POWER_MODE, data, &reply);
     }
 
-    virtual status_t getDisplayState(const sp<IBinder>& display, ui::DisplayState* state) {
+    status_t getDisplayState(const sp<IBinder>& display, ui::DisplayState* state) override {
         Parcel data, reply;
         data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
         data.writeStrongBinder(display);
@@ -326,7 +323,7 @@
         return result;
     }
 
-    virtual status_t getDisplayInfo(const sp<IBinder>& display, DisplayInfo* info) {
+    status_t getDisplayInfo(const sp<IBinder>& display, DisplayInfo* info) override {
         Parcel data, reply;
         data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
         data.writeStrongBinder(display);
@@ -336,7 +333,8 @@
         return reply.read(*info);
     }
 
-    virtual status_t getDisplayConfigs(const sp<IBinder>& display, Vector<DisplayConfig>* configs) {
+    status_t getDisplayConfigs(const sp<IBinder>& display,
+                               Vector<DisplayConfig>* configs) override {
         Parcel data, reply;
         data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
         data.writeStrongBinder(display);
@@ -354,9 +352,7 @@
         return result;
     }
 
-    virtual status_t getDisplayStats(const sp<IBinder>& display,
-            DisplayStatInfo* stats)
-    {
+    status_t getDisplayStats(const sp<IBinder>& display, DisplayStatInfo* stats) override {
         Parcel data, reply;
         data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
         data.writeStrongBinder(display);
@@ -370,8 +366,7 @@
         return result;
     }
 
-    virtual int getActiveConfig(const sp<IBinder>& display)
-    {
+    int getActiveConfig(const sp<IBinder>& display) override {
         Parcel data, reply;
         data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
         data.writeStrongBinder(display);
@@ -379,8 +374,8 @@
         return reply.readInt32();
     }
 
-    virtual status_t getDisplayColorModes(const sp<IBinder>& display,
-            Vector<ColorMode>* outColorModes) {
+    status_t getDisplayColorModes(const sp<IBinder>& display,
+                                  Vector<ColorMode>* outColorModes) override {
         Parcel data, reply;
         status_t result = data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
         if (result != NO_ERROR) {
@@ -409,8 +404,8 @@
         return result;
     }
 
-    virtual status_t getDisplayNativePrimaries(const sp<IBinder>& display,
-            ui::DisplayPrimaries& primaries) {
+    status_t getDisplayNativePrimaries(const sp<IBinder>& display,
+                                       ui::DisplayPrimaries& primaries) override {
         Parcel data, reply;
         status_t result = data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
         if (result != NO_ERROR) {
@@ -435,7 +430,7 @@
         return result;
     }
 
-    virtual ColorMode getActiveColorMode(const sp<IBinder>& display) {
+    ColorMode getActiveColorMode(const sp<IBinder>& display) override {
         Parcel data, reply;
         status_t result = data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
         if (result != NO_ERROR) {
@@ -455,8 +450,7 @@
         return static_cast<ColorMode>(reply.readInt32());
     }
 
-    virtual status_t setActiveColorMode(const sp<IBinder>& display,
-            ColorMode colorMode) {
+    status_t setActiveColorMode(const sp<IBinder>& display, ColorMode colorMode) override {
         Parcel data, reply;
         status_t result = data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
         if (result != NO_ERROR) {
@@ -481,8 +475,8 @@
         return static_cast<status_t>(reply.readInt32());
     }
 
-    virtual status_t getAutoLowLatencyModeSupport(const sp<IBinder>& display,
-                                                  bool* outSupport) const {
+    status_t getAutoLowLatencyModeSupport(const sp<IBinder>& display,
+                                          bool* outSupport) const override {
         Parcel data, reply;
         data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
         status_t result = data.writeStrongBinder(display);
@@ -499,7 +493,7 @@
         return reply.readBool(outSupport);
     }
 
-    virtual void setAutoLowLatencyMode(const sp<IBinder>& display, bool on) {
+    void setAutoLowLatencyMode(const sp<IBinder>& display, bool on) override {
         Parcel data, reply;
         status_t result = data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
         if (result != NO_ERROR) {
@@ -524,7 +518,8 @@
         }
     }
 
-    virtual status_t getGameContentTypeSupport(const sp<IBinder>& display, bool* outSupport) const {
+    status_t getGameContentTypeSupport(const sp<IBinder>& display,
+                                       bool* outSupport) const override {
         Parcel data, reply;
         data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
         status_t result = data.writeStrongBinder(display);
@@ -540,7 +535,7 @@
         return reply.readBool(outSupport);
     }
 
-    virtual void setGameContentType(const sp<IBinder>& display, bool on) {
+    void setGameContentType(const sp<IBinder>& display, bool on) override {
         Parcel data, reply;
         status_t result = data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
         if (result != NO_ERROR) {
@@ -563,7 +558,7 @@
         }
     }
 
-    virtual status_t clearAnimationFrameStats() {
+    status_t clearAnimationFrameStats() override {
         Parcel data, reply;
         status_t result = data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
         if (result != NO_ERROR) {
@@ -578,7 +573,7 @@
         return reply.readInt32();
     }
 
-    virtual status_t getAnimationFrameStats(FrameStats* outStats) const {
+    status_t getAnimationFrameStats(FrameStats* outStats) const override {
         Parcel data, reply;
         data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
         remote()->transact(BnSurfaceComposer::GET_ANIMATION_FRAME_STATS, data, &reply);
@@ -586,8 +581,8 @@
         return reply.readInt32();
     }
 
-    virtual status_t getHdrCapabilities(const sp<IBinder>& display,
-            HdrCapabilities* outCapabilities) const {
+    status_t getHdrCapabilities(const sp<IBinder>& display,
+                                HdrCapabilities* outCapabilities) const override {
         Parcel data, reply;
         data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
         status_t result = data.writeStrongBinder(display);
@@ -608,7 +603,7 @@
         return result;
     }
 
-    virtual status_t enableVSyncInjections(bool enable) {
+    status_t enableVSyncInjections(bool enable) override {
         Parcel data, reply;
         status_t result = data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
         if (result != NO_ERROR) {
@@ -629,7 +624,7 @@
         return result;
     }
 
-    virtual status_t injectVSync(nsecs_t when) {
+    status_t injectVSync(nsecs_t when) override {
         Parcel data, reply;
         status_t result = data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
         if (result != NO_ERROR) {
@@ -650,7 +645,7 @@
         return result;
     }
 
-    virtual status_t getLayerDebugInfo(std::vector<LayerDebugInfo>* outLayers) {
+    status_t getLayerDebugInfo(std::vector<LayerDebugInfo>* outLayers) override {
         if (!outLayers) {
             return UNEXPECTED_NULL;
         }
@@ -680,10 +675,10 @@
         return reply.readParcelableVector(outLayers);
     }
 
-    virtual status_t getCompositionPreference(ui::Dataspace* defaultDataspace,
-                                              ui::PixelFormat* defaultPixelFormat,
-                                              ui::Dataspace* wideColorGamutDataspace,
-                                              ui::PixelFormat* wideColorGamutPixelFormat) const {
+    status_t getCompositionPreference(ui::Dataspace* defaultDataspace,
+                                      ui::PixelFormat* defaultPixelFormat,
+                                      ui::Dataspace* wideColorGamutDataspace,
+                                      ui::PixelFormat* wideColorGamutPixelFormat) const override {
         Parcel data, reply;
         status_t error = data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
         if (error != NO_ERROR) {
@@ -703,7 +698,7 @@
         return error;
     }
 
-    virtual status_t getColorManagement(bool* outGetColorManagement) const {
+    status_t getColorManagement(bool* outGetColorManagement) const override {
         Parcel data, reply;
         data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
         remote()->transact(BnSurfaceComposer::GET_COLOR_MANAGEMENT, data, &reply);
@@ -715,10 +710,10 @@
         return err;
     }
 
-    virtual status_t getDisplayedContentSamplingAttributes(const sp<IBinder>& display,
-                                                           ui::PixelFormat* outFormat,
-                                                           ui::Dataspace* outDataspace,
-                                                           uint8_t* outComponentMask) const {
+    status_t getDisplayedContentSamplingAttributes(const sp<IBinder>& display,
+                                                   ui::PixelFormat* outFormat,
+                                                   ui::Dataspace* outDataspace,
+                                                   uint8_t* outComponentMask) const override {
         if (!outFormat || !outDataspace || !outComponentMask) return BAD_VALUE;
         Parcel data, reply;
         data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
@@ -752,8 +747,8 @@
         return error;
     }
 
-    virtual status_t setDisplayContentSamplingEnabled(const sp<IBinder>& display, bool enable,
-                                                      uint8_t componentMask, uint64_t maxFrames) {
+    status_t setDisplayContentSamplingEnabled(const sp<IBinder>& display, bool enable,
+                                              uint8_t componentMask, uint64_t maxFrames) override {
         Parcel data, reply;
         data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
         data.writeStrongBinder(display);
@@ -766,9 +761,9 @@
         return result;
     }
 
-    virtual status_t getDisplayedContentSample(const sp<IBinder>& display, uint64_t maxFrames,
-                                               uint64_t timestamp,
-                                               DisplayedFrameStats* outStats) const {
+    status_t getDisplayedContentSample(const sp<IBinder>& display, uint64_t maxFrames,
+                                       uint64_t timestamp,
+                                       DisplayedFrameStats* outStats) const override {
         if (!outStats) return BAD_VALUE;
 
         Parcel data, reply;
@@ -805,7 +800,7 @@
         return result;
     }
 
-    virtual status_t getProtectedContentSupport(bool* outSupported) const {
+    status_t getProtectedContentSupport(bool* outSupported) const override {
         Parcel data, reply;
         data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
         status_t error =
@@ -817,8 +812,8 @@
         return error;
     }
 
-    virtual status_t isWideColorDisplay(const sp<IBinder>& token,
-                                        bool* outIsWideColorDisplay) const {
+    status_t isWideColorDisplay(const sp<IBinder>& token,
+                                bool* outIsWideColorDisplay) const override {
         Parcel data, reply;
         status_t error = data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
         if (error != NO_ERROR) {
@@ -837,9 +832,8 @@
         return error;
     }
 
-    virtual status_t addRegionSamplingListener(const Rect& samplingArea,
-                                               const sp<IBinder>& stopLayerHandle,
-                                               const sp<IRegionSamplingListener>& listener) {
+    status_t addRegionSamplingListener(const Rect& samplingArea, const sp<IBinder>& stopLayerHandle,
+                                       const sp<IRegionSamplingListener>& listener) override {
         Parcel data, reply;
         status_t error = data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
         if (error != NO_ERROR) {
@@ -868,7 +862,7 @@
         return error;
     }
 
-    virtual status_t removeRegionSamplingListener(const sp<IRegionSamplingListener>& listener) {
+    status_t removeRegionSamplingListener(const sp<IRegionSamplingListener>& listener) override {
         Parcel data, reply;
         status_t error = data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
         if (error != NO_ERROR) {
@@ -888,12 +882,11 @@
         return error;
     }
 
-    virtual status_t setDesiredDisplayConfigSpecs(const sp<IBinder>& displayToken,
-                                                  int32_t defaultConfig, bool allowGroupSwitching,
-                                                  float primaryRefreshRateMin,
-                                                  float primaryRefreshRateMax,
-                                                  float appRequestRefreshRateMin,
-                                                  float appRequestRefreshRateMax) {
+    status_t setDesiredDisplayConfigSpecs(const sp<IBinder>& displayToken, int32_t defaultConfig,
+                                          bool allowGroupSwitching, float primaryRefreshRateMin,
+                                          float primaryRefreshRateMax,
+                                          float appRequestRefreshRateMin,
+                                          float appRequestRefreshRateMax) override {
         Parcel data, reply;
         status_t result = data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
         if (result != NO_ERROR) {
@@ -947,13 +940,12 @@
         return reply.readInt32();
     }
 
-    virtual status_t getDesiredDisplayConfigSpecs(const sp<IBinder>& displayToken,
-                                                  int32_t* outDefaultConfig,
-                                                  bool* outAllowGroupSwitching,
-                                                  float* outPrimaryRefreshRateMin,
-                                                  float* outPrimaryRefreshRateMax,
-                                                  float* outAppRequestRefreshRateMin,
-                                                  float* outAppRequestRefreshRateMax) {
+    status_t getDesiredDisplayConfigSpecs(const sp<IBinder>& displayToken,
+                                          int32_t* outDefaultConfig, bool* outAllowGroupSwitching,
+                                          float* outPrimaryRefreshRateMin,
+                                          float* outPrimaryRefreshRateMax,
+                                          float* outAppRequestRefreshRateMin,
+                                          float* outAppRequestRefreshRateMax) override {
         if (!outDefaultConfig || !outAllowGroupSwitching || !outPrimaryRefreshRateMin ||
             !outPrimaryRefreshRateMax || !outAppRequestRefreshRateMin ||
             !outAppRequestRefreshRateMax) {
@@ -1011,8 +1003,8 @@
         return reply.readInt32();
     }
 
-    virtual status_t getDisplayBrightnessSupport(const sp<IBinder>& displayToken,
-                                                 bool* outSupport) const {
+    status_t getDisplayBrightnessSupport(const sp<IBinder>& displayToken,
+                                         bool* outSupport) const override {
         Parcel data, reply;
         status_t error = data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
         if (error != NO_ERROR) {
@@ -1039,7 +1031,7 @@
         return NO_ERROR;
     }
 
-    virtual status_t setDisplayBrightness(const sp<IBinder>& displayToken, float brightness) {
+    status_t setDisplayBrightness(const sp<IBinder>& displayToken, float brightness) override {
         Parcel data, reply;
         status_t error = data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
         if (error != NO_ERROR) {
@@ -1064,7 +1056,7 @@
         return NO_ERROR;
     }
 
-    virtual status_t notifyPowerBoost(int32_t boostId) {
+    status_t notifyPowerBoost(int32_t boostId) override {
         Parcel data, reply;
         status_t error = data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
         if (error != NO_ERROR) {
@@ -1085,8 +1077,8 @@
         return NO_ERROR;
     }
 
-    virtual status_t setGlobalShadowSettings(const half4& ambientColor, const half4& spotColor,
-                                             float lightPosY, float lightPosZ, float lightRadius) {
+    status_t setGlobalShadowSettings(const half4& ambientColor, const half4& spotColor,
+                                     float lightPosY, float lightPosZ, float lightRadius) override {
         Parcel data, reply;
         status_t error = data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
         if (error != NO_ERROR) {
@@ -1114,8 +1106,8 @@
         return NO_ERROR;
     }
 
-    virtual status_t setFrameRate(const sp<IGraphicBufferProducer>& surface, float frameRate,
-                                  int8_t compatibility, bool shouldBeSeamless) {
+    status_t setFrameRate(const sp<IGraphicBufferProducer>& surface, float frameRate,
+                          int8_t compatibility, bool shouldBeSeamless) override {
         Parcel data, reply;
         status_t err = data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
         if (err != NO_ERROR) {
@@ -1156,7 +1148,7 @@
         return reply.readInt32();
     }
 
-    virtual status_t acquireFrameRateFlexibilityToken(sp<IBinder>* outToken) {
+    status_t acquireFrameRateFlexibilityToken(sp<IBinder>* outToken) override {
         if (!outToken) return BAD_VALUE;
 
         Parcel data, reply;
@@ -1191,40 +1183,34 @@
         return NO_ERROR;
     }
 
-    virtual status_t setFrameTimelineVsync(const sp<IGraphicBufferProducer>& surface,
-                                           int64_t frameTimelineVsyncId) {
+    status_t setFrameTimelineInfo(const sp<IGraphicBufferProducer>& surface,
+                                  const FrameTimelineInfo& frameTimelineInfo) override {
         Parcel data, reply;
         status_t err = data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
         if (err != NO_ERROR) {
-            ALOGE("setFrameTimelineVsync: failed writing interface token: %s (%d)", strerror(-err),
-                  -err);
+            ALOGE("%s: failed writing interface token: %s (%d)", __func__, strerror(-err), -err);
             return err;
         }
 
         err = data.writeStrongBinder(IInterface::asBinder(surface));
         if (err != NO_ERROR) {
-            ALOGE("setFrameTimelineVsync: failed writing strong binder: %s (%d)", strerror(-err),
-                  -err);
+            ALOGE("%s: failed writing strong binder: %s (%d)", __func__, strerror(-err), -err);
             return err;
         }
 
-        err = data.writeInt64(frameTimelineVsyncId);
-        if (err != NO_ERROR) {
-            ALOGE("setFrameTimelineVsync: failed writing int64_t: %s (%d)", strerror(-err), -err);
-            return err;
-        }
+        SAFE_PARCEL(frameTimelineInfo.write, data);
 
-        err = remote()->transact(BnSurfaceComposer::SET_FRAME_TIMELINE_VSYNC, data, &reply);
+        err = remote()->transact(BnSurfaceComposer::SET_FRAME_TIMELINE_INFO, data, &reply);
         if (err != NO_ERROR) {
-            ALOGE("setFrameTimelineVsync: failed to transact: %s (%d)", strerror(-err), err);
+            ALOGE("%s: failed to transact: %s (%d)", __func__, strerror(-err), err);
             return err;
         }
 
         return reply.readInt32();
     }
 
-    virtual status_t addTransactionTraceListener(
-            const sp<gui::ITransactionTraceListener>& listener) {
+    status_t addTransactionTraceListener(
+            const sp<gui::ITransactionTraceListener>& listener) override {
         Parcel data, reply;
         SAFE_PARCEL(data.writeInterfaceToken, ISurfaceComposer::getInterfaceDescriptor());
         SAFE_PARCEL(data.writeStrongBinder, IInterface::asBinder(listener));
@@ -1235,7 +1221,7 @@
     /**
      * Get priority of the RenderEngine in surface flinger.
      */
-    virtual int getGPUContextPriority() {
+    int getGPUContextPriority() override {
         Parcel data, reply;
         data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
         status_t err =
@@ -1269,8 +1255,9 @@
         case SET_TRANSACTION_STATE: {
             CHECK_INTERFACE(ISurfaceComposer, data, reply);
 
-            int64_t frameTimelineVsyncId;
-            SAFE_PARCEL(data.readInt64, &frameTimelineVsyncId);
+            FrameTimelineInfo frameTimelineInfo;
+            SAFE_PARCEL(frameTimelineInfo.read, data);
+
             uint32_t count = 0;
             SAFE_PARCEL_READ_SIZE(data.readUint32, &count, data.dataSize());
             Vector<ComposerState> state;
@@ -1324,10 +1311,10 @@
             uint64_t transactionId = -1;
             SAFE_PARCEL(data.readUint64, &transactionId);
 
-            return setTransactionState(frameTimelineVsyncId, state, displays, stateFlags,
-                                       applyToken, inputWindowCommands, desiredPresentTime,
-                                       isAutoTimestamp, uncachedBuffer, hasListenerCallbacks,
-                                       listenerCallbacks, transactionId);
+            return setTransactionState(frameTimelineInfo, state, displays, stateFlags, applyToken,
+                                       inputWindowCommands, desiredPresentTime, isAutoTimestamp,
+                                       uncachedBuffer, hasListenerCallbacks, listenerCallbacks,
+                                       transactionId);
         }
         case BOOT_FINISHED: {
             CHECK_INTERFACE(ISurfaceComposer, data, reply);
@@ -2078,30 +2065,26 @@
             }
             return NO_ERROR;
         }
-        case SET_FRAME_TIMELINE_VSYNC: {
+        case SET_FRAME_TIMELINE_INFO: {
             CHECK_INTERFACE(ISurfaceComposer, data, reply);
             sp<IBinder> binder;
             status_t err = data.readStrongBinder(&binder);
             if (err != NO_ERROR) {
-                ALOGE("setFrameTimelineVsync: failed to read strong binder: %s (%d)",
-                      strerror(-err), -err);
+                ALOGE("setFrameTimelineInfo: failed to read strong binder: %s (%d)", strerror(-err),
+                      -err);
                 return err;
             }
             sp<IGraphicBufferProducer> surface = interface_cast<IGraphicBufferProducer>(binder);
             if (!surface) {
-                ALOGE("setFrameTimelineVsync: failed to cast to IGraphicBufferProducer: %s (%d)",
+                ALOGE("setFrameTimelineInfo: failed to cast to IGraphicBufferProducer: %s (%d)",
                       strerror(-err), -err);
                 return err;
             }
-            int64_t frameTimelineVsyncId;
-            err = data.readInt64(&frameTimelineVsyncId);
-            if (err != NO_ERROR) {
-                ALOGE("setFrameTimelineVsync: failed to read int64_t: %s (%d)", strerror(-err),
-                      -err);
-                return err;
-            }
 
-            status_t result = setFrameTimelineVsync(surface, frameTimelineVsyncId);
+            FrameTimelineInfo frameTimelineInfo;
+            SAFE_PARCEL(frameTimelineInfo.read, data);
+
+            status_t result = setFrameTimelineInfo(surface, frameTimelineInfo);
             reply->writeInt32(result);
             return NO_ERROR;
         }
diff --git a/libs/gui/ITransactionCompletedListener.cpp b/libs/gui/ITransactionCompletedListener.cpp
index 1808571..0ded936 100644
--- a/libs/gui/ITransactionCompletedListener.cpp
+++ b/libs/gui/ITransactionCompletedListener.cpp
@@ -92,10 +92,8 @@
     return err;
 }
 
-JankData::JankData() :
-        frameVsyncId(ISurfaceComposer::INVALID_VSYNC_ID),
-        jankType(JankType::None) {
-}
+JankData::JankData()
+      : frameVsyncId(FrameTimelineInfo::INVALID_VSYNC_ID), jankType(JankType::None) {}
 
 status_t JankData::writeToParcel(Parcel* output) const {
     SAFE_PARCEL(output->writeInt64, frameVsyncId);
diff --git a/libs/gui/LayerState.cpp b/libs/gui/LayerState.cpp
index 2946aae..a4b054a 100644
--- a/libs/gui/LayerState.cpp
+++ b/libs/gui/LayerState.cpp
@@ -63,7 +63,7 @@
         shouldBeSeamless(true),
         fixedTransformHint(ui::Transform::ROT_INVALID),
         frameNumber(0),
-        frameTimelineVsyncId(ISurfaceComposer::INVALID_VSYNC_ID),
+        frameTimelineInfo(),
         autoRefresh(false) {
     matrix.dsdx = matrix.dtdy = 1.0f;
     matrix.dsdy = matrix.dtdx = 0.0f;
@@ -151,7 +151,7 @@
     SAFE_PARCEL(output.writeBool, shouldBeSeamless);
     SAFE_PARCEL(output.writeUint32, fixedTransformHint);
     SAFE_PARCEL(output.writeUint64, frameNumber);
-    SAFE_PARCEL(output.writeInt64, frameTimelineVsyncId);
+    SAFE_PARCEL(frameTimelineInfo.write, output);
     SAFE_PARCEL(output.writeBool, autoRefresh);
 
     SAFE_PARCEL(output.writeUint32, blurRegions.size());
@@ -270,7 +270,7 @@
     SAFE_PARCEL(input.readUint32, &tmpUint32);
     fixedTransformHint = static_cast<ui::Transform::RotationFlags>(tmpUint32);
     SAFE_PARCEL(input.readUint64, &frameNumber);
-    SAFE_PARCEL(input.readInt64, &frameTimelineVsyncId);
+    SAFE_PARCEL(frameTimelineInfo.read, input);
     SAFE_PARCEL(input.readBool, &autoRefresh);
 
     uint32_t numRegions = 0;
@@ -537,15 +537,9 @@
         what |= eFrameNumberChanged;
         frameNumber = other.frameNumber;
     }
-    if (other.what & eFrameTimelineVsyncChanged) {
-        // When merging vsync Ids we take the oldest valid one
-        if (frameTimelineVsyncId != ISurfaceComposer::INVALID_VSYNC_ID &&
-            other.frameTimelineVsyncId != ISurfaceComposer::INVALID_VSYNC_ID) {
-            frameTimelineVsyncId = std::max(frameTimelineVsyncId, other.frameTimelineVsyncId);
-        } else if (frameTimelineVsyncId == ISurfaceComposer::INVALID_VSYNC_ID) {
-            frameTimelineVsyncId = other.frameTimelineVsyncId;
-        }
-        what |= eFrameTimelineVsyncChanged;
+    if (other.what & eFrameTimelineInfoChanged) {
+        what |= eFrameTimelineInfoChanged;
+        frameTimelineInfo.merge(other.frameTimelineInfo);
     }
     if (other.what & eAutoRefreshChanged) {
         what |= eAutoRefreshChanged;
diff --git a/libs/gui/Surface.cpp b/libs/gui/Surface.cpp
index e82f0cc..59ad8d2 100644
--- a/libs/gui/Surface.cpp
+++ b/libs/gui/Surface.cpp
@@ -1496,8 +1496,8 @@
     case NATIVE_WINDOW_GET_LAST_QUEUED_BUFFER:
         res = dispatchGetLastQueuedBuffer(args);
         break;
-    case NATIVE_WINDOW_SET_FRAME_TIMELINE_VSYNC:
-        res = dispatchSetFrameTimelineVsync(args);
+    case NATIVE_WINDOW_SET_FRAME_TIMELINE_INFO:
+        res = dispatchSetFrameTimelineInfo(args);
         break;
     default:
         res = NAME_NOT_FOUND;
@@ -1806,12 +1806,13 @@
     return result;
 }
 
-int Surface::dispatchSetFrameTimelineVsync(va_list args) {
+int Surface::dispatchSetFrameTimelineInfo(va_list args) {
     ATRACE_CALL();
     auto frameTimelineVsyncId = static_cast<int64_t>(va_arg(args, int64_t));
+    auto inputEventId = static_cast<int32_t>(va_arg(args, int32_t));
 
-    ALOGV("Surface::dispatchSetFrameTimelineVsync");
-    return setFrameTimelineVsync(frameTimelineVsyncId);
+    ALOGV("Surface::%s", __func__);
+    return setFrameTimelineInfo({frameTimelineVsyncId, inputEventId});
 }
 
 bool Surface::transformToDisplayInverse() {
@@ -2579,9 +2580,8 @@
                                            shouldBeSeamless);
 }
 
-status_t Surface::setFrameTimelineVsync(int64_t frameTimelineVsyncId) {
-    return composerService()->setFrameTimelineVsync(mGraphicBufferProducer,
-        frameTimelineVsyncId);
+status_t Surface::setFrameTimelineInfo(const FrameTimelineInfo& frameTimelineInfo) {
+    return composerService()->setFrameTimelineInfo(mGraphicBufferProducer, frameTimelineInfo);
 }
 
 }; // namespace android
diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp
index 96c099b..a1bdc03 100644
--- a/libs/gui/SurfaceComposerClient.cpp
+++ b/libs/gui/SurfaceComposerClient.cpp
@@ -396,7 +396,7 @@
         mContainsBuffer(other.mContainsBuffer),
         mDesiredPresentTime(other.mDesiredPresentTime),
         mIsAutoTimestamp(other.mIsAutoTimestamp),
-        mFrameTimelineVsyncId(other.mFrameTimelineVsyncId),
+        mFrameTimelineInfo(other.mFrameTimelineInfo),
         mApplyToken(other.mApplyToken) {
     mDisplayStates = other.mDisplayStates;
     mComposerStates = other.mComposerStates;
@@ -427,7 +427,9 @@
     const bool containsBuffer = parcel->readBool();
     const int64_t desiredPresentTime = parcel->readInt64();
     const bool isAutoTimestamp = parcel->readBool();
-    const int64_t frameTimelineVsyncId = parcel->readInt64();
+    FrameTimelineInfo frameTimelineInfo;
+    SAFE_PARCEL(frameTimelineInfo.read, *parcel);
+
     sp<IBinder> applyToken;
     parcel->readNullableStrongBinder(&applyToken);
     size_t count = static_cast<size_t>(parcel->readUint32());
@@ -502,7 +504,7 @@
     mContainsBuffer = containsBuffer;
     mDesiredPresentTime = desiredPresentTime;
     mIsAutoTimestamp = isAutoTimestamp;
-    mFrameTimelineVsyncId = frameTimelineVsyncId;
+    mFrameTimelineInfo = frameTimelineInfo;
     mDisplayStates = displayStates;
     mListenerCallbacks = listenerCallbacks;
     mComposerStates = composerStates;
@@ -534,7 +536,7 @@
     parcel->writeBool(mContainsBuffer);
     parcel->writeInt64(mDesiredPresentTime);
     parcel->writeBool(mIsAutoTimestamp);
-    parcel->writeInt64(mFrameTimelineVsyncId);
+    SAFE_PARCEL(mFrameTimelineInfo.write, *parcel);
     parcel->writeStrongBinder(mApplyToken);
     parcel->writeUint32(static_cast<uint32_t>(mDisplayStates.size()));
     for (auto const& displayState : mDisplayStates) {
@@ -613,13 +615,7 @@
     mExplicitEarlyWakeupEnd = mExplicitEarlyWakeupEnd || other.mExplicitEarlyWakeupEnd;
     mApplyToken = other.mApplyToken;
 
-    // When merging vsync Ids we take the oldest one
-    if (mFrameTimelineVsyncId != ISurfaceComposer::INVALID_VSYNC_ID &&
-        other.mFrameTimelineVsyncId != ISurfaceComposer::INVALID_VSYNC_ID) {
-        mFrameTimelineVsyncId = std::max(mFrameTimelineVsyncId, other.mFrameTimelineVsyncId);
-    } else if (mFrameTimelineVsyncId == ISurfaceComposer::INVALID_VSYNC_ID) {
-        mFrameTimelineVsyncId = other.mFrameTimelineVsyncId;
-    }
+    mFrameTimelineInfo.merge(other.mFrameTimelineInfo);
 
     other.clear();
     return *this;
@@ -639,7 +635,7 @@
     mExplicitEarlyWakeupEnd = false;
     mDesiredPresentTime = 0;
     mIsAutoTimestamp = true;
-    mFrameTimelineVsyncId = ISurfaceComposer::INVALID_VSYNC_ID;
+    mFrameTimelineInfo.clear();
     mApplyToken = nullptr;
 }
 
@@ -651,9 +647,8 @@
     uncacheBuffer.id = cacheId;
 
     sp<IBinder> applyToken = IInterface::asBinder(TransactionCompletedListener::getIInstance());
-    sf->setTransactionState(ISurfaceComposer::INVALID_VSYNC_ID, {}, {}, 0, applyToken, {},
-                            systemTime(), true, uncacheBuffer, false, {},
-                            0 /* Undefined transactionId */);
+    sf->setTransactionState(FrameTimelineInfo{}, {}, {}, 0, applyToken, {}, systemTime(), true,
+                            uncacheBuffer, false, {}, 0 /* Undefined transactionId */);
 }
 
 void SurfaceComposerClient::Transaction::cacheBuffers() {
@@ -773,7 +768,7 @@
             ? mApplyToken
             : IInterface::asBinder(TransactionCompletedListener::getIInstance());
 
-    sf->setTransactionState(mFrameTimelineVsyncId, composerStates, displayStates, flags, applyToken,
+    sf->setTransactionState(mFrameTimelineInfo, composerStates, displayStates, flags, applyToken,
                             mInputWindowCommands, mDesiredPresentTime, mIsAutoTimestamp,
                             {} /*uncacheBuffer - only set in doUncacheBufferTransaction*/,
                             hasListenerCallbacks, listenerCallbacks, mId);
@@ -1549,22 +1544,22 @@
     return *this;
 }
 
-SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setFrameTimelineVsync(
-        int64_t frameTimelineVsyncId) {
-    mFrameTimelineVsyncId = frameTimelineVsyncId;
+SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setFrameTimelineInfo(
+        const FrameTimelineInfo& frameTimelineInfo) {
+    mFrameTimelineInfo = frameTimelineInfo;
     return *this;
 }
 
-SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setFrameTimelineVsync(
-        const sp<SurfaceControl>& sc, int64_t frameTimelineVsyncId) {
+SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setFrameTimelineInfo(
+        const sp<SurfaceControl>& sc, const FrameTimelineInfo& frameTimelineInfo) {
     layer_state_t* s = getLayerState(sc);
     if (!s) {
         mStatus = BAD_INDEX;
         return *this;
     }
 
-    s->what |= layer_state_t::eFrameTimelineVsyncChanged;
-    s->frameTimelineVsyncId = frameTimelineVsyncId;
+    s->what |= layer_state_t::eFrameTimelineInfoChanged;
+    s->frameTimelineInfo = frameTimelineInfo;
     return *this;
 }
 
diff --git a/libs/gui/include/gui/BLASTBufferQueue.h b/libs/gui/include/gui/BLASTBufferQueue.h
index 7f69bc4..fa3efe1 100644
--- a/libs/gui/include/gui/BLASTBufferQueue.h
+++ b/libs/gui/include/gui/BLASTBufferQueue.h
@@ -92,7 +92,7 @@
     void flushShadowQueue() { mFlushShadowQueue = true; }
 
     status_t setFrameRate(float frameRate, int8_t compatibility, bool shouldBeSeamless);
-    status_t setFrameTimelineVsync(int64_t frameTimelineVsyncId);
+    status_t setFrameTimelineInfo(const FrameTimelineInfo& info);
 
     virtual ~BLASTBufferQueue();
 
@@ -156,7 +156,7 @@
     // This is only relevant for shared buffer mode.
     bool mAutoRefresh GUARDED_BY(mMutex) = false;
 
-    std::queue<int64_t> mNextFrameTimelineVsyncIdQueue GUARDED_BY(mMutex);
+    std::queue<FrameTimelineInfo> mNextFrameTimelineInfoQueue GUARDED_BY(mMutex);
 
     // Last acquired buffer's scaling mode. This is used to check if we should update the blast
     // layer size immediately or wait until we get the next buffer. This will support scenarios
diff --git a/libs/gui/include/gui/DisplayEventDispatcher.h b/libs/gui/include/gui/DisplayEventDispatcher.h
index 5587acf..f446dd8 100644
--- a/libs/gui/include/gui/DisplayEventDispatcher.h
+++ b/libs/gui/include/gui/DisplayEventDispatcher.h
@@ -25,7 +25,7 @@
     // The Vsync Id corresponsing to this vsync event. This will be used to
     // populate ISurfaceComposer::setFrameTimelineVsync and
     // SurfaceComposerClient::setFrameTimelineVsync
-    int64_t id = ISurfaceComposer::INVALID_VSYNC_ID;
+    int64_t id = FrameTimelineInfo::INVALID_VSYNC_ID;
 
     // The deadline in CLOCK_MONOTONIC that the app needs to complete its
     // frame by (both on the CPU and the GPU)
diff --git a/libs/gui/include/gui/FrameTimelineInfo.h b/libs/gui/include/gui/FrameTimelineInfo.h
new file mode 100644
index 0000000..3b4c009
--- /dev/null
+++ b/libs/gui/include/gui/FrameTimelineInfo.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <stdint.h>
+
+#include <android/os/IInputConstants.h>
+#include <binder/Parcel.h>
+
+namespace android {
+
+struct FrameTimelineInfo {
+    // Needs to be in sync with android.graphics.FrameInfo.INVALID_VSYNC_ID in java
+    static constexpr int64_t INVALID_VSYNC_ID = -1;
+
+    // The vsync id that was used to start the transaction
+    int64_t vsyncId = INVALID_VSYNC_ID;
+
+    // The id of the input event that caused this buffer
+    int32_t inputEventId = android::os::IInputConstants::INVALID_INPUT_EVENT_ID;
+
+    status_t write(Parcel& output) const;
+    status_t read(const Parcel& input);
+
+    void merge(const FrameTimelineInfo& other);
+    void clear();
+};
+
+} // namespace android
diff --git a/libs/gui/include/gui/ISurfaceComposer.h b/libs/gui/include/gui/ISurfaceComposer.h
index 86f3c60..81ff6b0 100644
--- a/libs/gui/include/gui/ISurfaceComposer.h
+++ b/libs/gui/include/gui/ISurfaceComposer.h
@@ -24,6 +24,7 @@
 
 #include <android/gui/IScreenCaptureListener.h>
 #include <android/gui/ITransactionTraceListener.h>
+#include <gui/FrameTimelineInfo.h>
 #include <gui/ITransactionCompletedListener.h>
 
 #include <input/Flags.h>
@@ -117,9 +118,6 @@
 
     using EventRegistrationFlags = Flags<EventRegistration>;
 
-    // Needs to be in sync with android.graphics.FrameInfo.INVALID_VSYNC_ID in java
-    static constexpr int64_t INVALID_VSYNC_ID = -1;
-
     /*
      * Create a connection with SurfaceFlinger.
      */
@@ -164,7 +162,7 @@
 
     /* open/close transactions. requires ACCESS_SURFACE_FLINGER permission */
     virtual status_t setTransactionState(
-            int64_t frameTimelineVsyncId, const Vector<ComposerState>& state,
+            const FrameTimelineInfo& frameTimelineInfo, const Vector<ComposerState>& state,
             const Vector<DisplayState>& displays, uint32_t flags, const sp<IBinder>& applyToken,
             const InputWindowCommands& inputWindowCommands, int64_t desiredPresentTime,
             bool isAutoTimestamp, const client_cache_t& uncacheBuffer, bool hasListenerCallbacks,
@@ -494,11 +492,11 @@
     virtual status_t acquireFrameRateFlexibilityToken(sp<IBinder>* outToken) = 0;
 
     /*
-     * Sets the frame timeline vsync id received from choreographer that corresponds to next
+     * Sets the frame timeline vsync info received from choreographer that corresponds to next
      * buffer submitted on that surface.
      */
-    virtual status_t setFrameTimelineVsync(const sp<IGraphicBufferProducer>& surface,
-                                           int64_t frameTimelineVsyncId) = 0;
+    virtual status_t setFrameTimelineInfo(const sp<IGraphicBufferProducer>& surface,
+                                          const FrameTimelineInfo& frameTimelineInfo) = 0;
 
     /*
      * Adds a TransactionTraceListener to listen for transaction tracing state updates.
@@ -569,7 +567,7 @@
         SET_GAME_CONTENT_TYPE,
         SET_FRAME_RATE,
         ACQUIRE_FRAME_RATE_FLEXIBILITY_TOKEN,
-        SET_FRAME_TIMELINE_VSYNC,
+        SET_FRAME_TIMELINE_INFO,
         ADD_TRANSACTION_TRACE_LISTENER,
         GET_GPU_CONTEXT_PRIORITY,
         // Always append new enum to the end.
diff --git a/libs/gui/include/gui/LayerState.h b/libs/gui/include/gui/LayerState.h
index b1305c6..b3b074a 100644
--- a/libs/gui/include/gui/LayerState.h
+++ b/libs/gui/include/gui/LayerState.h
@@ -132,7 +132,7 @@
         eProducerDisconnect = 0x100'00000000,
         eFixedTransformHintChanged = 0x200'00000000,
         eFrameNumberChanged = 0x400'00000000,
-        eFrameTimelineVsyncChanged = 0x800'00000000,
+        eFrameTimelineInfoChanged = 0x800'00000000,
         eBlurRegionsChanged = 0x1000'00000000,
         eAutoRefreshChanged = 0x2000'00000000,
     };
@@ -238,7 +238,7 @@
     // graphics producer.
     uint64_t frameNumber;
 
-    int64_t frameTimelineVsyncId;
+    FrameTimelineInfo frameTimelineInfo;
 
     // Indicates that the consumer should acquire the next frame as soon as it
     // can and not wait for a frame to become available. This is only relevant
diff --git a/libs/gui/include/gui/Surface.h b/libs/gui/include/gui/Surface.h
index 43b5dcd..b6b5c7c 100644
--- a/libs/gui/include/gui/Surface.h
+++ b/libs/gui/include/gui/Surface.h
@@ -18,6 +18,7 @@
 #define ANDROID_GUI_SURFACE_H
 
 #include <gui/BufferQueueDefs.h>
+#include <gui/FrameTimelineInfo.h>
 #include <gui/HdrMetadata.h>
 #include <gui/IGraphicBufferProducer.h>
 #include <gui/IProducerListener.h>
@@ -187,7 +188,7 @@
     status_t getConsumerUsage(uint64_t* outUsage) const;
 
     virtual status_t setFrameRate(float frameRate, int8_t compatibility, bool shouldBeSeamless);
-    virtual status_t setFrameTimelineVsync(int64_t frameTimelineVsyncId);
+    virtual status_t setFrameTimelineInfo(const FrameTimelineInfo& info);
 
 protected:
     virtual ~Surface();
@@ -273,7 +274,7 @@
     int dispatchAddQueueInterceptor(va_list args);
     int dispatchAddQueryInterceptor(va_list args);
     int dispatchGetLastQueuedBuffer(va_list args);
-    int dispatchSetFrameTimelineVsync(va_list args);
+    int dispatchSetFrameTimelineInfo(va_list args);
     bool transformToDisplayInverse();
 
 protected:
diff --git a/libs/gui/include/gui/SurfaceComposerClient.h b/libs/gui/include/gui/SurfaceComposerClient.h
index 11db658..bed5c44 100644
--- a/libs/gui/include/gui/SurfaceComposerClient.h
+++ b/libs/gui/include/gui/SurfaceComposerClient.h
@@ -385,8 +385,8 @@
         int64_t mDesiredPresentTime = 0;
         bool mIsAutoTimestamp = true;
 
-        // The vsync Id provided by Choreographer.getVsyncId
-        int64_t mFrameTimelineVsyncId = ISurfaceComposer::INVALID_VSYNC_ID;
+        // The vsync id provided by Choreographer.getVsyncId and the input event id
+        FrameTimelineInfo mFrameTimelineInfo;
 
         // If not null, transactions will be queued up using this token otherwise a common token
         // per process will be used.
@@ -546,11 +546,12 @@
         Transaction& setFixedTransformHint(const sp<SurfaceControl>& sc, int32_t transformHint);
 
         // Sets the frame timeline vsync id received from choreographer that corresponds
-        // to the transaction.
-        Transaction& setFrameTimelineVsync(int64_t frameTimelineVsyncId);
+        // to the transaction, and the input event id that identifies the input event that caused
+        // the current frame.
+        Transaction& setFrameTimelineInfo(const FrameTimelineInfo& frameTimelineInfo);
         // Variant that only applies to a specific SurfaceControl.
-        Transaction& setFrameTimelineVsync(const sp<SurfaceControl>& sc,
-                int64_t frameTimelineVsyncId);
+        Transaction& setFrameTimelineInfo(const sp<SurfaceControl>& sc,
+                                          const FrameTimelineInfo& frameTimelineInfo);
 
         // Indicates that the consumer should acquire the next frame as soon as it
         // can and not wait for a frame to become available. This is only relevant
diff --git a/libs/gui/tests/Surface_test.cpp b/libs/gui/tests/Surface_test.cpp
index 63db9a7..3f7a5b1 100644
--- a/libs/gui/tests/Surface_test.cpp
+++ b/libs/gui/tests/Surface_test.cpp
@@ -695,7 +695,7 @@
     void destroyDisplay(const sp<IBinder>& /*display */) override {}
     std::vector<PhysicalDisplayId> getPhysicalDisplayIds() const override { return {}; }
     sp<IBinder> getPhysicalDisplayToken(PhysicalDisplayId) const override { return nullptr; }
-    status_t setTransactionState(int64_t /*frameTimelineVsyncId*/,
+    status_t setTransactionState(const FrameTimelineInfo& /*frameTimelineInfo*/,
                                  const Vector<ComposerState>& /*state*/,
                                  const Vector<DisplayState>& /*displays*/, uint32_t /*flags*/,
                                  const sp<IBinder>& /*applyToken*/,
@@ -877,8 +877,8 @@
         return NO_ERROR;
     }
 
-    status_t setFrameTimelineVsync(const sp<IGraphicBufferProducer>& /*surface*/,
-                                   int64_t /*frameTimelineVsyncId*/) override {
+    status_t setFrameTimelineInfo(const sp<IGraphicBufferProducer>& /*surface*/,
+                                  const FrameTimelineInfo& /*frameTimelineInfo*/) override {
         return NO_ERROR;
     }