Pass actual present time to ViewRootImpl

To measure end-to-end touch latency, we need to report the actual
present time to ViewRootImpl. ViewRootImpl, in turn, will report this
information to InputDispatcher. Finally, InputDispatcher will combine
all known information for a specific input event, and will report this
data to westworld.

In another patch, we will add a new call, 'reportLatencyInfo', to
InputPublisher. This call will allow the app to send this latency data
to InputDispatcher.

Bug: 169866723
Test: printed the input event present times inside ViewRootImpl
Change-Id: Ibd3a2cfeb1a340eb15cd2165071df1f8589634af
diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp
index f69ddac..9793300 100644
--- a/libs/hwui/renderthread/CanvasContext.cpp
+++ b/libs/hwui/renderthread/CanvasContext.cpp
@@ -599,10 +599,41 @@
     // TODO (b/169858044): Move this into JankTracker to adjust deadline when queue is
     // double-stuffed.
     if (CC_UNLIKELY(mFrameMetricsReporter.get() != nullptr)) {
-        mFrameMetricsReporter->reportFrameMetrics(frameInfo->data());
+        mFrameMetricsReporter->reportFrameMetrics(frameInfo->data(), false /*hasPresentTime*/);
     }
 }
 
+void CanvasContext::reportMetricsWithPresentTime() {
+    if (mFrameMetricsReporter == nullptr) {
+        return;
+    }
+    if (mNativeSurface == nullptr) {
+        return;
+    }
+    FrameInfo* forthBehind;
+    int64_t frameNumber;
+    {  // acquire lock
+        std::scoped_lock lock(mLast4FrameInfosMutex);
+        if (mLast4FrameInfos.size() != mLast4FrameInfos.capacity()) {
+            // Not enough frames yet
+            return;
+        }
+        // Surface object keeps stats for the last 8 frames.
+        std::tie(forthBehind, frameNumber) = mLast4FrameInfos.front();
+    }  // release lock
+
+    nsecs_t presentTime = 0;
+    native_window_get_frame_timestamps(
+            mNativeSurface->getNativeWindow(), frameNumber, nullptr /*outRequestedPresentTime*/,
+            nullptr /*outAcquireTime*/, nullptr /*outLatchTime*/,
+            nullptr /*outFirstRefreshStartTime*/, nullptr /*outLastRefreshStartTime*/,
+            nullptr /*outGpuCompositionDoneTime*/, &presentTime, nullptr /*outDequeueReadyTime*/,
+            nullptr /*outReleaseTime*/);
+
+    forthBehind->set(FrameInfoIndex::DisplayPresentTime) = presentTime;
+    mFrameMetricsReporter->reportFrameMetrics(forthBehind->data(), true /*hasPresentTime*/);
+}
+
 void CanvasContext::onSurfaceStatsAvailable(void* context, ASurfaceControl* control,
             ASurfaceControlStats* stats) {
 
@@ -624,6 +655,9 @@
             }
         }
     }
+
+    instance->reportMetricsWithPresentTime();
+
     if (frameInfo != nullptr) {
         if (gpuCompleteTime == -1) {
             gpuCompleteTime = frameInfo->get(FrameInfoIndex::SwapBuffersCompleted);
diff --git a/libs/hwui/renderthread/CanvasContext.h b/libs/hwui/renderthread/CanvasContext.h
index 2e7b2f6..74f426e 100644
--- a/libs/hwui/renderthread/CanvasContext.h
+++ b/libs/hwui/renderthread/CanvasContext.h
@@ -219,6 +219,12 @@
     SkRect computeDirtyRect(const Frame& frame, SkRect* dirty);
     void finishFrame(FrameInfo* frameInfo);
 
+    /**
+     * Invoke 'reportFrameMetrics' on the last frame stored in 'mLast4FrameInfos'.
+     * Populate the 'presentTime' field before calling.
+     */
+    void reportMetricsWithPresentTime();
+
     // The same type as Frame.mWidth and Frame.mHeight
     int32_t mLastFrameWidth = 0;
     int32_t mLastFrameHeight = 0;