SF: Implement FrameStats directly in FrameTimeline

Bug: 241394120
Test: builds, atest CtsUiAutomationTestCases:android.app.uiautomation.cts.UiAutomationTest#testWindowContentFrameStats$
Flag: com.android.graphics.surfaceflinger.flags.deprecate_frame_tracker
Change-Id: I3f12d504e821a6ba15a26604eb56f317c9d59a18
diff --git a/services/surfaceflinger/FrameTimeline/FrameTimeline.cpp b/services/surfaceflinger/FrameTimeline/FrameTimeline.cpp
index 47b811b..c13e444 100644
--- a/services/surfaceflinger/FrameTimeline/FrameTimeline.cpp
+++ b/services/surfaceflinger/FrameTimeline/FrameTimeline.cpp
@@ -378,6 +378,11 @@
     }
 }
 
+void SurfaceFrame::setDesiredPresentTime(nsecs_t desiredPresentTime) {
+    std::scoped_lock lock(mMutex);
+    mActuals.desiredPresentTime = desiredPresentTime;
+}
+
 void SurfaceFrame::setDropTime(nsecs_t dropTime) {
     std::scoped_lock lock(mMutex);
     mDropTime = dropTime;
@@ -1456,6 +1461,30 @@
             static_cast<float>(totalPresentToPresentWalls);
 }
 
+void FrameTimeline::generateFrameStats(int32_t layer, size_t count, FrameStats* outStats) const {
+    std::scoped_lock lock(mMutex);
+
+    // TODO: Include FPS calculation here
+    for (auto displayFrame : mDisplayFrames) {
+        if (!count--) {
+            break;
+        }
+
+        if (displayFrame->getActuals().presentTime <= 0) {
+            continue;
+        }
+
+        for (const auto& surfaceFrame : displayFrame->getSurfaceFrames()) {
+            if (surfaceFrame->getLayerId() == layer) {
+                outStats->actualPresentTimesNano.push_back(surfaceFrame->getActuals().presentTime);
+                outStats->desiredPresentTimesNano.push_back(
+                        surfaceFrame->getActuals().desiredPresentTime);
+                outStats->frameReadyTimesNano.push_back(surfaceFrame->getActuals().endTime);
+            }
+        }
+    }
+}
+
 std::optional<size_t> FrameTimeline::getFirstSignalFenceIndex() const {
     for (size_t i = 0; i < mPendingPresentFences.size(); i++) {
         const auto& [fence, _] = mPendingPresentFences[i];
diff --git a/services/surfaceflinger/FrameTimeline/FrameTimeline.h b/services/surfaceflinger/FrameTimeline/FrameTimeline.h
index cffb61e..6cda309 100644
--- a/services/surfaceflinger/FrameTimeline/FrameTimeline.h
+++ b/services/surfaceflinger/FrameTimeline/FrameTimeline.h
@@ -85,16 +85,20 @@
  */
 struct TimelineItem {
     TimelineItem(const nsecs_t startTime = 0, const nsecs_t endTime = 0,
-                 const nsecs_t presentTime = 0)
-          : startTime(startTime), endTime(endTime), presentTime(presentTime) {}
+                 const nsecs_t presentTime = 0, const nsecs_t desiredPresentTime = 0)
+          : startTime(startTime),
+            endTime(endTime),
+            presentTime(presentTime),
+            desiredPresentTime(desiredPresentTime) {}
 
     nsecs_t startTime;
     nsecs_t endTime;
     nsecs_t presentTime;
+    nsecs_t desiredPresentTime;
 
     bool operator==(const TimelineItem& other) const {
         return startTime == other.startTime && endTime == other.endTime &&
-                presentTime == other.presentTime;
+                presentTime == other.presentTime && desiredPresentTime != other.desiredPresentTime;
     }
 
     bool operator!=(const TimelineItem& other) const { return !(*this == other); }
@@ -183,6 +187,7 @@
     void setActualStartTime(nsecs_t actualStartTime);
     void setActualQueueTime(nsecs_t actualQueueTime);
     void setAcquireFenceTime(nsecs_t acquireFenceTime);
+    void setDesiredPresentTime(nsecs_t desiredPresentTime);
     void setDropTime(nsecs_t dropTime);
     void setPresentState(PresentState presentState, nsecs_t lastLatchTime = 0);
     void setRenderRate(Fps renderRate);
@@ -341,6 +346,9 @@
     // containing at least one layer ID.
     virtual float computeFps(const std::unordered_set<int32_t>& layerIds) = 0;
 
+    // Supports the legacy FrameStats interface
+    virtual void generateFrameStats(int32_t layer, size_t count, FrameStats* outStats) const = 0;
+
     // Restores the max number of display frames to default. Called by SF backdoor.
     virtual void reset() = 0;
 };
@@ -501,6 +509,7 @@
     void parseArgs(const Vector<String16>& args, std::string& result) override;
     void setMaxDisplayFrames(uint32_t size) override;
     float computeFps(const std::unordered_set<int32_t>& layerIds) override;
+    void generateFrameStats(int32_t layer, size_t count, FrameStats* outStats) const override;
     void reset() override;
 
     // Sets up the perfetto tracing backend and data source.