expose hwui frame stats through FrameStatsObserver

Change-Id: I88884bafc8e2f6d7f67a36d3609490e83cf8afd5
diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp
index 6f8d627..cdd2da0 100644
--- a/libs/hwui/renderthread/CanvasContext.cpp
+++ b/libs/hwui/renderthread/CanvasContext.cpp
@@ -505,6 +505,9 @@
 
     mJankTracker.addFrame(*mCurrentFrameInfo);
     mRenderThread.jankTracker().addFrame(*mCurrentFrameInfo);
+    if (CC_UNLIKELY(mFrameStatsReporter.get() != nullptr)) {
+        mFrameStatsReporter->reportFrameStats(mCurrentFrameInfo->data());
+    }
 
     GpuMemoryTracker::onFrameCompleted();
 }
diff --git a/libs/hwui/renderthread/CanvasContext.h b/libs/hwui/renderthread/CanvasContext.h
index 8e64cbb..270fb1f 100644
--- a/libs/hwui/renderthread/CanvasContext.h
+++ b/libs/hwui/renderthread/CanvasContext.h
@@ -20,6 +20,7 @@
 #include "DamageAccumulator.h"
 #include "FrameInfo.h"
 #include "FrameInfoVisualizer.h"
+#include "FrameStatsReporter.h"
 #include "IContextFactory.h"
 #include "LayerUpdateQueue.h"
 #include "RenderNode.h"
@@ -139,6 +140,31 @@
         return mRenderThread.renderState();
     }
 
+    void addFrameStatsObserver(FrameStatsObserver* observer) {
+        if (mFrameStatsReporter.get() == nullptr) {
+            mFrameStatsReporter.reset(new FrameStatsReporter());
+        }
+
+        mFrameStatsReporter->addObserver(observer);
+    }
+
+    void removeFrameStatsObserver(FrameStatsObserver* observer) {
+        if (mFrameStatsReporter.get() != nullptr) {
+            mFrameStatsReporter->removeObserver(observer);
+            if (!mFrameStatsReporter->hasObservers()) {
+                mFrameStatsReporter.reset(nullptr);
+            }
+        }
+    }
+
+    long getDroppedFrameReportCount() {
+        if (mFrameStatsReporter.get() != nullptr) {
+            return mFrameStatsReporter->getDroppedReports();
+        }
+
+        return 0;
+    }
+
 private:
     friend class RegisterFrameCallbackTask;
     // TODO: Replace with something better for layer & other GL object
@@ -187,6 +213,7 @@
     std::string mName;
     JankTracker mJankTracker;
     FrameInfoVisualizer mProfiler;
+    std::unique_ptr<FrameStatsReporter> mFrameStatsReporter;
 
     std::set<RenderNode*> mPrefetechedLayers;
 
diff --git a/libs/hwui/renderthread/RenderProxy.cpp b/libs/hwui/renderthread/RenderProxy.cpp
index db2a2c8..1d1b144 100644
--- a/libs/hwui/renderthread/RenderProxy.cpp
+++ b/libs/hwui/renderthread/RenderProxy.cpp
@@ -568,6 +568,54 @@
     post(task);
 }
 
+CREATE_BRIDGE2(addFrameStatsObserver, CanvasContext* context,
+        FrameStatsObserver* frameStatsObserver) {
+   args->context->addFrameStatsObserver(args->frameStatsObserver);
+   if (args->frameStatsObserver != nullptr) {
+       args->frameStatsObserver->decStrong(args->context);
+   }
+   return nullptr;
+}
+
+void RenderProxy::addFrameStatsObserver(FrameStatsObserver* observer) {
+    SETUP_TASK(addFrameStatsObserver);
+    args->context = mContext;
+    args->frameStatsObserver = observer;
+    if (observer != nullptr) {
+        observer->incStrong(mContext);
+    }
+    post(task);
+}
+
+CREATE_BRIDGE2(removeFrameStatsObserver, CanvasContext* context,
+        FrameStatsObserver* frameStatsObserver) {
+   args->context->removeFrameStatsObserver(args->frameStatsObserver);
+   if (args->frameStatsObserver != nullptr) {
+       args->frameStatsObserver->decStrong(args->context);
+   }
+   return nullptr;
+}
+
+void RenderProxy::removeFrameStatsObserver(FrameStatsObserver* observer) {
+    SETUP_TASK(removeFrameStatsObserver);
+    args->context = mContext;
+    args->frameStatsObserver = observer;
+    if (observer != nullptr) {
+        observer->incStrong(mContext);
+    }
+    post(task);
+}
+
+CREATE_BRIDGE1(getDroppedFrameReportCount, CanvasContext* context) {
+    return (void*) args->context->getDroppedFrameReportCount();
+}
+
+long RenderProxy::getDroppedFrameReportCount() {
+    SETUP_TASK(getDroppedFrameReportCount);
+    args->context = mContext;
+    return (long) postAndWait(task);
+}
+
 void RenderProxy::post(RenderTask* task) {
     mRenderThread.queue(task);
 }
diff --git a/libs/hwui/renderthread/RenderProxy.h b/libs/hwui/renderthread/RenderProxy.h
index 0f91b2a..4180d802 100644
--- a/libs/hwui/renderthread/RenderProxy.h
+++ b/libs/hwui/renderthread/RenderProxy.h
@@ -29,6 +29,7 @@
 #include <utils/StrongPointer.h>
 
 #include "../Caches.h"
+#include "../FrameStatsObserver.h"
 #include "../IContextFactory.h"
 #include "CanvasContext.h"
 #include "DrawFrameTask.h"
@@ -112,6 +113,10 @@
     ANDROID_API void drawRenderNode(RenderNode* node);
     ANDROID_API void setContentDrawBounds(int left, int top, int right, int bottom);
 
+    ANDROID_API void addFrameStatsObserver(FrameStatsObserver* observer);
+    ANDROID_API void removeFrameStatsObserver(FrameStatsObserver* observer);
+    ANDROID_API long getDroppedFrameReportCount();
+
 private:
     RenderThread& mRenderThread;
     CanvasContext* mContext;