Add unaggregated metrics for Garbage Collection

Test: tools/diff_test_trace_processor.py <path to trace processor binary> --name-filter=".*android_garbage*"
Bug: 325046706
Change-Id: Ia225e95a06b422077635f1f3a5dc7f155a1e6f23
diff --git a/Android.bp b/Android.bp
index e84e70b..cc7b4ad 100644
--- a/Android.bp
+++ b/Android.bp
@@ -5139,6 +5139,7 @@
         "protos/perfetto/metrics/android/android_boot.proto",
         "protos/perfetto/metrics/android/android_boot_unagg.proto",
         "protos/perfetto/metrics/android/android_frame_timeline_metric.proto",
+        "protos/perfetto/metrics/android/android_garbage_collection_unagg_metric.proto",
         "protos/perfetto/metrics/android/android_sysui_notifications_blocking_calls_metric.proto",
         "protos/perfetto/metrics/android/android_trusty_workqueues.proto",
         "protos/perfetto/metrics/android/anr_metric.proto",
@@ -5226,6 +5227,7 @@
         "protos/perfetto/metrics/android/android_boot.proto",
         "protos/perfetto/metrics/android/android_boot_unagg.proto",
         "protos/perfetto/metrics/android/android_frame_timeline_metric.proto",
+        "protos/perfetto/metrics/android/android_garbage_collection_unagg_metric.proto",
         "protos/perfetto/metrics/android/android_sysui_notifications_blocking_calls_metric.proto",
         "protos/perfetto/metrics/android/android_trusty_workqueues.proto",
         "protos/perfetto/metrics/android/anr_metric.proto",
@@ -5296,6 +5298,7 @@
         "protos/perfetto/metrics/android/android_boot.proto",
         "protos/perfetto/metrics/android/android_boot_unagg.proto",
         "protos/perfetto/metrics/android/android_frame_timeline_metric.proto",
+        "protos/perfetto/metrics/android/android_garbage_collection_unagg_metric.proto",
         "protos/perfetto/metrics/android/android_sysui_notifications_blocking_calls_metric.proto",
         "protos/perfetto/metrics/android/android_trusty_workqueues.proto",
         "protos/perfetto/metrics/android/anr_metric.proto",
@@ -11649,6 +11652,7 @@
         "src/trace_processor/metrics/sql/android/android_dvfs.sql",
         "src/trace_processor/metrics/sql/android/android_fastrpc.sql",
         "src/trace_processor/metrics/sql/android/android_frame_timeline_metric.sql",
+        "src/trace_processor/metrics/sql/android/android_garbage_collection_unagg.sql",
         "src/trace_processor/metrics/sql/android/android_gpu.sql",
         "src/trace_processor/metrics/sql/android/android_hwcomposer.sql",
         "src/trace_processor/metrics/sql/android/android_hwui_metric.sql",
diff --git a/BUILD b/BUILD
index 6a44d74..0fd0cb8 100644
--- a/BUILD
+++ b/BUILD
@@ -1949,6 +1949,7 @@
         "src/trace_processor/metrics/sql/android/android_dvfs.sql",
         "src/trace_processor/metrics/sql/android/android_fastrpc.sql",
         "src/trace_processor/metrics/sql/android/android_frame_timeline_metric.sql",
+        "src/trace_processor/metrics/sql/android/android_garbage_collection_unagg.sql",
         "src/trace_processor/metrics/sql/android/android_gpu.sql",
         "src/trace_processor/metrics/sql/android/android_hwcomposer.sql",
         "src/trace_processor/metrics/sql/android/android_hwui_metric.sql",
@@ -4296,6 +4297,7 @@
         "protos/perfetto/metrics/android/android_boot.proto",
         "protos/perfetto/metrics/android/android_boot_unagg.proto",
         "protos/perfetto/metrics/android/android_frame_timeline_metric.proto",
+        "protos/perfetto/metrics/android/android_garbage_collection_unagg_metric.proto",
         "protos/perfetto/metrics/android/android_sysui_notifications_blocking_calls_metric.proto",
         "protos/perfetto/metrics/android/android_trusty_workqueues.proto",
         "protos/perfetto/metrics/android/anr_metric.proto",
diff --git a/protos/perfetto/metrics/android/BUILD.gn b/protos/perfetto/metrics/android/BUILD.gn
index 9caeaef..33f4195 100644
--- a/protos/perfetto/metrics/android/BUILD.gn
+++ b/protos/perfetto/metrics/android/BUILD.gn
@@ -26,6 +26,7 @@
     "android_boot.proto",
     "android_boot_unagg.proto",
     "android_frame_timeline_metric.proto",
+    "android_garbage_collection_unagg_metric.proto",
     "android_sysui_notifications_blocking_calls_metric.proto",
     "android_trusty_workqueues.proto",
     "anr_metric.proto",
diff --git a/protos/perfetto/metrics/android/android_boot_unagg.proto b/protos/perfetto/metrics/android/android_boot_unagg.proto
index 12bf12b..c209840 100644
--- a/protos/perfetto/metrics/android/android_boot_unagg.proto
+++ b/protos/perfetto/metrics/android/android_boot_unagg.proto
@@ -19,7 +19,11 @@
 package perfetto.protos;
 
 import "protos/perfetto/metrics/android/app_process_starts_metric.proto";
+import "protos/perfetto/metrics/android/android_garbage_collection_unagg_metric.proto";
 
 message AndroidBootUnagg {
+  // Looks at all apps started after boot complete broadcast.
   optional AndroidAppProcessStartsMetric android_app_process_start_metric = 1;
+  // Looks at all GC that occurs after boot complete broadcast.
+  optional AndroidGarbageCollectionUnaggMetric android_post_boot_gc_metric = 2;
 }
diff --git a/protos/perfetto/metrics/android/android_garbage_collection_unagg_metric.proto b/protos/perfetto/metrics/android/android_garbage_collection_unagg_metric.proto
new file mode 100644
index 0000000..075b9a0
--- /dev/null
+++ b/protos/perfetto/metrics/android/android_garbage_collection_unagg_metric.proto
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2024 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 AndroidGarbageCollectionUnaggMetric {
+  message GarbageCollectionEvent {
+    // Name of thread running garbage collection.
+    optional string thread_name = 1;
+    // Name of process running garbage collection.
+    optional string process_name = 2;
+    // Type of garbage collection.
+    optional string gc_type = 3;
+    // Whether gargage collection is mark compact or copying.
+    optional int64 is_mark_compact = 4;
+    // MB reclaimed after garbage collection.
+    optional double reclaimed_mb = 5;
+    // Minimum heap size in MB during garbage collection.
+    optional double min_heap_mb = 6;
+    // Maximum heap size in MB during garbage collection.
+    optional double max_heap_mb = 7;
+    // Memory reclaimed per ms of running time.
+    optional double mb_per_ms_of_running_gc = 8;
+    // Memory reclaimed per ms of wall time.
+    optional double mb_per_ms_of_wall_gc = 9;
+    // Garbage collection wall duration.
+    optional int64 gc_dur = 10;
+    // Garbage collection duration spent executing on CPU.
+    optional int64 gc_running_dur = 11;
+    // Garbage collection duration spent waiting for CPU.
+    optional int64 gc_runnable_dur = 12;
+    // Garbage collection duration spent waiting in the Linux kernel on IO.
+    optional int64 gc_unint_io_dur = 13;
+    // Garbage collection duration spent waiting in the Linux kernel without IO.
+    optional int64 gc_unint_non_io_dur = 14;
+    // Garbage collection duration spent waiting in interruptible sleep.
+    optional int64 gc_int_dur = 15;
+    // ts of the event in trace.
+    optional int64 gc_ts = 16;
+    // pid of the event in trace.
+    optional int64 pid = 17;
+    // tid of the event in trace.
+    optional int64 tid = 18;
+    // monotonic duration of event.
+    optional int64 gc_monotonic_dur = 19;
+  }
+  repeated GarbageCollectionEvent gc_events = 1;
+}
\ No newline at end of file
diff --git a/protos/perfetto/metrics/android/app_process_starts_metric.proto b/protos/perfetto/metrics/android/app_process_starts_metric.proto
index dafce94..e8457df 100644
--- a/protos/perfetto/metrics/android/app_process_starts_metric.proto
+++ b/protos/perfetto/metrics/android/app_process_starts_metric.proto
@@ -18,7 +18,6 @@
 
 package perfetto.protos;
 
-// Looks at all apps started after boot complete broadcast.
 message AndroidAppProcessStartsMetric {
   // Next id : 4
   message ProcessStart {
diff --git a/protos/perfetto/metrics/metrics.proto b/protos/perfetto/metrics/metrics.proto
index 8bd4d38..5130b29 100644
--- a/protos/perfetto/metrics/metrics.proto
+++ b/protos/perfetto/metrics/metrics.proto
@@ -21,6 +21,7 @@
 import "protos/perfetto/metrics/android/ad_services_metric.proto";
 import "protos/perfetto/metrics/android/android_boot.proto";
 import "protos/perfetto/metrics/android/android_boot_unagg.proto";
+import "protos/perfetto/metrics/android/android_garbage_collection_unagg_metric.proto";
 import "protos/perfetto/metrics/android/sysui_notif_shade_list_builder_metric.proto";
 import "protos/perfetto/metrics/android/sysui_update_notif_on_ui_mode_changed_metric.proto";
 import "protos/perfetto/metrics/android/android_frame_timeline_metric.proto";
@@ -286,6 +287,9 @@
   // Android boot unaggregated metrics.
   optional AndroidBootUnagg android_boot_unagg = 62;
 
+  // Android garbage collection metrics
+  optional AndroidGarbageCollectionUnaggMetric android_garbage_collection_unagg = 63;
+
   // 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 58f9731..eb9ab74 100644
--- a/protos/perfetto/metrics/perfetto_merged_metrics.proto
+++ b/protos/perfetto/metrics/perfetto_merged_metrics.proto
@@ -193,9 +193,55 @@
 
 // End of protos/perfetto/metrics/android/android_boot.proto
 
+// Begin of protos/perfetto/metrics/android/android_garbage_collection_unagg_metric.proto
+
+message AndroidGarbageCollectionUnaggMetric {
+  message GarbageCollectionEvent {
+    // Name of thread running garbage collection.
+    optional string thread_name = 1;
+    // Name of process running garbage collection.
+    optional string process_name = 2;
+    // Type of garbage collection.
+    optional string gc_type = 3;
+    // Whether gargage collection is mark compact or copying.
+    optional int64 is_mark_compact = 4;
+    // MB reclaimed after garbage collection.
+    optional double reclaimed_mb = 5;
+    // Minimum heap size in MB during garbage collection.
+    optional double min_heap_mb = 6;
+    // Maximum heap size in MB during garbage collection.
+    optional double max_heap_mb = 7;
+    // Memory reclaimed per ms of running time.
+    optional double mb_per_ms_of_running_gc = 8;
+    // Memory reclaimed per ms of wall time.
+    optional double mb_per_ms_of_wall_gc = 9;
+    // Garbage collection wall duration.
+    optional int64 gc_dur = 10;
+    // Garbage collection duration spent executing on CPU.
+    optional int64 gc_running_dur = 11;
+    // Garbage collection duration spent waiting for CPU.
+    optional int64 gc_runnable_dur = 12;
+    // Garbage collection duration spent waiting in the Linux kernel on IO.
+    optional int64 gc_unint_io_dur = 13;
+    // Garbage collection duration spent waiting in the Linux kernel without IO.
+    optional int64 gc_unint_non_io_dur = 14;
+    // Garbage collection duration spent waiting in interruptible sleep.
+    optional int64 gc_int_dur = 15;
+    // ts of the event in trace.
+    optional int64 gc_ts = 16;
+    // pid of the event in trace.
+    optional int64 pid = 17;
+    // tid of the event in trace.
+    optional int64 tid = 18;
+    // monotonic duration of event.
+    optional int64 gc_monotonic_dur = 19;
+  }
+  repeated GarbageCollectionEvent gc_events = 1;
+}
+// End of protos/perfetto/metrics/android/android_garbage_collection_unagg_metric.proto
+
 // Begin of protos/perfetto/metrics/android/app_process_starts_metric.proto
 
-// Looks at all apps started after boot complete broadcast.
 message AndroidAppProcessStartsMetric {
   // Next id : 4
   message ProcessStart {
@@ -223,7 +269,10 @@
 // Begin of protos/perfetto/metrics/android/android_boot_unagg.proto
 
 message AndroidBootUnagg {
+  // Looks at all apps started after boot complete broadcast.
   optional AndroidAppProcessStartsMetric android_app_process_start_metric = 1;
+  // Looks at all GC that occurs after boot complete broadcast.
+  optional AndroidGarbageCollectionUnaggMetric android_post_boot_gc_metric = 2;
 }
 
 // End of protos/perfetto/metrics/android/android_boot_unagg.proto
@@ -2642,6 +2691,9 @@
   // Android boot unaggregated metrics.
   optional AndroidBootUnagg android_boot_unagg = 62;
 
+  // Android garbage collection metrics
+  optional AndroidGarbageCollectionUnaggMetric android_garbage_collection_unagg = 63;
+
   // Demo extensions.
   extensions 450 to 499;
 
diff --git a/python/perfetto/trace_processor/metrics.descriptor b/python/perfetto/trace_processor/metrics.descriptor
index 9783b76..5c04c0a 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 c92ba32..0aa6e64 100644
--- a/src/trace_processor/metrics/sql/android/BUILD.gn
+++ b/src/trace_processor/metrics/sql/android/BUILD.gn
@@ -35,6 +35,7 @@
     "android_dvfs.sql",
     "android_fastrpc.sql",
     "android_frame_timeline_metric.sql",
+    "android_garbage_collection_unagg.sql",
     "android_gpu.sql",
     "android_hwcomposer.sql",
     "android_hwui_metric.sql",
diff --git a/src/trace_processor/metrics/sql/android/android_boot_unagg.sql b/src/trace_processor/metrics/sql/android/android_boot_unagg.sql
index 2444b22..a1ba096 100644
--- a/src/trace_processor/metrics/sql/android/android_boot_unagg.sql
+++ b/src/trace_processor/metrics/sql/android/android_boot_unagg.sql
@@ -15,6 +15,8 @@
 --
 
 INCLUDE PERFETTO MODULE android.app_process_starts;
+INCLUDE PERFETTO MODULE android.garbage_collection;
+INCLUDE PERFETTO MODULE android.suspend;
 
 DROP VIEW IF EXISTS android_boot_unagg_output;
 CREATE PERFETTO VIEW android_boot_unagg_output AS
@@ -71,6 +73,35 @@
             ASC LIMIT 1 )
             AND reason = "service"
         )
-    )
-  )
+    )),
+    'android_post_boot_gc_metric', (SELECT AndroidGarbageCollectionUnaggMetric(
+        'gc_events', (
+            SELECT RepeatedField(
+                AndroidGarbageCollectionUnaggMetric_GarbageCollectionEvent(
+                    'thread_name', thread_name,
+                    'process_name', process_name,
+                    'gc_type', gc_type,
+                    'is_mark_compact', is_mark_compact,
+                    'reclaimed_mb', reclaimed_mb,
+                    'min_heap_mb', min_heap_mb,
+                    'max_heap_mb', max_heap_mb,
+                    'mb_per_ms_of_running_gc', reclaimed_mb/(gc_running_dur/1e6),
+                    'mb_per_ms_of_wall_gc', reclaimed_mb/(gc_dur/1e6),
+                    'gc_dur', gc_dur,
+                    'gc_running_dur', gc_running_dur,
+                    'gc_runnable_dur', gc_runnable_dur,
+                    'gc_unint_io_dur', gc_unint_io_dur,
+                    'gc_unint_non_io_dur', gc_unint_non_io_dur,
+                    'gc_int_dur', gc_int_dur,
+                    'gc_ts', gc_ts,
+                    'tid', tid,
+                    'pid', pid,
+                    'gc_monotonic_dur', _extract_duration_without_suspend(gc_ts, gc_dur)
+                )
+            ) FROM android_garbage_collection_events WHERE gc_ts > (SELECT COALESCE(MIN(ts), 0)
+                FROM thread_slice WHERE name GLOB "*android.intent.action.USER_UNLOCKED*" ORDER BY ts
+                ASC LIMIT 1
+            )
+        )
+    ))
 );
diff --git a/src/trace_processor/metrics/sql/android/android_garbage_collection_unagg.sql b/src/trace_processor/metrics/sql/android/android_garbage_collection_unagg.sql
new file mode 100644
index 0000000..ee54b7e
--- /dev/null
+++ b/src/trace_processor/metrics/sql/android/android_garbage_collection_unagg.sql
@@ -0,0 +1,47 @@
+--
+-- Copyright 2024 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.
+--
+
+INCLUDE PERFETTO MODULE android.garbage_collection;
+INCLUDE PERFETTO MODULE android.suspend;
+
+DROP VIEW IF EXISTS android_garbage_collection_unagg_output;
+CREATE PERFETTO VIEW android_garbage_collection_unagg_output AS
+SELECT AndroidGarbageCollectionUnaggMetric(
+  'gc_events', (
+    SELECT RepeatedField(
+      AndroidGarbageCollectionUnaggMetric_GarbageCollectionEvent(
+        'thread_name', thread_name,
+        'process_name', process_name,
+        'gc_type', gc_type,
+        'is_mark_compact', is_mark_compact,
+        'reclaimed_mb', reclaimed_mb,
+        'min_heap_mb', min_heap_mb,
+        'max_heap_mb', max_heap_mb,
+        'mb_per_ms_of_running_gc', reclaimed_mb/(gc_running_dur/1e6),
+        'mb_per_ms_of_wall_gc', reclaimed_mb/(gc_dur/1e6),
+        'gc_dur', gc_dur,
+        'gc_running_dur', gc_running_dur,
+        'gc_runnable_dur', gc_runnable_dur,
+        'gc_unint_io_dur', gc_unint_io_dur,
+        'gc_unint_non_io_dur', gc_unint_non_io_dur,
+        'gc_int_dur', gc_int_dur,
+        'gc_ts', gc_ts,
+        'tid', tid,
+        'pid', pid,
+        'gc_monotonic_dur', _extract_duration_without_suspend(gc_ts, gc_dur)
+      )) FROM android_garbage_collection_events
+  )
+);
diff --git a/test/trace_processor/diff_tests/metrics/android/android_boot_unagg.out b/test/trace_processor/diff_tests/metrics/android/android_boot_unagg.out
index 568da0b..cb0d712 100644
--- a/test/trace_processor/diff_tests/metrics/android/android_boot_unagg.out
+++ b/test/trace_processor/diff_tests/metrics/android/android_boot_unagg.out
@@ -214,4 +214,80 @@
       total_dur: 583162190
     }
   }
+  android_post_boot_gc_metric {
+    gc_events {
+      thread_name: "HeapTaskDaemon"
+      process_name: "com.google.android.deskclock"
+      gc_type: "full"
+      is_mark_compact: 1
+      reclaimed_mb: 3.1430000000000002
+      min_heap_mb: 2.754000
+      max_heap_mb: 5.897000
+      mb_per_ms_of_running_gc: 0.3262420579054222
+      mb_per_ms_of_wall_gc: 0.004718018639325977
+      gc_dur: 666169475
+      gc_running_dur: 9633951
+      gc_runnable_dur: 44371461
+      gc_unint_io_dur: 0
+      gc_unint_non_io_dur: 0
+      gc_int_dur: 0
+      gc_ts: 39041818011
+      tid: 3185
+      pid: 3162
+      gc_monotonic_dur: 666169475
+    }
+    gc_events {
+      thread_name: "HeapTaskDaemon"
+      process_name: "com.google.android.apps.nexuslauncher"
+      gc_type: "full"
+      is_mark_compact: 1
+      reclaimed_mb: 10.640000
+      min_heap_mb: 6.861000
+      max_heap_mb: 17.501000
+      mb_per_ms_of_running_gc: 93.68918788028213
+      mb_per_ms_of_wall_gc: 0.18073523433053545
+      gc_dur: 58870646
+      gc_running_dur: 113567
+      gc_runnable_dur: 0
+      gc_unint_io_dur: 0
+      gc_unint_non_io_dur: 0
+      gc_int_dur: 0
+      gc_ts: 39849615741
+      tid: 2534
+      pid: 2523
+      gc_monotonic_dur: 58870646
+    }
+    gc_events {
+      thread_name: "HeapTaskDaemon"
+      process_name: "com.google.android.apps.wellbeing"
+      gc_type: "full"
+      is_mark_compact: 1
+      gc_dur: 168393585
+      gc_running_dur: 1714233
+      gc_runnable_dur: 28482219
+      gc_unint_io_dur: 0
+      gc_unint_non_io_dur: 0
+      gc_int_dur: -1
+      gc_ts: 40022150450
+      tid: 2917
+      pid: 2909
+      gc_monotonic_dur: 168393585
+    }
+    gc_events {
+      thread_name: "HeapTaskDaemon"
+      process_name: "com.google.android.euicc"
+      gc_type: "full"
+      is_mark_compact: 1
+      gc_dur: 148630605
+      gc_running_dur: 4148763
+      gc_runnable_dur: -1
+      gc_unint_io_dur: 0
+      gc_unint_non_io_dur: 0
+      gc_int_dur: 0
+      gc_ts: 40041913430
+      tid: 2865
+      pid: 2855
+      gc_monotonic_dur: 148630605
+    }
+  }
 }
\ No newline at end of file
diff --git a/test/trace_processor/diff_tests/metrics/android/android_garbage_collection_unagg.out b/test/trace_processor/diff_tests/metrics/android/android_garbage_collection_unagg.out
new file mode 100644
index 0000000..1341536
--- /dev/null
+++ b/test/trace_processor/diff_tests/metrics/android/android_garbage_collection_unagg.out
@@ -0,0 +1,76 @@
+android_garbage_collection_unagg {
+  gc_events {
+    thread_name: "HeapTaskDaemon"
+    process_name: "com.google.android.deskclock"
+    gc_type: "full"
+    is_mark_compact: 1
+    reclaimed_mb: 3.1430000000000002
+    min_heap_mb: 2.754000
+    max_heap_mb: 5.897000
+    mb_per_ms_of_running_gc: 0.3262420579054222
+    mb_per_ms_of_wall_gc: 0.004718018639325977
+    gc_dur: 666169475
+    gc_running_dur: 9633951
+    gc_runnable_dur: 44371461
+    gc_unint_io_dur: 0
+    gc_unint_non_io_dur: 0
+    gc_int_dur: 0
+    gc_ts: 39041818011
+    tid: 3185
+    pid: 3162
+    gc_monotonic_dur: 666169475
+  }
+  gc_events {
+    thread_name: "HeapTaskDaemon"
+    process_name: "com.google.android.apps.nexuslauncher"
+    gc_type: "full"
+    is_mark_compact: 1
+    reclaimed_mb: 10.640000
+    min_heap_mb: 6.861000
+    max_heap_mb: 17.501000
+    mb_per_ms_of_running_gc: 93.68918788028213
+    mb_per_ms_of_wall_gc: 0.18073523433053545
+    gc_dur: 58870646
+    gc_running_dur: 113567
+    gc_runnable_dur: 0
+    gc_unint_io_dur: 0
+    gc_unint_non_io_dur: 0
+    gc_int_dur: 0
+    gc_ts: 39849615741
+    tid: 2534
+    pid: 2523
+    gc_monotonic_dur: 58870646
+  }
+  gc_events {
+    thread_name: "HeapTaskDaemon"
+    process_name: "com.google.android.apps.wellbeing"
+    gc_type: "full"
+    is_mark_compact: 1
+    gc_dur: 168393585
+    gc_running_dur: 1714233
+    gc_runnable_dur: 28482219
+    gc_unint_io_dur: 0
+    gc_unint_non_io_dur: 0
+    gc_int_dur: -1
+    gc_ts: 40022150450
+    tid: 2917
+    pid: 2909
+    gc_monotonic_dur: 168393585
+  }
+  gc_events {
+    thread_name: "HeapTaskDaemon"
+    process_name: "com.google.android.euicc"
+    gc_type: "full"
+    is_mark_compact: 1
+    gc_dur: 148630605
+    gc_running_dur: 4148763
+    gc_runnable_dur: -1
+    gc_unint_io_dur: 0
+    gc_unint_non_io_dur: 0
+    gc_int_dur: 0
+    gc_ts: 40041913430
+    tid: 2865
+    pid: 2855
+    gc_monotonic_dur: 148630605
+  }
+}
\ No newline at end of file
diff --git a/test/trace_processor/diff_tests/metrics/android/tests.py b/test/trace_processor/diff_tests/metrics/android/tests.py
index cb0c0a2..f5de58f 100644
--- a/test/trace_processor/diff_tests/metrics/android/tests.py
+++ b/test/trace_processor/diff_tests/metrics/android/tests.py
@@ -229,4 +229,10 @@
       trace=DataPath('android_postboot_unlock.pftrace'),
       query=Metric("android_app_process_starts"),
       out=Path('android_app_process_starts.out')
-    )
\ No newline at end of file
+    )
+
+  def test_android_garbage_collection(self):
+    return DiffTestBlueprint(
+        trace=DataPath('android_postboot_unlock.pftrace'),
+        query=Metric('android_garbage_collection_unagg'),
+        out=Path('android_garbage_collection_unagg.out'))
\ No newline at end of file