Add Android Binder metric

This metric tallies the number of Binder transactions per process. It will only work on traces with the binder_driver atrace flag enabled.

Bug: 224855483
Test: out/trace_processor_shell --run-metrics android_binder <local trace>
Test: tools/diff_test_trace_processor.py --query-metric-filter android_binder out/trace_processor_shell
Change-Id: I01e29242fde6d5303f5371f237ada3479de1ae46
diff --git a/Android.bp b/Android.bp
index a7c4677..3e771c0 100644
--- a/Android.bp
+++ b/Android.bp
@@ -3692,6 +3692,7 @@
     srcs: [
         "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",
@@ -3760,6 +3761,7 @@
     srcs: [
         "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",
@@ -8386,6 +8388,7 @@
     name: "perfetto_src_trace_processor_metrics_sql_gen_amalgamated_sql_metrics",
     srcs: [
         "src/trace_processor/metrics/sql/android/android_batt.sql",
+        "src/trace_processor/metrics/sql/android/android_binder.sql",
         "src/trace_processor/metrics/sql/android/android_camera.sql",
         "src/trace_processor/metrics/sql/android/android_camera_unagg.sql",
         "src/trace_processor/metrics/sql/android/android_cpu.sql",
diff --git a/BUILD b/BUILD
index a981ee3..3c90cb2 100644
--- a/BUILD
+++ b/BUILD
@@ -1051,6 +1051,7 @@
     name = "src_trace_processor_metrics_sql_gen_amalgamated_sql_metrics",
     srcs = [
         "src/trace_processor/metrics/sql/android/android_batt.sql",
+        "src/trace_processor/metrics/sql/android/android_binder.sql",
         "src/trace_processor/metrics/sql/android/android_camera.sql",
         "src/trace_processor/metrics/sql/android/android_camera_unagg.sql",
         "src/trace_processor/metrics/sql/android/android_cpu.sql",
@@ -2783,6 +2784,7 @@
     srcs = [
         "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",
diff --git a/protos/perfetto/metrics/android/BUILD.gn b/protos/perfetto/metrics/android/BUILD.gn
index c32d093..8091fb7 100644
--- a/protos/perfetto/metrics/android/BUILD.gn
+++ b/protos/perfetto/metrics/android/BUILD.gn
@@ -22,6 +22,7 @@
   sources = [
     "android_trusty_workqueues.proto",
     "batt_metric.proto",
+    "binder_metric.proto",
     "camera_metric.proto",
     "camera_unagg_metric.proto",
     "cpu_metric.proto",
diff --git a/protos/perfetto/metrics/android/binder_metric.proto b/protos/perfetto/metrics/android/binder_metric.proto
new file mode 100644
index 0000000..f60d022
--- /dev/null
+++ b/protos/perfetto/metrics/android/binder_metric.proto
@@ -0,0 +1,32 @@
+/*
+ * 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 metric provides per-process Binder statistics for traces with binder_driver enabled
+// Specifically, transactions are categorized and counted
+message AndroidBinderMetric {
+  message PerProcessBreakdown {
+    optional string process_name = 1;
+    optional uint32 pid = 2;
+    optional string slice_name = 3;
+    optional uint32 count = 4;
+  }
+
+  repeated PerProcessBreakdown process_breakdown = 1;
+}
\ No newline at end of file
diff --git a/protos/perfetto/metrics/metrics.proto b/protos/perfetto/metrics/metrics.proto
index 8d521cc..55571c4 100644
--- a/protos/perfetto/metrics/metrics.proto
+++ b/protos/perfetto/metrics/metrics.proto
@@ -54,6 +54,7 @@
 import "protos/perfetto/metrics/android/trace_quality.proto";
 import "protos/perfetto/metrics/android/android_trusty_workqueues.proto";
 import "protos/perfetto/metrics/android/unsymbolized_frames.proto";
+import "protos/perfetto/metrics/android/binder_metric.proto";
 
 // Trace processor metadata
 message TraceMetadata {
@@ -99,7 +100,7 @@
 
 // Root message for all Perfetto-based metrics.
 //
-// Next id: 46
+// Next id: 47
 message TraceMetrics {
   reserved 4, 10, 13, 14, 16, 19;
 
@@ -222,6 +223,9 @@
   // Summary of other concurrent trace recording.
   optional AndroidOtherTracesMetric android_other_traces = 45;
 
+  // Per-process Binder transaction metrics.
+  optional AndroidBinderMetric android_binder = 46;
+
   // Demo extensions.
   extensions 450 to 499;
 
diff --git a/protos/perfetto/metrics/perfetto_merged_metrics.proto b/protos/perfetto/metrics/perfetto_merged_metrics.proto
index 8989e9f..c99b45a 100644
--- a/protos/perfetto/metrics/perfetto_merged_metrics.proto
+++ b/protos/perfetto/metrics/perfetto_merged_metrics.proto
@@ -65,6 +65,22 @@
 
 // End of protos/perfetto/metrics/android/batt_metric.proto
 
+// Begin of protos/perfetto/metrics/android/binder_metric.proto
+
+// This metric provides per-process Binder statistics for traces with binder_driver enabled
+// Specifically, transactions are categorized and counted
+message AndroidBinderMetric {
+  message PerProcessBreakdown {
+    optional string process_name = 1;
+    optional uint32 pid = 2;
+    optional string slice_name = 3;
+    optional uint32 count = 4;
+  }
+
+  repeated PerProcessBreakdown process_breakdown = 1;
+}
+// End of protos/perfetto/metrics/android/binder_metric.proto
+
 // Begin of protos/perfetto/metrics/android/camera_metric.proto
 
 message AndroidCameraMetric {
@@ -1524,7 +1540,7 @@
 
 // Root message for all Perfetto-based metrics.
 //
-// Next id: 46
+// Next id: 47
 message TraceMetrics {
   reserved 4, 10, 13, 14, 16, 19;
 
@@ -1647,6 +1663,9 @@
   // Summary of other concurrent trace recording.
   optional AndroidOtherTracesMetric android_other_traces = 45;
 
+  // Per-process Binder transaction metrics.
+  optional AndroidBinderMetric android_binder = 46;
+
   // Demo extensions.
   extensions 450 to 499;
 
diff --git a/python/perfetto/trace_processor/metrics.descriptor b/python/perfetto/trace_processor/metrics.descriptor
index 5588fc6..81b6b62 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 9128379..8d1166a 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)
 // c4a38769074f8a8c2ffbf514b267919b5f2d47df
 // SHA1(protos/perfetto/metrics/metrics.proto)
-// 345fbfdfcdd221b820374ee35469035d1d86c5c1
+// 1555061bf1527fce27559876acaf3c31f82bf1d2
   
\ No newline at end of file
diff --git a/src/trace_processor/metrics/sql/BUILD.gn b/src/trace_processor/metrics/sql/BUILD.gn
index f90c2a0..0ad6c5b 100644
--- a/src/trace_processor/metrics/sql/BUILD.gn
+++ b/src/trace_processor/metrics/sql/BUILD.gn
@@ -18,6 +18,7 @@
   "trace_metadata.sql",
   "trace_stats.sql",
   "android/android_batt.sql",
+  "android/android_binder.sql",
   "android/android_camera.sql",
   "android/android_camera_unagg.sql",
   "android/android_cpu.sql",
diff --git a/src/trace_processor/metrics/sql/android/android_binder.sql b/src/trace_processor/metrics/sql/android/android_binder.sql
new file mode 100644
index 0000000..752eed8
--- /dev/null
+++ b/src/trace_processor/metrics/sql/android/android_binder.sql
@@ -0,0 +1,47 @@
+--
+-- 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.
+--
+
+-- Count Binder transactions per process
+CREATE VIEW binder_metrics_by_process AS
+SELECT
+  process.name as process_name,
+  process.pid as pid,
+  slice.name as slice_name,
+  COUNT(*) as event_count
+FROM slice
+  INNER JOIN thread_track ON slice.track_id=thread_track.id
+  INNER JOIN thread ON thread.utid=thread_track.utid
+  INNER JOIN process ON thread.upid=process.upid
+WHERE
+  slice.name like 'binder%'
+GROUP BY
+  process_name,
+  slice_name;
+
+CREATE VIEW android_binder_output AS
+SELECT AndroidBinderMetric(
+  'process_breakdown', (
+    SELECT RepeatedField(
+      AndroidBinderMetric_PerProcessBreakdown(
+        'process_name', process_name,
+        'pid', pid,
+        'slice_name', slice_name,
+        'count', event_count
+      )
+    )
+    FROM binder_metrics_by_process
+  )
+);
diff --git a/test/trace_processor/parsing/android_binder.out b/test/trace_processor/parsing/android_binder.out
new file mode 100644
index 0000000..ef53b12
--- /dev/null
+++ b/test/trace_processor/parsing/android_binder.out
@@ -0,0 +1,20 @@
+android_binder {
+  process_breakdown {
+    process_name: "test_process_a"
+    pid: 1
+    slice_name: "binder transaction"
+    count: 2
+  }
+  process_breakdown {
+    process_name: "test_process_b"
+    pid: 2
+    slice_name: "binder reply"
+    count: 1
+  }
+  process_breakdown {
+    process_name: "test_process_c"
+    pid: 3
+    slice_name: "binder reply"
+    count: 1
+  }
+}
\ No newline at end of file
diff --git a/test/trace_processor/parsing/android_binder.py b/test/trace_processor/parsing/android_binder.py
new file mode 100644
index 0000000..9cc29ba
--- /dev/null
+++ b/test/trace_processor/parsing/android_binder.py
@@ -0,0 +1,49 @@
+#!/usr/bin/env python3
+# 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.
+
+from os import sys, path
+
+import synth_common
+
+PROCESS_A_NAME = 'test_process_a'
+PROCESS_B_NAME = 'test_process_b'
+PROCESS_C_NAME = 'test_process_c'
+PROCESS_A_PID = 1
+PROCESS_B_PID = 2
+PROCESS_C_PID = 3
+PROCESS_A_PPID = 4
+PROCESS_B_PPID = 5
+PROCESS_C_PPID = 6
+PROCESS_A_TID = 7
+# These values need to be the same to keep track of process ids in kernel space
+PROCESS_B_TID = PROCESS_B_PID
+PROCESS_C_TID = PROCESS_C_PID
+
+trace = synth_common.create_trace()
+trace.add_packet()
+trace.add_process(PROCESS_A_PID, PROCESS_A_PPID, PROCESS_A_NAME)
+trace.add_process(PROCESS_B_PID, PROCESS_B_PPID, PROCESS_B_NAME)
+trace.add_process(PROCESS_C_PID, PROCESS_C_PPID, PROCESS_C_NAME)
+trace.add_thread(PROCESS_A_TID, PROCESS_A_PID, cmdline='Binder')
+trace.add_ftrace_packet(cpu=0)
+
+trace.add_binder_transaction(transaction_id=1, ts_start=1, ts_end=2, tid=PROCESS_A_TID,
+                             pid=PROCESS_A_PID, reply_id=2, reply_ts_start=3, reply_ts_end=4,
+                             reply_tid=PROCESS_B_TID, reply_pid=PROCESS_B_PID)
+trace.add_binder_transaction(transaction_id=3, ts_start=5, ts_end=6, tid=PROCESS_A_TID,
+                             pid=PROCESS_A_PID, reply_id=4, reply_ts_start=7, reply_ts_end=8,
+                             reply_tid=PROCESS_C_TID, reply_pid=PROCESS_C_PID)
+
+sys.stdout.buffer.write(trace.trace.SerializeToString())
\ No newline at end of file
diff --git a/test/trace_processor/parsing/index b/test/trace_processor/parsing/index
index 8011022..3ceeed7 100644
--- a/test/trace_processor/parsing/index
+++ b/test/trace_processor/parsing/index
@@ -153,3 +153,6 @@
 # coming from stderr before the TRACE: marker. See b/208691037.
 ../../data/atrace_uncompressed_b_208691037 sched_smoke.sql atrace_uncompressed_sched_count.out
 otheruuids.textproto android_other_traces otheruuids_android_other_traces.out
+
+# Per-process Binder transaction metrics
+android_binder.py android_binder android_binder.out