Integrate HWUI with PerformanceHintManager

PerformanceHintManager.Session is in java, so add JNI and a HintSessionWrapper
class in HardwareRenderer. Then pass the two calls as two std::functions
into DrawFrameTask.

Note Session is created per HardwareRenderer, not global (per
RenderThread).

Session includes UI thread, render thread, and the thread pool.
Desired duration is from the intended start duration to the frame
deadline. Add an actual frame start time to compute

Add system properties:
debug.hwui.use_hint_manager to enable PerformanceHintManager
debug.hwui.target_cpu_time_percent to control percentage of frame time
  to be used for target cpu duration.

Test: Manual test that there are no crashes and values make sense.
Bug: 158791282
Change-Id: I83f25433c10daa20033803fb7c4ae45eab34f1d3
diff --git a/libs/hwui/renderthread/DrawFrameTask.cpp b/libs/hwui/renderthread/DrawFrameTask.cpp
index 3408ffd..7a38a3b 100644
--- a/libs/hwui/renderthread/DrawFrameTask.cpp
+++ b/libs/hwui/renderthread/DrawFrameTask.cpp
@@ -21,6 +21,7 @@
 
 #include "../DeferredLayerUpdater.h"
 #include "../DisplayList.h"
+#include "../Properties.h"
 #include "../RenderNode.h"
 #include "CanvasContext.h"
 #include "RenderThread.h"
@@ -44,6 +45,12 @@
     mTargetNode = targetNode;
 }
 
+void DrawFrameTask::setHintSessionCallbacks(std::function<void(int64_t)> updateTargetWorkDuration,
+                                            std::function<void(int64_t)> reportActualWorkDuration) {
+    mUpdateTargetWorkDuration = std::move(updateTargetWorkDuration);
+    mReportActualWorkDuration = std::move(reportActualWorkDuration);
+}
+
 void DrawFrameTask::pushLayerUpdate(DeferredLayerUpdater* layer) {
     LOG_ALWAYS_FATAL_IF(!mContext,
                         "Lifecycle violation, there's no context to pushLayerUpdate with!");
@@ -102,6 +109,9 @@
     CanvasContext* context = mContext;
     std::function<void(int64_t)> callback = std::move(mFrameCallback);
     mFrameCallback = nullptr;
+    int64_t intendedVsync = mFrameInfo[static_cast<int>(FrameInfoIndex::IntendedVsync)];
+    int64_t frameDeadline = mFrameInfo[static_cast<int>(FrameInfoIndex::FrameDeadline)];
+    int64_t frameStartTime = mFrameInfo[static_cast<int>(FrameInfoIndex::FrameStartTime)];
 
     // From this point on anything in "this" is *UNSAFE TO ACCESS*
     if (canUnblockUiThread) {
@@ -124,6 +134,25 @@
     if (!canUnblockUiThread) {
         unblockUiThread();
     }
+
+    // These member callbacks are effectively const as they are set once during init, so it's safe
+    // to use these directly instead of making local copies.
+    if (mUpdateTargetWorkDuration && mReportActualWorkDuration) {
+        constexpr int64_t kSanityCheckLowerBound = 100000;       // 0.1ms
+        constexpr int64_t kSanityCheckUpperBound = 10000000000;  // 10s
+        int64_t targetWorkDuration = frameDeadline - intendedVsync;
+        targetWorkDuration = targetWorkDuration * Properties::targetCpuTimePercentage / 100;
+        if (targetWorkDuration > kSanityCheckLowerBound &&
+            targetWorkDuration < kSanityCheckUpperBound &&
+            targetWorkDuration != mLastTargetWorkDuration) {
+            mLastTargetWorkDuration = targetWorkDuration;
+            mUpdateTargetWorkDuration(targetWorkDuration);
+        }
+        int64_t frameDuration = systemTime(SYSTEM_TIME_MONOTONIC) - frameStartTime;
+        if (frameDuration > kSanityCheckLowerBound && frameDuration < kSanityCheckUpperBound) {
+            mReportActualWorkDuration(frameDuration);
+        }
+    }
 }
 
 bool DrawFrameTask::syncFrameState(TreeInfo& info) {