[wv] Add a jank approximation metric for WebView

This CL adds trace processor support for running WebView trace-based metrics
by following Chrome's example. Also adds a new webview_jank_approximation
metric that calculates the number of janks overlapping WebView renderer slices.

Bug: 273555049

Change-Id: I998765921b7f7a9bf8c98f0355290e7d8919a428
diff --git a/Android.bp b/Android.bp
index 81477a0..7a44cd2 100644
--- a/Android.bp
+++ b/Android.bp
@@ -2243,6 +2243,7 @@
         "perfetto_src_trace_processor_importers_proto_gen_cc_trace_descriptor",
         "perfetto_src_trace_processor_importers_proto_gen_cc_track_event_descriptor",
         "perfetto_src_trace_processor_metrics_gen_cc_all_chrome_metrics_descriptor",
+        "perfetto_src_trace_processor_metrics_gen_cc_all_webview_metrics_descriptor",
         "perfetto_src_trace_processor_metrics_gen_cc_metrics_descriptor",
         "perfetto_src_trace_processor_metrics_sql_gen_amalgamated_sql_metrics",
         "perfetto_src_trace_processor_stdlib_gen_amalgamated_stdlib",
@@ -4413,6 +4414,64 @@
     ],
 }
 
+// GN: //protos/perfetto/metrics/webview:descriptor
+genrule {
+    name: "perfetto_protos_perfetto_metrics_webview_descriptor",
+    srcs: [
+        "protos/perfetto/metrics/android/android_blocking_calls_cuj_metric.proto",
+        "protos/perfetto/metrics/android/android_frame_timeline_metric.proto",
+        "protos/perfetto/metrics/android/android_trusty_workqueues.proto",
+        "protos/perfetto/metrics/android/batt_metric.proto",
+        "protos/perfetto/metrics/android/binder_metric.proto",
+        "protos/perfetto/metrics/android/camera_metric.proto",
+        "protos/perfetto/metrics/android/camera_unagg_metric.proto",
+        "protos/perfetto/metrics/android/cpu_metric.proto",
+        "protos/perfetto/metrics/android/display_metrics.proto",
+        "protos/perfetto/metrics/android/dma_heap_metric.proto",
+        "protos/perfetto/metrics/android/dvfs_metric.proto",
+        "protos/perfetto/metrics/android/fastrpc_metric.proto",
+        "protos/perfetto/metrics/android/g2d_metric.proto",
+        "protos/perfetto/metrics/android/gpu_metric.proto",
+        "protos/perfetto/metrics/android/hwcomposer.proto",
+        "protos/perfetto/metrics/android/hwui_metric.proto",
+        "protos/perfetto/metrics/android/ion_metric.proto",
+        "protos/perfetto/metrics/android/irq_runtime_metric.proto",
+        "protos/perfetto/metrics/android/jank_cuj_metric.proto",
+        "protos/perfetto/metrics/android/java_heap_histogram.proto",
+        "protos/perfetto/metrics/android/java_heap_stats.proto",
+        "protos/perfetto/metrics/android/lmk_metric.proto",
+        "protos/perfetto/metrics/android/lmk_reason_metric.proto",
+        "protos/perfetto/metrics/android/mem_metric.proto",
+        "protos/perfetto/metrics/android/mem_unagg_metric.proto",
+        "protos/perfetto/metrics/android/monitor_contention_metric.proto",
+        "protos/perfetto/metrics/android/multiuser_metric.proto",
+        "protos/perfetto/metrics/android/network_metric.proto",
+        "protos/perfetto/metrics/android/other_traces.proto",
+        "protos/perfetto/metrics/android/package_list.proto",
+        "protos/perfetto/metrics/android/powrails_metric.proto",
+        "protos/perfetto/metrics/android/process_metadata.proto",
+        "protos/perfetto/metrics/android/profiler_smaps.proto",
+        "protos/perfetto/metrics/android/rt_runtime_metric.proto",
+        "protos/perfetto/metrics/android/simpleperf.proto",
+        "protos/perfetto/metrics/android/startup_metric.proto",
+        "protos/perfetto/metrics/android/surfaceflinger.proto",
+        "protos/perfetto/metrics/android/task_names.proto",
+        "protos/perfetto/metrics/android/thread_time_in_state_metric.proto",
+        "protos/perfetto/metrics/android/trace_quality.proto",
+        "protos/perfetto/metrics/android/unsymbolized_frames.proto",
+        "protos/perfetto/metrics/metrics.proto",
+        "protos/perfetto/metrics/webview/all_webview_metrics.proto",
+        "protos/perfetto/metrics/webview/webview_jank_approximation.proto",
+    ],
+    tools: [
+        "aprotoc",
+    ],
+    cmd: "mkdir -p $(genDir)/external/perfetto/ && $(location aprotoc) --proto_path=external/perfetto --descriptor_set_out=$(out) $(in)",
+    out: [
+        "perfetto_protos_perfetto_metrics_webview_descriptor.bin",
+    ],
+}
+
 // GN: //protos/perfetto/trace/android:cpp
 genrule {
     name: "perfetto_protos_perfetto_trace_android_cpp_gen",
@@ -9724,6 +9783,21 @@
     ],
 }
 
+// GN: //src/trace_processor/metrics:gen_cc_all_webview_metrics_descriptor
+genrule {
+    name: "perfetto_src_trace_processor_metrics_gen_cc_all_webview_metrics_descriptor",
+    srcs: [
+        ":perfetto_protos_perfetto_metrics_webview_descriptor",
+    ],
+    cmd: "$(location tools/gen_cc_proto_descriptor.py) --gen_dir=$(genDir) --cpp_out=$(out) $(in)",
+    out: [
+        "src/trace_processor/metrics/all_webview_metrics.descriptor.h",
+    ],
+    tool_files: [
+        "tools/gen_cc_proto_descriptor.py",
+    ],
+}
+
 // GN: //src/trace_processor/metrics:gen_cc_metrics_descriptor
 genrule {
     name: "perfetto_src_trace_processor_metrics_gen_cc_metrics_descriptor",
@@ -9913,6 +9987,7 @@
         "src/trace_processor/metrics/sql/experimental/reported_by_page.sql",
         "src/trace_processor/metrics/sql/trace_metadata.sql",
         "src/trace_processor/metrics/sql/trace_stats.sql",
+        "src/trace_processor/metrics/sql/webview/webview_jank_approximation.sql",
         "src/trace_processor/metrics/sql/webview/webview_power_usage.sql",
     ],
     cmd: "$(location tools/gen_amalgamated_sql.py) --namespace=sql_metrics --cpp-out=$(out) $(in)",
@@ -11953,6 +12028,7 @@
         "perfetto_src_trace_processor_importers_proto_gen_cc_trace_descriptor",
         "perfetto_src_trace_processor_importers_proto_gen_cc_track_event_descriptor",
         "perfetto_src_trace_processor_metrics_gen_cc_all_chrome_metrics_descriptor",
+        "perfetto_src_trace_processor_metrics_gen_cc_all_webview_metrics_descriptor",
         "perfetto_src_trace_processor_metrics_gen_cc_metrics_descriptor",
         "perfetto_src_trace_processor_metrics_sql_gen_amalgamated_sql_metrics",
         "perfetto_src_trace_processor_stdlib_gen_amalgamated_stdlib",
@@ -12468,6 +12544,7 @@
         "perfetto_src_trace_processor_importers_proto_gen_cc_trace_descriptor",
         "perfetto_src_trace_processor_importers_proto_gen_cc_track_event_descriptor",
         "perfetto_src_trace_processor_metrics_gen_cc_all_chrome_metrics_descriptor",
+        "perfetto_src_trace_processor_metrics_gen_cc_all_webview_metrics_descriptor",
         "perfetto_src_trace_processor_metrics_gen_cc_metrics_descriptor",
         "perfetto_src_trace_processor_metrics_sql_gen_amalgamated_sql_metrics",
         "perfetto_src_trace_processor_stdlib_gen_amalgamated_stdlib",
@@ -12690,6 +12767,7 @@
         "perfetto_src_trace_processor_importers_proto_gen_cc_trace_descriptor",
         "perfetto_src_trace_processor_importers_proto_gen_cc_track_event_descriptor",
         "perfetto_src_trace_processor_metrics_gen_cc_all_chrome_metrics_descriptor",
+        "perfetto_src_trace_processor_metrics_gen_cc_all_webview_metrics_descriptor",
         "perfetto_src_trace_processor_metrics_gen_cc_metrics_descriptor",
         "perfetto_src_trace_processor_metrics_sql_gen_amalgamated_sql_metrics",
         "perfetto_src_trace_processor_stdlib_gen_amalgamated_stdlib",
diff --git a/BUILD b/BUILD
index 05aee8b..01153ff 100644
--- a/BUILD
+++ b/BUILD
@@ -1704,6 +1704,7 @@
 perfetto_filegroup(
     name = "src_trace_processor_metrics_sql_webview_webview",
     srcs = [
+        "src/trace_processor/metrics/sql/webview/webview_jank_approximation.sql",
         "src/trace_processor/metrics/sql/webview/webview_power_usage.sql",
     ],
 )
@@ -1745,6 +1746,17 @@
     ],
 )
 
+# GN target: //src/trace_processor/metrics:gen_cc_all_webview_metrics_descriptor
+perfetto_cc_proto_descriptor(
+    name = "src_trace_processor_metrics_gen_cc_all_webview_metrics_descriptor",
+    deps = [
+        ":protos_perfetto_metrics_webview_descriptor",
+    ],
+    outs = [
+        "src/trace_processor/metrics/all_webview_metrics.descriptor.h",
+    ],
+)
+
 # GN target: //src/trace_processor/metrics:gen_cc_metrics_descriptor
 perfetto_cc_proto_descriptor(
     name = "src_trace_processor_metrics_gen_cc_metrics_descriptor",
@@ -3700,6 +3712,33 @@
     ],
 )
 
+# GN target: //protos/perfetto/metrics/webview:descriptor
+perfetto_proto_descriptor(
+    name = "protos_perfetto_metrics_webview_descriptor",
+    deps = [
+        ":protos_perfetto_metrics_webview_protos",
+    ],
+    outs = [
+        "protos_perfetto_metrics_webview_descriptor.bin",
+    ],
+)
+
+# GN target: //protos/perfetto/metrics/webview:source_set
+perfetto_proto_library(
+    name = "protos_perfetto_metrics_webview_protos",
+    srcs = [
+        "protos/perfetto/metrics/webview/all_webview_metrics.proto",
+        "protos/perfetto/metrics/webview/webview_jank_approximation.proto",
+    ],
+    visibility = [
+        PERFETTO_CONFIG.proto_library_visibility,
+    ],
+    deps = [
+        ":protos_perfetto_metrics_android_protos",
+        ":protos_perfetto_metrics_protos",
+    ],
+)
+
 # GN target: //protos/perfetto/trace/android:source_set
 perfetto_proto_library(
     name = "protos_perfetto_trace_android_protos",
@@ -4762,6 +4801,7 @@
                ":src_trace_processor_importers_proto_gen_cc_trace_descriptor",
                ":src_trace_processor_importers_proto_gen_cc_track_event_descriptor",
                ":src_trace_processor_metrics_gen_cc_all_chrome_metrics_descriptor",
+               ":src_trace_processor_metrics_gen_cc_all_webview_metrics_descriptor",
                ":src_trace_processor_metrics_gen_cc_metrics_descriptor",
                ":src_trace_processor_metrics_sql_gen_amalgamated_sql_metrics",
                ":src_trace_processor_stdlib_gen_amalgamated_stdlib",
@@ -4905,6 +4945,7 @@
                ":src_trace_processor_importers_proto_gen_cc_trace_descriptor",
                ":src_trace_processor_importers_proto_gen_cc_track_event_descriptor",
                ":src_trace_processor_metrics_gen_cc_all_chrome_metrics_descriptor",
+               ":src_trace_processor_metrics_gen_cc_all_webview_metrics_descriptor",
                ":src_trace_processor_metrics_gen_cc_metrics_descriptor",
                ":src_trace_processor_metrics_sql_gen_amalgamated_sql_metrics",
                ":src_trace_processor_stdlib_gen_amalgamated_stdlib",
@@ -5113,6 +5154,7 @@
                ":src_trace_processor_importers_proto_gen_cc_trace_descriptor",
                ":src_trace_processor_importers_proto_gen_cc_track_event_descriptor",
                ":src_trace_processor_metrics_gen_cc_all_chrome_metrics_descriptor",
+               ":src_trace_processor_metrics_gen_cc_all_webview_metrics_descriptor",
                ":src_trace_processor_metrics_gen_cc_metrics_descriptor",
                ":src_trace_processor_metrics_sql_gen_amalgamated_sql_metrics",
                ":src_trace_processor_stdlib_gen_amalgamated_stdlib",
diff --git a/protos/perfetto/metrics/metrics.proto b/protos/perfetto/metrics/metrics.proto
index 80122e5..8b5e5e4 100644
--- a/protos/perfetto/metrics/metrics.proto
+++ b/protos/perfetto/metrics/metrics.proto
@@ -247,4 +247,7 @@
 
   // Chrome metrics.
   extensions 1001 to 2000;
+
+  // WebView metrics.
+  extensions 2001 to 2500;
 }
diff --git a/protos/perfetto/metrics/perfetto_merged_metrics.proto b/protos/perfetto/metrics/perfetto_merged_metrics.proto
index 8d6e0c9..2fc2bae 100644
--- a/protos/perfetto/metrics/perfetto_merged_metrics.proto
+++ b/protos/perfetto/metrics/perfetto_merged_metrics.proto
@@ -2116,6 +2116,9 @@
 
   // Chrome metrics.
   extensions 1001 to 2000;
+
+  // WebView metrics.
+  extensions 2001 to 2500;
 }
 
 // End of protos/perfetto/metrics/metrics.proto
diff --git a/protos/perfetto/metrics/webview/BUILD.gn b/protos/perfetto/metrics/webview/BUILD.gn
new file mode 100644
index 0000000..744794c
--- /dev/null
+++ b/protos/perfetto/metrics/webview/BUILD.gn
@@ -0,0 +1,32 @@
+# Copyright (C) 2023 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.
+
+import("../../../../gn/proto_library.gni")
+
+perfetto_proto_library("@TYPE@") {
+  proto_generators = [ "source_set" ]
+  deps = [ "..:@TYPE@" ]
+  sources = [
+    "all_webview_metrics.proto",
+    "webview_jank_approximation.proto",
+  ]
+}
+
+perfetto_proto_library("descriptor") {
+  proto_generators = [ "descriptor" ]
+  import_dirs = [ "${perfetto_protobuf_src_dir}" ]
+  generate_descriptor = "all_webview_metrics.descriptor"
+  deps = [ ":source_set" ]
+  sources = [ "all_webview_metrics.proto" ]
+}
diff --git a/protos/perfetto/metrics/webview/all_webview_metrics.proto b/protos/perfetto/metrics/webview/all_webview_metrics.proto
new file mode 100644
index 0000000..d929d6b
--- /dev/null
+++ b/protos/perfetto/metrics/webview/all_webview_metrics.proto
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2023 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/metrics.proto";
+import "protos/perfetto/metrics/webview/webview_jank_approximation.proto";
+
+extend TraceMetrics {
+  optional WebViewJankApproximation webview_jank_approximation = 2001;
+}
\ No newline at end of file
diff --git a/protos/perfetto/metrics/webview/webview_jank_approximation.proto b/protos/perfetto/metrics/webview/webview_jank_approximation.proto
new file mode 100644
index 0000000..0d01a77
--- /dev/null
+++ b/protos/perfetto/metrics/webview/webview_jank_approximation.proto
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2023 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;
+
+message WebViewJankApproximation {
+  required int32 webview_janks = 1;
+  required int32 webview_janks_without_startup = 2;
+  required int32 webview_app_janks = 3;
+  required int32 webview_total_janks = 4;
+  required int32 total_janks = 5;
+}
diff --git a/python/generators/diff_tests/runner.py b/python/generators/diff_tests/runner.py
index 6219c25..7cb316a 100644
--- a/python/generators/diff_tests/runner.py
+++ b/python/generators/diff_tests/runner.py
@@ -391,7 +391,9 @@
       metrics_descriptor_paths = [
           os.path.join(metrics_protos_path, 'metrics.descriptor'),
           os.path.join(metrics_protos_path, 'chrome',
-                       'all_chrome_metrics.descriptor')
+                       'all_chrome_metrics.descriptor'),
+          os.path.join(metrics_protos_path, 'webview',
+                       'all_webview_metrics.descriptor')
       ]
     result_str = ""
 
diff --git a/python/perfetto/trace_processor/metrics.descriptor b/python/perfetto/trace_processor/metrics.descriptor
index ab45d2f..9aa5fe5 100644
--- a/python/perfetto/trace_processor/metrics.descriptor
+++ b/python/perfetto/trace_processor/metrics.descriptor
Binary files differ
diff --git a/python/perfetto/trace_processor/metrics.descriptor.sha1 b/python/perfetto/trace_processor/metrics.descriptor.sha1
index e350a9a..0a69bdf 100644
--- a/python/perfetto/trace_processor/metrics.descriptor.sha1
+++ b/python/perfetto/trace_processor/metrics.descriptor.sha1
@@ -2,5 +2,5 @@
 // SHA1(tools/gen_binary_descriptors)
 // 6886b319e65925c037179e71a803b8473d06dc7d
 // SHA1(protos/perfetto/metrics/metrics.proto)
-// 5cdfe579a9253cbaea9dcf23dc66388282429c92
+// b07fa0b4ad2deed79d2d8cc320f70502e19eee0c
   
\ No newline at end of file
diff --git a/src/trace_processor/metrics/BUILD.gn b/src/trace_processor/metrics/BUILD.gn
index 8ac796e..5a9757b 100644
--- a/src/trace_processor/metrics/BUILD.gn
+++ b/src/trace_processor/metrics/BUILD.gn
@@ -28,6 +28,11 @@
   descriptor_target = "../../../protos/perfetto/metrics/chrome:descriptor"
 }
 
+perfetto_cc_proto_descriptor("gen_cc_all_webview_metrics_descriptor") {
+  descriptor_name = "all_webview_metrics.descriptor"
+  descriptor_target = "../../../protos/perfetto/metrics/webview:descriptor"
+}
+
 source_set("metrics") {
   sources = [
     "metrics.cc",
@@ -47,6 +52,7 @@
   ]
   public_deps = [
     ":gen_cc_all_chrome_metrics_descriptor",
+    ":gen_cc_all_webview_metrics_descriptor",
     ":gen_cc_metrics_descriptor",
     "../util",
     "../util:descriptors",
diff --git a/src/trace_processor/metrics/sql/webview/BUILD.gn b/src/trace_processor/metrics/sql/webview/BUILD.gn
index 8c08b3d..2a24c97 100644
--- a/src/trace_processor/metrics/sql/webview/BUILD.gn
+++ b/src/trace_processor/metrics/sql/webview/BUILD.gn
@@ -18,5 +18,8 @@
 assert(enable_perfetto_trace_processor_sqlite)
 
 perfetto_sql_source_set("webview") {
-  sources = [ "webview_power_usage.sql" ]
+  sources = [
+    "webview_jank_approximation.sql",
+    "webview_power_usage.sql",
+  ]
 }
diff --git a/src/trace_processor/metrics/sql/webview/webview_jank_approximation.sql b/src/trace_processor/metrics/sql/webview/webview_jank_approximation.sql
new file mode 100644
index 0000000..6b3f449
--- /dev/null
+++ b/src/trace_processor/metrics/sql/webview/webview_jank_approximation.sql
@@ -0,0 +1,148 @@
+--
+-- Copyright 2023 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.
+
+-- We approximate WebView-related app janks by selecting WebView renderer
+-- slices and overlapping them with app jank slices for known apps.
+
+-- Select all WebView processes
+DROP VIEW IF EXISTS webview_processes;
+CREATE VIEW webview_processes AS
+SELECT * FROM process
+WHERE name IN ('com.google.android.gm',
+  'com.google.android.googlequicksearchbox',
+  'com.google.android.apps.searchlite',
+  'com.google.android.apps.magazines');
+
+-- Select all system processes
+DROP VIEW IF EXISTS system_processes;
+CREATE VIEW system_processes AS
+SELECT * FROM process
+WHERE name IN ('com.android.systemui',
+  '/system/bin/surfaceflinger',
+  'system_server');
+
+-- Select all slices related to startup
+DROP TABLE IF EXISTS webview_browser_startup_slices;
+CREATE TABLE webview_browser_startup_slices AS
+SELECT slice.id AS browser_startup_id, slice.ts, slice.dur
+FROM slice
+WHERE name = 'WebViewChromium.init';
+
+-- Select all scheduler slices from WebView renderer processes
+DROP TABLE IF EXISTS webview_renderer_slices;
+CREATE TABLE webview_renderer_slices AS
+SELECT sched_slice.id as renderer_id, sched_slice.ts, sched_slice.dur
+FROM sched_slice
+JOIN thread
+USING(utid)
+JOIN process
+USING (upid)
+WHERE process.name GLOB '*webview*Sand*';
+
+-- Select all jank slices
+DROP TABLE IF EXISTS all_self_jank_slices;
+CREATE TABLE all_self_jank_slices AS
+SELECT *
+FROM actual_frame_timeline_slice
+WHERE jank_type NOT IN ('None', 'Buffer Stuffing')
+  AND jank_tag = 'Self Jank';
+
+-- Select all jank slices from WebView processes
+-- @column id Id of jank slice from a WebView process
+-- @column ts Timestamp of the start of jank slice in a WebView process (in nanoseconds)
+-- @column dur Duration of jank slice in a WebView process (in nanoseconds)
+DROP VIEW IF EXISTS webview_app_jank_slices;
+CREATE VIEW webview_app_jank_slices AS
+SELECT * FROM all_self_jank_slices
+WHERE upid IN (SELECT upid FROM webview_processes);
+
+-- Select all jank slices from all processes except system processes
+-- @column id Id of jank slice from all processes except system processes
+-- @column ts Timestamp of the start of jank slice from all processes except system processes (in nanoseconds)
+-- @column dur Duration of the jank slice from all processes except system processes (in nanoseconds)
+DROP VIEW IF EXISTS webview_all_app_jank_slices;
+CREATE VIEW webview_all_app_jank_slices AS
+SELECT * FROM all_self_jank_slices
+WHERE upid NOT IN (SELECT upid FROM system_processes);
+
+-- Select jank slices from WebView processes overlapping WebView renderer
+-- scheduler slices
+-- @column id Id of jank slice from WebView processes overlapping WebView renderer
+-- @column ts Timestamp of the start of jank slice from WebView processes overlapping WebView renderer (in nanoseconds)
+-- @column dur Duration of jank slice from WebView processes overlapping WebView renderer (in nanoseconds)
+DROP TABLE IF EXISTS webview_jank_slices;
+CREATE VIRTUAL TABLE webview_jank_slices
+USING SPAN_JOIN(webview_renderer_slices,
+                webview_app_jank_slices);
+
+-- Select jank slices overlapping WebView startup slices
+-- @column id Id of jank slice overlapping WebView startup slices
+-- @column ts Timestamp of the start of jank slice overlapping WebView startup slices (in nanoseconds)
+-- @column dur Duration of jank slice overlapping WebView startup slices (in nanoseconds)
+DROP TABLE IF EXISTS webview_browser_startup_jank_slices;
+CREATE VIRTUAL TABLE webview_browser_startup_jank_slices
+USING SPAN_JOIN(webview_browser_startup_slices,
+               webview_app_jank_slices);
+
+-- Select jank slices from all processes except system processes overlapping
+-- WebView renderer scheduler slices
+-- @column id Id of jank slice from all processes except system processes overlapping WebView renderer scheduler slices
+-- @column ts Timestamp of the start of jank slice from all processes except system processes overlapping WebView renderer scheduler slices (in nanoseconds)
+-- @column dur Duration of jank slice from all processes except system processes overlapping WebView renderer scheduler slices (in nanoseconds)
+DROP TABLE IF EXISTS webview_total_jank_slices;
+CREATE VIRTUAL TABLE webview_total_jank_slices
+USING SPAN_JOIN(webview_renderer_slices,
+                webview_all_app_jank_slices);
+
+-- Select jank slices from WebView processes overlapping WebView renderer
+-- scheduler slices excluding WebView startup slices
+-- @column id Id of jank slice from WebView processes overlapping WebView renderer scheduler slices excluding WebView startup slices
+-- @column ts Timestamp of the start of jank slice from WebView processes overlapping WebView renderer scheduler slices excluding WebView startup slices (in nanoseconds)
+-- @column dur Duration of jank slice from WebView processes overlapping WebView renderer scheduler slices excluding WebView startup slices (in nanoseconds)
+DROP VIEW IF EXISTS webview_janks_slices_without_startup;
+CREATE VIEW webview_janks_slices_without_startup AS
+SELECT * FROM webview_jank_slices
+WHERE id NOT IN (SELECT id FROM webview_browser_startup_jank_slices);
+
+-- Summary for all types of janks
+-- @column webview_janks janks in WebView apps that overlap with WebView renderer
+-- @column webview_janks_without_startup same as above but excluding startup
+-- @column webview_app_janks janks in WebView apps
+-- @column webview_total_janks janks in all apps (except system) that overlap with WebView renderer
+-- @column total_janks janks in all apps (except system)
+DROP VIEW IF EXISTS webview_jank_approximation_summary;
+CREATE VIEW webview_jank_approximation_summary AS
+WITH wvj AS (SELECT COUNT(DISTINCT(id)) AS webview_janks
+  FROM webview_jank_slices),
+wvjwos AS (SELECT COUNT(DISTINCT(id))
+  AS webview_janks_without_startup FROM webview_janks_slices_without_startup),
+wvaj AS (SELECT COUNT(DISTINCT(id))
+  AS webview_app_janks FROM webview_app_jank_slices),
+wvtj AS (SELECT COUNT(DISTINCT(id)) AS webview_total_janks
+  FROM webview_total_jank_slices),
+tj AS (SELECT COUNT(DISTINCT(id))
+  AS total_janks FROM webview_all_app_jank_slices)
+SELECT *
+from wvj, wvjwos, wvaj, wvtj, tj;
+
+DROP VIEW IF EXISTS webview_jank_approximation_output;
+CREATE VIEW webview_jank_approximation_output AS
+SELECT WebViewJankApproximation(
+  'webview_janks', (SELECT webview_janks FROM webview_jank_approximation_summary),
+  'webview_janks_without_startup', (SELECT webview_janks_without_startup FROM webview_jank_approximation_summary),
+  'webview_app_janks', (SELECT webview_app_janks FROM webview_jank_approximation_summary),
+  'webview_total_janks', (SELECT webview_total_janks FROM webview_jank_approximation_summary),
+  'total_janks', (SELECT total_janks FROM webview_jank_approximation_summary)
+);
\ No newline at end of file
diff --git a/src/trace_processor/trace_processor_impl.cc b/src/trace_processor/trace_processor_impl.cc
index 68fbf51..ee3f5d9 100644
--- a/src/trace_processor/trace_processor_impl.cc
+++ b/src/trace_processor/trace_processor_impl.cc
@@ -90,6 +90,7 @@
 #include "protos/perfetto/trace/trace_packet.pbzero.h"
 
 #include "src/trace_processor/metrics/all_chrome_metrics.descriptor.h"
+#include "src/trace_processor/metrics/all_webview_metrics.descriptor.h"
 #include "src/trace_processor/metrics/metrics.descriptor.h"
 #include "src/trace_processor/metrics/metrics.h"
 #include "src/trace_processor/metrics/sql/amalgamated_sql_metrics.h"
@@ -428,6 +429,8 @@
                          skip_prefixes);
   tp->ExtendMetricsProto(kAllChromeMetricsDescriptor.data(),
                          kAllChromeMetricsDescriptor.size(), skip_prefixes);
+  tp->ExtendMetricsProto(kAllWebviewMetricsDescriptor.data(),
+                         kAllWebviewMetricsDescriptor.size(), skip_prefixes);
 
   // TODO(lalitm): remove this special casing and change
   // SanitizeMetricMountPaths if/when we move all protos for builtin metrics to
diff --git a/src/trace_processor/trace_processor_shell.cc b/src/trace_processor/trace_processor_shell.cc
index 1b02b27..da08183 100644
--- a/src/trace_processor/trace_processor_shell.cc
+++ b/src/trace_processor/trace_processor_shell.cc
@@ -49,6 +49,7 @@
 #include "perfetto/trace_processor/read_trace.h"
 #include "perfetto/trace_processor/trace_processor.h"
 #include "src/trace_processor/metrics/all_chrome_metrics.descriptor.h"
+#include "src/trace_processor/metrics/all_webview_metrics.descriptor.h"
 #include "src/trace_processor/metrics/metrics.descriptor.h"
 #include "src/trace_processor/metrics/metrics.h"
 #include "src/trace_processor/read_trace_internal.h"
@@ -1327,6 +1328,9 @@
   ExtendPoolWithBinaryDescriptor(pool, kAllChromeMetricsDescriptor.data(),
                                  kAllChromeMetricsDescriptor.size(),
                                  skip_prefixes);
+  ExtendPoolWithBinaryDescriptor(pool, kAllWebviewMetricsDescriptor.data(),
+                                 kAllWebviewMetricsDescriptor.size(),
+                                 skip_prefixes);
   return base::OkStatus();
 }
 
diff --git a/test/data/webview_jank.pb.sha256 b/test/data/webview_jank.pb.sha256
new file mode 100644
index 0000000..359858d
--- /dev/null
+++ b/test/data/webview_jank.pb.sha256
@@ -0,0 +1 @@
+c9c268e09755625d8b5fad404ccca2e657a8b061417d7e10f03984887e942548
\ No newline at end of file
diff --git a/test/trace_processor/diff_tests/include_index.py b/test/trace_processor/diff_tests/include_index.py
index 1d216a0..caab798 100644
--- a/test/trace_processor/diff_tests/include_index.py
+++ b/test/trace_processor/diff_tests/include_index.py
@@ -87,6 +87,7 @@
 from diff_tests.track_event.tests import TrackEvent
 from diff_tests.translation.tests import Translation
 from diff_tests.ufs.tests import Ufs
+from diff_tests.webview.tests import WebView
 
 sys.path.pop()
 
@@ -167,4 +168,5 @@
       *TablesSched(index_path, 'tables', 'TablesSched').fetch(),
       *TrackEvent(index_path, 'track_event', 'TrackEvent').fetch(),
       *Translation(index_path, 'translation', 'Translation').fetch(),
+      *WebView(index_path, 'webview', 'WebView').fetch(),
   ]
diff --git a/test/trace_processor/diff_tests/webview/tests.py b/test/trace_processor/diff_tests/webview/tests.py
new file mode 100644
index 0000000..ea6200b
--- /dev/null
+++ b/test/trace_processor/diff_tests/webview/tests.py
@@ -0,0 +1,36 @@
+#!/usr/bin/env python3
+# Copyright (C) 2023 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 a
+#
+#      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.
+
+from python.generators.diff_tests.testing import Path, DataPath, Metric
+from python.generators.diff_tests.testing import Csv, Json, TextProto
+from python.generators.diff_tests.testing import DiffTestBlueprint
+from python.generators.diff_tests.testing import TestSuite
+
+
+class WebView(TestSuite):
+
+  def test_webview_jank_approximation_metric(self):
+    return DiffTestBlueprint(
+        trace=DataPath('webview_jank.pb'),
+        query=Metric('webview_jank_approximation'),
+        out=TextProto(r"""
+            [perfetto.protos.webview_jank_approximation] {
+                webview_janks: 4
+                webview_janks_without_startup: 4
+                webview_app_janks: 12
+                webview_total_janks: 4
+                total_janks: 12
+            }
+            """))