metrics: Add experimental reported_by_page metric.

Add the experimental reported_by_page metric, which is a TBMv3 port of
the TBMv2 equivalent[1].

[1] https://github.com/catapult-project/catapult/blob/master/tracing/tracing/metrics/reported_by_page_metric.html

Bug: 174028247
Change-Id: I22e3f84fa997379d07f818834de9eb5845ebfcf5
diff --git a/Android.bp b/Android.bp
index 657752a..e155f4c 100644
--- a/Android.bp
+++ b/Android.bp
@@ -3625,6 +3625,7 @@
     "protos/perfetto/metrics/android/unsymbolized_frames.proto",
     "protos/perfetto/metrics/chrome/all_chrome_metrics.proto",
     "protos/perfetto/metrics/chrome/frame_times.proto",
+    "protos/perfetto/metrics/chrome/reported_by_page.proto",
     "protos/perfetto/metrics/chrome/test_chrome_metric.proto",
     "protos/perfetto/metrics/custom_options.proto",
     "protos/perfetto/metrics/metrics.proto",
@@ -7639,6 +7640,7 @@
     "src/trace_processor/metrics/chrome/scroll_jank_cause_queuing_delay.sql",
     "src/trace_processor/metrics/chrome/test_chrome_metric.sql",
     "src/trace_processor/metrics/experimental/frame_times.sql",
+    "src/trace_processor/metrics/experimental/reported_by_page.sql",
     "src/trace_processor/metrics/trace_metadata.sql",
     "src/trace_processor/metrics/webview/webview_power_usage.sql",
   ],
diff --git a/BUILD b/BUILD
index 525a525..f84beb2 100644
--- a/BUILD
+++ b/BUILD
@@ -947,6 +947,7 @@
         "src/trace_processor/metrics/chrome/scroll_jank_cause_queuing_delay.sql",
         "src/trace_processor/metrics/chrome/test_chrome_metric.sql",
         "src/trace_processor/metrics/experimental/frame_times.sql",
+        "src/trace_processor/metrics/experimental/reported_by_page.sql",
         "src/trace_processor/metrics/trace_metadata.sql",
         "src/trace_processor/metrics/webview/webview_power_usage.sql",
     ],
@@ -2341,6 +2342,7 @@
     srcs = [
         "protos/perfetto/metrics/chrome/all_chrome_metrics.proto",
         "protos/perfetto/metrics/chrome/frame_times.proto",
+        "protos/perfetto/metrics/chrome/reported_by_page.proto",
         "protos/perfetto/metrics/chrome/test_chrome_metric.proto",
     ],
     visibility = [
diff --git a/protos/perfetto/metrics/chrome/BUILD.gn b/protos/perfetto/metrics/chrome/BUILD.gn
index a30c131..41712a0 100644
--- a/protos/perfetto/metrics/chrome/BUILD.gn
+++ b/protos/perfetto/metrics/chrome/BUILD.gn
@@ -23,6 +23,7 @@
   sources = [
     "all_chrome_metrics.proto",
     "frame_times.proto",
+    "reported_by_page.proto",
     "test_chrome_metric.proto",
   ]
 }
diff --git a/protos/perfetto/metrics/chrome/all_chrome_metrics.proto b/protos/perfetto/metrics/chrome/all_chrome_metrics.proto
index 442cba3..7850972 100644
--- a/protos/perfetto/metrics/chrome/all_chrome_metrics.proto
+++ b/protos/perfetto/metrics/chrome/all_chrome_metrics.proto
@@ -21,8 +21,10 @@
 import "protos/perfetto/metrics/metrics.proto";
 import "protos/perfetto/metrics/chrome/frame_times.proto";
 import "protos/perfetto/metrics/chrome/test_chrome_metric.proto";
+import "protos/perfetto/metrics/chrome/reported_by_page.proto";
 
 extend TraceMetrics {
   optional TestChromeMetric test_chrome_metric = 1001;
   optional FrameTimes frame_times = 1002;
+  optional ReportedByPage reported_by_page = 1003;
 }
diff --git a/protos/perfetto/metrics/chrome/reported_by_page.proto b/protos/perfetto/metrics/chrome/reported_by_page.proto
new file mode 100644
index 0000000..c9870e9
--- /dev/null
+++ b/protos/perfetto/metrics/chrome/reported_by_page.proto
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+syntax = "proto2";
+
+package perfetto.protos;
+
+import "protos/perfetto/metrics/custom_options.proto";
+
+message ReportedByPage {
+  // Time from navigation start to telemetry:reported_by_page:viewable.
+  repeated double time_to_viewable = 1 [(unit) = "ms_smallerIsBetter"];
+  // Time from navigation start to telemetry:reported_by_page:interactive.
+  repeated double time_to_interactive = 2 [(unit) = "ms_smallerIsBetter"];
+  // Time from telemetry:reported_by_page:benchmark_begin to
+  // telemetry:reported_by_page:benchmark_end.
+  repeated double benchmark_time = 3 [(unit) = "ms_smallerIsBetter"];
+}
diff --git a/src/trace_processor/metrics/BUILD.gn b/src/trace_processor/metrics/BUILD.gn
index d3520d6..fcd4244 100644
--- a/src/trace_processor/metrics/BUILD.gn
+++ b/src/trace_processor/metrics/BUILD.gn
@@ -80,6 +80,7 @@
   "chrome/scroll_flow_event_queuing_delay.sql",
   "chrome/test_chrome_metric.sql",
   "experimental/frame_times.sql",
+  "experimental/reported_by_page.sql",
   "webview/webview_power_usage.sql",
 ]
 
diff --git a/src/trace_processor/metrics/experimental/reported_by_page.sql b/src/trace_processor/metrics/experimental/reported_by_page.sql
new file mode 100644
index 0000000..2685433
--- /dev/null
+++ b/src/trace_processor/metrics/experimental/reported_by_page.sql
@@ -0,0 +1,66 @@
+--
+-- Copyright 2021 The Android Open Source Project
+--
+-- Licensed under the Apache License, Version 2.0 (the "License");
+-- you may not use this file except in compliance with the License.
+-- You may obtain a copy of the License at
+--
+--     https://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+
+--------------------------------------------------------------------------------
+-- Collect page-reported events for each renderer. Note that we don't need to
+-- match up process ids, because the unique nav_id ensures we're only comparing
+-- corresponding events.
+
+DROP VIEW IF EXISTS page_reported_events;
+CREATE VIEW page_reported_events AS
+SELECT ts, name, EXTRACT_ARG(arg_set_id, "debug.data.navigationId") as nav_id
+FROM slice
+WHERE category = 'blink.user_timing' AND
+    (name = 'navigationStart' OR name LIKE 'telemetry:reported_by_page:%')
+ORDER BY nav_id, ts ASC;
+
+--------------------------------------------------------------------------------
+-- Compute the duration from the corresponding navigation start for each
+-- reported event.
+
+DROP VIEW IF EXISTS page_reported_durations;
+CREATE VIEW page_reported_durations AS
+SELECT p.name, (p.ts - (
+    SELECT MAX(ts) FROM page_reported_events
+    WHERE
+      nav_id = p.nav_id AND
+      ts < p.ts AND (
+        -- Viewable/interactive markers measure time from nav start.
+        (p.name LIKE 'telemetry:reported_by_page:%' AND
+         p.name NOT LIKE 'telemetry:reported_by_page:benchmark%' AND
+         name = 'navigationStart') OR
+        -- Benchmark end markers measure time from the most recent begin marker.
+        (p.name = 'telemetry:reported_by_page:benchmark_end' AND
+         name = 'telemetry:reported_by_page:benchmark_begin')
+      ))
+    ) / 1e6 as dur_ms
+FROM page_reported_events p;
+
+--------------------------------------------------------------------------------
+-- Combine results into the output table.
+
+DROP VIEW IF EXISTS reported_by_page_output;
+CREATE VIEW reported_by_page_output AS
+SELECT ReportedByPage(
+  'time_to_viewable', (
+      SELECT RepeatedField(dur_ms) FROM page_reported_durations
+      WHERE name = 'telemetry:reported_by_page:viewable'),
+  'time_to_interactive', (
+      SELECT RepeatedField(dur_ms) FROM page_reported_durations
+      WHERE name = 'telemetry:reported_by_page:interactive'),
+  'benchmark_time', (
+      SELECT RepeatedField(dur_ms) FROM page_reported_durations
+      WHERE name = 'telemetry:reported_by_page:benchmark_end')
+);