Adding render stats APIs to UiAutomation (framework native).

bug:12927198

Change-Id: Ibb1c07f7d89e11281e5c1f27f412a29ac6f9c4ab
diff --git a/services/surfaceflinger/Client.cpp b/services/surfaceflinger/Client.cpp
index 975631c..f7d32d0 100644
--- a/services/surfaceflinger/Client.cpp
+++ b/services/surfaceflinger/Client.cpp
@@ -155,5 +155,23 @@
     return mFlinger->onLayerRemoved(this, handle);
 }
 
+status_t Client::clearLayerFrameStats(const sp<IBinder>& handle) const {
+    sp<Layer> layer = getLayerUser(handle);
+    if (layer == NULL) {
+        return NAME_NOT_FOUND;
+    }
+    layer->clearFrameStats();
+    return NO_ERROR;
+}
+
+status_t Client::getLayerFrameStats(const sp<IBinder>& handle, FrameStats* outStats) const {
+    sp<Layer> layer = getLayerUser(handle);
+    if (layer == NULL) {
+        return NAME_NOT_FOUND;
+    }
+    layer->getFrameStats(outStats);
+    return NO_ERROR;
+}
+
 // ---------------------------------------------------------------------------
 }; // namespace android
diff --git a/services/surfaceflinger/Client.h b/services/surfaceflinger/Client.h
index 84e649f..b6d7381 100644
--- a/services/surfaceflinger/Client.h
+++ b/services/surfaceflinger/Client.h
@@ -60,6 +60,10 @@
 
     virtual status_t destroySurface(const sp<IBinder>& handle);
 
+    virtual status_t clearLayerFrameStats(const sp<IBinder>& handle) const;
+
+    virtual status_t getLayerFrameStats(const sp<IBinder>& handle, FrameStats* outStats) const;
+
     virtual status_t onTransact(
         uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags);
 
diff --git a/services/surfaceflinger/FrameTracker.cpp b/services/surfaceflinger/FrameTracker.cpp
index 2fb665e..c09bbe4 100644
--- a/services/surfaceflinger/FrameTracker.cpp
+++ b/services/surfaceflinger/FrameTracker.cpp
@@ -22,6 +22,7 @@
 #include <cutils/log.h>
 
 #include <ui/Fence.h>
+#include <ui/FrameStats.h>
 
 #include <utils/String8.h>
 
@@ -100,7 +101,7 @@
     processFencesLocked();
 }
 
-void FrameTracker::clear() {
+void FrameTracker::clearStats() {
     Mutex::Autolock lock(mMutex);
     for (size_t i = 0; i < NUM_FRAME_RECORDS; i++) {
         mFrameRecords[i].desiredPresentTime = 0;
@@ -115,6 +116,32 @@
     mFrameRecords[mOffset].actualPresentTime = INT64_MAX;
 }
 
+void FrameTracker::getStats(FrameStats* outStats) const {
+    Mutex::Autolock lock(mMutex);
+    processFencesLocked();
+
+    outStats->refreshPeriodNano = mDisplayPeriod;
+
+    const size_t offset = mOffset;
+    for (size_t i = 1; i < NUM_FRAME_RECORDS; i++) {
+        const size_t index = (offset + i) % NUM_FRAME_RECORDS;
+
+        // Skip frame records with no data (if buffer not yet full).
+        if (mFrameRecords[index].desiredPresentTime == 0) {
+            continue;
+        }
+
+        nsecs_t desiredPresentTimeNano = mFrameRecords[index].desiredPresentTime;
+        outStats->desiredPresentTimesNano.push_back(desiredPresentTimeNano);
+
+        nsecs_t actualPresentTimeNano = mFrameRecords[index].actualPresentTime;
+        outStats->actualPresentTimesNano.push_back(actualPresentTimeNano);
+
+        nsecs_t frameReadyTimeNano = mFrameRecords[index].frameReadyTime;
+        outStats->frameReadyTimesNano.push_back(frameReadyTimeNano);
+    }
+}
+
 void FrameTracker::logAndResetStats(const String8& name) {
     Mutex::Autolock lock(mMutex);
     logStatsLocked(name);
@@ -206,7 +233,7 @@
             mFrameRecords[idx].actualPresentTime < INT64_MAX;
 }
 
-void FrameTracker::dump(String8& result) const {
+void FrameTracker::dumpStats(String8& result) const {
     Mutex::Autolock lock(mMutex);
     processFencesLocked();
 
diff --git a/services/surfaceflinger/FrameTracker.h b/services/surfaceflinger/FrameTracker.h
index 9233247..cd5e3f3 100644
--- a/services/surfaceflinger/FrameTracker.h
+++ b/services/surfaceflinger/FrameTracker.h
@@ -78,15 +78,18 @@
     // advanceFrame advances the frame tracker to the next frame.
     void advanceFrame();
 
-    // clear resets all the tracked frame data to zero.
-    void clear();
+    // clearStats clears the tracked frame stats.
+    void clearStats();
+
+    // getStats gets the tracked frame stats.
+    void getStats(FrameStats* outStats) const;
 
     // logAndResetStats dumps the current statistics to the binary event log
     // and then resets the accumulated statistics to their initial values.
     void logAndResetStats(const String8& name);
 
-    // dump appends the current frame display time history to the result string.
-    void dump(String8& result) const;
+    // dumpStats dump appends the current frame display time history to the result string.
+    void dumpStats(String8& result) const;
 
 private:
     struct FrameRecord {
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 7f2ee2a..9920525 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -1244,18 +1244,22 @@
     }
 }
 
-void Layer::dumpStats(String8& result) const {
-    mFrameTracker.dump(result);
+void Layer::dumpFrameStats(String8& result) const {
+    mFrameTracker.dumpStats(result);
 }
 
-void Layer::clearStats() {
-    mFrameTracker.clear();
+void Layer::clearFrameStats() {
+    mFrameTracker.clearStats();
 }
 
 void Layer::logFrameStats() {
     mFrameTracker.logAndResetStats(mName);
 }
 
+void Layer::getFrameStats(FrameStats* outStats) const {
+    mFrameTracker.getStats(outStats);
+}
+
 // ---------------------------------------------------------------------------
 
 Layer::LayerCleaner::LayerCleaner(const sp<SurfaceFlinger>& flinger,
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index 8f8989e..62970c3 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -27,6 +27,7 @@
 #include <utils/String8.h>
 #include <utils/Timers.h>
 
+#include <ui/FrameStats.h>
 #include <ui/GraphicBuffer.h>
 #include <ui/PixelFormat.h>
 #include <ui/Region.h>
@@ -288,9 +289,10 @@
 
     /* always call base class first */
     void dump(String8& result, Colorizer& colorizer) const;
-    void dumpStats(String8& result) const;
-    void clearStats();
+    void dumpFrameStats(String8& result) const;
+    void clearFrameStats();
     void logFrameStats();
+    void getFrameStats(FrameStats* outStats) const;
 
 protected:
     // constant
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index d084bf5..a346520 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -574,6 +574,18 @@
     return NO_ERROR;
 }
 
+status_t SurfaceFlinger::clearAnimationFrameStats() {
+    Mutex::Autolock _l(mStateLock);
+    mAnimFrameTracker.clearStats();
+    return NO_ERROR;
+}
+
+status_t SurfaceFlinger::getAnimationFrameStats(FrameStats* outStats) const {
+    Mutex::Autolock _l(mStateLock);
+    mAnimFrameTracker.getStats(outStats);
+    return NO_ERROR;
+}
+
 // ----------------------------------------------------------------------------
 
 sp<IDisplayEventConnection> SurfaceFlinger::createDisplayEventConnection() {
@@ -2255,14 +2267,14 @@
     result.appendFormat("%" PRId64 "\n", period);
 
     if (name.isEmpty()) {
-        mAnimFrameTracker.dump(result);
+        mAnimFrameTracker.dumpStats(result);
     } else {
         const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
         const size_t count = currentLayers.size();
         for (size_t i=0 ; i<count ; i++) {
             const sp<Layer>& layer(currentLayers[i]);
             if (name == layer->getName()) {
-                layer->dumpStats(result);
+                layer->dumpFrameStats(result);
             }
         }
     }
@@ -2282,11 +2294,11 @@
     for (size_t i=0 ; i<count ; i++) {
         const sp<Layer>& layer(currentLayers[i]);
         if (name.isEmpty() || (name == layer->getName())) {
-            layer->clearStats();
+            layer->clearFrameStats();
         }
     }
 
-    mAnimFrameTracker.clear();
+    mAnimFrameTracker.clearStats();
 }
 
 // This should only be called from the main thread.  Otherwise it would need
@@ -2500,6 +2512,8 @@
         case BOOT_FINISHED:
         case BLANK:
         case UNBLANK:
+        case CLEAR_ANIMATION_FRAME_STATS:
+        case GET_ANIMATION_FRAME_STATS:
         {
             // codes that require permission check
             IPCThreadState* ipc = IPCThreadState::self();
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 630f4b7..717ee66 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -210,6 +210,8 @@
     // called when screen is turning back on
     virtual void unblank(const sp<IBinder>& display);
     virtual status_t getDisplayInfo(const sp<IBinder>& display, DisplayInfo* info);
+    virtual status_t clearAnimationFrameStats();
+    virtual status_t getAnimationFrameStats(FrameStats* outStats) const;
 
     /* ------------------------------------------------------------------------
      * DeathRecipient interface