Add Android Monitor Contention Aggregated Metric

Test: <trace_processer_shell> --run-metrics android_monitor_contention_agg <trace>
Test: tools/diff_test_trace_processor.py <trace_processer_shell> --name-filter=.*monitor_contention_agg*
Bug: 296403757
Change-Id: Ia27dfa70301b011b4d2870322c01fb7898e3053a
diff --git a/Android.bp b/Android.bp
index 83823dc..aaff342 100644
--- a/Android.bp
+++ b/Android.bp
@@ -4616,6 +4616,7 @@
         "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_agg_metric.proto",
         "protos/perfetto/metrics/android/monitor_contention_metric.proto",
         "protos/perfetto/metrics/android/multiuser_metric.proto",
         "protos/perfetto/metrics/android/network_metric.proto",
@@ -4696,6 +4697,7 @@
         "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_agg_metric.proto",
         "protos/perfetto/metrics/android/monitor_contention_metric.proto",
         "protos/perfetto/metrics/android/multiuser_metric.proto",
         "protos/perfetto/metrics/android/network_metric.proto",
@@ -4758,6 +4760,7 @@
         "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_agg_metric.proto",
         "protos/perfetto/metrics/android/monitor_contention_metric.proto",
         "protos/perfetto/metrics/android/multiuser_metric.proto",
         "protos/perfetto/metrics/android/network_metric.proto",
@@ -10430,6 +10433,7 @@
         "src/trace_processor/metrics/sql/android/android_mem.sql",
         "src/trace_processor/metrics/sql/android/android_mem_unagg.sql",
         "src/trace_processor/metrics/sql/android/android_monitor_contention.sql",
+        "src/trace_processor/metrics/sql/android/android_monitor_contention_agg.sql",
         "src/trace_processor/metrics/sql/android/android_multiuser.sql",
         "src/trace_processor/metrics/sql/android/android_multiuser_populator.sql",
         "src/trace_processor/metrics/sql/android/android_netperf.sql",
diff --git a/BUILD b/BUILD
index 8262e01..dbd0bd1 100644
--- a/BUILD
+++ b/BUILD
@@ -1861,6 +1861,7 @@
         "src/trace_processor/metrics/sql/android/android_mem.sql",
         "src/trace_processor/metrics/sql/android/android_mem_unagg.sql",
         "src/trace_processor/metrics/sql/android/android_monitor_contention.sql",
+        "src/trace_processor/metrics/sql/android/android_monitor_contention_agg.sql",
         "src/trace_processor/metrics/sql/android/android_multiuser.sql",
         "src/trace_processor/metrics/sql/android/android_multiuser_populator.sql",
         "src/trace_processor/metrics/sql/android/android_netperf.sql",
@@ -4097,6 +4098,7 @@
         "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_agg_metric.proto",
         "protos/perfetto/metrics/android/monitor_contention_metric.proto",
         "protos/perfetto/metrics/android/multiuser_metric.proto",
         "protos/perfetto/metrics/android/network_metric.proto",
diff --git a/protos/perfetto/metrics/android/BUILD.gn b/protos/perfetto/metrics/android/BUILD.gn
index bd639d8..74e7a72 100644
--- a/protos/perfetto/metrics/android/BUILD.gn
+++ b/protos/perfetto/metrics/android/BUILD.gn
@@ -51,6 +51,7 @@
     "lmk_reason_metric.proto",
     "mem_metric.proto",
     "mem_unagg_metric.proto",
+    "monitor_contention_agg_metric.proto",
     "monitor_contention_metric.proto",
     "multiuser_metric.proto",
     "network_metric.proto",
diff --git a/protos/perfetto/metrics/android/monitor_contention_agg_metric.proto b/protos/perfetto/metrics/android/monitor_contention_agg_metric.proto
new file mode 100644
index 0000000..43d861e
--- /dev/null
+++ b/protos/perfetto/metrics/android/monitor_contention_agg_metric.proto
@@ -0,0 +1,34 @@
+/*
+ * 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;
+
+ // This metric provides aggregated information about monitor contention graph
+ // in a trace
+message AndroidMonitorContentionAggMetric {
+  // Next id: 2
+  // Stats for Monitor contention aggregated by process.
+  message ProcessAggregation {
+    optional string name = 1;
+    optional int64 total_contention_count = 2;
+    optional int64 total_contention_dur = 3;
+    optional int64 main_thread_contention_count = 4;
+    optional int64 main_thread_contention_dur = 5;
+  }
+  repeated ProcessAggregation process_aggregation = 1;
+}
diff --git a/protos/perfetto/metrics/metrics.proto b/protos/perfetto/metrics/metrics.proto
index feb2d72..94c7666 100644
--- a/protos/perfetto/metrics/metrics.proto
+++ b/protos/perfetto/metrics/metrics.proto
@@ -62,6 +62,7 @@
 import "protos/perfetto/metrics/android/unsymbolized_frames.proto";
 import "protos/perfetto/metrics/android/binder_metric.proto";
 import "protos/perfetto/metrics/android/monitor_contention_metric.proto";
+import "protos/perfetto/metrics/android/monitor_contention_agg_metric.proto";
 
 // Trace processor metadata
 message TraceMetadata {
@@ -107,7 +108,7 @@
 
 // Root message for all Perfetto-based metrics.
 //
-// Next id: 56
+// Next id: 57
 message TraceMetrics {
   reserved 4, 10, 13, 14, 16, 19;
 
@@ -259,6 +260,8 @@
 
   // Metrics for App Not Responding (ANR) errors.
   optional AndroidAnrMetric android_anr = 55;
+  // Aggregated Android Monitor Contention metrics
+  optional AndroidMonitorContentionAggMetric android_monitor_contention_agg = 56;
 
   // 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 588cd05..54a7374 100644
--- a/protos/perfetto/metrics/perfetto_merged_metrics.proto
+++ b/protos/perfetto/metrics/perfetto_merged_metrics.proto
@@ -1382,6 +1382,25 @@
 
 // End of protos/perfetto/metrics/android/mem_unagg_metric.proto
 
+// Begin of protos/perfetto/metrics/android/monitor_contention_agg_metric.proto
+
+ // This metric provides aggregated information about monitor contention graph
+ // in a trace
+message AndroidMonitorContentionAggMetric {
+  // Next id: 2
+  // Stats for Monitor contention aggregated by process.
+  message ProcessAggregation {
+    optional string name = 1;
+    optional int64 total_contention_count = 2;
+    optional int64 total_contention_dur = 3;
+    optional int64 main_thread_contention_count = 4;
+    optional int64 main_thread_contention_dur = 5;
+  }
+  repeated ProcessAggregation process_aggregation = 1;
+}
+
+// End of protos/perfetto/metrics/android/monitor_contention_agg_metric.proto
+
 // Begin of protos/perfetto/metrics/android/monitor_contention_metric.proto
 
 // This metric provides information about the monitor contention graph in a
@@ -2244,7 +2263,7 @@
 
 // Root message for all Perfetto-based metrics.
 //
-// Next id: 56
+// Next id: 57
 message TraceMetrics {
   reserved 4, 10, 13, 14, 16, 19;
 
@@ -2396,6 +2415,8 @@
 
   // Metrics for App Not Responding (ANR) errors.
   optional AndroidAnrMetric android_anr = 55;
+  // Aggregated Android Monitor Contention metrics
+  optional AndroidMonitorContentionAggMetric android_monitor_contention_agg = 56;
 
   // Demo extensions.
   extensions 450 to 499;
diff --git a/python/perfetto/trace_processor/metrics.descriptor b/python/perfetto/trace_processor/metrics.descriptor
index 8f80340..5a432d5 100644
--- a/python/perfetto/trace_processor/metrics.descriptor
+++ b/python/perfetto/trace_processor/metrics.descriptor
Binary files differ
diff --git a/src/trace_processor/metrics/sql/android/BUILD.gn b/src/trace_processor/metrics/sql/android/BUILD.gn
index 92da898..f8c5303 100644
--- a/src/trace_processor/metrics/sql/android/BUILD.gn
+++ b/src/trace_processor/metrics/sql/android/BUILD.gn
@@ -45,6 +45,7 @@
     "android_lmk_reason.sql",
     "android_mem.sql",
     "android_mem_unagg.sql",
+    "android_monitor_contention_agg.sql",
     "android_monitor_contention.sql",
     "android_multiuser.sql",
     "android_multiuser_populator.sql",
diff --git a/src/trace_processor/metrics/sql/android/android_monitor_contention_agg.sql b/src/trace_processor/metrics/sql/android/android_monitor_contention_agg.sql
new file mode 100644
index 0000000..780b079
--- /dev/null
+++ b/src/trace_processor/metrics/sql/android/android_monitor_contention_agg.sql
@@ -0,0 +1,50 @@
+--
+-- 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.
+--
+
+SELECT IMPORT('android.monitor_contention');
+
+DROP VIEW IF EXISTS amc_process_agg;
+CREATE VIEW amc_process_agg AS
+WITH full_contention AS (
+  Select process_name, COUNT(*) as total_contention_count, SUM(dur)
+  as total_contention_dur from android_monitor_contention group by process_name
+),
+main_thread_contention AS
+(
+  Select process_name, COUNT(*) as main_thread_contention_count, SUM(dur)
+  as main_thread_contention_dur from android_monitor_contention
+  where is_blocked_thread_main=1 group by process_name
+)
+SELECT f.process_name, total_contention_count, total_contention_dur,
+ main_thread_contention_count, main_thread_contention_dur
+ from full_contention as f left join main_thread_contention as m on f.process_name = m.process_name;
+
+DROP VIEW IF EXISTS android_monitor_contention_agg_output;
+CREATE VIEW android_monitor_contention_agg_output AS
+SELECT AndroidMonitorContentionAggMetric(
+  'process_aggregation', (
+    SELECT RepeatedField(
+        AndroidMonitorContentionAggMetric_ProcessAggregation(
+            'name', process_name,
+            'total_contention_count', total_contention_count,
+            'total_contention_dur', total_contention_dur,
+            'main_thread_contention_count', main_thread_contention_count,
+            'main_thread_contention_dur', main_thread_contention_dur
+        )
+    )
+    FROM amc_process_agg
+  )
+);
\ No newline at end of file
diff --git a/test/trace_processor/diff_tests/android/tests.py b/test/trace_processor/diff_tests/android/tests.py
index f05f9b1..780fc5b 100644
--- a/test/trace_processor/diff_tests/android/tests.py
+++ b/test/trace_processor/diff_tests/android/tests.py
@@ -486,6 +486,41 @@
         query=Metric('android_monitor_contention'),
         out=Path('android_monitor_contention.out'))
 
+  def test_monitor_contention_agg_metric(self):
+    return DiffTestBlueprint(
+        trace=DataPath('android_monitor_contention_trace.atr'),
+        query=Metric('android_monitor_contention_agg'),
+        out=TextProto(r"""
+        android_monitor_contention_agg {
+          process_aggregation {
+            name: "android.process.media"
+            total_contention_count: 12
+            total_contention_dur: 12893198
+            main_thread_contention_count: 12
+            main_thread_contention_dur: 12893198
+          }
+          process_aggregation {
+            name: "com.android.providers.media.module"
+            total_contention_count: 7
+            total_contention_dur: 169793
+          }
+          process_aggregation {
+            name: "com.android.systemui"
+            total_contention_count: 8
+            total_contention_dur: 9445959
+            main_thread_contention_count: 5
+            main_thread_contention_dur: 9228582
+          }
+          process_aggregation {
+            name: "system_server"
+            total_contention_count: 354
+            total_contention_dur: 358898613
+            main_thread_contention_count: 27
+            main_thread_contention_dur: 36904702
+          }
+        }
+        """))
+
   def test_monitor_contention_graph(self):
     return DiffTestBlueprint(
         trace=DataPath('android_monitor_contention_trace.atr'),