Add chrome_unsymbolized_args metric

Bug: b/220179588
Change-Id: I541c87163227b739f360d0a43edfe8e9e1dbcd57
diff --git a/Android.bp b/Android.bp
index 448e0d3..8b40b5b 100644
--- a/Android.bp
+++ b/Android.bp
@@ -3826,6 +3826,7 @@
         "protos/perfetto/metrics/chrome/slice_names.proto",
         "protos/perfetto/metrics/chrome/test_chrome_metric.proto",
         "protos/perfetto/metrics/chrome/touch_jank.proto",
+        "protos/perfetto/metrics/chrome/unsymbolized_args.proto",
         "protos/perfetto/metrics/chrome/user_event_hashes.proto",
         "protos/perfetto/metrics/custom_options.proto",
         "protos/perfetto/metrics/metrics.proto",
@@ -8617,6 +8618,7 @@
         "src/trace_processor/metrics/sql/chrome/chrome_slice_names.sql",
         "src/trace_processor/metrics/sql/chrome/chrome_tasks.sql",
         "src/trace_processor/metrics/sql/chrome/chrome_thread_slice.sql",
+        "src/trace_processor/metrics/sql/chrome/chrome_unsymbolized_args.sql",
         "src/trace_processor/metrics/sql/chrome/chrome_user_event_hashes.sql",
         "src/trace_processor/metrics/sql/chrome/cpu_time_by_category.sql",
         "src/trace_processor/metrics/sql/chrome/cpu_time_by_rail_mode.sql",
diff --git a/BUILD b/BUILD
index d293f71..dcfb216 100644
--- a/BUILD
+++ b/BUILD
@@ -1210,6 +1210,7 @@
         "src/trace_processor/metrics/sql/chrome/chrome_slice_names.sql",
         "src/trace_processor/metrics/sql/chrome/chrome_tasks.sql",
         "src/trace_processor/metrics/sql/chrome/chrome_thread_slice.sql",
+        "src/trace_processor/metrics/sql/chrome/chrome_unsymbolized_args.sql",
         "src/trace_processor/metrics/sql/chrome/chrome_user_event_hashes.sql",
         "src/trace_processor/metrics/sql/chrome/cpu_time_by_category.sql",
         "src/trace_processor/metrics/sql/chrome/cpu_time_by_rail_mode.sql",
@@ -2938,6 +2939,7 @@
         "protos/perfetto/metrics/chrome/slice_names.proto",
         "protos/perfetto/metrics/chrome/test_chrome_metric.proto",
         "protos/perfetto/metrics/chrome/touch_jank.proto",
+        "protos/perfetto/metrics/chrome/unsymbolized_args.proto",
         "protos/perfetto/metrics/chrome/user_event_hashes.proto",
     ],
     visibility = [
diff --git a/protos/perfetto/metrics/chrome/BUILD.gn b/protos/perfetto/metrics/chrome/BUILD.gn
index e88997f..3a77c75 100644
--- a/protos/perfetto/metrics/chrome/BUILD.gn
+++ b/protos/perfetto/metrics/chrome/BUILD.gn
@@ -34,6 +34,7 @@
     "slice_names.proto",
     "test_chrome_metric.proto",
     "touch_jank.proto",
+    "unsymbolized_args.proto",
     "user_event_hashes.proto",
   ]
 }
diff --git a/protos/perfetto/metrics/chrome/all_chrome_metrics.proto b/protos/perfetto/metrics/chrome/all_chrome_metrics.proto
index a0b8763..1965df3 100644
--- a/protos/perfetto/metrics/chrome/all_chrome_metrics.proto
+++ b/protos/perfetto/metrics/chrome/all_chrome_metrics.proto
@@ -32,6 +32,7 @@
 import "protos/perfetto/metrics/chrome/test_chrome_metric.proto";
 import "protos/perfetto/metrics/chrome/touch_jank.proto";
 import "protos/perfetto/metrics/chrome/user_event_hashes.proto";
+import "protos/perfetto/metrics/chrome/unsymbolized_args.proto";
 
 // TODO(lalitm): rename metrics below to include a "chrome_" prefix.
 extend TraceMetrics {
@@ -48,4 +49,5 @@
   optional ChromeUserEventHashes chrome_user_event_hashes = 1011;
   optional ChromePerformanceMarkHashes chrome_performance_mark_hashes = 1012;
   optional ChromeSliceNames chrome_slice_names = 1013;
+  optional ChromeUnsymbolizedArgs chrome_unsymbolized_args = 1014;
 }
diff --git a/protos/perfetto/metrics/chrome/unsymbolized_args.proto b/protos/perfetto/metrics/chrome/unsymbolized_args.proto
new file mode 100644
index 0000000..aa8f5c0
--- /dev/null
+++ b/protos/perfetto/metrics/chrome/unsymbolized_args.proto
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2022 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;
+
+// This message is similar to perfetto.protos.UnsymbolizedFrames, but this is
+// for trace event arguments, not stack frames. Keeping them separate because
+// the protos may evolve independently.
+message ChromeUnsymbolizedArgs {
+  message Arg {
+    optional string module = 1;
+    optional string build_id = 2;
+    optional int64 address = 3;
+
+    // In some cases (Chrome/Webview) the ID that should be used to query
+    // symbols in Google's internal tera-scale symbolization service is !=
+    // `build_id` and requires some mangling.
+    // This field is == 'build_id` for non-chromium cases, and is the breakpad
+    // module ID (with lowercase hex digics) for chromium cases.
+    optional string google_lookup_id = 4;
+  }
+
+  repeated Arg args = 1;
+}
diff --git a/src/trace_processor/metrics/sql/BUILD.gn b/src/trace_processor/metrics/sql/BUILD.gn
index faadbdd..d0cf3d6 100644
--- a/src/trace_processor/metrics/sql/BUILD.gn
+++ b/src/trace_processor/metrics/sql/BUILD.gn
@@ -95,6 +95,7 @@
   "chrome/chrome_performance_mark_hashes.sql",
   "chrome/chrome_processes.sql",
   "chrome/chrome_slice_names.sql",
+  "chrome/chrome_unsymbolized_args.sql",
   "chrome/chrome_tasks.sql",
   "chrome/chrome_thread_slice.sql",
   "chrome/chrome_user_event_hashes.sql",
diff --git a/src/trace_processor/metrics/sql/chrome/chrome_unsymbolized_args.sql b/src/trace_processor/metrics/sql/chrome/chrome_unsymbolized_args.sql
new file mode 100644
index 0000000..934ee05
--- /dev/null
+++ b/src/trace_processor/metrics/sql/chrome/chrome_unsymbolized_args.sql
@@ -0,0 +1,58 @@
+--
+-- Copyright 2022 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.
+--
+
+-- To get mangled stack profile mappings.
+SELECT RUN_METRIC('android/unsymbolized_frames.sql');
+
+DROP VIEW IF EXISTS chrome_unsymbolized_args_view;
+
+CREATE VIEW chrome_unsymbolized_args_view AS
+SELECT ChromeUnsymbolizedArgs_Arg(
+    'module', spm.name,
+    'build_id', spm.build_id,
+    'address', unsymbolized_arg.rel_pc,
+    'google_lookup_id', spm.google_lookup_id
+) AS arg_proto
+FROM
+  (
+    SELECT arg_rel_pc.rel_pc AS rel_pc, arg_mapping_id.mapping_id AS mapping_id
+    FROM
+      (
+        SELECT arg_set_id, int_value AS rel_pc
+        FROM args
+        WHERE key = "chrome_mojo_event_info.mojo_interface_method.native_symbol.rel_pc"
+      ) arg_rel_pc
+    JOIN
+      (
+        SELECT
+          arg_set_id,
+          int_value AS mapping_id
+        FROM args
+        WHERE key = "chrome_mojo_event_info.mojo_interface_method.native_symbol.mapping_id"
+      ) arg_mapping_id
+      ON arg_rel_pc.arg_set_id = arg_mapping_id.arg_set_id
+  ) unsymbolized_arg
+JOIN mangled_stack_profile_mapping spm
+  ON unsymbolized_arg.mapping_id = spm.id
+WHERE spm.build_id != '';
+
+DROP VIEW IF EXISTS chrome_unsymbolized_args_output;
+
+CREATE VIEW chrome_unsymbolized_args_output AS
+SELECT ChromeUnsymbolizedArgs(
+    'args',
+    (SELECT RepeatedField(arg_proto) FROM chrome_unsymbolized_args_view)
+);
diff --git a/test/trace_processor/chrome/index b/test/trace_processor/chrome/index
index 759d809..a1318e7 100644
--- a/test/trace_processor/chrome/index
+++ b/test/trace_processor/chrome/index
@@ -69,3 +69,6 @@
 
 # Chrome tasks.
 ../../data/chrome_page_load_all_categories_not_extended.pftrace.gz chrome_tasks.sql chrome_tasks.out
+
+# Unsymbolized args.
+unsymbolized_args.textproto chrome_unsymbolized_args unsymbolized_args.out
diff --git a/test/trace_processor/chrome/unsymbolized_args.out b/test/trace_processor/chrome/unsymbolized_args.out
new file mode 100644
index 0000000..61d7cfc
--- /dev/null
+++ b/test/trace_processor/chrome/unsymbolized_args.out
@@ -0,0 +1,14 @@
+[perfetto.protos.chrome_unsymbolized_args]: {
+  args {
+     module: "/liblib.so"
+     build_id: "6275696c642d6964"
+     address: 123
+     google_lookup_id: "6275696c642d6964"
+   }
+   args {
+     module: "/libmonochrome_64.so"
+     build_id: "7f0715c286f8b16c10e4ad349cda3b9b56c7a773"
+     address: 234
+     google_lookup_id: "c215077ff8866cb110e4ad349cda3b9b0"
+   }
+}
\ No newline at end of file
diff --git a/test/trace_processor/chrome/unsymbolized_args.textproto b/test/trace_processor/chrome/unsymbolized_args.textproto
new file mode 100644
index 0000000..75e21de
--- /dev/null
+++ b/test/trace_processor/chrome/unsymbolized_args.textproto
@@ -0,0 +1,118 @@
+packet {
+  incremental_state_cleared: true
+  trusted_packet_sequence_id: 1
+  timestamp: 0
+  interned_data {
+    mapping_paths {
+      iid: 1
+      str: "liblib.so"
+    }
+    mapping_paths {
+        iid: 2
+        str: "libmonochrome_64.so"
+    }
+    build_ids {
+      iid: 2
+      str: "build-id"
+    }
+    # This build id has to have a specific format to test ELF->Breakpad
+    # demangling. Taken from
+    # test/trace_processor/profiling/heap_profile_no_symbols.textproto
+    build_ids {
+        iid: 3
+        str: "\x7f\x07\x15\xc2\x86\xf8\xb1\x6c\x10\xe4\xad\x34\x9c\xda\x3b\x9b\x56\xc7\xa7\x73"
+    }
+    mappings {
+        iid: 1
+        path_string_ids: 1
+        build_id: 2
+    }
+    mappings {
+        iid: 2
+        path_string_ids: 2
+        build_id: 3
+    }
+    unsymbolized_source_locations {
+        iid: 1
+        mapping_id: 1
+        rel_pc: 123
+    }
+    unsymbolized_source_locations {
+        iid: 2
+        mapping_id: 2
+        rel_pc: 234
+    }
+  }
+}
+# Track for slice begin/end events.
+packet {
+  timestamp: 0
+  trusted_packet_sequence_id: 1
+  track_descriptor {
+    uuid: 12345
+    thread {
+      pid: 123
+      tid: 345
+    }
+    parent_uuid: 0
+    chrome_thread {
+      thread_type: THREAD_POOL_FG_WORKER
+    }
+  }
+}
+
+# Slice begin with mojo arg
+packet {
+  trusted_packet_sequence_id: 1
+  timestamp: 10
+  track_event {
+    track_uuid: 12345
+    categories: "cat1"
+    type: 1
+    name: "slice1"
+    chrome_mojo_event_info {
+        mojo_interface_method_iid: 1
+    }
+  }
+}
+
+# Another slice begin with mojo arg
+packet {
+  trusted_packet_sequence_id: 1
+  timestamp: 11
+  track_event {
+    track_uuid: 12345
+    categories: "cat1"
+    type: 1
+    name: "slice2"
+    chrome_mojo_event_info {
+        mojo_interface_method_iid: 2
+    }
+  }
+}
+
+
+# Second slice end
+packet {
+  trusted_packet_sequence_id: 1
+  timestamp: 6000
+  track_event {
+    track_uuid: 12345
+    categories: "cat1"
+    name: "slice2"
+    type: 2
+  }
+}
+
+# First slice end
+
+packet {
+  trusted_packet_sequence_id: 1
+  timestamp: 6001
+  track_event {
+    track_uuid: 12345
+    categories: "cat1"
+    name: "slice1"
+    type: 2
+  }
+}
\ No newline at end of file