Add UKM and UMA for main frame animation and event processing

The bulk of the uncaptured main frame time metrics are due to input
handling and JS callbacks for rAF. This patch add metrics for those
and cleans up the signalling for main frame start.

There's a lot of plumbing here but I tried to go only as deep as
necessary to access the LocalFrameView.

Some metrics will change due to this patch. For example, we will
now include lifecycle update times induced by hit testing for event
handling.

Manually verified that metrics are emitted for the new categories.

Bug: 869966
Change-Id: Ic569b4ad9871c47147bac94bcdea14fa94d691be
Reviewed-on: https://chromium-review.googlesource.com/c/1407629
Auto-Submit: Stephen Chenney <[email protected]>
Reviewed-by: Antoine Labour <[email protected]>
Reviewed-by: Chris Harrelson <[email protected]>
Reviewed-by: vmpstr <[email protected]>
Reviewed-by: Sadrul Chowdhury <[email protected]>
Reviewed-by: Robert Kaplow <[email protected]>
Commit-Queue: Stephen Chenney <[email protected]>
Cr-Commit-Position: refs/heads/master@{#626811}
diff --git a/content/renderer/render_widget.cc b/content/renderer/render_widget.cc
index e51bcafa..f75bf59 100644
--- a/content/renderer/render_widget.cc
+++ b/content/renderer/render_widget.cc
@@ -206,6 +206,21 @@
   blink::WebWidget* webwidget_;
 };
 
+class ScopedUkmRafAlignedInputTimer {
+ public:
+  explicit ScopedUkmRafAlignedInputTimer(blink::WebWidget* webwidget)
+      : webwidget_(webwidget) {
+    webwidget_->BeginRafAlignedInput();
+  }
+
+  ~ScopedUkmRafAlignedInputTimer() { webwidget_->EndRafAlignedInput(); }
+
+ private:
+  blink::WebWidget* webwidget_;
+
+  DISALLOW_COPY_AND_ASSIGN(ScopedUkmRafAlignedInputTimer);
+};
+
 bool IsDateTimeInput(ui::TextInputType type) {
   return type == ui::TEXT_INPUT_TYPE_DATE ||
          type == ui::TEXT_INPUT_TYPE_DATE_TIME ||
@@ -983,10 +998,19 @@
 void RenderWidget::BeginMainFrame(base::TimeTicks frame_time) {
   if (!GetWebWidget())
     return;
-  if (input_event_queue_)
-    input_event_queue_->DispatchRafAlignedInput(frame_time);
 
-  GetWebWidget()->BeginFrame(frame_time);
+  // We record metrics only when running in multi-threaded mode, not
+  // single-thread mode for testing.
+  bool record_main_frame_metrics =
+      !!compositor_deps_->GetCompositorImplThreadTaskRunner();
+  if (input_event_queue_) {
+    base::Optional<ScopedUkmRafAlignedInputTimer> ukm_timer;
+    if (record_main_frame_metrics)
+      ukm_timer.emplace(GetWebWidget());
+    input_event_queue_->DispatchRafAlignedInput(frame_time);
+  }
+
+  GetWebWidget()->BeginFrame(frame_time, record_main_frame_metrics);
 }
 
 void RenderWidget::RequestNewLayerTreeFrameSink(
@@ -1120,10 +1144,15 @@
   host->SetDebugState(debug_state);
 }
 
-void RenderWidget::UpdateVisualState(bool record_main_frame_metrics) {
+void RenderWidget::UpdateVisualState() {
   if (!GetWebWidget())
     return;
 
+  // We record metrics only when running in multi-threaded mode, not
+  // single-thread mode for testing.
+  bool record_main_frame_metrics =
+      !!compositor_deps_->GetCompositorImplThreadTaskRunner();
+
   // When recording main frame metrics set the lifecycle reason to
   // kBeginMainFrame, because this is the calller of UpdateLifecycle
   // for the main frame. Otherwise, set the reason to kTests, which is
@@ -1158,6 +1187,13 @@
   }
 }
 
+void RenderWidget::RecordStartOfFrameMetrics() {
+  if (!GetWebWidget())
+    return;
+
+  GetWebWidget()->RecordStartOfFrameMetrics();
+}
+
 void RenderWidget::RecordEndOfFrameMetrics(base::TimeTicks frame_begin_time) {
   if (!GetWebWidget())
     return;