Merge dev/xldrx/counter-track-dynamic-source
diff --git a/Android.bp b/Android.bp
index fa33600..6ae0b48 100644
--- a/Android.bp
+++ b/Android.bp
@@ -637,6 +637,7 @@
         ":perfetto_protos_perfetto_trace_linux_zero_gen",
         ":perfetto_protos_perfetto_trace_minimal_zero_gen",
         ":perfetto_protos_perfetto_trace_non_minimal_zero_gen",
+        ":perfetto_protos_perfetto_trace_perfetto_cpp_gen",
         ":perfetto_protos_perfetto_trace_perfetto_zero_gen",
         ":perfetto_protos_perfetto_trace_power_zero_gen",
         ":perfetto_protos_perfetto_trace_profiling_inline_callstack_zero_gen",
@@ -775,6 +776,7 @@
         "perfetto_protos_perfetto_trace_linux_zero_gen_headers",
         "perfetto_protos_perfetto_trace_minimal_zero_gen_headers",
         "perfetto_protos_perfetto_trace_non_minimal_zero_gen_headers",
+        "perfetto_protos_perfetto_trace_perfetto_cpp_gen_headers",
         "perfetto_protos_perfetto_trace_perfetto_zero_gen_headers",
         "perfetto_protos_perfetto_trace_power_zero_gen_headers",
         "perfetto_protos_perfetto_trace_profiling_inline_callstack_zero_gen_headers",
@@ -943,6 +945,7 @@
         ":perfetto_protos_perfetto_trace_linux_zero_gen",
         ":perfetto_protos_perfetto_trace_minimal_zero_gen",
         ":perfetto_protos_perfetto_trace_non_minimal_zero_gen",
+        ":perfetto_protos_perfetto_trace_perfetto_cpp_gen",
         ":perfetto_protos_perfetto_trace_perfetto_zero_gen",
         ":perfetto_protos_perfetto_trace_power_zero_gen",
         ":perfetto_protos_perfetto_trace_profiling_inline_callstack_zero_gen",
@@ -1056,6 +1059,7 @@
         "perfetto_protos_perfetto_trace_linux_zero_gen_headers",
         "perfetto_protos_perfetto_trace_minimal_zero_gen_headers",
         "perfetto_protos_perfetto_trace_non_minimal_zero_gen_headers",
+        "perfetto_protos_perfetto_trace_perfetto_cpp_gen_headers",
         "perfetto_protos_perfetto_trace_perfetto_zero_gen_headers",
         "perfetto_protos_perfetto_trace_power_zero_gen_headers",
         "perfetto_protos_perfetto_trace_profiling_inline_callstack_zero_gen_headers",
@@ -1184,6 +1188,7 @@
         ":perfetto_protos_perfetto_trace_linux_zero_gen",
         ":perfetto_protos_perfetto_trace_minimal_zero_gen",
         ":perfetto_protos_perfetto_trace_non_minimal_zero_gen",
+        ":perfetto_protos_perfetto_trace_perfetto_cpp_gen",
         ":perfetto_protos_perfetto_trace_perfetto_zero_gen",
         ":perfetto_protos_perfetto_trace_power_zero_gen",
         ":perfetto_protos_perfetto_trace_profiling_inline_callstack_zero_gen",
@@ -1299,6 +1304,7 @@
         "perfetto_protos_perfetto_trace_linux_zero_gen_headers",
         "perfetto_protos_perfetto_trace_minimal_zero_gen_headers",
         "perfetto_protos_perfetto_trace_non_minimal_zero_gen_headers",
+        "perfetto_protos_perfetto_trace_perfetto_cpp_gen_headers",
         "perfetto_protos_perfetto_trace_perfetto_zero_gen_headers",
         "perfetto_protos_perfetto_trace_power_zero_gen_headers",
         "perfetto_protos_perfetto_trace_profiling_inline_callstack_zero_gen_headers",
@@ -1367,6 +1373,7 @@
         "perfetto_protos_perfetto_trace_linux_zero_gen_headers",
         "perfetto_protos_perfetto_trace_minimal_zero_gen_headers",
         "perfetto_protos_perfetto_trace_non_minimal_zero_gen_headers",
+        "perfetto_protos_perfetto_trace_perfetto_cpp_gen_headers",
         "perfetto_protos_perfetto_trace_perfetto_zero_gen_headers",
         "perfetto_protos_perfetto_trace_power_zero_gen_headers",
         "perfetto_protos_perfetto_trace_profiling_inline_callstack_zero_gen_headers",
@@ -3794,6 +3801,7 @@
         "protos/perfetto/trace/perfetto/perfetto_metatrace.proto",
         "protos/perfetto/trace/perfetto/trace_provenance.proto",
         "protos/perfetto/trace/perfetto/tracing_service_event.proto",
+        "protos/perfetto/trace/perfetto/tracing_v2_producer_stats.proto",
         "protos/perfetto/trace/power/android_energy_estimation_breakdown.proto",
         "protos/perfetto/trace/power/android_entity_state_residency.proto",
         "protos/perfetto/trace/power/battery_counters.proto",
@@ -3846,6 +3854,7 @@
         "protos/perfetto/trace/track_event/task_execution.proto",
         "protos/perfetto/trace/track_event/thread_descriptor.proto",
         "protos/perfetto/trace/track_event/track_descriptor.proto",
+        "protos/perfetto/trace/track_event/track_dimension.proto",
         "protos/perfetto/trace/track_event/track_event.proto",
         "protos/perfetto/trace/translation/translation_table.proto",
         "protos/perfetto/trace/trigger.proto",
@@ -8672,6 +8681,7 @@
         "protos/perfetto/trace/perfetto/perfetto_metatrace.proto",
         "protos/perfetto/trace/perfetto/trace_provenance.proto",
         "protos/perfetto/trace/perfetto/tracing_service_event.proto",
+        "protos/perfetto/trace/perfetto/tracing_v2_producer_stats.proto",
         "protos/perfetto/trace/power/android_energy_estimation_breakdown.proto",
         "protos/perfetto/trace/power/android_entity_state_residency.proto",
         "protos/perfetto/trace/power/battery_counters.proto",
@@ -8724,6 +8734,7 @@
         "protos/perfetto/trace/track_event/task_execution.proto",
         "protos/perfetto/trace/track_event/thread_descriptor.proto",
         "protos/perfetto/trace/track_event/track_descriptor.proto",
+        "protos/perfetto/trace/track_event/track_dimension.proto",
         "protos/perfetto/trace/track_event/track_event.proto",
         "protos/perfetto/trace/translation/translation_table.proto",
         "protos/perfetto/trace/trigger.proto",
@@ -10241,6 +10252,7 @@
         "protos/perfetto/trace/track_event/task_execution.proto",
         "protos/perfetto/trace/track_event/thread_descriptor.proto",
         "protos/perfetto/trace/track_event/track_descriptor.proto",
+        "protos/perfetto/trace/track_event/track_dimension.proto",
         "protos/perfetto/trace/track_event/track_event.proto",
     ],
     tools: [
@@ -10346,6 +10358,7 @@
         "protos/perfetto/trace/track_event/task_execution.proto",
         "protos/perfetto/trace/track_event/thread_descriptor.proto",
         "protos/perfetto/trace/track_event/track_descriptor.proto",
+        "protos/perfetto/trace/track_event/track_dimension.proto",
         "protos/perfetto/trace/track_event/track_event.proto",
     ],
     tools: [
@@ -11601,6 +11614,7 @@
         "protos/perfetto/trace/perfetto/perfetto_metatrace.proto",
         "protos/perfetto/trace/perfetto/trace_provenance.proto",
         "protos/perfetto/trace/perfetto/tracing_service_event.proto",
+        "protos/perfetto/trace/perfetto/tracing_v2_producer_stats.proto",
         "protos/perfetto/trace/power/android_energy_estimation_breakdown.proto",
         "protos/perfetto/trace/power/android_entity_state_residency.proto",
         "protos/perfetto/trace/power/battery_counters.proto",
@@ -11653,6 +11667,7 @@
         "protos/perfetto/trace/track_event/task_execution.proto",
         "protos/perfetto/trace/track_event/thread_descriptor.proto",
         "protos/perfetto/trace/track_event/track_descriptor.proto",
+        "protos/perfetto/trace/track_event/track_dimension.proto",
         "protos/perfetto/trace/track_event/track_event.proto",
         "protos/perfetto/trace/translation/translation_table.proto",
         "protos/perfetto/trace/trigger.proto",
@@ -11816,6 +11831,7 @@
         "protos/perfetto/trace/perfetto/perfetto_metatrace.proto",
         "protos/perfetto/trace/perfetto/trace_provenance.proto",
         "protos/perfetto/trace/perfetto/tracing_service_event.proto",
+        "protos/perfetto/trace/perfetto/tracing_v2_producer_stats.proto",
     ],
 }
 
@@ -11835,6 +11851,7 @@
         "external/perfetto/protos/perfetto/trace/perfetto/perfetto_metatrace.gen.cc",
         "external/perfetto/protos/perfetto/trace/perfetto/trace_provenance.gen.cc",
         "external/perfetto/protos/perfetto/trace/perfetto/tracing_service_event.gen.cc",
+        "external/perfetto/protos/perfetto/trace/perfetto/tracing_v2_producer_stats.gen.cc",
     ],
 }
 
@@ -11854,6 +11871,7 @@
         "external/perfetto/protos/perfetto/trace/perfetto/perfetto_metatrace.gen.h",
         "external/perfetto/protos/perfetto/trace/perfetto/trace_provenance.gen.h",
         "external/perfetto/protos/perfetto/trace/perfetto/tracing_service_event.gen.h",
+        "external/perfetto/protos/perfetto/trace/perfetto/tracing_v2_producer_stats.gen.h",
     ],
     export_include_dirs: [
         ".",
@@ -11869,6 +11887,7 @@
         "protos/perfetto/trace/perfetto/perfetto_metatrace.proto",
         "protos/perfetto/trace/perfetto/trace_provenance.proto",
         "protos/perfetto/trace/perfetto/tracing_service_event.proto",
+        "protos/perfetto/trace/perfetto/tracing_v2_producer_stats.proto",
     ],
 }
 
@@ -11887,6 +11906,7 @@
         "external/perfetto/protos/perfetto/trace/perfetto/perfetto_metatrace.pb.cc",
         "external/perfetto/protos/perfetto/trace/perfetto/trace_provenance.pb.cc",
         "external/perfetto/protos/perfetto/trace/perfetto/tracing_service_event.pb.cc",
+        "external/perfetto/protos/perfetto/trace/perfetto/tracing_v2_producer_stats.pb.cc",
     ],
 }
 
@@ -11905,6 +11925,7 @@
         "external/perfetto/protos/perfetto/trace/perfetto/perfetto_metatrace.pb.h",
         "external/perfetto/protos/perfetto/trace/perfetto/trace_provenance.pb.h",
         "external/perfetto/protos/perfetto/trace/perfetto/tracing_service_event.pb.h",
+        "external/perfetto/protos/perfetto/trace/perfetto/tracing_v2_producer_stats.pb.h",
     ],
     export_include_dirs: [
         ".",
@@ -11920,6 +11941,7 @@
         "protos/perfetto/trace/perfetto/perfetto_metatrace.proto",
         "protos/perfetto/trace/perfetto/trace_provenance.proto",
         "protos/perfetto/trace/perfetto/tracing_service_event.proto",
+        "protos/perfetto/trace/perfetto/tracing_v2_producer_stats.proto",
     ],
 }
 
@@ -11939,6 +11961,7 @@
         "external/perfetto/protos/perfetto/trace/perfetto/perfetto_metatrace.pbzero.cc",
         "external/perfetto/protos/perfetto/trace/perfetto/trace_provenance.pbzero.cc",
         "external/perfetto/protos/perfetto/trace/perfetto/tracing_service_event.pbzero.cc",
+        "external/perfetto/protos/perfetto/trace/perfetto/tracing_v2_producer_stats.pbzero.cc",
     ],
 }
 
@@ -11958,6 +11981,7 @@
         "external/perfetto/protos/perfetto/trace/perfetto/perfetto_metatrace.pbzero.h",
         "external/perfetto/protos/perfetto/trace/perfetto/trace_provenance.pbzero.h",
         "external/perfetto/protos/perfetto/trace/perfetto/tracing_service_event.pbzero.h",
+        "external/perfetto/protos/perfetto/trace/perfetto/tracing_v2_producer_stats.pbzero.h",
     ],
     export_include_dirs: [
         ".",
@@ -13279,6 +13303,7 @@
         "protos/perfetto/trace/track_event/task_execution.proto",
         "protos/perfetto/trace/track_event/thread_descriptor.proto",
         "protos/perfetto/trace/track_event/track_descriptor.proto",
+        "protos/perfetto/trace/track_event/track_dimension.proto",
         "protos/perfetto/trace/track_event/track_event.proto",
     ],
 }
@@ -13322,6 +13347,7 @@
         "external/perfetto/protos/perfetto/trace/track_event/task_execution.gen.cc",
         "external/perfetto/protos/perfetto/trace/track_event/thread_descriptor.gen.cc",
         "external/perfetto/protos/perfetto/trace/track_event/track_descriptor.gen.cc",
+        "external/perfetto/protos/perfetto/trace/track_event/track_dimension.gen.cc",
         "external/perfetto/protos/perfetto/trace/track_event/track_event.gen.cc",
     ],
 }
@@ -13365,6 +13391,7 @@
         "external/perfetto/protos/perfetto/trace/track_event/task_execution.gen.h",
         "external/perfetto/protos/perfetto/trace/track_event/thread_descriptor.gen.h",
         "external/perfetto/protos/perfetto/trace/track_event/track_descriptor.gen.h",
+        "external/perfetto/protos/perfetto/trace/track_event/track_dimension.gen.h",
         "external/perfetto/protos/perfetto/trace/track_event/track_event.gen.h",
     ],
     export_include_dirs: [
@@ -13404,6 +13431,7 @@
         "protos/perfetto/trace/track_event/task_execution.proto",
         "protos/perfetto/trace/track_event/thread_descriptor.proto",
         "protos/perfetto/trace/track_event/track_descriptor.proto",
+        "protos/perfetto/trace/track_event/track_dimension.proto",
         "protos/perfetto/trace/track_event/track_event.proto",
     ],
     tools: [
@@ -13446,6 +13474,7 @@
         "protos/perfetto/trace/track_event/task_execution.proto",
         "protos/perfetto/trace/track_event/thread_descriptor.proto",
         "protos/perfetto/trace/track_event/track_descriptor.proto",
+        "protos/perfetto/trace/track_event/track_dimension.proto",
         "protos/perfetto/trace/track_event/track_event.proto",
     ],
 }
@@ -13488,6 +13517,7 @@
         "external/perfetto/protos/perfetto/trace/track_event/task_execution.pb.cc",
         "external/perfetto/protos/perfetto/trace/track_event/thread_descriptor.pb.cc",
         "external/perfetto/protos/perfetto/trace/track_event/track_descriptor.pb.cc",
+        "external/perfetto/protos/perfetto/trace/track_event/track_dimension.pb.cc",
         "external/perfetto/protos/perfetto/trace/track_event/track_event.pb.cc",
     ],
 }
@@ -13530,6 +13560,7 @@
         "external/perfetto/protos/perfetto/trace/track_event/task_execution.pb.h",
         "external/perfetto/protos/perfetto/trace/track_event/thread_descriptor.pb.h",
         "external/perfetto/protos/perfetto/trace/track_event/track_descriptor.pb.h",
+        "external/perfetto/protos/perfetto/trace/track_event/track_dimension.pb.h",
         "external/perfetto/protos/perfetto/trace/track_event/track_event.pb.h",
     ],
     export_include_dirs: [
@@ -13569,6 +13600,7 @@
         "protos/perfetto/trace/track_event/task_execution.proto",
         "protos/perfetto/trace/track_event/thread_descriptor.proto",
         "protos/perfetto/trace/track_event/track_descriptor.proto",
+        "protos/perfetto/trace/track_event/track_dimension.proto",
         "protos/perfetto/trace/track_event/track_event.proto",
     ],
 }
@@ -13612,6 +13644,7 @@
         "external/perfetto/protos/perfetto/trace/track_event/task_execution.pbzero.cc",
         "external/perfetto/protos/perfetto/trace/track_event/thread_descriptor.pbzero.cc",
         "external/perfetto/protos/perfetto/trace/track_event/track_descriptor.pbzero.cc",
+        "external/perfetto/protos/perfetto/trace/track_event/track_dimension.pbzero.cc",
         "external/perfetto/protos/perfetto/trace/track_event/track_event.pbzero.cc",
     ],
 }
@@ -13655,6 +13688,7 @@
         "external/perfetto/protos/perfetto/trace/track_event/task_execution.pbzero.h",
         "external/perfetto/protos/perfetto/trace/track_event/thread_descriptor.pbzero.h",
         "external/perfetto/protos/perfetto/trace/track_event/track_descriptor.pbzero.h",
+        "external/perfetto/protos/perfetto/trace/track_event/track_dimension.pbzero.h",
         "external/perfetto/protos/perfetto/trace/track_event/track_event.pbzero.h",
     ],
     export_include_dirs: [
@@ -13999,6 +14033,7 @@
         "protos/perfetto/trace/perfetto/perfetto_metatrace.proto",
         "protos/perfetto/trace/perfetto/trace_provenance.proto",
         "protos/perfetto/trace/perfetto/tracing_service_event.proto",
+        "protos/perfetto/trace/perfetto/tracing_v2_producer_stats.proto",
         "protos/perfetto/trace/power/android_energy_estimation_breakdown.proto",
         "protos/perfetto/trace/power/android_entity_state_residency.proto",
         "protos/perfetto/trace/power/battery_counters.proto",
@@ -14051,6 +14086,7 @@
         "protos/perfetto/trace/track_event/task_execution.proto",
         "protos/perfetto/trace/track_event/thread_descriptor.proto",
         "protos/perfetto/trace/track_event/track_descriptor.proto",
+        "protos/perfetto/trace/track_event/track_dimension.proto",
         "protos/perfetto/trace/track_event/track_event.proto",
         "protos/perfetto/trace/translation/translation_table.proto",
         "protos/perfetto/trace/trigger.proto",
@@ -15557,6 +15593,7 @@
         "protos/perfetto/trace/track_event/task_execution.proto",
         "protos/perfetto/trace/track_event/thread_descriptor.proto",
         "protos/perfetto/trace/track_event/track_descriptor.proto",
+        "protos/perfetto/trace/track_event/track_dimension.proto",
         "protos/perfetto/trace/track_event/track_event.proto",
         "protos/third_party/chromium/chrome_enums.proto",
         "protos/third_party/chromium/chrome_track_event.proto",
@@ -17856,11 +17893,15 @@
         "src/trace_processor/core/exec/combine_batches.cc",
         "src/trace_processor/core/exec/context.cc",
         "src/trace_processor/core/exec/dataframe_scan.cc",
+        "src/trace_processor/core/exec/distinct.cc",
+        "src/trace_processor/core/exec/filter.cc",
         "src/trace_processor/core/exec/group_table.cc",
         "src/trace_processor/core/exec/grouped_sort.cc",
         "src/trace_processor/core/exec/hash_aggregate.cc",
+        "src/trace_processor/core/exec/interval_fill_gaps.cc",
         "src/trace_processor/core/exec/interval_flatten.cc",
         "src/trace_processor/core/exec/interval_intersect.cc",
+        "src/trace_processor/core/exec/interval_lanes.cc",
         "src/trace_processor/core/exec/operator.cc",
         "src/trace_processor/core/exec/pipeline.cc",
         "src/trace_processor/core/exec/row_cursor.cc",
@@ -17888,12 +17929,16 @@
         "src/trace_processor/core/exec/assert_type_unittest.cc",
         "src/trace_processor/core/exec/breaker_unittest.cc",
         "src/trace_processor/core/exec/dataframe_scan_unittest.cc",
+        "src/trace_processor/core/exec/distinct_unittest.cc",
         "src/trace_processor/core/exec/executor_contract_unittest.cc",
+        "src/trace_processor/core/exec/filter_unittest.cc",
         "src/trace_processor/core/exec/group_table_unittest.cc",
         "src/trace_processor/core/exec/grouped_sort_unittest.cc",
         "src/trace_processor/core/exec/hash_aggregate_unittest.cc",
+        "src/trace_processor/core/exec/interval_fill_gaps_unittest.cc",
         "src/trace_processor/core/exec/interval_flatten_unittest.cc",
         "src/trace_processor/core/exec/interval_intersect_unittest.cc",
+        "src/trace_processor/core/exec/interval_lanes_unittest.cc",
         "src/trace_processor/core/exec/operator_unittest.cc",
         "src/trace_processor/core/exec/row_batch_unittest.cc",
         "src/trace_processor/core/exec/row_store_unittest.cc",
@@ -17962,6 +18007,7 @@
         "src/trace_processor/core/util/bit_vector_unittest.cc",
         "src/trace_processor/core/util/flex_vector_unittest.cc",
         "src/trace_processor/core/util/heap_unittest.cc",
+        "src/trace_processor/core/util/interval_gaps_unittest.cc",
         "src/trace_processor/core/util/ops_unittest.cc",
         "src/trace_processor/core/util/slab_unittest.cc",
         "src/trace_processor/core/util/sort_unittest.cc",
@@ -19121,12 +19167,15 @@
     name: "perfetto_src_trace_processor_perfetto_sql_pipeline_operations_operations",
     srcs: [
         "src/trace_processor/perfetto_sql/pipeline/operations/aggregate_stage.cc",
+        "src/trace_processor/perfetto_sql/pipeline/operations/distinct.cc",
+        "src/trace_processor/perfetto_sql/pipeline/operations/interval_fill_gaps.cc",
         "src/trace_processor/perfetto_sql/pipeline/operations/interval_flatten.cc",
         "src/trace_processor/perfetto_sql/pipeline/operations/interval_intersect.cc",
         "src/trace_processor/perfetto_sql/pipeline/operations/order_by.cc",
         "src/trace_processor/perfetto_sql/pipeline/operations/projection.cc",
         "src/trace_processor/perfetto_sql/pipeline/operations/scan.cc",
         "src/trace_processor/perfetto_sql/pipeline/operations/tree_accumulate.cc",
+        "src/trace_processor/perfetto_sql/pipeline/operations/where.cc",
     ],
 }
 
@@ -19400,7 +19449,6 @@
     name: "perfetto_src_trace_processor_perfetto_sql_stdlib_intervals_intervals",
     srcs: [
         "src/trace_processor/perfetto_sql/stdlib/intervals/create_intervals.sql",
-        "src/trace_processor/perfetto_sql/stdlib/intervals/fill_gaps.sql",
         "src/trace_processor/perfetto_sql/stdlib/intervals/intersect.sql",
         "src/trace_processor/perfetto_sql/stdlib/intervals/mipmap.sql",
         "src/trace_processor/perfetto_sql/stdlib/intervals/overlap.sql",
@@ -21443,8 +21491,11 @@
         ":perfetto_include_perfetto_profiling_pprof_builder",
         ":perfetto_include_perfetto_protozero_protozero",
         ":perfetto_include_perfetto_public_abi_base",
+        ":perfetto_include_perfetto_public_abi_public",
         ":perfetto_include_perfetto_public_base",
+        ":perfetto_include_perfetto_public_protos_protos",
         ":perfetto_include_perfetto_public_protozero",
+        ":perfetto_include_perfetto_public_public",
         ":perfetto_include_perfetto_trace_processor_basic_types",
         ":perfetto_include_perfetto_trace_processor_io",
         ":perfetto_include_perfetto_trace_processor_storage",
@@ -23703,6 +23754,7 @@
         "protos/perfetto/trace/perfetto/perfetto_metatrace.proto",
         "protos/perfetto/trace/perfetto/trace_provenance.proto",
         "protos/perfetto/trace/perfetto/tracing_service_event.proto",
+        "protos/perfetto/trace/perfetto/tracing_v2_producer_stats.proto",
         "protos/perfetto/trace/power/android_energy_estimation_breakdown.proto",
         "protos/perfetto/trace/power/android_entity_state_residency.proto",
         "protos/perfetto/trace/power/battery_counters.proto",
@@ -23755,6 +23807,7 @@
         "protos/perfetto/trace/track_event/task_execution.proto",
         "protos/perfetto/trace/track_event/thread_descriptor.proto",
         "protos/perfetto/trace/track_event/track_descriptor.proto",
+        "protos/perfetto/trace/track_event/track_dimension.proto",
         "protos/perfetto/trace/track_event/track_event.proto",
         "protos/perfetto/trace/translation/translation_table.proto",
         "protos/perfetto/trace/trigger.proto",
@@ -24200,6 +24253,7 @@
         "protos/perfetto/trace/perfetto/perfetto_metatrace.proto",
         "protos/perfetto/trace/perfetto/trace_provenance.proto",
         "protos/perfetto/trace/perfetto/tracing_service_event.proto",
+        "protos/perfetto/trace/perfetto/tracing_v2_producer_stats.proto",
         "protos/perfetto/trace/power/android_energy_estimation_breakdown.proto",
         "protos/perfetto/trace/power/android_entity_state_residency.proto",
         "protos/perfetto/trace/power/battery_counters.proto",
@@ -24252,6 +24306,7 @@
         "protos/perfetto/trace/track_event/task_execution.proto",
         "protos/perfetto/trace/track_event/thread_descriptor.proto",
         "protos/perfetto/trace/track_event/track_descriptor.proto",
+        "protos/perfetto/trace/track_event/track_dimension.proto",
         "protos/perfetto/trace/track_event/track_event.proto",
         "protos/perfetto/trace/translation/translation_table.proto",
         "protos/perfetto/trace/trigger.proto",
@@ -25675,8 +25730,11 @@
         ":perfetto_include_perfetto_ext_traced_sys_stats_counters",
         ":perfetto_include_perfetto_protozero_protozero",
         ":perfetto_include_perfetto_public_abi_base",
+        ":perfetto_include_perfetto_public_abi_public",
         ":perfetto_include_perfetto_public_base",
+        ":perfetto_include_perfetto_public_protos_protos",
         ":perfetto_include_perfetto_public_protozero",
+        ":perfetto_include_perfetto_public_public",
         ":perfetto_include_perfetto_trace_processor_basic_types",
         ":perfetto_include_perfetto_trace_processor_io",
         ":perfetto_include_perfetto_trace_processor_storage",
@@ -26394,8 +26452,11 @@
         ":perfetto_include_perfetto_profiling_pprof_builder",
         ":perfetto_include_perfetto_protozero_protozero",
         ":perfetto_include_perfetto_public_abi_base",
+        ":perfetto_include_perfetto_public_abi_public",
         ":perfetto_include_perfetto_public_base",
+        ":perfetto_include_perfetto_public_protos_protos",
         ":perfetto_include_perfetto_public_protozero",
+        ":perfetto_include_perfetto_public_public",
         ":perfetto_include_perfetto_trace_processor_basic_types",
         ":perfetto_include_perfetto_trace_processor_io",
         ":perfetto_include_perfetto_trace_processor_storage",
@@ -26910,6 +26971,7 @@
         ":perfetto_protos_perfetto_trace_linux_zero_gen",
         ":perfetto_protos_perfetto_trace_minimal_zero_gen",
         ":perfetto_protos_perfetto_trace_non_minimal_zero_gen",
+        ":perfetto_protos_perfetto_trace_perfetto_cpp_gen",
         ":perfetto_protos_perfetto_trace_perfetto_zero_gen",
         ":perfetto_protos_perfetto_trace_power_zero_gen",
         ":perfetto_protos_perfetto_trace_profiling_inline_callstack_zero_gen",
@@ -27043,6 +27105,7 @@
         "perfetto_protos_perfetto_trace_linux_zero_gen_headers",
         "perfetto_protos_perfetto_trace_minimal_zero_gen_headers",
         "perfetto_protos_perfetto_trace_non_minimal_zero_gen_headers",
+        "perfetto_protos_perfetto_trace_perfetto_cpp_gen_headers",
         "perfetto_protos_perfetto_trace_perfetto_zero_gen_headers",
         "perfetto_protos_perfetto_trace_power_zero_gen_headers",
         "perfetto_protos_perfetto_trace_profiling_inline_callstack_zero_gen_headers",
diff --git a/BUILD b/BUILD
index 0a638e0..70f067a 100644
--- a/BUILD
+++ b/BUILD
@@ -267,6 +267,7 @@
                ":protos_perfetto_trace_linux_zero",
                ":protos_perfetto_trace_minimal_zero",
                ":protos_perfetto_trace_non_minimal_zero",
+               ":protos_perfetto_trace_perfetto_cpp",
                ":protos_perfetto_trace_perfetto_zero",
                ":protos_perfetto_trace_power_zero",
                ":protos_perfetto_trace_profiling_inline_callstack_zero",
@@ -623,8 +624,11 @@
         ":include_perfetto_ext_traced_sys_stats_counters",
         ":include_perfetto_protozero_protozero",
         ":include_perfetto_public_abi_base",
+        ":include_perfetto_public_abi_public",
         ":include_perfetto_public_base",
+        ":include_perfetto_public_protos_protos",
         ":include_perfetto_public_protozero",
+        ":include_perfetto_public_public",
         ":include_perfetto_trace_processor_basic_types",
         ":include_perfetto_trace_processor_io",
         ":include_perfetto_trace_processor_storage",
@@ -966,8 +970,11 @@
         ":include_perfetto_profiling_pprof_builder",
         ":include_perfetto_protozero_protozero",
         ":include_perfetto_public_abi_base",
+        ":include_perfetto_public_abi_public",
         ":include_perfetto_public_base",
+        ":include_perfetto_public_protos_protos",
         ":include_perfetto_public_protozero",
+        ":include_perfetto_public_public",
         ":include_perfetto_trace_processor_basic_types",
         ":include_perfetto_trace_processor_io",
         ":include_perfetto_trace_processor_storage",
@@ -1373,6 +1380,7 @@
                ":protos_perfetto_trace_linux_zero",
                ":protos_perfetto_trace_minimal_zero",
                ":protos_perfetto_trace_non_minimal_zero",
+               ":protos_perfetto_trace_perfetto_cpp",
                ":protos_perfetto_trace_perfetto_zero",
                ":protos_perfetto_trace_power_zero",
                ":protos_perfetto_trace_profiling_inline_callstack_zero",
@@ -1721,6 +1729,7 @@
         "include/perfetto/public/protos/trace/track_event/debug_annotation.pzc.h",
         "include/perfetto/public/protos/trace/track_event/state_descriptor.pzc.h",
         "include/perfetto/public/protos/trace/track_event/track_descriptor.pzc.h",
+        "include/perfetto/public/protos/trace/track_event/track_dimension.pzc.h",
         "include/perfetto/public/protos/trace/track_event/track_event.pzc.h",
         "include/perfetto/public/protos/trace/trigger.pzc.h",
     ],
@@ -2608,16 +2617,25 @@
         "src/trace_processor/core/exec/context.h",
         "src/trace_processor/core/exec/dataframe_scan.cc",
         "src/trace_processor/core/exec/dataframe_scan.h",
+        "src/trace_processor/core/exec/distinct.cc",
+        "src/trace_processor/core/exec/distinct.h",
+        "src/trace_processor/core/exec/filter.cc",
+        "src/trace_processor/core/exec/filter.h",
+        "src/trace_processor/core/exec/filter_value.h",
         "src/trace_processor/core/exec/group_table.cc",
         "src/trace_processor/core/exec/group_table.h",
         "src/trace_processor/core/exec/grouped_sort.cc",
         "src/trace_processor/core/exec/grouped_sort.h",
         "src/trace_processor/core/exec/hash_aggregate.cc",
         "src/trace_processor/core/exec/hash_aggregate.h",
+        "src/trace_processor/core/exec/interval_fill_gaps.cc",
+        "src/trace_processor/core/exec/interval_fill_gaps.h",
         "src/trace_processor/core/exec/interval_flatten.cc",
         "src/trace_processor/core/exec/interval_flatten.h",
         "src/trace_processor/core/exec/interval_intersect.cc",
         "src/trace_processor/core/exec/interval_intersect.h",
+        "src/trace_processor/core/exec/interval_lanes.cc",
+        "src/trace_processor/core/exec/interval_lanes.h",
         "src/trace_processor/core/exec/layout_column.h",
         "src/trace_processor/core/exec/operator.cc",
         "src/trace_processor/core/exec/operator.h",
@@ -2695,6 +2713,7 @@
         "src/trace_processor/core/util/bit_vector.h",
         "src/trace_processor/core/util/flex_vector.h",
         "src/trace_processor/core/util/heap.h",
+        "src/trace_processor/core/util/interval_gaps.h",
         "src/trace_processor/core/util/ops.cc",
         "src/trace_processor/core/util/ops.h",
         "src/trace_processor/core/util/range.h",
@@ -3904,6 +3923,10 @@
     srcs = [
         "src/trace_processor/perfetto_sql/pipeline/operations/aggregate_stage.cc",
         "src/trace_processor/perfetto_sql/pipeline/operations/aggregate_stage.h",
+        "src/trace_processor/perfetto_sql/pipeline/operations/distinct.cc",
+        "src/trace_processor/perfetto_sql/pipeline/operations/distinct.h",
+        "src/trace_processor/perfetto_sql/pipeline/operations/interval_fill_gaps.cc",
+        "src/trace_processor/perfetto_sql/pipeline/operations/interval_fill_gaps.h",
         "src/trace_processor/perfetto_sql/pipeline/operations/interval_flatten.cc",
         "src/trace_processor/perfetto_sql/pipeline/operations/interval_flatten.h",
         "src/trace_processor/perfetto_sql/pipeline/operations/interval_intersect.cc",
@@ -3916,6 +3939,8 @@
         "src/trace_processor/perfetto_sql/pipeline/operations/scan.h",
         "src/trace_processor/perfetto_sql/pipeline/operations/tree_accumulate.cc",
         "src/trace_processor/perfetto_sql/pipeline/operations/tree_accumulate.h",
+        "src/trace_processor/perfetto_sql/pipeline/operations/where.cc",
+        "src/trace_processor/perfetto_sql/pipeline/operations/where.h",
     ],
 )
 
@@ -4255,7 +4280,6 @@
     name = "src_trace_processor_perfetto_sql_stdlib_intervals_intervals",
     srcs = [
         "src/trace_processor/perfetto_sql/stdlib/intervals/create_intervals.sql",
-        "src/trace_processor/perfetto_sql/stdlib/intervals/fill_gaps.sql",
         "src/trace_processor/perfetto_sql/stdlib/intervals/intersect.sql",
         "src/trace_processor/perfetto_sql/stdlib/intervals/mipmap.sql",
         "src/trace_processor/perfetto_sql/stdlib/intervals/overlap.sql",
@@ -9945,6 +9969,14 @@
     ],
 )
 
+# GN target: //protos/perfetto/trace/perfetto:cpp
+perfetto_cc_protocpp_library(
+    name = "protos_perfetto_trace_perfetto_cpp",
+    deps = [
+        ":protos_perfetto_trace_perfetto_protos",
+    ],
+)
+
 # GN target: //protos/perfetto/trace/perfetto:source_set
 perfetto_proto_library(
     name = "protos_perfetto_trace_perfetto_protos",
@@ -9953,6 +9985,7 @@
         "protos/perfetto/trace/perfetto/perfetto_metatrace.proto",
         "protos/perfetto/trace/perfetto/trace_provenance.proto",
         "protos/perfetto/trace/perfetto/tracing_service_event.proto",
+        "protos/perfetto/trace/perfetto/tracing_v2_producer_stats.proto",
     ],
     visibility = [
         PERFETTO_CONFIG.proto_library_visibility,
@@ -10334,6 +10367,7 @@
         "protos/perfetto/trace/track_event/task_execution.proto",
         "protos/perfetto/trace/track_event/thread_descriptor.proto",
         "protos/perfetto/trace/track_event/track_descriptor.proto",
+        "protos/perfetto/trace/track_event/track_dimension.proto",
         "protos/perfetto/trace/track_event/track_event.proto",
     ],
     visibility = [
@@ -11795,6 +11829,7 @@
                ":protos_perfetto_trace_linux_zero",
                ":protos_perfetto_trace_minimal_zero",
                ":protos_perfetto_trace_non_minimal_zero",
+               ":protos_perfetto_trace_perfetto_cpp",
                ":protos_perfetto_trace_perfetto_zero",
                ":protos_perfetto_trace_power_zero",
                ":protos_perfetto_trace_profiling_inline_callstack_zero",
@@ -12140,8 +12175,11 @@
         ":include_perfetto_ext_traced_sys_stats_counters",
         ":include_perfetto_protozero_protozero",
         ":include_perfetto_public_abi_base",
+        ":include_perfetto_public_abi_public",
         ":include_perfetto_public_base",
+        ":include_perfetto_public_protos_protos",
         ":include_perfetto_public_protozero",
+        ":include_perfetto_public_public",
         ":include_perfetto_trace_processor_basic_types",
         ":include_perfetto_trace_processor_io",
         ":include_perfetto_trace_processor_storage",
@@ -12283,8 +12321,11 @@
         ":include_perfetto_profiling_pprof_builder",
         ":include_perfetto_protozero_protozero",
         ":include_perfetto_public_abi_base",
+        ":include_perfetto_public_abi_public",
         ":include_perfetto_public_base",
+        ":include_perfetto_public_protos_protos",
         ":include_perfetto_public_protozero",
+        ":include_perfetto_public_public",
         ":include_perfetto_trace_processor_basic_types",
         ":include_perfetto_trace_processor_io",
         ":include_perfetto_trace_processor_storage",
diff --git a/buildtools/.gitignore b/buildtools/.gitignore
index 457678d..986e027 100644
--- a/buildtools/.gitignore
+++ b/buildtools/.gitignore
@@ -14,6 +14,7 @@
 /clang_format/
 /cpp-httplib/
 /d8/
+/debian_bullseye_s390x-sysroot/
 /debian_sid_arm-sysroot/
 /debian_sid_arm64-sysroot/
 /debian_sid_armel-sysroot/
diff --git a/contrib/rust-sdk/Cargo.lock b/contrib/rust-sdk/Cargo.lock
index 95f7d3f..0dc0db1 100644
--- a/contrib/rust-sdk/Cargo.lock
+++ b/contrib/rust-sdk/Cargo.lock
@@ -350,7 +350,7 @@
 
 [[package]]
 name = "perfetto-sdk"
-version = "1.1.1"
+version = "1.2.0"
 dependencies = [
  "bitflags",
  "paste",
@@ -399,7 +399,7 @@
 
 [[package]]
 name = "perfetto-sdk-sys"
-version = "1.3.0"
+version = "2.0.0"
 dependencies = [
  "bindgen",
  "cc",
diff --git a/contrib/rust-sdk/perfetto-sys/Cargo.toml b/contrib/rust-sdk/perfetto-sys/Cargo.toml
index 512d861..39d405a 100644
--- a/contrib/rust-sdk/perfetto-sys/Cargo.toml
+++ b/contrib/rust-sdk/perfetto-sys/Cargo.toml
@@ -1,7 +1,7 @@
 [package]
 edition = "2024"
 name = "perfetto-sdk-sys"
-version = "1.3.0"
+version = "2.0.0"
 authors = ["David Reveman <reveman@meta.com>"]
 build = "build.rs"
 description = "Low-level FFI bindings for Perfetto"
diff --git a/contrib/rust-sdk/perfetto/Cargo.toml b/contrib/rust-sdk/perfetto/Cargo.toml
index b0af8f4..354eb2b 100644
--- a/contrib/rust-sdk/perfetto/Cargo.toml
+++ b/contrib/rust-sdk/perfetto/Cargo.toml
@@ -1,7 +1,7 @@
 [package]
 edition = "2024"
 name = "perfetto-sdk"
-version = "1.1.1"
+version = "1.2.0"
 authors = ["David Reveman <reveman@meta.com>"]
 description = "Bindings for the Perfetto tracing framework"
 readme = "README.md"
@@ -20,7 +20,7 @@
 vendored = ["perfetto-sdk-sys/vendored"]
 
 [dependencies]
-perfetto-sdk-sys = { path = "../perfetto-sys", version = "1.3.0", default-features = false }
+perfetto-sdk-sys = { path = "../perfetto-sys", version = "2.0.0", default-features = false }
 bitflags = "2"
 paste = "1"
 thiserror = "1"
diff --git a/contrib/rust-sdk/perfetto/src/data_source.rs b/contrib/rust-sdk/perfetto/src/data_source.rs
index 6d93eab..3374152 100644
--- a/contrib/rust-sdk/perfetto/src/data_source.rs
+++ b/contrib/rust-sdk/perfetto/src/data_source.rs
@@ -199,6 +199,7 @@
     callbacks: DsCallbacks,
     buffer_exhausted_policy: DataSourceBufferExhaustedPolicy,
     buffer_exhausted_policy_configurable: bool,
+    supports_tracing_v2: bool,
     will_notify_on_stop: bool,
     handles_incremental_state_clear: bool,
 }
@@ -236,6 +237,15 @@
         self
     }
 
+    /// Lets an instance of the data source take a tracing v2 writer when its
+    /// config selects v2. Its packets are then written in the append-only
+    /// format, which `add_packet` sees to.
+    #[must_use = "Builder methods return an updated builder; use the returned value or keep chaining."]
+    pub fn supports_tracing_v2(mut self, supports: bool) -> Self {
+        self.args.supports_tracing_v2 = supports;
+        self
+    }
+
     /// Set notify on stop flag.
     #[must_use = "Builder methods return an updated builder; use the returned value or keep chaining."]
     pub fn will_notify_on_stop(mut self, will_notify_on_stop: bool) -> Self {
@@ -385,10 +395,6 @@
         // - `self.iterator.tracer` must be a pointer provided by a call to
         //   PerfettoDsImplTraceIterateBegin/Next.
         unsafe { PerfettoDsTracerImplPacketBegin(self.iterator.tracer, &mut impl_writer) };
-        // This SDK never calls PerfettoDsSetSupportsTracingV2(), so Begin always
-        // gives a length-delimited writer. PbMsg can't write proto group, so we
-        // check that here.
-        debug_assert_eq!(impl_writer.encoding, 0);
         let writer = PbMsgWriter {
             writer: StreamWriter {
                 writer: RefCell::new(impl_writer),
@@ -813,6 +819,7 @@
                 ds_impl,
                 args.buffer_exhausted_policy_configurable,
             );
+            PerfettoDsSetSupportsTracingV2(ds_impl, args.supports_tracing_v2);
             let success = PerfettoDsImplRegister(
                 ds_impl,
                 &raw mut self.enabled,
diff --git a/contrib/rust-sdk/perfetto/src/pb_msg.rs b/contrib/rust-sdk/perfetto/src/pb_msg.rs
index 148eae6..c8c61d1 100644
--- a/contrib/rust-sdk/perfetto/src/pb_msg.rs
+++ b/contrib/rust-sdk/perfetto/src/pb_msg.rs
@@ -58,6 +58,29 @@
     parent: Weak<RefCell<PbMsgSizeField>>,
 }
 
+/// How nested messages are written. The root's encoding is chosen when it is
+/// made, and each child takes its parent's.
+#[derive(Clone, Copy, Debug, PartialEq, Eq)]
+pub enum PbMsgEncoding {
+    /// Standard protobuf: a nested message is a length-delimited field, its
+    /// length written once the message is complete.
+    LengthDelimited,
+    /// The append-only format a tracing v2 writer takes: a nested message
+    /// starts with a start-group tag and ends with a closing byte, so nothing
+    /// is written after the fact.
+    ProtoGroup,
+}
+
+/// Values of the C SDK's `enum PerfettoPbMsgEncoding`, which the writer
+/// carries.
+pub(crate) const PB_MSG_ENCODING_LENGTH_DELIMITED: u32 = 0;
+const PB_MSG_ENCODING_PROTO_GROUP: u32 = 1;
+
+/// The wire type opening a nested message in proto group mode.
+const PB_WIRE_TYPE_START_GROUP: u32 = 3;
+/// The byte closing a nested message in proto group mode.
+const PB_PROTO_GROUP_END_BYTE: u8 = 0x04;
+
 impl PbMsgSizeField {
     pub fn patch(&mut self, writer: &PbMsgWriter) {
         assert!(!self.ptr.is_null());
@@ -90,14 +113,23 @@
     size_field: Rc<RefCell<PbMsgSizeField>>,
     size: usize,
     writer: &'a PbMsgWriter,
+    encoding: PbMsgEncoding,
 }
 
 impl<'a> PbMsg<'a> {
-    /// Creates a new message struct using `writer`.
+    /// Creates a new root message using `writer`, its nested messages written
+    /// in the encoding the writer carries.
     pub fn new(writer: &'a PbMsgWriter) -> Result<Self, PbMsgError> {
         if !writer.writer.has_valid_writer() {
             return Err(PbMsgError::MissingOutputForWriter);
         }
+        let encoding = match writer.writer.writer.borrow().encoding {
+            PB_MSG_ENCODING_PROTO_GROUP => PbMsgEncoding::ProtoGroup,
+            e => {
+                debug_assert_eq!(e, PB_MSG_ENCODING_LENGTH_DELIMITED);
+                PbMsgEncoding::LengthDelimited
+            }
+        };
         Ok(Self {
             size_field: Rc::new(RefCell::new(PbMsgSizeField {
                 ptr: std::ptr::null_mut(),
@@ -105,9 +137,15 @@
             })),
             size: 0,
             writer,
+            encoding,
         })
     }
 
+    /// How this message's nested messages are written.
+    pub fn encoding(&self) -> PbMsgEncoding {
+        self.encoding
+    }
+
     /// Append bytes to message.
     pub fn append_bytes(&mut self, bytes: &[u8]) {
         if crate::__unlikely!(bytes.len() > self.writer.writer.available_bytes()) {
@@ -204,6 +242,23 @@
     where
         F: FnMut(&mut PbMsg),
     {
+        if self.encoding == PbMsgEncoding::ProtoGroup {
+            // No length field: the child ends with a closing byte.
+            self.append_varint(u64::from((field_id << 3) | PB_WIRE_TYPE_START_GROUP));
+            let mut nested = PbMsg {
+                size_field: Rc::new(RefCell::new(PbMsgSizeField {
+                    ptr: std::ptr::null_mut(),
+                    parent: Rc::downgrade(&self.size_field),
+                })),
+                size: 0,
+                writer: self.writer,
+                encoding: self.encoding,
+            };
+            cb(&mut nested);
+            self.size += nested.finalize();
+            self.append_byte(PB_PROTO_GROUP_END_BYTE);
+            return;
+        }
         let tag = pb_make_tag(field_id, PbWireType::Delimited);
         self.append_varint(tag.into());
         if crate::__unlikely!(
@@ -223,6 +278,7 @@
             })),
             size: 0,
             writer: self.writer,
+            encoding: self.encoding,
         };
         cb(&mut nested);
         self.size += nested.finalize();
@@ -295,4 +351,29 @@
         ]);
         Ok(())
     }
+
+    #[test]
+    fn append_nested_proto_group() -> Result<(), Box<dyn Error>> {
+        let writer = PbMsgWriter::new();
+        let hb = HeapBuffer::new(&writer.writer);
+        writer.writer.writer.borrow_mut().encoding = PB_MSG_ENCODING_PROTO_GROUP;
+        let mut msg = PbMsg::new(&writer)?;
+        msg.append_bytes(b"foo");
+        msg.append_nested(3, |msg| {
+            assert_eq!(msg.encoding(), PbMsgEncoding::ProtoGroup);
+            msg.append_nested(4, |msg| {
+                msg.append_cstr_field(10, "bar");
+            });
+        });
+        let size = msg.finalize();
+        assert_eq!(size, 12);
+        let written_size = writer.writer.get_written_size();
+        assert_eq!(written_size, 12);
+        let mut result: Vec<u8> = vec![0u8; written_size];
+        hb.copy_into(&mut result);
+        // Each nested message opens with a start-group tag and closes with
+        // 0x04, with no length.
+        assert_eq!(result, [102, 111, 111, 27, 35, 82, 3, 98, 97, 114, 4, 4]);
+        Ok(())
+    }
 }
diff --git a/contrib/rust-sdk/perfetto/src/protos/config/data_source_config.pz.rs b/contrib/rust-sdk/perfetto/src/protos/config/data_source_config.pz.rs
index c2e9368..ee7321a 100644
--- a/contrib/rust-sdk/perfetto/src/protos/config/data_source_config.pz.rs
+++ b/contrib/rust-sdk/perfetto/src/protos/config/data_source_config.pz.rs
@@ -32,6 +32,21 @@
     BUFFER_EXHAUSTED_STALL_THEN_DROP: 3,
 });
 
+// `DataSourceConfig.ExperimentalTracingV2Config.ChunkSizeOption`: a chunk
+// size the producer may pick for its ring buffer.
+pb_msg!(DataSourceConfigExperimentalTracingV2ConfigChunkSizeOption {
+    size_bytes: u32, primitive, 1,
+    weight: u32, primitive, 2,
+});
+
+// `DataSourceConfig.ExperimentalTracingV2Config`: whether an instance takes
+// a tracing v2 writer, where the data source supports one, and how its
+// ring buffer is laid out.
+pb_msg!(DataSourceConfigExperimentalTracingV2Config {
+    use_v2_probability_percent: u32, primitive, 1,
+    chunk_size_options: DataSourceConfigExperimentalTracingV2ConfigChunkSizeOption, msg, 2,
+});
+
 pb_msg!(DataSourceConfig {
     name: String, primitive, 1,
     target_buffer: u32, primitive, 2,
@@ -42,6 +57,8 @@
     session_initiator: DataSourceConfigSessionInitiator, enum, 8,
     tracing_session_id: u64, primitive, 4,
     buffer_exhausted_policy: DataSourceConfigBufferExhaustedPolicy, enum, 9,
+    supports_tracing_v2: bool, primitive, 147,
+    experimental_tracing_v2: DataSourceConfigExperimentalTracingV2Config, msg, 148,
     track_event_config: TrackEventConfig, msg, 113,
     for_testing: TestConfig, msg, 1001,
 });
diff --git a/contrib/rust-sdk/perfetto/src/stream_writer.rs b/contrib/rust-sdk/perfetto/src/stream_writer.rs
index 105661a..f2ad373 100644
--- a/contrib/rust-sdk/perfetto/src/stream_writer.rs
+++ b/contrib/rust-sdk/perfetto/src/stream_writer.rs
@@ -12,6 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+use crate::pb_msg::PB_MSG_ENCODING_LENGTH_DELIMITED;
 use perfetto_sdk_sys::*;
 use std::{cell::RefCell, ptr, slice};
 
@@ -171,9 +172,7 @@
                 end: ptr::null_mut(),
                 write_ptr: ptr::null_mut(),
                 written_previously: 0,
-                // Standard length-delimited protobuf, the only encoding this
-                // SDK writes.
-                encoding: 0,
+                encoding: PB_MSG_ENCODING_LENGTH_DELIMITED,
             }),
         }
     }
diff --git a/docs/analysis/perfetto-sql-pipe-getting-started.md b/docs/analysis/perfetto-sql-pipe-getting-started.md
index f4d6049..8429eea 100644
--- a/docs/analysis/perfetto-sql-pipe-getting-started.md
+++ b/docs/analysis/perfetto-sql-pipe-getting-started.md
@@ -1,8 +1,5 @@
 # Getting Started with PerfettoSQL Pipe Syntax
 
-This page is a prototype of the introductory guide to querying traces with
-PerfettoSQL pipe syntax.
-
 > **Warning:** Pipe syntax is **experimental and unstable**. Do **not** rely on
 > it in dashboards, scripts, or production queries. Anything can and will break
 > without notice. To run the examples on this page in the Perfetto UI or
@@ -18,39 +15,36 @@
 
 ## How Pipelines Work
 
-Standard SQL queries read inside-out: you start with `SELECT` to list the
-columns you want at the end, then write `FROM` to say where the data comes
-from, and nest subqueries or CTEs whenever you need multi-step transformations.
+A SQL query reads inside-out: `SELECT` comes first but runs last, and every
+extra step needs another subquery or CTE. A pipeline reads top to bottom, in
+the order the work happens:
 
-With pipe syntax, queries read top-to-bottom in the order data is processed:
-
-1. Start with a **source**: `FROM <table>`, `FROM (<subquery>)`, or
+1. It starts with a **source**: `FROM <table>`, `FROM (<subquery>)`, or
    `INTERVAL INTERSECTION OF (...)`.
-2. Chain one or more **pipe stages** with `|>` that transform, aggregate, or
-   reshape the rows step by step.
+2. Each `|>` **stage** takes the rows from the step before and passes new rows
+   to the next.
 
 ```sql
 PERFETTO PRAGMA pipelines = 1;
 
 FROM slice
+|> WHERE dur > 0
 |> RENAME dur AS duration_ns
 |> SELECT id, name, ts, duration_ns;
 ```
 
-Every `|>` stage takes the table produced by the previous step and outputs a new
-table for the next step.
-
 ### Saving a pipeline as a table
 
-You can run a pipeline directly as a query, or save its output into a
-`PERFETTO TABLE` so you can query it further with SQL:
+Run a pipeline as a query on its own, or save it as a `PERFETTO TABLE` and query
+that with SQL:
 
 ```sql
 PERFETTO PRAGMA pipelines = 1;
 
 CREATE PERFETTO TABLE named_slices AS
-FROM (SELECT id, ts, dur, name FROM slice WHERE dur > 0)
-|> RENAME dur AS duration_ns;
+FROM slice
+|> WHERE dur > 0
+|> SELECT id, ts, dur AS duration_ns, name;
 
 SELECT name, duration_ns
 FROM named_slices
@@ -62,26 +56,24 @@
 
 ## Intersecting Time Intervals: `INTERVAL INTERSECTION OF`
 
-Many trace analysis questions ask where two or more sets of time intervals
+Many questions about a trace ask where two or more sets of intervals
 `[ts, ts + dur)` overlap:
 
 - What CPU frequency was each core running at during every scheduling slice?
 - Which slices were active while a thread was in a particular state?
-- How much power was used by each task during active GPU regions?
+- How much power did each task use while the GPU was active?
 
-`INTERVAL INTERSECTION OF` takes two or more interval sources and emits one row
-for every overlapping time region they share:
+`INTERVAL INTERSECTION OF` takes two or more interval sources and gives one row
+for every region where all of them overlap:
 
 ```sql
 PERFETTO PRAGMA pipelines = 1;
 
--- 1. Scheduling slices with positive duration
 CREATE PERFETTO TABLE running_sched AS
 SELECT ts, dur, cpu, utid
 FROM sched
 WHERE dur > 0;
 
--- 2. CPU frequency intervals per CPU
 CREATE PERFETTO TABLE cpu_freq AS
 SELECT
   c.ts,
@@ -92,14 +84,11 @@
 JOIN cpu_counter_track AS t ON c.track_id = t.id
 WHERE t.name = 'cpufreq';
 
--- 3. Intersect scheduling slices with CPU frequency per CPU
 CREATE PERFETTO TABLE sched_with_freq AS
 INTERVAL INTERSECTION OF (running_sched AS s, cpu_freq AS f) PER cpu
-|> SELECT ts, dur, cpu, s.utid, f.freq;
+|> SELECT ts, dur, cpu, utid, freq;
 ```
 
-### How it works
-
 ```
 running_sched (s):   [------- utid 10 -------)     [--- utid 20 ---)
 cpu_freq (f):        [--- 1.8 GHz ---)[-------- 2.4 GHz --------)
@@ -107,26 +96,23 @@
 Result regions:      [-- 10 @ 1.8G --)[- 10 -]     [-- 20 @ 2.4G --)
 ```
 
-- **Region `ts` and `dur`:** Bare `ts` and `dur` in the output are the start and
-  duration of the overlapping region, clipped to where all inputs were active at
-  the same time.
-- **Partitioning with `PER`:** Adding `PER cpu` intersects intervals only when
-  they occur on the same `cpu`. The `cpu` column is available directly by its
-  bare name.
-- **Accessing input columns:** Each input has an alias, here `AS s` and `AS f`.
-  All columns from `s` and `f` are carried along and accessed via `s.<col>` and
-  `f.<col>`. This includes each input's original unclipped `s.ts` and `s.dur`.
+- **`ts` and `dur`** are the overlapping region, clipped to where every input
+  is active.
+- **`PER cpu`** only intersects rows on the same `cpu`.
+- **Input columns** carry through. Write them bare, as in `utid` and `freq`,
+  or through the input's alias, as in `s.utid`. If two inputs have a column of
+  the same name, the alias is needed.
+- **An input's own bounds** are `s.ts` and `s.dur`, before clipping.
 
 ---
 
-## Flattening Overlapping Intervals: `INTERVAL FLATTEN`
+## Flattening Overlapping Intervals: `INTERVAL FLATTEN` {#flattening-overlapping-intervals-interval-flatten}
 
-To count concurrent activity or sum a value across active intervals, use
-`INTERVAL FLATTEN`. It splits a single set of overlapping intervals into
-segments and computes an aggregate for each segment.
+`INTERVAL FLATTEN` splits one set of overlapping intervals into segments and
+aggregates the rows active in each. Use it to count concurrent activity or sum
+a value across it.
 
-For example, two tasks run during `[0, 10)` and `[5, 15)`, with weights 2 and
-3. Flattening shows when one or both are active:
+Two tasks run during `[0, 10)` and `[5, 15)`, with weights 2 and 3:
 
 ```sql
 PERFETTO PRAGMA pipelines = 1;
@@ -145,41 +131,75 @@
 | 5 | 5 | 2 | 5 |
 | 10 | 5 | 1 | 3 |
 
-Use `PER` to flatten each group independently. For example, count overlapping
-positive-duration slices on each track:
+`PER` flattens each group on its own. To count overlapping slices on each
+track:
 
 ```sql
-FROM (SELECT ts, dur, track_id FROM slice WHERE dur > 0)
+FROM slice
+|> WHERE dur > 0
 |> INTERVAL FLATTEN PER track_id AGGREGATE COUNT(*) AS active;
 ```
 
-The result contains `ts`, `dur`, `track_id`, and `active`. Other input columns
-are discarded. Gaps with no activity produce no rows. Input need not be sorted.
+The result has `ts`, `dur`, `track_id` and `active`; every other column is
+dropped. Gaps with no activity give no rows.
 
-`SUM` adds the values of active rows; it does not multiply them by the segment's
-duration. To calculate a duration-weighted total, save the pipeline as a
-`PERFETTO TABLE` and aggregate `dur * total_weight` in a SQL query.
+`SUM` adds the values of the active rows. It does not weight them by the
+segment's duration: for that, save the pipeline as a table and sum
+`dur * total_weight` in SQL.
 
 See the [syntax reference](/docs/analysis/perfetto-sql-pipe-syntax.md#interval-flatten)
-for point intervals, `NULL` handling, and supported aggregate expressions.
+for zero-duration intervals, `NULL`s and the supported aggregates.
+
+---
+
+## Filling Gaps: `INTERVAL FILL GAPS` {#filling-gaps-interval-fill-gaps}
+
+`INTERVAL FILL GAPS` keeps every input row and adds a row for each stretch of a
+background interval which no input covers. A filler row takes its values from
+the background, and `NULL` for columns the background does not have.
+
+To mark when each CPU was idle between 0 and 10:
+
+```sql
+PERFETTO PRAGMA pipelines = 1;
+
+CREATE PERFETTO TABLE spans AS
+SELECT 2 AS ts, 3 AS dur, 0 AS cpu, 'run' AS state
+UNION ALL SELECT 6, 2, 0, 'run'
+UNION ALL SELECT 1, 4, 1, 'run';
+
+FROM spans
+|> INTERVAL FILL GAPS WITH (SELECT 0 AS ts, 10 AS dur, 'idle' AS state) PER cpu
+|> ORDER BY cpu, ts;
+```
+
+| ts | dur | cpu | state |
+| -- | --- | --- | ----- |
+| 0 | 2 | 0 | idle |
+| 2 | 3 | 0 | run |
+| 5 | 1 | 0 | idle |
+| 6 | 2 | 0 | run |
+| 8 | 2 | 0 | idle |
+| 0 | 1 | 1 | idle |
+| 1 | 4 | 1 | run |
+| 5 | 5 | 1 | idle |
 
 ---
 
 ## Summing Over Trees: `TREE ACCUMULATE`
 
-Traces often contain trees where each row has an `id` and a `parent_id`, with
-`parent_id IS NULL` at the roots:
+Traces hold many trees where each row has an `id` and a `parent_id`, and roots
+have `parent_id IS NULL`:
 
-- Nested userspace slices in `slice`
-- Sampled callstacks from CPU profiling, perf, and native heap profiles
-- Java heap graph shortest-path trees
+- Nested slices in `slice`.
+- Callstacks from CPU profiling, perf and native heap profiles.
+- Java heap graph shortest-path trees.
 
-`TREE ACCUMULATE` computes cumulative sums over an `id` and `parent_id` tree in
-a single stage, keeping all existing columns and appending the totals:
+`TREE ACCUMULATE` sums over such a tree in one stage. It keeps every column and
+adds the totals at the end:
 
-- **`TREE ACCUMULATE UP`:** Sums each node's value with all of its descendants.
-- **`TREE ACCUMULATE DOWN`:** Sums each node's value with all of its ancestors
-  from the root down to the node.
+- **`UP`** sums each node with all its descendants.
+- **`DOWN`** sums each node with all its ancestors.
 
 ```sql
 PERFETTO PRAGMA pipelines = 1;
@@ -190,14 +210,11 @@
 UNION ALL SELECT 2, 0, 'b', 30
 UNION ALL SELECT 3, 1, 'c', 40;
 
-CREATE PERFETTO TABLE tree_totals AS
 FROM tree
 |> TREE ACCUMULATE UP SUM(self) AS subtree_total
-|> TREE ACCUMULATE DOWN SUM(self) AS path_total;
-
-SELECT name, self, subtree_total, path_total
-FROM tree_totals
-ORDER BY id;
+|> TREE ACCUMULATE DOWN SUM(self) AS path_total
+|> ORDER BY id
+|> SELECT name, self, subtree_total, path_total;
 ```
 
 For the tree `root (10) -> a (20) -> c (40)` and `root (10) -> b (30)`:
@@ -211,42 +228,81 @@
 
 ---
 
+## Grouping: `AGGREGATE`
+
+`AGGREGATE` collapses each group of rows into one, as `GROUP BY` does in SQL:
+
+```sql
+FROM slice
+|> WHERE dur > 0
+|> AGGREGATE COUNT(*) AS slices, SUM(dur) AS total, MAX(dur) AS longest
+   GROUP BY track_id;
+```
+
+The result has `track_id`, `slices`, `total` and `longest`. Without `GROUP BY`,
+every row goes into one group.
+
+---
+
+## Filtering and Sorting Rows
+
+- **`|> WHERE`** keeps the rows that match. Today it supports comparing a
+  column with a number, joined with `AND`:
+  ```sql
+  FROM slice
+  |> WHERE dur > 0 AND depth = 0
+  ```
+- **`|> DISTINCT`** drops repeated rows:
+  ```sql
+  FROM slice
+  |> SELECT track_id
+  |> DISTINCT
+  ```
+- **`|> ORDER BY`** sorts by numeric columns:
+  ```sql
+  FROM slice
+  |> ORDER BY dur DESC
+  ```
+
+---
+
 ## Reshaping Columns
 
-Instead of wrapping queries in outer `SELECT`s just to add, drop, or rename a
-column, you can modify the row in place with column-reshaping stages:
+These stages change the columns without wrapping the query in another
+`SELECT`:
 
-- **`|> SELECT`:** Pick, reorder, or rename columns. You can also use
-  `* EXCEPT (col1, col2)` to exclude columns or `* REPLACE (other_col AS col1)`
-  to substitute a column in place:
+- **`|> SELECT`** picks, reorders and renames columns. `* EXCEPT (...)` drops
+  some, and `* REPLACE (other_col AS col)` swaps one in place:
   ```sql
   FROM slice
   |> SELECT * EXCEPT (arg_set_id, parent_id)
   ```
-- **`|> EXTEND`:** Append new columns to the end of the current row while
-  keeping all existing columns:
+- **`|> EXTEND`** adds columns at the end:
   ```sql
   FROM slice AS s
   |> EXTEND s.dur AS original_dur
   ```
-- **`|> DROP`:** Remove one or more columns by name:
+- **`|> DROP`** removes columns:
   ```sql
   FROM slice
   |> DROP category, track_id, arg_set_id
   ```
-- **`|> RENAME`:** Rename columns in place without listing every other column:
+- **`|> RENAME`** renames columns in place:
   ```sql
   FROM slice
   |> RENAME ts AS start_ts, dur AS duration_ns
   ```
-- **`|> SET`:** Replace an existing column's value in place:
+- **`|> SET`** replaces a column's values:
   ```sql
-  FROM tree AS t
+  FROM tree
   |> TREE ACCUMULATE UP SUM(self) AS total
   |> SET self = total
   |> DROP total
   ```
 
+`SELECT`, `EXTEND` and `SET` only take columns today: `a + 1` is not supported
+yet.
+
 ---
 
 ## Next Steps
diff --git a/docs/analysis/perfetto-sql-pipe-migration.md b/docs/analysis/perfetto-sql-pipe-migration.md
index 6c503e1..79cc72c 100644
--- a/docs/analysis/perfetto-sql-pipe-migration.md
+++ b/docs/analysis/perfetto-sql-pipe-migration.md
@@ -1,8 +1,8 @@
 # Migrating to PerfettoSQL Pipe Syntax
 
-This guide is for people who already know PerfettoSQL. It covers why we are
-introducing pipe syntax, how it differs from existing macros and virtual
-tables, and how to migrate existing queries.
+This guide is for people who already know PerfettoSQL. It covers why pipe
+syntax exists, how it differs from the macros and virtual tables it replaces,
+and how to migrate queries to it.
 
 > **Warning:** Pipe syntax is **experimental and unstable**. Do **not** rely on
 > it in dashboards, scripts, or production queries. Anything can and will break
@@ -22,85 +22,80 @@
 Writing trace analysis queries in standard SQLite has several recurring pain
 points:
 
-1. **Table macros and virtual tables do not compose well.** Operations like
-   interval intersection and tree traversal do not exist in SQL. Perfetto
-   exposed them through SQLite virtual tables like `SPAN_JOIN` or C++ table
-   functions wrapped in macros like `_interval_intersect!`,
-   `_graph_aggregating_scan!`, and `_callstacks_self_to_cumulative!`. Chaining
-   two or three of these together requires deeply nested subqueries or a sequence
-   of intermediate views and tables.
-2. **Manual `id` plumbing and back-joins.** `_interval_intersect!` only returns
-   `ts`, `dur`, `id_0`, `id_1`, and so on. To read any other columns from your
-   inputs, every input needs an `id` column or an `_ii_subquery!` wrapper,
-   followed by a `JOIN` per input table on `id_0`, `id_1`, etc.
-3. **Manual indexing and temporary tables for trees.** Summing values up a
-   callstack or heap graph with `_graph_aggregating_scan!` requires
-   materializing a raw table, creating a `PERFETTO INDEX` on `parent_id` so the
-   leaf-finding `NOT IN` query does not go quadratic, running the scan, and
-   joining the result back onto the raw table by `id`.
-4. **Hard-to-read macro errors and SQLite virtual table overhead.** PerfettoSQL
-   macros are text substitutions, so a mistake in an argument produces a SQLite
-   error pointing inside the expanded macro body. At runtime, passing rows
-   between SQLite and custom operators forces every row through SQLite's
-   row-at-a-time virtual table interface.
+1. **Macros and virtual tables do not compose.** SQL has no interval
+   intersection or tree traversal, so Perfetto exposes them as SQLite virtual
+   tables like `SPAN_JOIN`, or as C++ table functions wrapped in macros like
+   `_interval_intersect!` and `_graph_aggregating_scan!`. Chaining two or
+   three of them takes deeply nested subqueries or a series of intermediate
+   tables.
+2. **Back-joins on `id`.** `_interval_intersect!` returns only `ts`, `dur`,
+   the partition columns and `id_0`, `id_1`, and so on. To read any other
+   column, every input needs an `id` column or an `_ii_subquery!` wrapper, and
+   the result needs a `JOIN` back to each input.
+3. **Indexes and temporary tables for trees.** Summing up a callstack or heap
+   graph with `_graph_aggregating_scan!` means saving a table, indexing
+   `parent_id` so the leaf-finding `NOT IN` query is not quadratic, running the
+   scan, and joining the result back by `id`.
+4. **Confusing errors and slow row-by-row execution.** Macros are text
+   substitution, so a mistake in an argument gives a SQLite error pointing
+   inside the expanded macro. At runtime, every row passes one at a time
+   through SQLite's virtual table interface.
 
 ### What changes with pipes
 
-PerfettoSQL pipe syntax uses linear `|>` stages, modeled on
-[GoogleSQL pipe syntax](https://cloud.google.com/bigquery/docs/pipe-syntax), and
-runs them on a columnar batch executor:
+Pipe syntax chains `|>` stages, as
+[GoogleSQL pipe syntax](https://cloud.google.com/bigquery/docs/pipe-syntax)
+does, and runs them on a columnar executor in C++:
 
-- **`INTERVAL INTERSECTION OF` and `TREE ACCUMULATE` are part of the language.**
-  They carry input columns through automatically. You do not need `id_0`/`id_1`
-  back-joins, `_ii_subquery!`, or `parent_id` indexes.
-- **Direct dataframe scans.** When a pipeline reads a finalized `PERFETTO TABLE`
-  such as `slice` or `sched`, it reads the table's columnar storage directly in
-  C++ without going through SQLite.
-- **Compile-time column checks and pruning.** The compiler checks column names
-  and types up front, points at the offending token on error, and drops unused
-  columns and unused tree aggregates before execution.
+- **Interval and tree operations are part of the language.** Stages like
+  `INTERVAL INTERSECTION OF` and `TREE ACCUMULATE` carry input columns through,
+  so there are no `id_0`/`id_1` back-joins, `_ii_subquery!` wrappers or
+  `parent_id` indexes.
+- **Tables are read directly.** A pipeline reads tables such as `slice`,
+  `sched` or any `PERFETTO TABLE` from their columnar storage, without going
+  through SQLite.
+- **Errors come early.** Column names and types are checked before anything
+  runs, and errors point at the token at fault. Unused columns and aggregates
+  are dropped before execution.
 
 ---
 
 ## Opting In
 
-In `trace_processor_shell`, the Perfetto UI, the Python API, and diff tests,
-enable pipe syntax on your connection with:
+In `trace_processor_shell`, the Perfetto UI, the Python API and diff tests,
+turn pipe syntax on with:
 
 ```sql
 PERFETTO PRAGMA pipelines = 1;
 ```
 
-You can turn it back off with `PERFETTO PRAGMA pipelines = 0;`. Inside the
-PerfettoSQL standard library, pipelines are enabled by default without the
-pragma.
+`PERFETTO PRAGMA pipelines = 0;` turns it off again. The standard library
+can always use pipelines.
 
 ---
 
 ## What Goes in SQL vs. the Pipeline?
 
-Pipe syntax is being built incrementally. Today, pipelines support three trace
-operations, `INTERVAL INTERSECTION OF`, `INTERVAL FLATTEN`, and
-`TREE ACCUMULATE`, and six
-column-reshaping stages: `SELECT`, `EXTEND`, `DROP`, `RENAME`, `SET`, and `AS`.
-
-When migrating a query today, split the work between SQL and the pipeline as
-follows:
+Pipelines do not do everything SQL does yet. Split the work like this:
 
 | Task | Where to do it today |
 | :--- | :--- |
-| Filtering rows, standard `JOIN`s, `GROUP BY`, window functions, and computed expressions | Inside the `FROM (SELECT ...)` source subquery, or in a standard SQL query over the resulting `PERFETTO TABLE`. |
-| Intersecting time intervals across two or more tables | `INTERVAL INTERSECTION OF (...) [PER ...]` at the start of a pipeline. |
-| Counting or summing concurrent activity within one set of intervals | `\|> INTERVAL FLATTEN [PER ...] AGGREGATE COUNT(*) AS active` stage; see the [worked example](/docs/analysis/perfetto-sql-pipe-getting-started.md#flattening-overlapping-intervals-interval-flatten). |
-| Summing values up or down a parent-child tree | `\|> TREE ACCUMULATE UP \| DOWN SUM(col) AS total` stage. |
-| Picking, dropping, renaming, or swapping columns | `\|> SELECT`, `\|> EXTEND`, `\|> DROP`, `\|> RENAME`, `\|> SET`, `\|> AS` stages. |
-| Sorting final output by numeric columns | `\|> ORDER BY col [DESC]` as the last stage. |
-| Sorting by strings or expressions, or limiting rows | In a `SELECT` with `ORDER BY` or `LIMIT` over the `PERFETTO TABLE` created by the pipeline. |
+| Filtering by comparing columns with numbers, joined by `AND` | `\|> WHERE dur > 0 AND depth = 0` |
+| Any other filter, `JOIN`s, window functions and computed expressions | In the `FROM (SELECT ...)` subquery, or in SQL over the table the pipeline saves. |
+| Intersecting intervals across two or more tables | `INTERVAL INTERSECTION OF (...) [PER ...]` |
+| Counting or summing concurrent activity in one set of intervals | `\|> INTERVAL FLATTEN [PER ...] AGGREGATE ...`; see the [example](/docs/analysis/perfetto-sql-pipe-getting-started.md#flattening-overlapping-intervals-interval-flatten). |
+| Filling the gaps between intervals | `\|> INTERVAL FILL GAPS WITH <background> [PER ...]` |
+| Aggregating up or down a tree | `\|> TREE ACCUMULATE UP \| DOWN ...` |
+| `COUNT(*)`, and `SUM`, `MIN` and `MAX` of integer columns, per group | `\|> AGGREGATE ... [GROUP BY ...]` |
+| Any other aggregate | In SQL. |
+| Removing repeated rows | `\|> DISTINCT` |
+| Picking, dropping, renaming or swapping columns | `\|> SELECT`, `EXTEND`, `DROP`, `RENAME`, `SET` and `AS` |
+| Sorting by numeric columns | `\|> ORDER BY col [DESC]` |
+| Sorting by strings or expressions, or `LIMIT` | In SQL over the table the pipeline saves. |
 
-> **Note:** A pipeline can be run as a top-level statement or as the body of
-> `CREATE [OR REPLACE] PERFETTO TABLE ... AS <pipeline>`. It cannot yet be used
-> as the body of `CREATE PERFETTO VIEW`, `CREATE PERFETTO FUNCTION`, or a `WITH`
-> CTE.
+A pipeline can be a statement on its own or the body of
+`CREATE [OR REPLACE] PERFETTO TABLE`. It cannot yet be the body of a view,
+function or `WITH` clause.
 
 ---
 
@@ -112,6 +107,7 @@
 
 ```sql
 INCLUDE PERFETTO MODULE intervals.intersect;
+INCLUDE PERFETTO MODULE wattson.utils;
 
 CREATE PERFETTO TABLE _estimates_w_tasks_attribution AS
 SELECT ii.ts, ii.dur, ii.cpu, uw.estimated_mw, s.utid
@@ -141,45 +137,35 @@
 
 ### Migration checklist for `INTERVAL INTERSECTION OF`
 
-1. **Drop the back-joins and `_ii_subquery!` wrappers.**
-   `_interval_intersect!` required every input to have an `id` column so you
-   could join `id_0` and `id_1` back to the input tables.
-   `INTERVAL INTERSECTION OF` carries the operands' columns automatically and
-   only requires `ts` and `dur` on its inputs. Only keep `_ii_subquery!` if you
-   specifically need SQLite's `_auto_id` exposed as `alias.id` in your output.
-2. **Give every operand a distinct alias.**
-   Write `INTERVAL INTERSECTION OF (a AS x, b AS y)`. Omitting `AS <alias>` on
-   a subquery or reusing an alias across operands is a compile error.
-3. **Use `PER` instead of partition column lists or `PARTITIONED`.**
-   Write `PER cpu` or `PER utid, track_id`. For unpartitioned intersections,
-   omit `PER` altogether.
-4. **Qualify operand columns, and leave region `ts`, `dur`, and `PER` columns bare.**
-   Bare `ts` and `dur` are the intersected region's start and duration. Bare
-   `cpu` is the partition key shared by the matched rows. All other operand
-   columns, including each operand's original unclipped `x.ts` and `x.dur`, must
-   be qualified with the operand's alias, such as `x.utid` or `y.freq`. Always
-   follow `INTERVAL INTERSECTION OF` with `|> SELECT ...`; without a `SELECT`
-   stage, every operand's `ts` and `dur` remain in the output row and produce
-   duplicate column names.
-5. **Watch for behavioral differences.**
-   - **Rows with `dur IS NULL` or `ts IS NULL` are skipped.** If an input table
-     computes duration with `lead(ts) OVER (...) - ts AS dur`, its final row has
-     `dur IS NULL`. `_interval_intersect!` coerced `NULL` duration to `0`;
-     `INTERVAL INTERSECTION OF` skips rows where `ts` or `dur` is `NULL`.
-   - **Negative `ts` or `dur` is an error.** Unfinished slices with `dur = -1`
-     are rejected with `ts or dur is below zero`. Filter `WHERE dur >= 0` or
-     `WHERE dur > 0` in the input.
-   - **Overlapping intervals within an operand work.** `SPAN_JOIN` produces
-     wrong results when intervals overlap within a single table, whereas
-     `INTERVAL INTERSECTION OF` handles overlapping intervals automatically.
+1. **Drop the back-joins and `_ii_subquery!` wrappers.** Inputs only need
+   `ts` and `dur`; every other column carries through.
+2. **Give every input its own alias:** `INTERVAL INTERSECTION OF (a AS x, b AS
+   y)`. A subquery without an alias, or two inputs with one alias, is an error.
+3. **Use `PER` for partitions:** `PER cpu`, or `PER utid, track_id`. Leave it
+   out to intersect everything.
+4. **Bare names mean the region.** `ts` and `dur` are the overlapping region,
+   and `cpu` is the shared `PER` value. An input's own bounds are `x.ts` and
+   `x.dur`. Other columns can be bare, as in `utid`, unless two inputs have
+   one of that name: then write `x.utid`. If two inputs share a column name,
+   end with a `|> SELECT` which names each copy, or the result cannot be saved
+   as a table.
+5. **Watch for differences in behaviour.**
+   - **`NULL` bounds are skipped.** A `dur` computed with
+     `lead(ts) OVER (...) - ts` is `NULL` on the last row.
+     `_interval_intersect!` treated that as `dur = 0`; the pipeline skips the
+     row.
+   - **Intervals may overlap within an input.** `SPAN_JOIN` gives wrong
+     results when they do; `INTERVAL INTERSECTION OF` handles it.
+   - **Negative bounds are an error**, as in `_interval_intersect!`. Filter
+     out unfinished slices, which have `dur = -1`, with `|> WHERE dur >= 0`
+     or in the input subquery.
 
 ---
 
 ## Migrating Tree Aggregations
 
-Replace `_graph_aggregating_scan!`, `_callstacks_self_to_cumulative!`, and
-recursive CTE subtree or path sums with `TREE ACCUMULATE UP` and
-`TREE ACCUMULATE DOWN`.
+Replace `_graph_aggregating_scan!`, and recursive CTEs which sum over subtrees
+or paths, with `TREE ACCUMULATE UP` and `TREE ACCUMULATE DOWN`.
 
 ### Before: `_graph_aggregating_scan!`
 
@@ -237,29 +223,22 @@
 
 ### Migration checklist for `TREE ACCUMULATE`
 
-1. **Delete intermediate raw tables, `parent_id` indexes, and back-joins.**
-   You can pipe directly from a macro or subquery:
+1. **Delete intermediate tables, `parent_id` indexes and back-joins.** Pipe
+   straight from a macro or subquery:
    ```sql
    CREATE PERFETTO TABLE _linux_perf_callstacks AS
    FROM _callstacks_for_callsites!((SELECT callsite_id FROM perf_sample))
    |> TREE ACCUMULATE UP SUM(self_count) AS cumulative_count;
    ```
-   `TREE ACCUMULATE` keeps all columns of the input row and appends
-   `cumulative_count` at the end. You do not need to `JOIN` the result back to
-   the input table or create a `PERFETTO INDEX` on `parent_id`.
-2. **Make sure the source has `id` and `parent_id` columns.**
-   `TREE ACCUMULATE` looks up bare `id` and `parent_id` in the current row.
-   Root nodes must have `parent_id IS NULL`.
-3. **Totals always include the node itself.**
-   `TREE ACCUMULATE UP SUM(x) AS total` adds `x` for the node to `x` for all of
-   its descendants. `TREE ACCUMULATE DOWN SUM(x) AS path` adds `x` for the node
-   to `x` for all of its ancestors. When migrating hand-written
-   `_graph_aggregating_scan!` queries, check whether the old step query forgot
-   to add `r.self_*` for non-leaf nodes.
-4. **Preserve `ORDER BY id` on public tables if required.**
-   `TREE ACCUMULATE UP` emits rows in child-first order, and `DOWN` emits rows
-   in parent-first order. If a public stdlib table or test expects rows sorted
-   by `id`, end the pipeline with `|> ORDER BY id`.
+   The input's columns are kept, with `cumulative_count` added at the end.
+2. **The source needs `id` and `parent_id` columns**, with `parent_id IS NULL`
+   on roots.
+3. **Totals include the node itself.** `UP SUM(x)` adds a node's `x` to its
+   descendants'; `DOWN SUM(x)` adds it to its ancestors'. Hand-written
+   `_graph_aggregating_scan!` steps sometimes forgot to add `r.self_*` for
+   nodes with children, so check that results match.
+4. **Sort if order matters.** `UP` outputs children first and `DOWN` parents
+   first. If a table or test expects rows by `id`, end with `|> ORDER BY id`.
 
 ---
 
@@ -267,44 +246,44 @@
 
 ### 1. Every source column needs a valid, distinct name
 
-When a pipeline reads from a SQL subquery, the compiler checks every column
-returned by that subquery before column pruning runs, including columns that a
-later stage drops:
+Every column of a source subquery is checked, even one a later stage drops:
 
-- **Unaliased expressions fail:**
+- **An expression needs a name:**
   ```sql
-  -- ERROR: expected every column to have a valid name, but '1 + 1' is not one:
+  -- ERROR: expected every column to have a name, but column 3 has none:
   -- give it one with AS
   FROM (SELECT id, parent_id, 1 + 1 FROM tree)
   |> TREE ACCUMULATE UP SUM(id) AS total
   |> SELECT id, total;
   ```
-- **Duplicate column names in a subquery fail:** SQLite renames the second `x`
-  in `SELECT 1 AS x, 2 AS x` to `x:1`. The pipeline compiler rejects this with:
-  `expected distinct column names, but there are two named 'x', which SQLite renamed to 'x' and 'x:1'`.
+- **Names must be distinct:** `FROM (SELECT 1 AS x, 2 AS x)` fails with
+  `expected distinct column names, but there are two named 'x'`.
 
-### 2. Wrap `WHERE` and `JOIN` in parentheses inside `FROM`
+### 2. `FROM` takes a table, a macro or a subquery
 
-A pipeline's `FROM` clause only accepts a table or view name, or a parenthesized
-`SELECT` subquery:
+`FROM` cannot have its own `WHERE` or `JOIN`. Filter with a `|> WHERE` stage,
+or put the SQL in a subquery:
 
 ```sql
 -- ERROR:
 FROM slice WHERE dur > 0 |> TREE ACCUMULATE UP SUM(dur) AS total;
 
 -- OK:
-FROM (SELECT id, parent_id, dur FROM slice WHERE dur > 0)
+FROM slice
+|> WHERE dur > 0
+|> TREE ACCUMULATE UP SUM(dur) AS total;
+
+-- OK, and needed for a JOIN or a filter WHERE does not support:
+FROM (SELECT id, parent_id, dur FROM slice WHERE name GLOB 'Choreographer*')
 |> TREE ACCUMULATE UP SUM(dur) AS total;
 ```
 
-### 3. Table aliases snapshot the row at the point they are bound
+### 3. An alias remembers the row as it was when it was set
 
-In pipe stages like `DROP`, `RENAME`, `SET`, and `EXTEND`, a table alias
-remembers the columns the row had when the alias was created:
+`DROP`, `RENAME`, `SET` and `EXTEND` do not change an alias:
 
-- `FROM t |> DROP x |> SELECT t.x` still works and recovers `x`.
-- `FROM t |> RENAME x AS y |> SELECT t.x` still accesses the column as `t.x`,
-  while bare `y` accesses it by its new name.
-- `|> SELECT ...` builds a new row and clears all previous aliases.
-- `|> AS u` replaces all previous aliases with `u`, snapshotting the current
-  row.
+- `FROM t AS t |> DROP x |> SELECT t.x` still finds `x`.
+- After `FROM t AS t |> RENAME x AS y`, the column is `y` bare but still `t.x`
+  through the alias.
+- `|> SELECT` clears every alias.
+- `|> AS u` replaces every alias with `u`, for the row as it is now.
diff --git a/docs/analysis/perfetto-sql-pipe-syntax.md b/docs/analysis/perfetto-sql-pipe-syntax.md
index f6f00bf..e1e5548 100644
--- a/docs/analysis/perfetto-sql-pipe-syntax.md
+++ b/docs/analysis/perfetto-sql-pipe-syntax.md
@@ -1,8 +1,5 @@
 # PerfettoSQL Pipe Syntax Reference
 
-This page is the language syntax and semantics reference for PerfettoSQL
-pipelines.
-
 > **Warning:** Pipe syntax is **experimental and unstable**. Do **not** rely on
 > it in dashboards, scripts, or production queries. Anything can and will break
 > without notice. Outside the PerfettoSQL standard library, enable it on a
@@ -18,373 +15,556 @@
 
 ## Pragma and Statement Forms
 
-### `PERFETTO PRAGMA pipelines`
+### `PERFETTO PRAGMA pipelines` {#perfetto-pragma-pipelines}
 
-Controls whether pipe syntax is permitted on the current connection outside the
-standard library:
+Turns pipe syntax on or off for the connection. The standard library can always
+use it.
 
 ```sql
-PERFETTO PRAGMA pipelines = 1;  -- Enable pipelines
-PERFETTO PRAGMA pipelines = 0;  -- Disable pipelines
+PERFETTO PRAGMA pipelines = 1;  -- On
+PERFETTO PRAGMA pipelines = 0;  -- Off
 ```
 
-The right-hand side must evaluate to a whole number. Unknown pragma names
-produce an error.
+The value must be a non-negative integer literal; any value other than `0`
+turns pipelines on. The pragma name is case-sensitive.
 
 ### Top-level forms
 
-A pipeline is valid in two statement positions:
+A pipeline can be a statement on its own, or the body of a `PERFETTO TABLE`:
 
 ```sql
--- 1. Standalone query
 <pipeline>;
 
--- 2. Materialized Perfetto table
 CREATE [OR REPLACE] PERFETTO TABLE <table_name> [(<schema>)] AS
 <pipeline>;
 ```
 
-A `<pipeline>` consists of a source, either `FROM` or `INTERVAL INTERSECTION OF`,
-followed by zero or more `|>` stages:
+It cannot yet be the body of a view, function or `WITH` clause, or appear inside
+a subquery.
 
-```sql
-<source>
-[|> <stage_1>]
-[|> <stage_2>]
-...
+A `<pipeline>` is a source followed by any number of stages:
+
+```railroad pipeline
+Diagram(
+  NonTerminal('source-clause'),
+  ZeroOrMore(Sequence(Terminal('|>'), NonTerminal('stage'))))
 ```
 
-> **Note:** The pipe operator `|>` must be written with no whitespace between
-> `|` and `>`. The pipeline keywords `TREE`, `ACCUMULATE`, `UP`, `DOWN`,
-> `INTERVAL`, `INTERSECTION`, `FLATTEN`, `AGGREGATE`, `PER`, and `EXTEND` are non-reserved and remain
-> valid as normal identifiers in standard SQL statements.
+- `|>` must be written with no space between `|` and `>`.
+- `TREE`, `ACCUMULATE`, `UP`, `DOWN`, `INTERVAL`, `INTERSECTION`, `FLATTEN`,
+  `FILL`, `GAPS`, `AGGREGATE`, `PER` and `EXTEND` are not reserved, so they can
+  still be used as names in SQL.
+- An alias always needs `AS`: `FROM slice AS s`, not `FROM slice s`.
+
+A `<source-clause>` is [`FROM`](#from) or
+[`INTERVAL INTERSECTION OF`](#interval-intersection-of). A `<stage>` is one of:
+
+```railroad stage
+Diagram(Choice(0,
+  Link(Terminal('WHERE'), '#where'),
+  Link(Terminal('DISTINCT'), '#distinct'),
+  Link(Terminal('ORDER BY'), '#order-by'),
+  Link(Terminal('INTERVAL FLATTEN'), '#interval-flatten'),
+  Link(Terminal('INTERVAL FILL GAPS'), '#interval-fill-gaps'),
+  Link(Terminal('TREE ACCUMULATE'), '#tree-accumulate'),
+  Link(Terminal('AGGREGATE'), '#aggregate'),
+  Link(Terminal('SELECT'), '#select'),
+  Link(Terminal('EXTEND'), '#extend'),
+  Link(Terminal('DROP'), '#drop'),
+  Link(Terminal('RENAME'), '#rename'),
+  Link(Terminal('SET'), '#set'),
+  Link(Terminal('AS'), '#as')))
+```
+
+### Shared rules
+
+A `<source>` is a table or a subquery, with an optional alias:
+
+```railroad source
+Diagram(
+  Choice(0,
+    NonTerminal('table-name'),
+    Sequence(Terminal('('), NonTerminal('select-stmt'), Terminal(')'))),
+  Optional(Sequence(Terminal('AS'), NonTerminal('alias'))))
+```
+
+A `<column>` can be qualified by an alias:
+
+```railroad column
+Diagram(Optional(Sequence(NonTerminal('alias'), Terminal('.'))), NonTerminal('name'))
+```
+
+A `<per-clause>` lists the columns that split rows into groups:
+
+```railroad per-clause
+Diagram(Terminal('PER'), OneOrMore(NonTerminal('column'), Terminal(',')))
+```
+
+A column listed again groups nothing new.
+
+### Limits
+
+- A pipeline outputs at most 256 columns.
+- Every column of a source must have a distinct name made of letters, digits
+  and `_`, not starting with a digit. This holds even for columns a later stage
+  drops:
+  - A column with no name, such as `SELECT 1 + 1`, fails with `expected every
+    column to have a name, but column <n> has none: give it one with AS`.
+  - A name which is not a valid identifier fails with `expected every column
+    to have a valid name, but '<name>' is not one: give it one with AS`.
+  - Two columns with one name fail with `expected distinct column names, but
+    there are two named '<name>'`.
 
 ---
 
-## Pipeline Sources
+## Sources
 
-### `FROM`
+### `FROM` {#from}
 
-Starts a pipeline from a single relation:
-
-```sql
-FROM [<schema>.]<table_name> [[AS] <alias>]
-FROM (<select_stmt>) [[AS] <alias>]
+```railroad
+Diagram(Terminal('FROM'), NonTerminal('source'))
 ```
 
-- `<table_name>` may be any table or view, or a macro invocation that expands to
-  a table or parenthesized subquery.
-- `(<select_stmt>)` may be any valid SQL `SELECT` statement enclosed in
-  parentheses.
-- **Table qualifier:**
-  - If `<alias>` is given, columns of the source can be qualified with
-    `<alias>.<col>`. When the source is a table name, `<alias>` replaces
-    `<table_name>` as the qualifier.
-  - If the source is an unaliased `<table_name>`, columns can be qualified with
-    `<table_name>.<col>`.
-  - If the source is an unaliased `(<select_stmt>)`, its columns have no table
-    qualifier unless a later `|> AS <alias>` stage binds one.
+- `<table-name>` is a table, a view, or a macro which expands to one. A
+  schema-qualified name such as `main.t` is not supported.
+- `<select-stmt>` is any SQL `SELECT`.
+- **Qualifiers:** `FROM slice` lets columns be written `slice.<col>`.
+  `FROM slice AS s` makes that `s.<col>` instead. An unaliased subquery has no
+  qualifier until a later `|> AS <alias>`.
 
-### `INTERVAL INTERSECTION OF`
+### `INTERVAL INTERSECTION OF` {#interval-intersection-of}
 
-Starts a pipeline with the overlapping time regions across two or more
-relations:
+Finds where intervals from two or more sources overlap:
 
-```sql
-INTERVAL INTERSECTION OF (
-  <source_1> [AS] <alias_1>,
-  <source_2> [AS] <alias_2>
-  [, <source_N> [AS] <alias_N> ...]
-) [PER <col_1> [, <col_2> ...]]
+```railroad
+Diagram(
+  Terminal('INTERVAL'), Terminal('INTERSECTION'), Terminal('OF'),
+  Terminal('('), OneOrMore(NonTerminal('source'), Terminal(',')), Terminal(')'),
+  Optional(NonTerminal('per-clause')))
 ```
 
 #### Requirements
 
-1. At least two operand sources must be listed.
-2. Every operand must have a distinct alias. An unaliased table name acts as its
-   own alias; a parenthesized subquery must specify `[AS] <alias>`.
-3. Every operand must contain `ts` and `dur` columns, and every column listed in
-   `PER` must exist in every operand.
+- At least two sources.
+- Each source has its own alias. A table name is its own alias; a subquery
+  needs `AS <alias>`.
+- Every source has `ts` and `dur`, and every `PER` column.
 
-#### Output columns and scoping
+#### Output
 
-For each overlapping region `[ts, ts + dur)` shared by all operands within a
-matching `PER` key group, one row is produced with the following columns:
+One row is produced for each region `[ts, ts + dur)` where a row of every
+source overlaps, among rows that agree on the `PER` columns.
 
-1. `ts` and `dur`: 64-bit integer columns holding the intersected region's start
-   and duration. These are the only `ts` and `dur` columns visible to
-   unqualified column lookups.
-2. Each operand's columns in operand order:
-   - The first operand's `PER` key columns are visible both unqualified, such as
-     `cpu`, and qualified, such as `<alias_1>.cpu`.
-   - All other operand columns are qualified-only. This includes each operand's
-     original `ts` and `dur`, as well as subsequent operands' copies of `PER`
-     columns. They can only be referenced via `<alias_i>.<col>` or expanded via
-     `*` or `<alias_i>.*`.
+| Column | Found by bare name | Found through alias |
+| :--- | :--- | :--- |
+| Region `ts`, `dur` | Yes | No |
+| Each source's own `ts`, `dur` | No | `<alias>.ts` |
+| `PER` columns of the first source | Yes | Yes |
+| `PER` columns of later sources | No | Yes |
+| Every other source column | Yes, if only one source has it | Yes |
 
-#### Interval semantics
+A bare name two sources share is ambiguous, and an error when something refers
+to it.
 
-- **Half-open bounds:** Each interval is `[ts, ts + dur)`. Two intervals
-  touching at their endpoints, such as `[0, 10)` and `[10, 20)`, do not
-  intersect.
-- **Zero-duration points:** A row with `dur = 0` is a point at instant `ts`. It
-  intersects an interval `[a, b)` when `a <= ts < b`, and intersects another
-  point when both sit at the same instant `ts`, producing a region with
+`*`, `|> AS <alias>` and the result of a pipeline which ends at the
+intersection all hold the columns found by bare name: the region's `ts` and
+`dur`, then each source's columns in order. When two sources share a column
+name, both copies are in the result, which then cannot be saved as a table. Add
+a `|> SELECT` naming them through their aliases.
+
+#### Interval rules
+
+- **Half-open:** `[0, 10)` and `[10, 20)` do not overlap.
+- **Points:** A row with `dur = 0` is the instant `ts`. It overlaps `[a, b)`
+  when `a <= ts < b`, and another point at the same instant. The region has
   `dur = 0`.
-- **Missing bounds:** A row with `ts IS NULL` or `dur IS NULL` covers no time
-  and is skipped.
-- **Negative bounds:** A row with `ts < 0` or `dur < 0` fails with the error
-  `ts or dur is below zero`.
-- **`NULL` in `PER` columns:** Two rows with `NULL` in a `PER` column agree on
-  that column, matching `GROUP BY` semantics.
-
-### Source column naming rules
-
-Every column of any pipeline source must have a valid identifier name matching
-`^[a-zA-Z_][a-zA-Z0-9_]*$` and must be distinct within that source, even if a
-later stage drops the column:
-
-- Unaliased SQL expressions like `1 + 1` or `max(ts)` are rejected with:
-  `expected every column to have a valid name, but '<expr>' is not one: give it one with AS`.
-- Duplicate column names in a source are rejected with:
-  `expected distinct column names, but there are two named '<name>'`.
+- **`NULL` bounds:** A row with a `NULL` `ts` or `dur` is skipped.
+- **Negative bounds:** A negative `ts` or `dur` fails with `ts or dur is below
+  zero`.
+- **Overflow:** `ts + dur` beyond the 64-bit range fails with `integer
+  overflow`.
+- **`NULL` in `PER` columns:** Rows holding `NULL` in a `PER` column agree on
+  it, as in `GROUP BY`.
 
 ---
 
-## Pipeline Stages
+## Aggregates
 
-### `INTERVAL FLATTEN`
+`INTERVAL FLATTEN`, `TREE ACCUMULATE` and `AGGREGATE` take an
+`<aggregate-list>`, and treat every aggregate the same way:
 
-Splits overlapping intervals into segments and aggregates the rows active in
-each segment:
-
-```sql
-|> INTERVAL FLATTEN [PER <col_1> [, <col_2> ...]]
-  AGGREGATE <aggregate> AS <out_1> [, <aggregate> AS <out_2> ...]
+```railroad aggregate-list
+Diagram(OneOrMore(
+  Sequence(NonTerminal('aggregate'), Terminal('AS'), NonTerminal('name')),
+  Terminal(',')))
 ```
 
-- **Interval columns:** Resolves bare `ts` and `dur` in the current row. Both
-  must be integer columns. Input need not be sorted; the pipeline arranges
-  rows by timestamp within each group.
-- **Grouping:** Each distinct combination of `PER` values is flattened
-  independently. Without `PER`, all rows belong to one group. `NULL` keys
-  group together, as in SQL `GROUP BY`.
-- **Aggregates:** At least one is required. Supported forms are `COUNT(*)`
-  and `SUM([<qualifier>.]<column>)`. Each needs an `AS` name. `SUM` accepts
-  integer columns (`ID`, `UINT32`, `INT32`, or `LONG`), ignores `NULL` values,
-  and returns `NULL` if all contributing values are `NULL`. Expressions,
-  `DISTINCT`, `FILTER`, `OVER`, and other aggregate functions are unsupported.
-- **Output:** Replaces the current row with `ts`, `dur`, the `PER` columns in
-  their listed order, and the named aggregates in their listed order. `ts`,
-  `dur`, and aggregates are `LONG` columns. Other input columns and all table
-  aliases are removed. Output names must be distinct.
-
-#### Interval semantics
-
-- **Segments:** Positive-duration intervals cover `[ts, ts + dur)`. Output
-  splits at input start and end timestamps, with aggregates over the rows
-  covering each segment. Gaps with no active rows produce no output. Adjacent
-  segments are not merged merely because their aggregate values are equal.
-- **Zero-duration points:** Rows with `dur = 0` at the same timestamp produce
-  one additional zero-duration segment per group. Its aggregates include all
-  points there and all positive-duration intervals covering that instant.
-  Intervals ending there are excluded; intervals starting there are included.
-  Points do not contribute to positive-duration segments.
-- **Missing bounds:** Rows with `ts IS NULL` or `dur IS NULL` are skipped.
-- **Negative bounds:** Negative `ts` or `dur` values cause an error. Filter out
-  unfinished trace slices (`dur = -1`) in the source subquery if needed.
-- **Overflow:** Interval endpoints and aggregate arithmetic use checked signed
-  64-bit integers; overflow causes an error.
-
-For a worked example, see
-[Flattening Overlapping Intervals](/docs/analysis/perfetto-sql-pipe-getting-started.md#flattening-overlapping-intervals-interval-flatten).
-
----
-
-### `TREE ACCUMULATE`
-
-Accumulates sums up or down a tree defined by `id` and `parent_id`:
-
-```sql
-|> TREE ACCUMULATE UP|DOWN
-  SUM([<qualifier>.]<col_1>) AS <out_1>
-  [, SUM([<qualifier>.]<col_2>) AS <out_2> ...]
+```railroad aggregate
+Diagram(Choice(0,
+  Sequence(Terminal('COUNT'), Terminal('('), Terminal('*'), Terminal(')')),
+  Sequence(
+    Choice(0, Terminal('SUM'), Terminal('MIN'), Terminal('MAX')),
+    Terminal('('), NonTerminal('column'), Terminal(')'))))
 ```
 
-- **Tree structure columns:** Resolves bare `id` and `parent_id` in the current
-  row. Root nodes have `parent_id IS NULL`.
-- **Directions:**
-  - `UP`: Bottom-up fold. Each node's aggregate is the sum of its own value and
-    the values of all its descendants. Output rows are emitted child-first.
-  - `DOWN`: Top-down fold. Each node's aggregate is the sum of its own value and
-    the values of all its ancestors. Output rows are emitted parent-first.
-- **Aggregate expressions:**
-  - Only `SUM(<column_ref>)` is currently supported. `DISTINCT`, `FILTER`,
-    `OVER`, `*`, non-column expressions, and other aggregate functions are
-    rejected.
-  - The target column must be an integer type: `ID`, `UINT32`, `INT32`, or
-    `LONG`. `NULL` values contribute `0`.
-  - All aggregates in a single stage resolve their input columns against the row
-    before the stage. A stage cannot reference an output column defined in the
-    same stage.
-- **Output:** Keeps all columns of the input row and existing table aliases, and
-  appends `<out_1>, <out_2>, ...` as `LONG` columns.
+- **Forms:** Each aggregate needs an `AS` name. Expressions, `DISTINCT`,
+  `FILTER`, `OVER` and other functions are rejected.
+- **`COUNT(*)`** counts rows.
+- **`SUM`, `MIN` and `MAX`** take an integer column. They skip `NULL`s and
+  return `NULL` if every value is `NULL`. A column from a SQL source whose type
+  is not known in advance is checked when the query runs.
+- **Results** are `LONG` columns. Overflow is an error.
+- **Scope:** Every aggregate reads the row from before the stage, so one
+  aggregate cannot read another.
+- **Names:** An aggregate can take a name another column has. That name is then
+  ambiguous, and an error when a later stage refers to it.
 
 ---
 
-### `ORDER BY`
+## Stages
+
+### `WHERE` {#where}
+
+Keeps the rows that match a condition:
+
+```railroad
+Diagram(
+  Terminal('WHERE'),
+  OneOrMore(
+    Sequence(
+      NonTerminal('column'), NonTerminal('op'), NonTerminal('number')),
+    Terminal('AND')))
+```
+
+- `<op>` is one of `=`, `!=`, `<`, `<=`, `>` and `>=`.
+- `<number>` is an integer or floating-point literal.
+- `NULL` never matches. Integers compare with fractions as in SQL.
+- Keeps all columns and aliases.
+- Not supported yet: `OR`, `NOT`, `IS NULL`, parentheses, strings, functions,
+  arithmetic, and a literal on the left. Filter in the source subquery instead.
+
+### `DISTINCT` {#distinct}
+
+Removes repeated rows:
+
+```railroad
+Diagram(Terminal('DISTINCT'))
+```
+
+- Rows are equal when they agree on every column found by bare name. `NULL`s
+  are equal.
+- Columns only an alias finds, such as an intersection's `x.ts`, are not
+  compared, and are dropped since they have no one value per row. Aliases are
+  kept, holding only the columns that were compared.
+- The first of each set of equal rows is kept, and kept rows stay in order.
+- A row can have at most 64 columns.
+
+### `ORDER BY` {#order-by}
 
 Sorts the rows:
 
-```sql
-|> ORDER BY <expr_1> [ASC | DESC] [, <expr_2> [ASC | DESC] ...]
+```railroad
+Diagram(
+  Terminal('ORDER'), Terminal('BY'),
+  OneOrMore(
+    Sequence(NonTerminal('column'),
+      Optional(Choice(0, Terminal('ASC'), Terminal('DESC')))),
+    Terminal(',')))
 ```
 
-- **Keys:** The first key decides the order and each later key breaks ties
-  among the ones before it. Each defaults to `ASC`. A key parses as an
-  expression, but only a column, optionally qualified, is supported yet. A
-  bitwise OR (`|`) must be in parentheses, since `|>` starts the next stage.
-- **Types:** Keys must be integer or floating-point columns. Ordering by a
-  string column is not supported yet. A key read from a SQL subquery or view
-  must hold integers.
-- **`NULL` values:** Sort as in SQLite: first when ascending, last when
-  descending.
-- **Ties:** Rows equal on every key keep the order they arrived in.
-- **Output:** Keeps all columns of the input row and existing table aliases.
-  A later `TREE ACCUMULATE` or `INTERVAL FLATTEN` stage arranges rows as it
-  needs, so put `ORDER BY` last to order a pipeline's result.
+- The first key decides the order and each later key breaks ties. Each defaults
+  to `ASC`.
+- A key is a column, which can be qualified. Expressions are not supported yet.
+- Keys must hold numbers. Sorting by a string column is not supported yet.
+- `NULL`s come first when ascending and last when descending, as in SQLite.
+- Rows equal on every key keep their order.
+- Keeps all columns and aliases.
+- `INTERVAL FLATTEN`, `INTERVAL FILL GAPS`, `TREE ACCUMULATE` and `AGGREGATE`
+  arrange rows their own way, so put `ORDER BY` after them.
+
+### `INTERVAL FLATTEN` {#interval-flatten}
+
+Splits overlapping intervals into segments and aggregates the rows active in
+each:
+
+```railroad
+Diagram(
+  Terminal('INTERVAL'), Terminal('FLATTEN'), Optional(NonTerminal('per-clause')),
+  Terminal('AGGREGATE'), NonTerminal('aggregate-list'))
+```
+
+- **Intervals:** Bare `ts` and `dur`, which must be integer columns. Input does
+  not need to be sorted.
+- **Groups:** Each combination of `PER` values is flattened on its own. Without
+  `PER`, all rows are one group. `NULL` keys group together.
+- **Aggregates:** At least one; see [Aggregates](#aggregates). Each is taken
+  over the rows covering a segment.
+- **Output:** `ts`, `dur`, the `PER` columns, then the aggregates. Every other
+  column and all aliases are dropped. A `PER` column listed twice is output
+  twice, so its name is then ambiguous.
+
+Interval rules:
+
+- **Segments:** Output splits at every input start and end. Gaps with no rows
+  give no output. Neighbouring segments are not merged even when their values
+  match.
+- **Points:** Rows with `dur = 0` at one instant give one extra segment with
+  `dur = 0`. Its aggregates cover those points and the intervals active at that
+  instant: intervals starting there count, intervals ending there do not.
+  Points do not count towards other segments.
+- **`NULL` bounds:** Rows with a `NULL` `ts` or `dur` are skipped.
+- **Negative bounds** are an error. Filter out unfinished slices, which have
+  `dur = -1`, first.
+- **Overflow** is an error.
+
+For an example, see
+[Flattening Overlapping Intervals](/docs/analysis/perfetto-sql-pipe-getting-started.md#flattening-overlapping-intervals-interval-flatten).
+
+### `INTERVAL FILL GAPS` {#interval-fill-gaps}
+
+Keeps every row and adds a row for each stretch of a background interval which
+no row covers:
+
+```railroad
+Diagram(
+  Terminal('INTERVAL'), Terminal('FILL'), Terminal('GAPS'), Terminal('WITH'),
+  NonTerminal('source'), Optional(NonTerminal('per-clause')))
+```
+
+`<source>` holds the background intervals.
+
+- **Intervals:** Bare `ts` and `dur`, in the input and the background.
+- **Lanes:** Each combination of `PER` values is filled on its own. The
+  background has either every `PER` column or none of them:
+  - With them, it says which lanes exist. A lane with no input is filled whole,
+    and input in a lane the background does not have gets no fillers.
+  - Without them, the same background applies to every lane in the input.
+- **Fillers** take each background column's value by name, their lane's `PER`
+  values, and `NULL` for every other column. Every background column must also
+  be in the input.
+- **Types:** A column takes one type across both inputs. A column holding
+  strings in one and numbers in the other is an error.
+- **Output:** The input's columns. Rows come out in no particular order. Aliases
+  are kept.
+
+Interval rules:
+
+- Overlapping input rows cover their union.
+- An input row with `dur = -1` covers everything after its `ts`.
+- An input row with a `NULL` `ts` covers nothing, but is still output.
+- A point does not split a filler.
+- A negative input `ts` is an error.
+- Background rows which overlap within a lane are an error.
+
+For an example, see
+[Filling Gaps](/docs/analysis/perfetto-sql-pipe-getting-started.md#filling-gaps-interval-fill-gaps).
+
+### `TREE ACCUMULATE` {#tree-accumulate}
+
+Aggregates up or down a tree:
+
+```railroad
+Diagram(
+  Terminal('TREE'), Terminal('ACCUMULATE'),
+  Choice(0, Terminal('UP'), Terminal('DOWN')),
+  NonTerminal('aggregate-list'))
+```
+
+- **Tree:** Bare `id` and `parent_id`. Roots have `parent_id IS NULL`.
+- **Directions:**
+  - `UP`: each node's aggregate covers itself and all its descendants. Rows
+    come out children first.
+  - `DOWN`: each node's aggregate covers itself and all its ancestors. Rows
+    come out parents first.
+- **Aggregates:** See [Aggregates](#aggregates). `COUNT(*)` going `DOWN` is a
+  node's depth, counting from 1.
+- **Output:** Every input column, then the aggregates. Aliases are kept but do
+  not include the new columns.
+- **Errors:** Two rows with one `id`, a row which is its own parent, and a
+  `parent_id` with no row of that `id`. These are only checked if a later stage
+  reads one of the aggregates; otherwise the stage is skipped.
+
+### `AGGREGATE` {#aggregate}
+
+Collapses each group of rows into one:
+
+```railroad
+Diagram(
+  Terminal('AGGREGATE'), NonTerminal('aggregate-list'),
+  Optional(NonTerminal('group-by')))
+```
+
+```railroad group-by
+Diagram(
+  Terminal('GROUP'), Terminal('BY'),
+  OneOrMore(
+    Sequence(NonTerminal('column'),
+      Optional(Sequence(Terminal('AS'), NonTerminal('name')))),
+    Terminal(',')))
+```
+
+- **Groups:** Rows that agree on every `GROUP BY` column. A key can have any
+  type and can be qualified. `NULL` keys group together. Without `GROUP BY`,
+  all rows are one group, which gives a row even when there are no rows.
+- **Aggregates:** At least one; see [Aggregates](#aggregates).
+- **Output:** The keys, then the aggregates. A key is named by its `AS` name,
+  or else its column name without qualifier. Every other column and all aliases
+  are dropped. A key listed twice, even as `cpu` and `t.cpu`, groups once
+  but is output twice.
+- **Order:** Groups come out in the order their first rows arrived.
+
+For example, CPU time per slice:
+
+```sql
+INCLUDE PERFETTO MODULE slices.with_context;
+
+INTERVAL INTERSECTION OF (
+  (SELECT id, ts, dur, utid FROM thread_slice WHERE dur > 0) AS s,
+  (SELECT ts, dur, utid FROM sched WHERE dur > 0) AS running
+) PER utid
+|> AGGREGATE SUM(dur) AS cpu_time GROUP BY s.id
+|> ORDER BY id;
+```
+
+### `SELECT` {#select}
+
+Replaces the row with the listed items, and clears all aliases:
+
+```railroad
+Diagram(Terminal('SELECT'), OneOrMore(NonTerminal('item'), Terminal(',')))
+```
+
+Each `<item>` is one of:
+
+```railroad item
+Diagram(Choice(0,
+  Sequence(NonTerminal('column'),
+    Optional(Sequence(Terminal('AS'), NonTerminal('name')))),
+  NonTerminal('star')))
+```
+
+- **A column.** Without `AS`, it keeps its name. Other expressions parse, but
+  fail with `a computed column is not supported yet`.
+- **A `<star>`:**
+
+```railroad star
+Diagram(
+  Optional(Sequence(NonTerminal('alias'), Terminal('.'))), Terminal('*'),
+  Optional(NonTerminal('except')), Optional(NonTerminal('replace')))
+```
+
+```railroad except
+Diagram(
+  Terminal('EXCEPT'), Terminal('('),
+  OneOrMore(NonTerminal('name'), Terminal(',')), Terminal(')'))
+```
+
+```railroad replace
+Diagram(
+  Terminal('REPLACE'), Terminal('('),
+  OneOrMore(
+    Sequence(NonTerminal('column'), Terminal('AS'), NonTerminal('target')),
+    Terminal(',')),
+  Terminal(')'))
+```
+
+A star works as follows:
+
+1. `*` is the columns found by bare name. After `INTERVAL INTERSECTION OF`,
+   that leaves out each source's own `ts` and `dur`. `<alias>.*` is the
+   columns the alias had when it was set.
+2. `EXCEPT` removes every column with a listed name. Each name must match at
+   least one column and be listed once, and at least one column must remain.
+3. `REPLACE (<column> AS <target>)` puts `<column>`'s values in `<target>`,
+   keeping `<target>`'s name and position. `<column>` is looked up in the row
+   before the stage; `<target>` must be one column left after `EXCEPT`.
+4. Every column a star adds can be referred to by bare name in later stages.
+
+### `EXTEND` {#extend}
+
+Adds columns at the end of the row, keeping every column and alias:
+
+```railroad
+Diagram(Terminal('EXTEND'), OneOrMore(NonTerminal('item'), Terminal(',')))
+```
+
+- Items are as in `SELECT`, except that a bare `*` is not allowed. Use
+  `<alias>.*` to add an alias's columns.
+- Items read the row before the stage, so one cannot refer to another.
+- Aliases do not include the new columns.
+
+### `DROP` {#drop}
+
+Removes columns by name:
+
+```railroad
+Diagram(Terminal('DROP'), OneOrMore(NonTerminal('name'), Terminal(',')))
+```
+
+- Each name must match a column found by bare name, and removes every column
+  of that name.
+- Each name is listed once, and at least one column must remain.
+- Aliases keep the dropped columns. An alias with the same name as a dropped
+  column is removed.
+
+### `RENAME` {#rename}
+
+Renames columns in place:
+
+```railroad
+Diagram(
+  Terminal('RENAME'),
+  OneOrMore(
+    Sequence(NonTerminal('old'), Terminal('AS'), NonTerminal('new')),
+    Terminal(',')))
+```
+
+- Each `<old>` must be one column found by bare name, listed once.
+- All renames happen together, so `|> RENAME x AS y, y AS x` swaps `x` and
+  `y`.
+- Renaming to an existing name is allowed; the name is then ambiguous.
+- Aliases keep the old name.
+
+### `SET` {#set}
+
+Replaces the values of columns in place:
+
+```railroad
+Diagram(
+  Terminal('SET'),
+  OneOrMore(
+    Sequence(NonTerminal('target'), Terminal('='), NonTerminal('column')),
+    Terminal(',')))
+```
+
+- Each `<target>` must be one column found by bare name, listed once.
+- Each `<column>` is looked up in the row before the stage. So `|> SET x = y, y = x` swaps the values of `x` and `y`. Other
+  expressions fail with `a computed column is not supported yet`.
+- Aliases keep the old values. An alias with the same name as a target is
+  removed.
+
+### `AS` {#as}
+
+Replaces all aliases with one alias for the current row:
+
+```railroad
+Diagram(Terminal('AS'), NonTerminal('alias'))
+```
+
+After `|> AS u`, earlier aliases are gone, and `u.<col>` and `u.*` are the
+columns found by bare name at this point. After `INTERVAL INTERSECTION OF`,
+`u.ts` is the region's `ts`, and the sources' own `ts` and `dur` can no longer
+be reached.
 
 ---
 
-### `SELECT`
+## Names
 
-Replaces the current row with the specified items and clears all table aliases:
-
-```sql
-|> SELECT <select_item> [, <select_item> ...]
-```
-
-Each `<select_item>` is one of:
-
-- **Column reference:** `[<qualifier>.]<col> [[AS] <alias>]`
-- **Star expansion:**
-  `[<qualifier>.]* [EXCEPT (<col_1> [, <col_2> ...])] [REPLACE (<replace_item> [, ...])]`
-  where each `<replace_item>` is `[<qualifier>.]<source_col> AS <target_col>`.
-  `AS` is required in `REPLACE`.
-
-Star expansion rules:
-
-1. `*` starts with all columns in the current row, including qualified-only
-   operand columns after `INTERVAL INTERSECTION OF`. `<qualifier>.*` starts with
-   the columns captured when `<qualifier>` was bound.
-2. `EXCEPT (<col>, ...)` removes every column matching any listed bare name
-   case-insensitively. Every listed name must match at least one column, no name
-   may be listed twice, and at least one column must remain after `EXCEPT`.
-3. `REPLACE (<source_col> AS <target_col>, ...)` resolves `<source_col>` against
-   the input row or aliases before the stage and replaces the value of
-   `<target_col>` in the star's expansion while keeping `<target_col>`'s
-   position and name. `<target_col>` must match a single column remaining in the
-   star after `EXCEPT`.
-4. All columns produced by `*` or `<qualifier>.*` can be referenced without a
-   qualifier in subsequent stages.
-
----
-
-### `EXTEND`
-
-Appends columns to the end of the current row while keeping all existing columns
-and aliases:
-
-```sql
-|> EXTEND <extend_item> [, <extend_item> ...]
-```
-
-- Accepts the same items as `SELECT`, except that a bare `*` is not allowed. Use
-  `<qualifier>.*` to append all columns of a table alias.
-- All items in `EXTEND` resolve against the row before the stage, so an item
-  cannot reference another column added in the same `EXTEND` stage.
-- Columns added by `EXTEND` are not added to any existing table aliases.
-
----
-
-### `DROP`
-
-Removes columns from the current row by bare name:
-
-```sql
-|> DROP <col_1> [, <col_2> ...]
-```
-
-- Every listed name must match at least one unqualified-accessible column in the
-  current row, and removes all columns of that name from the bare row.
-- No name may be listed twice, and at least one column must remain in the row
-  after `DROP`.
-- Existing table aliases keep the dropped columns, except that any table alias
-  whose name matches a dropped column name is removed.
-
----
-
-### `RENAME`
-
-Renames columns in the current row in place:
-
-```sql
-|> RENAME <old_1> [AS] <new_1> [, <old_2> [AS] <new_2> ...]
-```
-
-- `<old_i>` must be a bare column name that resolves unambiguously in the
-  current row, and may not be listed twice in the same `RENAME`.
-- All renames in a single stage take effect at the same time, so
-  `|> RENAME x AS y, y AS x` swaps `x` and `y`.
-- Renaming a column to an existing column's name is allowed. This creates
-  duplicate column names in the row, which only error if a later stage
-  references the ambiguous name.
-- Existing table aliases are unaffected and continue to expose the column under
-  its old name.
-
----
-
-### `SET`
-
-Replaces the values of existing columns in the current row in place:
-
-```sql
-|> SET <target_1> = [<qualifier>.]<source_1> [, <target_2> = [<qualifier>.]<source_2> ...]
-```
-
-- `<target_i>` must be a bare column name that resolves unambiguously in the
-  current row, and may not be listed twice in the same `SET`.
-- Every `<source_i>` is resolved against the row and aliases before the stage,
-  so `|> SET x = y, y = x` swaps the values of `x` and `y`.
-- Existing table aliases keep the pre-`SET` values, except that any table alias
-  whose name matches `<target_i>` is removed.
-
----
-
-### `AS`
-
-Replaces all existing table aliases with a single new alias bound to a snapshot
-of the current row:
-
-```sql
-|> AS <alias>
-```
-
-After `|> AS u`, earlier table aliases are no longer in scope, and `u.<col>` and
-`u.*` reflect the row as of the `AS` stage.
-
----
-
-## Name Resolution and Ambiguity Rules
-
-- **Case insensitivity:** Column names and table aliases are matched
-  case-insensitively using ASCII folding, while keeping the casing of the
-  defining column or alias in output schemas.
-- **Duplicate column names:** A stage is allowed to create duplicate column
-  names in the row, such as `|> EXTEND x` or `|> RENAME x AS y` when `y` already
-  exists. Duplicate names only cause an error if a later stage references the
-  ambiguous name without a table qualifier. You can also drop or exclude all
-  copies at once via `DROP y` or `* EXCEPT (y)`.
-- **Quoted identifiers:** Identifiers may be quoted with `"..."`, `` `...` ``,
-  or `[...]`. Inside `"..."` and `` `...` ``, doubling the quote character
-  escapes a literal quote, and `""` spells the empty column name.
+- **Case:** Column names and aliases match regardless of ASCII case. Output
+  keeps the case they were defined with.
+- **Duplicates:** A stage can leave two columns with one name, as
+  `|> RENAME x AS y` does when `y` exists. This is only an error when a later
+  stage refers to that name without a qualifier. `DROP y` or `* EXCEPT (y)`
+  removes every copy.
+- **Quoting:** Names can be quoted with `"..."`, `` `...` `` or `[...]`. Inside
+  `"..."` and `` `...` ``, a doubled quote is a literal quote.
diff --git a/docs/contributing/ui-getting-started.md b/docs/contributing/ui-getting-started.md
index 3abaa5c..c765992 100644
--- a/docs/contributing/ui-getting-started.md
+++ b/docs/contributing/ui-getting-started.md
@@ -118,9 +118,9 @@
 
 Local state of components can reside in class members and accessed directly in
 methods via accessing `this`. State that needs to be persisted (e.g. into
-permalinks) is kept in a `Store` mounted via `trace.mountStore()`, see
+permalinks) is registered via `trace.registerStorage()`, see
 [UI plugins](ui-plugins#state).
 
-There are restrictions on what can be used in a store: plain JS objects
+There are restrictions on what can be persisted: plain JS objects
 are OK, but class instances are not (this limitation is due to state
 serialization: the state should be a valid JSON object).
diff --git a/docs/contributing/ui-plugins.md b/docs/contributing/ui-plugins.md
index b5b20fd..73ff12a 100644
--- a/docs/contributing/ui-plugins.md
+++ b/docs/contributing/ui-plugins.md
@@ -1528,121 +1528,75 @@
 Plugins can persist information into permalinks. This allows plugins to
 gracefully handle permalinking and is an opt-in - not automatic - mechanism.
 
-Persistent plugin state works using a `Store<T>` where `T` is some JSON
-serializable object. `Store` is implemented
-[here](https://github.com/google/perfetto/blob/main/ui/src/base/store.ts).
-`Store` allows for reading and writing `T`. Reading:
+Persistent plugin state is registered with `registerStorage()` on your `Trace`
+object. You provide a unique id, a [Zod](https://zod.dev) schema describing
+the shape of the state, and a default value. The schema's output type must be
+JSON serializable.
 
 ```typescript
-interface Foo {
-  bar: string;
-}
+import {z} from 'zod';
 
-const store: Store<Foo> = getFooStoreSomehow();
-
-// store.state is immutable and must not be edited.
-const foo = store.state.foo;
-const bar = foo.bar;
-
-console.log(bar);
-```
-
-Writing:
-
-```typescript
-interface Foo {
-  bar: string;
-}
-
-const store: Store<Foo> = getFooStoreSomehow();
-
-store.edit((draft) => {
-  draft.foo.bar = 'Hello, world!';
+const MY_STATE_SCHEMA = z.object({
+  version: z.literal(1),
+  favouriteSlices: z.array(z.number()),
 });
 
-console.log(store.state.foo.bar);
-// > Hello, world!
-```
+type MyState = z.infer<typeof MY_STATE_SCHEMA>;
 
-First define an interface for your specific plugin state.
-
-```typescript
-interface MyState {
-  favouriteSlices: MySliceInfo[];
-}
-```
-
-To access permalink state, call `mountStore()` on your `Trace` object, passing
-in a store id and a migration function.
-
-```typescript
 export default class implements PerfettoPlugin {
   static readonly id = 'com.example.MyPlugin';
   async onTraceLoad(trace: Trace): Promise<void> {
-    const store = trace.mountStore('com.example.MyPlugin', migrate);
+    const storage = trace.registerStorage({
+      id: 'com.example.MyPlugin',
+      schema: MY_STATE_SCHEMA,
+      defaultValue: {version: 1, favouriteSlices: []},
+    });
   }
 }
-
-function migrate(initialState: unknown): MyState {
-  // ...
-}
 ```
 
-When it comes to migration, there are two cases to consider:
-
-- Loading a new trace
-- Loading from a permalink
-
-In case of a new trace, your migration function is called with `undefined`. In
-this case you should return a default version of `MyState`:
+The returned `Storage<MyState>` allows reading and writing the state:
 
 ```typescript
-const DEFAULT = {favouriteSlices: []};
+// The returned value is deeply frozen and must not be edited.
+const slices = storage.get().favouriteSlices;
 
-function migrate(initialState: unknown): MyState {
-  if (initialState === undefined) {
-    // Return default version of MyState.
-    return DEFAULT;
-  } else {
-    // Migrate old version here.
-  }
-}
+// To update the state, set a new value.
+const current = storage.get();
+storage.set({...current, favouriteSlices: [...current.favouriteSlices, 42]});
 ```
 
-In the permalink case, your migration function is called with the state of the
-plugin store at the time the permalink was generated. This may be from an older
-or newer version of the plugin.
+`get()` validates the stored value against the schema:
 
-**Plugins must not make assumptions about the contents of `initialState`!**
+- Loading a new trace: there is no stored value, so `defaultValue` is returned.
+- Loading from a permalink: the value stored at the time the permalink was
+  generated is validated against the schema. This may come from an older or
+  newer version of the plugin. If it is valid, the parsed value is returned,
+  otherwise `defaultValue` is returned.
 
-In this case you need to carefully validate the state object. This could be
-achieved in several ways, none of which are particularly straight forward. State
-migration is difficult!
+**Plugins must not make assumptions about the contents of a permalink!** The
+schema is the only thing standing between your plugin and arbitrary JSON, so
+keep it strict.
 
-One brute force way would be to use a version number.
+Including a version number (e.g. `version: z.literal(1)`) makes it easy to
+reject state from incompatible versions of the plugin: anything that doesn't
+match falls back to `defaultValue`.
+
+If you would rather recover from partially invalid state than discard all of
+it, add `.catch()` to individual fields. Only the invalid fields are then
+replaced:
 
 ```typescript
-interface MyState {
-  version: number;
-  favouriteSlices: MySliceInfo[];
-}
-
-const VERSION = 3;
-const DEFAULT = {favouriteSlices: []};
-
-function migrate(initialState: unknown): MyState {
-  if (initialState && (initialState as {version: any}).version === VERSION) {
-    // Version number checks out, assume the structure is correct.
-    return initialState as State;
-  } else {
-    // Null, undefined, or bad version number - return default value.
-    return DEFAULT;
-  }
-}
+const MY_STATE_SCHEMA = z.object({
+  version: z.literal(1),
+  favouriteSlices: z.array(z.number()).catch([]),
+});
 ```
 
-You'll need to remember to update your version number when making changes!
-Migration should be unit-tested to ensure compatibility.
+Permalinks live forever, so be careful when changing the schema. Changes that
+make previously stored state invalid will silently reset the state of anyone
+opening an older permalink. Schemas should be unit-tested against examples of
+previously stored state to ensure compatibility.
 
 Examples:
 
diff --git a/docs/design-docs/perfetto-sql-pipelines.md b/docs/design-docs/perfetto-sql-pipelines.md
index 358414c..cc6f3f8 100644
--- a/docs/design-docs/perfetto-sql-pipelines.md
+++ b/docs/design-docs/perfetto-sql-pipelines.md
@@ -1,8 +1,7 @@
 # PerfettoSQL Pipe Operator Implementation Notes
 
-This page describes how each PerfettoSQL pipeline source and operator is
-implemented, what data structures and fast paths it uses, and what its memory
-and streaming characteristics are.
+This page describes how pipelines are compiled and run, and how each stage is
+implemented.
 
 > **Warning:** Pipe syntax and its implementation are **experimental and
 > unstable**. Do **not** rely on anything described here. Both the syntax and
@@ -16,310 +15,390 @@
 
 ---
 
-## Overview: Batches and Pruning
+## From Query to Rows
 
-Pipelines execute over columnar batches of up to 8192 rows. Each column in a
-batch is a view over a contiguous array, an optional validity bitvector for
-nulls, and an optional row-selection index buffer for filtering or reordering
-rows without copying values.
+Code: `/src/trace_processor/perfetto_sql/pipeline/`
 
-Before any operator runs, a backward liveness pass walks from the pipeline's
-final output columns back to the sources:
+1. **Compile.** `Compiler` turns the parsed pipeline into a `LogicalPlan`: a
+   tree of `PlanNode`s, one per source or stage, each holding a
+   `PlanOperation`. Names are resolved and types checked here, so errors point
+   at the token at fault.
+2. **Prune.** `PruneColumns` drops what nothing reads (see
+   [Column pruning](#column-pruning)).
+3. **Serialize.** `SelectPipelineSql` writes the plan to bytes and wraps it in
+   a SQL statement calling the `__intrinsic_pipeline` table function. Each SQL
+   source becomes an argument built by `__intrinsic_dataframe_agg` (see
+   [`FROM`](#from)).
+4. **Lower.** When SQLite runs that statement, the plan is read back
+   (`DeserializePlan`), the SQL sources are bound as dataframes
+   (`BindDataframeArgs`), and `Lower` turns it into a `PhysicalPlan` of
+   executor operators. A table read directly is checked to be the one the plan
+   was compiled against.
+5. **Run.** A `RowCursor` pulls batches through the operators and SQLite reads
+   them row by row.
 
-- Unused columns are dropped from table and subquery scans.
-- Unused columns carried through `INTERVAL INTERSECTION OF` are dropped before
-  the operands are read into memory.
-- Unused `SUM(...)` aggregates in `TREE ACCUMULATE` are dropped. If none of a
-  `TREE ACCUMULATE` stage's output columns are read downstream, the entire stage
-  is removed from the plan, skipping node numbering, tree ordering, and
-  accumulation.
+Each `PlanOperation` lowers itself through `Lowering`. Operators state what
+they need, such as a column of a given type (`RequireType`), rows grouped by
+some keys and sorted by `ts` (`RequireIntervalLanes`), or a tree order
+(`RequireTreeWalk`). `Lowering` adds a conversion, sort or grouping only when
+the rows are not already that way. Operators also declare what they produce,
+such as sorted columns, so later stages can skip work.
+
+An operator with more than one input, such as `INTERVAL INTERSECTION OF`, reads
+each extra input through a side pipeline (`AddSidePipeline`) lowered the same
+way.
+
+### Batches
+
+Operators pass columnar batches (`RowBatch`) of up to 2048 rows. Each column is
+a view over a flat array, with an optional bitvector for `NULL`s. A batch has
+one `Selection`: increasing row indices saying which rows are live. It can only
+drop rows, so filtering copies nothing. Reordering rows, as sorting does,
+copies them into new buffers (`RowStore::Gather`).
+
+### Column pruning
+
+Before lowering, `PruneColumns` walks from the pipeline's output back to its
+sources and marks the columns that are read:
+
+- Sources only read live columns. A scan always reads at least one column, so
+  it still knows how many rows there are.
+- `INTERVAL INTERSECTION OF` only keeps the operand columns that are read.
+- Aggregates nobody reads are dropped from `TREE ACCUMULATE`, `INTERVAL
+  FLATTEN` and `AGGREGATE`. If no `TREE ACCUMULATE` output is read, the whole
+  stage goes.
+- `INTERVAL FILL GAPS` drops outputs nobody reads.
+- `WHERE`, `ORDER BY` and `DISTINCT` keep the columns they compare, and
+  `AGGREGATE` keeps its keys.
 
 ---
 
-## `FROM`
+## `FROM` {#from}
 
-How a `FROM` source is read depends on what it names.
+Code: `operations/scan.cc`, `/src/trace_processor/core/exec/dataframe_scan.cc`
 
-### Finalized `PERFETTO TABLE`s and built-in tables
+Every source is read as a dataframe by `DataframeScan`.
 
-When `FROM` names an unqualified table backed by a finalized Trace Processor
-dataframe, such as `slice`, `sched`, or any table created with
-`CREATE PERFETTO TABLE`, the pipeline reads the dataframe's columnar storage
-directly in C++ without opening a SQLite cursor:
+### Tables
 
-- Only the columns needed by downstream stages are read.
-- String and integer buffers are referenced directly in each batch rather than
-  copied per row.
-- If a table has an `id` column stored as an implicit `0, 1, 2, ...` row-index
-  sequence, downstream operators like `TREE ACCUMULATE` detect this storage type
-  and skip hash-table lookups.
+When `FROM` names a finalized dataframe, such as `slice`, `sched` or any
+`PERFETTO TABLE`, the pipeline reads its storage directly:
 
-### Views and `SELECT` subqueries
+- Only live columns are read, and hidden columns are skipped.
+- Column buffers are referenced, not copied.
+- Sorted columns are declared as such, so an `ORDER BY` on them is free.
+- An `id` column stored as `0, 1, 2, ...` lets `TREE ACCUMULATE` skip its hash
+  table.
 
-When `FROM` names a view, a virtual table, or a parenthesized `SELECT` subquery,
-Trace Processor prepares and steps the SQL query in SQLite and copies the
-returned values into columnar batches.
+### Views and subqueries
 
-If column pruning finds that some columns of the SQL source are never read
-downstream, the source query is wrapped before preparing it in SQLite:
+A view, virtual table or `SELECT` subquery has its column names and types
+worked out by `RelationAnalyzer` when the pipeline compiles. If it only picks
+and renames columns of a finalized table, the table is read directly as above.
+
+Otherwise SQLite runs it once, and `__intrinsic_dataframe_agg` collects the
+rows into a dataframe which is passed to the pipeline:
 
 ```sql
-WITH __pipeline_source(c0, c1, c2, ...) AS (SELECT * FROM <source>)
-SELECT c0 AS "<col_0>", c2 AS "<col_2>" FROM __pipeline_source
+SELECT __intrinsic_dataframe_agg('<col_0>,<col_2>', "<col_0>", "<col_2>")
+FROM <source>
 ```
 
-Projecting only the needed positional columns lets SQLite's query planner drop
-unused expressions or joins when it flattens the subquery, and avoids copying
-unused columns out of SQLite.
+Only live columns are listed, so SQLite can skip computing the rest.
 
 ---
 
 ## `INTERVAL INTERSECTION OF`
 
-Implementation: `/src/trace_processor/core/exec/interval_intersect.cc`
+Code: `/src/trace_processor/core/exec/interval_intersect.cc`
 
-`INTERVAL INTERSECTION OF` is a blocking source: it reads all of its operands in
-full before emitting the first output batch.
+`INTERVAL INTERSECTION OF` reads all its operands before it outputs anything.
 
-### 1. Reading and partitioning operands
+### 1. Reading operands
 
-Each operand is executed as an independent sub-pipeline and read into memory:
+Each operand is a side pipeline:
 
-- `ts`, `dur`, and all `PER` columns must be 64-bit integers. Rows where `ts` or
-  `dur` is `NULL` are skipped. Rows where `ts < 0` or `dur < 0` stop execution
-  with an error.
-- Only the operand columns that are referenced downstream are buffered in the
-  operand's `RowStore`. Unreferenced columns are discarded as batches arrive.
-- Each valid row's `[ts, ts + dur)` interval and row index are inserted into a
-  per-operand hash map keyed by the `PER` columns. Each `PER` column contributes
-  1 presence byte and 8 value bytes to the partition key, so two rows with
-  `NULL` in a `PER` column land in the same partition.
-- Once an operand finishes reading, the intervals in each partition are sorted
-  by start, end, and row index, then scanned once to record whether any two
-  intervals in that partition overlap.
+- `ts` and `dur` are converted to 64-bit integers. `PER` columns are converted
+  to one type across operands; strings are allowed.
+- Rows are grouped by the `PER` columns and sorted by `ts` within each group,
+  if they are not already.
+- Rows with a `NULL` `ts` or `dur` are skipped. A negative bound, or a
+  `ts + dur` that overflows, is an error.
+- Only operand columns read downstream are kept.
 
-### 2. Intersecting within each partition
+All operands number their `PER` keys in one shared `GroupTable`, so a key has
+the same number everywhere. A key that no earlier operand has can produce no
+region, so its rows are dropped as they are read. While a lane is read, the
+operator notes whether any two of its intervals overlap.
 
-A partition can only produce output if its `PER` key exists in every operand.
-The operator iterates over the keys of whichever operand has the fewest distinct
-`PER` keys, and skips any key missing from another operand.
+### 2. Intersecting each key
 
-For each key present in all operands, it chooses between two paths:
+Only keys of the operand with the fewest keys can start a region, so the
+operator walks those and skips any key another operand lacks. For each key:
 
-- **All-disjoint fast path:** If every operand's intervals in that partition are
-  non-overlapping, it runs a single multi-way linear sweep across all operands
-  at once, emitting regions directly to the output buffer with no intermediate
-  region allocations.
-- **Pairwise narrowing path:** If at least one operand has overlapping intervals
-  in that partition, the operands for that key are sorted in ascending order of
-  interval count. The smallest operand seeds the running set of candidate
-  regions. Each remaining operand narrows the running set one at a time using
-  `IntervalIntersector`, which picks between a linear sweep, binary search, or
-  an interval tree based on whether that operand has overlaps and how many
-  candidate regions are currently active.
+- **No overlaps:** If no operand's intervals overlap each other, one sweep
+  moves through all operands at once and writes regions straight to the
+  output.
+- **Overlaps:** Otherwise the operands narrow the regions one at a time,
+  smallest first. Each step uses `IntervalIntersector`, which picks a linear
+  sweep, binary search or interval tree depending on the operand and how many
+  regions are left.
 
-Candidate and output regions are stored as two flat arrays of bounds and one
-flat array of operand row indices, avoiding per-region heap allocations.
+Regions are stored as flat arrays of bounds and operand rows, so no region
+needs its own allocation.
 
-### 3. Serving output batches
+### 3. Output
 
-Once all partitions are intersected, output is served in batches of up to 8192
-regions. Each batch writes the region `ts` and `dur` into two flat `Int64`
-columns and attaches row-selection views into each operand's buffered `RowStore`
-for the retained columns.
+Regions are output in batches of up to 2048. Each batch holds the region's `ts`
+and `dur`, then the kept columns of each operand, copied from the rows the
+region came from.
+
+### Names
+
+The compiler puts the region's `ts` and `dur` first in the row, then every
+operand column. Each operand column is marked `qualified_only` when only its
+alias should find it: the operand's own `ts` and `dur`, and the `PER` columns of
+operands after the first. Everything else is found by its bare name too.
 
 ---
 
 ## `INTERVAL FLATTEN`
 
-Implementation: `/src/trace_processor/core/exec/interval_flatten.cc`
+Code: `/src/trace_processor/core/exec/interval_flatten.cc`
 
-The planner prepares input grouped by the `PER` keys and ordered by `ts`
-within each group, adding sorting and grouping only when the existing order
-cannot be reused. These preparation steps can buffer the input; the flattening
-step itself processes ordered batches incrementally.
+Input is grouped by the `PER` keys and sorted by `ts` within each group,
+through `RequireIntervalLanes`, which adds a sort only if needed.
+`IntervalFlatten` then streams through the sorted rows.
 
-`IntervalFlatten` sweeps one group at a time. A min-heap tracks active interval
-endpoints. Running counts and sums are updated when intervals start or expire,
-so producing a segment does not require scanning every active interval. Each
-active interval retains its contributions so they can be subtracted at its
-endpoint. Sums also track the number of non-NULL contributions, allowing an
-all-NULL sum to remain NULL.
+A min-heap tracks when active intervals end. Each interval keeps its row's
+aggregate states in a slot, and a batch of segments is aggregated together from
+the slots live in each, so a segment does not rescan every active interval.
+While no input has been `NULL`, aggregates that can remove a value, as counts
+and sums can, add each slot at its interval's first segment, remove it at its
+end and keep running totals. Otherwise, as for `MIN` and `MAX`, each slot is
+merged into a tree over the batch's segments. A sum notes whether it added any
+value, so a sum of only `NULL`s stays `NULL`.
 
-Points at a timestamp are accumulated separately and emitted together once all
-rows starting at that timestamp have been consumed. Their totals include
-positive-duration intervals active at that instant, but are not carried into
-the next positive-duration segment.
+Points at one instant are collected and output together once every row
+starting there has been read. Their totals include intervals active at that
+instant but do not carry into the next segment.
 
-Completed segments are emitted in bounded batches. The sweep retains active
-interval state and the grouping keys needed for output, rather than buffering
-all completed segments. Finalization drains intervals still active when the
-input ends. Endpoint and sum arithmetic is checked for integer overflow.
+Segments are output in bounded batches; only active intervals are held.
+Endpoint and sum arithmetic is checked for overflow.
 
-Unused aggregates are pruned, but the stage remains even if no aggregates are
-needed: flattening still changes the rows and their interval boundaries.
+Unused aggregates are pruned, but the stage stays even with none left, since it
+still decides the rows.
+
+---
+
+## `INTERVAL FILL GAPS`
+
+Code: `/src/trace_processor/core/exec/interval_fill_gaps.cc`
+
+The background is a side pipeline, read whole before the input. Both are
+grouped by the `PER` keys and sorted by `ts` through `RequireIntervalLanes`,
+and columns shared by the two are converted to one type.
+
+`IntervalFillGaps` streams through the input, outputs every row unchanged, and
+adds a filler for each part of the background that no input row in the same
+lane covers. It runs in one of two ways:
+
+- **The background has the `PER` columns, or there are none.** Each background
+  row belongs to one lane. A lane with no input is filled whole.
+- **The background has no `PER` columns but the input does.** Every input lane
+  is filled against the whole background.
+
+A filler takes each column from the background column of the same name, else
+the lane's `PER` value, else `NULL`. An input `dur` of `-1` lasts forever.
+Fillers never have zero duration, and output rows are in no particular order.
 
 ---
 
 ## `TREE ACCUMULATE`
 
-Implementation:
+Code:
 - `/src/trace_processor/core/exec/tree_number_nodes.cc`
 - `/src/trace_processor/core/exec/tree_order.cc`
 - `/src/trace_processor/core/exec/tree_accumulate.cc`
 
-A `TREE ACCUMULATE` stage lowers into three steps: node numbering, tree
-ordering, and accumulation.
+A `TREE ACCUMULATE` stage lowers to three steps: numbering nodes, ordering
+rows, and accumulating.
 
-### 1. Node numbering: `TreeNumberNodes`
+### 1. Numbering nodes: `TreeNumberNodes`
 
-Tree operators need per-node state: visited bitvectors, waiting lists, and
-running sums. Raw `id` values from a filtered query can be arbitrary 64-bit
-integers or strings scattered across a wide range, so indexing an array directly
-by `id` would either fail or allocate memory proportional to the largest `id` in
-the original table.
+The tree operators keep state per node. An `id` can be any 64-bit integer or a
+string, so arrays indexed by it could be huge or impossible.
 
-`TreeNumberNodes` solves this by appending two dense `Uint32` columns to each
-batch: the row's node number, assigned `0, 1, 2, ...` in order of first
-sighting, and its parent's node number, using `kNoNode` for roots where
-`parent_id IS NULL`. Downstream tree operators only inspect these two dense
-`Uint32` columns, so all per-node arrays are sized to the number of rows in the
-input.
+`TreeNumberNodes` adds two dense `Uint32` columns to each batch: the row's node
+number, given out `0, 1, 2, ...` in order of first sighting, and its parent's,
+or `kNoNode` for a root. Later operators only read these, so per-node arrays
+are as long as the input.
 
-`TreeNumberNodes` has three tiers of execution:
+It has three paths:
 
-1. **Dataframe `Id` fast path:** When scanning an unfiltered dataframe whose
-   `id` column has storage type `Id`, whose `parent_id` column is `Uint32`, and
-   where every row's parent appears at an earlier row, node numbers are assigned
-   in place by copying `parent_id` and filling `0, 1, 2, ...` with no hash map
-   and no per-cell type dispatch.
-2. **Dense integer fast path:** When `id` or `parent_id` arrives as a general
-   integer column from a SQLite subquery, the operator tracks whether the IDs
-   seen so far are still `0, 1, 2, ...` with parents referencing already-seen
-   IDs. As long as that holds, each `id` is already its own node number and the
-   hash map stays empty.
-3. **Hash map path:** On the first non-dense integer or string `id`, the
-   operator backfills its `FlatHashMap` with any previously seen dense IDs and
-   maps all subsequent `id` and `parent_id` values through the hash map.
+1. **`Id` columns:** When reading an unfiltered dataframe whose `id` is stored
+   as `Id`, whose `parent_id` is `Uint32`, and where every parent comes before
+   its children, the numbers are copied straight from the columns.
+2. **Dense integers:** While the `id`s seen are `0, 1, 2, ...` and every parent
+   has been seen, each `id` is its own number and nothing is hashed.
+3. **Hash map:** From the first `id` that breaks this, or any string `id`, a
+   `FlatHashMap` maps ids to numbers. Ids seen before are added to it first.
 
-### 2. Tree ordering: `TreeChildFirst` and `TreeParentFirst`
+### 2. Ordering rows: `TreeChildFirst` and `TreeParentFirst`
 
-Accumulating up or down a tree requires rows to be ordered so that the values a
-node depends on have already been computed when the node is visited. Neither
-direction requires strict depth-first traversal order. Subtrees may be
-interleaved because the accumulator stores a running total per node rather than
-a single root-to-leaf stack.
+Rows must arrive so that what a node depends on is done before it. This needs
+no strict depth-first order: subtrees can interleave, since the accumulator
+keeps a total per node.
 
 #### `UP`: `TreeChildFirst`
 
-`TREE ACCUMULATE UP` requires every child to appear before its parent. Because a
-streaming operator cannot know whether an arriving node has children until the
-end of the input, `TreeChildFirst` is a blocking operator that reads all input
-rows before emitting:
+`UP` needs every child before its parent. A row's children may come at the very
+end, so `TreeChildFirst` reads all rows before it outputs any:
 
-- As rows arrive, it tracks two flags: whether the input is already child-first,
-  meaning no row's parent has been seen before the row itself, and whether it is
-  parent-first, meaning every non-root row's parent has already been seen.
-- **Already child-first:** Emits the buffered batches in arrival order without
-  building an index permutation.
-- **Already parent-first:** Emits the buffered rows in reverse arrival order,
-  since reversing any parent-first ordering yields a valid child-first ordering.
-- **Unordered:** Builds a flat compressed-sparse-row child list over the node
-  numbers, traverses from the roots with an explicit stack to produce a
-  parent-first order, verifies that all rows were reached to catch cycles, and
-  reverses the result.
+- It notes whether the input is already child first, or already parent first.
+- **Child first:** outputs the rows as they came.
+- **Parent first:** outputs them in reverse.
+- **Neither:** builds a child list over the node numbers, walks it from the
+  roots to get a parent-first order, checks that every row was reached, which
+  catches cycles, and reverses it.
 
 #### `DOWN`: `TreeParentFirst`
 
-`TREE ACCUMULATE DOWN` requires every parent to appear before its children.
-Unlike `UP`, this is not a full pipeline breaker: a row can be emitted as soon
-as its parent has been emitted.
+`DOWN` needs every parent before its children. A row can go as soon as its
+parent has, so `TreeParentFirst` streams:
 
-- `TreeParentFirst` keeps a bitvector of nodes that have already been emitted.
-- When a batch arrives, any root row or row whose parent is already marked as
-  emitted passes straight through. If every row in the batch passes, the batch
-  is forwarded as-is without copying any columns.
-- Only rows that arrive before their parent are copied into a side buffer and
-  linked into a per-parent waiting list. The moment that parent row arrives and
-  is emitted, its waiting children and any of their waiting descendants are
-  released and emitted after the batch.
-- Memory and copying cost are proportional to how many rows arrive before their
-  parents. When the input is already parent-first, nothing is buffered or
-  copied.
+- A bitvector marks the nodes already output.
+- A root, or a row whose parent is out, passes straight through. A batch where
+  every row passes is forwarded without copying.
+- A row that arrives before its parent is copied aside onto its parent's
+  waiting list. When the parent is output, its waiting children and their
+  waiting descendants follow.
+- Only rows that arrive before their parents cost memory or copies.
 
-### 3. Accumulation: `TreeAccumulateUp` and `TreeAccumulateDown`
+### 3. Accumulating: `TreeAccumulateUp` and `TreeAccumulateDown`
 
-Each `SUM(col)` in the stage runs a streaming `TreeAccumulateUp` or
-`TreeAccumulateDown` operator over the ordered batches:
+One streaming operator computes every aggregate of the stage, using the
+executor's shared aggregate functions
+(`/src/trace_processor/core/exec/aggregate_function.h`), as `INTERVAL FLATTEN`
+and `AGGREGATE` do:
 
-- The summed column is verified or widened to flat `Int64`, with `NULL` values
-  contributing `0`. Checked 64-bit addition is used so integer overflow is
-  reported as an error rather than wrapping silently.
-- The operator keeps a single `std::vector<int64_t>` indexed by node number:
-  - **`TreeAccumulateUp`:** When a row for `node` arrives, every descendant has
-    already been processed and added its subtree sum into `by_node[node]`. The
-    operator sets `total = value + by_node[node]`, writes `total` to the output
-    batch, and adds `total` into `by_node[parent]`.
-  - **`TreeAccumulateDown`:** When a row for `node` arrives, its `parent` has
-    already been processed and stored its path sum in `by_node[parent]`. The
-    operator sets `total = value + by_node[parent]`, stores `by_node[node] =
-    total`, and writes `total` to the output batch.
+- Aggregated columns are converted to flat `Int64`. A sum skips `NULL`s and
+  notes whether it added anything, so a sum of nothing is `NULL`. Overflow is
+  an error.
+- Every node's aggregate states sit in one vector indexed by node number. For
+  each batch, every row is added into its node's state, then states are merged
+  along the batch's edges in row order:
+  - **Up:** Children come first, so when a node arrives its descendants are
+    already merged into it. It is then merged into its parent.
+  - **Down:** Parents come first, so when a node arrives its parent already
+    covers every ancestor. The parent is merged into it.
 
-### 4. Reuse across consecutive `TREE ACCUMULATE` stages
+### 4. Several `TREE ACCUMULATE` stages
 
-When a pipeline chains multiple `TREE ACCUMULATE` stages:
+- Later stages reuse the first stage's node numbers while `id` and `parent_id`
+  are the same columns.
+- Two `UP` stages in a row, or two `DOWN` stages, reuse the first stage's row
+  order.
+- Switching between `UP` and `DOWN` keeps the numbers and reorders the rows.
 
-- Consecutive `TREE ACCUMULATE` stages share the same `TreeNumberNodes` columns
-  as long as `id` and `parent_id` still refer to the same underlying columns.
-- Two consecutive `TREE ACCUMULATE UP` stages, or two consecutive `DOWN` stages,
-  reuse the tree ordering from the first stage and skip inserting a second
-  ordering operator.
-- Switching between `UP` and `DOWN` reuses the node numbering and re-orders the
-  rows for the new direction.
+---
+
+## `AGGREGATE`
+
+Code: `/src/trace_processor/core/exec/hash_aggregate.cc`
+
+`AGGREGATE` lowers to one `HashAggregate`, which reads all input before
+outputting. `GroupTable` hashes each row's keys to find its group, numbering
+groups in the order they are first seen. Integer keys of any width compare
+equal by value, strings by their interned id, and `NULL`s equal each other.
+Each group's aggregate states sit beside its keys, and every row is added as it
+is read, so memory grows with the number of groups, not rows. At the end,
+groups are output in the order they were first seen. If the input was sorted by
+the keys, the output is declared sorted too.
+
+Without `GROUP BY` there is one group, which is output even when there were no
+rows.
+
+Unused aggregates are pruned. The stage itself always stays, since it decides
+the rows.
+
+The compiler replaces the row with the keys and then the aggregates, and clears
+all aliases.
+
+---
+
+## `WHERE`
+
+Code: `operations/where.cc`, `/src/trace_processor/core/exec/filter.cc`
+
+`WHERE` lowers to one streaming `Filter`. Each comparison's literal is cast to
+its column's type once, during lowering, and stored with the plan
+(`PhysicalPlan::filter_values()`). A column with no known type is first
+converted to the literal's type. `Filter` compares with the same kernels as the
+dataframe's own filters and narrows each batch's selection, so nothing is
+copied.
+
+---
+
+## `DISTINCT`
+
+Code: `operations/distinct.cc`, `/src/trace_processor/core/exec/distinct.cc`
+
+`DISTINCT` lowers to one streaming `Distinct`. A `GroupTable` holds the keys of
+the rows kept so far; a row whose keys are already there is dropped by
+narrowing the selection. Memory grows with the number of distinct rows, and
+rows keep their order. A row can have at most 64 columns.
 
 ---
 
 ## `ORDER BY`
 
-Implementation: `/src/trace_processor/core/exec/sort.cc`
+Code: `/src/trace_processor/core/exec/sort.cc`
 
-`ORDER BY` is a blocking stage: `Sort` reads every row before emitting any. It
-encodes each row's keys into one fixed-width, byte-comparable record, sorts
-row indices by those records, and serves the buffered rows through a
-row-selection index rather than copying them into sorted order.
+`Sort` reads every row before outputting any. It encodes each row's keys into
+one fixed-width record that compares as bytes, sorts the row indices by those
+records, then copies the rows out in that order.
 
-The planner tracks the order rows are known to be in. A single ascending key
-which a dataframe scan already keeps sorted, such as `ts` on `slice`, needs no
-`Sort` at all. After a sort, the planner forgets any tree order, so a later
-`TREE ACCUMULATE` rearranges rows again while reusing its node numbering.
+Keys must be numbers: `Uint32`, `Int32`, `Int64` or `Double`. A string column
+is rejected when the pipeline compiles. A key from SQLite whose type is not
+known is converted to integers.
 
-Keys of a known type are sorted as they are. A key read from SQLite has no
-promised type, so it is first checked to hold integers.
+Lowering tracks the order rows are in. A single ascending key that a table
+already keeps sorted, such as `ts` on `slice`, needs no `Sort`. A `Sort` that
+nothing reads the order of, because a later stage sorts, groups or walks a tree
+first, is removed. After a sort, the tree order is forgotten, so a later
+`TREE ACCUMULATE` reorders the rows but keeps its node numbers.
 
 ---
 
-## `SELECT`, `EXTEND`, `DROP`, `RENAME`, `SET`, and `AS`
+## `SELECT`, `EXTEND`, `DROP`, `RENAME`, `SET` and `AS`
 
-Implementation: `/src/trace_processor/perfetto_sql/pipeline/compiler.cc`
+Code: `/src/trace_processor/perfetto_sql/pipeline/operations/projection.cc`
 
-The column-reshaping stages `SELECT`, `EXTEND`, `DROP`, `RENAME`, `SET`, and
-`AS` have no runtime operators and do no work during batch execution.
+These stages only exist while the pipeline compiles. They add no operators
+and copy no data.
 
-During compilation, the pipeline compiler maintains the current row as a vector
-of `(column_name, ColumnId, qualified_only)` entries, alongside a list of active
-table aliases. Each active alias holds a snapshot of that vector from when the
-alias was bound:
+The compiler keeps the current row as a list of `RowColumn`s: a name, the
+`ColumnId` holding its values, and whether it is `qualified_only`, meaning only
+an alias finds it. Next to it is a list of aliases, each a copy of the row from
+when it was set.
 
-- `DROP` removes entries from the compile-time row vector.
-- `RENAME` changes the `column_name` string on matching entries.
-- `SET` updates a target entry's `ColumnId` to point at the source column's
-  `ColumnId`.
-- `EXTEND` appends new `(column_name, ColumnId)` entries to the row vector.
-- `AS` replaces the active alias list with a copy of the current row vector.
-- `SELECT` replaces the row vector with the selected `(column_name, ColumnId)`
-  entries and clears the active alias list.
+- `DROP` removes the columns of that name a bare name finds, and any alias of
+  that name.
+- `RENAME` changes the name of a column.
+- `SET` points a column at another `ColumnId`, and removes any alias of that
+  name.
+- `EXTEND` adds columns at the end. A bare `*` is refused.
+- `AS` drops `qualified_only` columns from the row, and replaces every alias
+  with one for the row that is left.
+- `SELECT` replaces the row with the listed columns and clears every alias. A
+  bare `*` only takes columns that are not `qualified_only`. Every column it
+  lists, including those from `<alias>.*`, can then be found by bare name.
 
-At the end of compilation, only the `ColumnId`s present in the final row vector
-are marked live for column pruning and mapped to physical batch column indices
-when returning results to SQLite. Reordering, duplicating, renaming, or dropping
-columns in pipe stages never copies column data at runtime.
+`AGGREGATE`, `INTERVAL FLATTEN` and `INTERVAL FILL GAPS` also rebuild the row
+and aliases.
+
+When compiling ends, the columns of the row that are not `qualified_only`
+become the pipeline's output. Pruning starts from those, and lowering maps each
+to a column of the final batch. Reordering, duplicating, renaming or dropping
+columns never copies data.
diff --git a/docs/images/heap_docs/19-merged-class-classes.png b/docs/images/heap_docs/19-merged-class-classes.png
new file mode 100644
index 0000000..a71330e
--- /dev/null
+++ b/docs/images/heap_docs/19-merged-class-classes.png
Binary files differ
diff --git a/docs/learning-more/symbolization.md b/docs/learning-more/symbolization.md
index 806b094..3badaeb 100644
--- a/docs/learning-more/symbolization.md
+++ b/docs/learning-more/symbolization.md
@@ -209,6 +209,20 @@
 - You must manage `PERFETTO_BINARY_PATH` / `PERFETTO_PROGUARD_MAP` by hand; none
   of the auto-discovery from Option 1 applies.
 
+### Merged classes {#merged-classes}
+
+Optimizing and obfuscating an app (for example, with R8) can merge several
+classes into one. When the deobfuscation mapping records which classes were
+merged, Perfetto marks the resulting classes in heap dumps as potentially
+merged (`heap_graph_class.potentially_merged`) and shows a warning next to them
+in the UI; see
+[Heap Dump Explorer](/docs/visualization/heap-dump-explorer.md#merged-classes).
+
+If the mapping doesn't record merged classes, Perfetto can't tell which classes
+were merged, so it flags every renamed class instead. For example, R8 records
+merged classes in `com.android.tools.r8.mergedClasses` comments starting with
+mapping format 2.3; older R8 mapping files don't.
+
 ### Symbol lookup order
 
 For each native mapping in the trace, the symbolizer looks for a file with
diff --git a/docs/toc.md b/docs/toc.md
index 3c892b6..fee0af3 100644
--- a/docs/toc.md
+++ b/docs/toc.md
@@ -108,6 +108,7 @@
       - [UI Automation](visualization/ui-automation.md) {.tag-android .tag-linux .tag-cpp-rust .tag-perf}
       - [Commands Reference](visualization/commands-automation-reference.md) {.tag-android .tag-linux .tag-cpp-rust .tag-perf}
       - [Extension Servers](visualization/extension-servers.md) {.tag-android .tag-linux .tag-cpp-rust .tag-perf}
+      - [Googler Features](visualization/googler-features.md) {.tag-android .tag-linux .tag-cpp-rust .tag-perf}
 
   - [Trace Analysis](#)
 
diff --git a/docs/visualization/embedding-api-reference.md b/docs/visualization/embedding-api-reference.md
index d62b774..bdf512f 100644
--- a/docs/visualization/embedding-api-reference.md
+++ b/docs/visualization/embedding-api-reference.md
@@ -123,6 +123,7 @@
 | ----------------- | ------------------------------ | --------------------------------------------------------------------------------------------------------------------------------- |
 | `mode`            | `embedded`                     | Enables embedded mode: the sidebar is **disabled entirely** (not just hidden) and the file-drop handler is not installed. Use this when embedding. |
 | `hideSidebar`     | `true`                         | Hides the sidebar visually without fully disabling it.                                                                             |
+| `hideStatusbar`   | `true`                         | Hides the status bar at the bottom of the window.                                                                                  |
 | `url`             | `<https url>`                  | UI fetches a public trace itself (requires CORS allowing the UI origin). Alternative to `postMessage` for public traces.           |
 | `s`               | `<hash>`                       | Loads a permalink (saved state).                                                                                                   |
 | `visStart`        | `<ns>`                         | Initial viewport start, raw **nanosecond** timestamp (as in SQL tables). Pair with `visEnd`.                                       |
diff --git a/docs/visualization/extension-servers.md b/docs/visualization/extension-servers.md
index 38426c4..17059c5 100644
--- a/docs/visualization/extension-servers.md
+++ b/docs/visualization/extension-servers.md
@@ -340,6 +340,9 @@
   hasn't expired and has read access to the repository (Settings > Personal
   access tokens). For HTTPS servers with SSO, try logging into the server
   directly in a new tab to refresh your session, then reload the Perfetto UI.
+  For Googlers accessing the internal extension server, third-party cookies
+  must be enabled; see
+  [Googler Features & 3rd-Party Cookies](/docs/visualization/googler-features.md).
 - **404** — The endpoint doesn't exist. Check that the server implements the
   expected [endpoint paths](/docs/visualization/extension-server-protocol.md#endpoints)
   and that the repository/branch/path are correct.
diff --git a/docs/visualization/googler-features.md b/docs/visualization/googler-features.md
new file mode 100644
index 0000000..ffe6a04
--- /dev/null
+++ b/docs/visualization/googler-features.md
@@ -0,0 +1,84 @@
+# Googler Features & 3rd-Party Cookies
+
+When using the [Perfetto UI](https://ui.perfetto.dev), Googlers have access to
+internal features that extend the UI with Google-specific workflows, including:
+
+- **Internal macros** — Pre-configured command sequences and queries for
+  analyzing internal traces, available in the command palette (`Ctrl+Shift+P` /
+  `Cmd+Shift+P`).
+- **Internal SQL modules** — Shared PerfettoSQL modules packaged and served
+  internally, accessible via `INCLUDE PERFETTO MODULE`.
+- **Proto descriptors** — Automatic decoding of internal protobuf messages
+  embedded in traces.
+- **Trace sharing** — Internal trace uploading and sharing features integrated
+  directly into the UI.
+
+These features are provided by connecting to the internal Google extension
+server at `https://perfetto-gae-internal.googleplex.com`.
+
+## Why 3rd-Party Cookies Are Required
+
+The Perfetto UI is hosted on `https://ui.perfetto.dev`, while the internal
+extension server is hosted on `https://perfetto-gae-internal.googleplex.com`.
+Because these origins have different domains, browser requests from the Perfetto
+UI to the extension server are **cross-site (third-party)** requests.
+
+Authentication to the internal extension server relies on corporate single
+sign-on (SSO) session cookies. If your browser blocks 3rd-party cookies, these
+authentication cookies will not be sent, causing requests to fail with HTTP 403
+or CORS errors. As a result:
+
+1. The internal extension server cannot load its manifest, macros, or SQL
+   modules.
+2. The UI cannot verify your internal user status, disabling Googler-specific
+   features such as internal trace sharing.
+
+## How to Enable 3rd-Party Cookies in Chrome
+
+To enable access to internal features, you need to allow third-party cookies for
+the internal extension server.
+
+### Option 1: Add a Site Exception in Chrome Settings (Recommended)
+
+You do not need to allow 3rd-party cookies globally. You can add specific site
+exceptions:
+
+1. Open Chrome settings by navigating to `chrome://settings/cookies` or
+   `chrome://settings/trackingProtection` (or go to **Settings** → **Privacy and
+   security** → **Third-party cookies** / **Tracking Protection**).
+2. Under **Sites allowed to use third-party cookies** (or **Allowed to use
+   third-party cookies**), click **Add**.
+3. Add `https://ui.perfetto.dev` and click **Add**.
+4. Reload [https://ui.perfetto.dev](https://ui.perfetto.dev).
+
+### Option 2: Allow via the Chrome Address Bar
+
+1. Navigate to [https://ui.perfetto.dev](https://ui.perfetto.dev).
+2. Look for the **eye icon** (or the site controls icon next to the address bar)
+   indicating blocked third-party cookies.
+3. Click the icon and toggle **Third-party cookies** to **Allowed** for
+   `ui.perfetto.dev`.
+4. Reload the page when prompted.
+
+## Verifying Your Setup
+
+Once 3rd-party cookies are enabled:
+
+1. Open [https://ui.perfetto.dev](https://ui.perfetto.dev).
+2. Open **Settings** (gear icon in the sidebar) and navigate to **Extension
+   Servers**.
+3. You should see the internal extension server listed as enabled, with
+   available modules loaded (e.g. `default`).
+4. Press `Ctrl+Shift+P` (or `Cmd+Shift+P` on Mac) to open the command palette.
+   Google-internal macros should appear in the command list.
+5. Internal trace sharing options will now be available when viewing traces.
+
+## Troubleshooting
+
+- **Server still shows an error:** Navigate directly to
+  `https://perfetto-gae-internal.googleplex.com` in a separate tab to ensure your
+  SSO session is active, then reload `https://ui.perfetto.dev`.
+- **Still blocked on corp network/VPN:** Ensure you are connected to the
+  corporate network or VPN so that `googleplex.com` endpoints are reachable.
+- See [Extension Servers](/docs/visualization/extension-servers.md) for more
+  details on extension server mechanics and troubleshooting.
diff --git a/docs/visualization/heap-dump-explorer.md b/docs/visualization/heap-dump-explorer.md
index 58bb2f2..559519c 100644
--- a/docs/visualization/heap-dump-explorer.md
+++ b/docs/visualization/heap-dump-explorer.md
@@ -484,6 +484,10 @@
 of which classes own the most memory. Clicking a class name opens
 Objects filtered to that class.
 
+A warning icon after a class name means the class may include other
+classes merged into it during app optimization; see
+[Merged classes](#merged-classes).
+
 ## Objects
 
 The Objects tab lists reachable instances. Opening it from Classes or
@@ -677,6 +681,28 @@
 Multiple flamegraph selections can be open at once, each as its own
 tab — useful for comparing two call stacks side by side.
 
+## Merged classes
+
+When an app is optimized and obfuscated (for example, by R8), several
+source classes can be merged into one: a class merged into its only
+subclass, or similar sibling classes combined. In a heap dump, all
+instances of those classes appear under the target class's name, so its
+count, shallow size, and retained size represent the combined total.
+
+When the trace includes a deobfuscation mapping for the app (see
+[Symbolization and deobfuscation](/docs/learning-more/symbolization.md#merged-classes)),
+the explorer and heap graph flamegraphs mark classes that may include
+merged classes with a warning icon. Hover over the icon (or the
+flamegraph node) for details.
+
+![Classes tab with a warning icon after `com.example.sampleapp.MainActivityJava`; its tooltip reads "Possibly merged class".](../images/heap_docs/19-merged-class-classes.png)
+
+Treat a flagged class's numbers as an upper bound for the class shown:
+part of the memory may belong to classes that were merged into it. To
+see which classes were merged, look up the class in the deobfuscation
+mapping. If the mapping doesn't record merged classes (for example, R8
+mapping files older than format 2.3), every renamed class is flagged.
+
 ## Case studies
 
 <!-- TODO(zezeozue): Break these case studies out and integrate them into
diff --git a/gn/perfetto.gni b/gn/perfetto.gni
index 32429b3..91a7a5c 100644
--- a/gn/perfetto.gni
+++ b/gn/perfetto.gni
@@ -297,8 +297,6 @@
   # This flag enables the use of inotify on AF_UNIX sockets to re-connect when
   # the server disconnects. Disabled in chromium as inotify is not allowed by
   # Chrome's seccomp sandbox (b/470556120).
-  # On Android platform (non-standalone) builds this flag is ignored. The flag
-  # "use_unix_socket_inotify" is used instead (see perfetto_flags.aconfig).
   enable_perfetto_sock_inotify =
       !is_wasm && (perfetto_build_standalone || is_perfetto_build_generator) &&
       !build_with_chromium
diff --git a/gn/perfetto_benchmarks.gni b/gn/perfetto_benchmarks.gni
index 3ba634d..89509dd 100644
--- a/gn/perfetto_benchmarks.gni
+++ b/gn/perfetto_benchmarks.gni
@@ -24,6 +24,7 @@
   "src/trace_processor:benchmarks",
   "src/trace_processor/containers:benchmarks",
   "src/trace_processor/importers/common:benchmarks",
+  "src/trace_processor/core/common:benchmarks",
   "src/trace_processor/core/exec:benchmarks",
   "src/trace_processor/core/util:benchmarks",
   "src/trace_processor/core/interpreter:benchmarks",
diff --git a/gn/standalone/toolchain/BUILD.gn b/gn/standalone/toolchain/BUILD.gn
index 3308758..7bf814b 100644
--- a/gn/standalone/toolchain/BUILD.gn
+++ b/gn/standalone/toolchain/BUILD.gn
@@ -133,6 +133,11 @@
     _target_triplet = "arm-linux-gnueabihf"
     _default_target_sysroot =
         rebase_path("//buildtools/debian_sid_arm-sysroot", root_build_dir)
+  } else if (target_os == "linux" && target_cpu == "s390x") {
+    _target_triplet = "s390x-linux-gnu"
+    _default_target_sysroot =
+        rebase_path("//buildtools/debian_bullseye_s390x-sysroot",
+                    root_build_dir)
   } else if (target_os == "linux" && target_cpu == "riscv64") {
     _target_triplet = "riscv64-linux-gnu"
   } else if (target_os == "linux" && target_cpu == "x64") {
diff --git a/include/perfetto/base/compiler.h b/include/perfetto/base/compiler.h
index d07e733..bbf236f 100644
--- a/include/perfetto/base/compiler.h
+++ b/include/perfetto/base/compiler.h
@@ -160,6 +160,15 @@
 #define PERFETTO_NO_DESTROY
 #endif
 
+// Lets a class with a non-trivial destructor or copy still be passed and
+// returned in registers, as a trivial one is. The class must not depend on
+// its address staying the same across a move: the bytes are just copied.
+#if defined(__clang__) && PERFETTO_HAS_ATTRIBUTE(trivial_abi)
+#define PERFETTO_TRIVIAL_ABI __attribute__((trivial_abi))
+#else
+#define PERFETTO_TRIVIAL_ABI
+#endif
+
 // Macro for telling -Wimplicit-fallthrough that a fallthrough is intentional.
 #define PERFETTO_FALLTHROUGH [[fallthrough]]
 
diff --git a/include/perfetto/base/status.h b/include/perfetto/base/status.h
index ee39593..b3a772d 100644
--- a/include/perfetto/base/status.h
+++ b/include/perfetto/base/status.h
@@ -17,10 +17,11 @@
 #ifndef INCLUDE_PERFETTO_BASE_STATUS_H_
 #define INCLUDE_PERFETTO_BASE_STATUS_H_
 
+#include <cstdint>
 #include <optional>
 #include <string>
 #include <string_view>
-#include <vector>
+#include <utility>
 
 #include "perfetto/base/compiler.h"
 #include "perfetto/base/export.h"
@@ -37,27 +38,47 @@
 // Similar to absl::Status, an optional "payload" can also be included with more
 // context about the error. This allows passing additional metadata about the
 // error (e.g. location of errors, potential mitigations etc).
-class PERFETTO_EXPORT_COMPONENT Status {
+//
+// A Status is one word: zero when ok, else the error, kept on the heap. Errors
+// are rare and statuses are created, moved and destroyed everywhere, so all
+// an ok status costs is inline and trivial, and everything to do with an
+// error is out of line. Being one word, it is passed and returned in a
+// register.
+class PERFETTO_EXPORT_COMPONENT PERFETTO_TRIVIAL_ABI Status {
  public:
-  Status() : ok_(true) {}
-  explicit Status(std::string msg) : ok_(false), message_(std::move(msg)) {
-    PERFETTO_CHECK(!message_.empty());
+  constexpr Status() = default;
+  explicit Status(std::string msg);
+
+  Status(const Status& other)
+      : rep_(other.rep_ > kMovedFrom ? Clone(other.rep_) : other.rep_) {}
+  Status& operator=(const Status& other) {
+    if (this != &other) {
+      Status copy(other);
+      std::swap(rep_, copy.rep_);
+    }
+    return *this;
   }
 
-  // Copy operations.
-  Status(const Status&) = default;
-  Status& operator=(const Status&) = default;
+  // Move operations. A moved-from status is an error saying so, as accessing
+  // it is a bug, rather than passing for ok.
+  Status(Status&& other) noexcept
+      : rep_(std::exchange(other.rep_, kMovedFrom)) {}
+  Status& operator=(Status&& other) noexcept {
+    if (this != &other) {
+      Release();
+      rep_ = std::exchange(other.rep_, kMovedFrom);
+    }
+    return *this;
+  }
 
-  // Move operations. The moved-from state is valid but unspecified.
-  Status(Status&&) noexcept = default;
-  Status& operator=(Status&&) = default;
+  ~Status() { Release(); }
 
-  bool ok() const { return ok_; }
+  bool ok() const { return rep_ == kOk; }
 
   // When ok() is false this returns the error message. Returns the empty string
   // otherwise.
-  const std::string& message() const { return message_; }
-  const char* c_message() const { return message_.c_str(); }
+  const std::string& message() const;
+  const char* c_message() const { return message().c_str(); }
 
   //////////////////////////////////////////////////////////////////////////////
   // Payload Management APIs
@@ -94,14 +115,23 @@
   bool ErasePayload(std::string_view type_url);
 
  private:
-  struct Payload {
-    std::string type_url;
-    std::string payload;
-  };
+  // The error: its message and payloads.
+  struct Rep;
 
-  bool ok_ = false;
-  std::string message_;
-  std::vector<Payload> payloads_;
+  // Values of `rep_` which are not a Rep.
+  static constexpr uintptr_t kOk = 0;
+  static constexpr uintptr_t kMovedFrom = 1;
+
+  void Release() {
+    if (PERFETTO_UNLIKELY(rep_ > kMovedFrom)) {
+      Delete(rep_);
+    }
+  }
+  static void Delete(uintptr_t rep);
+  static uintptr_t Clone(uintptr_t rep);
+  Rep* rep() const;
+
+  uintptr_t rep_ = kOk;
 };
 
 // Returns a status object which represents the Ok status.
diff --git a/include/perfetto/ext/base/circular_queue.h b/include/perfetto/ext/base/circular_queue.h
index 48e8a42..e8d74c5 100644
--- a/include/perfetto/ext/base/circular_queue.h
+++ b/include/perfetto/ext/base/circular_queue.h
@@ -23,6 +23,7 @@
 #include <algorithm>
 #include <cstddef>
 #include <iterator>
+#include <memory>
 
 #include "perfetto/base/logging.h"
 #include "perfetto/ext/base/utils.h"
@@ -236,10 +237,13 @@
 
   void erase_front(size_t n) {
     increment_generation();
-    for (; n && (begin_ < end_); --n) {
-      Get(begin_)->~T();
-      begin_++;  // This needs to be its own statement, Get() checks begin_.
-    }
+    // Clamping |n| upfront gives the loop a single exit condition and a known
+    // trip count. For trivially destructible types the body is empty and the
+    // compiler drops the loop entirely, making this O(1).
+    n = std::min(n, size());
+    for (size_t i = 0; i < n; i++)
+      Get(begin_ + i)->~T();
+    begin_ += n;
   }
 
   void pop_front() { erase_front(1); }
@@ -350,15 +354,25 @@
 
     AlignedUniquePtr<T[]> new_vec = AlignedAllocTyped<T[]>(new_capacity);
 
-    // Move all elements in the expanded array.
-    size_t new_size = 0;
-    for (uint64_t i = begin_; i < end_; i++)
-      new (&new_vec[new_size++]) T(std::move(*Get(i)));  // Placement move ctor.
+    // The live elements are at most two contiguous runs in the old buffer:
+    // [start, start + wrap) and, if wrapped, [0, new_size - wrap).
+    // Operating on local pointers, rather than going through Get(), avoids
+    // reloading the members on each iteration (the compiler can't prove the
+    // stores into |new_vec| don't alias them). This lets trivially copyable
+    // types be copied with a vectorized loop and the dtor loop be dropped
+    // for trivially destructible ones.
+    size_t new_size = size();
+    T* src = entries_.get();
+    T* dst = new_vec.get();
+    size_t start = static_cast<size_t>(begin_ & (capacity_ - 1));
+    size_t wrap = std::min(new_size, capacity_ - start);
+    std::uninitialized_move(src + start, src + start + wrap, dst);
+    std::uninitialized_move(src, src + (new_size - wrap), dst + wrap);
 
     // Even if all the elements are std::move()-d and likely empty, we are still
     // required to call the dtor for them.
-    for (uint64_t i = begin_; i < end_; i++)
-      Get(i)->~T();
+    std::destroy(src + start, src + start + wrap);
+    std::destroy(src, src + (new_size - wrap));
 
     begin_ = 0;
     end_ = new_size;
diff --git a/include/perfetto/ext/base/flags.h b/include/perfetto/ext/base/flags.h
index 99346e2..0809555 100644
--- a/include/perfetto/ext/base/flags.h
+++ b/include/perfetto/ext/base/flags.h
@@ -32,8 +32,6 @@
 #define PERFETTO_FLAGS_USE_LOCKFREE_TASKRUNNER \
   PERFETTO_BUILDFLAG(PERFETTO_ENABLE_LOCKFREE_TASKRUNNER)
 #define PERFETTO_FLAGS_BUFFER_CLONE_PRESERVE_READ_ITER true
-#define PERFETTO_FLAGS_USE_UNIX_SOCKET_INOTIFY \
-  PERFETTO_BUILDFLAG(PERFETTO_ENABLE_SOCK_INOTIFY)
 #define PERFETTO_FLAGS_TRIGGER_PERFETTO_ON_TRACED_PROBES_DISCONNECT false
 #define PERFETTO_FLAGS_USE_ANON_RSS_IN_WATCHDOG true
 
diff --git a/include/perfetto/ext/base/status_macros.h b/include/perfetto/ext/base/status_macros.h
index 12a4cb3..0accc25 100644
--- a/include/perfetto/ext/base/status_macros.h
+++ b/include/perfetto/ext/base/status_macros.h
@@ -33,11 +33,12 @@
 
 // Evalues |rhs| which should return a base::StatusOr<T> and assigns this
 // to |lhs|. If the status is an error status, returns the status from the
-// current function.
-#define ASSIGN_OR_RETURN(lhs, rhs)                                   \
-  PERFETTO_INTERNAL_MACRO_CONCAT(auto status_or, __LINE__) = rhs;    \
-  RETURN_IF_ERROR(                                                   \
-      PERFETTO_INTERNAL_MACRO_CONCAT(status_or, __LINE__).status()); \
+// current function, moved rather than copied out.
+#define ASSIGN_OR_RETURN(lhs, rhs)                                        \
+  PERFETTO_INTERNAL_MACRO_CONCAT(auto status_or, __LINE__) = rhs;         \
+  if (!PERFETTO_INTERNAL_MACRO_CONCAT(status_or, __LINE__).ok())          \
+    return std::move(PERFETTO_INTERNAL_MACRO_CONCAT(status_or, __LINE__)) \
+        .status();                                                        \
   lhs = std::move(PERFETTO_INTERNAL_MACRO_CONCAT(status_or, __LINE__).value())
 
 #endif  // INCLUDE_PERFETTO_EXT_BASE_STATUS_MACROS_H_
diff --git a/include/perfetto/ext/base/status_or.h b/include/perfetto/ext/base/status_or.h
index 81b6449..16f6b79 100644
--- a/include/perfetto/ext/base/status_or.h
+++ b/include/perfetto/ext/base/status_or.h
@@ -17,7 +17,8 @@
 #ifndef INCLUDE_PERFETTO_EXT_BASE_STATUS_OR_H_
 #define INCLUDE_PERFETTO_EXT_BASE_STATUS_OR_H_
 
-#include <optional>
+#include <new>
+#include <type_traits>
 #include <utility>
 
 #include "perfetto/base/status.h"
@@ -31,26 +32,56 @@
 //
 // This class is modelled closely on absl::Status and should essentially 1:1
 // match it's API.
+//
+// The value is held only while the status is ok, in a union, as
+// std::optional holds its value: there is no separate flag for whether there
+// is a value. A value is only ever constructed where there was none and
+// destroyed where there will be none; one value replaces another by T's own
+// assignment.
 template <typename T>
 class StatusOr {
  public:
+  static_assert(!std::is_const<T>::value,
+                "StatusOr<const T> is not supported: use StatusOr<T>");
+
   // Matches naming of declarations in similar types e.g. std::optional,
   // std::variant.
   using value_type = T;
 
   // Intentionally implicit to allow idomatic usage (e.g. returning value/status
   // from base::StatusOr returning function).
-  StatusOr(base::Status status) : StatusOr(std::move(status), std::nullopt) {
+  StatusOr(base::Status status) : status_(std::move(status)) {
     if (status_.ok()) {
       // Matches what Abseil's approach towards OkStatus being passed to
       // absl::StatusOr<T>.
       PERFETTO_FATAL("base::OkStatus passed to StatusOr: this is not allowed");
     }
   }
-  StatusOr(T value) : StatusOr(base::OkStatus(), std::move(value)) {}
+  StatusOr(T value) { new (&value_) T(std::move(value)); }
+
+  StatusOr(const StatusOr& other) { ConstructFrom(other); }
+  StatusOr(StatusOr&& other) noexcept(
+      std::is_nothrow_move_constructible<T>::value) {
+    ConstructFrom(std::move(other));
+  }
+  StatusOr& operator=(const StatusOr& other) {
+    AssignFrom(other);
+    return *this;
+  }
+  StatusOr& operator=(StatusOr&& other) noexcept(
+      std::is_nothrow_move_assignable<T>::value &&
+      std::is_nothrow_move_constructible<T>::value) {
+    AssignFrom(std::move(other));
+    return *this;
+  }
+  ~StatusOr() { Destroy(); }
 
   bool ok() const { return status_.ok(); }
-  const base::Status& status() const { return status_; }
+  const base::Status& status() const& { return status_; }
+  // Moves an error out, leaving the value of an ok StatusOr in place.
+  base::Status status() && {
+    return ok() ? base::OkStatus() : std::move(status_);
+  }
 
   // For an lvalue caller, if ok(), returns a reference to the value, so the
   // StatusOr keeps owning it.
@@ -58,7 +89,7 @@
   T& ValueOrDie() & {
     if (!ok())
       PERFETTO_FATAL("%s", status_.c_message());
-    return *value_;
+    return value_;
   }
 
   // For an rvalue caller, if ok(), moves the value out because the StatusOr
@@ -67,14 +98,14 @@
   T ValueOrDie() && {
     if (!ok())
       PERFETTO_FATAL("%s", status_.c_message());
-    return std::move(*value_);
+    return std::move(value_);
   }
 
   T& value() {
     PERFETTO_DCHECK(status_.ok());
-    return *value_;
+    return value_;
   }
-  const T& value() const { return *value_; }
+  const T& value() const { return value_; }
 
   T& operator*() { return value(); }
   const T& operator*() const { return value(); }
@@ -83,13 +114,40 @@
   const T* operator->() const { return &value(); }
 
  private:
-  StatusOr(base::Status status, std::optional<T> value)
-      : status_(std::move(status)), value_(std::move(value)) {
-    PERFETTO_DCHECK(!status_.ok() || value_.has_value());
+  // Copies or moves |other| into a StatusOr with no value. A moved-from
+  // StatusOr keeps its status, and so a moved-from value which it still
+  // destroys.
+  template <typename Other>
+  void ConstructFrom(Other&& other) {
+    if (other.ok()) {
+      new (&value_) T(std::forward<Other>(other).value_);
+    } else {
+      status_ = std::forward<Other>(other).status_;
+    }
+  }
+
+  template <typename Other>
+  void AssignFrom(Other&& other) {
+    if (ok() && other.ok()) {
+      value_ = std::forward<Other>(other).value_;
+    } else if (this != &other) {
+      Destroy();
+      status_ = base::OkStatus();
+      ConstructFrom(std::forward<Other>(other));
+    }
+  }
+
+  // Ends the value's lifetime, if there is one.
+  void Destroy() {
+    if (ok()) {
+      value_.~T();
+    }
   }
 
   base::Status status_;
-  std::optional<T> value_;
+  union {
+    T value_;
+  };
 };
 
 // Deduction guide to make returning StatusOr less verbose.
diff --git a/include/perfetto/ext/base/type_set.h b/include/perfetto/ext/base/type_set.h
index 2a848f0..6c07b97 100644
--- a/include/perfetto/ext/base/type_set.h
+++ b/include/perfetto/ext/base/type_set.h
@@ -86,6 +86,15 @@
 
   uint32_t index() const { return type_idx_; }
 
+  // The inverse of index(): the TypeSet holding the type at `index`, or
+  // nullopt if there is no such type. For reading back a stored index().
+  static std::optional<TypeSet> FromIndex(uint32_t index) {
+    if (index >= kSize) {
+      return std::nullopt;
+    }
+    return TypeSet(index);
+  }
+
   template <typename T>
   constexpr bool Is() const {
     return type_idx_ == GetTypeIndex<T>();
diff --git a/include/perfetto/ext/base/unix_socket.h b/include/perfetto/ext/base/unix_socket.h
index 28551ca..de01d3f 100644
--- a/include/perfetto/ext/base/unix_socket.h
+++ b/include/perfetto/ext/base/unix_socket.h
@@ -481,7 +481,7 @@
 
 // Creates a LinuxFileWatch for the given unix socket.
 // Returns nullptr if:
-// - flags::use_unix_socket_inotify == false
+// - The build disables it (enable_perfetto_sock_inotify in gn/perfetto.gni).
 // - `sock_name` is not a file-system linked unix socket.
 // - The underlying filesystem doesn't support inotify (or other errors occur).
 // - Any platform other than Linux/Android.
diff --git a/include/perfetto/public/protos/BUILD.gn b/include/perfetto/public/protos/BUILD.gn
index 518a6ea..6473399 100644
--- a/include/perfetto/public/protos/BUILD.gn
+++ b/include/perfetto/public/protos/BUILD.gn
@@ -30,6 +30,7 @@
     "trace/track_event/debug_annotation.pzc.h",
     "trace/track_event/state_descriptor.pzc.h",
     "trace/track_event/track_descriptor.pzc.h",
+    "trace/track_event/track_dimension.pzc.h",
     "trace/track_event/track_event.pzc.h",
     "trace/trigger.pzc.h",
   ]
diff --git a/include/perfetto/public/protos/trace/interned_data/interned_data.pzc.h b/include/perfetto/public/protos/trace/interned_data/interned_data.pzc.h
index b49c234..db701b6 100644
--- a/include/perfetto/public/protos/trace/interned_data/interned_data.pzc.h
+++ b/include/perfetto/public/protos/trace/interned_data/interned_data.pzc.h
@@ -84,6 +84,11 @@
 PERFETTO_PB_FIELD(perfetto_protos_InternedData,
                   MSG,
                   perfetto_protos_InternedString,
+                  track_dimension_strings,
+                  52);
+PERFETTO_PB_FIELD(perfetto_protos_InternedData,
+                  MSG,
+                  perfetto_protos_InternedString,
                   build_ids,
                   16);
 PERFETTO_PB_FIELD(perfetto_protos_InternedData,
diff --git a/include/perfetto/public/protos/trace/trace_packet.pzc.h b/include/perfetto/public/protos/trace/trace_packet.pzc.h
index 3d2c152..bd0eec9 100644
--- a/include/perfetto/public/protos/trace/trace_packet.pzc.h
+++ b/include/perfetto/public/protos/trace/trace_packet.pzc.h
@@ -44,6 +44,7 @@
 PERFETTO_PB_MSG_DECL(perfetto_protos_DeobfuscationMapping);
 PERFETTO_PB_MSG_DECL(perfetto_protos_EntityStateResidency);
 PERFETTO_PB_MSG_DECL(perfetto_protos_EtwTraceEventBundle);
+PERFETTO_PB_MSG_DECL(perfetto_protos_ExperimentalTracingV2ProducerStats);
 PERFETTO_PB_MSG_DECL(perfetto_protos_ExtensionDescriptor);
 PERFETTO_PB_MSG_DECL(perfetto_protos_FtraceEventBundle);
 PERFETTO_PB_MSG_DECL(perfetto_protos_FtraceStats);
@@ -244,6 +245,11 @@
                   35);
 PERFETTO_PB_FIELD(perfetto_protos_TracePacket,
                   MSG,
+                  perfetto_protos_ExperimentalTracingV2ProducerStats,
+                  experimental_tracing_v2_producer_stats,
+                  139);
+PERFETTO_PB_FIELD(perfetto_protos_TracePacket,
+                  MSG,
                   perfetto_protos_ProfilePacket,
                   profile_packet,
                   37);
diff --git a/include/perfetto/public/protos/trace/track_event/track_descriptor.pzc.h b/include/perfetto/public/protos/trace/track_event/track_descriptor.pzc.h
index 8bf7d83..b0bc0dd 100644
--- a/include/perfetto/public/protos/trace/track_event/track_descriptor.pzc.h
+++ b/include/perfetto/public/protos/trace/track_event/track_descriptor.pzc.h
@@ -31,6 +31,7 @@
 PERFETTO_PB_MSG_DECL(perfetto_protos_ProcessDescriptor);
 PERFETTO_PB_MSG_DECL(perfetto_protos_StateDescriptor);
 PERFETTO_PB_MSG_DECL(perfetto_protos_ThreadDescriptor);
+PERFETTO_PB_MSG_DECL(perfetto_protos_TrackDimension);
 
 PERFETTO_PB_ENUM_IN_MSG(perfetto_protos_TrackDescriptor, ChildTracksOrdering){
     PERFETTO_PB_ENUM_IN_MSG_ENTRY(perfetto_protos_TrackDescriptor, UNKNOWN) = 0,
@@ -165,5 +166,10 @@
                   enum perfetto_protos_TrackDescriptor_ThreadOrdering,
                   thread_ordering,
                   20);
+PERFETTO_PB_FIELD(perfetto_protos_TrackDescriptor,
+                  MSG,
+                  perfetto_protos_TrackDimension,
+                  dimensions,
+                  21);
 
 #endif  // INCLUDE_PERFETTO_PUBLIC_PROTOS_TRACE_TRACK_EVENT_TRACK_DESCRIPTOR_PZC_H_
diff --git a/include/perfetto/public/protos/trace/track_event/track_dimension.pzc.h b/include/perfetto/public/protos/trace/track_event/track_dimension.pzc.h
new file mode 100644
index 0000000..658239c
--- /dev/null
+++ b/include/perfetto/public/protos/trace/track_event/track_dimension.pzc.h
@@ -0,0 +1,61 @@
+/*
+ * 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.
+ */
+
+// Autogenerated by the ProtoZero C compiler plugin.
+// Invoked by tools/gen_c_protos
+// DO NOT EDIT.
+#ifndef INCLUDE_PERFETTO_PUBLIC_PROTOS_TRACE_TRACK_EVENT_TRACK_DIMENSION_PZC_H_
+#define INCLUDE_PERFETTO_PUBLIC_PROTOS_TRACE_TRACK_EVENT_TRACK_DIMENSION_PZC_H_
+
+#include <stdbool.h>
+#include <stdint.h>
+
+#include "perfetto/public/pb_macros.h"
+
+PERFETTO_PB_MSG(perfetto_protos_TrackDimension);
+PERFETTO_PB_FIELD(perfetto_protos_TrackDimension, STRING, const char*, name, 1);
+PERFETTO_PB_FIELD(perfetto_protos_TrackDimension,
+                  VARINT,
+                  uint64_t,
+                  name_iid,
+                  7);
+PERFETTO_PB_FIELD(perfetto_protos_TrackDimension,
+                  VARINT,
+                  int64_t,
+                  int_value,
+                  2);
+PERFETTO_PB_FIELD(perfetto_protos_TrackDimension,
+                  STRING,
+                  const char*,
+                  string_value,
+                  3);
+PERFETTO_PB_FIELD(perfetto_protos_TrackDimension,
+                  VARINT,
+                  uint64_t,
+                  string_value_iid,
+                  5);
+PERFETTO_PB_FIELD(perfetto_protos_TrackDimension,
+                  STRING,
+                  const char*,
+                  display_name,
+                  4);
+PERFETTO_PB_FIELD(perfetto_protos_TrackDimension,
+                  VARINT,
+                  uint64_t,
+                  display_name_iid,
+                  6);
+
+#endif  // INCLUDE_PERFETTO_PUBLIC_PROTOS_TRACE_TRACK_EVENT_TRACK_DIMENSION_PZC_H_
diff --git a/infra/perfetto.dev/package.json b/infra/perfetto.dev/package.json
index 73ae145..3f03ead 100644
--- a/infra/perfetto.dev/package.json
+++ b/infra/perfetto.dev/package.json
@@ -8,6 +8,7 @@
   "license": "Apache-2.0",
   "dependencies": {
     "mermaid": "^11.16.1",
+    "railroad-diagrams": "1.0.0",
     "sass": "^1.94.0"
   },
   "devDependencies": {
diff --git a/infra/perfetto.dev/pnpm-lock.yaml b/infra/perfetto.dev/pnpm-lock.yaml
index bbed3e5..db2514e 100644
--- a/infra/perfetto.dev/pnpm-lock.yaml
+++ b/infra/perfetto.dev/pnpm-lock.yaml
@@ -11,6 +11,9 @@
       mermaid:
         specifier: ^11.16.1
         version: 11.16.1
+      railroad-diagrams:
+        specifier: 1.0.0
+        version: 1.0.0
       sass:
         specifier: ^1.94.0
         version: 1.101.0
@@ -586,6 +589,9 @@
     resolution: {integrity: sha512-/FPD0nUc9jH6rfFjji9IBqOz4pcSE3CsT1m7Ep6Mdb0LxSUMj8hgl6GomOvZzpNpAqqGaXA0P3VSrZLFzIhQrw==}
     engines: {node: '>=12.0.0'}
 
+  railroad-diagrams@1.0.0:
+    resolution: {integrity: sha512-cz93DjNeLY0idrCNOH6PviZGRN9GJhsdm9hpn1YCS879fj4W+x5IFJhhkRZcwVgMmFF7R82UA/7Oh+R8lLZg6A==}
+
   readdirp@5.0.0:
     resolution: {integrity: sha512-9u/XQ1pvrQtYyMpZe7DXKv2p5CNvyVwzUB6uhLAnQwHMSgKMBR62lc7AHljaeteeHXn11XTAaLLUVZYVZyuRBQ==}
     engines: {node: '>= 20.19.0'}
@@ -1208,6 +1214,8 @@
       '@types/node': 26.1.1
       long: 5.3.2
 
+  railroad-diagrams@1.0.0: {}
+
   readdirp@5.0.0: {}
 
   robust-predicates@3.0.3: {}
diff --git a/infra/perfetto.dev/src/assets/style.scss b/infra/perfetto.dev/src/assets/style.scss
index ce4b13f..af1f44a 100644
--- a/infra/perfetto.dev/src/assets/style.scss
+++ b/infra/perfetto.dev/src/assets/style.scss
@@ -988,6 +988,44 @@
     box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
     border-top: 3px solid #8bc34a;
   }
+  .railroad {
+    overflow-x: auto;
+    margin: 16px 0;
+    svg {
+      display: block;
+    }
+    path {
+      stroke-width: 2;
+      stroke: var(--color-text);
+      fill: none;
+    }
+    rect {
+      stroke-width: 2;
+      stroke: var(--color-text);
+      fill: var(--color-bg);
+    }
+    text {
+      font: 600 14px monospace;
+      text-anchor: middle;
+      fill: var(--color-text);
+    }
+    text.comment {
+      font: italic 12px monospace;
+    }
+    a:hover rect {
+      fill: var(--color-border-light);
+      stroke: var(--color-link);
+    }
+    .railroad-name {
+      font: italic 14px monospace;
+      color: var(--color-text-secondary);
+    }
+    // Terminals have rounded corners; non-terminals are square and italic.
+    g:has(> rect:not([rx])) > text {
+      font-style: italic;
+      font-weight: normal;
+    }
+  }
   .code-block-wrapper {
     position: relative;
     &:hover .code-copy-button,
diff --git a/infra/perfetto.dev/src/render.mjs b/infra/perfetto.dev/src/render.mjs
index 4469dc7..70a05fb 100644
--- a/infra/perfetto.dev/src/render.mjs
+++ b/infra/perfetto.dev/src/render.mjs
@@ -26,12 +26,15 @@
 //    it is just a return value that feeds the next build's cache signature.
 
 import fs from "node:fs";
+import { createRequire } from "node:module";
 import path from "node:path";
 import ejs from "ejs";
 import { Renderer, marked } from "marked";
 import hljs from "highlight.js";
 import { headingAnchor } from "./md_utils.mjs";
 
+const railroad = createRequire(import.meta.url)("railroad-diagrams");
+
 const CS_BASE_URL = "https://github.com/google/perfetto/blob/main/";
 
 const SRC_DIR = path.dirname(new URL(import.meta.url).pathname);
@@ -162,10 +165,34 @@
   return originalLinkFn(href, title, text);
 }
 
+// Makes a diagram item, such as a Terminal, a link to `href`.
+function railroadLink(item, href) {
+  item.tagName = "a";
+  item.attrs.href = href;
+  return item;
+}
+
+// A ```railroad block is an expression over the railroad-diagrams
+// constructors, e.g. Diagram(Terminal('FROM'), NonTerminal('table')), plus
+// Link(item, href). ```railroad <name> labels the diagram with a rule name.
+function renderRailroad(text, name) {
+  const scope = { ...railroad, Link: railroadLink };
+  const names = Object.keys(scope);
+  const diagram = new Function(...names, `return (${text});`)(
+    ...names.map((n) => scope[n]),
+  );
+  const label = name ? `<div class="railroad-name">${name}</div>` : "";
+  return `<div class="railroad">${label}${diagram.toString()}</div>`;
+}
+
 function renderCode(text, lang) {
   if (lang === "mermaid") {
     return `<div class="mermaid">${text}</div>`;
   }
+  const [kind, ...rest] = (lang || "").split(/\s+/);
+  if (kind === "railroad") {
+    return renderRailroad(text, rest.join(" "));
+  }
 
   let hlHtml = "";
   if (lang) {
diff --git a/perfetto_flags.aconfig b/perfetto_flags.aconfig
index f1be42a..93a987b 100644
--- a/perfetto_flags.aconfig
+++ b/perfetto_flags.aconfig
@@ -23,13 +23,6 @@
   is_fixed_read_only: true
 }
 flag {
-  name: "use_unix_socket_inotify"
-  namespace: "perfetto"
-  description: "Enables immediate reconnection to traced in case of crash or disconnection using inotify"
-  bug: "445943111"
-  is_fixed_read_only: true
-}
-flag {
   name: "trigger_perfetto_on_traced_probes_disconnect"
   namespace: "perfetto"
   description: "When enabled, traced fires a trigger when traced_probes disconnects, allowing pre-configured trace sessions to capture crash diagnostics."
diff --git a/protos/perfetto/common/trace_stats.proto b/protos/perfetto/common/trace_stats.proto
index 343574b..e0fa395 100644
--- a/protos/perfetto/common/trace_stats.proto
+++ b/protos/perfetto/common/trace_stats.proto
@@ -178,6 +178,13 @@
     // The buffer index (0..N, as defined in the TraceConfig).
     optional uint32 buffer = 4;
 
+    // Which protocol carried this writer's chunks to the buffer.
+    // This is a bitmask of ProtocolAbiVersion (see producer_port.proto).
+    // The value is 1 for the SMB (v1) and 2 for the tracing v2 ring buffer.
+    // Both bits are set only if a v1 and a v2 writer of the same producer used
+    // the same writer ID which should NOT be happening.
+    optional uint32 protocol_abi_versions = 5;
+
     // These two arrays have the same cardinality and match the cardinality of
     // chunk_payload_histogram_def + 1 (for the overflow bucket, see below).
     // `sum` contains the SUM(entries) and `counts` contains the COUNT(entries)
diff --git a/protos/perfetto/trace/interned_data/interned_data.proto b/protos/perfetto/trace/interned_data/interned_data.proto
index 4388398..9185bda 100644
--- a/protos/perfetto/trace/interned_data/interned_data.proto
+++ b/protos/perfetto/trace/interned_data/interned_data.proto
@@ -64,7 +64,7 @@
 // Note: field IDs up to 15 should be used for frequent data only.
 //
 // Next reserved id: 8 (up to 15).
-// Next id: 51.
+// Next id: 53.
 message InternedData {
   // TODO(eseckler): Replace iid fields inside interned messages with
   // map<iid, message> type fields in InternedData.
@@ -82,6 +82,9 @@
   repeated InternedString debug_annotation_string_values = 29;
   // Interned correlation ids in track_event.
   repeated InternedString correlation_id_str = 43;
+  // Interned names, string values and display names of TrackDimensions (see
+  // TrackDimension.name_iid, string_value_iid and display_name_iid).
+  repeated InternedString track_dimension_strings = 52;
 
   //
   // == STABLE PUBLIC API: Callstacks and symbolization ==
diff --git a/protos/perfetto/trace/perfetto/BUILD.gn b/protos/perfetto/trace/perfetto/BUILD.gn
index 10b44ea..4cf1b44 100644
--- a/protos/perfetto/trace/perfetto/BUILD.gn
+++ b/protos/perfetto/trace/perfetto/BUILD.gn
@@ -20,5 +20,6 @@
     "perfetto_metatrace.proto",
     "trace_provenance.proto",
     "tracing_service_event.proto",
+    "tracing_v2_producer_stats.proto",
   ]
 }
diff --git a/protos/perfetto/trace/perfetto/tracing_v2_producer_stats.proto b/protos/perfetto/trace/perfetto/tracing_v2_producer_stats.proto
new file mode 100644
index 0000000..65a7ee5
--- /dev/null
+++ b/protos/perfetto/trace/perfetto/tracing_v2_producer_stats.proto
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 2026 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;
+
+// Stats for the tracing v2 ring buffer of one producer since connection.
+// The service emits one packet for each connected producer that has a data
+// source in the session and an attached ring buffer. A producer that only uses
+// the SMB has no stats packet. A cloned session keeps the stats from the time
+// of the clone.
+//
+// These stats include producer identity, so they are separate from TraceStats
+// and pass through the session's trace filter.
+//
+// Next id: 22.
+message ExperimentalTracingV2ProducerStats {
+  // The producer that owns the ring buffer.
+  optional uint32 producer_id = 1;
+  optional int32 pid = 2;
+  optional string producer_name = 3;
+
+  // Layout of the attached ring buffer.
+  optional uint32 chunk_size_bytes = 4;
+  optional uint32 num_chunks = 5;
+
+  // The service counts the fields below while it reads the ring buffer.
+
+  // Num. chunks that the service copied out of the ring buffer.
+  optional uint64 chunks_read = 6;
+
+  // Total size of the packet fragments in |chunks_read|. It excludes the
+  // chunk headers and the fragment sizes.
+  optional uint64 bytes_read = 7;
+
+  // Num. chunks discarded because their writer marked them as lossy.
+  // A writer marks the next chunk it gets after it dropped data, e.g. when
+  // the ring buffer was full.
+  optional uint64 data_loss_chunks = 8;
+
+  // Num. chunks discarded because the sizes of their fragments are invalid.
+  // Either a size cannot be decoded, or the fragments do not fit in the
+  // chunk. A nonzero value points to a writer bug or to corrupt memory.
+  optional uint64 malformed_chunks = 9;
+
+  // Num. chunks discarded because the service does not know their format.
+  optional uint64 unsupported_format_chunks = 10;
+
+  // The next three count chunks in |chunks_read| that no trace buffer
+  // stored.
+
+  // The chunk's writer ID was zero or out of range.
+  optional uint64 invalid_writer_chunks = 11;
+
+  // The chunk's target buffer is not a TraceBuffer that the producer can
+  // write to.
+  optional uint64 invalid_destination_chunks = 12;
+
+  // The trace buffer refused the chunk. Its BufferStats say why, in
+  // |abi_violations| or |chunks_discarded|.
+  optional uint64 trace_buffer_rejected_chunks = 13;
+
+  // Num. chunks that the service read while their writer was still filling
+  // them. The writer then moves its open fragment to another chunk.
+  optional uint64 rewrite_requests = 14;
+
+  // Num. ring buffer positions that gave no chunk to the service. They are
+  // positions that no writer claimed, chunks with no published fragment and
+  // the discarded chunks above.
+  optional uint64 positions_skipped = 15;
+
+  // Num. times the service read the ring buffer. It reads it when the
+  // producer sends a DrainV2RingBuffer request, on its own (e.g. on a
+  // flush), and to retry a pass that stopped early.
+  optional uint64 drain_passes = 16;
+
+  // Time that the service spent in |drain_passes|, measured with
+  // CLOCK_MONOTONIC. It does not count time when the device was suspended.
+  optional uint64 drain_time_ns = 17;
+
+  // Time of the longest of |drain_passes|, on the same clock. The service
+  // has one main thread, so a long pass delays every other producer and
+  // request.
+  optional uint64 drain_max_time_ns = 18;
+
+  // The producer's writers count the fields below in the ring buffer header.
+  // The service reports the values as it finds them, so a buggy or hostile
+  // producer can set anything here.
+
+  // Num. packets that the writers dropped before the packets reached a
+  // chunk. This includes packets dropped before the service attached the
+  // ring buffer. A writer adds its drops when it flushes or stops dropping,
+  // so the value can lag.
+  optional uint64 writer_dropped_packets = 19;
+
+  // Num. times a writer waited for a free chunk, and the total time of those
+  // waits. This is time that the app's threads were blocked. A writer checks
+  // again after about 100 ms, so a longer stall counts several times.
+  optional uint64 writer_stalls = 20;
+  optional uint64 writer_stall_time_ms = 21;
+}
diff --git a/protos/perfetto/trace/perfetto_trace.proto b/protos/perfetto/trace/perfetto_trace.proto
index cccae7a..3774099 100644
--- a/protos/perfetto/trace/perfetto_trace.proto
+++ b/protos/perfetto/trace/perfetto_trace.proto
@@ -6492,6 +6492,13 @@
     // The buffer index (0..N, as defined in the TraceConfig).
     optional uint32 buffer = 4;
 
+    // Which protocol carried this writer's chunks to the buffer.
+    // This is a bitmask of ProtocolAbiVersion (see producer_port.proto).
+    // The value is 1 for the SMB (v1) and 2 for the tracing v2 ring buffer.
+    // Both bits are set only if a v1 and a v2 writer of the same producer used
+    // the same writer ID which should NOT be happening.
+    optional uint32 protocol_abi_versions = 5;
+
     // These two arrays have the same cardinality and match the cardinality of
     // chunk_payload_histogram_def + 1 (for the overflow bucket, see below).
     // `sum` contains the SUM(entries) and `counts` contains the COUNT(entries)
@@ -15870,7 +15877,7 @@
 // Note: field IDs up to 15 should be used for frequent data only.
 //
 // Next reserved id: 8 (up to 15).
-// Next id: 51.
+// Next id: 53.
 message InternedData {
   // TODO(eseckler): Replace iid fields inside interned messages with
   // map<iid, message> type fields in InternedData.
@@ -15888,6 +15895,9 @@
   repeated InternedString debug_annotation_string_values = 29;
   // Interned correlation ids in track_event.
   repeated InternedString correlation_id_str = 43;
+  // Interned names, string values and display names of TrackDimensions (see
+  // TrackDimension.name_iid, string_value_iid and display_name_iid).
+  repeated InternedString track_dimension_strings = 52;
 
   //
   // == STABLE PUBLIC API: Callstacks and symbolization ==
@@ -16364,6 +16374,106 @@
 
 // End of protos/perfetto/trace/perfetto/tracing_service_event.proto
 
+// Begin of protos/perfetto/trace/perfetto/tracing_v2_producer_stats.proto
+
+// Stats for the tracing v2 ring buffer of one producer since connection.
+// The service emits one packet for each connected producer that has a data
+// source in the session and an attached ring buffer. A producer that only uses
+// the SMB has no stats packet. A cloned session keeps the stats from the time
+// of the clone.
+//
+// These stats include producer identity, so they are separate from TraceStats
+// and pass through the session's trace filter.
+//
+// Next id: 22.
+message ExperimentalTracingV2ProducerStats {
+  // The producer that owns the ring buffer.
+  optional uint32 producer_id = 1;
+  optional int32 pid = 2;
+  optional string producer_name = 3;
+
+  // Layout of the attached ring buffer.
+  optional uint32 chunk_size_bytes = 4;
+  optional uint32 num_chunks = 5;
+
+  // The service counts the fields below while it reads the ring buffer.
+
+  // Num. chunks that the service copied out of the ring buffer.
+  optional uint64 chunks_read = 6;
+
+  // Total size of the packet fragments in |chunks_read|. It excludes the
+  // chunk headers and the fragment sizes.
+  optional uint64 bytes_read = 7;
+
+  // Num. chunks discarded because their writer marked them as lossy.
+  // A writer marks the next chunk it gets after it dropped data, e.g. when
+  // the ring buffer was full.
+  optional uint64 data_loss_chunks = 8;
+
+  // Num. chunks discarded because the sizes of their fragments are invalid.
+  // Either a size cannot be decoded, or the fragments do not fit in the
+  // chunk. A nonzero value points to a writer bug or to corrupt memory.
+  optional uint64 malformed_chunks = 9;
+
+  // Num. chunks discarded because the service does not know their format.
+  optional uint64 unsupported_format_chunks = 10;
+
+  // The next three count chunks in |chunks_read| that no trace buffer
+  // stored.
+
+  // The chunk's writer ID was zero or out of range.
+  optional uint64 invalid_writer_chunks = 11;
+
+  // The chunk's target buffer is not a TraceBuffer that the producer can
+  // write to.
+  optional uint64 invalid_destination_chunks = 12;
+
+  // The trace buffer refused the chunk. Its BufferStats say why, in
+  // |abi_violations| or |chunks_discarded|.
+  optional uint64 trace_buffer_rejected_chunks = 13;
+
+  // Num. chunks that the service read while their writer was still filling
+  // them. The writer then moves its open fragment to another chunk.
+  optional uint64 rewrite_requests = 14;
+
+  // Num. ring buffer positions that gave no chunk to the service. They are
+  // positions that no writer claimed, chunks with no published fragment and
+  // the discarded chunks above.
+  optional uint64 positions_skipped = 15;
+
+  // Num. times the service read the ring buffer. It reads it when the
+  // producer sends a DrainV2RingBuffer request, on its own (e.g. on a
+  // flush), and to retry a pass that stopped early.
+  optional uint64 drain_passes = 16;
+
+  // Time that the service spent in |drain_passes|, measured with
+  // CLOCK_MONOTONIC. It does not count time when the device was suspended.
+  optional uint64 drain_time_ns = 17;
+
+  // Time of the longest of |drain_passes|, on the same clock. The service
+  // has one main thread, so a long pass delays every other producer and
+  // request.
+  optional uint64 drain_max_time_ns = 18;
+
+  // The producer's writers count the fields below in the ring buffer header.
+  // The service reports the values as it finds them, so a buggy or hostile
+  // producer can set anything here.
+
+  // Num. packets that the writers dropped before the packets reached a
+  // chunk. This includes packets dropped before the service attached the
+  // ring buffer. A writer adds its drops when it flushes or stops dropping,
+  // so the value can lag.
+  optional uint64 writer_dropped_packets = 19;
+
+  // Num. times a writer waited for a free chunk, and the total time of those
+  // waits. This is time that the app's threads were blocked. A writer checks
+  // again after about 100 ms, so a longer stall counts several times.
+  optional uint64 writer_stalls = 20;
+  optional uint64 writer_stall_time_ms = 21;
+}
+
+// End of protos/perfetto/trace/perfetto/tracing_v2_producer_stats.proto
+
 // Begin of protos/perfetto/common/android_energy_consumer_descriptor.proto
 
 // Energy consumer based on aidl class:
@@ -17981,6 +18091,86 @@
 
 // End of protos/perfetto/trace/track_event/state_descriptor.proto
 
+// Begin of protos/perfetto/trace/track_event/track_dimension.proto
+
+// A named, typed key/value which is part of a track's identity.
+//
+// Dimensions are the single vocabulary for identifiers which apply to a set of
+// tracks: *well-known* dimensions are synthesized by trace processor, while
+// producers can declare their own *custom* dimensions (`rank`, `shard`,
+// `stage`, ...) on a TrackDescriptor.
+//
+// Reserved names: the names of the well-known dimensions are reserved and
+// cannot be used for custom dimensions. They are:
+//  * `machine`: the machine the track belongs to.
+//  * `gpu`: the GPU the track belongs to.
+//  * `cpu`: the CPU the track belongs to.
+//  * `process`: the process the track belongs to.
+//  * `thread`: the thread the track belongs to.
+// Their values are derived by trace processor from the typed fields of the
+// TrackDescriptor (e.g. `process`, `thread`) and from import context, and mean
+// the same thing across data sources. A custom dimension using a reserved name
+// is ignored and trace processor records the
+// `track_descriptor_reserved_dimension_name` import error.
+//
+// A dimension has no scope field: it is declared on the track described by the
+// containing TrackDescriptor and applies to that track and its `parent_uuid`
+// descendants, whether it is a process, thread or any other track. In
+// particular, a dimension declared on a process track doesn't apply to the
+// threads of the process unless their tracks are `parent_uuid` descendants of
+// the process track.
+//
+// Declaring a *different* value for a dimension name which is already
+// inherited from an ancestor is invalid: trace processor records an import
+// error and keeps the inherited value.
+//
+// The dimensions declared on a TrackDescriptor (names and values; the order
+// and `display_name` don't matter) are part of the identity of that track:
+//  * they are fixed for the lifetime of the track, so every TrackDescriptor
+//    emitted for a given `uuid`, including the first one, must declare the
+//    same dimensions. A TrackDescriptor declaring different dimensions is
+//    rejected as a conflicting reservation and the first one is kept.
+//  * sibling tracks are only merged (see
+//    `TrackDescriptor.sibling_merge_behavior`) if they declare the same
+//    dimensions.
+message TrackDimension {
+  // The canonical dimension key, e.g. "rank". Must be non-empty and must not
+  // be one of the reserved names listed above.
+  oneof name_field {
+    string name = 1;
+    // Interned version of `name`: corresponds to the `track_dimension_strings`
+    // field in InternedData, looked up like `string_value_iid`.
+    uint64 name_iid = 7;
+  }
+
+  // The typed value of the dimension. This is the value used for SQL queries,
+  // track identity and (for well-known dimensions) merging, so it must be
+  // stable for the whole trace.
+  oneof value {
+    int64 int_value = 2;
+    string string_value = 3;
+    // Interned version of `string_value`: corresponds to the
+    // `track_dimension_strings` field in InternedData, looked up in the
+    // interned data of the sequence the TrackDescriptor is emitted on. The
+    // resolved string is the value, so an interned and an inline string with
+    // the same contents are the same value.
+    uint64 string_value_iid = 5;
+  }
+
+  // Optional human readable label for this *value*, e.g. "worker-east" for
+  // rank 7. Only affects presentation: the canonical typed value above is what
+  // SQL and merging use.
+  oneof display {
+    string display_name = 4;
+    // Interned version of `display_name`: corresponds to the
+    // `track_dimension_strings` field in InternedData, looked up like
+    // `string_value_iid`.
+    uint64 display_name_iid = 6;
+  }
+}
+
+// End of protos/perfetto/trace/track_event/track_dimension.proto
+
 // Begin of protos/perfetto/trace/track_event/track_descriptor.proto
 
 // Defines a track for TrackEvents. Slices and instant events on the same track
@@ -17996,7 +18186,7 @@
 // |TrackEvent::track_uuid|. It is possible but not necessary to emit a
 // TrackDescriptor for this implicit track.
 //
-// Next id: 21.
+// Next id: 22.
 message TrackDescriptor {
   // Unique ID that identifies this track. This ID is global to the whole trace.
   // Producers should ensure that it is unlikely to clash with IDs emitted by
@@ -18196,6 +18386,7 @@
   //    `SIBLING_MERGE_BEHAVIOR_BY_TRACK_NAME`.
   // 3. Depending on the behavior, the corresponding key must match (e.g. `name`
   //    for `BY_TRACK_NAME`, `sibling_merge_key` for `BY_SIBLING_MERGE_KEY`).
+  // 4. All tracks must declare the same `dimensions`.
   //
   // Specifically:
   //   - in the UI, all tracks which are merged together will be
@@ -18339,6 +18530,24 @@
     THREAD_ORDERING_EXPLICIT = 1;
   }
   optional ThreadOrdering thread_ordering = 20;
+
+  // Custom, producer-declared dimensions for this track. Repeated so that a
+  // track can carry more than one independent dimension (e.g. `rank` and
+  // `stage`).
+  //
+  // Dimensions declared here apply to this track and its `parent_uuid`
+  // descendants. See TrackDimension for the full resolution rules.
+  //
+  // Dimensions are part of the track's identity: every descriptor emitted for
+  // this `uuid` must declare the same dimensions, starting with the first one,
+  // and only siblings declaring the same dimensions are merged. See
+  // TrackDimension for details.
+  //
+  // Well-known dimensions (`machine`, `gpu`, `cpu`, `process`, `thread`) are
+  // synthesized by trace processor from the typed fields above and from import
+  // context: their names are reserved and producers must *not* declare them
+  // here. See TrackDimension for the full list of reserved names.
+  repeated TrackDimension dimensions = 21;
 }
 
 // End of protos/perfetto/trace/track_event/track_descriptor.proto
@@ -18471,7 +18680,7 @@
 // See the [Buffers and Dataflow](/docs/concepts/buffers.md) doc for details.
 //
 // Next reserved id: 14 (up to 15).
-// Next id: 139.
+// Next id: 140.
 message TracePacket {
   // Encapsulates the state and configuration of the ProtoVM instances running
   // when the trace was snapshotted. This allows TP to re-instantiate the VMs
@@ -18544,6 +18753,8 @@
     TraceConfig trace_config = 33;
     FtraceStats ftrace_stats = 34;
     TraceStats trace_stats = 35;
+    ExperimentalTracingV2ProducerStats experimental_tracing_v2_producer_stats =
+        139;
     ProfilePacket profile_packet = 37;
     StreamingAllocation streaming_allocation = 74;
     StreamingFree streaming_free = 75;
diff --git a/protos/perfetto/trace/trace_packet.proto b/protos/perfetto/trace/trace_packet.proto
index c2f0667..afa89f7 100644
--- a/protos/perfetto/trace/trace_packet.proto
+++ b/protos/perfetto/trace/trace_packet.proto
@@ -60,6 +60,7 @@
 import "protos/perfetto/trace/perfetto/perfetto_metatrace.proto";
 import "protos/perfetto/trace/perfetto/trace_provenance.proto";
 import "protos/perfetto/trace/perfetto/tracing_service_event.proto";
+import "protos/perfetto/trace/perfetto/tracing_v2_producer_stats.proto";
 import "protos/perfetto/trace/power/android_energy_estimation_breakdown.proto";
 import "protos/perfetto/trace/power/android_entity_state_residency.proto";
 import "protos/perfetto/trace/power/battery_counters.proto";
@@ -112,7 +113,7 @@
 // See the [Buffers and Dataflow](/docs/concepts/buffers.md) doc for details.
 //
 // Next reserved id: 14 (up to 15).
-// Next id: 139.
+// Next id: 140.
 message TracePacket {
   // Encapsulates the state and configuration of the ProtoVM instances running
   // when the trace was snapshotted. This allows TP to re-instantiate the VMs
@@ -185,6 +186,8 @@
     TraceConfig trace_config = 33;
     FtraceStats ftrace_stats = 34;
     TraceStats trace_stats = 35;
+    ExperimentalTracingV2ProducerStats experimental_tracing_v2_producer_stats =
+        139;
     ProfilePacket profile_packet = 37;
     StreamingAllocation streaming_allocation = 74;
     StreamingFree streaming_free = 75;
diff --git a/protos/perfetto/trace/track_event/BUILD.gn b/protos/perfetto/trace/track_event/BUILD.gn
index a92abf4..c066d5a 100644
--- a/protos/perfetto/trace/track_event/BUILD.gn
+++ b/protos/perfetto/trace/track_event/BUILD.gn
@@ -43,6 +43,7 @@
     "task_execution.proto",
     "thread_descriptor.proto",
     "track_descriptor.proto",
+    "track_dimension.proto",
     "track_event.proto",
   ]
   generate_descriptor = "track_event.descriptor"
diff --git a/protos/perfetto/trace/track_event/track_descriptor.proto b/protos/perfetto/trace/track_event/track_descriptor.proto
index 03fa36a..de5a2f6 100644
--- a/protos/perfetto/trace/track_event/track_descriptor.proto
+++ b/protos/perfetto/trace/track_event/track_descriptor.proto
@@ -21,6 +21,7 @@
 import "protos/perfetto/trace/track_event/process_descriptor.proto";
 import "protos/perfetto/trace/track_event/thread_descriptor.proto";
 import "protos/perfetto/trace/track_event/counter_descriptor.proto";
+import "protos/perfetto/trace/track_event/track_dimension.proto";
 import "protos/perfetto/trace/track_event/state_descriptor.proto";
 
 package perfetto.protos;
@@ -38,7 +39,7 @@
 // |TrackEvent::track_uuid|. It is possible but not necessary to emit a
 // TrackDescriptor for this implicit track.
 //
-// Next id: 21.
+// Next id: 22.
 message TrackDescriptor {
   // Unique ID that identifies this track. This ID is global to the whole trace.
   // Producers should ensure that it is unlikely to clash with IDs emitted by
@@ -238,6 +239,7 @@
   //    `SIBLING_MERGE_BEHAVIOR_BY_TRACK_NAME`.
   // 3. Depending on the behavior, the corresponding key must match (e.g. `name`
   //    for `BY_TRACK_NAME`, `sibling_merge_key` for `BY_SIBLING_MERGE_KEY`).
+  // 4. All tracks must declare the same `dimensions`.
   //
   // Specifically:
   //   - in the UI, all tracks which are merged together will be
@@ -381,4 +383,22 @@
     THREAD_ORDERING_EXPLICIT = 1;
   }
   optional ThreadOrdering thread_ordering = 20;
+
+  // Custom, producer-declared dimensions for this track. Repeated so that a
+  // track can carry more than one independent dimension (e.g. `rank` and
+  // `stage`).
+  //
+  // Dimensions declared here apply to this track and its `parent_uuid`
+  // descendants. See TrackDimension for the full resolution rules.
+  //
+  // Dimensions are part of the track's identity: every descriptor emitted for
+  // this `uuid` must declare the same dimensions, starting with the first one,
+  // and only siblings declaring the same dimensions are merged. See
+  // TrackDimension for details.
+  //
+  // Well-known dimensions (`machine`, `gpu`, `cpu`, `process`, `thread`) are
+  // synthesized by trace processor from the typed fields above and from import
+  // context: their names are reserved and producers must *not* declare them
+  // here. See TrackDimension for the full list of reserved names.
+  repeated TrackDimension dimensions = 21;
 }
diff --git a/protos/perfetto/trace/track_event/track_dimension.proto b/protos/perfetto/trace/track_event/track_dimension.proto
new file mode 100644
index 0000000..d7d4264
--- /dev/null
+++ b/protos/perfetto/trace/track_event/track_dimension.proto
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2026 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;
+
+// A named, typed key/value which is part of a track's identity.
+//
+// Dimensions are the single vocabulary for identifiers which apply to a set of
+// tracks: *well-known* dimensions are synthesized by trace processor, while
+// producers can declare their own *custom* dimensions (`rank`, `shard`,
+// `stage`, ...) on a TrackDescriptor.
+//
+// Reserved names: the names of the well-known dimensions are reserved and
+// cannot be used for custom dimensions. They are:
+//  * `machine`: the machine the track belongs to.
+//  * `gpu`: the GPU the track belongs to.
+//  * `cpu`: the CPU the track belongs to.
+//  * `process`: the process the track belongs to.
+//  * `thread`: the thread the track belongs to.
+// Their values are derived by trace processor from the typed fields of the
+// TrackDescriptor (e.g. `process`, `thread`) and from import context, and mean
+// the same thing across data sources. A custom dimension using a reserved name
+// is ignored and trace processor records the
+// `track_descriptor_reserved_dimension_name` import error.
+//
+// A dimension has no scope field: it is declared on the track described by the
+// containing TrackDescriptor and applies to that track and its `parent_uuid`
+// descendants, whether it is a process, thread or any other track. In
+// particular, a dimension declared on a process track doesn't apply to the
+// threads of the process unless their tracks are `parent_uuid` descendants of
+// the process track.
+//
+// Declaring a *different* value for a dimension name which is already
+// inherited from an ancestor is invalid: trace processor records an import
+// error and keeps the inherited value.
+//
+// The dimensions declared on a TrackDescriptor (names and values; the order
+// and `display_name` don't matter) are part of the identity of that track:
+//  * they are fixed for the lifetime of the track, so every TrackDescriptor
+//    emitted for a given `uuid`, including the first one, must declare the
+//    same dimensions. A TrackDescriptor declaring different dimensions is
+//    rejected as a conflicting reservation and the first one is kept.
+//  * sibling tracks are only merged (see
+//    `TrackDescriptor.sibling_merge_behavior`) if they declare the same
+//    dimensions.
+message TrackDimension {
+  // The canonical dimension key, e.g. "rank". Must be non-empty and must not
+  // be one of the reserved names listed above.
+  oneof name_field {
+    string name = 1;
+    // Interned version of `name`: corresponds to the `track_dimension_strings`
+    // field in InternedData, looked up like `string_value_iid`.
+    uint64 name_iid = 7;
+  }
+
+  // The typed value of the dimension. This is the value used for SQL queries,
+  // track identity and (for well-known dimensions) merging, so it must be
+  // stable for the whole trace.
+  oneof value {
+    int64 int_value = 2;
+    string string_value = 3;
+    // Interned version of `string_value`: corresponds to the
+    // `track_dimension_strings` field in InternedData, looked up in the
+    // interned data of the sequence the TrackDescriptor is emitted on. The
+    // resolved string is the value, so an interned and an inline string with
+    // the same contents are the same value.
+    uint64 string_value_iid = 5;
+  }
+
+  // Optional human readable label for this *value*, e.g. "worker-east" for
+  // rank 7. Only affects presentation: the canonical typed value above is what
+  // SQL and merging use.
+  oneof display {
+    string display_name = 4;
+    // Interned version of `display_name`: corresponds to the
+    // `track_dimension_strings` field in InternedData, looked up like
+    // `string_value_iid`.
+    uint64 display_name_iid = 6;
+  }
+}
diff --git a/python/perfetto/protos/perfetto/trace/perfetto_trace_pb2.py b/python/perfetto/protos/perfetto/trace/perfetto_trace_pb2.py
index 6ecb2d9..fb213a7 100644
--- a/python/perfetto/protos/perfetto/trace/perfetto_trace_pb2.py
+++ b/python/perfetto/protos/perfetto/trace/perfetto_trace_pb2.py
@@ -24,7 +24,7 @@
 
 
 
-DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n*protos/perfetto/trace/perfetto_trace.proto\x12\x0fperfetto.protos\"\x94\x01\n\x10\x46traceDescriptor\x12K\n\x11\x61trace_categories\x18\x01 \x03(\x0b\x32\x30.perfetto.protos.FtraceDescriptor.AtraceCategory\x1a\x33\n\x0e\x41traceCategory\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x13\n\x0b\x64\x65scription\x18\x02 \x01(\t\"\x9f\x0f\n\x14GpuCounterDescriptor\x12\x43\n\x05specs\x18\x01 \x03(\x0b\x32\x34.perfetto.protos.GpuCounterDescriptor.GpuCounterSpec\x12\x45\n\x06\x62locks\x18\x02 \x03(\x0b\x32\x35.perfetto.protos.GpuCounterDescriptor.GpuCounterBlock\x12Q\n\x0e\x63ounter_groups\x18\x06 \x03(\x0b\x32\x39.perfetto.protos.GpuCounterDescriptor.GpuCounterGroupSpec\x12\x1e\n\x16min_sampling_period_ns\x18\x03 \x01(\x04\x12\x1e\n\x16max_sampling_period_ns\x18\x04 \x01(\x04\x12&\n\x1esupports_instrumented_sampling\x18\x05 \x01(\x08\x12\x1e\n\x16supports_counter_names\x18\x07 \x01(\x08\x12#\n\x1bsupports_counter_name_globs\x18\x08 \x01(\x08\x1a\xec\x04\n\x0eGpuCounterSpec\x12\x12\n\ncounter_id\x18\x01 \x01(\r\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x13\n\x0b\x64\x65scription\x18\x03 \x01(\t\x12\x18\n\x0eint_peak_value\x18\x05 \x01(\x03H\x00\x12\x1b\n\x11\x64ouble_peak_value\x18\x06 \x01(\x01H\x00\x12J\n\x0fnumerator_units\x18\x07 \x03(\x0e\x32\x31.perfetto.protos.GpuCounterDescriptor.MeasureUnit\x12L\n\x11\x64\x65nominator_units\x18\x08 \x03(\x0e\x32\x31.perfetto.protos.GpuCounterDescriptor.MeasureUnit\x12\x19\n\x11select_by_default\x18\t \x01(\x08\x12\x45\n\x06groups\x18\n \x03(\x0e\x32\x35.perfetto.protos.GpuCounterDescriptor.GpuCounterGroup\x12\\\n\x0fvalue_direction\x18\x0b \x01(\x0e\x32\x43.perfetto.protos.GpuCounterDescriptor.GpuCounterSpec.ValueDirection\"~\n\x0eValueDirection\x12\x1f\n\x1bVALUE_DIRECTION_UNSPECIFIED\x10\x00\x12%\n!VALUE_DIRECTION_BACKWARDS_LOOKING\x10\x01\x12$\n VALUE_DIRECTION_FORWARDS_LOOKING\x10\x02\x42\x0c\n\npeak_valueJ\x04\x08\x04\x10\x05\x1as\n\x0fGpuCounterBlock\x12\x10\n\x08\x62lock_id\x18\x01 \x01(\r\x12\x16\n\x0e\x62lock_capacity\x18\x02 \x01(\r\x12\x0c\n\x04name\x18\x03 \x01(\t\x12\x13\n\x0b\x64\x65scription\x18\x04 \x01(\t\x12\x13\n\x0b\x63ounter_ids\x18\x05 \x03(\r\x1a_\n\x13GpuCounterGroupSpec\x12\x10\n\x08group_id\x18\x01 \x01(\r\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x13\n\x0b\x64\x65scription\x18\x03 \x01(\t\x12\x13\n\x0b\x63ounter_ids\x18\x04 \x03(\r\"\x86\x01\n\x0fGpuCounterGroup\x12\x10\n\x0cUNCLASSIFIED\x10\x00\x12\n\n\x06SYSTEM\x10\x01\x12\x0c\n\x08VERTICES\x10\x02\x12\r\n\tFRAGMENTS\x10\x03\x12\x0e\n\nPRIMITIVES\x10\x04\x12\n\n\x06MEMORY\x10\x05\x12\x0b\n\x07\x43OMPUTE\x10\x06\x12\x0f\n\x0bRAY_TRACING\x10\x07\"\xac\x04\n\x0bMeasureUnit\x12\x08\n\x04NONE\x10\x00\x12\x07\n\x03\x42IT\x10\x01\x12\x0b\n\x07KILOBIT\x10\x02\x12\x0b\n\x07MEGABIT\x10\x03\x12\x0b\n\x07GIGABIT\x10\x04\x12\x0b\n\x07TERABIT\x10\x05\x12\x0b\n\x07PETABIT\x10\x06\x12\x08\n\x04\x42YTE\x10\x07\x12\x0c\n\x08KILOBYTE\x10\x08\x12\x0c\n\x08MEGABYTE\x10\t\x12\x0c\n\x08GIGABYTE\x10\n\x12\x0c\n\x08TERABYTE\x10\x0b\x12\x0c\n\x08PETABYTE\x10\x0c\x12\t\n\x05HERTZ\x10\r\x12\r\n\tKILOHERTZ\x10\x0e\x12\r\n\tMEGAHERTZ\x10\x0f\x12\r\n\tGIGAHERTZ\x10\x10\x12\r\n\tTERAHERTZ\x10\x11\x12\r\n\tPETAHERTZ\x10\x12\x12\x0e\n\nNANOSECOND\x10\x13\x12\x0f\n\x0bMICROSECOND\x10\x14\x12\x0f\n\x0bMILLISECOND\x10\x15\x12\n\n\x06SECOND\x10\x16\x12\n\n\x06MINUTE\x10\x17\x12\x08\n\x04HOUR\x10\x18\x12\n\n\x06VERTEX\x10\x19\x12\t\n\x05PIXEL\x10\x1a\x12\x0c\n\x08TRIANGLE\x10\x1b\x12\r\n\tPRIMITIVE\x10&\x12\x0c\n\x08\x46RAGMENT\x10\'\x12\r\n\tMILLIWATT\x10\x1c\x12\x08\n\x04WATT\x10\x1d\x12\x0c\n\x08KILOWATT\x10\x1e\x12\t\n\x05JOULE\x10\x1f\x12\x08\n\x04VOLT\x10 \x12\n\n\x06\x41MPERE\x10!\x12\x0b\n\x07\x43\x45LSIUS\x10\"\x12\x0e\n\nFAHRENHEIT\x10#\x12\n\n\x06KELVIN\x10$\x12\x0b\n\x07PERCENT\x10%\x12\x0f\n\x0bINSTRUCTION\x10(\"E\n\x12TrackEventCategory\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x13\n\x0b\x64\x65scription\x18\x02 \x01(\t\x12\x0c\n\x04tags\x18\x03 \x03(\t\"Y\n\x14TrackEventDescriptor\x12\x41\n\x14\x61vailable_categories\x18\x01 \x03(\x0b\x32#.perfetto.protos.TrackEventCategory\"R\n\tVmProgram\x12\x0f\n\x07version\x18\x01 \x01(\r\x12\x34\n\x0cinstructions\x18\x02 \x03(\x0b\x32\x1e.perfetto.protos.VmInstruction\"\xde\x03\n\rVmInstruction\x12-\n\x06select\x18\x01 \x01(\x0b\x32\x1b.perfetto.protos.VmOpSelectH\x00\x12\x30\n\x08reg_load\x18\x02 \x01(\x0b\x32\x1c.perfetto.protos.VmOpRegLoadH\x00\x12+\n\x05merge\x18\x03 \x01(\x0b\x32\x1a.perfetto.protos.VmOpMergeH\x00\x12\'\n\x03set\x18\x04 \x01(\x0b\x32\x18.perfetto.protos.VmOpSetH\x00\x12\'\n\x03\x64\x65l\x18\x05 \x01(\x0b\x32\x18.perfetto.protos.VmOpDelH\x00\x12>\n\x0b\x61\x62ort_level\x18\x06 \x01(\x0e\x32).perfetto.protos.VmInstruction.AbortLevel\x12;\n\x13nested_instructions\x18\x07 \x03(\x0b\x32\x1e.perfetto.protos.VmInstruction\"c\n\nAbortLevel\x12\x1c\n\x18SKIP_CURRENT_INSTRUCTION\x10\x01\x12,\n(SKIP_CURRENT_INSTRUCTION_AND_BREAK_OUTER\x10\x02\x12\t\n\x05\x41\x42ORT\x10\x03\x42\x0b\n\toperation\"\xd7\x02\n\nVmOpSelect\x12-\n\x06\x63ursor\x18\x01 \x01(\x0e\x32\x1d.perfetto.protos.VmCursorEnum\x12@\n\rrelative_path\x18\x02 \x03(\x0b\x32).perfetto.protos.VmOpSelect.PathComponent\x12\x1b\n\x13\x63reate_if_not_exist\x18\x03 \x01(\x08\x1a\xba\x01\n\rPathComponent\x12\x12\n\x08\x66ield_id\x18\x01 \x01(\rH\x00\x12\x15\n\x0b\x61rray_index\x18\x02 \x01(\rH\x00\x12\x1a\n\x10map_key_field_id\x18\x03 \x01(\rH\x00\x12\x13\n\x0bis_repeated\x18\x05 \x01(\x08\x12\x19\n\x11register_to_match\x18\x06 \x01(\r\x12)\n!store_foreach_index_into_register\x18\x07 \x01(\rB\x07\n\x05\x66ield\"R\n\x0bVmOpRegLoad\x12-\n\x06\x63ursor\x18\x01 \x01(\x0e\x32\x1d.perfetto.protos.VmCursorEnum\x12\x14\n\x0c\x64st_register\x18\x02 \x01(\r\"?\n\tVmOpMerge\x12\x18\n\x10skip_submessages\x18\x01 \x01(\x08\x12\x18\n\x10\x64\x65l_if_src_empty\x18\x02 \x01(\x08\"\t\n\x07VmOpSet\"\t\n\x07VmOpDel\"\xb7\x03\n\x14\x44\x61taSourceDescriptor\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\n\n\x02id\x18\x07 \x01(\x04\x12\x1b\n\x13will_notify_on_stop\x18\x02 \x01(\x08\x12\x1c\n\x14will_notify_on_start\x18\x03 \x01(\x08\x12\'\n\x1fhandles_incremental_state_clear\x18\x04 \x01(\x08\x12\x10\n\x08no_flush\x18\t \x01(\x08\x12\x37\n\x0fprotovm_program\x18\n \x01(\x0b\x32\x1a.perfetto.protos.VmProgramB\x02(\x01\x12I\n\x16gpu_counter_descriptor\x18\x05 \x01(\x0b\x32%.perfetto.protos.GpuCounterDescriptorB\x02(\x01\x12I\n\x16track_event_descriptor\x18\x06 \x01(\x0b\x32%.perfetto.protos.TrackEventDescriptorB\x02(\x01\x12@\n\x11\x66trace_descriptor\x18\x08 \x01(\x0b\x32!.perfetto.protos.FtraceDescriptorB\x02(\x01\"\xe2\x06\n\x13TracingServiceState\x12@\n\tproducers\x18\x01 \x03(\x0b\x32-.perfetto.protos.TracingServiceState.Producer\x12\x45\n\x0c\x64\x61ta_sources\x18\x02 \x03(\x0b\x32/.perfetto.protos.TracingServiceState.DataSource\x12M\n\x10tracing_sessions\x18\x06 \x03(\x0b\x32\x33.perfetto.protos.TracingServiceState.TracingSession\x12!\n\x19supports_tracing_sessions\x18\x07 \x01(\x08\x12\x14\n\x0cnum_sessions\x18\x03 \x01(\x05\x12\x1c\n\x14num_sessions_started\x18\x04 \x01(\x05\x12\x1f\n\x17tracing_service_version\x18\x05 \x01(\t\x1a\x8d\x01\n\x08Producer\x12\n\n\x02id\x18\x01 \x01(\x05\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x0b\n\x03pid\x18\x05 \x01(\x05\x12\x0b\n\x03uid\x18\x03 \x01(\x05\x12\x13\n\x0bsdk_version\x18\x04 \x01(\t\x12\x0e\n\x06\x66rozen\x18\x06 \x01(\x08\x12\x12\n\nmachine_id\x18\x07 \x01(\r\x12\x14\n\x0cmachine_name\x18\x08 \x01(\t\x1a_\n\nDataSource\x12<\n\rds_descriptor\x18\x01 \x01(\x0b\x32%.perfetto.protos.DataSourceDescriptor\x12\x13\n\x0bproducer_id\x18\x02 \x01(\x05\x1a\x89\x02\n\x0eTracingSession\x12\n\n\x02id\x18\x01 \x01(\x04\x12\x14\n\x0c\x63onsumer_uid\x18\x02 \x01(\x05\x12\r\n\x05state\x18\x03 \x01(\t\x12\x1b\n\x13unique_session_name\x18\x04 \x01(\t\x12\x16\n\x0e\x62uffer_size_kb\x18\x05 \x03(\r\x12\x13\n\x0b\x64uration_ms\x18\x06 \x01(\r\x12\x18\n\x10num_data_sources\x18\x07 \x01(\r\x12\x19\n\x11start_realtime_ns\x18\x08 \x01(\x03\x12\x17\n\x0f\x62ugreport_score\x18\t \x01(\x05\x12\x1a\n\x12\x62ugreport_filename\x18\n \x01(\t\x12\x12\n\nis_started\x18\x0b \x01(\x08\"\xa1\x01\n\x0fTraceAttributes\x12=\n\tattribute\x18\x01 \x03(\x0b\x32*.perfetto.protos.TraceAttributes.Attribute\x1aO\n\tAttribute\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\x14\n\nlong_value\x18\x02 \x01(\x03H\x00\x12\x16\n\x0cstring_value\x18\x03 \x01(\tH\x00\x42\x07\n\x05value\"&\n\x13\x41ndroidAflagsConfig\x12\x0f\n\x07poll_ms\x18\x01 \x01(\r\"@\n!AndroidGameInterventionListConfig\x12\x1b\n\x13package_name_filter\x18\x01 \x03(\t\"\xef\x04\n\x17\x41ndroidInputEventConfig\x12@\n\x04mode\x18\x01 \x01(\x0e\x32\x32.perfetto.protos.AndroidInputEventConfig.TraceMode\x12\x41\n\x05rules\x18\x02 \x03(\x0b\x32\x32.perfetto.protos.AndroidInputEventConfig.TraceRule\x12%\n\x1dtrace_dispatcher_input_events\x18\x03 \x01(\x08\x12(\n trace_dispatcher_window_dispatch\x18\x04 \x01(\x08\x12\x1a\n\x12trace_evdev_events\x18\x05 \x01(\x08\x1a\xc8\x01\n\tTraceRule\x12H\n\x0btrace_level\x18\x01 \x01(\x0e\x32\x33.perfetto.protos.AndroidInputEventConfig.TraceLevel\x12\x1a\n\x12match_all_packages\x18\x02 \x03(\t\x12\x1a\n\x12match_any_packages\x18\x03 \x03(\t\x12\x14\n\x0cmatch_secure\x18\x04 \x01(\x08\x12#\n\x1bmatch_ime_connection_active\x18\x05 \x01(\x08\"?\n\tTraceMode\x12\x18\n\x14TRACE_MODE_TRACE_ALL\x10\x00\x12\x18\n\x14TRACE_MODE_USE_RULES\x10\x01\"V\n\nTraceLevel\x12\x14\n\x10TRACE_LEVEL_NONE\x10\x00\x12\x18\n\x14TRACE_LEVEL_REDACTED\x10\x01\x12\x18\n\x14TRACE_LEVEL_COMPLETE\x10\x02\"\xb1\x01\n\x10\x41ndroidLogConfig\x12.\n\x07log_ids\x18\x01 \x03(\x0e\x32\x1d.perfetto.protos.AndroidLogId\x12\x35\n\x08min_prio\x18\x03 \x01(\x0e\x32#.perfetto.protos.AndroidLogPriority\x12\x13\n\x0b\x66ilter_tags\x18\x04 \x03(\t\x12\x1b\n\x13preserve_log_buffer\x18\x05 \x01(\x08J\x04\x08\x02\x10\x03\"+\n\x18\x41ndroidPolledStateConfig\x12\x0f\n\x07poll_ms\x18\x01 \x01(\r\":\n\x19\x41ndroidProcessStateConfig\x12\x1d\n\x15\x64ump_process_metadata\x18\x01 \x01(\x08\"\x8a\x01\n\x1c\x41ndroidSdkSyspropGuardConfig\x12(\n surfaceflinger_skia_track_events\x18\x01 \x01(\x08\x12\x1e\n\x16hwui_skia_track_events\x18\x02 \x01(\x08\x12 \n\x18hwui_package_name_filter\x18\x03 \x03(\t\"E\n\x1b\x41ndroidSystemPropertyConfig\x12\x0f\n\x07poll_ms\x18\x01 \x01(\r\x12\x15\n\rproperty_name\x18\x02 \x03(\t\"f\n\x12\x41ppWakelocksConfig\x12\x16\n\x0ewrite_delay_ms\x18\x01 \x01(\x05\x12 \n\x18\x66ilter_duration_below_ms\x18\x02 \x01(\x05\x12\x16\n\x0e\x64rop_owner_pid\x18\x03 \x01(\x08\"\"\n\x0f\x43puPerUidConfig\x12\x0f\n\x07poll_ms\x18\x01 \x01(\r\"\xf8\x01\n\x12\x44isplayVideoConfig\x12\r\n\x05scale\x18\x01 \x01(\x02\x12:\n\x06\x66ormat\x18\x02 \x01(\x0e\x32*.perfetto.protos.DisplayVideoConfig.Format\x12\x1f\n\x17key_frame_interval_secs\x18\x03 \x01(\r\x12\x1d\n\x15max_stream_size_bytes\x18\x04 \x01(\x04\x12\x13\n\x0b\x62itrate_bps\x18\x05 \x01(\r\"B\n\x06\x46ormat\x12\x16\n\x12\x46ORMAT_UNSPECIFIED\x10\x00\x12\x0f\n\x0b\x46ORMAT_H264\x10\x01\x12\x0f\n\x0b\x46ORMAT_HEVC\x10\x02\"M\n\x11InputMethodConfig\x12\x0e\n\x06\x63lient\x18\x01 \x01(\x08\x12\x0f\n\x07service\x18\x02 \x01(\x08\x12\x17\n\x0fmanager_service\x18\x03 \x01(\x08\"(\n\x15KernelWakelocksConfig\x12\x0f\n\x07poll_ms\x18\x01 \x01(\r\"\xab\x01\n\x18NetworkPacketTraceConfig\x12\x0f\n\x07poll_ms\x18\x01 \x01(\r\x12\x1d\n\x15\x61ggregation_threshold\x18\x02 \x01(\r\x12\x14\n\x0cintern_limit\x18\x03 \x01(\r\x12\x17\n\x0f\x64rop_local_port\x18\x04 \x01(\x08\x12\x18\n\x10\x64rop_remote_port\x18\x05 \x01(\x08\x12\x16\n\x0e\x64rop_tcp_flags\x18\x06 \x01(\x08\"|\n\x12PackagesListConfig\x12\x1b\n\x13package_name_filter\x18\x01 \x03(\t\x12!\n\x19package_name_regex_filter\x18\x03 \x03(\t\x12&\n\x1eonly_write_on_cpu_use_every_ms\x18\x02 \x01(\r\"\x84\x02\n\x10PixelModemConfig\x12\x41\n\x0b\x65vent_group\x18\x01 \x01(\x0e\x32,.perfetto.protos.PixelModemConfig.EventGroup\x12\x1f\n\x17pigweed_hash_allow_list\x18\x02 \x03(\x03\x12\x1e\n\x16pigweed_hash_deny_list\x18\x03 \x03(\x03\"l\n\nEventGroup\x12\x17\n\x13\x45VENT_GROUP_UNKNOWN\x10\x00\x12\x1d\n\x19\x45VENT_GROUP_LOW_BANDWIDTH\x10\x01\x12&\n\"EVENT_GROUP_HIGH_AND_LOW_BANDWIDTH\x10\x02\"\xf8\x01\n\x0eProtoLogConfig\x12\x37\n\x0fgroup_overrides\x18\x01 \x03(\x0b\x32\x1e.perfetto.protos.ProtoLogGroup\x12\x41\n\x0ctracing_mode\x18\x02 \x01(\x0e\x32+.perfetto.protos.ProtoLogConfig.TracingMode\x12>\n\x16\x64\x65\x66\x61ult_log_from_level\x18\x03 \x01(\x0e\x32\x1e.perfetto.protos.ProtoLogLevel\"*\n\x0bTracingMode\x12\x0b\n\x07\x44\x45\x46\x41ULT\x10\x00\x12\x0e\n\nENABLE_ALL\x10\x01\"q\n\rProtoLogGroup\x12\x12\n\ngroup_name\x18\x01 \x01(\t\x12\x30\n\x08log_from\x18\x02 \x01(\x0e\x32\x1e.perfetto.protos.ProtoLogLevel\x12\x1a\n\x12\x63ollect_stacktrace\x18\x03 \x01(\x08\"\x83\x04\n\x1aSurfaceFlingerLayersConfig\x12>\n\x04mode\x18\x01 \x01(\x0e\x32\x30.perfetto.protos.SurfaceFlingerLayersConfig.Mode\x12J\n\x0btrace_flags\x18\x02 \x03(\x0e\x32\x35.perfetto.protos.SurfaceFlingerLayersConfig.TraceFlag\"\x85\x01\n\x04Mode\x12\x14\n\x10MODE_UNSPECIFIED\x10\x00\x12\x0f\n\x0bMODE_ACTIVE\x10\x01\x12\x12\n\x0eMODE_GENERATED\x10\x02\x12\r\n\tMODE_DUMP\x10\x03\x12!\n\x1dMODE_GENERATED_BUGREPORT_ONLY\x10\x04\x12\x10\n\x0cMODE_PROTOVM\x10\x05\"\xd0\x01\n\tTraceFlag\x12\x1a\n\x16TRACE_FLAG_UNSPECIFIED\x10\x00\x12\x14\n\x10TRACE_FLAG_INPUT\x10\x02\x12\x1a\n\x16TRACE_FLAG_COMPOSITION\x10\x04\x12\x14\n\x10TRACE_FLAG_EXTRA\x10\x08\x12\x12\n\x0eTRACE_FLAG_HWC\x10\x10\x12\x16\n\x12TRACE_FLAG_BUFFERS\x10 \x12\x1f\n\x1bTRACE_FLAG_VIRTUAL_DISPLAYS\x10@\x12\x12\n\x0eTRACE_FLAG_ALL\x10\x0e\"\xac\x01\n SurfaceFlingerTransactionsConfig\x12\x44\n\x04mode\x18\x01 \x01(\x0e\x32\x36.perfetto.protos.SurfaceFlingerTransactionsConfig.Mode\"B\n\x04Mode\x12\x14\n\x10MODE_UNSPECIFIED\x10\x00\x12\x13\n\x0fMODE_CONTINUOUS\x10\x01\x12\x0f\n\x0bMODE_ACTIVE\x10\x02\"1\n\x15\x41ndroidUserListConfig\x12\x18\n\x10user_type_filter\x18\x01 \x03(\t\"\xab\x04\n\x13WindowManagerConfig\x12H\n\rlog_frequency\x18\x01 \x01(\x0e\x32\x31.perfetto.protos.WindowManagerConfig.LogFrequency\x12@\n\tlog_level\x18\x02 \x01(\x0e\x32-.perfetto.protos.WindowManagerConfig.LogLevel\x12>\n\x08log_mode\x18\x03 \x01(\x0e\x32,.perfetto.protos.WindowManagerConfig.LogMode\"\x84\x01\n\x0cLogFrequency\x12\x1d\n\x19LOG_FREQUENCY_UNSPECIFIED\x10\x00\x12\x17\n\x13LOG_FREQUENCY_FRAME\x10\x01\x12\x1d\n\x19LOG_FREQUENCY_TRANSACTION\x10\x02\x12\x1d\n\x19LOG_FREQUENCY_SINGLE_DUMP\x10\x03\"i\n\x08LogLevel\x12\x19\n\x15LOG_LEVEL_UNSPECIFIED\x10\x00\x12\x15\n\x11LOG_LEVEL_VERBOSE\x10\x01\x12\x13\n\x0fLOG_LEVEL_DEBUG\x10\x02\x12\x16\n\x12LOG_LEVEL_CRITICAL\x10\x03\"V\n\x07LogMode\x12\x18\n\x14LOG_MODE_UNSPECIFIED\x10\x00\x12\x17\n\x13LOG_MODE_FULL_STATE\x10\x01\x12\x18\n\x14LOG_MODE_INCREMENTAL\x10\x02\"\xbd\x02\n\x0c\x43hromeConfig\x12\x14\n\x0ctrace_config\x18\x01 \x01(\t\x12!\n\x19privacy_filtering_enabled\x18\x02 \x01(\x08\x12\x1e\n\x16\x63onvert_to_legacy_json\x18\x03 \x01(\x08\x12\x45\n\x0f\x63lient_priority\x18\x04 \x01(\x0e\x32,.perfetto.protos.ChromeConfig.ClientPriority\x12\x1f\n\x17json_agent_label_filter\x18\x05 \x01(\t\x12)\n!event_package_name_filter_enabled\x18\x06 \x01(\x08\"A\n\x0e\x43lientPriority\x12\x0b\n\x07UNKNOWN\x10\x00\x12\x0e\n\nBACKGROUND\x10\x01\x12\x12\n\x0eUSER_INITIATED\x10\x02\"\xe6\x01\n\x1e\x43hromiumHistogramSamplesConfig\x12S\n\nhistograms\x18\x01 \x03(\x0b\x32?.perfetto.protos.ChromiumHistogramSamplesConfig.HistogramSample\x12\x1e\n\x16\x66ilter_histogram_names\x18\x02 \x01(\x08\x1aO\n\x0fHistogramSample\x12\x16\n\x0ehistogram_name\x18\x01 \x01(\t\x12\x11\n\tmin_value\x18\x02 \x01(\x03\x12\x11\n\tmax_value\x18\x03 \x01(\x03\"c\n\"ChromiumSamplingHeapProfilerConfig\x12\x1f\n\x17sampling_interval_bytes\x18\x01 \x01(\x04\x12\x1c\n\x14sampling_interval_ms\x18\x02 \x01(\r\"C\n#ChromiumStackSamplingProfilerConfig\x12\x1c\n\x14sampling_interval_ms\x18\x01 \x01(\r\";\n\x1b\x43hromiumSystemMetricsConfig\x12\x1c\n\x14sampling_interval_ms\x18\x01 \x01(\r\"@\n\x08V8Config\x12\x1a\n\x12log_script_sources\x18\x01 \x01(\x08\x12\x18\n\x10log_instructions\x18\x02 \x01(\x08\"\xb1\x03\n\tEtwConfig\x12?\n\x0ckernel_flags\x18\x01 \x03(\x0e\x32%.perfetto.protos.EtwConfig.KernelFlagB\x02\x18\x01\x12!\n\x19scheduler_provider_events\x18\x02 \x03(\t\x12\x1e\n\x16memory_provider_events\x18\x03 \x03(\t\x12 \n\x14\x66ile_provider_events\x18\x04 \x03(\tB\x02\x18\x01\x12\x1d\n\x15stack_sampling_events\x18\x05 \x03(\t\x12 \n\x14\x64isk_provider_events\x18\x06 \x03(\tB\x02\x18\x01\x12!\n\x19system_io_provider_events\x18\x07 \x03(\t\x12\x44\n\x18stack_sampling_debug_ids\x18\x08 \x03(\x0b\x32\".perfetto.protos.EtwConfig.DebugId\x1a)\n\x07\x44\x65\x62ugId\x12\x0c\n\x04path\x18\x01 \x01(\t\x12\x10\n\x08\x64\x65\x62ug_id\x18\x02 \x01(\t\")\n\nKernelFlag\x12\x0b\n\x07\x43SWITCH\x10\x00\x12\x0e\n\nDISPATCHER\x10\x01\"+\n\x12\x46rozenFtraceConfig\x12\x15\n\rinstance_name\x18\x01 \x01(\t\"\xca\x0e\n\x0c\x46traceConfig\x12\x15\n\rftrace_events\x18\x01 \x03(\t\x12\x19\n\x11\x61trace_categories\x18\x02 \x03(\t\x12\x13\n\x0b\x61trace_apps\x18\x03 \x03(\t\x12$\n\x1c\x61trace_categories_prefer_sdk\x18\x1c \x03(\t\x12\x1d\n\x15\x61trace_userspace_only\x18\" \x01(\x08\x12\x16\n\x0e\x62uffer_size_kb\x18\n \x01(\r\x12\x1f\n\x17\x62uffer_size_lower_bound\x18\x1b \x01(\x08\x12\x17\n\x0f\x64rain_period_ms\x18\x0b \x01(\r\x12\x1c\n\x14\x64rain_buffer_percent\x18\x1d \x01(\r\x12G\n\rcompact_sched\x18\x0c \x01(\x0b\x32\x30.perfetto.protos.FtraceConfig.CompactSchedConfig\x12?\n\x0cprint_filter\x18\x16 \x01(\x0b\x32).perfetto.protos.FtraceConfig.PrintFilter\x12\x17\n\x0fsymbolize_ksyms\x18\r \x01(\x08\x12\x46\n\x10ksyms_mem_policy\x18\x11 \x01(\x0e\x32,.perfetto.protos.FtraceConfig.KsymsMemPolicy\x12\x19\n\x11throttle_rss_stat\x18\x0f \x01(\x08\x12%\n\x1d\x64\x65nser_generic_event_encoding\x18  \x01(\x08\x12\x1e\n\x16\x64isable_generic_events\x18\x10 \x01(\x08\x12\x16\n\x0esyscall_events\x18\x12 \x03(\t\x12\x1d\n\x15\x65nable_function_graph\x18\x13 \x01(\x08\x12\x18\n\x10\x66unction_filters\x18\x14 \x03(\t\x12\x1c\n\x14\x66unction_graph_roots\x18\x15 \x03(\t\x12 \n\x18\x66unction_graph_max_depth\x18! \x01(\r\x12@\n\rkprobe_events\x18\x1e \x03(\x0b\x32).perfetto.protos.FtraceConfig.KprobeEvent\x12\x1e\n\x16preserve_ftrace_buffer\x18\x17 \x01(\x08\x12\x1f\n\x17use_monotonic_raw_clock\x18\x18 \x01(\x08\x12\x15\n\rinstance_name\x18\x19 \x01(\t\x12\x18\n\x10\x64\x65\x62ug_ftrace_abi\x18\x1f \x01(\x08\x12\x15\n\rtids_to_trace\x18# \x03(\r\x12\x44\n\x0ftracefs_options\x18$ \x03(\x0b\x32+.perfetto.protos.FtraceConfig.TracefsOption\x12\x17\n\x0ftracing_cpumask\x18% \x01(\t\x12\x36\n*initialize_ksyms_synchronously_for_testing\x18\x0e \x01(\x08\x42\x02\x18\x01\x1a%\n\x12\x43ompactSchedConfig\x12\x0f\n\x07\x65nabled\x18\x01 \x01(\x08\x1a\x82\x02\n\x0bPrintFilter\x12=\n\x05rules\x18\x01 \x03(\x0b\x32..perfetto.protos.FtraceConfig.PrintFilter.Rule\x1a\xb3\x01\n\x04Rule\x12\x10\n\x06prefix\x18\x01 \x01(\tH\x00\x12R\n\natrace_msg\x18\x03 \x01(\x0b\x32<.perfetto.protos.FtraceConfig.PrintFilter.Rule.AtraceMessageH\x00\x12\r\n\x05\x61llow\x18\x02 \x01(\x08\x1a-\n\rAtraceMessage\x12\x0c\n\x04type\x18\x01 \x01(\t\x12\x0e\n\x06prefix\x18\x02 \x01(\tB\x07\n\x05match\x1a\xd0\x01\n\x0bKprobeEvent\x12\r\n\x05probe\x18\x01 \x01(\t\x12\x42\n\x04type\x18\x02 \x01(\x0e\x32\x34.perfetto.protos.FtraceConfig.KprobeEvent.KprobeType\"n\n\nKprobeType\x12\x17\n\x13KPROBE_TYPE_UNKNOWN\x10\x00\x12\x16\n\x12KPROBE_TYPE_KPROBE\x10\x01\x12\x19\n\x15KPROBE_TYPE_KRETPROBE\x10\x02\x12\x14\n\x10KPROBE_TYPE_BOTH\x10\x03\x1a\xa2\x01\n\rTracefsOption\x12\x0c\n\x04name\x18\x01 \x01(\t\x12@\n\x05state\x18\x02 \x01(\x0e\x32\x31.perfetto.protos.FtraceConfig.TracefsOption.State\"A\n\x05State\x12\x11\n\rSTATE_UNKNOWN\x10\x00\x12\x11\n\rSTATE_ENABLED\x10\x01\x12\x12\n\x0eSTATE_DISABLED\x10\x02\"T\n\x0eKsymsMemPolicy\x12\x15\n\x11KSYMS_UNSPECIFIED\x10\x00\x12\x19\n\x15KSYMS_CLEANUP_ON_STOP\x10\x01\x12\x10\n\x0cKSYMS_RETAIN\x10\x02J\x04\x08\x1a\x10\x1b\"\xe7\x06\n\x10GpuCounterConfig\x12\x19\n\x11\x63ounter_period_ns\x18\x01 \x01(\x04\x12\x13\n\x0b\x63ounter_ids\x18\x02 \x03(\r\x12\x15\n\rcounter_names\x18\x06 \x03(\t\x12\x1f\n\x15instrumented_sampling\x18\x03 \x01(\x08H\x00\x12\x64\n\x1cinstrumented_sampling_config\x18\x05 \x01(\x0b\x32<.perfetto.protos.GpuCounterConfig.InstrumentedSamplingConfigH\x00\x12\x15\n\rfix_gpu_clock\x18\x04 \x01(\x08\x1a\xcf\x04\n\x1aInstrumentedSamplingConfig\x12n\n\x15\x61\x63tivity_name_filters\x18\x03 \x03(\x0b\x32O.perfetto.protos.GpuCounterConfig.InstrumentedSamplingConfig.ActivityNameFilter\x12!\n\x19\x61\x63tivity_tx_include_globs\x18\x06 \x03(\t\x12!\n\x19\x61\x63tivity_tx_exclude_globs\x18\x07 \x03(\t\x12\x63\n\x0f\x61\x63tivity_ranges\x18\x05 \x03(\x0b\x32J.perfetto.protos.GpuCounterConfig.InstrumentedSamplingConfig.ActivityRange\x1a\xe7\x01\n\x12\x41\x63tivityNameFilter\x12\x11\n\tname_glob\x18\x01 \x01(\t\x12k\n\tname_base\x18\x02 \x01(\x0e\x32X.perfetto.protos.GpuCounterConfig.InstrumentedSamplingConfig.ActivityNameFilter.NameBase\"Q\n\x08NameBase\x12\x17\n\x13MANGLED_KERNEL_NAME\x10\x00\x12\x19\n\x15\x44\x45MANGLED_KERNEL_NAME\x10\x01\x12\x11\n\rFUNCTION_NAME\x10\x02\x1a,\n\rActivityRange\x12\x0c\n\x04skip\x18\x01 \x01(\r\x12\r\n\x05\x63ount\x18\x02 \x01(\rB\x1c\n\x1ainstrumented_sampling_mode\"u\n\x15GpuRenderStagesConfig\x12\x16\n\x0e\x66ull_loadstore\x18\x01 \x01(\x08\x12\x14\n\x0clow_overhead\x18\x02 \x01(\x08\x12\x15\n\rtrace_metrics\x18\x03 \x03(\t\x12\x17\n\x0f\x64rawcall_stages\x18\x04 \x01(\x08\"Z\n\x12VulkanMemoryConfig\x12!\n\x19track_driver_memory_usage\x18\x01 \x01(\x08\x12!\n\x19track_device_memory_usage\x18\x02 \x01(\x08\"\xa3\x02\n\x0fInodeFileConfig\x12\x18\n\x10scan_interval_ms\x18\x01 \x01(\r\x12\x15\n\rscan_delay_ms\x18\x02 \x01(\r\x12\x17\n\x0fscan_batch_size\x18\x03 \x01(\r\x12\x13\n\x0b\x64o_not_scan\x18\x04 \x01(\x08\x12\x19\n\x11scan_mount_points\x18\x05 \x03(\t\x12T\n\x13mount_point_mapping\x18\x06 \x03(\x0b\x32\x37.perfetto.protos.InodeFileConfig.MountPointMappingEntry\x1a@\n\x16MountPointMappingEntry\x12\x12\n\nmountpoint\x18\x01 \x01(\t\x12\x12\n\nscan_roots\x18\x02 \x03(\t\"\xa5\x01\n\rConsoleConfig\x12\x35\n\x06output\x18\x01 \x01(\x0e\x32%.perfetto.protos.ConsoleConfig.Output\x12\x15\n\renable_colors\x18\x02 \x01(\x08\"F\n\x06Output\x12\x16\n\x12OUTPUT_UNSPECIFIED\x10\x00\x12\x11\n\rOUTPUT_STDOUT\x10\x01\x12\x11\n\rOUTPUT_STDERR\x10\x02\"Y\n\x11InterceptorConfig\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x36\n\x0e\x63onsole_config\x18\x64 \x01(\x0b\x32\x1e.perfetto.protos.ConsoleConfig\"[\n\x15SystemdJournaldConfig\x12\x10\n\x08min_prio\x18\x01 \x01(\r\x12\x1a\n\x12\x66ilter_identifiers\x18\x02 \x03(\t\x12\x14\n\x0c\x66ilter_units\x18\x03 \x03(\t\"\xc0\x03\n\x12\x41ndroidPowerConfig\x12\x17\n\x0f\x62\x61ttery_poll_ms\x18\x01 \x01(\r\x12M\n\x10\x62\x61ttery_counters\x18\x02 \x03(\x0e\x32\x33.perfetto.protos.AndroidPowerConfig.BatteryCounters\x12\x1b\n\x13\x63ollect_power_rails\x18\x03 \x01(\x08\x12+\n#collect_energy_estimation_breakdown\x18\x04 \x01(\x08\x12&\n\x1e\x63ollect_entity_state_residency\x18\x05 \x01(\x08\"\xcf\x01\n\x0f\x42\x61tteryCounters\x12\x1f\n\x1b\x42\x41TTERY_COUNTER_UNSPECIFIED\x10\x00\x12\x1a\n\x16\x42\x41TTERY_COUNTER_CHARGE\x10\x01\x12$\n BATTERY_COUNTER_CAPACITY_PERCENT\x10\x02\x12\x1b\n\x17\x42\x41TTERY_COUNTER_CURRENT\x10\x03\x12\x1f\n\x1b\x42\x41TTERY_COUNTER_CURRENT_AVG\x10\x04\x12\x1b\n\x17\x42\x41TTERY_COUNTER_VOLTAGE\x10\x05\"\xbf\x01\n\x13PriorityBoostConfig\x12@\n\x06policy\x18\x01 \x01(\x0e\x32\x30.perfetto.protos.PriorityBoostConfig.BoostPolicy\x12\x10\n\x08priority\x18\x02 \x01(\r\"T\n\x0b\x42oostPolicy\x12\x16\n\x12POLICY_UNSPECIFIED\x10\x00\x12\x16\n\x12POLICY_SCHED_OTHER\x10\x01\x12\x15\n\x11POLICY_SCHED_FIFO\x10\x02\"\xeb\x03\n\x12ProcessStatsConfig\x12:\n\x06quirks\x18\x01 \x03(\x0e\x32*.perfetto.protos.ProcessStatsConfig.Quirks\x12#\n\x1bscan_all_processes_on_start\x18\x02 \x01(\x08\x12\x1b\n\x13record_thread_names\x18\x03 \x01(\x08\x12\x1a\n\x12proc_stats_poll_ms\x18\x04 \x01(\r\x12\x1f\n\x17proc_stats_cache_ttl_ms\x18\x06 \x01(\r\x12\x19\n\x11scan_smaps_rollup\x18\n \x01(\x08\x12\x1a\n\x12record_process_age\x18\x0b \x01(\x08\x12\x1e\n\x16record_process_runtime\x18\x0c \x01(\x08\x12!\n\x19record_process_dmabuf_rss\x18\r \x01(\x08\x12\x1b\n\x13resolve_process_fds\x18\t \x01(\x08\x12 \n\x18skip_main_thread_message\x18\x0e \x01(\x08\"U\n\x06Quirks\x12\x16\n\x12QUIRKS_UNSPECIFIED\x10\x00\x12\x1c\n\x14\x44ISABLE_INITIAL_DUMP\x10\x01\x1a\x02\x08\x01\x12\x15\n\x11\x44ISABLE_ON_DEMAND\x10\x02J\x04\x08\x07\x10\x08J\x04\x08\x08\x10\t\"\xcc\x06\n\x0fHeapprofdConfig\x12\x1f\n\x17sampling_interval_bytes\x18\x01 \x01(\x04\x12)\n!adaptive_sampling_shmem_threshold\x18\x18 \x01(\x04\x12\x35\n-adaptive_sampling_max_sampling_interval_bytes\x18\x19 \x01(\x04\x12\x17\n\x0fprocess_cmdline\x18\x02 \x03(\t\x12\x0b\n\x03pid\x18\x04 \x03(\x04\x12\x1b\n\x13target_installed_by\x18\x1a \x03(\t\x12\r\n\x05heaps\x18\x14 \x03(\t\x12\x15\n\rexclude_heaps\x18\x1b \x03(\t\x12\x1a\n\x12stream_allocations\x18\x17 \x01(\x08\x12\x1f\n\x17heap_sampling_intervals\x18\x16 \x03(\x04\x12\x11\n\tall_heaps\x18\x15 \x01(\x08\x12\x0b\n\x03\x61ll\x18\x05 \x01(\x08\x12\x1f\n\x17min_anonymous_memory_kb\x18\x0f \x01(\r\x12\x1f\n\x17max_heapprofd_memory_kb\x18\x10 \x01(\r\x12\x1e\n\x16max_heapprofd_cpu_secs\x18\x11 \x01(\x04\x12\x1a\n\x12skip_symbol_prefix\x18\x07 \x03(\t\x12U\n\x16\x63ontinuous_dump_config\x18\x06 \x01(\x0b\x32\x35.perfetto.protos.HeapprofdConfig.ContinuousDumpConfig\x12\x18\n\x10shmem_size_bytes\x18\x08 \x01(\x04\x12\x14\n\x0c\x62lock_client\x18\t \x01(\x08\x12\x1f\n\x17\x62lock_client_timeout_us\x18\x0e \x01(\r\x12\x12\n\nno_startup\x18\n \x01(\x08\x12\x12\n\nno_running\x18\x0b \x01(\x08\x12\x13\n\x0b\x64ump_at_max\x18\r \x01(\x08\x12\x1d\n\x15\x64isable_fork_teardown\x18\x12 \x01(\x08\x12\x1f\n\x17\x64isable_vfork_detection\x18\x13 \x01(\x08\x1aG\n\x14\x43ontinuousDumpConfig\x12\x15\n\rdump_phase_ms\x18\x05 \x01(\r\x12\x18\n\x10\x64ump_interval_ms\x18\x06 \x01(\rJ\x04\x08\x0c\x10\r\"\xfb\x02\n\x12ProcessSmapsConfig\x12\x32\n\x0csmaps_config\x18\x01 \x01(\x0b\x32\x1c.perfetto.protos.SmapsConfig\x12\x38\n\x05scope\x18\x02 \x01(\x0b\x32).perfetto.protos.ProcessSmapsConfig.Scope\x12\x16\n\x0eread_period_ms\x18\x03 \x01(\r\x12 \n\x18max_processes_per_period\x18\x04 \x01(\r\x1a\xbc\x01\n\x05Scope\x12\x16\n\x0etarget_cmdline\x18\x01 \x03(\t\x12\x46\n\ntarget_uid\x18\x02 \x03(\x0b\x32\x32.perfetto.protos.ProcessSmapsConfig.Scope.UidRange\x1aS\n\x08UidRange\x12\x0f\n\x07min_uid\x18\x01 \x01(\r\x12\x0f\n\x07max_uid\x18\x02 \x01(\r\x12%\n\x1d\x61ndroid_match_across_profiles\x18\x03 \x01(\x08\"\xe0\x03\n\x0bSmapsConfig\x12\x39\n\nvma_fields\x18\x01 \x03(\x0e\x32%.perfetto.protos.SmapsConfig.VmaField\x12\x14\n\x0cunaggregated\x18\x02 \x01(\x08\x12<\n\x14name_redaction_rules\x18\x03 \x03(\x0b\x32\x1e.perfetto.protos.RedactionRule\"\xc1\x02\n\x08VmaField\x12\x15\n\x11VMA_FIELD_UNKNOWN\x10\x00\x12\x12\n\x0eVMA_FIELD_SIZE\x10\x01\x12\x11\n\rVMA_FIELD_RSS\x10\x02\x12\x17\n\x13VMA_FIELD_ANONYMOUS\x10\x03\x12\x12\n\x0eVMA_FIELD_SWAP\x10\x04\x12\x1a\n\x16VMA_FIELD_SHARED_CLEAN\x10\x05\x12\x1a\n\x16VMA_FIELD_SHARED_DIRTY\x10\x06\x12\x1b\n\x17VMA_FIELD_PRIVATE_CLEAN\x10\x07\x12\x1b\n\x17VMA_FIELD_PRIVATE_DIRTY\x10\x08\x12\x14\n\x10VMA_FIELD_LOCKED\x10\t\x12\x11\n\rVMA_FIELD_PSS\x10\n\x12\x17\n\x13VMA_FIELD_PSS_DIRTY\x10\x0b\x12\x16\n\x12VMA_FIELD_SWAP_PSS\x10\x0c\"\xb6\x02\n\rRedactionRule\x12\x0f\n\x07pattern\x18\x01 \x01(\t\x12<\n\nmatch_mode\x18\x02 \x01(\x0e\x32(.perfetto.protos.RedactionRule.MatchMode\x12\x11\n\tkeep_full\x18\x03 \x01(\x08\x12\x18\n\x10replacement_name\x18\x04 \x01(\t\x12\x1b\n\x13keep_file_extension\x18\x05 \x01(\x08\x12\x1a\n\x12keep_path_elements\x18\x06 \x01(\r\"p\n\tMatchMode\x12\x16\n\x12MATCH_MODE_UNKNOWN\x10\x00\x12\x15\n\x11MATCH_MODE_PREFIX\x10\x01\x12\x18\n\x14MATCH_MODE_GLOB_PATH\x10\x02\x12\x1a\n\x16MATCH_MODE_GLOB_STRING\x10\x03\"\xd1\x03\n\x0fJavaHprofConfig\x12\x17\n\x0fprocess_cmdline\x18\x01 \x03(\t\x12\x0b\n\x03pid\x18\x02 \x03(\x04\x12\x1b\n\x13target_installed_by\x18\x07 \x03(\t\x12U\n\x16\x63ontinuous_dump_config\x18\x03 \x01(\x0b\x32\x35.perfetto.protos.JavaHprofConfig.ContinuousDumpConfig\x12\x1f\n\x17min_anonymous_memory_kb\x18\x04 \x01(\r\x12\x1d\n\x15min_java_heap_size_kb\x18\t \x01(\r\x12\x12\n\ndump_smaps\x18\x05 \x01(\x08\x12\x32\n\x0csmaps_config\x18\x08 \x01(\x0b\x32\x1c.perfetto.protos.SmapsConfig\x12\x15\n\rignored_types\x18\x06 \x03(\t\x12\x1b\n\x13\x64ump_oome_callstack\x18\n \x01(\x08\x1ah\n\x14\x43ontinuousDumpConfig\x12\x15\n\rdump_phase_ms\x18\x01 \x01(\r\x12\x18\n\x10\x64ump_interval_ms\x18\x02 \x01(\r\x12\x1f\n\x17scan_pids_only_on_start\x18\x03 \x01(\x08\"\xc9\n\n\nPerfEvents\x1a\x9d\x03\n\x08Timebase\x12\x13\n\tfrequency\x18\x02 \x01(\x04H\x00\x12\x10\n\x06period\x18\x01 \x01(\x04H\x00\x12\x18\n\x0epoll_period_ms\x18\x06 \x01(\rH\x00\x12\x36\n\x07\x63ounter\x18\x04 \x01(\x0e\x32#.perfetto.protos.PerfEvents.CounterH\x01\x12<\n\ntracepoint\x18\x03 \x01(\x0b\x32&.perfetto.protos.PerfEvents.TracepointH\x01\x12\x39\n\traw_event\x18\x05 \x01(\x0b\x32$.perfetto.protos.PerfEvents.RawEventH\x01\x12<\n\tmodifiers\x18\x0c \x03(\x0e\x32).perfetto.protos.PerfEvents.EventModifier\x12>\n\x0ftimestamp_clock\x18\x0b \x01(\x0e\x32%.perfetto.protos.PerfEvents.PerfClock\x12\x0c\n\x04name\x18\n \x01(\tB\n\n\x08intervalB\x07\n\x05\x65vent\x1a*\n\nTracepoint\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0e\n\x06\x66ilter\x18\x02 \x01(\t\x1a\\\n\x08RawEvent\x12\x0c\n\x04type\x18\x01 \x01(\r\x12\x0e\n\x06\x63onfig\x18\x02 \x01(\x04\x12\x0f\n\x07\x63onfig1\x18\x03 \x01(\x04\x12\x0f\n\x07\x63onfig2\x18\x04 \x01(\x04\x12\x10\n\x08pmu_name\x18\x05 \x01(\t\"\xe8\x03\n\x07\x43ounter\x12\x13\n\x0fUNKNOWN_COUNTER\x10\x00\x12\x10\n\x0cSW_CPU_CLOCK\x10\x01\x12\x12\n\x0eSW_PAGE_FAULTS\x10\x02\x12\x11\n\rSW_TASK_CLOCK\x10\x03\x12\x17\n\x13SW_CONTEXT_SWITCHES\x10\x04\x12\x15\n\x11SW_CPU_MIGRATIONS\x10\x05\x12\x16\n\x12SW_PAGE_FAULTS_MIN\x10\x06\x12\x16\n\x12SW_PAGE_FAULTS_MAJ\x10\x07\x12\x17\n\x13SW_ALIGNMENT_FAULTS\x10\x08\x12\x17\n\x13SW_EMULATION_FAULTS\x10\t\x12\x0c\n\x08SW_DUMMY\x10\x14\x12\x11\n\rHW_CPU_CYCLES\x10\n\x12\x13\n\x0fHW_INSTRUCTIONS\x10\x0b\x12\x17\n\x13HW_CACHE_REFERENCES\x10\x0c\x12\x13\n\x0fHW_CACHE_MISSES\x10\r\x12\x1a\n\x16HW_BRANCH_INSTRUCTIONS\x10\x0e\x12\x14\n\x10HW_BRANCH_MISSES\x10\x0f\x12\x11\n\rHW_BUS_CYCLES\x10\x10\x12\x1e\n\x1aHW_STALLED_CYCLES_FRONTEND\x10\x11\x12\x1d\n\x19HW_STALLED_CYCLES_BACKEND\x10\x12\x12\x15\n\x11HW_REF_CPU_CYCLES\x10\x13\"\x8d\x01\n\tPerfClock\x12\x16\n\x12UNKNOWN_PERF_CLOCK\x10\x00\x12\x17\n\x13PERF_CLOCK_REALTIME\x10\x01\x12\x18\n\x14PERF_CLOCK_MONOTONIC\x10\x02\x12\x1c\n\x18PERF_CLOCK_MONOTONIC_RAW\x10\x03\x12\x17\n\x13PERF_CLOCK_BOOTTIME\x10\x04\"\x95\x01\n\rEventModifier\x12\x1a\n\x16UNKNOWN_EVENT_MODIFIER\x10\x00\x12\"\n\x1e\x45VENT_MODIFIER_COUNT_USERSPACE\x10\x01\x12\x1f\n\x1b\x45VENT_MODIFIER_COUNT_KERNEL\x10\x02\x12#\n\x1f\x45VENT_MODIFIER_COUNT_HYPERVISOR\x10\x03\"\x95\x02\n\rFollowerEvent\x12\x36\n\x07\x63ounter\x18\x01 \x01(\x0e\x32#.perfetto.protos.PerfEvents.CounterH\x00\x12<\n\ntracepoint\x18\x02 \x01(\x0b\x32&.perfetto.protos.PerfEvents.TracepointH\x00\x12\x39\n\traw_event\x18\x03 \x01(\x0b\x32$.perfetto.protos.PerfEvents.RawEventH\x00\x12<\n\tmodifiers\x18\x05 \x03(\x0e\x32).perfetto.protos.PerfEvents.EventModifier\x12\x0c\n\x04name\x18\x04 \x01(\tB\x07\n\x05\x65vent\"\x85\t\n\x0fPerfEventConfig\x12\x36\n\x08timebase\x18\x0f \x01(\x0b\x32$.perfetto.protos.PerfEvents.Timebase\x12\x31\n\tfollowers\x18\x13 \x03(\x0b\x32\x1e.perfetto.protos.FollowerEvent\x12N\n\x12\x63\x61llstack_sampling\x18\x10 \x01(\x0b\x32\x32.perfetto.protos.PerfEventConfig.CallstackSampling\x12\x12\n\ntarget_cpu\x18\x14 \x03(\r\x12\x1b\n\x13ignore_open_failure\x18\x15 \x01(\x08\x12\r\n\x05\x63puid\x18\x16 \x03(\t\x12\"\n\x1aring_buffer_read_period_ms\x18\x08 \x01(\r\x12\x19\n\x11ring_buffer_pages\x18\x03 \x01(\r\x12!\n\x19max_enqueued_footprint_kb\x18\x11 \x01(\x04\x12\x1c\n\x14max_daemon_memory_kb\x18\r \x01(\r\x12$\n\x1cremote_descriptor_timeout_ms\x18\t \x01(\r\x12$\n\x1cunwind_state_clear_period_ms\x18\n \x01(\r\x12\x1b\n\x13target_installed_by\x18\x12 \x03(\t\x12\x10\n\x08\x61ll_cpus\x18\x01 \x01(\x08\x12\x1a\n\x12sampling_frequency\x18\x02 \x01(\r\x12\x15\n\rkernel_frames\x18\x0c \x01(\x08\x12\x12\n\ntarget_pid\x18\x04 \x03(\x05\x12\x16\n\x0etarget_cmdline\x18\x05 \x03(\t\x12\x13\n\x0b\x65xclude_pid\x18\x06 \x03(\x05\x12\x17\n\x0f\x65xclude_cmdline\x18\x07 \x03(\t\x12 \n\x18\x61\x64\x64itional_cmdline_count\x18\x0b \x01(\r\x1a\xa3\x01\n\x11\x43\x61llstackSampling\x12\x35\n\x05scope\x18\x01 \x01(\x0b\x32&.perfetto.protos.PerfEventConfig.Scope\x12\x15\n\rkernel_frames\x18\x02 \x01(\x08\x12@\n\x0buser_frames\x18\x03 \x01(\x0e\x32+.perfetto.protos.PerfEventConfig.UnwindMode\x1a\xa0\x01\n\x05Scope\x12\x12\n\ntarget_pid\x18\x01 \x03(\x05\x12\x16\n\x0etarget_cmdline\x18\x02 \x03(\t\x12\x13\n\x0b\x65xclude_pid\x18\x03 \x03(\x05\x12\x17\n\x0f\x65xclude_cmdline\x18\x04 \x03(\t\x12 \n\x18\x61\x64\x64itional_cmdline_count\x18\x05 \x01(\r\x12\x1b\n\x13process_shard_count\x18\x06 \x01(\r\"~\n\nUnwindMode\x12\x12\n\x0eUNWIND_UNKNOWN\x10\x00\x12\x0f\n\x0bUNWIND_SKIP\x10\x01\x12\x10\n\x0cUNWIND_DWARF\x10\x02\x12\x18\n\x14UNWIND_FRAME_POINTER\x10\x03\x12\x1f\n\x1bUNWIND_KERNEL_FRAME_POINTER\x10\x04J\x04\x08\x0e\x10\x0f\"(\n\rProtoVmConfig\x12\x17\n\x0fmemory_limit_kb\x18\x01 \x01(\r\"\xbf\x01\n\tQnxConfig\x12\x1a\n\x12qnx_kernel_buffers\x18\x01 \x01(\r\x12\x1b\n\x13qnx_kernel_kbuffers\x18\x02 \x01(\r\x12\x1e\n\x16qnx_kernel_wide_events\x18\x03 \x01(\x08\x12\x17\n\x0fqnx_cache_pages\x18\x04 \x01(\r\x12\x1b\n\x13qnx_cache_max_pages\x18\x05 \x01(\x05\x12#\n\x1bqnx_trace_buffer_init_bytes\x18\x06 \x01(\r\"\x9a\x01\n\x13StatsdTracingConfig\x12-\n\x0cpush_atom_id\x18\x01 \x03(\x0e\x32\x17.perfetto.protos.AtomId\x12\x18\n\x10raw_push_atom_id\x18\x02 \x03(\x05\x12:\n\x0bpull_config\x18\x03 \x03(\x0b\x32%.perfetto.protos.StatsdPullAtomConfig\"\x8c\x01\n\x14StatsdPullAtomConfig\x12-\n\x0cpull_atom_id\x18\x01 \x03(\x0e\x32\x17.perfetto.protos.AtomId\x12\x18\n\x10raw_pull_atom_id\x18\x02 \x03(\x05\x12\x19\n\x11pull_frequency_ms\x18\x03 \x01(\x05\x12\x10\n\x08packages\x18\x04 \x03(\t\"\x84\x05\n\x0eSysStatsConfig\x12\x19\n\x11meminfo_period_ms\x18\x01 \x01(\r\x12:\n\x10meminfo_counters\x18\x02 \x03(\x0e\x32 .perfetto.protos.MeminfoCounters\x12\x18\n\x10vmstat_period_ms\x18\x03 \x01(\r\x12\x38\n\x0fvmstat_counters\x18\x04 \x03(\x0e\x32\x1f.perfetto.protos.VmstatCounters\x12\x16\n\x0estat_period_ms\x18\x05 \x01(\r\x12\x43\n\rstat_counters\x18\x06 \x03(\x0e\x32,.perfetto.protos.SysStatsConfig.StatCounters\x12\x19\n\x11\x64\x65vfreq_period_ms\x18\x07 \x01(\r\x12\x19\n\x11\x63pufreq_period_ms\x18\x08 \x01(\r\x12\x1b\n\x13\x62uddyinfo_period_ms\x18\t \x01(\r\x12\x1a\n\x12\x64iskstat_period_ms\x18\n \x01(\r\x12\x15\n\rpsi_period_ms\x18\x0b \x01(\r\x12\x19\n\x11thermal_period_ms\x18\x0c \x01(\r\x12\x19\n\x11\x63puidle_period_ms\x18\r \x01(\r\x12\x19\n\x11gpufreq_period_ms\x18\x0e \x01(\r\x12\x16\n\x0eslab_period_ms\x18\x0f \x01(\r\"{\n\x0cStatCounters\x12\x14\n\x10STAT_UNSPECIFIED\x10\x00\x12\x12\n\x0eSTAT_CPU_TIMES\x10\x01\x12\x13\n\x0fSTAT_IRQ_COUNTS\x10\x02\x12\x17\n\x13STAT_SOFTIRQ_COUNTS\x10\x03\x12\x13\n\x0fSTAT_FORK_COUNT\x10\x04\"%\n\x10SystemInfoConfig\x12\x11\n\tirq_names\x18\x01 \x01(\x08\"\x8d\x04\n\nTestConfig\x12\x15\n\rmessage_count\x18\x01 \x01(\r\x12\x1f\n\x17max_messages_per_second\x18\x02 \x01(\r\x12\x0c\n\x04seed\x18\x03 \x01(\r\x12\x14\n\x0cmessage_size\x18\x04 \x01(\r\x12\x1e\n\x16send_batch_on_register\x18\x05 \x01(\x08\x12=\n\x0c\x64ummy_fields\x18\x06 \x01(\x0b\x32\'.perfetto.protos.TestConfig.DummyFields\x1a\xc3\x02\n\x0b\x44ummyFields\x12\x14\n\x0c\x66ield_uint32\x18\x01 \x01(\r\x12\x13\n\x0b\x66ield_int32\x18\x02 \x01(\x05\x12\x14\n\x0c\x66ield_uint64\x18\x03 \x01(\x04\x12\x13\n\x0b\x66ield_int64\x18\x04 \x01(\x03\x12\x15\n\rfield_fixed64\x18\x05 \x01(\x06\x12\x16\n\x0e\x66ield_sfixed64\x18\x06 \x01(\x10\x12\x15\n\rfield_fixed32\x18\x07 \x01(\x07\x12\x16\n\x0e\x66ield_sfixed32\x18\x08 \x01(\x0f\x12\x14\n\x0c\x66ield_double\x18\t \x01(\x01\x12\x13\n\x0b\x66ield_float\x18\n \x01(\x02\x12\x14\n\x0c\x66ield_sint64\x18\x0b \x01(\x12\x12\x14\n\x0c\x66ield_sint32\x18\x0c \x01(\x11\x12\x14\n\x0c\x66ield_string\x18\r \x01(\t\x12\x13\n\x0b\x66ield_bytes\x18\x0e \x01(\x0c\"\xd2\x02\n\x10TrackEventConfig\x12\x1b\n\x13\x64isabled_categories\x18\x01 \x03(\t\x12\x1a\n\x12\x65nabled_categories\x18\x02 \x03(\t\x12\x15\n\rdisabled_tags\x18\x03 \x03(\t\x12\x14\n\x0c\x65nabled_tags\x18\x04 \x03(\t\x12&\n\x1e\x64isable_incremental_timestamps\x18\x05 \x01(\x08\x12!\n\x19timestamp_unit_multiplier\x18\x06 \x01(\x04\x12 \n\x18\x66ilter_debug_annotations\x18\x07 \x01(\x08\x12#\n\x1b\x65nable_thread_time_sampling\x18\x08 \x01(\x08\x12\"\n\x1athread_time_subsampling_ns\x18\n \x01(\x04\x12\"\n\x1a\x66ilter_dynamic_event_names\x18\t \x01(\x08\"\xed$\n\x10\x44\x61taSourceConfig\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x15\n\rtarget_buffer\x18\x02 \x01(\r\x12\x1a\n\x12target_buffer_name\x18\x0b \x01(\t\x12\x19\n\x11trace_duration_ms\x18\x03 \x01(\r\x12)\n!prefer_suspend_clock_for_duration\x18z \x01(\x08\x12\x17\n\x0fstop_timeout_ms\x18\x07 \x01(\r\x12\x1f\n\x17\x65nable_extra_guardrails\x18\x06 \x01(\x08\x12M\n\x11session_initiator\x18\x08 \x01(\x0e\x32\x32.perfetto.protos.DataSourceConfig.SessionInitiator\x12\x1a\n\x12tracing_session_id\x18\x04 \x01(\x04\x12X\n\x17\x62uffer_exhausted_policy\x18\t \x01(\x0e\x32\x37.perfetto.protos.DataSourceConfig.BufferExhaustedPolicy\x12<\n\x0epriority_boost\x18\n \x01(\x0b\x32$.perfetto.protos.PriorityBoostConfig\x12\x36\n\x0eprotovm_config\x18\x0c \x01(\x0b\x32\x1e.perfetto.protos.ProtoVmConfig\x12\x1c\n\x13supports_tracing_v2\x18\x93\x01 \x01(\x08\x12_\n\x17\x65xperimental_tracing_v2\x18\x94\x01 \x01(\x0b\x32=.perfetto.protos.DataSourceConfig.ExperimentalTracingV2Config\x12\x38\n\rftrace_config\x18\x64 \x01(\x0b\x32\x1d.perfetto.protos.FtraceConfigB\x02(\x01\x12?\n\x11inode_file_config\x18\x66 \x01(\x0b\x32 .perfetto.protos.InodeFileConfigB\x02(\x01\x12\x45\n\x14process_stats_config\x18g \x01(\x0b\x32#.perfetto.protos.ProcessStatsConfigB\x02(\x01\x12=\n\x10sys_stats_config\x18h \x01(\x0b\x32\x1f.perfetto.protos.SysStatsConfigB\x02(\x01\x12>\n\x10heapprofd_config\x18i \x01(\x0b\x32 .perfetto.protos.HeapprofdConfigB\x02(\x01\x12?\n\x11java_hprof_config\x18n \x01(\x0b\x32 .perfetto.protos.JavaHprofConfigB\x02(\x01\x12\x45\n\x14\x61ndroid_power_config\x18j \x01(\x0b\x32#.perfetto.protos.AndroidPowerConfigB\x02(\x01\x12\x41\n\x12\x61ndroid_log_config\x18k \x01(\x0b\x32!.perfetto.protos.AndroidLogConfigB\x02(\x01\x12\x41\n\x12gpu_counter_config\x18l \x01(\x0b\x32!.perfetto.protos.GpuCounterConfigB\x02(\x01\x12\x65\n%android_game_intervention_list_config\x18t \x01(\x0b\x32\x32.perfetto.protos.AndroidGameInterventionListConfigB\x02(\x01\x12\x45\n\x14packages_list_config\x18m \x01(\x0b\x32#.perfetto.protos.PackagesListConfigB\x02(\x01\x12?\n\x11perf_event_config\x18o \x01(\x0b\x32 .perfetto.protos.PerfEventConfigB\x02(\x01\x12\x45\n\x14vulkan_memory_config\x18p \x01(\x0b\x32#.perfetto.protos.VulkanMemoryConfigB\x02(\x01\x12\x41\n\x12track_event_config\x18q \x01(\x0b\x32!.perfetto.protos.TrackEventConfigB\x02(\x01\x12R\n\x1b\x61ndroid_polled_state_config\x18r \x01(\x0b\x32).perfetto.protos.AndroidPolledStateConfigB\x02(\x01\x12X\n\x1e\x61ndroid_system_property_config\x18v \x01(\x0b\x32,.perfetto.protos.AndroidSystemPropertyConfigB\x02(\x01\x12G\n\x15statsd_tracing_config\x18u \x01(\x0b\x32$.perfetto.protos.StatsdTracingConfigB\x02(\x01\x12=\n\x12system_info_config\x18w \x01(\x0b\x32!.perfetto.protos.SystemInfoConfig\x12\x46\n\x14\x66rozen_ftrace_config\x18\x88\x01 \x01(\x0b\x32#.perfetto.protos.FrozenFtraceConfigB\x02(\x01\x12\x34\n\rchrome_config\x18\x65 \x01(\x0b\x32\x1d.perfetto.protos.ChromeConfig\x12\x30\n\tv8_config\x18\x7f \x01(\x0b\x32\x19.perfetto.protos.V8ConfigB\x02(\x01\x12>\n\x12interceptor_config\x18s \x01(\x0b\x32\".perfetto.protos.InterceptorConfig\x12R\n\x1bnetwork_packet_trace_config\x18x \x01(\x0b\x32).perfetto.protos.NetworkPacketTraceConfigB\x02(\x01\x12U\n\x1csurfaceflinger_layers_config\x18y \x01(\x0b\x32+.perfetto.protos.SurfaceFlingerLayersConfigB\x02(\x01\x12\x61\n\"surfaceflinger_transactions_config\x18{ \x01(\x0b\x32\x31.perfetto.protos.SurfaceFlingerTransactionsConfigB\x02(\x01\x12[\n android_sdk_sysprop_guard_config\x18| \x01(\x0b\x32-.perfetto.protos.AndroidSdkSyspropGuardConfigB\x02(\x01\x12\x32\n\netw_config\x18} \x01(\x0b\x32\x1a.perfetto.protos.EtwConfigB\x02(\x01\x12<\n\x0fprotolog_config\x18~ \x01(\x0b\x32\x1f.perfetto.protos.ProtoLogConfigB\x02(\x01\x12Q\n\x1a\x61ndroid_input_event_config\x18\x80\x01 \x01(\x0b\x32(.perfetto.protos.AndroidInputEventConfigB\x02(\x01\x12\x42\n\x12pixel_modem_config\x18\x81\x01 \x01(\x0b\x32!.perfetto.protos.PixelModemConfigB\x02(\x01\x12G\n\x14windowmanager_config\x18\x82\x01 \x01(\x0b\x32$.perfetto.protos.WindowManagerConfigB\x02(\x01\x12R\n\x17\x63hromium_system_metrics\x18\x83\x01 \x01(\x0b\x32,.perfetto.protos.ChromiumSystemMetricsConfigB\x02(\x01\x12L\n\x17kernel_wakelocks_config\x18\x84\x01 \x01(\x0b\x32&.perfetto.protos.KernelWakelocksConfigB\x02(\x01\x12L\n\x17gpu_renderstages_config\x18\x85\x01 \x01(\x0b\x32&.perfetto.protos.GpuRenderStagesConfigB\x02(\x01\x12X\n\x1a\x63hromium_histogram_samples\x18\x86\x01 \x01(\x0b\x32/.perfetto.protos.ChromiumHistogramSamplesConfigB\x02(\x01\x12\x46\n\x14\x61pp_wakelocks_config\x18\x87\x01 \x01(\x0b\x32#.perfetto.protos.AppWakelocksConfigB\x02(\x01\x12\x41\n\x12\x63pu_per_uid_config\x18\x89\x01 \x01(\x0b\x32 .perfetto.protos.CpuPerUidConfigB\x02(\x01\x12\x45\n\x10user_list_config\x18\x8a\x01 \x01(\x0b\x32&.perfetto.protos.AndroidUserListConfigB\x02(\x01\x12\x43\n\x12inputmethod_config\x18\x8b\x01 \x01(\x0b\x32\".perfetto.protos.InputMethodConfigB\x02(\x01\x12H\n\x15\x61ndroid_aflags_config\x18\x8c\x01 \x01(\x0b\x32$.perfetto.protos.AndroidAflagsConfigB\x02(\x01\x12\x44\n\x0fjournald_config\x18\x8d\x01 \x01(\x0b\x32&.perfetto.protos.SystemdJournaldConfigB\x02(\x01\x12\x46\n\x14\x64isplay_video_config\x18\x8e\x01 \x01(\x0b\x32#.perfetto.protos.DisplayVideoConfigB\x02(\x01\x12\x63\n chromium_stack_sampling_profiler\x18\x8f\x01 \x01(\x0b\x32\x34.perfetto.protos.ChromiumStackSamplingProfilerConfigB\x02(\x01\x12\x61\n\x1f\x63hromium_sampling_heap_profiler\x18\x90\x01 \x01(\x0b\x32\x33.perfetto.protos.ChromiumSamplingHeapProfilerConfigB\x02(\x01\x12U\n\x1c\x61ndroid_process_state_config\x18\x91\x01 \x01(\x0b\x32*.perfetto.protos.AndroidProcessStateConfigB\x02(\x01\x12\x46\n\x14process_smaps_config\x18\x92\x01 \x01(\x0b\x32#.perfetto.protos.ProcessSmapsConfigB\x02(\x01\x12\x33\n\nqnx_config\x18\x96\x01 \x01(\x0b\x32\x1a.perfetto.protos.QnxConfigB\x02(\x01\x12\x16\n\rlegacy_config\x18\xe8\x07 \x01(\t\x12\x31\n\x0b\x66or_testing\x18\xe9\x07 \x01(\x0b\x32\x1b.perfetto.protos.TestConfig\x1a\x84\x02\n\x1b\x45xperimentalTracingV2Config\x12\"\n\x1ause_v2_probability_percent\x18\x01 \x01(\r\x12i\n\x12\x63hunk_size_options\x18\x02 \x03(\x0b\x32M.perfetto.protos.DataSourceConfig.ExperimentalTracingV2Config.ChunkSizeOption\x12\x1f\n\x17\x64rain_occupancy_percent\x18\x03 \x01(\x05\x1a\x35\n\x0f\x43hunkSizeOption\x12\x12\n\nsize_bytes\x18\x01 \x01(\r\x12\x0e\n\x06weight\x18\x02 \x01(\r\"[\n\x10SessionInitiator\x12!\n\x1dSESSION_INITIATOR_UNSPECIFIED\x10\x00\x12$\n SESSION_INITIATOR_TRUSTED_SYSTEM\x10\x01\"\xa1\x01\n\x15\x42ufferExhaustedPolicy\x12 \n\x1c\x42UFFER_EXHAUSTED_UNSPECIFIED\x10\x00\x12\x19\n\x15\x42UFFER_EXHAUSTED_DROP\x10\x01\x12%\n!BUFFER_EXHAUSTED_STALL_THEN_ABORT\x10\x02\x12$\n BUFFER_EXHAUSTED_STALL_THEN_DROP\x10\x03J\x0b\x08\xff\xff\xff\x7f\x10\x80\x80\x80\x80\x01\"\xbb.\n\x0bTraceConfig\x12:\n\x07\x62uffers\x18\x01 \x03(\x0b\x32).perfetto.protos.TraceConfig.BufferConfig\x12/\n\'experimental_trace_buffer_v2_compaction\x18\x32 \x01(\x08\x12=\n\x0c\x64\x61ta_sources\x18\x02 \x03(\x0b\x32\'.perfetto.protos.TraceConfig.DataSource\x12L\n\x14\x62uiltin_data_sources\x18\x14 \x01(\x0b\x32..perfetto.protos.TraceConfig.BuiltinDataSource\x12\x13\n\x0b\x64uration_ms\x18\x03 \x01(\r\x12)\n!prefer_suspend_clock_for_duration\x18$ \x01(\x08\x12\x1f\n\x17\x65nable_extra_guardrails\x18\x04 \x01(\x08\x12I\n\rlockdown_mode\x18\x05 \x01(\x0e\x32\x32.perfetto.protos.TraceConfig.LockdownModeOperation\x12>\n\tproducers\x18\x06 \x03(\x0b\x32+.perfetto.protos.TraceConfig.ProducerConfig\x12\x44\n\x0fstatsd_metadata\x18\x07 \x01(\x0b\x32+.perfetto.protos.TraceConfig.StatsdMetadata\x12\x17\n\x0fwrite_into_file\x18\x08 \x01(\x08\x12\x13\n\x0boutput_path\x18\x1d \x01(\t\x12\x1c\n\x14\x66ile_write_period_ms\x18\t \x01(\r\x12\x1b\n\x13max_file_size_bytes\x18\n \x01(\x04\x12L\n\x13guardrail_overrides\x18\x0b \x01(\x0b\x32/.perfetto.protos.TraceConfig.GuardrailOverrides\x12\x16\n\x0e\x64\x65\x66\x65rred_start\x18\x0c \x01(\x08\x12\x17\n\x0f\x66lush_period_ms\x18\r \x01(\r\x12\x18\n\x10\x66lush_timeout_ms\x18\x0e \x01(\r\x12#\n\x1b\x64\x61ta_source_stop_timeout_ms\x18\x17 \x01(\r\x12\x16\n\x0enotify_traceur\x18\x10 \x01(\x08\x12\x17\n\x0f\x62ugreport_score\x18\x1e \x01(\x05\x12\x1a\n\x12\x62ugreport_filename\x18& \x01(\t\x12\x42\n\x0etrigger_config\x18\x11 \x01(\x0b\x32*.perfetto.protos.TraceConfig.TriggerConfig\x12\x19\n\x11\x61\x63tivate_triggers\x18\x12 \x03(\t\x12U\n\x18incremental_state_config\x18\x15 \x01(\x0b\x32\x33.perfetto.protos.TraceConfig.IncrementalStateConfig\x12$\n\x18\x61llow_user_build_tracing\x18\x13 \x01(\x08\x42\x02\x18\x01\x12\x1b\n\x13unique_session_name\x18\x16 \x01(\t\x12J\n\x10\x63ompression_type\x18\x18 \x01(\x0e\x32,.perfetto.protos.TraceConfig.CompressionTypeB\x02\x18\x01\x12\x43\n\x0b\x63ompression\x18/ \x01(\x0b\x32..perfetto.protos.TraceConfig.CompressionConfig\x12Q\n\x16incident_report_config\x18\x19 \x01(\x0b\x32\x31.perfetto.protos.TraceConfig.IncidentReportConfig\x12\x42\n\x0estatsd_logging\x18\x1f \x01(\x0e\x32*.perfetto.protos.TraceConfig.StatsdLogging\x12\x1a\n\x0etrace_uuid_msb\x18\x1b \x01(\x03\x42\x02\x18\x01\x12\x1a\n\x0etrace_uuid_lsb\x18\x1c \x01(\x03\x42\x02\x18\x01\x12>\n\x0ctrace_filter\x18! \x01(\x0b\x32(.perfetto.protos.TraceConfig.TraceFilter\x12O\n\x15\x61ndroid_report_config\x18\" \x01(\x0b\x32\x30.perfetto.protos.TraceConfig.AndroidReportConfig\x12N\n\x15\x63md_trace_start_delay\x18# \x01(\x0b\x32/.perfetto.protos.TraceConfig.CmdTraceStartDelay\x12I\n\x12session_semaphores\x18\' \x03(\x0b\x32-.perfetto.protos.TraceConfig.SessionSemaphore\x12<\n\x0epriority_boost\x18( \x01(\x0b\x32$.perfetto.protos.PriorityBoostConfig\x12\x16\n\x0e\x65xclusive_prio\x18) \x01(\r\x12\x45\n\x10write_flush_mode\x18, \x01(\x0e\x32+.perfetto.protos.TraceConfig.WriteFlushMode\x12\x42\n\x11\x66\x66lush_post_write\x18- \x01(\x0e\x32\'.perfetto.protos.TraceConfig.FFlushMode\x12\x1a\n\x12trace_all_machines\x18+ \x01(\x08\x12:\n\x10trace_attributes\x18\x30 \x01(\x0b\x32 .perfetto.protos.TraceAttributes\x12$\n\x1cpersist_trace_across_reboots\x18\x31 \x01(\x08\x1a\x94\x03\n\x0c\x42ufferConfig\x12\x0f\n\x07size_kb\x18\x01 \x01(\r\x12I\n\x0b\x66ill_policy\x18\x04 \x01(\x0e\x32\x34.perfetto.protos.TraceConfig.BufferConfig.FillPolicy\x12\x19\n\x11transfer_on_clone\x18\x05 \x01(\x08\x12\x1a\n\x12\x63lear_before_clone\x18\x06 \x01(\x08\x12\x0c\n\x04name\x18\x07 \x01(\t\x12U\n\x11\x65xperimental_mode\x18\x08 \x01(\x0e\x32:.perfetto.protos.TraceConfig.BufferConfig.ExperimentalMode\";\n\nFillPolicy\x12\x0f\n\x0bUNSPECIFIED\x10\x00\x12\x0f\n\x0bRING_BUFFER\x10\x01\x12\x0b\n\x07\x44ISCARD\x10\x02\"C\n\x10\x45xperimentalMode\x12\x14\n\x10MODE_UNSPECIFIED\x10\x00\x12\x13\n\x0fTRACE_BUFFER_V2\x10\x01\"\x04\x08\x02\x10\x02J\x04\x08\x02\x10\x03J\x04\x08\x03\x10\x04\x1a\x9e\x01\n\nDataSource\x12\x31\n\x06\x63onfig\x18\x01 \x01(\x0b\x32!.perfetto.protos.DataSourceConfig\x12\x1c\n\x14producer_name_filter\x18\x02 \x03(\t\x12\"\n\x1aproducer_name_regex_filter\x18\x03 \x03(\t\x12\x1b\n\x13machine_name_filter\x18\x04 \x03(\t\x1a\x90\x03\n\x11\x42uiltinDataSource\x12\"\n\x1a\x64isable_clock_snapshotting\x18\x01 \x01(\x08\x12\x1c\n\x14\x64isable_trace_config\x18\x02 \x01(\x08\x12\x1b\n\x13\x64isable_system_info\x18\x03 \x01(\x08\x12\x1e\n\x16\x64isable_service_events\x18\x04 \x01(\x08\x12:\n\x13primary_trace_clock\x18\x05 \x01(\x0e\x32\x1d.perfetto.protos.BuiltinClock\x12\x1c\n\x14snapshot_interval_ms\x18\x06 \x01(\r\x12)\n!prefer_suspend_clock_for_snapshot\x18\x07 \x01(\x08\x12&\n\x1e\x64isable_chunk_usage_histograms\x18\x08 \x01(\x08\x12%\n\x1d\x64isable_extension_descriptors\x18\t \x01(\x08\x12(\n enable_concurrent_session_events\x18\n \x01(\x08\x1aR\n\x0eProducerConfig\x12\x15\n\rproducer_name\x18\x01 \x01(\t\x12\x13\n\x0bshm_size_kb\x18\x02 \x01(\r\x12\x14\n\x0cpage_size_kb\x18\x03 \x01(\r\x1a\x8e\x01\n\x0eStatsdMetadata\x12\x1b\n\x13triggering_alert_id\x18\x01 \x01(\x03\x12\x1d\n\x15triggering_config_uid\x18\x02 \x01(\x05\x12\x1c\n\x14triggering_config_id\x18\x03 \x01(\x03\x12\"\n\x1atriggering_subscription_id\x18\x04 \x01(\x03\x1a^\n\x12GuardrailOverrides\x12$\n\x18max_upload_per_day_bytes\x18\x01 \x01(\x04\x42\x02\x18\x01\x12\"\n\x1amax_tracing_buffer_size_kb\x18\x02 \x01(\r\x1a\xca\x03\n\rTriggerConfig\x12L\n\x0ctrigger_mode\x18\x01 \x01(\x0e\x32\x36.perfetto.protos.TraceConfig.TriggerConfig.TriggerMode\x12\'\n\x1fuse_clone_snapshot_if_available\x18\x05 \x01(\x08\x12\x44\n\x08triggers\x18\x02 \x03(\x0b\x32\x32.perfetto.protos.TraceConfig.TriggerConfig.Trigger\x12\x1a\n\x12trigger_timeout_ms\x18\x03 \x01(\r\x1a{\n\x07Trigger\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x1b\n\x13producer_name_regex\x18\x02 \x01(\t\x12\x15\n\rstop_delay_ms\x18\x03 \x01(\r\x12\x14\n\x0cmax_per_24_h\x18\x04 \x01(\r\x12\x18\n\x10skip_probability\x18\x05 \x01(\x01\"]\n\x0bTriggerMode\x12\x0f\n\x0bUNSPECIFIED\x10\x00\x12\x11\n\rSTART_TRACING\x10\x01\x12\x10\n\x0cSTOP_TRACING\x10\x02\x12\x12\n\x0e\x43LONE_SNAPSHOT\x10\x04\"\x04\x08\x03\x10\x03J\x04\x08\x04\x10\x05\x1a\x31\n\x16IncrementalStateConfig\x12\x17\n\x0f\x63lear_period_ms\x18\x01 \x01(\r\x1a\xc1\x01\n\x11\x43ompressionConfig\x12G\n\x07\x64\x65\x66late\x18\x01 \x01(\x0b\x32\x36.perfetto.protos.TraceConfig.CompressionConfig.Deflate\x12\x41\n\x04zstd\x18\x02 \x01(\x0b\x32\x33.perfetto.protos.TraceConfig.CompressionConfig.Zstd\x1a\t\n\x07\x44\x65\x66late\x1a\x15\n\x04Zstd\x12\r\n\x05level\x18\x01 \x01(\x05\x1a\x97\x01\n\x14IncidentReportConfig\x12\x1b\n\x13\x64\x65stination_package\x18\x01 \x01(\t\x12\x19\n\x11\x64\x65stination_class\x18\x02 \x01(\t\x12\x15\n\rprivacy_level\x18\x03 \x01(\x05\x12\x16\n\x0eskip_incidentd\x18\x05 \x01(\x08\x12\x18\n\x0cskip_dropbox\x18\x04 \x01(\x08\x42\x02\x18\x01\x1a\x94\x06\n\x0bTraceFilter\x12\x10\n\x08\x62ytecode\x18\x01 \x01(\x0c\x12\x13\n\x0b\x62ytecode_v2\x18\x02 \x01(\x0c\x12W\n\x13string_filter_chain\x18\x03 \x01(\x0b\x32:.perfetto.protos.TraceConfig.TraceFilter.StringFilterChain\x12\x1c\n\x14\x62ytecode_overlay_v54\x18\x04 \x01(\x0c\x12[\n\x17string_filter_chain_v54\x18\x05 \x01(\x0b\x32:.perfetto.protos.TraceConfig.TraceFilter.StringFilterChain\x1a\xde\x01\n\x10StringFilterRule\x12K\n\x06policy\x18\x01 \x01(\x0e\x32;.perfetto.protos.TraceConfig.TraceFilter.StringFilterPolicy\x12\x15\n\rregex_pattern\x18\x02 \x01(\t\x12\"\n\x1a\x61trace_payload_starts_with\x18\x03 \x01(\t\x12\x0c\n\x04name\x18\x04 \x01(\t\x12\x34\n\rsemantic_type\x18\x05 \x03(\x0e\x32\x1d.perfetto.protos.SemanticType\x1a]\n\x11StringFilterChain\x12H\n\x05rules\x18\x01 \x03(\x0b\x32\x39.perfetto.protos.TraceConfig.TraceFilter.StringFilterRule\"\xc9\x01\n\x12StringFilterPolicy\x12\x13\n\x0fSFP_UNSPECIFIED\x10\x00\x12\x1b\n\x17SFP_MATCH_REDACT_GROUPS\x10\x01\x12\"\n\x1eSFP_ATRACE_MATCH_REDACT_GROUPS\x10\x02\x12\x13\n\x0fSFP_MATCH_BREAK\x10\x03\x12\x1a\n\x16SFP_ATRACE_MATCH_BREAK\x10\x04\x12,\n(SFP_ATRACE_REPEATED_SEARCH_REDACT_GROUPS\x10\x05\x1a\x97\x01\n\x13\x41ndroidReportConfig\x12 \n\x18reporter_service_package\x18\x01 \x01(\t\x12\x1e\n\x16reporter_service_class\x18\x02 \x01(\t\x12\x13\n\x0bskip_report\x18\x03 \x01(\x08\x12)\n!use_pipe_in_framework_for_testing\x18\x04 \x01(\x08\x1a@\n\x12\x43mdTraceStartDelay\x12\x14\n\x0cmin_delay_ms\x18\x01 \x01(\r\x12\x14\n\x0cmax_delay_ms\x18\x02 \x01(\r\x1a\x41\n\x10SessionSemaphore\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x1f\n\x17max_other_session_count\x18\x02 \x01(\x04\"U\n\x15LockdownModeOperation\x12\x16\n\x12LOCKDOWN_UNCHANGED\x10\x00\x12\x12\n\x0eLOCKDOWN_CLEAR\x10\x01\x12\x10\n\x0cLOCKDOWN_SET\x10\x02\"Q\n\x0f\x43ompressionType\x12 \n\x1c\x43OMPRESSION_TYPE_UNSPECIFIED\x10\x00\x12\x1c\n\x18\x43OMPRESSION_TYPE_DEFLATE\x10\x01\"h\n\rStatsdLogging\x12\x1e\n\x1aSTATSD_LOGGING_UNSPECIFIED\x10\x00\x12\x1a\n\x16STATSD_LOGGING_ENABLED\x10\x01\x12\x1b\n\x17STATSD_LOGGING_DISABLED\x10\x02\"v\n\x0eWriteFlushMode\x12\x1b\n\x17WRITE_FLUSH_UNSPECIFIED\x10\x00\x12\x14\n\x10WRITE_FLUSH_AUTO\x10\x01\x12\x18\n\x14WRITE_FLUSH_DISABLED\x10\x02\x12\x17\n\x13WRITE_FLUSH_ENABLED\x10\x03\"M\n\nFFlushMode\x12\x16\n\x12\x46\x46LUSH_UNSPECIFIED\x10\x00\x12\x13\n\x0f\x46\x46LUSH_DISABLED\x10\x01\x12\x12\n\x0e\x46\x46LUSH_ENABLED\x10\x02J\x04\x08\x0f\x10\x10J\x04\x08%\x10&J\x04\x08\x1a\x10\x1bJ\x04\x08 \x10!J\x04\x08*\x10+J\x04\x08.\x10/R\x05notes\"M\n\x07Utsname\x12\x0f\n\x07sysname\x18\x01 \x01(\t\x12\x0f\n\x07version\x18\x02 \x01(\t\x12\x0f\n\x07release\x18\x03 \x01(\t\x12\x0f\n\x07machine\x18\x04 \x01(\t\"\x93\x04\n\nSystemInfo\x12)\n\x07utsname\x18\x01 \x01(\x0b\x32\x18.perfetto.protos.Utsname\x12!\n\x19\x61ndroid_build_fingerprint\x18\x02 \x01(\t\x12#\n\x1b\x61ndroid_device_manufacturer\x18\x0e \x01(\t\x12\x19\n\x11\x61ndroid_soc_model\x18\t \x01(\t\x12\x1f\n\x17\x64\x65vice_tree_compatibles\x18\x12 \x03(\t\x12\x1f\n\x17\x61ndroid_guest_soc_model\x18\r \x01(\t\x12!\n\x19\x61ndroid_hardware_revision\x18\n \x01(\t\x12\x1d\n\x15\x61ndroid_storage_model\x18\x0b \x01(\t\x12\x19\n\x11\x61ndroid_ram_model\x18\x0c \x01(\t\x12\x1e\n\x16\x61ndroid_serial_console\x18\x0f \x01(\t\x12\x1f\n\x17tracing_service_version\x18\x04 \x01(\t\x12\x1b\n\x13\x61ndroid_sdk_version\x18\x05 \x01(\x04\x12\x11\n\tpage_size\x18\x06 \x01(\r\x12\x10\n\x08num_cpus\x18\x08 \x01(\r\x12\x19\n\x11timezone_off_mins\x18\x07 \x01(\x05\x12\n\n\x02hz\x18\x03 \x01(\x03\x12\x18\n\x10system_ram_bytes\x18\x10 \x01(\x04\x12\x14\n\x0cmachine_name\x18\x11 \x01(\t\"\x86\r\n\nTraceStats\x12=\n\x0c\x62uffer_stats\x18\x01 \x03(\x0b\x32\'.perfetto.protos.TraceStats.BufferStats\x12#\n\x1b\x63hunk_payload_histogram_def\x18\x11 \x03(\x03\x12=\n\x0cwriter_stats\x18\x12 \x03(\x0b\x32\'.perfetto.protos.TraceStats.WriterStats\x12\x1b\n\x13producers_connected\x18\x02 \x01(\r\x12\x16\n\x0eproducers_seen\x18\x03 \x01(\x04\x12\x1f\n\x17\x64\x61ta_sources_registered\x18\x04 \x01(\r\x12\x19\n\x11\x64\x61ta_sources_seen\x18\x05 \x01(\x04\x12\x18\n\x10tracing_sessions\x18\x06 \x01(\r\x12\x15\n\rtotal_buffers\x18\x07 \x01(\r\x12\x18\n\x10\x63hunks_discarded\x18\x08 \x01(\x04\x12\x19\n\x11patches_discarded\x18\t \x01(\x04\x12\x17\n\x0finvalid_packets\x18\n \x01(\x04\x12=\n\x0c\x66ilter_stats\x18\x0b \x01(\x0b\x32\'.perfetto.protos.TraceStats.FilterStats\x12\x19\n\x11\x66lushes_requested\x18\x0c \x01(\x04\x12\x19\n\x11\x66lushes_succeeded\x18\r \x01(\x04\x12\x16\n\x0e\x66lushes_failed\x18\x0e \x01(\x04\x12J\n\x13\x66inal_flush_outcome\x18\x0f \x01(\x0e\x32-.perfetto.protos.TraceStats.FinalFlushOutcome\x1a\xff\x04\n\x0b\x42ufferStats\x12\x13\n\x0b\x62uffer_size\x18\x0c \x01(\x04\x12\x15\n\rbytes_written\x18\x01 \x01(\x04\x12\x19\n\x11\x62ytes_overwritten\x18\r \x01(\x04\x12\x12\n\nbytes_read\x18\x0e \x01(\x04\x12\x1d\n\x15padding_bytes_written\x18\x0f \x01(\x04\x12\x1d\n\x15padding_bytes_cleared\x18\x10 \x01(\x04\x12\x16\n\x0e\x63hunks_written\x18\x02 \x01(\x04\x12\x18\n\x10\x63hunks_rewritten\x18\n \x01(\x04\x12\x18\n\x10\x63hunks_relocated\x18\x14 \x01(\x04\x12\x1a\n\x12\x63hunks_overwritten\x18\x03 \x01(\x04\x12\x18\n\x10\x63hunks_discarded\x18\x12 \x01(\x04\x12\x13\n\x0b\x63hunks_read\x18\x11 \x01(\x04\x12%\n\x1d\x63hunks_committed_out_of_order\x18\x0b \x01(\x04\x12\x18\n\x10write_wrap_count\x18\x04 \x01(\x04\x12\x13\n\x0b\x63ompactions\x18\x17 \x01(\x04\x12\x1b\n\x13\x63ompactions_skipped\x18\x18 \x01(\x04\x12\x19\n\x11patches_succeeded\x18\x05 \x01(\x04\x12\x16\n\x0epatches_failed\x18\x06 \x01(\x04\x12\x1c\n\x14readaheads_succeeded\x18\x07 \x01(\x04\x12\x19\n\x11readaheads_failed\x18\x08 \x01(\x04\x12\x16\n\x0e\x61\x62i_violations\x18\t \x01(\x04\x12 \n\x18trace_writer_packet_loss\x18\x13 \x01(\x04\x12!\n\x19oversized_packets_dropped\x18\x16 \x01(\x04J\x04\x08\x15\x10\x16\x1a\x87\x01\n\x0bWriterStats\x12\x13\n\x0bsequence_id\x18\x01 \x01(\x04\x12\x0e\n\x06\x62uffer\x18\x04 \x01(\r\x12*\n\x1e\x63hunk_payload_histogram_counts\x18\x02 \x03(\x04\x42\x02\x10\x01\x12\'\n\x1b\x63hunk_payload_histogram_sum\x18\x03 \x03(\x03\x42\x02\x10\x01\x1a\x9a\x01\n\x0b\x46ilterStats\x12\x15\n\rinput_packets\x18\x01 \x01(\x04\x12\x13\n\x0binput_bytes\x18\x02 \x01(\x04\x12\x14\n\x0coutput_bytes\x18\x03 \x01(\x04\x12\x0e\n\x06\x65rrors\x18\x04 \x01(\x04\x12\x15\n\rtime_taken_ns\x18\x05 \x01(\x04\x12\"\n\x1a\x62ytes_discarded_per_buffer\x18\x14 \x03(\x04\"c\n\x11\x46inalFlushOutcome\x12\x1b\n\x17\x46INAL_FLUSH_UNSPECIFIED\x10\x00\x12\x19\n\x15\x46INAL_FLUSH_SUCCEEDED\x10\x01\x12\x16\n\x12\x46INAL_FLUSH_FAILED\x10\x02\"\xd6\x07\n\rAndroidAflags\x12\x32\n\x05\x66lags\x18\x01 \x03(\x0b\x32#.perfetto.protos.AndroidAflags.Flag\x12\r\n\x05\x65rror\x18\x02 \x01(\t\x1a\x82\x03\n\x04\x46lag\x12\x16\n\x0e\x66lag_namespace\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x0b\n\x03pkg\x18\x03 \x01(\t\x12\x11\n\tcontainer\x18\x04 \x01(\t\x12\r\n\x05value\x18\x05 \x01(\t\x12\x14\n\x0cstaged_value\x18\x06 \x01(\t\x12\x41\n\npermission\x18\x07 \x01(\x0e\x32-.perfetto.protos.AndroidAflags.FlagPermission\x12I\n\x11value_picked_from\x18\x08 \x01(\x0e\x32..perfetto.protos.AndroidAflags.ValuePickedFrom\x12J\n\x0fstorage_backend\x18\t \x01(\x0e\x32\x31.perfetto.protos.AndroidAflags.FlagStorageBackend\x12\x35\n\x04type\x18\n \x01(\x0e\x32\'.perfetto.protos.AndroidAflags.FlagType\"p\n\x0e\x46lagPermission\x12\x1f\n\x1b\x46LAG_PERMISSION_UNSPECIFIED\x10\x00\x12\x1d\n\x19\x46LAG_PERMISSION_READ_ONLY\x10\x01\x12\x1e\n\x1a\x46LAG_PERMISSION_READ_WRITE\x10\x02\"\x8e\x01\n\x0fValuePickedFrom\x12!\n\x1dVALUE_PICKED_FROM_UNSPECIFIED\x10\x00\x12\x1d\n\x19VALUE_PICKED_FROM_DEFAULT\x10\x01\x12\x1c\n\x18VALUE_PICKED_FROM_SERVER\x10\x02\x12\x1b\n\x17VALUE_PICKED_FROM_LOCAL\x10\x03\"\xa4\x01\n\x12\x46lagStorageBackend\x12$\n FLAG_STORAGE_BACKEND_UNSPECIFIED\x10\x00\x12\x1d\n\x19\x46LAG_STORAGE_BACKEND_NONE\x10\x01\x12!\n\x1d\x46LAG_STORAGE_BACKEND_ACONFIGD\x10\x02\x12&\n\"FLAG_STORAGE_BACKEND_DEVICE_CONFIG\x10\x03\"S\n\x08\x46lagType\x12\x19\n\x15\x46LAG_TYPE_UNSPECIFIED\x10\x00\x12\x15\n\x11\x46LAG_TYPE_BOOLEAN\x10\x01\x12\x15\n\x11\x46LAG_TYPE_INTEGER\x10\x02\"\x8f\x03\n\x1b\x41ndroidGameInterventionList\x12S\n\rgame_packages\x18\x01 \x03(\x0b\x32<.perfetto.protos.AndroidGameInterventionList.GamePackageInfo\x12\x13\n\x0bparse_error\x18\x02 \x01(\x08\x12\x12\n\nread_error\x18\x03 \x01(\x08\x1aZ\n\x0cGameModeInfo\x12\x0c\n\x04mode\x18\x01 \x01(\r\x12\x11\n\tuse_angle\x18\x02 \x01(\x08\x12\x1c\n\x14resolution_downscale\x18\x03 \x01(\x02\x12\x0b\n\x03\x66ps\x18\x04 \x01(\x02\x1a\x95\x01\n\x0fGamePackageInfo\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0b\n\x03uid\x18\x02 \x01(\x04\x12\x14\n\x0c\x63urrent_mode\x18\x03 \x01(\r\x12Q\n\x0egame_mode_info\x18\x04 \x03(\x0b\x32\x39.perfetto.protos.AndroidGameInterventionList.GameModeInfo\"\xb2\x04\n\x10\x41ndroidLogPacket\x12:\n\x06\x65vents\x18\x01 \x03(\x0b\x32*.perfetto.protos.AndroidLogPacket.LogEvent\x12\x36\n\x05stats\x18\x02 \x01(\x0b\x32\'.perfetto.protos.AndroidLogPacket.Stats\x1a\xe4\x02\n\x08LogEvent\x12-\n\x06log_id\x18\x01 \x01(\x0e\x32\x1d.perfetto.protos.AndroidLogId\x12\x0b\n\x03pid\x18\x02 \x01(\x05\x12\x0b\n\x03tid\x18\x03 \x01(\x05\x12\x0b\n\x03uid\x18\x04 \x01(\x05\x12\x11\n\ttimestamp\x18\x05 \x01(\x04\x12\x0b\n\x03tag\x18\x06 \x01(\t\x12\x31\n\x04prio\x18\x07 \x01(\x0e\x32#.perfetto.protos.AndroidLogPriority\x12\x0f\n\x07message\x18\x08 \x01(\t\x12<\n\x04\x61rgs\x18\t \x03(\x0b\x32..perfetto.protos.AndroidLogPacket.LogEvent.Arg\x1a`\n\x03\x41rg\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x13\n\tint_value\x18\x02 \x01(\x03H\x00\x12\x15\n\x0b\x66loat_value\x18\x03 \x01(\x02H\x00\x12\x16\n\x0cstring_value\x18\x04 \x01(\tH\x00\x42\x07\n\x05value\x1a\x43\n\x05Stats\x12\x11\n\tnum_total\x18\x01 \x01(\x04\x12\x12\n\nnum_failed\x18\x02 \x01(\x04\x12\x13\n\x0bnum_skipped\x18\x03 \x01(\x04\"\x8b\x01\n\x15\x41ndroidSystemProperty\x12\x44\n\x06values\x18\x01 \x03(\x0b\x32\x34.perfetto.protos.AndroidSystemProperty.PropertyValue\x1a,\n\rPropertyValue\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t\"R\n\rCpuPerUidData\x12\x15\n\rcluster_count\x18\x01 \x01(\r\x12\x0f\n\x03uid\x18\x02 \x03(\rB\x02\x10\x01\x12\x19\n\rtotal_time_ms\x18\x03 \x03(\x04\x42\x02\x10\x01\"\xf1\x03\n\x12GraphicsFrameEvent\x12\x45\n\x0c\x62uffer_event\x18\x01 \x01(\x0b\x32/.perfetto.protos.GraphicsFrameEvent.BufferEvent\x1a\xa2\x01\n\x0b\x42ufferEvent\x12\x14\n\x0c\x66rame_number\x18\x01 \x01(\r\x12\x41\n\x04type\x18\x02 \x01(\x0e\x32\x33.perfetto.protos.GraphicsFrameEvent.BufferEventType\x12\x12\n\nlayer_name\x18\x03 \x01(\t\x12\x13\n\x0b\x64uration_ns\x18\x04 \x01(\x04\x12\x11\n\tbuffer_id\x18\x05 \x01(\r\"\xee\x01\n\x0f\x42ufferEventType\x12\x0f\n\x0bUNSPECIFIED\x10\x00\x12\x0b\n\x07\x44\x45QUEUE\x10\x01\x12\t\n\x05QUEUE\x10\x02\x12\x08\n\x04POST\x10\x03\x12\x11\n\rACQUIRE_FENCE\x10\x04\x12\t\n\x05LATCH\x10\x05\x12\x1a\n\x16HWC_COMPOSITION_QUEUED\x10\x06\x12\x18\n\x14\x46\x41LLBACK_COMPOSITION\x10\x07\x12\x11\n\rPRESENT_FENCE\x10\x08\x12\x11\n\rRELEASE_FENCE\x10\t\x12\n\n\x06MODIFY\x10\n\x12\n\n\x06\x44\x45TACH\x10\x0b\x12\n\n\x06\x41TTACH\x10\x0c\x12\n\n\x06\x43\x41NCEL\x10\r\"@\n\x13InitialDisplayState\x12\x15\n\rdisplay_state\x18\x01 \x01(\x05\x12\x12\n\nbrightness\x18\x02 \x01(\x01\"\xfa\x02\n\x12KernelWakelockData\x12>\n\x08wakelock\x18\x01 \x03(\x0b\x32,.perfetto.protos.KernelWakelockData.Wakelock\x12\x17\n\x0bwakelock_id\x18\x02 \x03(\rB\x02\x10\x01\x12\x1c\n\x10time_held_millis\x18\x03 \x03(\x04\x42\x02\x10\x01\x12\x13\n\x0b\x65rror_flags\x18\x04 \x01(\x04\x1a\xd7\x01\n\x08Wakelock\x12\x13\n\x0bwakelock_id\x18\x01 \x01(\r\x12\x15\n\rwakelock_name\x18\x02 \x01(\t\x12H\n\rwakelock_type\x18\x03 \x01(\x0e\x32\x31.perfetto.protos.KernelWakelockData.Wakelock.Type\"U\n\x04Type\x12\x19\n\x15WAKELOCK_TYPE_UNKNOWN\x10\x00\x12\x18\n\x14WAKELOCK_TYPE_KERNEL\x10\x01\x12\x18\n\x14WAKELOCK_TYPE_NATIVE\x10\x02\"\xfe\x01\n\x0cPackagesList\x12;\n\x08packages\x18\x01 \x03(\x0b\x32).perfetto.protos.PackagesList.PackageInfo\x12\x13\n\x0bparse_error\x18\x02 \x01(\x08\x12\x12\n\nread_error\x18\x03 \x01(\x08\x1a\x87\x01\n\x0bPackageInfo\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0b\n\x03uid\x18\x02 \x01(\x04\x12\x12\n\ndebuggable\x18\x03 \x01(\x08\x12\x1e\n\x16profileable_from_shell\x18\x04 \x01(\x08\x12\x14\n\x0cversion_code\x18\x05 \x01(\x03\x12\x13\n\x0bprofileable\x18\x06 \x01(\x08\"<\n\x10PixelModemEvents\x12\x0e\n\x06\x65vents\x18\x01 \x03(\x0c\x12\x18\n\x10\x65vent_time_nanos\x18\x02 \x03(\x04\"+\n\x17PixelModemTokenDatabase\x12\x10\n\x08\x64\x61tabase\x18\x01 \x01(\x0c\"\xcb\x01\n\x12RecoveredTraceInfo\x12:\n\x06reason\x18\x01 \x01(\x0e\x32*.perfetto.protos.RecoveredTraceInfo.Reason\x12 \n\x18original_file_size_bytes\x18\x02 \x01(\x04\x12\x17\n\x0f\x62ytes_truncated\x18\x03 \x01(\x04\">\n\x06Reason\x12\x16\n\x12REASON_UNSPECIFIED\x10\x00\x12\x1c\n\x18REASON_UNEXPECTED_REBOOT\x10\x01\"\x81\x01\n\x0f\x41ndroidUserList\x12\x38\n\x05users\x18\x01 \x03(\x0b\x32).perfetto.protos.AndroidUserList.UserInfo\x12\r\n\x05\x65rror\x18\x02 \x01(\x05\x1a%\n\x08UserInfo\x12\x0c\n\x04type\x18\x01 \x01(\t\x12\x0b\n\x03uid\x18\x02 \x01(\x05\"\xf2\x01\n\x17\x43hromeBenchmarkMetadata\x12\x1f\n\x17\x62\x65nchmark_start_time_us\x18\x01 \x01(\x03\x12\x19\n\x11story_run_time_us\x18\x02 \x01(\x03\x12\x16\n\x0e\x62\x65nchmark_name\x18\x03 \x01(\t\x12\x1d\n\x15\x62\x65nchmark_description\x18\x04 \x01(\t\x12\r\n\x05label\x18\x05 \x01(\t\x12\x12\n\nstory_name\x18\x06 \x01(\t\x12\x12\n\nstory_tags\x18\x07 \x03(\t\x12\x17\n\x0fstory_run_index\x18\x08 \x01(\x05\x12\x14\n\x0chad_failures\x18\t \x01(\x08\"\xe8\x02\n\x14\x43hromeMetadataPacket\x12O\n\x1b\x62\x61\x63kground_tracing_metadata\x18\x01 \x01(\x0b\x32*.perfetto.protos.BackgroundTracingMetadata\x12\x1b\n\x13\x63hrome_version_code\x18\x02 \x01(\x05\x12\x1a\n\x12\x65nabled_categories\x18\x03 \x01(\t\x12K\n\x12\x66ield_trial_hashes\x18\x04 \x03(\x0b\x32/.perfetto.protos.ChromeMetadataPacket.FinchHash\x12\x18\n\x10\x61pp_package_name\x18\x05 \x01(\t\x12\x13\n\x0b\x61pp_version\x18\x06 \x01(\t\x12\x0f\n\x07\x63hannel\x18\x07 \x01(\r\x12\x0f\n\x07os_name\x18\x08 \x01(\t\x1a(\n\tFinchHash\x12\x0c\n\x04name\x18\x01 \x01(\r\x12\r\n\x05group\x18\x02 \x01(\r\"\x95\x08\n\x19\x42\x61\x63kgroundTracingMetadata\x12N\n\x0etriggered_rule\x18\x01 \x01(\x0b\x32\x36.perfetto.protos.BackgroundTracingMetadata.TriggerRule\x12L\n\x0c\x61\x63tive_rules\x18\x02 \x03(\x0b\x32\x36.perfetto.protos.BackgroundTracingMetadata.TriggerRule\x12\x1a\n\x12scenario_name_hash\x18\x03 \x01(\x07\x1a\xbd\x06\n\x0bTriggerRule\x12X\n\x0ctrigger_type\x18\x01 \x01(\x0e\x32\x42.perfetto.protos.BackgroundTracingMetadata.TriggerRule.TriggerType\x12\\\n\x0ehistogram_rule\x18\x02 \x01(\x0b\x32\x44.perfetto.protos.BackgroundTracingMetadata.TriggerRule.HistogramRule\x12T\n\nnamed_rule\x18\x03 \x01(\x0b\x32@.perfetto.protos.BackgroundTracingMetadata.TriggerRule.NamedRule\x12\x11\n\tname_hash\x18\x04 \x01(\x07\x1aj\n\rHistogramRule\x12\x1b\n\x13histogram_name_hash\x18\x01 \x01(\x06\x12\x1d\n\x15histogram_min_trigger\x18\x02 \x01(\x03\x12\x1d\n\x15histogram_max_trigger\x18\x03 \x01(\x03\x1a\x96\x02\n\tNamedRule\x12^\n\nevent_type\x18\x01 \x01(\x0e\x32J.perfetto.protos.BackgroundTracingMetadata.TriggerRule.NamedRule.EventType\x12!\n\x19\x63ontent_trigger_name_hash\x18\x02 \x01(\x06\"\x85\x01\n\tEventType\x12\x0f\n\x0bUNSPECIFIED\x10\x00\x12\x13\n\x0fSESSION_RESTORE\x10\x01\x12\x0e\n\nNAVIGATION\x10\x02\x12\x0b\n\x07STARTUP\x10\x03\x12\x10\n\x0cREACHED_CODE\x10\x04\x12\x13\n\x0f\x43ONTENT_TRIGGER\x10\x05\x12\x0e\n\tTEST_RULE\x10\xe8\x07\"\x87\x01\n\x0bTriggerType\x12\x17\n\x13TRIGGER_UNSPECIFIED\x10\x00\x12\x36\n2MONITOR_AND_DUMP_WHEN_SPECIFIC_HISTOGRAM_AND_VALUE\x10\x01\x12\'\n#MONITOR_AND_DUMP_WHEN_TRIGGER_NAMED\x10\x02\"\xd3\x02\n\x11\x43hromeTracedValue\x12\x42\n\x0bnested_type\x18\x01 \x01(\x0e\x32-.perfetto.protos.ChromeTracedValue.NestedType\x12\x11\n\tdict_keys\x18\x02 \x03(\t\x12\x37\n\x0b\x64ict_values\x18\x03 \x03(\x0b\x32\".perfetto.protos.ChromeTracedValue\x12\x38\n\x0c\x61rray_values\x18\x04 \x03(\x0b\x32\".perfetto.protos.ChromeTracedValue\x12\x11\n\tint_value\x18\x05 \x01(\x05\x12\x14\n\x0c\x64ouble_value\x18\x06 \x01(\x01\x12\x12\n\nbool_value\x18\x07 \x01(\x08\x12\x14\n\x0cstring_value\x18\x08 \x01(\t\"!\n\nNestedType\x12\x08\n\x04\x44ICT\x10\x00\x12\t\n\x05\x41RRAY\x10\x01\"6\n\x16\x43hromeStringTableEntry\x12\r\n\x05value\x18\x01 \x01(\t\x12\r\n\x05index\x18\x02 \x01(\x05\"\x81\x05\n\x10\x43hromeTraceEvent\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x11\n\ttimestamp\x18\x02 \x01(\x03\x12\r\n\x05phase\x18\x03 \x01(\x05\x12\x11\n\tthread_id\x18\x04 \x01(\x05\x12\x10\n\x08\x64uration\x18\x05 \x01(\x03\x12\x17\n\x0fthread_duration\x18\x06 \x01(\x03\x12\r\n\x05scope\x18\x07 \x01(\t\x12\n\n\x02id\x18\x08 \x01(\x04\x12\r\n\x05\x66lags\x18\t \x01(\r\x12\x1b\n\x13\x63\x61tegory_group_name\x18\n \x01(\t\x12\x12\n\nprocess_id\x18\x0b \x01(\x05\x12\x18\n\x10thread_timestamp\x18\x0c \x01(\x03\x12\x0f\n\x07\x62ind_id\x18\r \x01(\x04\x12\x33\n\x04\x61rgs\x18\x0e \x03(\x0b\x32%.perfetto.protos.ChromeTraceEvent.Arg\x12\x12\n\nname_index\x18\x0f \x01(\r\x12!\n\x19\x63\x61tegory_group_name_index\x18\x10 \x01(\r\x1a\x8c\x02\n\x03\x41rg\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x14\n\nbool_value\x18\x02 \x01(\x08H\x00\x12\x14\n\nuint_value\x18\x03 \x01(\x04H\x00\x12\x13\n\tint_value\x18\x04 \x01(\x03H\x00\x12\x16\n\x0c\x64ouble_value\x18\x05 \x01(\x01H\x00\x12\x16\n\x0cstring_value\x18\x06 \x01(\tH\x00\x12\x17\n\rpointer_value\x18\x07 \x01(\x04H\x00\x12\x14\n\njson_value\x18\x08 \x01(\tH\x00\x12:\n\x0ctraced_value\x18\n \x01(\x0b\x32\".perfetto.protos.ChromeTracedValueH\x00\x12\x12\n\nname_index\x18\t \x01(\rB\x07\n\x05value\"\x80\x01\n\x0e\x43hromeMetadata\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x16\n\x0cstring_value\x18\x02 \x01(\tH\x00\x12\x14\n\nbool_value\x18\x03 \x01(\x08H\x00\x12\x13\n\tint_value\x18\x04 \x01(\x03H\x00\x12\x14\n\njson_value\x18\x05 \x01(\tH\x00\x42\x07\n\x05value\"\x94\x01\n\x15\x43hromeLegacyJsonTrace\x12>\n\x04type\x18\x01 \x01(\x0e\x32\x30.perfetto.protos.ChromeLegacyJsonTrace.TraceType\x12\x0c\n\x04\x64\x61ta\x18\x02 \x01(\t\"-\n\tTraceType\x12\x0e\n\nUSER_TRACE\x10\x00\x12\x10\n\x0cSYSTEM_TRACE\x10\x01\"\xa7\x02\n\x11\x43hromeEventBundle\x12;\n\x0ctrace_events\x18\x01 \x03(\x0b\x32!.perfetto.protos.ChromeTraceEventB\x02\x18\x01\x12\x31\n\x08metadata\x18\x02 \x03(\x0b\x32\x1f.perfetto.protos.ChromeMetadata\x12\x1c\n\x14legacy_ftrace_output\x18\x04 \x03(\t\x12\x41\n\x11legacy_json_trace\x18\x05 \x03(\x0b\x32&.perfetto.protos.ChromeLegacyJsonTrace\x12\x41\n\x0cstring_table\x18\x03 \x03(\x0b\x32\'.perfetto.protos.ChromeStringTableEntryB\x02\x18\x01\"Q\n\rChromeTrigger\x12\x14\n\x0ctrigger_name\x18\x01 \x01(\t\x12\x19\n\x11trigger_name_hash\x18\x02 \x01(\x07\x12\x0f\n\x07\x66low_id\x18\x03 \x01(\x06\"V\n\x08V8String\x12\x10\n\x06latin1\x18\x01 \x01(\x0cH\x00\x12\x12\n\x08utf16_le\x18\x02 \x01(\x0cH\x00\x12\x12\n\x08utf16_be\x18\x03 \x01(\x0cH\x00\x42\x10\n\x0e\x65ncoded_string\"k\n\x10InternedV8String\x12\x0b\n\x03iid\x18\x01 \x01(\x04\x12\x10\n\x06latin1\x18\x02 \x01(\x0cH\x00\x12\x12\n\x08utf16_le\x18\x03 \x01(\x0cH\x00\x12\x12\n\x08utf16_be\x18\x04 \x01(\x0cH\x00\x42\x10\n\x0e\x65ncoded_string\"\xc5\x02\n\x12InternedV8JsScript\x12\x0b\n\x03iid\x18\x01 \x01(\x04\x12\x11\n\tscript_id\x18\x02 \x01(\x05\x12\x36\n\x04type\x18\x03 \x01(\x0e\x32(.perfetto.protos.InternedV8JsScript.Type\x12\'\n\x04name\x18\x04 \x01(\x0b\x32\x19.perfetto.protos.V8String\x12)\n\x06source\x18\x05 \x01(\x0b\x32\x19.perfetto.protos.V8String\"\x82\x01\n\x04Type\x12\x10\n\x0cTYPE_UNKNOWN\x10\x00\x12\x0f\n\x0bTYPE_NORMAL\x10\x01\x12\r\n\tTYPE_EVAL\x10\x02\x12\x0f\n\x0bTYPE_MODULE\x10\x03\x12\x0f\n\x0bTYPE_NATIVE\x10\x04\x12\x12\n\x0eTYPE_EXTENSION\x10\x05\x12\x12\n\x0eTYPE_INSPECTOR\x10\x06\"W\n\x14InternedV8WasmScript\x12\x0b\n\x03iid\x18\x01 \x01(\x04\x12\x11\n\tscript_id\x18\x02 \x01(\x05\x12\x0b\n\x03url\x18\x03 \x01(\t\x12\x12\n\nwire_bytes\x18\x04 \x01(\x0c\"\xd5\x08\n\x14InternedV8JsFunction\x12\x0b\n\x03iid\x18\x01 \x01(\x04\x12\x1f\n\x17v8_js_function_name_iid\x18\x02 \x01(\x04\x12\x18\n\x10v8_js_script_iid\x18\x03 \x01(\x04\x12\x13\n\x0bis_toplevel\x18\x04 \x01(\x08\x12\x38\n\x04kind\x18\x05 \x01(\x0e\x32*.perfetto.protos.InternedV8JsFunction.Kind\x12\x13\n\x0b\x62yte_offset\x18\x06 \x01(\r\x12\x0c\n\x04line\x18\x07 \x01(\r\x12\x0e\n\x06\x63olumn\x18\x08 \x01(\r\"\xf2\x06\n\x04Kind\x12\x10\n\x0cKIND_UNKNOWN\x10\x00\x12\x18\n\x14KIND_NORMAL_FUNCTION\x10\x01\x12\x0f\n\x0bKIND_MODULE\x10\x02\x12\x15\n\x11KIND_ASYNC_MODULE\x10\x03\x12\x19\n\x15KIND_BASE_CONSTRUCTOR\x10\x04\x12!\n\x1dKIND_DEFAULT_BASE_CONSTRUCTOR\x10\x05\x12$\n KIND_DEFAULT_DERIVED_CONSTRUCTOR\x10\x06\x12\x1c\n\x18KIND_DERIVED_CONSTRUCTOR\x10\x07\x12\x18\n\x14KIND_GETTER_FUNCTION\x10\x08\x12\x1f\n\x1bKIND_STATIC_GETTER_FUNCTION\x10\t\x12\x18\n\x14KIND_SETTER_FUNCTION\x10\n\x12\x1f\n\x1bKIND_STATIC_SETTER_FUNCTION\x10\x0b\x12\x17\n\x13KIND_ARROW_FUNCTION\x10\x0c\x12\x1d\n\x19KIND_ASYNC_ARROW_FUNCTION\x10\r\x12\x17\n\x13KIND_ASYNC_FUNCTION\x10\x0e\x12\x1d\n\x19KIND_ASYNC_CONCISE_METHOD\x10\x0f\x12$\n KIND_STATIC_ASYNC_CONCISE_METHOD\x10\x10\x12\'\n#KIND_ASYNC_CONCISE_GENERATOR_METHOD\x10\x11\x12.\n*KIND_STATIC_ASYNC_CONCISE_GENERATOR_METHOD\x10\x12\x12!\n\x1dKIND_ASYNC_GENERATOR_FUNCTION\x10\x13\x12\x1b\n\x17KIND_GENERATOR_FUNCTION\x10\x14\x12!\n\x1dKIND_CONCISE_GENERATOR_METHOD\x10\x15\x12(\n$KIND_STATIC_CONCISE_GENERATOR_METHOD\x10\x16\x12\x17\n\x13KIND_CONCISE_METHOD\x10\x17\x12\x1e\n\x1aKIND_STATIC_CONCISE_METHOD\x10\x18\x12+\n\'KIND_CLASS_MEMBERS_INITIALIZER_FUNCTION\x10\x19\x12*\n&KIND_CLASS_STATIC_INITIALIZER_FUNCTION\x10\x1a\x12\x10\n\x0cKIND_INVALID\x10\x1b\"\xc7\x02\n\x11InternedV8Isolate\x12\x0b\n\x03iid\x18\x01 \x01(\x04\x12\x0b\n\x03pid\x18\x02 \x01(\r\x12\x12\n\nisolate_id\x18\x03 \x01(\x05\x12@\n\ncode_range\x18\x04 \x01(\x0b\x32,.perfetto.protos.InternedV8Isolate.CodeRange\x12(\n embedded_blob_code_start_address\x18\x05 \x01(\x04\x12\x1f\n\x17\x65mbedded_blob_code_size\x18\x06 \x01(\x04\x1aw\n\tCodeRange\x12\x14\n\x0c\x62\x61se_address\x18\x01 \x01(\x04\x12\x0c\n\x04size\x18\x02 \x01(\x04\x12-\n%embedded_blob_code_copy_start_address\x18\x03 \x01(\x04\x12\x17\n\x0fis_process_wide\x18\x04 \x01(\x08\"\xd8\x03\n\x08V8JsCode\x12\x16\n\x0ev8_isolate_iid\x18\x01 \x01(\x04\x12\x0b\n\x03tid\x18\x02 \x01(\r\x12\x1a\n\x12v8_js_function_iid\x18\x03 \x01(\x04\x12,\n\x04tier\x18\x04 \x01(\x0e\x32\x1e.perfetto.protos.V8JsCode.Tier\x12\x19\n\x11instruction_start\x18\x05 \x01(\x04\x12\x1e\n\x16instruction_size_bytes\x18\x06 \x01(\x04\x12\x16\n\x0cmachine_code\x18\x07 \x01(\x0cH\x00\x12\x12\n\x08\x62ytecode\x18\x08 \x01(\x0cH\x00\x12\x1a\n\x10source_positions\x18\t \x01(\x0cH\x01\x12\x1c\n\x12\x62ytecode_positions\x18\n \x01(\x0cH\x01\x12$\n\x1ainlined_bytecode_positions\x18\x0b \x01(\x0cH\x01\"x\n\x04Tier\x12\x10\n\x0cTIER_UNKNOWN\x10\x00\x12\x11\n\rTIER_IGNITION\x10\x01\x12\x12\n\x0eTIER_SPARKPLUG\x10\x02\x12\x0f\n\x0bTIER_MAGLEV\x10\x03\x12\x13\n\x0fTIER_TURBOSHAFT\x10\x04\x12\x11\n\rTIER_TURBOFAN\x10\x05\x42\x0e\n\x0cinstructionsB\x0c\n\nsource_map\"\xe1\x03\n\x0eV8InternalCode\x12\x16\n\x0ev8_isolate_iid\x18\x01 \x01(\x04\x12\x0b\n\x03tid\x18\x02 \x01(\r\x12\x0c\n\x04name\x18\x03 \x01(\t\x12\x32\n\x04type\x18\x04 \x01(\x0e\x32$.perfetto.protos.V8InternalCode.Type\x12\x12\n\nbuiltin_id\x18\x05 \x01(\x05\x12\x19\n\x11instruction_start\x18\x06 \x01(\x04\x12\x1e\n\x16instruction_size_bytes\x18\x07 \x01(\x04\x12\x14\n\x0cmachine_code\x18\x08 \x01(\x0c\"\x82\x02\n\x04Type\x12\x10\n\x0cTYPE_UNKNOWN\x10\x00\x12\x19\n\x15TYPE_BYTECODE_HANDLER\x10\x01\x12\x14\n\x10TYPE_FOR_TESTING\x10\x02\x12\x10\n\x0cTYPE_BUILTIN\x10\x03\x12\x16\n\x12TYPE_WASM_FUNCTION\x10\x04\x12\x1e\n\x1aTYPE_WASM_TO_CAPI_FUNCTION\x10\x05\x12\x1c\n\x18TYPE_WASM_TO_JS_FUNCTION\x10\x06\x12\x1c\n\x18TYPE_JS_TO_WASM_FUNCTION\x10\x07\x12\x1a\n\x16TYPE_JS_TO_JS_FUNCTION\x10\x08\x12\x15\n\x11TYPE_C_WASM_ENTRY\x10\t\"\xc3\x02\n\nV8WasmCode\x12\x16\n\x0ev8_isolate_iid\x18\x01 \x01(\x04\x12\x0b\n\x03tid\x18\x02 \x01(\r\x12\x1a\n\x12v8_wasm_script_iid\x18\x03 \x01(\x04\x12\x15\n\rfunction_name\x18\x04 \x01(\t\x12.\n\x04tier\x18\x05 \x01(\x0e\x32 .perfetto.protos.V8WasmCode.Tier\x12\x1d\n\x15\x63ode_offset_in_module\x18\x06 \x01(\x05\x12\x19\n\x11instruction_start\x18\x07 \x01(\x04\x12\x1e\n\x16instruction_size_bytes\x18\x08 \x01(\x04\x12\x14\n\x0cmachine_code\x18\t \x01(\x0c\"=\n\x04Tier\x12\x10\n\x0cTIER_UNKNOWN\x10\x00\x12\x10\n\x0cTIER_LIFTOFF\x10\x01\x12\x11\n\rTIER_TURBOFAN\x10\x02\"\xb0\x01\n\x0cV8RegExpCode\x12\x16\n\x0ev8_isolate_iid\x18\x01 \x01(\x04\x12\x0b\n\x03tid\x18\x02 \x01(\r\x12*\n\x07pattern\x18\x03 \x01(\x0b\x32\x19.perfetto.protos.V8String\x12\x19\n\x11instruction_start\x18\x04 \x01(\x04\x12\x1e\n\x16instruction_size_bytes\x18\x05 \x01(\x04\x12\x14\n\x0cmachine_code\x18\x06 \x01(\x0c\"\xe1\x01\n\nV8CodeMove\x12\x13\n\x0bisolate_iid\x18\x01 \x01(\x04\x12\x0b\n\x03tid\x18\x02 \x01(\r\x12&\n\x1e\x66rom_instruction_start_address\x18\x03 \x01(\x04\x12$\n\x1cto_instruction_start_address\x18\x04 \x01(\x04\x12\x1e\n\x16instruction_size_bytes\x18\x05 \x01(\x04\x12\x19\n\x0fto_machine_code\x18\x06 \x01(\x0cH\x00\x12\x15\n\x0bto_bytecode\x18\x07 \x01(\x0cH\x00\x42\x11\n\x0fto_instructions\"\x1d\n\x0eV8CodeDefaults\x12\x0b\n\x03tid\x18\x01 \x01(\r\"\x92\x03\n\rClockSnapshot\x12\x34\n\x06\x63locks\x18\x01 \x03(\x0b\x32$.perfetto.protos.ClockSnapshot.Clock\x12:\n\x13primary_trace_clock\x18\x02 \x01(\x0e\x32\x1d.perfetto.protos.BuiltinClock\x1a\x8e\x02\n\x05\x43lock\x12\x10\n\x08\x63lock_id\x18\x01 \x01(\r\x12\x11\n\ttimestamp\x18\x02 \x01(\x04\x12\x16\n\x0eis_incremental\x18\x03 \x01(\x08\x12\x1a\n\x12unit_multiplier_ns\x18\x04 \x01(\x04\"\xab\x01\n\rBuiltinClocks\x12\x0b\n\x07UNKNOWN\x10\x00\x12\x0c\n\x08REALTIME\x10\x01\x12\x13\n\x0fREALTIME_COARSE\x10\x02\x12\r\n\tMONOTONIC\x10\x03\x12\x14\n\x10MONOTONIC_COARSE\x10\x04\x12\x11\n\rMONOTONIC_RAW\x10\x05\x12\x0c\n\x08\x42OOTTIME\x10\x06\x12\x18\n\x14\x42UILTIN_CLOCK_MAX_ID\x10?\"\x04\x08\x07\x10\x07\"\x04\x08\x08\x10\x08\"\xd2\x0c\n\x0f\x43SwitchEtwEvent\x12\x15\n\rnew_thread_id\x18\x01 \x01(\r\x12\x15\n\rold_thread_id\x18\x02 \x01(\r\x12\x1b\n\x13new_thread_priority\x18\x03 \x01(\x11\x12\x1b\n\x13old_thread_priority\x18\x04 \x01(\x11\x12\x18\n\x10previous_c_state\x18\x05 \x01(\r\x12V\n\x16old_thread_wait_reason\x18\x06 \x01(\x0e\x32\x34.perfetto.protos.CSwitchEtwEvent.OldThreadWaitReasonH\x00\x12$\n\x1aold_thread_wait_reason_int\x18\x0b \x01(\x05H\x00\x12R\n\x14old_thread_wait_mode\x18\x07 \x01(\x0e\x32\x32.perfetto.protos.CSwitchEtwEvent.OldThreadWaitModeH\x01\x12\"\n\x18old_thread_wait_mode_int\x18\x0c \x01(\x05H\x01\x12K\n\x10old_thread_state\x18\x08 \x01(\x0e\x32/.perfetto.protos.CSwitchEtwEvent.OldThreadStateH\x02\x12\x1e\n\x14old_thread_state_int\x18\r \x01(\x11H\x02\x12\'\n\x1fold_thread_wait_ideal_processor\x18\t \x01(\x11\x12\x1c\n\x14new_thread_wait_time\x18\n \x01(\r\"\xe9\x05\n\x13OldThreadWaitReason\x12\r\n\tEXECUTIVE\x10\x00\x12\r\n\tFREE_PAGE\x10\x01\x12\x0b\n\x07PAGE_IN\x10\x02\x12\x13\n\x0fPOOL_ALLOCATION\x10\x03\x12\x13\n\x0f\x44\x45LAY_EXECUTION\x10\x04\x12\x0b\n\x07SUSPEND\x10\x05\x12\x10\n\x0cUSER_REQUEST\x10\x06\x12\x10\n\x0cWR_EXECUTIVE\x10\x07\x12\x10\n\x0cWR_FREE_PAGE\x10\x08\x12\x0e\n\nWR_PAGE_IN\x10\t\x12\x16\n\x12WR_POOL_ALLOCATION\x10\n\x12\x16\n\x12WR_DELAY_EXECUTION\x10\x0b\x12\x10\n\x0cWR_SUSPENDED\x10\x0c\x12\x13\n\x0fWR_USER_REQUEST\x10\r\x12\x11\n\rWR_EVENT_PAIR\x10\x0e\x12\x0c\n\x08WR_QUEUE\x10\x0f\x12\x13\n\x0fWR_LPC_RECEIVER\x10\x10\x12\x10\n\x0cWR_LPC_REPLY\x10\x11\x12\x15\n\x11WR_VIRTUAL_MEMORY\x10\x12\x12\x0f\n\x0bWR_PAGE_OUT\x10\x13\x12\x12\n\x0eWR_RENDEZ_VOUS\x10\x14\x12\x12\n\x0eWR_KEYED_EVENT\x10\x15\x12\x11\n\rWR_TERMINATED\x10\x16\x12\x16\n\x12WR_PROCESS_IN_SWAP\x10\x17\x12\x17\n\x13WR_CPU_RATE_CONTROL\x10\x18\x12\x14\n\x10WR_CALLOUT_STACK\x10\x19\x12\r\n\tWR_KERNEL\x10\x1a\x12\x0f\n\x0bWR_RESOURCE\x10\x1b\x12\x10\n\x0cWR_PUSH_LOCK\x10\x1c\x12\x0c\n\x08WR_MUTEX\x10\x1d\x12\x12\n\x0eWR_QUANTUM_END\x10\x1e\x12\x13\n\x0fWR_DISPATCH_INT\x10\x1f\x12\x10\n\x0cWR_PREEMPTED\x10 \x12\x16\n\x12WR_YIELD_EXECUTION\x10!\x12\x11\n\rWR_FAST_MUTEX\x10\"\x12\x12\n\x0eWR_GUARD_MUTEX\x10#\x12\x0e\n\nWR_RUNDOWN\x10$\x12\x17\n\x13MAXIMUM_WAIT_REASON\x10%\"3\n\x11OldThreadWaitMode\x12\x0f\n\x0bKERNEL_MODE\x10\x00\x12\r\n\tUSER_MODE\x10\x01\"\x87\x01\n\x0eOldThreadState\x12\x0f\n\x0bINITIALIZED\x10\x00\x12\t\n\x05READY\x10\x01\x12\x0b\n\x07RUNNING\x10\x02\x12\x0b\n\x07STANDBY\x10\x03\x12\x0e\n\nTERMINATED\x10\x04\x12\x0b\n\x07WAITING\x10\x05\x12\x0e\n\nTRANSITION\x10\x06\x12\x12\n\x0e\x44\x45\x46\x45RRED_READY\x10\x07\x42$\n\"old_thread_wait_reason_enum_or_intB\"\n old_thread_wait_mode_enum_or_intB\x1e\n\x1cold_thread_state_enum_or_int\"\x88\x04\n\x13ReadyThreadEtwEvent\x12\x13\n\x0bt_thread_id\x18\x01 \x01(\r\x12J\n\radjust_reason\x18\x02 \x01(\x0e\x32\x31.perfetto.protos.ReadyThreadEtwEvent.AdjustReasonH\x00\x12\x1b\n\x11\x61\x64just_reason_int\x18\x05 \x01(\x05H\x00\x12\x18\n\x10\x61\x64just_increment\x18\x03 \x01(\x11\x12>\n\x04\x66lag\x18\x04 \x01(\x0e\x32..perfetto.protos.ReadyThreadEtwEvent.TraceFlagH\x01\x12\x12\n\x08\x66lag_int\x18\x06 \x01(\x05H\x01\"X\n\x0c\x41\x64justReason\x12\x18\n\x14IGNORE_THE_INCREMENT\x10\x00\x12\x13\n\x0f\x41PPLY_INCREMENT\x10\x01\x12\x19\n\x15\x41PPLY_INCREMENT_BOOST\x10\x02\"z\n\tTraceFlag\x12\x1a\n\x16TRACE_FLAG_UNSPECIFIED\x10\x00\x12\x12\n\x0eTHREAD_READIED\x10\x01\x12\x1c\n\x18KERNEL_STACK_SWAPPED_OUT\x10\x02\x12\x1f\n\x1bPROCESS_ADDRESS_SWAPPED_OUT\x10\x04\x42\x1b\n\x19\x61\x64just_reason_enum_or_intB\x12\n\x10\x66lag_enum_or_int\"\x90\x03\n\x0fMemInfoEtwEvent\x12\x17\n\x0fpriority_levels\x18\x01 \x01(\r\x12\x17\n\x0fzero_page_count\x18\x02 \x01(\x04\x12\x17\n\x0f\x66ree_page_count\x18\x03 \x01(\x04\x12\x1b\n\x13modified_page_count\x18\x04 \x01(\x04\x12$\n\x1cmodified_no_write_page_count\x18\x05 \x01(\x04\x12\x16\n\x0e\x62\x61\x64_page_count\x18\x06 \x01(\x04\x12\x1b\n\x13standby_page_counts\x18\x07 \x03(\x04\x12\x1e\n\x16repurposed_page_counts\x18\x08 \x03(\x04\x12%\n\x1dmodified_page_count_page_file\x18\t \x01(\x04\x12\x1d\n\x15paged_pool_page_count\x18\n \x01(\x04\x12!\n\x19non_paged_pool_page_count\x18\x0b \x01(\x04\x12\x16\n\x0emdl_page_count\x18\x0c \x01(\x04\x12\x19\n\x11\x63ommit_page_count\x18\r \x01(\x04\"\xa4\x01\n\x14\x46ileIoCreateEtwEvent\x12\x0f\n\x07irp_ptr\x18\x01 \x01(\x04\x12\x13\n\x0b\x66ile_object\x18\x02 \x01(\x04\x12\x0c\n\x04ttid\x18\x03 \x01(\r\x12\x16\n\x0e\x63reate_options\x18\x04 \x01(\r\x12\x17\n\x0f\x66ile_attributes\x18\x05 \x01(\r\x12\x14\n\x0cshare_access\x18\x06 \x01(\r\x12\x11\n\topen_path\x18\x07 \x01(\t\"\xb8\x01\n\x15\x46ileIoDirEnumEtwEvent\x12\x0f\n\x07irp_ptr\x18\x01 \x01(\x04\x12\x13\n\x0b\x66ile_object\x18\x02 \x01(\x04\x12\x10\n\x08\x66ile_key\x18\x03 \x01(\x04\x12\x0c\n\x04ttid\x18\x04 \x01(\r\x12\x0e\n\x06length\x18\x05 \x01(\r\x12\x12\n\ninfo_class\x18\x06 \x01(\r\x12\x12\n\nfile_index\x18\x07 \x01(\r\x12\x11\n\tfile_name\x18\x08 \x01(\t\x12\x0e\n\x06opcode\x18\t \x01(\r\"\x92\x01\n\x12\x46ileIoInfoEtwEvent\x12\x0f\n\x07irp_ptr\x18\x01 \x01(\x04\x12\x13\n\x0b\x66ile_object\x18\x02 \x01(\x04\x12\x10\n\x08\x66ile_key\x18\x03 \x01(\x04\x12\x12\n\nextra_info\x18\x04 \x01(\x04\x12\x0c\n\x04ttid\x18\x05 \x01(\r\x12\x12\n\ninfo_class\x18\x06 \x01(\r\x12\x0e\n\x06opcode\x18\x07 \x01(\r\"\xa2\x01\n\x17\x46ileIoReadWriteEtwEvent\x12\x0e\n\x06offset\x18\x01 \x01(\x04\x12\x0f\n\x07irp_ptr\x18\x02 \x01(\x04\x12\x13\n\x0b\x66ile_object\x18\x03 \x01(\x04\x12\x10\n\x08\x66ile_key\x18\x04 \x01(\x04\x12\x0c\n\x04ttid\x18\x05 \x01(\r\x12\x0f\n\x07io_size\x18\x06 \x01(\r\x12\x10\n\x08io_flags\x18\x07 \x01(\r\x12\x0e\n\x06opcode\x18\x08 \x01(\r\"n\n\x16\x46ileIoSimpleOpEtwEvent\x12\x0f\n\x07irp_ptr\x18\x01 \x01(\x04\x12\x13\n\x0b\x66ile_object\x18\x02 \x01(\x04\x12\x10\n\x08\x66ile_key\x18\x03 \x01(\x04\x12\x0c\n\x04ttid\x18\x04 \x01(\r\x12\x0e\n\x06opcode\x18\x05 \x01(\r\"M\n\x13\x46ileIoOpEndEtwEvent\x12\x0f\n\x07irp_ptr\x18\x01 \x01(\x04\x12\x12\n\nextra_info\x18\x02 \x01(\x04\x12\x11\n\tnt_status\x18\x03 \x01(\r\"\xae\x01\n\x1b\x46ileIoPathOperationEtwEvent\x12\x0f\n\x07irp_ptr\x18\x01 \x01(\x04\x12\x13\n\x0b\x66ile_object\x18\x02 \x01(\x04\x12\x10\n\x08\x66ile_key\x18\x03 \x01(\x04\x12\x12\n\nextra_info\x18\x04 \x01(\x04\x12\x0c\n\x04ttid\x18\x05 \x01(\r\x12\x12\n\ninfo_class\x18\x06 \x01(\r\x12\x11\n\tfile_name\x18\x07 \x01(\t\x12\x0e\n\x06opcode\x18\x08 \x01(\r\";\n\x11StackWalkEtwEvent\x12\x0f\n\x07trigger\x18\x01 \x01(\t\x12\x15\n\rcallstack_iid\x18\x02 \x01(\x04\"\xcc\x01\n\x0e\x44iskIoEtwEvent\x12\x13\n\x0b\x64isk_number\x18\x01 \x01(\r\x12\x11\n\tirp_flags\x18\x02 \x01(\r\x12\x15\n\rtransfer_size\x18\x03 \x01(\r\x12\x13\n\x0b\x62yte_offset\x18\x04 \x01(\x03\x12\x13\n\x0b\x66ile_object\x18\x05 \x01(\x04\x12\x0f\n\x07irp_ptr\x18\x06 \x01(\x04\x12\x15\n\rresponse_time\x18\x07 \x01(\x03\x12\x19\n\x11issuing_thread_id\x18\x08 \x01(\r\x12\x0e\n\x06opcode\x18\t \x01(\r\"\xc3\x06\n\rEtwTraceEvent\x12\x11\n\ttimestamp\x18\x01 \x01(\x04\x12\x0b\n\x03\x63pu\x18\x04 \x01(\r\x12\x11\n\tthread_id\x18\x05 \x01(\r\x12\x34\n\x08\x63_switch\x18\x02 \x01(\x0b\x32 .perfetto.protos.CSwitchEtwEventH\x00\x12<\n\x0cready_thread\x18\x03 \x01(\x0b\x32$.perfetto.protos.ReadyThreadEtwEventH\x00\x12\x34\n\x08mem_info\x18\x06 \x01(\x0b\x32 .perfetto.protos.MemInfoEtwEventH\x00\x12?\n\x0e\x66ile_io_create\x18\x07 \x01(\x0b\x32%.perfetto.protos.FileIoCreateEtwEventH\x00\x12\x42\n\x10\x66ile_io_dir_enum\x18\x08 \x01(\x0b\x32&.perfetto.protos.FileIoDirEnumEtwEventH\x00\x12;\n\x0c\x66ile_io_info\x18\t \x01(\x0b\x32#.perfetto.protos.FileIoInfoEtwEventH\x00\x12\x46\n\x12\x66ile_io_read_write\x18\n \x01(\x0b\x32(.perfetto.protos.FileIoReadWriteEtwEventH\x00\x12\x44\n\x11\x66ile_io_simple_op\x18\x0b \x01(\x0b\x32\'.perfetto.protos.FileIoSimpleOpEtwEventH\x00\x12>\n\x0e\x66ile_io_op_end\x18\x0c \x01(\x0b\x32$.perfetto.protos.FileIoOpEndEtwEventH\x00\x12\x38\n\nstack_walk\x18\r \x01(\x0b\x32\".perfetto.protos.StackWalkEtwEventH\x00\x12N\n\x16\x66ile_io_path_operation\x18\x0e \x01(\x0b\x32,.perfetto.protos.FileIoPathOperationEtwEventH\x00\x12\x32\n\x07\x64isk_io\x18\x0f \x01(\x0b\x32\x1f.perfetto.protos.DiskIoEtwEventH\x00\x42\x07\n\x05\x65vent\"Q\n\x13\x45twTraceEventBundle\x12\x0b\n\x03\x63pu\x18\x01 \x01(\r\x12-\n\x05\x65vent\x18\x02 \x03(\x0b\x32\x1e.perfetto.protos.EtwTraceEvent\"G\n\x11\x46ileDescriptorSet\x12\x32\n\x04\x66ile\x18\x01 \x03(\x0b\x32$.perfetto.protos.FileDescriptorProto\"\xbf\x02\n\x13\x46ileDescriptorProto\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0f\n\x07package\x18\x02 \x01(\t\x12\x12\n\ndependency\x18\x03 \x03(\t\x12\x19\n\x11public_dependency\x18\n \x03(\x05\x12\x17\n\x0fweak_dependency\x18\x0b \x03(\x05\x12\x36\n\x0cmessage_type\x18\x04 \x03(\x0b\x32 .perfetto.protos.DescriptorProto\x12\x37\n\tenum_type\x18\x05 \x03(\x0b\x32$.perfetto.protos.EnumDescriptorProto\x12\x38\n\textension\x18\x07 \x03(\x0b\x32%.perfetto.protos.FieldDescriptorProtoJ\x04\x08\x06\x10\x07J\x04\x08\x08\x10\tJ\x04\x08\t\x10\nJ\x04\x08\x0c\x10\r\"\xd2\x03\n\x0f\x44\x65scriptorProto\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x34\n\x05\x66ield\x18\x02 \x03(\x0b\x32%.perfetto.protos.FieldDescriptorProto\x12\x38\n\textension\x18\x06 \x03(\x0b\x32%.perfetto.protos.FieldDescriptorProto\x12\x35\n\x0bnested_type\x18\x03 \x03(\x0b\x32 .perfetto.protos.DescriptorProto\x12\x37\n\tenum_type\x18\x04 \x03(\x0b\x32$.perfetto.protos.EnumDescriptorProto\x12\x39\n\noneof_decl\x18\x08 \x03(\x0b\x32%.perfetto.protos.OneofDescriptorProto\x12\x46\n\x0ereserved_range\x18\t \x03(\x0b\x32..perfetto.protos.DescriptorProto.ReservedRange\x12\x15\n\rreserved_name\x18\n \x03(\t\x1a+\n\rReservedRange\x12\r\n\x05start\x18\x01 \x01(\x05\x12\x0b\n\x03\x65nd\x18\x02 \x01(\x05J\x04\x08\x05\x10\x06J\x04\x08\x07\x10\x08\"\x9e\x02\n\x13UninterpretedOption\x12;\n\x04name\x18\x02 \x03(\x0b\x32-.perfetto.protos.UninterpretedOption.NamePart\x12\x18\n\x10identifier_value\x18\x03 \x01(\t\x12\x1a\n\x12positive_int_value\x18\x04 \x01(\x04\x12\x1a\n\x12negative_int_value\x18\x05 \x01(\x03\x12\x14\n\x0c\x64ouble_value\x18\x06 \x01(\x01\x12\x14\n\x0cstring_value\x18\x07 \x01(\x0c\x12\x17\n\x0f\x61ggregate_value\x18\x08 \x01(\t\x1a\x33\n\x08NamePart\x12\x11\n\tname_part\x18\x01 \x01(\t\x12\x14\n\x0cis_extension\x18\x02 \x01(\x08\"c\n\x0c\x46ieldOptions\x12\x0e\n\x06packed\x18\x02 \x01(\x08\x12\x43\n\x14uninterpreted_option\x18\xe7\x07 \x03(\x0b\x32$.perfetto.protos.UninterpretedOption\"\xaf\x05\n\x14\x46ieldDescriptorProto\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0e\n\x06number\x18\x03 \x01(\x05\x12:\n\x05label\x18\x04 \x01(\x0e\x32+.perfetto.protos.FieldDescriptorProto.Label\x12\x38\n\x04type\x18\x05 \x01(\x0e\x32*.perfetto.protos.FieldDescriptorProto.Type\x12\x11\n\ttype_name\x18\x06 \x01(\t\x12\x10\n\x08\x65xtendee\x18\x02 \x01(\t\x12\x15\n\rdefault_value\x18\x07 \x01(\t\x12.\n\x07options\x18\x08 \x01(\x0b\x32\x1d.perfetto.protos.FieldOptions\x12\x13\n\x0boneof_index\x18\t \x01(\x05\"\xb6\x02\n\x04Type\x12\x0f\n\x0bTYPE_DOUBLE\x10\x01\x12\x0e\n\nTYPE_FLOAT\x10\x02\x12\x0e\n\nTYPE_INT64\x10\x03\x12\x0f\n\x0bTYPE_UINT64\x10\x04\x12\x0e\n\nTYPE_INT32\x10\x05\x12\x10\n\x0cTYPE_FIXED64\x10\x06\x12\x10\n\x0cTYPE_FIXED32\x10\x07\x12\r\n\tTYPE_BOOL\x10\x08\x12\x0f\n\x0bTYPE_STRING\x10\t\x12\x0e\n\nTYPE_GROUP\x10\n\x12\x10\n\x0cTYPE_MESSAGE\x10\x0b\x12\x0e\n\nTYPE_BYTES\x10\x0c\x12\x0f\n\x0bTYPE_UINT32\x10\r\x12\r\n\tTYPE_ENUM\x10\x0e\x12\x11\n\rTYPE_SFIXED32\x10\x0f\x12\x11\n\rTYPE_SFIXED64\x10\x10\x12\x0f\n\x0bTYPE_SINT32\x10\x11\x12\x0f\n\x0bTYPE_SINT64\x10\x12\"C\n\x05Label\x12\x12\n\x0eLABEL_OPTIONAL\x10\x01\x12\x12\n\x0eLABEL_REQUIRED\x10\x02\x12\x12\n\x0eLABEL_REPEATED\x10\x03J\x04\x08\n\x10\x0b\"T\n\x14OneofDescriptorProto\x12\x0c\n\x04name\x18\x01 \x01(\t\x12.\n\x07options\x18\x02 \x01(\x0b\x32\x1d.perfetto.protos.OneofOptions\"\x80\x01\n\x13\x45numDescriptorProto\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x38\n\x05value\x18\x02 \x03(\x0b\x32).perfetto.protos.EnumValueDescriptorProto\x12\x15\n\rreserved_name\x18\x05 \x03(\tJ\x04\x08\x03\x10\x04J\x04\x08\x04\x10\x05\">\n\x18\x45numValueDescriptorProto\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0e\n\x06number\x18\x02 \x01(\x05J\x04\x08\x03\x10\x04\"!\n\x0cOneofOptions*\t\x08\xe8\x07\x10\x80\x80\x80\x80\x02J\x06\x08\xe7\x07\x10\xe8\x07\"\x91\x01\n\x13\x45xtensionDescriptor\x12;\n\rextension_set\x18\x01 \x01(\x0b\x32\".perfetto.protos.FileDescriptorSetH\x00\x12\x1c\n\x12\x65xtension_set_gzip\x18\x02 \x01(\x0cH\x00\x12\x11\n\tfile_name\x18\x03 \x01(\tB\x0c\n\ndescriptor\"\x88\x02\n\x0cInodeFileMap\x12\x17\n\x0f\x62lock_device_id\x18\x01 \x01(\x04\x12\x14\n\x0cmount_points\x18\x02 \x03(\t\x12\x34\n\x07\x65ntries\x18\x03 \x03(\x0b\x32#.perfetto.protos.InodeFileMap.Entry\x1a\x92\x01\n\x05\x45ntry\x12\x14\n\x0cinode_number\x18\x01 \x01(\x04\x12\r\n\x05paths\x18\x02 \x03(\t\x12\x36\n\x04type\x18\x03 \x01(\x0e\x32(.perfetto.protos.InodeFileMap.Entry.Type\",\n\x04Type\x12\x0b\n\x07UNKNOWN\x10\x00\x12\x08\n\x04\x46ILE\x10\x01\x12\r\n\tDIRECTORY\x10\x02\"M\n\x1f\x41ndroidFsDatareadEndFtraceEvent\x12\r\n\x05\x62ytes\x18\x01 \x01(\x05\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x0e\n\x06offset\x18\x03 \x01(\x03\"\x8e\x01\n!AndroidFsDatareadStartFtraceEvent\x12\r\n\x05\x62ytes\x18\x01 \x01(\x05\x12\x0f\n\x07\x63mdline\x18\x02 \x01(\t\x12\x0e\n\x06i_size\x18\x03 \x01(\x03\x12\x0b\n\x03ino\x18\x04 \x01(\x04\x12\x0e\n\x06offset\x18\x05 \x01(\x03\x12\x0f\n\x07pathbuf\x18\x06 \x01(\t\x12\x0b\n\x03pid\x18\x07 \x01(\x05\"N\n AndroidFsDatawriteEndFtraceEvent\x12\r\n\x05\x62ytes\x18\x01 \x01(\x05\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x0e\n\x06offset\x18\x03 \x01(\x03\"\x8f\x01\n\"AndroidFsDatawriteStartFtraceEvent\x12\r\n\x05\x62ytes\x18\x01 \x01(\x05\x12\x0f\n\x07\x63mdline\x18\x02 \x01(\t\x12\x0e\n\x06i_size\x18\x03 \x01(\x03\x12\x0b\n\x03ino\x18\x04 \x01(\x04\x12\x0e\n\x06offset\x18\x05 \x01(\x03\x12\x0f\n\x07pathbuf\x18\x06 \x01(\t\x12\x0b\n\x03pid\x18\x07 \x01(\x05\"J\n\x1c\x41ndroidFsFsyncEndFtraceEvent\x12\r\n\x05\x62ytes\x18\x01 \x01(\x05\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x0e\n\x06offset\x18\x03 \x01(\x03\"l\n\x1e\x41ndroidFsFsyncStartFtraceEvent\x12\x0f\n\x07\x63mdline\x18\x01 \x01(\t\x12\x0e\n\x06i_size\x18\x02 \x01(\x03\x12\x0b\n\x03ino\x18\x03 \x01(\x04\x12\x0f\n\x07pathbuf\x18\x04 \x01(\t\x12\x0b\n\x03pid\x18\x05 \x01(\x05\"\xbd\x01\n\x18\x42\x63lIrqTriggerFtraceEvent\x12\n\n\x02id\x18\x01 \x01(\x05\x12\x10\n\x08throttle\x18\x02 \x01(\x05\x12\x12\n\ncpu0_limit\x18\x03 \x01(\x05\x12\x12\n\ncpu1_limit\x18\x04 \x01(\x05\x12\x12\n\ncpu2_limit\x18\x05 \x01(\x05\x12\x11\n\ttpu_limit\x18\x06 \x01(\x05\x12\x11\n\tgpu_limit\x18\x07 \x01(\x05\x12\x0f\n\x07voltage\x18\x08 \x01(\x05\x12\x10\n\x08\x63\x61pacity\x18\t \x01(\x05\"\x95\x01\n\x1c\x42inderTransactionFtraceEvent\x12\x10\n\x08\x64\x65\x62ug_id\x18\x01 \x01(\x05\x12\x13\n\x0btarget_node\x18\x02 \x01(\x05\x12\x0f\n\x07to_proc\x18\x03 \x01(\x05\x12\x11\n\tto_thread\x18\x04 \x01(\x05\x12\r\n\x05reply\x18\x05 \x01(\x05\x12\x0c\n\x04\x63ode\x18\x06 \x01(\r\x12\r\n\x05\x66lags\x18\x07 \x01(\r\"8\n$BinderTransactionReceivedFtraceEvent\x12\x10\n\x08\x64\x65\x62ug_id\x18\x01 \x01(\x05\"v\n\x1c\x42inderSetPriorityFtraceEvent\x12\x0c\n\x04proc\x18\x01 \x01(\x05\x12\x0e\n\x06thread\x18\x02 \x01(\x05\x12\x10\n\x08old_prio\x18\x03 \x01(\r\x12\x10\n\x08new_prio\x18\x04 \x01(\r\x12\x14\n\x0c\x64\x65sired_prio\x18\x05 \x01(\r\"$\n\x15\x42inderLockFtraceEvent\x12\x0b\n\x03tag\x18\x01 \x01(\t\"&\n\x17\x42inderLockedFtraceEvent\x12\x0b\n\x03tag\x18\x01 \x01(\t\"&\n\x17\x42inderUnlockFtraceEvent\x12\x0b\n\x03tag\x18\x01 \x01(\t\"}\n$BinderTransactionAllocBufFtraceEvent\x12\x11\n\tdata_size\x18\x01 \x01(\x04\x12\x10\n\x08\x64\x65\x62ug_id\x18\x02 \x01(\x05\x12\x14\n\x0coffsets_size\x18\x03 \x01(\x04\x12\x1a\n\x12\x65xtra_buffers_size\x18\x04 \x01(\x04\"\'\n\x18\x42inderCommandFtraceEvent\x12\x0b\n\x03\x63md\x18\x01 \x01(\r\"&\n\x17\x42inderReturnFtraceEvent\x12\x0b\n\x03\x63md\x18\x01 \x01(\r\"\x81\x01\n\x17\x42lockRqIssueFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0e\n\x06sector\x18\x02 \x01(\x04\x12\x11\n\tnr_sector\x18\x03 \x01(\r\x12\r\n\x05\x62ytes\x18\x04 \x01(\r\x12\x0c\n\x04rwbs\x18\x05 \x01(\t\x12\x0c\n\x04\x63omm\x18\x06 \x01(\t\x12\x0b\n\x03\x63md\x18\x07 \x01(\t\"j\n\x1c\x42lockBioBackmergeFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0e\n\x06sector\x18\x02 \x01(\x04\x12\x11\n\tnr_sector\x18\x03 \x01(\r\x12\x0c\n\x04rwbs\x18\x04 \x01(\t\x12\x0c\n\x04\x63omm\x18\x05 \x01(\t\"g\n\x19\x42lockBioBounceFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0e\n\x06sector\x18\x02 \x01(\x04\x12\x11\n\tnr_sector\x18\x03 \x01(\r\x12\x0c\n\x04rwbs\x18\x04 \x01(\t\x12\x0c\n\x04\x63omm\x18\x05 \x01(\t\"j\n\x1b\x42lockBioCompleteFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0e\n\x06sector\x18\x02 \x01(\x04\x12\x11\n\tnr_sector\x18\x03 \x01(\r\x12\r\n\x05\x65rror\x18\x04 \x01(\x05\x12\x0c\n\x04rwbs\x18\x05 \x01(\t\"k\n\x1d\x42lockBioFrontmergeFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0e\n\x06sector\x18\x02 \x01(\x04\x12\x11\n\tnr_sector\x18\x03 \x01(\r\x12\x0c\n\x04rwbs\x18\x04 \x01(\t\x12\x0c\n\x04\x63omm\x18\x05 \x01(\t\"f\n\x18\x42lockBioQueueFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0e\n\x06sector\x18\x02 \x01(\x04\x12\x11\n\tnr_sector\x18\x03 \x01(\r\x12\x0c\n\x04rwbs\x18\x04 \x01(\t\x12\x0c\n\x04\x63omm\x18\x05 \x01(\t\"}\n\x18\x42lockBioRemapFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0e\n\x06sector\x18\x02 \x01(\x04\x12\x11\n\tnr_sector\x18\x03 \x01(\r\x12\x0f\n\x07old_dev\x18\x04 \x01(\x04\x12\x12\n\nold_sector\x18\x05 \x01(\x04\x12\x0c\n\x04rwbs\x18\x06 \x01(\t\"H\n\x1b\x42lockDirtyBufferFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0e\n\x06sector\x18\x02 \x01(\x04\x12\x0c\n\x04size\x18\x03 \x01(\x04\"c\n\x15\x42lockGetrqFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0e\n\x06sector\x18\x02 \x01(\x04\x12\x11\n\tnr_sector\x18\x03 \x01(\r\x12\x0c\n\x04rwbs\x18\x04 \x01(\t\x12\x0c\n\x04\x63omm\x18\x05 \x01(\t\"$\n\x14\x42lockPlugFtraceEvent\x12\x0c\n\x04\x63omm\x18\x01 \x01(\t\"t\n\x17\x42lockRqAbortFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0e\n\x06sector\x18\x02 \x01(\x04\x12\x11\n\tnr_sector\x18\x03 \x01(\r\x12\x0e\n\x06\x65rrors\x18\x04 \x01(\x05\x12\x0c\n\x04rwbs\x18\x05 \x01(\t\x12\x0b\n\x03\x63md\x18\x06 \x01(\t\"\x86\x01\n\x1a\x42lockRqCompleteFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0e\n\x06sector\x18\x02 \x01(\x04\x12\x11\n\tnr_sector\x18\x03 \x01(\r\x12\x0e\n\x06\x65rrors\x18\x04 \x01(\x05\x12\x0c\n\x04rwbs\x18\x05 \x01(\t\x12\x0b\n\x03\x63md\x18\x06 \x01(\t\x12\r\n\x05\x65rror\x18\x07 \x01(\x05\"\x82\x01\n\x18\x42lockRqInsertFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0e\n\x06sector\x18\x02 \x01(\x04\x12\x11\n\tnr_sector\x18\x03 \x01(\r\x12\r\n\x05\x62ytes\x18\x04 \x01(\r\x12\x0c\n\x04rwbs\x18\x05 \x01(\t\x12\x0c\n\x04\x63omm\x18\x06 \x01(\t\x12\x0b\n\x03\x63md\x18\x07 \x01(\t\"\x8d\x01\n\x17\x42lockRqRemapFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0e\n\x06sector\x18\x02 \x01(\x04\x12\x11\n\tnr_sector\x18\x03 \x01(\r\x12\x0f\n\x07old_dev\x18\x04 \x01(\x04\x12\x12\n\nold_sector\x18\x05 \x01(\x04\x12\x0f\n\x07nr_bios\x18\x06 \x01(\r\x12\x0c\n\x04rwbs\x18\x07 \x01(\t\"v\n\x19\x42lockRqRequeueFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0e\n\x06sector\x18\x02 \x01(\x04\x12\x11\n\tnr_sector\x18\x03 \x01(\r\x12\x0e\n\x06\x65rrors\x18\x04 \x01(\x05\x12\x0c\n\x04rwbs\x18\x05 \x01(\t\x12\x0b\n\x03\x63md\x18\x06 \x01(\t\"e\n\x17\x42lockSleeprqFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0e\n\x06sector\x18\x02 \x01(\x04\x12\x11\n\tnr_sector\x18\x03 \x01(\r\x12\x0c\n\x04rwbs\x18\x04 \x01(\t\x12\x0c\n\x04\x63omm\x18\x05 \x01(\t\"d\n\x15\x42lockSplitFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0e\n\x06sector\x18\x02 \x01(\x04\x12\x12\n\nnew_sector\x18\x03 \x01(\x04\x12\x0c\n\x04rwbs\x18\x04 \x01(\t\x12\x0c\n\x04\x63omm\x18\x05 \x01(\t\"H\n\x1b\x42lockTouchBufferFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0e\n\x06sector\x18\x02 \x01(\x04\x12\x0c\n\x04size\x18\x03 \x01(\x04\"5\n\x16\x42lockUnplugFtraceEvent\x12\r\n\x05nr_rq\x18\x01 \x01(\x05\x12\x0c\n\x04\x63omm\x18\x02 \x01(\t\"\x91\x01\n\x17\x42lockIoStartFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0e\n\x06sector\x18\x02 \x01(\x04\x12\x11\n\tnr_sector\x18\x03 \x01(\r\x12\r\n\x05\x62ytes\x18\x04 \x01(\r\x12\x0e\n\x06ioprio\x18\x05 \x01(\r\x12\x0c\n\x04rwbs\x18\x06 \x01(\t\x12\x0c\n\x04\x63omm\x18\x07 \x01(\t\x12\x0b\n\x03\x63md\x18\x08 \x01(\t\"\x90\x01\n\x16\x42lockIoDoneFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0e\n\x06sector\x18\x02 \x01(\x04\x12\x11\n\tnr_sector\x18\x03 \x01(\r\x12\r\n\x05\x62ytes\x18\x04 \x01(\r\x12\x0e\n\x06ioprio\x18\x05 \x01(\r\x12\x0c\n\x04rwbs\x18\x06 \x01(\t\x12\x0c\n\x04\x63omm\x18\x07 \x01(\t\x12\x0b\n\x03\x63md\x18\x08 \x01(\t\"\x8e\x01\n\x1b\x43groupAttachTaskFtraceEvent\x12\x10\n\x08\x64st_root\x18\x01 \x01(\x05\x12\x0e\n\x06\x64st_id\x18\x02 \x01(\x05\x12\x0b\n\x03pid\x18\x03 \x01(\x05\x12\x0c\n\x04\x63omm\x18\x04 \x01(\t\x12\r\n\x05\x63name\x18\x05 \x01(\t\x12\x11\n\tdst_level\x18\x06 \x01(\x05\x12\x10\n\x08\x64st_path\x18\x07 \x01(\t\"^\n\x16\x43groupMkdirFtraceEvent\x12\x0c\n\x04root\x18\x01 \x01(\x05\x12\n\n\x02id\x18\x02 \x01(\x05\x12\r\n\x05\x63name\x18\x03 \x01(\t\x12\r\n\x05level\x18\x04 \x01(\x05\x12\x0c\n\x04path\x18\x05 \x01(\t\"G\n\x18\x43groupRemountFtraceEvent\x12\x0c\n\x04root\x18\x01 \x01(\x05\x12\x0f\n\x07ss_mask\x18\x02 \x01(\r\x12\x0c\n\x04name\x18\x03 \x01(\t\"^\n\x16\x43groupRmdirFtraceEvent\x12\x0c\n\x04root\x18\x01 \x01(\x05\x12\n\n\x02id\x18\x02 \x01(\x05\x12\r\n\x05\x63name\x18\x03 \x01(\t\x12\r\n\x05level\x18\x04 \x01(\x05\x12\x0c\n\x04path\x18\x05 \x01(\t\"\x91\x01\n\x1e\x43groupTransferTasksFtraceEvent\x12\x10\n\x08\x64st_root\x18\x01 \x01(\x05\x12\x0e\n\x06\x64st_id\x18\x02 \x01(\x05\x12\x0b\n\x03pid\x18\x03 \x01(\x05\x12\x0c\n\x04\x63omm\x18\x04 \x01(\t\x12\r\n\x05\x63name\x18\x05 \x01(\t\x12\x11\n\tdst_level\x18\x06 \x01(\x05\x12\x10\n\x08\x64st_path\x18\x07 \x01(\t\"K\n\x1c\x43groupDestroyRootFtraceEvent\x12\x0c\n\x04root\x18\x01 \x01(\x05\x12\x0f\n\x07ss_mask\x18\x02 \x01(\r\x12\x0c\n\x04name\x18\x03 \x01(\t\"`\n\x18\x43groupReleaseFtraceEvent\x12\x0c\n\x04root\x18\x01 \x01(\x05\x12\n\n\x02id\x18\x02 \x01(\x05\x12\r\n\x05\x63name\x18\x03 \x01(\t\x12\r\n\x05level\x18\x04 \x01(\x05\x12\x0c\n\x04path\x18\x05 \x01(\t\"_\n\x17\x43groupRenameFtraceEvent\x12\x0c\n\x04root\x18\x01 \x01(\x05\x12\n\n\x02id\x18\x02 \x01(\x05\x12\r\n\x05\x63name\x18\x03 \x01(\t\x12\r\n\x05level\x18\x04 \x01(\x05\x12\x0c\n\x04path\x18\x05 \x01(\t\"I\n\x1a\x43groupSetupRootFtraceEvent\x12\x0c\n\x04root\x18\x01 \x01(\x05\x12\x0f\n\x07ss_mask\x18\x02 \x01(\r\x12\x0c\n\x04name\x18\x03 \x01(\t\"$\n\x14\x43lkEnableFtraceEvent\x12\x0c\n\x04name\x18\x01 \x01(\t\"%\n\x15\x43lkDisableFtraceEvent\x12\x0c\n\x04name\x18\x01 \x01(\t\"3\n\x15\x43lkSetRateFtraceEvent\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0c\n\x04rate\x18\x02 \x01(\x04\"F\n\x18\x43maAllocStartFtraceEvent\x12\r\n\x05\x61lign\x18\x01 \x01(\r\x12\r\n\x05\x63ount\x18\x02 \x01(\r\x12\x0c\n\x04name\x18\x03 \x01(\t\"\xc4\x01\n\x17\x43maAllocInfoFtraceEvent\x12\r\n\x05\x61lign\x18\x01 \x01(\r\x12\r\n\x05\x63ount\x18\x02 \x01(\r\x12\x0f\n\x07\x65rr_iso\x18\x03 \x01(\r\x12\x0f\n\x07\x65rr_mig\x18\x04 \x01(\r\x12\x10\n\x08\x65rr_test\x18\x05 \x01(\r\x12\x0c\n\x04name\x18\x06 \x01(\t\x12\x11\n\tnr_mapped\x18\x07 \x01(\x04\x12\x13\n\x0bnr_migrated\x18\x08 \x01(\x04\x12\x14\n\x0cnr_reclaimed\x18\t \x01(\x04\x12\x0b\n\x03pfn\x18\n \x01(\x04\"s\n\x19\x43maAllocFinishFtraceEvent\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0b\n\x03pfn\x18\x02 \x01(\x04\x12\x0c\n\x04page\x18\x03 \x01(\x04\x12\r\n\x05\x63ount\x18\x04 \x01(\x04\x12\r\n\x05\x61lign\x18\x05 \x01(\r\x12\x0f\n\x07\x65rrorno\x18\x06 \x01(\x05\"y\n\x1cMmCompactionBeginFtraceEvent\x12\x12\n\nzone_start\x18\x01 \x01(\x04\x12\x13\n\x0bmigrate_pfn\x18\x02 \x01(\x04\x12\x10\n\x08\x66ree_pfn\x18\x03 \x01(\x04\x12\x10\n\x08zone_end\x18\x04 \x01(\x04\x12\x0c\n\x04sync\x18\x05 \x01(\r\"\x90\x01\n&MmCompactionDeferCompactionFtraceEvent\x12\x0b\n\x03nid\x18\x01 \x01(\x05\x12\x0b\n\x03idx\x18\x02 \x01(\r\x12\r\n\x05order\x18\x03 \x01(\x05\x12\x12\n\nconsidered\x18\x04 \x01(\r\x12\x13\n\x0b\x64\x65\x66\x65r_shift\x18\x05 \x01(\r\x12\x14\n\x0corder_failed\x18\x06 \x01(\x05\"\x89\x01\n\x1fMmCompactionDeferredFtraceEvent\x12\x0b\n\x03nid\x18\x01 \x01(\x05\x12\x0b\n\x03idx\x18\x02 \x01(\r\x12\r\n\x05order\x18\x03 \x01(\x05\x12\x12\n\nconsidered\x18\x04 \x01(\r\x12\x13\n\x0b\x64\x65\x66\x65r_shift\x18\x05 \x01(\r\x12\x14\n\x0corder_failed\x18\x06 \x01(\x05\"\x8b\x01\n!MmCompactionDeferResetFtraceEvent\x12\x0b\n\x03nid\x18\x01 \x01(\x05\x12\x0b\n\x03idx\x18\x02 \x01(\r\x12\r\n\x05order\x18\x03 \x01(\x05\x12\x12\n\nconsidered\x18\x04 \x01(\r\x12\x13\n\x0b\x64\x65\x66\x65r_shift\x18\x05 \x01(\r\x12\x14\n\x0corder_failed\x18\x06 \x01(\x05\"\x87\x01\n\x1aMmCompactionEndFtraceEvent\x12\x12\n\nzone_start\x18\x01 \x01(\x04\x12\x13\n\x0bmigrate_pfn\x18\x02 \x01(\x04\x12\x10\n\x08\x66ree_pfn\x18\x03 \x01(\x04\x12\x10\n\x08zone_end\x18\x04 \x01(\x04\x12\x0c\n\x04sync\x18\x05 \x01(\r\x12\x0e\n\x06status\x18\x06 \x01(\x05\"W\n\x1fMmCompactionFinishedFtraceEvent\x12\x0b\n\x03nid\x18\x01 \x01(\x05\x12\x0b\n\x03idx\x18\x02 \x01(\r\x12\r\n\x05order\x18\x03 \x01(\x05\x12\x0b\n\x03ret\x18\x04 \x01(\x05\"s\n\'MmCompactionIsolateFreepagesFtraceEvent\x12\x11\n\tstart_pfn\x18\x01 \x01(\x04\x12\x0f\n\x07\x65nd_pfn\x18\x02 \x01(\x04\x12\x12\n\nnr_scanned\x18\x03 \x01(\x04\x12\x10\n\x08nr_taken\x18\x04 \x01(\x04\"v\n*MmCompactionIsolateMigratepagesFtraceEvent\x12\x11\n\tstart_pfn\x18\x01 \x01(\x04\x12\x0f\n\x07\x65nd_pfn\x18\x02 \x01(\x04\x12\x12\n\nnr_scanned\x18\x03 \x01(\x04\x12\x10\n\x08nr_taken\x18\x04 \x01(\x04\"4\n%MmCompactionKcompactdSleepFtraceEvent\x12\x0b\n\x03nid\x18\x01 \x01(\x05\"r\n$MmCompactionKcompactdWakeFtraceEvent\x12\x0b\n\x03nid\x18\x01 \x01(\x05\x12\r\n\x05order\x18\x02 \x01(\x05\x12\x15\n\rclasszone_idx\x18\x03 \x01(\r\x12\x17\n\x0fhighest_zoneidx\x18\x04 \x01(\r\"M\n#MmCompactionMigratepagesFtraceEvent\x12\x13\n\x0bnr_migrated\x18\x01 \x01(\x04\x12\x11\n\tnr_failed\x18\x02 \x01(\x04\"W\n\x1fMmCompactionSuitableFtraceEvent\x12\x0b\n\x03nid\x18\x01 \x01(\x05\x12\x0b\n\x03idx\x18\x02 \x01(\r\x12\r\n\x05order\x18\x03 \x01(\x05\x12\x0b\n\x03ret\x18\x04 \x01(\x05\"g\n(MmCompactionTryToCompactPagesFtraceEvent\x12\r\n\x05order\x18\x01 \x01(\x05\x12\x10\n\x08gfp_mask\x18\x02 \x01(\r\x12\x0c\n\x04mode\x18\x03 \x01(\r\x12\x0c\n\x04prio\x18\x04 \x01(\x05\"t\n&MmCompactionWakeupKcompactdFtraceEvent\x12\x0b\n\x03nid\x18\x01 \x01(\x05\x12\r\n\x05order\x18\x02 \x01(\x05\x12\x15\n\rclasszone_idx\x18\x03 \x01(\r\x12\x17\n\x0fhighest_zoneidx\x18\x04 \x01(\r\"M\n\x1bParamSetValueCpmFtraceEvent\x12\x0c\n\x04\x62ody\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\r\x12\x11\n\ttimestamp\x18\x03 \x01(\x03\"L\n\x14\x43puhpExitFtraceEvent\x12\x0b\n\x03\x63pu\x18\x01 \x01(\r\x12\x0b\n\x03idx\x18\x02 \x01(\x05\x12\x0b\n\x03ret\x18\x03 \x01(\x05\x12\r\n\x05state\x18\x04 \x01(\x05\"S\n\x1a\x43puhpMultiEnterFtraceEvent\x12\x0b\n\x03\x63pu\x18\x01 \x01(\r\x12\x0b\n\x03\x66un\x18\x02 \x01(\x04\x12\x0b\n\x03idx\x18\x03 \x01(\x05\x12\x0e\n\x06target\x18\x04 \x01(\x05\"N\n\x15\x43puhpEnterFtraceEvent\x12\x0b\n\x03\x63pu\x18\x01 \x01(\r\x12\x0b\n\x03\x66un\x18\x02 \x01(\x04\x12\x0b\n\x03idx\x18\x03 \x01(\x05\x12\x0e\n\x06target\x18\x04 \x01(\x05\"P\n\x17\x43puhpLatencyFtraceEvent\x12\x0b\n\x03\x63pu\x18\x01 \x01(\r\x12\x0b\n\x03ret\x18\x02 \x01(\x05\x12\r\n\x05state\x18\x03 \x01(\r\x12\x0c\n\x04time\x18\x04 \x01(\x04\"W\n\x15\x43puhpPauseFtraceEvent\x12\x13\n\x0b\x61\x63tive_cpus\x18\x01 \x01(\r\x12\x0c\n\x04\x63pus\x18\x02 \x01(\r\x12\r\n\x05pause\x18\x03 \x01(\r\x12\x0c\n\x04time\x18\x04 \x01(\r\"\xaa\x01\n\x1e\x43rosEcSensorhubDataFtraceEvent\x12\x14\n\x0c\x63urrent_time\x18\x01 \x01(\x03\x12\x19\n\x11\x63urrent_timestamp\x18\x02 \x01(\x03\x12\r\n\x05\x64\x65lta\x18\x03 \x01(\x03\x12\x19\n\x11\x65\x63_fifo_timestamp\x18\x04 \x01(\r\x12\x15\n\rec_sensor_num\x18\x05 \x01(\r\x12\x16\n\x0e\x66ifo_timestamp\x18\x06 \x01(\x03\"1\n\x14\x44\x63vshFreqFtraceEvent\x12\x0b\n\x03\x63pu\x18\x01 \x01(\x04\x12\x0c\n\x04\x66req\x18\x02 \x01(\x04\"w\n\x1b\x44\x65vfreqFrequencyFtraceEvent\x12\x10\n\x08\x64\x65v_name\x18\x01 \x01(\t\x12\x0c\n\x04\x66req\x18\x02 \x01(\x04\x12\x11\n\tprev_freq\x18\x03 \x01(\x04\x12\x11\n\tbusy_time\x18\x04 \x01(\x04\x12\x12\n\ntotal_time\x18\x05 \x01(\x04\"[\n\x17\x44maFenceInitFtraceEvent\x12\x0f\n\x07\x63ontext\x18\x01 \x01(\r\x12\x0e\n\x06\x64river\x18\x02 \x01(\t\x12\r\n\x05seqno\x18\x03 \x01(\r\x12\x10\n\x08timeline\x18\x04 \x01(\t\"[\n\x17\x44maFenceEmitFtraceEvent\x12\x0f\n\x07\x63ontext\x18\x01 \x01(\r\x12\x0e\n\x06\x64river\x18\x02 \x01(\t\x12\r\n\x05seqno\x18\x03 \x01(\r\x12\x10\n\x08timeline\x18\x04 \x01(\t\"_\n\x1b\x44maFenceSignaledFtraceEvent\x12\x0f\n\x07\x63ontext\x18\x01 \x01(\r\x12\x0e\n\x06\x64river\x18\x02 \x01(\t\x12\r\n\x05seqno\x18\x03 \x01(\r\x12\x10\n\x08timeline\x18\x04 \x01(\t\"`\n\x1c\x44maFenceWaitStartFtraceEvent\x12\x0f\n\x07\x63ontext\x18\x01 \x01(\r\x12\x0e\n\x06\x64river\x18\x02 \x01(\t\x12\r\n\x05seqno\x18\x03 \x01(\r\x12\x10\n\x08timeline\x18\x04 \x01(\t\"^\n\x1a\x44maFenceWaitEndFtraceEvent\x12\x0f\n\x07\x63ontext\x18\x01 \x01(\r\x12\x0e\n\x06\x64river\x18\x02 \x01(\t\x12\r\n\x05seqno\x18\x03 \x01(\r\x12\x10\n\x08timeline\x18\x04 \x01(\t\"M\n\x16\x44maHeapStatFtraceEvent\x12\r\n\x05inode\x18\x01 \x01(\x04\x12\x0b\n\x03len\x18\x02 \x01(\x03\x12\x17\n\x0ftotal_allocated\x18\x03 \x01(\x04\"\x81\x01\n\x1e\x44puTracingMarkWriteFtraceEvent\x12\x0b\n\x03pid\x18\x01 \x01(\x05\x12\x12\n\ntrace_name\x18\x02 \x01(\t\x12\x13\n\x0btrace_begin\x18\x03 \x01(\r\x12\x0c\n\x04name\x18\x04 \x01(\t\x12\x0c\n\x04type\x18\x05 \x01(\r\x12\r\n\x05value\x18\x06 \x01(\x05\"A\n\x1e\x44puDsiCmdFifoStatusFtraceEvent\x12\x0e\n\x06header\x18\x01 \x01(\r\x12\x0f\n\x07payload\x18\x02 \x01(\r\"2\n\x13\x44puDsiRxFtraceEvent\x12\x0b\n\x03\x63md\x18\x01 \x01(\r\x12\x0e\n\x06rx_buf\x18\x03 \x01(\x0c\"S\n\x13\x44puDsiTxFtraceEvent\x12\x0c\n\x04type\x18\x01 \x01(\r\x12\x0c\n\x04last\x18\x03 \x01(\r\x12\x10\n\x08\x64\x65lay_ms\x18\x04 \x01(\r\x12\x0e\n\x06tx_buf\x18\x05 \x01(\x0c\"X\n\x1d\x44puDispDpuUnderrunFtraceEvent\x12\n\n\x02id\x18\x01 \x01(\x05\x12\x16\n\x0e\x66rames_pending\x18\x02 \x01(\x05\x12\x13\n\x0bvsync_count\x18\x03 \x01(\x05\"R\n!DpuDispVblankIrqEnableFtraceEvent\x12\n\n\x02id\x18\x01 \x01(\x05\x12\x11\n\toutput_id\x18\x02 \x01(\x05\x12\x0e\n\x06\x65nable\x18\x03 \x01(\x05\"\x8d\x01\n\"DpuDispFrameDoneTimeoutFtraceEvent\x12\x12\n\ndisplay_id\x18\x01 \x01(\x05\x12\x11\n\toutput_id\x18\x02 \x01(\r\x12\x16\n\x0e\x66rames_pending\x18\x03 \x01(\x05\x12\x10\n\x08te_count\x18\x04 \x01(\x05\x12\x16\n\x0e\x64uring_disable\x18\x05 \x01(\r\"v\n#DpuDispFrameStartTimeoutFtraceEvent\x12\x12\n\ndisplay_id\x18\x01 \x01(\x05\x12\x11\n\toutput_id\x18\x02 \x01(\r\x12\x16\n\x0e\x66rames_pending\x18\x03 \x01(\x05\x12\x10\n\x08te_count\x18\x04 \x01(\x05\"u\n\"DpuDispFrameDoneMissingFtraceEvent\x12\x12\n\ndisplay_id\x18\x01 \x01(\x05\x12\x11\n\toutput_id\x18\x02 \x01(\r\x12\x16\n\x0e\x66rames_pending\x18\x03 \x01(\x05\x12\x10\n\x08te_count\x18\x04 \x01(\x05\"v\n#DpuDispFrameStartMissingFtraceEvent\x12\x12\n\ndisplay_id\x18\x01 \x01(\x05\x12\x11\n\toutput_id\x18\x02 \x01(\r\x12\x16\n\x0e\x66rames_pending\x18\x03 \x01(\x05\x12\x10\n\x08te_count\x18\x04 \x01(\x05\"\\\n!DpuDispDpuLineUnderrunFtraceEvent\x12\n\n\x02id\x18\x01 \x01(\x05\x12\x16\n\x0e\x66rames_pending\x18\x02 \x01(\x05\x12\x13\n\x0bvsync_count\x18\x03 \x01(\x05\"W\n\x19\x44rmVblankEventFtraceEvent\x12\x0c\n\x04\x63rtc\x18\x01 \x01(\x05\x12\x11\n\thigh_prec\x18\x02 \x01(\r\x12\x0b\n\x03seq\x18\x03 \x01(\r\x12\x0c\n\x04time\x18\x04 \x01(\x03\"M\n\"DrmVblankEventDeliveredFtraceEvent\x12\x0c\n\x04\x63rtc\x18\x01 \x01(\x05\x12\x0c\n\x04\x66ile\x18\x02 \x01(\x04\x12\x0b\n\x03seq\x18\x03 \x01(\r\"\xa2\x01\n\x1b\x44wc3AllocRequestFtraceEvent\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0b\n\x03req\x18\x02 \x01(\x04\x12\x0e\n\x06\x61\x63tual\x18\x03 \x01(\r\x12\x0e\n\x06length\x18\x04 \x01(\r\x12\x0e\n\x06status\x18\x05 \x01(\x05\x12\x0c\n\x04zero\x18\x06 \x01(\x05\x12\x14\n\x0cshort_not_ok\x18\x07 \x01(\x05\x12\x14\n\x0cno_interrupt\x18\x08 \x01(\x05\"\xc0\x01\n\x1a\x44wc3CompleteTrbFtraceEvent\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0b\n\x03trb\x18\x02 \x01(\x04\x12\x11\n\tallocated\x18\x03 \x01(\r\x12\x0e\n\x06queued\x18\x04 \x01(\r\x12\x0b\n\x03\x62pl\x18\x05 \x01(\r\x12\x0b\n\x03\x62ph\x18\x06 \x01(\r\x12\x0c\n\x04size\x18\x07 \x01(\r\x12\x0c\n\x04\x63trl\x18\x08 \x01(\r\x12\x0c\n\x04type\x18\t \x01(\r\x12\x0f\n\x07\x65nqueue\x18\n \x01(\r\x12\x0f\n\x07\x64\x65queue\x18\x0b \x01(\r\"~\n\x16\x44wc3CtrlReqFtraceEvent\x12\x14\n\x0c\x62RequestType\x18\x01 \x01(\r\x12\x10\n\x08\x62Request\x18\x02 \x01(\r\x12\x0e\n\x06wValue\x18\x03 \x01(\r\x12\x0e\n\x06wIndex\x18\x04 \x01(\r\x12\x0f\n\x07wLength\x18\x05 \x01(\r\x12\x0b\n\x03str\x18\x06 \x01(\t\"\x9f\x01\n\x18\x44wc3EpDequeueFtraceEvent\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0b\n\x03req\x18\x02 \x01(\x04\x12\x0e\n\x06\x61\x63tual\x18\x03 \x01(\r\x12\x0e\n\x06length\x18\x04 \x01(\r\x12\x0e\n\x06status\x18\x05 \x01(\x05\x12\x0c\n\x04zero\x18\x06 \x01(\x05\x12\x14\n\x0cshort_not_ok\x18\x07 \x01(\x05\x12\x14\n\x0cno_interrupt\x18\x08 \x01(\x05\"\x9d\x01\n\x16\x44wc3EpQueueFtraceEvent\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0b\n\x03req\x18\x02 \x01(\x04\x12\x0e\n\x06\x61\x63tual\x18\x03 \x01(\r\x12\x0e\n\x06length\x18\x04 \x01(\r\x12\x0e\n\x06status\x18\x05 \x01(\x05\x12\x0c\n\x04zero\x18\x06 \x01(\x05\x12\x14\n\x0cshort_not_ok\x18\x07 \x01(\x05\x12\x14\n\x0cno_interrupt\x18\x08 \x01(\x05\"D\n\x14\x44wc3EventFtraceEvent\x12\r\n\x05\x65vent\x18\x01 \x01(\r\x12\x10\n\x08\x65p0state\x18\x02 \x01(\r\x12\x0b\n\x03str\x18\x03 \x01(\t\"\xa1\x01\n\x1a\x44wc3FreeRequestFtraceEvent\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0b\n\x03req\x18\x02 \x01(\x04\x12\x0e\n\x06\x61\x63tual\x18\x03 \x01(\r\x12\x0e\n\x06length\x18\x04 \x01(\r\x12\x0e\n\x06status\x18\x05 \x01(\x05\x12\x0c\n\x04zero\x18\x06 \x01(\x05\x12\x14\n\x0cshort_not_ok\x18\x07 \x01(\x05\x12\x14\n\x0cno_interrupt\x18\x08 \x01(\x05\"{\n\x1a\x44wc3GadgetEpCmdFtraceEvent\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0b\n\x03\x63md\x18\x02 \x01(\r\x12\x0e\n\x06param0\x18\x03 \x01(\r\x12\x0e\n\x06param1\x18\x04 \x01(\r\x12\x0e\n\x06param2\x18\x05 \x01(\r\x12\x12\n\ncmd_status\x18\x06 \x01(\x05\"\xcd\x01\n\x1e\x44wc3GadgetEpDisableFtraceEvent\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x11\n\tmaxpacket\x18\x02 \x01(\r\x12\x17\n\x0fmaxpacket_limit\x18\x03 \x01(\r\x12\x13\n\x0bmax_streams\x18\x04 \x01(\r\x12\x10\n\x08maxburst\x18\x05 \x01(\r\x12\r\n\x05\x66lags\x18\x06 \x01(\r\x12\x11\n\tdirection\x18\x07 \x01(\r\x12\x13\n\x0btrb_enqueue\x18\x08 \x01(\r\x12\x13\n\x0btrb_dequeue\x18\t \x01(\r\"\xcc\x01\n\x1d\x44wc3GadgetEpEnableFtraceEvent\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x11\n\tmaxpacket\x18\x02 \x01(\r\x12\x17\n\x0fmaxpacket_limit\x18\x03 \x01(\r\x12\x13\n\x0bmax_streams\x18\x04 \x01(\r\x12\x10\n\x08maxburst\x18\x05 \x01(\r\x12\r\n\x05\x66lags\x18\x06 \x01(\r\x12\x11\n\tdirection\x18\x07 \x01(\r\x12\x13\n\x0btrb_enqueue\x18\x08 \x01(\r\x12\x13\n\x0btrb_dequeue\x18\t \x01(\r\"M\n\x1f\x44wc3GadgetGenericCmdFtraceEvent\x12\x0b\n\x03\x63md\x18\x01 \x01(\r\x12\r\n\x05param\x18\x02 \x01(\r\x12\x0e\n\x06status\x18\x03 \x01(\x05\"\xa4\x01\n\x1d\x44wc3GadgetGivebackFtraceEvent\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0b\n\x03req\x18\x02 \x01(\x04\x12\x0e\n\x06\x61\x63tual\x18\x03 \x01(\r\x12\x0e\n\x06length\x18\x04 \x01(\r\x12\x0e\n\x06status\x18\x05 \x01(\x05\x12\x0c\n\x04zero\x18\x06 \x01(\x05\x12\x14\n\x0cshort_not_ok\x18\x07 \x01(\x05\x12\x14\n\x0cno_interrupt\x18\x08 \x01(\x05\"\xbf\x01\n\x19\x44wc3PrepareTrbFtraceEvent\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0b\n\x03trb\x18\x02 \x01(\x04\x12\x11\n\tallocated\x18\x03 \x01(\r\x12\x0e\n\x06queued\x18\x04 \x01(\r\x12\x0b\n\x03\x62pl\x18\x05 \x01(\r\x12\x0b\n\x03\x62ph\x18\x06 \x01(\r\x12\x0c\n\x04size\x18\x07 \x01(\r\x12\x0c\n\x04\x63trl\x18\x08 \x01(\r\x12\x0c\n\x04type\x18\t \x01(\r\x12\x0f\n\x07\x65nqueue\x18\n \x01(\r\x12\x0f\n\x07\x64\x65queue\x18\x0b \x01(\r\"P\n\x14\x44wc3ReadlFtraceEvent\x12\x0c\n\x04\x62\x61se\x18\x01 \x01(\x04\x12\x0e\n\x06offset\x18\x02 \x01(\r\x12\r\n\x05value\x18\x03 \x01(\r\x12\x0b\n\x03msg\x18\x04 \x01(\t\"Q\n\x15\x44wc3WritelFtraceEvent\x12\x0c\n\x04\x62\x61se\x18\x01 \x01(\x04\x12\x0e\n\x06offset\x18\x02 \x01(\r\x12\r\n\x05value\x18\x03 \x01(\r\x12\x0b\n\x03msg\x18\x04 \x01(\t\"`\n\x1b\x45xt4DaWriteBeginFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x0b\n\x03pos\x18\x03 \x01(\x03\x12\x0b\n\x03len\x18\x04 \x01(\r\x12\r\n\x05\x66lags\x18\x05 \x01(\r\"_\n\x19\x45xt4DaWriteEndFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x0b\n\x03pos\x18\x03 \x01(\x03\x12\x0b\n\x03len\x18\x04 \x01(\r\x12\x0e\n\x06\x63opied\x18\x05 \x01(\r\"Z\n\x1c\x45xt4SyncFileEnterFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x0e\n\x06parent\x18\x03 \x01(\x04\x12\x10\n\x08\x64\x61tasync\x18\x04 \x01(\x05\"D\n\x1b\x45xt4SyncFileExitFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x0b\n\x03ret\x18\x03 \x01(\x05\"b\n\x1c\x45xt4AllocDaBlocksFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x13\n\x0b\x64\x61ta_blocks\x18\x03 \x01(\r\x12\x13\n\x0bmeta_blocks\x18\x04 \x01(\r\"\xc1\x01\n\x1d\x45xt4AllocateBlocksFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\r\n\x05\x62lock\x18\x03 \x01(\x04\x12\x0b\n\x03len\x18\x04 \x01(\r\x12\x0f\n\x07logical\x18\x05 \x01(\r\x12\r\n\x05lleft\x18\x06 \x01(\r\x12\x0e\n\x06lright\x18\x07 \x01(\r\x12\x0c\n\x04goal\x18\x08 \x01(\x04\x12\r\n\x05pleft\x18\t \x01(\x04\x12\x0e\n\x06pright\x18\n \x01(\x04\x12\r\n\x05\x66lags\x18\x0b \x01(\r\"S\n\x1c\x45xt4AllocateInodeFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x0b\n\x03\x64ir\x18\x03 \x01(\x04\x12\x0c\n\x04mode\x18\x04 \x01(\r\"Q\n#Ext4BeginOrderedTruncateFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x10\n\x08new_size\x18\x03 \x01(\x03\"U\n\x1c\x45xt4CollapseRangeFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x0e\n\x06offset\x18\x03 \x01(\x03\x12\x0b\n\x03len\x18\x04 \x01(\x03\"\xca\x01\n\x1d\x45xt4DaReleaseSpaceFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x10\n\x08i_blocks\x18\x03 \x01(\x04\x12\x14\n\x0c\x66reed_blocks\x18\x04 \x01(\x05\x12\x1c\n\x14reserved_data_blocks\x18\x05 \x01(\x05\x12\x1c\n\x14reserved_meta_blocks\x18\x06 \x01(\x05\x12\x1d\n\x15\x61llocated_meta_blocks\x18\x07 \x01(\x05\x12\x0c\n\x04mode\x18\x08 \x01(\r\"\xa8\x01\n\x1d\x45xt4DaReserveSpaceFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x10\n\x08i_blocks\x18\x03 \x01(\x04\x12\x1c\n\x14reserved_data_blocks\x18\x04 \x01(\x05\x12\x1c\n\x14reserved_meta_blocks\x18\x05 \x01(\x05\x12\x0c\n\x04mode\x18\x06 \x01(\r\x12\x11\n\tmd_needed\x18\x07 \x01(\x05\"\xe4\x01\n#Ext4DaUpdateReserveSpaceFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x10\n\x08i_blocks\x18\x03 \x01(\x04\x12\x13\n\x0bused_blocks\x18\x04 \x01(\x05\x12\x1c\n\x14reserved_data_blocks\x18\x05 \x01(\x05\x12\x1c\n\x14reserved_meta_blocks\x18\x06 \x01(\x05\x12\x1d\n\x15\x61llocated_meta_blocks\x18\x07 \x01(\x05\x12\x13\n\x0bquota_claim\x18\x08 \x01(\x05\x12\x0c\n\x04mode\x18\t \x01(\r\"\xcf\x01\n\x1b\x45xt4DaWritePagesFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x12\n\nfirst_page\x18\x03 \x01(\x04\x12\x13\n\x0bnr_to_write\x18\x04 \x01(\x03\x12\x11\n\tsync_mode\x18\x05 \x01(\x05\x12\x11\n\tb_blocknr\x18\x06 \x01(\x04\x12\x0e\n\x06\x62_size\x18\x07 \x01(\r\x12\x0f\n\x07\x62_state\x18\x08 \x01(\r\x12\x0f\n\x07io_done\x18\t \x01(\x05\x12\x15\n\rpages_written\x18\n \x01(\x05\"g\n!Ext4DaWritePagesExtentFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x0c\n\x04lblk\x18\x03 \x01(\x04\x12\x0b\n\x03len\x18\x04 \x01(\r\x12\r\n\x05\x66lags\x18\x05 \x01(\r\"^\n\x1c\x45xt4DirectIOEnterFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x0b\n\x03pos\x18\x03 \x01(\x03\x12\x0b\n\x03len\x18\x04 \x01(\x04\x12\n\n\x02rw\x18\x05 \x01(\x05\"j\n\x1b\x45xt4DirectIOExitFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x0b\n\x03pos\x18\x03 \x01(\x03\x12\x0b\n\x03len\x18\x04 \x01(\x04\x12\n\n\x02rw\x18\x05 \x01(\x05\x12\x0b\n\x03ret\x18\x06 \x01(\x05\"G\n\x1c\x45xt4DiscardBlocksFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03\x62lk\x18\x02 \x01(\x04\x12\r\n\x05\x63ount\x18\x03 \x01(\x04\"]\n$Ext4DiscardPreallocationsFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x0b\n\x03len\x18\x03 \x01(\r\x12\x0e\n\x06needed\x18\x04 \x01(\r\"B\n\x18\x45xt4DropInodeFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x0c\n\x04\x64rop\x18\x03 \x01(\x05\"q\n\x1c\x45xt4EsCacheExtentFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x0c\n\x04lblk\x18\x03 \x01(\r\x12\x0b\n\x03len\x18\x04 \x01(\r\x12\x0c\n\x04pblk\x18\x05 \x01(\x04\x12\x0e\n\x06status\x18\x06 \x01(\r\"V\n,Ext4EsFindDelayedExtentRangeEnterFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x0c\n\x04lblk\x18\x03 \x01(\r\"\x80\x01\n+Ext4EsFindDelayedExtentRangeExitFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x0c\n\x04lblk\x18\x03 \x01(\r\x12\x0b\n\x03len\x18\x04 \x01(\r\x12\x0c\n\x04pblk\x18\x05 \x01(\x04\x12\x0e\n\x06status\x18\x06 \x01(\x04\"r\n\x1d\x45xt4EsInsertExtentFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x0c\n\x04lblk\x18\x03 \x01(\r\x12\x0b\n\x03len\x18\x04 \x01(\r\x12\x0c\n\x04pblk\x18\x05 \x01(\x04\x12\x0e\n\x06status\x18\x06 \x01(\x04\"L\n\"Ext4EsLookupExtentEnterFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x0c\n\x04lblk\x18\x03 \x01(\r\"\x85\x01\n!Ext4EsLookupExtentExitFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x0c\n\x04lblk\x18\x03 \x01(\r\x12\x0b\n\x03len\x18\x04 \x01(\r\x12\x0c\n\x04pblk\x18\x05 \x01(\x04\x12\x0e\n\x06status\x18\x06 \x01(\x04\x12\r\n\x05\x66ound\x18\x07 \x01(\x05\"T\n\x1d\x45xt4EsRemoveExtentFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x0c\n\x04lblk\x18\x03 \x01(\x03\x12\x0b\n\x03len\x18\x04 \x01(\x03\"q\n\x17\x45xt4EsShrinkFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x11\n\tnr_shrunk\x18\x02 \x01(\x05\x12\x11\n\tscan_time\x18\x03 \x01(\x04\x12\x12\n\nnr_skipped\x18\x04 \x01(\x05\x12\x0f\n\x07retried\x18\x05 \x01(\x05\"R\n\x1c\x45xt4EsShrinkCountFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x12\n\nnr_to_scan\x18\x02 \x01(\x05\x12\x11\n\tcache_cnt\x18\x03 \x01(\x05\"V\n Ext4EsShrinkScanEnterFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x12\n\nnr_to_scan\x18\x02 \x01(\x05\x12\x11\n\tcache_cnt\x18\x03 \x01(\x05\"T\n\x1f\x45xt4EsShrinkScanExitFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x11\n\tnr_shrunk\x18\x02 \x01(\x05\x12\x11\n\tcache_cnt\x18\x03 \x01(\x05\"D\n\x19\x45xt4EvictInodeFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\r\n\x05nlink\x18\x03 \x01(\x05\"\x95\x01\n+Ext4ExtConvertToInitializedEnterFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x0e\n\x06m_lblk\x18\x03 \x01(\r\x12\r\n\x05m_len\x18\x04 \x01(\r\x12\x0e\n\x06u_lblk\x18\x05 \x01(\r\x12\r\n\x05u_len\x18\x06 \x01(\r\x12\x0e\n\x06u_pblk\x18\x07 \x01(\x04\"\xc7\x01\n.Ext4ExtConvertToInitializedFastpathFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x0e\n\x06m_lblk\x18\x03 \x01(\r\x12\r\n\x05m_len\x18\x04 \x01(\r\x12\x0e\n\x06u_lblk\x18\x05 \x01(\r\x12\r\n\x05u_len\x18\x06 \x01(\r\x12\x0e\n\x06u_pblk\x18\x07 \x01(\x04\x12\x0e\n\x06i_lblk\x18\x08 \x01(\r\x12\r\n\x05i_len\x18\t \x01(\r\x12\x0e\n\x06i_pblk\x18\n \x01(\x04\"\x9f\x01\n(Ext4ExtHandleUnwrittenExtentsFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\r\n\x05\x66lags\x18\x03 \x01(\x05\x12\x0c\n\x04lblk\x18\x04 \x01(\r\x12\x0c\n\x04pblk\x18\x05 \x01(\x04\x12\x0b\n\x03len\x18\x06 \x01(\r\x12\x11\n\tallocated\x18\x07 \x01(\r\x12\x0e\n\x06newblk\x18\x08 \x01(\x04\"P\n\x19\x45xt4ExtInCacheFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x0c\n\x04lblk\x18\x03 \x01(\r\x12\x0b\n\x03ret\x18\x04 \x01(\x05\"T\n\x1c\x45xt4ExtLoadExtentFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x0c\n\x04pblk\x18\x03 \x01(\x04\x12\x0c\n\x04lblk\x18\x04 \x01(\r\"f\n Ext4ExtMapBlocksEnterFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x0c\n\x04lblk\x18\x03 \x01(\r\x12\x0b\n\x03len\x18\x04 \x01(\r\x12\r\n\x05\x66lags\x18\x05 \x01(\r\"\x90\x01\n\x1f\x45xt4ExtMapBlocksExitFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\r\n\x05\x66lags\x18\x03 \x01(\r\x12\x0c\n\x04pblk\x18\x04 \x01(\x04\x12\x0c\n\x04lblk\x18\x05 \x01(\r\x12\x0b\n\x03len\x18\x06 \x01(\r\x12\x0e\n\x06mflags\x18\x07 \x01(\r\x12\x0b\n\x03ret\x18\x08 \x01(\x05\"b\n\x1c\x45xt4ExtPutInCacheFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x0c\n\x04lblk\x18\x03 \x01(\r\x12\x0b\n\x03len\x18\x04 \x01(\r\x12\r\n\x05start\x18\x05 \x01(\x04\"d\n\x1d\x45xt4ExtRemoveSpaceFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\r\n\x05start\x18\x03 \x01(\r\x12\x0b\n\x03\x65nd\x18\x04 \x01(\r\x12\r\n\x05\x64\x65pth\x18\x05 \x01(\x05\"\xc1\x01\n!Ext4ExtRemoveSpaceDoneFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\r\n\x05start\x18\x03 \x01(\r\x12\x0b\n\x03\x65nd\x18\x04 \x01(\r\x12\r\n\x05\x64\x65pth\x18\x05 \x01(\x05\x12\x0f\n\x07partial\x18\x06 \x01(\x03\x12\x12\n\neh_entries\x18\x07 \x01(\r\x12\x0f\n\x07pc_lblk\x18\x08 \x01(\r\x12\x0f\n\x07pc_pclu\x18\t \x01(\x04\x12\x10\n\x08pc_state\x18\n \x01(\x05\"A\n\x17\x45xt4ExtRmIdxFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x0c\n\x04pblk\x18\x03 \x01(\x04\"\xba\x01\n\x18\x45xt4ExtRmLeafFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x0f\n\x07partial\x18\x03 \x01(\x03\x12\r\n\x05start\x18\x04 \x01(\r\x12\x0f\n\x07\x65\x65_lblk\x18\x05 \x01(\r\x12\x0f\n\x07\x65\x65_pblk\x18\x06 \x01(\x04\x12\x0e\n\x06\x65\x65_len\x18\x07 \x01(\x05\x12\x0f\n\x07pc_lblk\x18\x08 \x01(\r\x12\x0f\n\x07pc_pclu\x18\t \x01(\x04\x12\x10\n\x08pc_state\x18\n \x01(\x05\"a\n\x1c\x45xt4ExtShowExtentFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x0c\n\x04pblk\x18\x03 \x01(\x04\x12\x0c\n\x04lblk\x18\x04 \x01(\r\x12\x0b\n\x03len\x18\x05 \x01(\r\"q\n\x1d\x45xt4FallocateEnterFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x0e\n\x06offset\x18\x03 \x01(\x03\x12\x0b\n\x03len\x18\x04 \x01(\x03\x12\x0c\n\x04mode\x18\x05 \x01(\x05\x12\x0b\n\x03pos\x18\x06 \x01(\x03\"b\n\x1c\x45xt4FallocateExitFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x0b\n\x03pos\x18\x03 \x01(\x03\x12\x0e\n\x06\x62locks\x18\x04 \x01(\r\x12\x0b\n\x03ret\x18\x05 \x01(\x05\"\x89\x01\n Ext4FindDelallocRangeFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x0c\n\x04\x66rom\x18\x03 \x01(\r\x12\n\n\x02to\x18\x04 \x01(\r\x12\x0f\n\x07reverse\x18\x05 \x01(\x05\x12\r\n\x05\x66ound\x18\x06 \x01(\x05\x12\x11\n\tfound_blk\x18\x07 \x01(\r\"c\n\x15\x45xt4ForgetFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\r\n\x05\x62lock\x18\x03 \x01(\x04\x12\x13\n\x0bis_metadata\x18\x04 \x01(\x05\x12\x0c\n\x04mode\x18\x05 \x01(\r\"p\n\x19\x45xt4FreeBlocksFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\r\n\x05\x62lock\x18\x03 \x01(\x04\x12\r\n\x05\x63ount\x18\x04 \x01(\x04\x12\r\n\x05\x66lags\x18\x05 \x01(\x05\x12\x0c\n\x04mode\x18\x06 \x01(\r\"l\n\x18\x45xt4FreeInodeFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x0b\n\x03uid\x18\x03 \x01(\r\x12\x0b\n\x03gid\x18\x04 \x01(\r\x12\x0e\n\x06\x62locks\x18\x05 \x01(\x04\x12\x0c\n\x04mode\x18\x06 \x01(\r\"}\n)Ext4GetImpliedClusterAllocExitFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\r\n\x05\x66lags\x18\x02 \x01(\r\x12\x0c\n\x04lblk\x18\x03 \x01(\r\x12\x0c\n\x04pblk\x18\x04 \x01(\x04\x12\x0b\n\x03len\x18\x05 \x01(\r\x12\x0b\n\x03ret\x18\x06 \x01(\x05\"]\n&Ext4GetReservedClusterAllocFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x0c\n\x04lblk\x18\x03 \x01(\r\x12\x0b\n\x03len\x18\x04 \x01(\r\"f\n Ext4IndMapBlocksEnterFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x0c\n\x04lblk\x18\x03 \x01(\r\x12\x0b\n\x03len\x18\x04 \x01(\r\x12\r\n\x05\x66lags\x18\x05 \x01(\r\"\x90\x01\n\x1f\x45xt4IndMapBlocksExitFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\r\n\x05\x66lags\x18\x03 \x01(\r\x12\x0c\n\x04pblk\x18\x04 \x01(\x04\x12\x0c\n\x04lblk\x18\x05 \x01(\r\x12\x0b\n\x03len\x18\x06 \x01(\r\x12\x0e\n\x06mflags\x18\x07 \x01(\r\x12\x0b\n\x03ret\x18\x08 \x01(\x05\"S\n\x1a\x45xt4InsertRangeFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x0e\n\x06offset\x18\x03 \x01(\x03\x12\x0b\n\x03len\x18\x04 \x01(\x03\"h\n\x1d\x45xt4InvalidatepageFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\r\n\x05index\x18\x03 \x01(\x04\x12\x0e\n\x06offset\x18\x04 \x01(\x04\x12\x0e\n\x06length\x18\x05 \x01(\r\"\x81\x01\n\x1b\x45xt4JournalStartFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\n\n\x02ip\x18\x02 \x01(\x04\x12\x0e\n\x06\x62locks\x18\x03 \x01(\x05\x12\x12\n\nrsv_blocks\x18\x04 \x01(\x05\x12\x0f\n\x07nblocks\x18\x05 \x01(\x05\x12\x14\n\x0crevoke_creds\x18\x06 \x01(\x05\"N\n#Ext4JournalStartReservedFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\n\n\x02ip\x18\x02 \x01(\x04\x12\x0e\n\x06\x62locks\x18\x03 \x01(\x05\"r\n\'Ext4JournalledInvalidatepageFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\r\n\x05index\x18\x03 \x01(\x04\x12\x0e\n\x06offset\x18\x04 \x01(\x04\x12\x0e\n\x06length\x18\x05 \x01(\r\"g\n!Ext4JournalledWriteEndFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x0b\n\x03pos\x18\x03 \x01(\x03\x12\x0b\n\x03len\x18\x04 \x01(\r\x12\x0e\n\x06\x63opied\x18\x05 \x01(\r\"4\n\x18\x45xt4LoadInodeFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\"<\n\x1e\x45xt4LoadInodeBitmapFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\r\n\x05group\x18\x02 \x01(\r\"E\n\x1d\x45xt4MarkInodeDirtyFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\n\n\x02ip\x18\x03 \x01(\x04\"9\n\x1b\x45xt4MbBitmapLoadFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\r\n\x05group\x18\x02 \x01(\r\">\n Ext4MbBuddyBitmapLoadFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\r\n\x05group\x18\x02 \x01(\r\"E\n&Ext4MbDiscardPreallocationsFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0e\n\x06needed\x18\x02 \x01(\x05\"m\n\x1b\x45xt4MbNewGroupPaFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x11\n\tpa_pstart\x18\x03 \x01(\x04\x12\x11\n\tpa_lstart\x18\x04 \x01(\x04\x12\x0e\n\x06pa_len\x18\x05 \x01(\r\"m\n\x1b\x45xt4MbNewInodePaFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x11\n\tpa_pstart\x18\x03 \x01(\x04\x12\x11\n\tpa_lstart\x18\x04 \x01(\x04\x12\x0e\n\x06pa_len\x18\x05 \x01(\r\"Q\n\x1f\x45xt4MbReleaseGroupPaFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x11\n\tpa_pstart\x18\x02 \x01(\x04\x12\x0e\n\x06pa_len\x18\x03 \x01(\r\"Y\n\x1f\x45xt4MbReleaseInodePaFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\r\n\x05\x62lock\x18\x03 \x01(\x04\x12\r\n\x05\x63ount\x18\x04 \x01(\r\"\x86\x03\n\x1b\x45xt4MballocAllocFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x14\n\x0corig_logical\x18\x03 \x01(\r\x12\x12\n\norig_start\x18\x04 \x01(\x05\x12\x12\n\norig_group\x18\x05 \x01(\r\x12\x10\n\x08orig_len\x18\x06 \x01(\x05\x12\x14\n\x0cgoal_logical\x18\x07 \x01(\r\x12\x12\n\ngoal_start\x18\x08 \x01(\x05\x12\x12\n\ngoal_group\x18\t \x01(\r\x12\x10\n\x08goal_len\x18\n \x01(\x05\x12\x16\n\x0eresult_logical\x18\x0b \x01(\r\x12\x14\n\x0cresult_start\x18\x0c \x01(\x05\x12\x14\n\x0cresult_group\x18\r \x01(\r\x12\x12\n\nresult_len\x18\x0e \x01(\x05\x12\r\n\x05\x66ound\x18\x0f \x01(\r\x12\x0e\n\x06groups\x18\x10 \x01(\r\x12\r\n\x05\x62uddy\x18\x11 \x01(\r\x12\r\n\x05\x66lags\x18\x12 \x01(\r\x12\x0c\n\x04tail\x18\x13 \x01(\r\x12\n\n\x02\x63r\x18\x14 \x01(\r\"y\n\x1d\x45xt4MballocDiscardFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x14\n\x0cresult_start\x18\x03 \x01(\x05\x12\x14\n\x0cresult_group\x18\x04 \x01(\r\x12\x12\n\nresult_len\x18\x05 \x01(\x05\"v\n\x1a\x45xt4MballocFreeFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x14\n\x0cresult_start\x18\x03 \x01(\x05\x12\x14\n\x0cresult_group\x18\x04 \x01(\r\x12\x12\n\nresult_len\x18\x05 \x01(\x05\"\xe2\x01\n\x1e\x45xt4MballocPreallocFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x14\n\x0corig_logical\x18\x03 \x01(\r\x12\x12\n\norig_start\x18\x04 \x01(\x05\x12\x12\n\norig_group\x18\x05 \x01(\r\x12\x10\n\x08orig_len\x18\x06 \x01(\x05\x12\x16\n\x0eresult_logical\x18\x07 \x01(\r\x12\x14\n\x0cresult_start\x18\x08 \x01(\x05\x12\x14\n\x0cresult_group\x18\t \x01(\r\x12\x12\n\nresult_len\x18\n \x01(\x05\"y\n#Ext4OtherInodeUpdateTimeFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x10\n\x08orig_ino\x18\x03 \x01(\x04\x12\x0b\n\x03uid\x18\x04 \x01(\r\x12\x0b\n\x03gid\x18\x05 \x01(\r\x12\x0c\n\x04mode\x18\x06 \x01(\r\"_\n\x18\x45xt4PunchHoleFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x0e\n\x06offset\x18\x03 \x01(\x03\x12\x0b\n\x03len\x18\x04 \x01(\x03\x12\x0c\n\x04mode\x18\x05 \x01(\x05\"R\n\"Ext4ReadBlockBitmapLoadFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\r\n\x05group\x18\x02 \x01(\r\x12\x10\n\x08prefetch\x18\x03 \x01(\r\"B\n\x17\x45xt4ReadpageFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\r\n\x05index\x18\x03 \x01(\x04\"E\n\x1a\x45xt4ReleasepageFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\r\n\x05index\x18\x03 \x01(\x04\"\xc8\x01\n\x1b\x45xt4RemoveBlocksFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x0c\n\x04\x66rom\x18\x03 \x01(\r\x12\n\n\x02to\x18\x04 \x01(\r\x12\x0f\n\x07partial\x18\x05 \x01(\x03\x12\x0f\n\x07\x65\x65_pblk\x18\x06 \x01(\x04\x12\x0f\n\x07\x65\x65_lblk\x18\x07 \x01(\r\x12\x0e\n\x06\x65\x65_len\x18\x08 \x01(\r\x12\x0f\n\x07pc_lblk\x18\t \x01(\r\x12\x0f\n\x07pc_pclu\x18\n \x01(\x04\x12\x10\n\x08pc_state\x18\x0b \x01(\x05\"\xb1\x01\n\x1c\x45xt4RequestBlocksFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x0b\n\x03len\x18\x03 \x01(\r\x12\x0f\n\x07logical\x18\x04 \x01(\r\x12\r\n\x05lleft\x18\x05 \x01(\r\x12\x0e\n\x06lright\x18\x06 \x01(\r\x12\x0c\n\x04goal\x18\x07 \x01(\x04\x12\r\n\x05pleft\x18\x08 \x01(\x04\x12\x0e\n\x06pright\x18\t \x01(\x04\x12\r\n\x05\x66lags\x18\n \x01(\r\"E\n\x1b\x45xt4RequestInodeFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03\x64ir\x18\x02 \x01(\x04\x12\x0c\n\x04mode\x18\x03 \x01(\r\"2\n\x15\x45xt4SyncFsFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0c\n\x04wait\x18\x02 \x01(\x05\"m\n\x1a\x45xt4TrimAllFreeFtraceEvent\x12\x11\n\tdev_major\x18\x01 \x01(\x05\x12\x11\n\tdev_minor\x18\x02 \x01(\x05\x12\r\n\x05group\x18\x03 \x01(\r\x12\r\n\x05start\x18\x04 \x01(\x05\x12\x0b\n\x03len\x18\x05 \x01(\x05\"l\n\x19\x45xt4TrimExtentFtraceEvent\x12\x11\n\tdev_major\x18\x01 \x01(\x05\x12\x11\n\tdev_minor\x18\x02 \x01(\x05\x12\r\n\x05group\x18\x03 \x01(\r\x12\r\n\x05start\x18\x04 \x01(\x05\x12\x0b\n\x03len\x18\x05 \x01(\x05\"H\n\x1c\x45xt4TruncateEnterFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x0e\n\x06\x62locks\x18\x03 \x01(\x04\"G\n\x1b\x45xt4TruncateExitFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x0e\n\x06\x62locks\x18\x03 \x01(\x04\"T\n\x1a\x45xt4UnlinkEnterFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x0e\n\x06parent\x18\x03 \x01(\x04\x12\x0c\n\x04size\x18\x04 \x01(\x03\"B\n\x19\x45xt4UnlinkExitFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x0b\n\x03ret\x18\x03 \x01(\x05\"^\n\x19\x45xt4WriteBeginFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x0b\n\x03pos\x18\x03 \x01(\x03\x12\x0b\n\x03len\x18\x04 \x01(\r\x12\r\n\x05\x66lags\x18\x05 \x01(\r\"]\n\x17\x45xt4WriteEndFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x0b\n\x03pos\x18\x03 \x01(\x03\x12\x0b\n\x03len\x18\x04 \x01(\r\x12\x0e\n\x06\x63opied\x18\x05 \x01(\r\"C\n\x18\x45xt4WritepageFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\r\n\x05index\x18\x03 \x01(\x04\"\xe0\x01\n\x19\x45xt4WritepagesFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x13\n\x0bnr_to_write\x18\x03 \x01(\x03\x12\x15\n\rpages_skipped\x18\x04 \x01(\x03\x12\x13\n\x0brange_start\x18\x05 \x01(\x03\x12\x11\n\trange_end\x18\x06 \x01(\x03\x12\x17\n\x0fwriteback_index\x18\x07 \x01(\x04\x12\x11\n\tsync_mode\x18\x08 \x01(\x05\x12\x13\n\x0b\x66or_kupdate\x18\t \x01(\r\x12\x14\n\x0crange_cyclic\x18\n \x01(\r\"\xa2\x01\n\x1f\x45xt4WritepagesResultFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x0b\n\x03ret\x18\x03 \x01(\x05\x12\x15\n\rpages_written\x18\x04 \x01(\x05\x12\x15\n\rpages_skipped\x18\x05 \x01(\x03\x12\x17\n\x0fwriteback_index\x18\x06 \x01(\x04\x12\x11\n\tsync_mode\x18\x07 \x01(\x05\"_\n\x18\x45xt4ZeroRangeFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x0e\n\x06offset\x18\x03 \x01(\x03\x12\x0b\n\x03len\x18\x04 \x01(\x03\x12\x0c\n\x04mode\x18\x05 \x01(\x05\"d\n\x1a\x46\x32\x66sDoSubmitBioFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\r\n\x05\x62type\x18\x02 \x01(\x05\x12\x0c\n\x04sync\x18\x03 \x01(\r\x12\x0e\n\x06sector\x18\x04 \x01(\x04\x12\x0c\n\x04size\x18\x05 \x01(\r\"\x8e\x01\n\x19\x46\x32\x66sEvictInodeFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x0c\n\x04pino\x18\x03 \x01(\x04\x12\x0c\n\x04mode\x18\x04 \x01(\r\x12\x0c\n\x04size\x18\x05 \x01(\x03\x12\r\n\x05nlink\x18\x06 \x01(\r\x12\x0e\n\x06\x62locks\x18\x07 \x01(\x04\x12\x0e\n\x06\x61\x64vise\x18\x08 \x01(\r\"\x8a\x01\n\x18\x46\x32\x66sFallocateFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x0c\n\x04mode\x18\x03 \x01(\x05\x12\x0e\n\x06offset\x18\x04 \x01(\x03\x12\x0b\n\x03len\x18\x05 \x01(\x03\x12\x0c\n\x04size\x18\x06 \x01(\x03\x12\x0e\n\x06\x62locks\x18\x07 \x01(\x04\x12\x0b\n\x03ret\x18\x08 \x01(\x05\"w\n\x1b\x46\x32\x66sGetDataBlockFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x0e\n\x06iblock\x18\x03 \x01(\x04\x12\x10\n\x08\x62h_start\x18\x04 \x01(\x04\x12\x0f\n\x07\x62h_size\x18\x05 \x01(\x04\x12\x0b\n\x03ret\x18\x06 \x01(\x05\"\xce\x01\n\x18\x46\x32\x66sGetVictimFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0c\n\x04type\x18\x02 \x01(\x05\x12\x0f\n\x07gc_type\x18\x03 \x01(\x05\x12\x12\n\nalloc_mode\x18\x04 \x01(\x05\x12\x0f\n\x07gc_mode\x18\x05 \x01(\x05\x12\x0e\n\x06victim\x18\x06 \x01(\r\x12\x10\n\x08ofs_unit\x18\x07 \x01(\r\x12\x12\n\npre_victim\x18\x08 \x01(\r\x12\x0f\n\x07prefree\x18\t \x01(\r\x12\x0c\n\x04\x66ree\x18\n \x01(\r\x12\x0c\n\x04\x63ost\x18\x0b \x01(\r\"\x88\x01\n\x13\x46\x32\x66sIgetFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x0c\n\x04pino\x18\x03 \x01(\x04\x12\x0c\n\x04mode\x18\x04 \x01(\r\x12\x0c\n\x04size\x18\x05 \x01(\x03\x12\r\n\x05nlink\x18\x06 \x01(\r\x12\x0e\n\x06\x62locks\x18\x07 \x01(\x04\x12\x0e\n\x06\x61\x64vise\x18\x08 \x01(\r\"@\n\x17\x46\x32\x66sIgetExitFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x0b\n\x03ret\x18\x03 \x01(\x05\"@\n\x17\x46\x32\x66sNewInodeFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x0b\n\x03ret\x18\x03 \x01(\x05\"\x8f\x01\n\x17\x46\x32\x66sReadpageFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\r\n\x05index\x18\x03 \x01(\x04\x12\x0f\n\x07\x62lkaddr\x18\x04 \x01(\x04\x12\x0c\n\x04type\x18\x05 \x01(\x05\x12\x0b\n\x03\x64ir\x18\x06 \x01(\x05\x12\r\n\x05\x64irty\x18\x07 \x01(\x05\x12\x10\n\x08uptodate\x18\x08 \x01(\x05\"O\n\x1e\x46\x32\x66sReserveNewBlockFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03nid\x18\x02 \x01(\r\x12\x13\n\x0bofs_in_node\x18\x03 \x01(\r\"\x82\x01\n\x1b\x46\x32\x66sSetPageDirtyFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x0c\n\x04type\x18\x03 \x01(\x05\x12\x0b\n\x03\x64ir\x18\x04 \x01(\x05\x12\r\n\x05index\x18\x05 \x01(\x04\x12\r\n\x05\x64irty\x18\x06 \x01(\x05\x12\x10\n\x08uptodate\x18\x07 \x01(\x05\"f\n\x1e\x46\x32\x66sSubmitWritePageFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x0c\n\x04type\x18\x03 \x01(\x05\x12\r\n\x05index\x18\x04 \x01(\x04\x12\r\n\x05\x62lock\x18\x05 \x01(\r\"\x91\x01\n\x1c\x46\x32\x66sSyncFileEnterFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x0c\n\x04pino\x18\x03 \x01(\x04\x12\x0c\n\x04mode\x18\x04 \x01(\r\x12\x0c\n\x04size\x18\x05 \x01(\x03\x12\r\n\x05nlink\x18\x06 \x01(\r\x12\x0e\n\x06\x62locks\x18\x07 \x01(\x04\x12\x0e\n\x06\x61\x64vise\x18\x08 \x01(\r\"z\n\x1b\x46\x32\x66sSyncFileExitFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x0f\n\x07need_cp\x18\x03 \x01(\r\x12\x10\n\x08\x64\x61tasync\x18\x04 \x01(\x05\x12\x0b\n\x03ret\x18\x05 \x01(\x05\x12\x11\n\tcp_reason\x18\x06 \x01(\x05\"A\n\x15\x46\x32\x66sSyncFsFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\r\n\x05\x64irty\x18\x02 \x01(\x05\x12\x0c\n\x04wait\x18\x03 \x01(\x05\"\x8c\x01\n\x17\x46\x32\x66sTruncateFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x0c\n\x04pino\x18\x03 \x01(\x04\x12\x0c\n\x04mode\x18\x04 \x01(\r\x12\x0c\n\x04size\x18\x05 \x01(\x03\x12\r\n\x05nlink\x18\x06 \x01(\r\x12\x0e\n\x06\x62locks\x18\x07 \x01(\x04\x12\x0e\n\x06\x61\x64vise\x18\x08 \x01(\r\"j\n\"F2fsTruncateBlocksEnterFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x0c\n\x04size\x18\x03 \x01(\x03\x12\x0e\n\x06\x62locks\x18\x04 \x01(\x04\x12\x0c\n\x04\x66rom\x18\x05 \x01(\x04\"J\n!F2fsTruncateBlocksExitFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x0b\n\x03ret\x18\x03 \x01(\x05\"j\n&F2fsTruncateDataBlocksRangeFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x0b\n\x03nid\x18\x03 \x01(\r\x12\x0b\n\x03ofs\x18\x04 \x01(\r\x12\x0c\n\x04\x66ree\x18\x05 \x01(\x05\"o\n\'F2fsTruncateInodeBlocksEnterFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x0c\n\x04size\x18\x03 \x01(\x03\x12\x0e\n\x06\x62locks\x18\x04 \x01(\x04\x12\x0c\n\x04\x66rom\x18\x05 \x01(\x04\"O\n&F2fsTruncateInodeBlocksExitFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x0b\n\x03ret\x18\x03 \x01(\x05\"V\n\x1b\x46\x32\x66sTruncateNodeFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x0b\n\x03nid\x18\x03 \x01(\r\x12\x10\n\x08\x62lk_addr\x18\x04 \x01(\r\"\\\n!F2fsTruncateNodesEnterFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x0b\n\x03nid\x18\x03 \x01(\r\x12\x10\n\x08\x62lk_addr\x18\x04 \x01(\r\"I\n F2fsTruncateNodesExitFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x0b\n\x03ret\x18\x03 \x01(\x05\"h\n#F2fsTruncatePartialNodesFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x0b\n\x03nid\x18\x03 \x01(\r\x12\r\n\x05\x64\x65pth\x18\x04 \x01(\x05\x12\x0b\n\x03\x65rr\x18\x05 \x01(\x05\"b\n\x1a\x46\x32\x66sUnlinkEnterFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x0c\n\x04size\x18\x03 \x01(\x03\x12\x0e\n\x06\x62locks\x18\x04 \x01(\x04\x12\x0c\n\x04name\x18\x05 \x01(\t\"B\n\x19\x46\x32\x66sUnlinkExitFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x0b\n\x03ret\x18\x03 \x01(\x05\"\x83\x01\n\x1c\x46\x32\x66sVmPageMkwriteFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x0c\n\x04type\x18\x03 \x01(\x05\x12\x0b\n\x03\x64ir\x18\x04 \x01(\x05\x12\r\n\x05index\x18\x05 \x01(\x04\x12\r\n\x05\x64irty\x18\x06 \x01(\x05\x12\x10\n\x08uptodate\x18\x07 \x01(\x05\"^\n\x19\x46\x32\x66sWriteBeginFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x0b\n\x03pos\x18\x03 \x01(\x03\x12\x0b\n\x03len\x18\x04 \x01(\r\x12\r\n\x05\x66lags\x18\x05 \x01(\r\"l\n\x1e\x46\x32\x66sWriteCheckpointFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x11\n\tis_umount\x18\x02 \x01(\r\x12\x0b\n\x03msg\x18\x03 \x01(\t\x12\x0e\n\x06reason\x18\x04 \x01(\x05\x12\r\n\x05phase\x18\x05 \x01(\r\"]\n\x17\x46\x32\x66sWriteEndFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x0b\n\x03pos\x18\x03 \x01(\x03\x12\x0b\n\x03len\x18\x04 \x01(\r\x12\x0e\n\x06\x63opied\x18\x05 \x01(\r\"\xa9\x03\n\x15\x46\x32\x66sIostatFtraceEvent\x12\x0f\n\x07\x61pp_bio\x18\x01 \x01(\x04\x12\x10\n\x08\x61pp_brio\x18\x02 \x01(\x04\x12\x0f\n\x07\x61pp_dio\x18\x03 \x01(\x04\x12\x10\n\x08\x61pp_drio\x18\x04 \x01(\x04\x12\x0f\n\x07\x61pp_mio\x18\x05 \x01(\x04\x12\x10\n\x08\x61pp_mrio\x18\x06 \x01(\x04\x12\x0f\n\x07\x61pp_rio\x18\x07 \x01(\x04\x12\x0f\n\x07\x61pp_wio\x18\x08 \x01(\x04\x12\x0b\n\x03\x64\x65v\x18\t \x01(\x04\x12\x10\n\x08\x66s_cdrio\x18\n \x01(\x04\x12\x11\n\tfs_cp_dio\x18\x0b \x01(\x04\x12\x11\n\tfs_cp_mio\x18\x0c \x01(\x04\x12\x11\n\tfs_cp_nio\x18\r \x01(\x04\x12\x0e\n\x06\x66s_dio\x18\x0e \x01(\x04\x12\x12\n\nfs_discard\x18\x0f \x01(\x04\x12\x0f\n\x07\x66s_drio\x18\x10 \x01(\x04\x12\x11\n\tfs_gc_dio\x18\x11 \x01(\x04\x12\x11\n\tfs_gc_nio\x18\x12 \x01(\x04\x12\x10\n\x08\x66s_gdrio\x18\x13 \x01(\x04\x12\x0e\n\x06\x66s_mio\x18\x14 \x01(\x04\x12\x0f\n\x07\x66s_mrio\x18\x15 \x01(\x04\x12\x0e\n\x06\x66s_nio\x18\x16 \x01(\x04\x12\x0f\n\x07\x66s_nrio\x18\x17 \x01(\x04\"\xc7\x04\n\x1c\x46\x32\x66sIostatLatencyFtraceEvent\x12\x10\n\x08\x64_rd_avg\x18\x01 \x01(\r\x12\x10\n\x08\x64_rd_cnt\x18\x02 \x01(\r\x12\x11\n\td_rd_peak\x18\x03 \x01(\r\x12\x13\n\x0b\x64_wr_as_avg\x18\x04 \x01(\r\x12\x13\n\x0b\x64_wr_as_cnt\x18\x05 \x01(\r\x12\x14\n\x0c\x64_wr_as_peak\x18\x06 \x01(\r\x12\x12\n\nd_wr_s_avg\x18\x07 \x01(\r\x12\x12\n\nd_wr_s_cnt\x18\x08 \x01(\r\x12\x13\n\x0b\x64_wr_s_peak\x18\t \x01(\r\x12\x0b\n\x03\x64\x65v\x18\n \x01(\x04\x12\x10\n\x08m_rd_avg\x18\x0b \x01(\r\x12\x10\n\x08m_rd_cnt\x18\x0c \x01(\r\x12\x11\n\tm_rd_peak\x18\r \x01(\r\x12\x13\n\x0bm_wr_as_avg\x18\x0e \x01(\r\x12\x13\n\x0bm_wr_as_cnt\x18\x0f \x01(\r\x12\x14\n\x0cm_wr_as_peak\x18\x10 \x01(\r\x12\x12\n\nm_wr_s_avg\x18\x11 \x01(\r\x12\x12\n\nm_wr_s_cnt\x18\x12 \x01(\r\x12\x13\n\x0bm_wr_s_peak\x18\x13 \x01(\r\x12\x10\n\x08n_rd_avg\x18\x14 \x01(\r\x12\x10\n\x08n_rd_cnt\x18\x15 \x01(\r\x12\x11\n\tn_rd_peak\x18\x16 \x01(\r\x12\x13\n\x0bn_wr_as_avg\x18\x17 \x01(\r\x12\x13\n\x0bn_wr_as_cnt\x18\x18 \x01(\r\x12\x14\n\x0cn_wr_as_peak\x18\x19 \x01(\r\x12\x12\n\nn_wr_s_avg\x18\x1a \x01(\r\x12\x12\n\nn_wr_s_cnt\x18\x1b \x01(\r\x12\x13\n\x0bn_wr_s_peak\x18\x1c \x01(\r\"Z\n\x1b\x46\x32\x66sBackgroundGcFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0f\n\x07wait_ms\x18\x02 \x01(\r\x12\x0f\n\x07prefree\x18\x03 \x01(\r\x12\x0c\n\x04\x66ree\x18\x04 \x01(\r\"\x8e\x02\n\x16\x46\x32\x66sGcBeginFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0c\n\x04sync\x18\x02 \x01(\r\x12\x12\n\nbackground\x18\x03 \x01(\r\x12\x13\n\x0b\x64irty_nodes\x18\x04 \x01(\x03\x12\x13\n\x0b\x64irty_dents\x18\x05 \x01(\x03\x12\x13\n\x0b\x64irty_imeta\x18\x06 \x01(\x03\x12\x10\n\x08\x66ree_sec\x18\x07 \x01(\r\x12\x10\n\x08\x66ree_seg\x18\x08 \x01(\r\x12\x14\n\x0creserved_seg\x18\t \x01(\x05\x12\x13\n\x0bprefree_seg\x18\n \x01(\r\x12\x0f\n\x07gc_type\x18\x0b \x01(\x05\x12\x10\n\x08no_bg_gc\x18\x0c \x01(\r\x12\x14\n\x0cnr_free_secs\x18\r \x01(\r\"\xe4\x01\n\x14\x46\x32\x66sGcEndFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ret\x18\x02 \x01(\x05\x12\x11\n\tseg_freed\x18\x03 \x01(\x05\x12\x11\n\tsec_freed\x18\x04 \x01(\x05\x12\x13\n\x0b\x64irty_nodes\x18\x05 \x01(\x03\x12\x13\n\x0b\x64irty_dents\x18\x06 \x01(\x03\x12\x13\n\x0b\x64irty_imeta\x18\x07 \x01(\x03\x12\x10\n\x08\x66ree_sec\x18\x08 \x01(\r\x12\x10\n\x08\x66ree_seg\x18\t \x01(\r\x12\x14\n\x0creserved_seg\x18\n \x01(\x05\x12\x13\n\x0bprefree_seg\x18\x0b \x01(\r\"\x92\x02\n\x1e\x46\x32\x66sLockElapsedTimeFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0c\n\x04\x63omm\x18\x02 \x01(\t\x12\x0b\n\x03pid\x18\x03 \x01(\x05\x12\x0c\n\x04prio\x18\x04 \x01(\x05\x12\x14\n\x0cioprio_class\x18\x05 \x01(\x05\x12\x13\n\x0bioprio_data\x18\x06 \x01(\x05\x12\x11\n\tlock_name\x18\x07 \x01(\r\x12\x10\n\x08is_write\x18\x08 \x01(\r\x12\x12\n\ntotal_time\x18\t \x01(\x04\x12\x14\n\x0crunning_time\x18\n \x01(\x04\x12\x15\n\rrunnable_time\x18\x0b \x01(\x04\x12\x15\n\rio_sleep_time\x18\x0c \x01(\x04\x12\x12\n\nother_time\x18\r \x01(\x04\"N\n\x19\x46\x61strpcDmaStatFtraceEvent\x12\x0b\n\x03\x63id\x18\x01 \x01(\x05\x12\x0b\n\x03len\x18\x02 \x01(\x03\x12\x17\n\x0ftotal_allocated\x18\x03 \x01(\x04\"D\n\x19\x46\x61strpcDmaFreeFtraceEvent\x12\x0b\n\x03\x63id\x18\x01 \x01(\x05\x12\x0c\n\x04phys\x18\x02 \x01(\x04\x12\x0c\n\x04size\x18\x03 \x01(\x04\"c\n\x1a\x46\x61strpcDmaAllocFtraceEvent\x12\x0b\n\x03\x63id\x18\x01 \x01(\x05\x12\x0c\n\x04phys\x18\x02 \x01(\x04\x12\x0c\n\x04size\x18\x03 \x01(\x04\x12\x0c\n\x04\x61ttr\x18\x04 \x01(\x04\x12\x0e\n\x06mflags\x18\x05 \x01(\x05\"E\n\x1a\x46\x61strpcDmaUnmapFtraceEvent\x12\x0b\n\x03\x63id\x18\x01 \x01(\x05\x12\x0c\n\x04phys\x18\x02 \x01(\x04\x12\x0c\n\x04size\x18\x03 \x01(\x04\"z\n\x18\x46\x61strpcDmaMapFtraceEvent\x12\x0b\n\x03\x63id\x18\x01 \x01(\x05\x12\n\n\x02\x66\x64\x18\x02 \x01(\x05\x12\x0c\n\x04phys\x18\x03 \x01(\x04\x12\x0c\n\x04size\x18\x04 \x01(\x04\x12\x0b\n\x03len\x18\x05 \x01(\x04\x12\x0c\n\x04\x61ttr\x18\x06 \x01(\r\x12\x0e\n\x06mflags\x18\x07 \x01(\x05\"X\n\x14\x46\x65nceInitFtraceEvent\x12\x0f\n\x07\x63ontext\x18\x01 \x01(\r\x12\x0e\n\x06\x64river\x18\x02 \x01(\t\x12\r\n\x05seqno\x18\x03 \x01(\r\x12\x10\n\x08timeline\x18\x04 \x01(\t\"[\n\x17\x46\x65nceDestroyFtraceEvent\x12\x0f\n\x07\x63ontext\x18\x01 \x01(\r\x12\x0e\n\x06\x64river\x18\x02 \x01(\t\x12\r\n\x05seqno\x18\x03 \x01(\r\x12\x10\n\x08timeline\x18\x04 \x01(\t\"`\n\x1c\x46\x65nceEnableSignalFtraceEvent\x12\x0f\n\x07\x63ontext\x18\x01 \x01(\r\x12\x0e\n\x06\x64river\x18\x02 \x01(\t\x12\r\n\x05seqno\x18\x03 \x01(\r\x12\x10\n\x08timeline\x18\x04 \x01(\t\"\\\n\x18\x46\x65nceSignaledFtraceEvent\x12\x0f\n\x07\x63ontext\x18\x01 \x01(\r\x12\x0e\n\x06\x64river\x18\x02 \x01(\t\x12\r\n\x05seqno\x18\x03 \x01(\r\x12\x10\n\x08timeline\x18\x04 \x01(\t\"l\n\"MmFilemapAddToPageCacheFtraceEvent\x12\x0b\n\x03pfn\x18\x01 \x01(\x04\x12\r\n\x05i_ino\x18\x02 \x01(\x04\x12\r\n\x05index\x18\x03 \x01(\x04\x12\r\n\x05s_dev\x18\x04 \x01(\x04\x12\x0c\n\x04page\x18\x05 \x01(\x04\"q\n\'MmFilemapDeleteFromPageCacheFtraceEvent\x12\x0b\n\x03pfn\x18\x01 \x01(\x04\x12\r\n\x05i_ino\x18\x02 \x01(\x04\x12\r\n\x05index\x18\x03 \x01(\x04\x12\r\n\x05s_dev\x18\x04 \x01(\x04\x12\x0c\n\x04page\x18\x05 \x01(\x04\"E\n\x14\x44oSysOpenFtraceEvent\x12\x10\n\x08\x66ilename\x18\x01 \x01(\t\x12\r\n\x05\x66lags\x18\x02 \x01(\x05\x12\x0c\n\x04mode\x18\x03 \x01(\x05\"\'\n\x13OpenExecFtraceEvent\x12\x10\n\x08\x66ilename\x18\x01 \x01(\t\"+\n\x10PrintFtraceEvent\x12\n\n\x02ip\x18\x01 \x01(\x04\x12\x0b\n\x03\x62uf\x18\x02 \x01(\t\"8\n\x19\x46uncgraphEntryFtraceEvent\x12\r\n\x05\x64\x65pth\x18\x01 \x01(\x05\x12\x0c\n\x04\x66unc\x18\x02 \x01(\x04\"k\n\x18\x46uncgraphExitFtraceEvent\x12\x10\n\x08\x63\x61lltime\x18\x01 \x01(\x04\x12\r\n\x05\x64\x65pth\x18\x02 \x01(\x05\x12\x0c\n\x04\x66unc\x18\x03 \x01(\x04\x12\x0f\n\x07overrun\x18\x04 \x01(\x04\x12\x0f\n\x07rettime\x18\x05 \x01(\x04\"t\n\x1e\x46wtpPerfettoCounterFtraceEvent\x12\x11\n\ttimestamp\x18\x01 \x01(\x04\x12\x10\n\x08track_id\x18\x02 \x01(\r\x12\x10\n\x08\x63\x61tegory\x18\x03 \x01(\t\x12\x0c\n\x04name\x18\x04 \x01(\t\x12\r\n\x05value\x18\x05 \x01(\r\"r\n\x1c\x46wtpPerfettoSliceFtraceEvent\x12\x11\n\ttimestamp\x18\x01 \x01(\x04\x12\x10\n\x08track_id\x18\x02 \x01(\r\x12\x10\n\x08\x63\x61tegory\x18\x03 \x01(\t\x12\x0c\n\x04name\x18\x04 \x01(\t\x12\r\n\x05\x62\x65gin\x18\x05 \x01(\r\"X\n\x1eG2dTracingMarkWriteFtraceEvent\x12\x0b\n\x03pid\x18\x01 \x01(\x05\x12\x0c\n\x04name\x18\x04 \x01(\t\x12\x0c\n\x04type\x18\x05 \x01(\r\x12\r\n\x05value\x18\x06 \x01(\x05\"\xc2\x01\n\x12GenericFtraceEvent\x12\x12\n\nevent_name\x18\x01 \x01(\t\x12\x38\n\x05\x66ield\x18\x02 \x03(\x0b\x32).perfetto.protos.GenericFtraceEvent.Field\x1a^\n\x05\x46ield\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x13\n\tstr_value\x18\x03 \x01(\tH\x00\x12\x13\n\tint_value\x18\x04 \x01(\x03H\x00\x12\x14\n\nuint_value\x18\x05 \x01(\x04H\x00\x42\x07\n\x05value\"\xbe\x01\n\x0bKprobeEvent\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x35\n\x04type\x18\x02 \x01(\x0e\x32\'.perfetto.protos.KprobeEvent.KprobeType\"j\n\nKprobeType\x12\x17\n\x13KPROBE_TYPE_UNKNOWN\x10\x00\x12\x15\n\x11KPROBE_TYPE_BEGIN\x10\x01\x12\x13\n\x0fKPROBE_TYPE_END\x10\x02\x12\x17\n\x13KPROBE_TYPE_INSTANT\x10\x03\"=\n\x19GoogleIccEventFtraceEvent\x12\r\n\x05\x65vent\x18\x01 \x01(\t\x12\x11\n\ttimestamp\x18\x02 \x01(\x04\"=\n\x19GoogleIrmEventFtraceEvent\x12\r\n\x05\x65vent\x18\x01 \x01(\t\x12\x11\n\ttimestamp\x18\x02 \x01(\x04\"C\n\x16GpuMemTotalFtraceEvent\x12\x0e\n\x06gpu_id\x18\x01 \x01(\r\x12\x0b\n\x03pid\x18\x02 \x01(\r\x12\x0c\n\x04size\x18\x03 \x01(\x04\"z\n\x16\x44rmSchedJobFtraceEvent\x12\x0e\n\x06\x65ntity\x18\x01 \x01(\x04\x12\r\n\x05\x66\x65nce\x18\x02 \x01(\x04\x12\x14\n\x0chw_job_count\x18\x03 \x01(\x05\x12\n\n\x02id\x18\x04 \x01(\x04\x12\x11\n\tjob_count\x18\x05 \x01(\r\x12\x0c\n\x04name\x18\x06 \x01(\t\"x\n\x14\x44rmRunJobFtraceEvent\x12\x0e\n\x06\x65ntity\x18\x01 \x01(\x04\x12\r\n\x05\x66\x65nce\x18\x02 \x01(\x04\x12\x14\n\x0chw_job_count\x18\x03 \x01(\x05\x12\n\n\x02id\x18\x04 \x01(\x04\x12\x11\n\tjob_count\x18\x05 \x01(\r\x12\x0c\n\x04name\x18\x06 \x01(\t\".\n\x1d\x44rmSchedProcessJobFtraceEvent\x12\r\n\x05\x66\x65nce\x18\x01 \x01(\x04\"f\n\x1c\x44rmSchedJobAddDepFtraceEvent\x12\x15\n\rfence_context\x18\x01 \x01(\x04\x12\x13\n\x0b\x66\x65nce_seqno\x18\x02 \x01(\x04\x12\x0b\n\x03\x63tx\x18\x03 \x01(\x04\x12\r\n\x05seqno\x18\x04 \x01(\x04\"H\n\x1a\x44rmSchedJobDoneFtraceEvent\x12\x15\n\rfence_context\x18\x01 \x01(\x04\x12\x13\n\x0b\x66\x65nce_seqno\x18\x02 \x01(\x04\"\xa0\x01\n\x1b\x44rmSchedJobQueueFtraceEvent\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x11\n\tjob_count\x18\x02 \x01(\r\x12\x14\n\x0chw_job_count\x18\x03 \x01(\x05\x12\x0b\n\x03\x64\x65v\x18\x04 \x01(\t\x12\x15\n\rfence_context\x18\x05 \x01(\x04\x12\x13\n\x0b\x66\x65nce_seqno\x18\x06 \x01(\x04\x12\x11\n\tclient_id\x18\x07 \x01(\x04\"\x9e\x01\n\x19\x44rmSchedJobRunFtraceEvent\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x11\n\tjob_count\x18\x02 \x01(\r\x12\x14\n\x0chw_job_count\x18\x03 \x01(\x05\x12\x0b\n\x03\x64\x65v\x18\x04 \x01(\t\x12\x15\n\rfence_context\x18\x05 \x01(\x04\x12\x13\n\x0b\x66\x65nce_seqno\x18\x06 \x01(\x04\x12\x11\n\tclient_id\x18\x07 \x01(\x04\"m\n#DrmSchedJobUnschedulableFtraceEvent\x12\x15\n\rfence_context\x18\x01 \x01(\x04\x12\x13\n\x0b\x66\x65nce_seqno\x18\x02 \x01(\x04\x12\x0b\n\x03\x63tx\x18\x03 \x01(\x04\x12\r\n\x05seqno\x18\x04 \x01(\x04\"\x15\n\x13HypEnterFtraceEvent\"\x14\n\x12HypExitFtraceEvent\"3\n\x14HostHcallFtraceEvent\x12\n\n\x02id\x18\x01 \x01(\r\x12\x0f\n\x07invalid\x18\x02 \x01(\r\"3\n\x12HostSmcFtraceEvent\x12\n\n\x02id\x18\x01 \x01(\x04\x12\x11\n\tforwarded\x18\x02 \x01(\r\"4\n\x17HostMemAbortFtraceEvent\x12\x0b\n\x03\x65sr\x18\x01 \x01(\x04\x12\x0c\n\x04\x61\x64\x64r\x18\x02 \x01(\x04\"\x87\x01\n\x16HostFfaCallFtraceEvent\x12\x0f\n\x07\x66unc_id\x18\x01 \x01(\x04\x12\x0e\n\x06res_a1\x18\x02 \x01(\x04\x12\x0e\n\x06res_a2\x18\x03 \x01(\x04\x12\x0e\n\x06res_a3\x18\x04 \x01(\x04\x12\x0e\n\x06res_a4\x18\x05 \x01(\x04\x12\x0f\n\x07handled\x18\x06 \x01(\x05\x12\x0b\n\x03\x65rr\x18\x07 \x01(\x05\"?\n\x15IommuIdmapFtraceEvent\x12\x0c\n\x04\x66rom\x18\x01 \x01(\x04\x12\n\n\x02to\x18\x02 \x01(\x04\x12\x0c\n\x04prot\x18\x03 \x01(\x05\"7\n\x19PsciMemProtectFtraceEvent\x12\r\n\x05\x63ount\x18\x01 \x01(\x04\x12\x0b\n\x03was\x18\x02 \x01(\x04\"=\n\x1eHypervisorHostHcallFtraceEvent\x12\n\n\x02id\x18\x01 \x01(\r\x12\x0f\n\x07invalid\x18\x02 \x01(\r\"=\n\x1cHypervisorHostSmcFtraceEvent\x12\n\n\x02id\x18\x01 \x01(\x04\x12\x11\n\tforwarded\x18\x02 \x01(\r\"\x1e\n\x1cHypervisorHypExitFtraceEvent\"I\n\x1fHypervisorIommuIdmapFtraceEvent\x12\x0c\n\x04\x66rom\x18\x01 \x01(\x04\x12\n\n\x02to\x18\x02 \x01(\x04\x12\x0c\n\x04prot\x18\x03 \x01(\x05\"A\n#HypervisorPsciMemProtectFtraceEvent\x12\r\n\x05\x63ount\x18\x01 \x01(\x04\x12\x0b\n\x03was\x18\x02 \x01(\x04\">\n!HypervisorHostMemAbortFtraceEvent\x12\x0b\n\x03\x65sr\x18\x01 \x01(\x04\x12\x0c\n\x04\x61\x64\x64r\x18\x02 \x01(\x04\"\x1f\n\x1dHypervisorHypEnterFtraceEvent\"6\n\'HypervisorIommuIdmapCompleteFtraceEvent\x12\x0b\n\x03map\x18\x01 \x01(\r\"3\n$HypervisorVcpuIllegalTrapFtraceEvent\x12\x0b\n\x03\x65sr\x18\x01 \x01(\x04\"b\n\x12I2cReadFtraceEvent\x12\x12\n\nadapter_nr\x18\x01 \x01(\x05\x12\x0e\n\x06msg_nr\x18\x02 \x01(\r\x12\x0c\n\x04\x61\x64\x64r\x18\x03 \x01(\r\x12\r\n\x05\x66lags\x18\x04 \x01(\r\x12\x0b\n\x03len\x18\x05 \x01(\r\"p\n\x13I2cWriteFtraceEvent\x12\x12\n\nadapter_nr\x18\x01 \x01(\x05\x12\x0e\n\x06msg_nr\x18\x02 \x01(\r\x12\x0c\n\x04\x61\x64\x64r\x18\x03 \x01(\r\x12\r\n\x05\x66lags\x18\x04 \x01(\r\x12\x0b\n\x03len\x18\x05 \x01(\r\x12\x0b\n\x03\x62uf\x18\x07 \x01(\x0c\"H\n\x14I2cResultFtraceEvent\x12\x12\n\nadapter_nr\x18\x01 \x01(\x05\x12\x0f\n\x07nr_msgs\x18\x02 \x01(\r\x12\x0b\n\x03ret\x18\x03 \x01(\x05\"p\n\x13I2cReplyFtraceEvent\x12\x12\n\nadapter_nr\x18\x01 \x01(\x05\x12\x0e\n\x06msg_nr\x18\x02 \x01(\r\x12\x0c\n\x04\x61\x64\x64r\x18\x03 \x01(\r\x12\r\n\x05\x66lags\x18\x04 \x01(\r\x12\x0b\n\x03len\x18\x05 \x01(\r\x12\x0b\n\x03\x62uf\x18\x07 \x01(\x0c\"j\n\x14SmbusReadFtraceEvent\x12\x12\n\nadapter_nr\x18\x01 \x01(\x05\x12\r\n\x05\x66lags\x18\x02 \x01(\r\x12\x0c\n\x04\x61\x64\x64r\x18\x03 \x01(\r\x12\x0f\n\x07\x63ommand\x18\x04 \x01(\r\x12\x10\n\x08protocol\x18\x05 \x01(\r\"x\n\x15SmbusWriteFtraceEvent\x12\x12\n\nadapter_nr\x18\x01 \x01(\x05\x12\x0c\n\x04\x61\x64\x64r\x18\x02 \x01(\r\x12\r\n\x05\x66lags\x18\x03 \x01(\r\x12\x0f\n\x07\x63ommand\x18\x04 \x01(\r\x12\x0b\n\x03len\x18\x05 \x01(\r\x12\x10\n\x08protocol\x18\x06 \x01(\r\"\x8d\x01\n\x16SmbusResultFtraceEvent\x12\x12\n\nadapter_nr\x18\x01 \x01(\x05\x12\x0c\n\x04\x61\x64\x64r\x18\x02 \x01(\r\x12\r\n\x05\x66lags\x18\x03 \x01(\r\x12\x12\n\nread_write\x18\x04 \x01(\r\x12\x0f\n\x07\x63ommand\x18\x05 \x01(\r\x12\x0b\n\x03res\x18\x06 \x01(\x05\x12\x10\n\x08protocol\x18\x07 \x01(\r\"x\n\x15SmbusReplyFtraceEvent\x12\x12\n\nadapter_nr\x18\x01 \x01(\x05\x12\x0c\n\x04\x61\x64\x64r\x18\x02 \x01(\r\x12\r\n\x05\x66lags\x18\x03 \x01(\r\x12\x0f\n\x07\x63ommand\x18\x04 \x01(\r\x12\x0b\n\x03len\x18\x05 \x01(\r\x12\x10\n\x08protocol\x18\x06 \x01(\r\"M\n\x12IonStatFtraceEvent\x12\x11\n\tbuffer_id\x18\x01 \x01(\r\x12\x0b\n\x03len\x18\x02 \x01(\x03\x12\x17\n\x0ftotal_allocated\x18\x03 \x01(\x04\"%\n\x13IpiEntryFtraceEvent\x12\x0e\n\x06reason\x18\x01 \x01(\t\"$\n\x12IpiExitFtraceEvent\x12\x0e\n\x06reason\x18\x01 \x01(\t\":\n\x13IpiRaiseFtraceEvent\x12\x13\n\x0btarget_cpus\x18\x01 \x01(\r\x12\x0e\n\x06reason\x18\x02 \x01(\t\"&\n\x17SoftirqEntryFtraceEvent\x12\x0b\n\x03vec\x18\x01 \x01(\r\"%\n\x16SoftirqExitFtraceEvent\x12\x0b\n\x03vec\x18\x01 \x01(\r\"&\n\x17SoftirqRaiseFtraceEvent\x12\x0b\n\x03vec\x18\x01 \x01(\r\"H\n\x1aIrqHandlerEntryFtraceEvent\x12\x0b\n\x03irq\x18\x01 \x01(\x05\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x0f\n\x07handler\x18\x03 \x01(\r\"5\n\x19IrqHandlerExitFtraceEvent\x12\x0b\n\x03irq\x18\x01 \x01(\x05\x12\x0b\n\x03ret\x18\x02 \x01(\x05\",\n\x1aLocalTimerEntryFtraceEvent\x12\x0e\n\x06vector\x18\x01 \x01(\x05\"+\n\x19LocalTimerExitFtraceEvent\x12\x0e\n\x06vector\x18\x01 \x01(\x05\"?\n\x1bKgslGpuFrequencyFtraceEvent\x12\x10\n\x08gpu_freq\x18\x01 \x01(\r\x12\x0e\n\x06gpu_id\x18\x02 \x01(\r\"q\n#KgslAdrenoCmdbatchQueuedFtraceEvent\x12\n\n\x02id\x18\x01 \x01(\r\x12\x11\n\ttimestamp\x18\x02 \x01(\r\x12\x0e\n\x06queued\x18\x03 \x01(\r\x12\r\n\x05\x66lags\x18\x04 \x01(\r\x12\x0c\n\x04prio\x18\x05 \x01(\r\"\xf9\x01\n&KgslAdrenoCmdbatchSubmittedFtraceEvent\x12\n\n\x02id\x18\x01 \x01(\r\x12\x11\n\ttimestamp\x18\x02 \x01(\r\x12\x10\n\x08inflight\x18\x03 \x01(\x03\x12\r\n\x05\x66lags\x18\x04 \x01(\r\x12\r\n\x05ticks\x18\x05 \x01(\x04\x12\x0c\n\x04secs\x18\x06 \x01(\x04\x12\r\n\x05usecs\x18\x07 \x01(\x04\x12\x0c\n\x04prio\x18\x08 \x01(\x05\x12\r\n\x05rb_id\x18\t \x01(\x05\x12\x0c\n\x04rptr\x18\n \x01(\r\x12\x0c\n\x04wptr\x18\x0b \x01(\r\x12\x12\n\nq_inflight\x18\x0c \x01(\x05\x12\x16\n\x0e\x64ispatch_queue\x18\r \x01(\x05\"_\n!KgslAdrenoCmdbatchSyncFtraceEvent\x12\n\n\x02id\x18\x01 \x01(\r\x12\x11\n\ttimestamp\x18\x02 \x01(\r\x12\r\n\x05ticks\x18\x03 \x01(\x04\x12\x0c\n\x04prio\x18\x04 \x01(\x05\"\xd5\x02\n$KgslAdrenoCmdbatchRetiredFtraceEvent\x12\n\n\x02id\x18\x01 \x01(\r\x12\x11\n\ttimestamp\x18\x02 \x01(\r\x12\x10\n\x08inflight\x18\x03 \x01(\x03\x12\x10\n\x08recovery\x18\x04 \x01(\r\x12\r\n\x05\x66lags\x18\x05 \x01(\r\x12\r\n\x05start\x18\x06 \x01(\x04\x12\x0e\n\x06retire\x18\x07 \x01(\x04\x12\x0c\n\x04prio\x18\x08 \x01(\x05\x12\r\n\x05rb_id\x18\t \x01(\x05\x12\x0c\n\x04rptr\x18\n \x01(\r\x12\x0c\n\x04wptr\x18\x0b \x01(\r\x12\x12\n\nq_inflight\x18\x0c \x01(\x05\x12\x16\n\x0e\x66\x61ult_recovery\x18\r \x01(\x04\x12\x16\n\x0e\x64ispatch_queue\x18\x0e \x01(\r\x12\x17\n\x0fsubmitted_to_rb\x18\x0f \x01(\x04\x12\x16\n\x0eretired_on_gmu\x18\x10 \x01(\x04\x12\x0e\n\x06\x61\x63tive\x18\x11 \x01(\x04\"A\n\x1d\x41llocPagesIommuEndFtraceEvent\x12\x11\n\tgfp_flags\x18\x01 \x01(\r\x12\r\n\x05order\x18\x02 \x01(\r\"B\n\x1e\x41llocPagesIommuFailFtraceEvent\x12\x11\n\tgfp_flags\x18\x01 \x01(\r\x12\r\n\x05order\x18\x02 \x01(\r\"C\n\x1f\x41llocPagesIommuStartFtraceEvent\x12\x11\n\tgfp_flags\x18\x01 \x01(\r\x12\r\n\x05order\x18\x02 \x01(\r\"?\n\x1b\x41llocPagesSysEndFtraceEvent\x12\x11\n\tgfp_flags\x18\x01 \x01(\r\x12\r\n\x05order\x18\x02 \x01(\r\"@\n\x1c\x41llocPagesSysFailFtraceEvent\x12\x11\n\tgfp_flags\x18\x01 \x01(\r\x12\r\n\x05order\x18\x02 \x01(\r\"A\n\x1d\x41llocPagesSysStartFtraceEvent\x12\x11\n\tgfp_flags\x18\x01 \x01(\r\x12\r\n\x05order\x18\x02 \x01(\r\"3\n\"DmaAllocContiguousRetryFtraceEvent\x12\r\n\x05tries\x18\x01 \x01(\x05\"S\n\x18IommuMapRangeFtraceEvent\x12\x12\n\nchunk_size\x18\x01 \x01(\x04\x12\x0b\n\x03len\x18\x02 \x01(\x04\x12\n\n\x02pa\x18\x03 \x01(\x04\x12\n\n\x02va\x18\x04 \x01(\x04\"f\n\"IommuSecPtblMapRangeEndFtraceEvent\x12\x0b\n\x03len\x18\x01 \x01(\x04\x12\x0b\n\x03num\x18\x02 \x01(\x05\x12\n\n\x02pa\x18\x03 \x01(\r\x12\x0e\n\x06sec_id\x18\x04 \x01(\x05\x12\n\n\x02va\x18\x05 \x01(\x04\"h\n$IommuSecPtblMapRangeStartFtraceEvent\x12\x0b\n\x03len\x18\x01 \x01(\x04\x12\x0b\n\x03num\x18\x02 \x01(\x05\x12\n\n\x02pa\x18\x03 \x01(\r\x12\x0e\n\x06sec_id\x18\x04 \x01(\x05\x12\n\n\x02va\x18\x05 \x01(\x04\"p\n\x1cIonAllocBufferEndFtraceEvent\x12\x13\n\x0b\x63lient_name\x18\x01 \x01(\t\x12\r\n\x05\x66lags\x18\x02 \x01(\r\x12\x11\n\theap_name\x18\x03 \x01(\t\x12\x0b\n\x03len\x18\x04 \x01(\x04\x12\x0c\n\x04mask\x18\x05 \x01(\r\"\x80\x01\n\x1dIonAllocBufferFailFtraceEvent\x12\x13\n\x0b\x63lient_name\x18\x01 \x01(\t\x12\r\n\x05\x65rror\x18\x02 \x01(\x03\x12\r\n\x05\x66lags\x18\x03 \x01(\r\x12\x11\n\theap_name\x18\x04 \x01(\t\x12\x0b\n\x03len\x18\x05 \x01(\x04\x12\x0c\n\x04mask\x18\x06 \x01(\r\"\x84\x01\n!IonAllocBufferFallbackFtraceEvent\x12\x13\n\x0b\x63lient_name\x18\x01 \x01(\t\x12\r\n\x05\x65rror\x18\x02 \x01(\x03\x12\r\n\x05\x66lags\x18\x03 \x01(\r\x12\x11\n\theap_name\x18\x04 \x01(\t\x12\x0b\n\x03len\x18\x05 \x01(\x04\x12\x0c\n\x04mask\x18\x06 \x01(\r\"r\n\x1eIonAllocBufferStartFtraceEvent\x12\x13\n\x0b\x63lient_name\x18\x01 \x01(\t\x12\r\n\x05\x66lags\x18\x02 \x01(\r\x12\x11\n\theap_name\x18\x03 \x01(\t\x12\x0b\n\x03len\x18\x04 \x01(\x04\x12\x0c\n\x04mask\x18\x05 \x01(\r\"+\n\x1aIonCpAllocRetryFtraceEvent\x12\r\n\x05tries\x18\x01 \x01(\x05\"_\n\x1fIonCpSecureBufferEndFtraceEvent\x12\r\n\x05\x61lign\x18\x01 \x01(\x04\x12\r\n\x05\x66lags\x18\x02 \x01(\x04\x12\x11\n\theap_name\x18\x03 \x01(\t\x12\x0b\n\x03len\x18\x04 \x01(\x04\"a\n!IonCpSecureBufferStartFtraceEvent\x12\r\n\x05\x61lign\x18\x01 \x01(\x04\x12\r\n\x05\x66lags\x18\x02 \x01(\x04\x12\x11\n\theap_name\x18\x03 \x01(\t\x12\x0b\n\x03len\x18\x04 \x01(\x04\"(\n\x19IonPrefetchingFtraceEvent\x12\x0b\n\x03len\x18\x01 \x01(\x04\"[\n#IonSecureCmaAddToPoolEndFtraceEvent\x12\x13\n\x0bis_prefetch\x18\x01 \x01(\r\x12\x0b\n\x03len\x18\x02 \x01(\x04\x12\x12\n\npool_total\x18\x03 \x01(\x05\"]\n%IonSecureCmaAddToPoolStartFtraceEvent\x12\x13\n\x0bis_prefetch\x18\x01 \x01(\r\x12\x0b\n\x03len\x18\x02 \x01(\x04\x12\x12\n\npool_total\x18\x03 \x01(\x05\"b\n\"IonSecureCmaAllocateEndFtraceEvent\x12\r\n\x05\x61lign\x18\x01 \x01(\x04\x12\r\n\x05\x66lags\x18\x02 \x01(\x04\x12\x11\n\theap_name\x18\x03 \x01(\t\x12\x0b\n\x03len\x18\x04 \x01(\x04\"d\n$IonSecureCmaAllocateStartFtraceEvent\x12\r\n\x05\x61lign\x18\x01 \x01(\x04\x12\r\n\x05\x66lags\x18\x02 \x01(\x04\x12\x11\n\theap_name\x18\x03 \x01(\t\x12\x0b\n\x03len\x18\x04 \x01(\x04\"R\n$IonSecureCmaShrinkPoolEndFtraceEvent\x12\x14\n\x0c\x64rained_size\x18\x01 \x01(\x04\x12\x14\n\x0cskipped_size\x18\x02 \x01(\x04\"T\n&IonSecureCmaShrinkPoolStartFtraceEvent\x12\x14\n\x0c\x64rained_size\x18\x01 \x01(\x04\x12\x14\n\x0cskipped_size\x18\x02 \x01(\x04\"2\n\x10KfreeFtraceEvent\x12\x11\n\tcall_site\x18\x01 \x01(\x04\x12\x0b\n\x03ptr\x18\x02 \x01(\x04\"o\n\x12KmallocFtraceEvent\x12\x13\n\x0b\x62ytes_alloc\x18\x01 \x01(\x04\x12\x11\n\tbytes_req\x18\x02 \x01(\x04\x12\x11\n\tcall_site\x18\x03 \x01(\x04\x12\x11\n\tgfp_flags\x18\x04 \x01(\r\x12\x0b\n\x03ptr\x18\x05 \x01(\x04\"\x81\x01\n\x16KmallocNodeFtraceEvent\x12\x13\n\x0b\x62ytes_alloc\x18\x01 \x01(\x04\x12\x11\n\tbytes_req\x18\x02 \x01(\x04\x12\x11\n\tcall_site\x18\x03 \x01(\x04\x12\x11\n\tgfp_flags\x18\x04 \x01(\r\x12\x0c\n\x04node\x18\x05 \x01(\x05\x12\x0b\n\x03ptr\x18\x06 \x01(\x04\"v\n\x19KmemCacheAllocFtraceEvent\x12\x13\n\x0b\x62ytes_alloc\x18\x01 \x01(\x04\x12\x11\n\tbytes_req\x18\x02 \x01(\x04\x12\x11\n\tcall_site\x18\x03 \x01(\x04\x12\x11\n\tgfp_flags\x18\x04 \x01(\r\x12\x0b\n\x03ptr\x18\x05 \x01(\x04\"\x88\x01\n\x1dKmemCacheAllocNodeFtraceEvent\x12\x13\n\x0b\x62ytes_alloc\x18\x01 \x01(\x04\x12\x11\n\tbytes_req\x18\x02 \x01(\x04\x12\x11\n\tcall_site\x18\x03 \x01(\x04\x12\x11\n\tgfp_flags\x18\x04 \x01(\r\x12\x0c\n\x04node\x18\x05 \x01(\x05\x12\x0b\n\x03ptr\x18\x06 \x01(\x04\":\n\x18KmemCacheFreeFtraceEvent\x12\x11\n\tcall_site\x18\x01 \x01(\x04\x12\x0b\n\x03ptr\x18\x02 \x01(\x04\"*\n\x1aMigratePagesEndFtraceEvent\x12\x0c\n\x04mode\x18\x01 \x01(\x05\",\n\x1cMigratePagesStartFtraceEvent\x12\x0c\n\x04mode\x18\x01 \x01(\x05\"(\n\x17MigrateRetryFtraceEvent\x12\r\n\x05tries\x18\x01 \x01(\x05\"j\n\x16MmPageAllocFtraceEvent\x12\x11\n\tgfp_flags\x18\x01 \x01(\r\x12\x13\n\x0bmigratetype\x18\x02 \x01(\x05\x12\r\n\x05order\x18\x03 \x01(\r\x12\x0c\n\x04page\x18\x04 \x01(\x04\x12\x0b\n\x03pfn\x18\x05 \x01(\x04\"\xba\x01\n\x1dMmPageAllocExtfragFtraceEvent\x12\x19\n\x11\x61lloc_migratetype\x18\x01 \x01(\x05\x12\x13\n\x0b\x61lloc_order\x18\x02 \x01(\x05\x12\x1c\n\x14\x66\x61llback_migratetype\x18\x03 \x01(\x05\x12\x16\n\x0e\x66\x61llback_order\x18\x04 \x01(\x05\x12\x0c\n\x04page\x18\x05 \x01(\x04\x12\x18\n\x10\x63hange_ownership\x18\x06 \x01(\x05\x12\x0b\n\x03pfn\x18\x07 \x01(\x04\"a\n MmPageAllocZoneLockedFtraceEvent\x12\x13\n\x0bmigratetype\x18\x01 \x01(\x05\x12\r\n\x05order\x18\x02 \x01(\r\x12\x0c\n\x04page\x18\x03 \x01(\x04\x12\x0b\n\x03pfn\x18\x04 \x01(\x04\"A\n\x15MmPageFreeFtraceEvent\x12\r\n\x05order\x18\x01 \x01(\r\x12\x0c\n\x04page\x18\x02 \x01(\x04\x12\x0b\n\x03pfn\x18\x03 \x01(\x04\"G\n\x1cMmPageFreeBatchedFtraceEvent\x12\x0c\n\x04\x63old\x18\x01 \x01(\x05\x12\x0c\n\x04page\x18\x02 \x01(\x04\x12\x0b\n\x03pfn\x18\x03 \x01(\x04\"[\n\x1aMmPagePcpuDrainFtraceEvent\x12\x13\n\x0bmigratetype\x18\x01 \x01(\x05\x12\r\n\x05order\x18\x02 \x01(\r\x12\x0c\n\x04page\x18\x03 \x01(\x04\x12\x0b\n\x03pfn\x18\x04 \x01(\x04\"O\n\x12RssStatFtraceEvent\x12\x0e\n\x06member\x18\x01 \x01(\x05\x12\x0c\n\x04size\x18\x02 \x01(\x03\x12\x0c\n\x04\x63urr\x18\x03 \x01(\r\x12\r\n\x05mm_id\x18\x04 \x01(\r\"S\n\x18IonHeapShrinkFtraceEvent\x12\x11\n\theap_name\x18\x01 \x01(\t\x12\x0b\n\x03len\x18\x02 \x01(\x04\x12\x17\n\x0ftotal_allocated\x18\x03 \x01(\x03\"Q\n\x16IonHeapGrowFtraceEvent\x12\x11\n\theap_name\x18\x01 \x01(\t\x12\x0b\n\x03len\x18\x02 \x01(\x04\x12\x17\n\x0ftotal_allocated\x18\x03 \x01(\x03\"7\n\x1aIonBufferCreateFtraceEvent\x12\x0c\n\x04\x61\x64\x64r\x18\x01 \x01(\x04\x12\x0b\n\x03len\x18\x02 \x01(\x04\"8\n\x1bIonBufferDestroyFtraceEvent\x12\x0c\n\x04\x61\x64\x64r\x18\x01 \x01(\x04\x12\x0b\n\x03len\x18\x02 \x01(\x04\"\x99\x01\n(MmAllocContigMigrateRangeInfoFtraceEvent\x12\r\n\x05start\x18\x01 \x01(\x04\x12\x0b\n\x03\x65nd\x18\x02 \x01(\x04\x12\x13\n\x0bnr_migrated\x18\x03 \x01(\x04\x12\x14\n\x0cnr_reclaimed\x18\x04 \x01(\x04\x12\x11\n\tnr_mapped\x18\x05 \x01(\x04\x12\x13\n\x0bmigratetype\x18\x06 \x01(\x05\"I\n\x18\x44mabufRssStatFtraceEvent\x12\x0b\n\x03rss\x18\x01 \x01(\x04\x12\x11\n\trss_delta\x18\x02 \x01(\x03\x12\r\n\x05i_ino\x18\x03 \x01(\x04\"(\n\x19KvmAccessFaultFtraceEvent\x12\x0b\n\x03ipa\x18\x01 \x01(\x04\"4\n\x14KvmAckIrqFtraceEvent\x12\x0f\n\x07irqchip\x18\x01 \x01(\r\x12\x0b\n\x03pin\x18\x02 \x01(\r\"2\n\x14KvmAgeHvaFtraceEvent\x12\x0b\n\x03\x65nd\x18\x01 \x01(\x04\x12\r\n\x05start\x18\x02 \x01(\x04\"T\n\x15KvmAgePageFtraceEvent\x12\x0b\n\x03gfn\x18\x01 \x01(\x04\x12\x0b\n\x03hva\x18\x02 \x01(\x04\x12\r\n\x05level\x18\x03 \x01(\r\x12\x12\n\nreferenced\x18\x04 \x01(\r\"2\n\x1bKvmArmClearDebugFtraceEvent\x12\x13\n\x0bguest_debug\x18\x01 \x01(\r\"9\n\x1aKvmArmSetDreg32FtraceEvent\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\r\"7\n\x1aKvmArmSetRegsetFtraceEvent\x12\x0b\n\x03len\x18\x01 \x01(\x05\x12\x0c\n\x04name\x18\x02 \x01(\t\"@\n\x1bKvmArmSetupDebugFtraceEvent\x12\x13\n\x0bguest_debug\x18\x01 \x01(\r\x12\x0c\n\x04vcpu\x18\x02 \x01(\x04\"&\n\x13KvmEntryFtraceEvent\x12\x0f\n\x07vcpu_pc\x18\x01 \x01(\x04\"B\n\x12KvmExitFtraceEvent\x12\x0e\n\x06\x65sr_ec\x18\x01 \x01(\r\x12\x0b\n\x03ret\x18\x02 \x01(\x05\x12\x0f\n\x07vcpu_pc\x18\x03 \x01(\x04\"!\n\x11KvmFpuFtraceEvent\x12\x0c\n\x04load\x18\x01 \x01(\r\"o\n\x19KvmGetTimerMapFtraceEvent\x12\x15\n\rdirect_ptimer\x18\x01 \x01(\x05\x12\x15\n\rdirect_vtimer\x18\x02 \x01(\x05\x12\x13\n\x0b\x65mul_ptimer\x18\x03 \x01(\x05\x12\x0f\n\x07vcpu_id\x18\x04 \x01(\x04\"T\n\x18KvmGuestFaultFtraceEvent\x12\x0b\n\x03hsr\x18\x01 \x01(\x04\x12\r\n\x05hxfar\x18\x02 \x01(\x04\x12\x0b\n\x03ipa\x18\x03 \x01(\x04\x12\x0f\n\x07vcpu_pc\x18\x04 \x01(\x04\")\n\x1aKvmHandleSysRegFtraceEvent\x12\x0b\n\x03hsr\x18\x01 \x01(\x04\"B\n\x16KvmHvcArm64FtraceEvent\x12\x0b\n\x03imm\x18\x01 \x01(\x04\x12\n\n\x02r0\x18\x02 \x01(\x04\x12\x0f\n\x07vcpu_pc\x18\x03 \x01(\x04\"W\n\x15KvmIrqLineFtraceEvent\x12\x0f\n\x07irq_num\x18\x01 \x01(\x05\x12\r\n\x05level\x18\x02 \x01(\x05\x12\x0c\n\x04type\x18\x03 \x01(\r\x12\x10\n\x08vcpu_idx\x18\x04 \x01(\x05\"I\n\x12KvmMmioFtraceEvent\x12\x0b\n\x03gpa\x18\x01 \x01(\x04\x12\x0b\n\x03len\x18\x02 \x01(\r\x12\x0c\n\x04type\x18\x03 \x01(\r\x12\x0b\n\x03val\x18\x04 \x01(\x04\"I\n\x19KvmMmioEmulateFtraceEvent\x12\x0c\n\x04\x63psr\x18\x01 \x01(\x04\x12\r\n\x05instr\x18\x02 \x01(\x04\x12\x0f\n\x07vcpu_pc\x18\x03 \x01(\x04\"@\n\x1bKvmSetGuestDebugFtraceEvent\x12\x13\n\x0bguest_debug\x18\x01 \x01(\r\x12\x0c\n\x04vcpu\x18\x02 \x01(\x04\"I\n\x14KvmSetIrqFtraceEvent\x12\x0b\n\x03gsi\x18\x01 \x01(\r\x12\x15\n\rirq_source_id\x18\x02 \x01(\x05\x12\r\n\x05level\x18\x03 \x01(\x05\"\'\n\x18KvmSetSpteHvaFtraceEvent\x12\x0b\n\x03hva\x18\x01 \x01(\x04\";\n\x19KvmSetWayFlushFtraceEvent\x12\r\n\x05\x63\x61\x63he\x18\x01 \x01(\r\x12\x0f\n\x07vcpu_pc\x18\x02 \x01(\x04\"\x8b\x01\n\x17KvmSysAccessFtraceEvent\x12\x0b\n\x03\x43Rm\x18\x01 \x01(\r\x12\x0b\n\x03\x43Rn\x18\x02 \x01(\r\x12\x0b\n\x03Op0\x18\x03 \x01(\r\x12\x0b\n\x03Op1\x18\x04 \x01(\r\x12\x0b\n\x03Op2\x18\x05 \x01(\r\x12\x10\n\x08is_write\x18\x06 \x01(\r\x12\x0c\n\x04name\x18\x07 \x01(\t\x12\x0f\n\x07vcpu_pc\x18\x08 \x01(\x04\"\'\n\x18KvmTestAgeHvaFtraceEvent\x12\x0b\n\x03hva\x18\x01 \x01(\x04\"D\n\x1aKvmTimerEmulateFtraceEvent\x12\x13\n\x0bshould_fire\x18\x01 \x01(\r\x12\x11\n\ttimer_idx\x18\x02 \x01(\x05\"5\n KvmTimerHrtimerExpireFtraceEvent\x12\x11\n\ttimer_idx\x18\x01 \x01(\x05\"O\n\x1fKvmTimerRestoreStateFtraceEvent\x12\x0b\n\x03\x63tl\x18\x01 \x01(\x04\x12\x0c\n\x04\x63val\x18\x02 \x01(\x04\x12\x11\n\ttimer_idx\x18\x03 \x01(\x05\"L\n\x1cKvmTimerSaveStateFtraceEvent\x12\x0b\n\x03\x63tl\x18\x01 \x01(\x04\x12\x0c\n\x04\x63val\x18\x02 \x01(\x04\x12\x11\n\ttimer_idx\x18\x03 \x01(\x05\"K\n\x1cKvmTimerUpdateIrqFtraceEvent\x12\x0b\n\x03irq\x18\x01 \x01(\r\x12\r\n\x05level\x18\x02 \x01(\x05\x12\x0f\n\x07vcpu_id\x18\x03 \x01(\x04\"F\n\x19KvmToggleCacheFtraceEvent\x12\x0b\n\x03now\x18\x01 \x01(\r\x12\x0f\n\x07vcpu_pc\x18\x02 \x01(\x04\x12\x0b\n\x03was\x18\x03 \x01(\r\"9\n\x1bKvmUnmapHvaRangeFtraceEvent\x12\x0b\n\x03\x65nd\x18\x01 \x01(\x04\x12\r\n\x05start\x18\x02 \x01(\x04\"-\n\x1bKvmUserspaceExitFtraceEvent\x12\x0e\n\x06reason\x18\x01 \x01(\r\"E\n\x18KvmVcpuWakeupFtraceEvent\x12\n\n\x02ns\x18\x01 \x01(\x04\x12\r\n\x05valid\x18\x02 \x01(\r\x12\x0e\n\x06waited\x18\x03 \x01(\r\"9\n\x16KvmWfxArm64FtraceEvent\x12\x0e\n\x06is_wfe\x18\x01 \x01(\r\x12\x0f\n\x07vcpu_pc\x18\x02 \x01(\x04\"T\n\x12TrapRegFtraceEvent\x12\n\n\x02\x66n\x18\x01 \x01(\t\x12\x10\n\x08is_write\x18\x02 \x01(\r\x12\x0b\n\x03reg\x18\x03 \x01(\x05\x12\x13\n\x0bwrite_value\x18\x04 \x01(\x04\"N\n\x1fVgicUpdateIrqPendingFtraceEvent\x12\x0b\n\x03irq\x18\x01 \x01(\r\x12\r\n\x05level\x18\x02 \x01(\r\x12\x0f\n\x07vcpu_id\x18\x03 \x01(\x04\"t\n\x18LowmemoryKillFtraceEvent\x12\x0c\n\x04\x63omm\x18\x01 \x01(\t\x12\x0b\n\x03pid\x18\x02 \x01(\x05\x12\x16\n\x0epagecache_size\x18\x03 \x01(\x03\x12\x17\n\x0fpagecache_limit\x18\x04 \x01(\x03\x12\x0c\n\x04\x66ree\x18\x05 \x01(\x03\"q\n\x1fLwisTracingMarkWriteFtraceEvent\x12\x11\n\tlwis_name\x18\x01 \x01(\t\x12\x0c\n\x04type\x18\x02 \x01(\r\x12\x0b\n\x03pid\x18\x03 \x01(\x05\x12\x11\n\tfunc_name\x18\x04 \x01(\t\x12\r\n\x05value\x18\x05 \x01(\x03\"Y\n\x1fMaliTracingMarkWriteFtraceEvent\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0b\n\x03pid\x18\x02 \x01(\x05\x12\x0c\n\x04type\x18\x03 \x01(\r\x12\r\n\x05value\x18\x04 \x01(\x05\"u\n\x1dMaliMaliKCPUCQSSETFtraceEvent\x12\n\n\x02id\x18\x01 \x01(\r\x12\x11\n\tinfo_val1\x18\x02 \x01(\x04\x12\x11\n\tinfo_val2\x18\x03 \x01(\x04\x12\x0f\n\x07kctx_id\x18\x04 \x01(\r\x12\x11\n\tkctx_tgid\x18\x05 \x01(\x05\"{\n#MaliMaliKCPUCQSWAITSTARTFtraceEvent\x12\n\n\x02id\x18\x01 \x01(\r\x12\x11\n\tinfo_val1\x18\x02 \x01(\x04\x12\x11\n\tinfo_val2\x18\x03 \x01(\x04\x12\x0f\n\x07kctx_id\x18\x04 \x01(\r\x12\x11\n\tkctx_tgid\x18\x05 \x01(\x05\"y\n!MaliMaliKCPUCQSWAITENDFtraceEvent\x12\n\n\x02id\x18\x01 \x01(\r\x12\x11\n\tinfo_val1\x18\x02 \x01(\x04\x12\x11\n\tinfo_val2\x18\x03 \x01(\x04\x12\x0f\n\x07kctx_id\x18\x04 \x01(\r\x12\x11\n\tkctx_tgid\x18\x05 \x01(\x05\"z\n\"MaliMaliKCPUFENCESIGNALFtraceEvent\x12\x11\n\tinfo_val1\x18\x01 \x01(\x04\x12\x11\n\tinfo_val2\x18\x02 \x01(\x04\x12\x11\n\tkctx_tgid\x18\x03 \x01(\x05\x12\x0f\n\x07kctx_id\x18\x04 \x01(\r\x12\n\n\x02id\x18\x05 \x01(\r\"}\n%MaliMaliKCPUFENCEWAITSTARTFtraceEvent\x12\x11\n\tinfo_val1\x18\x01 \x01(\x04\x12\x11\n\tinfo_val2\x18\x02 \x01(\x04\x12\x11\n\tkctx_tgid\x18\x03 \x01(\x05\x12\x0f\n\x07kctx_id\x18\x04 \x01(\r\x12\n\n\x02id\x18\x05 \x01(\r\"{\n#MaliMaliKCPUFENCEWAITENDFtraceEvent\x12\x11\n\tinfo_val1\x18\x01 \x01(\x04\x12\x11\n\tinfo_val2\x18\x02 \x01(\x04\x12\x11\n\tkctx_tgid\x18\x03 \x01(\x05\x12\x0f\n\x07kctx_id\x18\x04 \x01(\r\x12\n\n\x02id\x18\x05 \x01(\r\"\\\n$MaliMaliCSFINTERRUPTSTARTFtraceEvent\x12\x11\n\tkctx_tgid\x18\x01 \x01(\x05\x12\x0f\n\x07kctx_id\x18\x02 \x01(\r\x12\x10\n\x08info_val\x18\x03 \x01(\x04\"Z\n\"MaliMaliCSFINTERRUPTENDFtraceEvent\x12\x11\n\tkctx_tgid\x18\x01 \x01(\x05\x12\x0f\n\x07kctx_id\x18\x02 \x01(\r\x12\x10\n\x08info_val\x18\x03 \x01(\x04\"l\n4MaliMaliPMMCUHCTLCORESDOWNSCALENOTIFYPENDFtraceEvent\x12\x11\n\tkctx_tgid\x18\x01 \x01(\x05\x12\x0f\n\x07kctx_id\x18\x02 \x01(\r\x12\x10\n\x08info_val\x18\x03 \x01(\x04\"c\n+MaliMaliPMMCUHCTLCORESNOTIFYPENDFtraceEvent\x12\x11\n\tkctx_tgid\x18\x01 \x01(\x05\x12\x0f\n\x07kctx_id\x18\x02 \x01(\r\x12\x10\n\x08info_val\x18\x03 \x01(\x04\"d\n,MaliMaliPMMCUHCTLCOREINACTIVEPENDFtraceEvent\x12\x11\n\tkctx_tgid\x18\x01 \x01(\x05\x12\x0f\n\x07kctx_id\x18\x02 \x01(\r\x12\x10\n\x08info_val\x18\x03 \x01(\x04\"`\n(MaliMaliPMMCUHCTLMCUONRECHECKFtraceEvent\x12\x11\n\tkctx_tgid\x18\x01 \x01(\x05\x12\x0f\n\x07kctx_id\x18\x02 \x01(\r\x12\x10\n\x08info_val\x18\x03 \x01(\x04\"f\n.MaliMaliPMMCUHCTLSHADERSCOREOFFPENDFtraceEvent\x12\x11\n\tkctx_tgid\x18\x01 \x01(\x05\x12\x0f\n\x07kctx_id\x18\x02 \x01(\r\x12\x10\n\x08info_val\x18\x03 \x01(\x04\"b\n*MaliMaliPMMCUHCTLSHADERSPENDOFFFtraceEvent\x12\x11\n\tkctx_tgid\x18\x01 \x01(\x05\x12\x0f\n\x07kctx_id\x18\x02 \x01(\r\x12\x10\n\x08info_val\x18\x03 \x01(\x04\"a\n)MaliMaliPMMCUHCTLSHADERSPENDONFtraceEvent\x12\x11\n\tkctx_tgid\x18\x01 \x01(\x05\x12\x0f\n\x07kctx_id\x18\x02 \x01(\r\x12\x10\n\x08info_val\x18\x03 \x01(\x04\"c\n+MaliMaliPMMCUHCTLSHADERSREADYOFFFtraceEvent\x12\x11\n\tkctx_tgid\x18\x01 \x01(\x05\x12\x0f\n\x07kctx_id\x18\x02 \x01(\r\x12\x10\n\x08info_val\x18\x03 \x01(\x04\"W\n\x1fMaliMaliPMMCUINSLEEPFtraceEvent\x12\x11\n\tkctx_tgid\x18\x01 \x01(\x05\x12\x0f\n\x07kctx_id\x18\x02 \x01(\r\x12\x10\n\x08info_val\x18\x03 \x01(\x04\"S\n\x1bMaliMaliPMMCUOFFFtraceEvent\x12\x11\n\tkctx_tgid\x18\x01 \x01(\x05\x12\x0f\n\x07kctx_id\x18\x02 \x01(\r\x12\x10\n\x08info_val\x18\x03 \x01(\x04\"R\n\x1aMaliMaliPMMCUONFtraceEvent\x12\x11\n\tkctx_tgid\x18\x01 \x01(\x05\x12\x0f\n\x07kctx_id\x18\x02 \x01(\r\x12\x10\n\x08info_val\x18\x03 \x01(\x04\"d\n,MaliMaliPMMCUONCOREATTRUPDATEPENDFtraceEvent\x12\x11\n\tkctx_tgid\x18\x01 \x01(\x05\x12\x0f\n\x07kctx_id\x18\x02 \x01(\r\x12\x10\n\x08info_val\x18\x03 \x01(\x04\"_\n\'MaliMaliPMMCUONGLBREINITPENDFtraceEvent\x12\x11\n\tkctx_tgid\x18\x01 \x01(\x05\x12\x0f\n\x07kctx_id\x18\x02 \x01(\r\x12\x10\n\x08info_val\x18\x03 \x01(\x04\"V\n\x1eMaliMaliPMMCUONHALTFtraceEvent\x12\x11\n\tkctx_tgid\x18\x01 \x01(\x05\x12\x0f\n\x07kctx_id\x18\x02 \x01(\r\x12\x10\n\x08info_val\x18\x03 \x01(\x04\"^\n&MaliMaliPMMCUONHWCNTDISABLEFtraceEvent\x12\x11\n\tkctx_tgid\x18\x01 \x01(\x05\x12\x0f\n\x07kctx_id\x18\x02 \x01(\r\x12\x10\n\x08info_val\x18\x03 \x01(\x04\"]\n%MaliMaliPMMCUONHWCNTENABLEFtraceEvent\x12\x11\n\tkctx_tgid\x18\x01 \x01(\x05\x12\x0f\n\x07kctx_id\x18\x02 \x01(\r\x12\x10\n\x08info_val\x18\x03 \x01(\x04\"Z\n\"MaliMaliPMMCUONPENDHALTFtraceEvent\x12\x11\n\tkctx_tgid\x18\x01 \x01(\x05\x12\x0f\n\x07kctx_id\x18\x02 \x01(\r\x12\x10\n\x08info_val\x18\x03 \x01(\x04\"[\n#MaliMaliPMMCUONPENDSLEEPFtraceEvent\x12\x11\n\tkctx_tgid\x18\x01 \x01(\x05\x12\x0f\n\x07kctx_id\x18\x02 \x01(\r\x12\x10\n\x08info_val\x18\x03 \x01(\x04\"_\n\'MaliMaliPMMCUONSLEEPINITIATEFtraceEvent\x12\x11\n\tkctx_tgid\x18\x01 \x01(\x05\x12\x0f\n\x07kctx_id\x18\x02 \x01(\r\x12\x10\n\x08info_val\x18\x03 \x01(\x04\"W\n\x1fMaliMaliPMMCUPENDOFFFtraceEvent\x12\x11\n\tkctx_tgid\x18\x01 \x01(\x05\x12\x0f\n\x07kctx_id\x18\x02 \x01(\r\x12\x10\n\x08info_val\x18\x03 \x01(\x04\"\\\n$MaliMaliPMMCUPENDONRELOADFtraceEvent\x12\x11\n\tkctx_tgid\x18\x01 \x01(\x05\x12\x0f\n\x07kctx_id\x18\x02 \x01(\r\x12\x10\n\x08info_val\x18\x03 \x01(\x04\"Y\n!MaliMaliPMMCUPOWERDOWNFtraceEvent\x12\x11\n\tkctx_tgid\x18\x01 \x01(\x05\x12\x0f\n\x07kctx_id\x18\x02 \x01(\r\x12\x10\n\x08info_val\x18\x03 \x01(\x04\"Y\n!MaliMaliPMMCURESETWAITFtraceEvent\x12\x11\n\tkctx_tgid\x18\x01 \x01(\x05\x12\x0f\n\x07kctx_id\x18\x02 \x01(\r\x12\x10\n\x08info_val\x18\x03 \x01(\x04\"W\n\x1cMaliGpuPowerStateFtraceEvent\x12\x11\n\tchange_ns\x18\x01 \x01(\x04\x12\x12\n\nfrom_state\x18\x02 \x01(\x05\x12\x10\n\x08to_state\x18\x03 \x01(\x05\"@\n\x18MdpCmdKickoffFtraceEvent\x12\x0f\n\x07\x63tl_num\x18\x01 \x01(\r\x12\x13\n\x0bkickoff_cnt\x18\x02 \x01(\x05\"Z\n\x14MdpCommitFtraceEvent\x12\x0b\n\x03num\x18\x01 \x01(\r\x12\x10\n\x08play_cnt\x18\x02 \x01(\r\x12\x10\n\x08\x63lk_rate\x18\x03 \x01(\r\x12\x11\n\tbandwidth\x18\x04 \x01(\x04\"[\n\x17MdpPerfSetOtFtraceEvent\x12\x0c\n\x04pnum\x18\x01 \x01(\r\x12\x0e\n\x06xin_id\x18\x02 \x01(\r\x12\x0e\n\x06rd_lim\x18\x03 \x01(\r\x12\x12\n\nis_vbif_rt\x18\x04 \x01(\r\"\x8c\x02\n\x18MdpSsppChangeFtraceEvent\x12\x0b\n\x03num\x18\x01 \x01(\r\x12\x10\n\x08play_cnt\x18\x02 \x01(\r\x12\r\n\x05mixer\x18\x03 \x01(\r\x12\r\n\x05stage\x18\x04 \x01(\r\x12\r\n\x05\x66lags\x18\x05 \x01(\r\x12\x0e\n\x06\x66ormat\x18\x06 \x01(\r\x12\r\n\x05img_w\x18\x07 \x01(\r\x12\r\n\x05img_h\x18\x08 \x01(\r\x12\r\n\x05src_x\x18\t \x01(\r\x12\r\n\x05src_y\x18\n \x01(\r\x12\r\n\x05src_w\x18\x0b \x01(\r\x12\r\n\x05src_h\x18\x0c \x01(\r\x12\r\n\x05\x64st_x\x18\r \x01(\r\x12\r\n\x05\x64st_y\x18\x0e \x01(\r\x12\r\n\x05\x64st_w\x18\x0f \x01(\r\x12\r\n\x05\x64st_h\x18\x10 \x01(\r\"S\n\x1bTracingMarkWriteFtraceEvent\x12\x0b\n\x03pid\x18\x01 \x01(\x05\x12\x12\n\ntrace_name\x18\x02 \x01(\t\x12\x13\n\x0btrace_begin\x18\x03 \x01(\r\"d\n\x1dMdpCmdPingpongDoneFtraceEvent\x12\x0f\n\x07\x63tl_num\x18\x01 \x01(\r\x12\x10\n\x08intf_num\x18\x02 \x01(\r\x12\x0e\n\x06pp_num\x18\x03 \x01(\r\x12\x10\n\x08koff_cnt\x18\x04 \x01(\x05\"\xa4\x01\n\x17MdpCompareBwFtraceEvent\x12\x0e\n\x06new_ab\x18\x01 \x01(\x04\x12\x0e\n\x06new_ib\x18\x02 \x01(\x04\x12\x0e\n\x06new_wb\x18\x03 \x01(\x04\x12\x0e\n\x06old_ab\x18\x04 \x01(\x04\x12\x0e\n\x06old_ib\x18\x05 \x01(\x04\x12\x0e\n\x06old_wb\x18\x06 \x01(\x04\x12\x16\n\x0eparams_changed\x18\x07 \x01(\r\x12\x11\n\tupdate_bw\x18\x08 \x01(\r\"p\n\x1eMdpPerfSetPanicLutsFtraceEvent\x12\x0c\n\x04pnum\x18\x01 \x01(\r\x12\x0b\n\x03\x66mt\x18\x02 \x01(\r\x12\x0c\n\x04mode\x18\x03 \x01(\r\x12\x11\n\tpanic_lut\x18\x04 \x01(\r\x12\x12\n\nrobust_lut\x18\x05 \x01(\r\"\x89\x02\n\x15MdpSsppSetFtraceEvent\x12\x0b\n\x03num\x18\x01 \x01(\r\x12\x10\n\x08play_cnt\x18\x02 \x01(\r\x12\r\n\x05mixer\x18\x03 \x01(\r\x12\r\n\x05stage\x18\x04 \x01(\r\x12\r\n\x05\x66lags\x18\x05 \x01(\r\x12\x0e\n\x06\x66ormat\x18\x06 \x01(\r\x12\r\n\x05img_w\x18\x07 \x01(\r\x12\r\n\x05img_h\x18\x08 \x01(\r\x12\r\n\x05src_x\x18\t \x01(\r\x12\r\n\x05src_y\x18\n \x01(\r\x12\r\n\x05src_w\x18\x0b \x01(\r\x12\r\n\x05src_h\x18\x0c \x01(\r\x12\r\n\x05\x64st_x\x18\r \x01(\r\x12\r\n\x05\x64st_y\x18\x0e \x01(\r\x12\r\n\x05\x64st_w\x18\x0f \x01(\r\x12\r\n\x05\x64st_h\x18\x10 \x01(\r\"A\n\x1cMdpCmdReadptrDoneFtraceEvent\x12\x0f\n\x07\x63tl_num\x18\x01 \x01(\r\x12\x10\n\x08koff_cnt\x18\x02 \x01(\x05\"I\n\x15MdpMisrCrcFtraceEvent\x12\x10\n\x08\x62lock_id\x18\x01 \x01(\r\x12\x11\n\tvsync_cnt\x18\x02 \x01(\r\x12\x0b\n\x03\x63rc\x18\x03 \x01(\r\"}\n\x1cMdpPerfSetQosLutsFtraceEvent\x12\x0c\n\x04pnum\x18\x01 \x01(\r\x12\x0b\n\x03\x66mt\x18\x02 \x01(\r\x12\x0c\n\x04intf\x18\x03 \x01(\r\x12\x0b\n\x03rot\x18\x04 \x01(\r\x12\n\n\x02\x66l\x18\x05 \x01(\r\x12\x0b\n\x03lut\x18\x06 \x01(\r\x12\x0e\n\x06linear\x18\x07 \x01(\r\"N\n\x1aMdpTraceCounterFtraceEvent\x12\x0b\n\x03pid\x18\x01 \x01(\x05\x12\x14\n\x0c\x63ounter_name\x18\x02 \x01(\t\x12\r\n\x05value\x18\x03 \x01(\x05\"-\n\x1aMdpCmdReleaseBwFtraceEvent\x12\x0f\n\x07\x63tl_num\x18\x01 \x01(\r\".\n\x19MdpMixerUpdateFtraceEvent\x12\x11\n\tmixer_num\x18\x01 \x01(\r\"\xa0\x01\n\x1dMdpPerfSetWmLevelsFtraceEvent\x12\x0c\n\x04pnum\x18\x01 \x01(\r\x12\x11\n\tuse_space\x18\x02 \x01(\r\x12\x16\n\x0epriority_bytes\x18\x03 \x01(\r\x12\x0b\n\x03wm0\x18\x04 \x01(\r\x12\x0b\n\x03wm1\x18\x05 \x01(\r\x12\x0b\n\x03wm2\x18\x06 \x01(\r\x12\x0e\n\x06mb_cnt\x18\x07 \x01(\r\x12\x0f\n\x07mb_size\x18\x08 \x01(\r\"H\n\x1fMdpVideoUnderrunDoneFtraceEvent\x12\x0f\n\x07\x63tl_num\x18\x01 \x01(\r\x12\x14\n\x0cunderrun_cnt\x18\x02 \x01(\r\"E\n\x1dMdpCmdWaitPingpongFtraceEvent\x12\x0f\n\x07\x63tl_num\x18\x01 \x01(\r\x12\x13\n\x0bkickoff_cnt\x18\x02 \x01(\x05\"\xce\x01\n\x1dMdpPerfPrefillCalcFtraceEvent\x12\x0c\n\x04pnum\x18\x01 \x01(\r\x12\x13\n\x0blatency_buf\x18\x02 \x01(\r\x12\n\n\x02ot\x18\x03 \x01(\r\x12\r\n\x05y_buf\x18\x04 \x01(\r\x12\x10\n\x08y_scaler\x18\x05 \x01(\r\x12\x10\n\x08pp_lines\x18\x06 \x01(\r\x12\x10\n\x08pp_bytes\x18\x07 \x01(\r\x12\x0f\n\x07post_sc\x18\x08 \x01(\r\x12\x11\n\tfbc_bytes\x18\t \x01(\r\x12\x15\n\rprefill_bytes\x18\n \x01(\r\"Q\n\x1bMdpPerfUpdateBusFtraceEvent\x12\x0e\n\x06\x63lient\x18\x01 \x01(\x05\x12\x10\n\x08\x61\x62_quota\x18\x02 \x01(\x04\x12\x10\n\x08ib_quota\x18\x03 \x01(\x04\"0\n\x1fRotatorBwAoAsContextFtraceEvent\x12\r\n\x05state\x18\x01 \x01(\r\"Y\n\x18MmEventRecordFtraceEvent\x12\x0f\n\x07\x61vg_lat\x18\x01 \x01(\r\x12\r\n\x05\x63ount\x18\x02 \x01(\r\x12\x0f\n\x07max_lat\x18\x03 \x01(\r\x12\x0c\n\x04type\x18\x04 \x01(\r\"H\n\x1aNetifReceiveSkbFtraceEvent\x12\x0b\n\x03len\x18\x01 \x01(\r\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x0f\n\x07skbaddr\x18\x03 \x01(\x04\"O\n\x15NetDevXmitFtraceEvent\x12\x0b\n\x03len\x18\x01 \x01(\r\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\n\n\x02rc\x18\x03 \x01(\x05\x12\x0f\n\x07skbaddr\x18\x04 \x01(\x04\"\xfb\x02\n\x1eNapiGroReceiveEntryFtraceEvent\x12\x10\n\x08\x64\x61ta_len\x18\x01 \x01(\r\x12\x10\n\x08gso_size\x18\x02 \x01(\r\x12\x10\n\x08gso_type\x18\x03 \x01(\r\x12\x0c\n\x04hash\x18\x04 \x01(\r\x12\x11\n\tip_summed\x18\x05 \x01(\r\x12\x0f\n\x07l4_hash\x18\x06 \x01(\r\x12\x0b\n\x03len\x18\x07 \x01(\r\x12\x12\n\nmac_header\x18\x08 \x01(\x05\x12\x18\n\x10mac_header_valid\x18\t \x01(\r\x12\x0c\n\x04name\x18\n \x01(\t\x12\x0f\n\x07napi_id\x18\x0b \x01(\r\x12\x10\n\x08nr_frags\x18\x0c \x01(\r\x12\x10\n\x08protocol\x18\r \x01(\r\x12\x15\n\rqueue_mapping\x18\x0e \x01(\r\x12\x0f\n\x07skbaddr\x18\x0f \x01(\x04\x12\x10\n\x08truesize\x18\x10 \x01(\r\x12\x12\n\nvlan_proto\x18\x11 \x01(\r\x12\x13\n\x0bvlan_tagged\x18\x12 \x01(\r\x12\x10\n\x08vlan_tci\x18\x13 \x01(\r\",\n\x1dNapiGroReceiveExitFtraceEvent\x12\x0b\n\x03ret\x18\x01 \x01(\x05\"P\n\x1cOomScoreAdjUpdateFtraceEvent\x12\x0c\n\x04\x63omm\x18\x01 \x01(\t\x12\x15\n\room_score_adj\x18\x02 \x01(\x05\x12\x0b\n\x03pid\x18\x03 \x01(\x05\"$\n\x15MarkVictimFtraceEvent\x12\x0b\n\x03pid\x18\x01 \x01(\x05\">\n\x1b\x44siCmdFifoStatusFtraceEvent\x12\x0e\n\x06header\x18\x01 \x01(\r\x12\x0f\n\x07payload\x18\x02 \x01(\r\"/\n\x10\x44siRxFtraceEvent\x12\x0b\n\x03\x63md\x18\x01 \x01(\r\x12\x0e\n\x06rx_buf\x18\x03 \x01(\x0c\">\n\x10\x44siTxFtraceEvent\x12\x0c\n\x04last\x18\x01 \x01(\r\x12\x0c\n\x04type\x18\x03 \x01(\r\x12\x0e\n\x06tx_buf\x18\x04 \x01(\x0c\"\x7f\n\x1cPanelWriteGenericFtraceEvent\x12\x0b\n\x03pid\x18\x01 \x01(\x05\x12\x12\n\ntrace_name\x18\x02 \x01(\t\x12\x13\n\x0btrace_begin\x18\x03 \x01(\r\x12\x0c\n\x04name\x18\x04 \x01(\t\x12\x0c\n\x04type\x18\x05 \x01(\r\x12\r\n\x05value\x18\x06 \x01(\x05\"F\n\x18GramCollisionFtraceEvent\x12\x13\n\x0bpanel_index\x18\x01 \x01(\x05\x12\x15\n\rcollision_cnt\x18\x02 \x01(\r\"\xc5\x01\n\x1cPanelSettingsFullFtraceEvent\x12\x13\n\x0bpanel_index\x18\x01 \x01(\x05\x12\x0b\n\x03hbm\x18\x02 \x01(\r\x12\x0b\n\x03irc\x18\x03 \x01(\r\x12\r\n\x05h_pwm\x18\x04 \x01(\r\x12\x0f\n\x07\x66i_auto\x18\x05 \x01(\r\x12\x11\n\tfi_manual\x18\x06 \x01(\r\x12\x12\n\nearly_exit\x18\x07 \x01(\r\x12\x0e\n\x06min_rr\x18\x08 \x01(\r\x12\x0e\n\x06max_rr\x18\t \x01(\r\x12\x0f\n\x07te_freq\x18\n \x01(\r\"q\n\x1cPanelSettingsLiteFtraceEvent\x12\x13\n\x0bpanel_index\x18\x01 \x01(\x05\x12\x0b\n\x03vrr\x18\x02 \x01(\r\x12\x0e\n\x06min_rr\x18\x03 \x01(\r\x12\x0e\n\x06max_rr\x18\x04 \x01(\r\x12\x0f\n\x07te_freq\x18\x05 \x01(\r\"\x84\x03\n\x1eSchedSwitchWithCtrsFtraceEvent\x12\x0f\n\x07old_pid\x18\x01 \x01(\x05\x12\x0f\n\x07new_pid\x18\x02 \x01(\x05\x12\x0c\n\x04\x63\x63tr\x18\x03 \x01(\x04\x12\x0c\n\x04\x63tr0\x18\x04 \x01(\x04\x12\x0c\n\x04\x63tr1\x18\x05 \x01(\x04\x12\x0c\n\x04\x63tr2\x18\x06 \x01(\x04\x12\x0c\n\x04\x63tr3\x18\x07 \x01(\x04\x12\r\n\x05lctr0\x18\x08 \x01(\r\x12\r\n\x05lctr1\x18\t \x01(\r\x12\x0c\n\x04\x63tr4\x18\n \x01(\x04\x12\x0c\n\x04\x63tr5\x18\x0b \x01(\x04\x12\x11\n\tprev_comm\x18\x0c \x01(\t\x12\x10\n\x08prev_pid\x18\r \x01(\x05\x12\x0b\n\x03\x63yc\x18\x0e \x01(\r\x12\x0c\n\x04inst\x18\x0f \x01(\r\x12\x0f\n\x07stallbm\x18\x10 \x01(\r\x12\x0c\n\x04l3dm\x18\x11 \x01(\r\x12\x10\n\x08next_pid\x18\x12 \x01(\x05\x12\x11\n\tnext_comm\x18\x13 \x01(\t\x12\x12\n\nprev_state\x18\x14 \x01(\x03\x12\x0c\n\x04\x61mu0\x18\x15 \x01(\x04\x12\x0c\n\x04\x61mu1\x18\x16 \x01(\x04\x12\x0c\n\x04\x61mu2\x18\x17 \x01(\x04\"A\n\x12LongIrqFtraceEvent\x12\x0b\n\x03irq\x18\x01 \x01(\x05\x12\x0f\n\x07latency\x18\x02 \x01(\r\x12\r\n\x05\x63ount\x18\x03 \x01(\r\"H\n\x16LongSoftirqFtraceEvent\x12\x0e\n\x06vec_nr\x18\x01 \x01(\x05\x12\x0f\n\x07latency\x18\x02 \x01(\r\x12\r\n\x05\x63ount\x18\x03 \x01(\r\"0\n\x1cPixelMmKswapdWakeFtraceEvent\x12\x10\n\x08whatever\x18\x01 \x01(\x05\"\x85\x01\n\x1cPixelMmKswapdDoneFtraceEvent\x12\x18\n\x10\x64\x65lta_nr_scanned\x18\x01 \x01(\x04\x12\x1a\n\x12\x64\x65lta_nr_reclaimed\x18\x02 \x01(\x04\x12\x1a\n\x12\x64\x65lta_nr_allocated\x18\x03 \x01(\x04\x12\x13\n\x0b\x64uration_ns\x18\x04 \x01(\x04\"8\n\x17\x43puFrequencyFtraceEvent\x12\r\n\x05state\x18\x01 \x01(\r\x12\x0e\n\x06\x63pu_id\x18\x02 \x01(\r\"S\n\x1d\x43puFrequencyLimitsFtraceEvent\x12\x10\n\x08min_freq\x18\x01 \x01(\r\x12\x10\n\x08max_freq\x18\x02 \x01(\r\x12\x0e\n\x06\x63pu_id\x18\x03 \x01(\r\"3\n\x12\x43puIdleFtraceEvent\x12\r\n\x05state\x18\x01 \x01(\r\x12\x0e\n\x06\x63pu_id\x18\x02 \x01(\r\"E\n\x16\x43lockEnableFtraceEvent\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\r\n\x05state\x18\x02 \x01(\x04\x12\x0e\n\x06\x63pu_id\x18\x03 \x01(\x04\"F\n\x17\x43lockDisableFtraceEvent\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\r\n\x05state\x18\x02 \x01(\x04\x12\x0e\n\x06\x63pu_id\x18\x03 \x01(\x04\"F\n\x17\x43lockSetRateFtraceEvent\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\r\n\x05state\x18\x02 \x01(\x04\x12\x0e\n\x06\x63pu_id\x18\x03 \x01(\x04\"F\n\x18SuspendResumeFtraceEvent\x12\x0e\n\x06\x61\x63tion\x18\x01 \x01(\t\x12\x0b\n\x03val\x18\x02 \x01(\x05\x12\r\n\x05start\x18\x03 \x01(\r\"8\n\x17GpuFrequencyFtraceEvent\x12\x0e\n\x06gpu_id\x18\x01 \x01(\r\x12\r\n\x05state\x18\x02 \x01(\r\">\n\x1fWakeupSourceActivateFtraceEvent\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\r\n\x05state\x18\x02 \x01(\x04\"@\n!WakeupSourceDeactivateFtraceEvent\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\r\n\x05state\x18\x02 \x01(\x04\"\x85\x01\n\x18GpuWorkPeriodFtraceEvent\x12\x0e\n\x06gpu_id\x18\x01 \x01(\r\x12\x0b\n\x03uid\x18\x02 \x01(\r\x12\x15\n\rstart_time_ns\x18\x03 \x01(\x04\x12\x13\n\x0b\x65nd_time_ns\x18\x04 \x01(\x04\x12 \n\x18total_active_duration_ns\x18\x05 \x01(\x04\"q\n DevicePmCallbackStartFtraceEvent\x12\x0e\n\x06\x64\x65vice\x18\x01 \x01(\t\x12\x0e\n\x06\x64river\x18\x02 \x01(\t\x12\x0e\n\x06parent\x18\x03 \x01(\t\x12\x0e\n\x06pm_ops\x18\x04 \x01(\t\x12\r\n\x05\x65vent\x18\x05 \x01(\x05\"O\n\x1e\x44\x65vicePmCallbackEndFtraceEvent\x12\x0e\n\x06\x64\x65vice\x18\x01 \x01(\t\x12\x0e\n\x06\x64river\x18\x02 \x01(\t\x12\r\n\x05\x65rror\x18\x03 \x01(\x05\"@\n\x18GpuPowerStateFtraceEvent\x12\x11\n\told_state\x18\x01 \x01(\x05\x12\x11\n\tnew_state\x18\x02 \x01(\x05\"N\n\x1dPsciDomainIdleExitFtraceEvent\x12\x0e\n\x06\x63pu_id\x18\x01 \x01(\r\x12\r\n\x05state\x18\x02 \x01(\r\x12\x0e\n\x06s2idle\x18\x03 \x01(\r\"O\n\x1ePsciDomainIdleEnterFtraceEvent\x12\x0e\n\x06\x63pu_id\x18\x01 \x01(\r\x12\r\n\x05state\x18\x02 \x01(\r\x12\x0e\n\x06s2idle\x18\x03 \x01(\r\"!\n\x12\x43onsoleFtraceEvent\x12\x0b\n\x03msg\x18\x01 \x01(\t\"/\n\x13SysEnterFtraceEvent\x12\n\n\x02id\x18\x01 \x01(\x03\x12\x0c\n\x04\x61rgs\x18\x02 \x03(\x04\"-\n\x12SysExitFtraceEvent\x12\n\n\x02id\x18\x01 \x01(\x03\x12\x0b\n\x03ret\x18\x02 \x01(\x03\"+\n\x1bRegulatorDisableFtraceEvent\x12\x0c\n\x04name\x18\x01 \x01(\t\"3\n#RegulatorDisableCompleteFtraceEvent\x12\x0c\n\x04name\x18\x01 \x01(\t\"*\n\x1aRegulatorEnableFtraceEvent\x12\x0c\n\x04name\x18\x01 \x01(\t\"2\n\"RegulatorEnableCompleteFtraceEvent\x12\x0c\n\x04name\x18\x01 \x01(\t\"/\n\x1fRegulatorEnableDelayFtraceEvent\x12\x0c\n\x04name\x18\x01 \x01(\t\"H\n\x1eRegulatorSetVoltageFtraceEvent\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0b\n\x03min\x18\x02 \x01(\x05\x12\x0b\n\x03max\x18\x03 \x01(\x05\"C\n&RegulatorSetVoltageCompleteFtraceEvent\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0b\n\x03val\x18\x02 \x01(\r\"4\n\x14RpmStatusFtraceEvent\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0e\n\x06status\x18\x02 \x01(\x05\"}\n\"SamsungTracingMarkWriteFtraceEvent\x12\x0b\n\x03pid\x18\x01 \x01(\x05\x12\x12\n\ntrace_name\x18\x02 \x01(\t\x12\x13\n\x0btrace_begin\x18\x03 \x01(\r\x12\x12\n\ntrace_type\x18\x04 \x01(\r\x12\r\n\x05value\x18\x05 \x01(\x05\"\x9c\x01\n\x16SchedSwitchFtraceEvent\x12\x11\n\tprev_comm\x18\x01 \x01(\t\x12\x10\n\x08prev_pid\x18\x02 \x01(\x05\x12\x11\n\tprev_prio\x18\x03 \x01(\x05\x12\x12\n\nprev_state\x18\x04 \x01(\x03\x12\x11\n\tnext_comm\x18\x05 \x01(\t\x12\x10\n\x08next_pid\x18\x06 \x01(\x05\x12\x11\n\tnext_prio\x18\x07 \x01(\x05\"f\n\x16SchedWakeupFtraceEvent\x12\x0c\n\x04\x63omm\x18\x01 \x01(\t\x12\x0b\n\x03pid\x18\x02 \x01(\x05\x12\x0c\n\x04prio\x18\x03 \x01(\x05\x12\x0f\n\x07success\x18\x04 \x01(\x05\x12\x12\n\ntarget_cpu\x18\x05 \x01(\x05\"M\n\x1dSchedBlockedReasonFtraceEvent\x12\x0b\n\x03pid\x18\x01 \x01(\x05\x12\x0e\n\x06\x63\x61ller\x18\x02 \x01(\x04\x12\x0f\n\x07io_wait\x18\x03 \x01(\r\"Q\n\x1aSchedCpuHotplugFtraceEvent\x12\x14\n\x0c\x61\x66\x66\x65\x63ted_cpu\x18\x01 \x01(\x05\x12\r\n\x05\x65rror\x18\x02 \x01(\x05\x12\x0e\n\x06status\x18\x03 \x01(\x05\"f\n\x16SchedWakingFtraceEvent\x12\x0c\n\x04\x63omm\x18\x01 \x01(\t\x12\x0b\n\x03pid\x18\x02 \x01(\x05\x12\x0c\n\x04prio\x18\x03 \x01(\x05\x12\x0f\n\x07success\x18\x04 \x01(\x05\x12\x12\n\ntarget_cpu\x18\x05 \x01(\x05\"i\n\x19SchedWakeupNewFtraceEvent\x12\x0c\n\x04\x63omm\x18\x01 \x01(\t\x12\x0b\n\x03pid\x18\x02 \x01(\x05\x12\x0c\n\x04prio\x18\x03 \x01(\x05\x12\x0f\n\x07success\x18\x04 \x01(\x05\x12\x12\n\ntarget_cpu\x18\x05 \x01(\x05\"M\n\x1bSchedProcessExecFtraceEvent\x12\x10\n\x08\x66ilename\x18\x01 \x01(\t\x12\x0b\n\x03pid\x18\x02 \x01(\x05\x12\x0f\n\x07old_pid\x18\x03 \x01(\x05\"T\n\x1bSchedProcessExitFtraceEvent\x12\x0c\n\x04\x63omm\x18\x01 \x01(\t\x12\x0b\n\x03pid\x18\x02 \x01(\x05\x12\x0c\n\x04tgid\x18\x03 \x01(\x05\x12\x0c\n\x04prio\x18\x04 \x01(\x05\"m\n\x1bSchedProcessForkFtraceEvent\x12\x13\n\x0bparent_comm\x18\x01 \x01(\t\x12\x12\n\nparent_pid\x18\x02 \x01(\x05\x12\x12\n\nchild_comm\x18\x03 \x01(\t\x12\x11\n\tchild_pid\x18\x04 \x01(\x05\"F\n\x1bSchedProcessFreeFtraceEvent\x12\x0c\n\x04\x63omm\x18\x01 \x01(\t\x12\x0b\n\x03pid\x18\x02 \x01(\x05\x12\x0c\n\x04prio\x18\x03 \x01(\x05\"8\n\x1bSchedProcessHangFtraceEvent\x12\x0c\n\x04\x63omm\x18\x01 \x01(\t\x12\x0b\n\x03pid\x18\x02 \x01(\x05\"F\n\x1bSchedProcessWaitFtraceEvent\x12\x0c\n\x04\x63omm\x18\x01 \x01(\t\x12\x0b\n\x03pid\x18\x02 \x01(\x05\x12\x0c\n\x04prio\x18\x03 \x01(\x05\"X\n\x19SchedPiSetprioFtraceEvent\x12\x0c\n\x04\x63omm\x18\x01 \x01(\t\x12\x0f\n\x07newprio\x18\x02 \x01(\x05\x12\x0f\n\x07oldprio\x18\x03 \x01(\x05\x12\x0b\n\x03pid\x18\x04 \x01(\x05\"\xc8\x02\n\x1aSchedCpuUtilCfsFtraceEvent\x12\x0e\n\x06\x61\x63tive\x18\x01 \x01(\x05\x12\x10\n\x08\x63\x61pacity\x18\x02 \x01(\x04\x12\x15\n\rcapacity_orig\x18\x03 \x01(\x04\x12\x0b\n\x03\x63pu\x18\x04 \x01(\r\x12\x16\n\x0e\x63pu_importance\x18\x05 \x01(\x04\x12\x10\n\x08\x63pu_util\x18\x06 \x01(\x04\x12\x10\n\x08\x65xit_lat\x18\x07 \x01(\r\x12\x16\n\x0egroup_capacity\x18\x08 \x01(\x04\x12\x18\n\x10grp_overutilized\x18\t \x01(\r\x12\x10\n\x08idle_cpu\x18\n \x01(\r\x12\x12\n\nnr_running\x18\x0b \x01(\r\x12\x11\n\tspare_cap\x18\x0c \x01(\x03\x12\x11\n\ttask_fits\x18\r \x01(\r\x12\x17\n\x0fwake_group_util\x18\x0e \x01(\x04\x12\x11\n\twake_util\x18\x0f \x01(\x04\"\x89\x01\n\x1bSchedMigrateTaskFtraceEvent\x12\x0c\n\x04\x63omm\x18\x01 \x01(\t\x12\x0b\n\x03pid\x18\x02 \x01(\x05\x12\x0c\n\x04prio\x18\x03 \x01(\x05\x12\x10\n\x08orig_cpu\x18\x04 \x01(\x05\x12\x10\n\x08\x64\x65st_cpu\x18\x05 \x01(\x05\x12\x0f\n\x07running\x18\x06 \x01(\x05\x12\x0c\n\x04load\x18\x07 \x01(\r\"\xf0\x01\n\x1eSchedWakeupTaskAttrFtraceEvent\x12\x0b\n\x03pid\x18\x01 \x01(\x05\x12\x14\n\x0c\x63pu_affinity\x18\x02 \x01(\x04\x12\x11\n\ttask_util\x18\x03 \x01(\x04\x12\x12\n\nuclamp_min\x18\x04 \x01(\x04\x12\x10\n\x08vruntime\x18\x05 \x01(\x04\x12#\n\x1bsched_qos_user_defined_flag\x18\x06 \x01(\x04\x12\x19\n\x11rampup_multiplier\x18\x07 \x01(\r\x12 \n\x18\x65\x66\x66\x65\x63t_rampup_multiplier\x18\x08 \x01(\r\x12\x10\n\x08tag_nice\x18\t \x01(\x05\"[\n\x1cSchedGroupTrackerFtraceEvent\x12\x0c\n\x04\x63omm\x18\x01 \x01(\t\x12\x0b\n\x03pid\x18\x02 \x01(\x05\x12\r\n\x05group\x18\x03 \x01(\t\x12\x11\n\tgroup_num\x18\x04 \x01(\x05\"B\n\x17ScmCallStartFtraceEvent\x12\x0f\n\x07\x61rginfo\x18\x01 \x01(\r\x12\n\n\x02x0\x18\x02 \x01(\x04\x12\n\n\x02x5\x18\x03 \x01(\x04\"\x17\n\x15ScmCallEndFtraceEvent\"\xfc\x01\n\x1fScsiDispatchCmdErrorFtraceEvent\x12\x0f\n\x07host_no\x18\x01 \x01(\r\x12\x0f\n\x07\x63hannel\x18\x02 \x01(\r\x12\n\n\x02id\x18\x03 \x01(\r\x12\x0b\n\x03lun\x18\x04 \x01(\r\x12\x0b\n\x03rtn\x18\x05 \x01(\x05\x12\x0e\n\x06opcode\x18\x06 \x01(\r\x12\x0f\n\x07\x63md_len\x18\x07 \x01(\r\x12\x12\n\ndata_sglen\x18\x08 \x01(\r\x12\x12\n\nprot_sglen\x18\t \x01(\r\x12\x0f\n\x07prot_op\x18\n \x01(\r\x12\x12\n\ndriver_tag\x18\x0c \x01(\x05\x12\x15\n\rscheduler_tag\x18\r \x01(\x05\x12\x0c\n\x04\x63mnd\x18\x0e \x01(\x0c\"\xaf\x02\n!ScsiDispatchCmdTimeoutFtraceEvent\x12\x0f\n\x07host_no\x18\x01 \x01(\r\x12\x0f\n\x07\x63hannel\x18\x02 \x01(\r\x12\n\n\x02id\x18\x03 \x01(\r\x12\x0b\n\x03lun\x18\x04 \x01(\r\x12\x0e\n\x06result\x18\x05 \x01(\x05\x12\x0e\n\x06opcode\x18\x06 \x01(\r\x12\x0f\n\x07\x63md_len\x18\x07 \x01(\r\x12\x12\n\ndata_sglen\x18\x08 \x01(\r\x12\x12\n\nprot_sglen\x18\t \x01(\r\x12\x0f\n\x07prot_op\x18\n \x01(\r\x12\x12\n\ndriver_tag\x18\x0c \x01(\x05\x12\x15\n\rscheduler_tag\x18\r \x01(\x05\x12\x11\n\tsense_key\x18\x0e \x01(\r\x12\x0b\n\x03\x61sc\x18\x0f \x01(\r\x12\x0c\n\x04\x61scq\x18\x10 \x01(\r\x12\x0c\n\x04\x63mnd\x18\x11 \x01(\x0c\"*\n\x17ScsiEhWakeupFtraceEvent\x12\x0f\n\x07host_no\x18\x01 \x01(\r\"y\n\x1eSdeTracingMarkWriteFtraceEvent\x12\x0b\n\x03pid\x18\x01 \x01(\x05\x12\x12\n\ntrace_name\x18\x02 \x01(\t\x12\x12\n\ntrace_type\x18\x03 \x01(\r\x12\r\n\x05value\x18\x04 \x01(\x05\x12\x13\n\x0btrace_begin\x18\x05 \x01(\r\"\x8d\x02\n\x17SdeSdeEvtlogFtraceEvent\x12\x12\n\nevtlog_tag\x18\x01 \x01(\t\x12\x0b\n\x03pid\x18\x02 \x01(\x05\x12\x0e\n\x06tag_id\x18\x03 \x01(\r\x12\x0b\n\x03\x64\x30\x30\x18\x04 \x01(\r\x12\x0b\n\x03\x64\x30\x31\x18\x05 \x01(\r\x12\x0b\n\x03\x64\x30\x32\x18\x06 \x01(\r\x12\x0b\n\x03\x64\x30\x33\x18\x07 \x01(\r\x12\x0b\n\x03\x64\x30\x34\x18\x08 \x01(\r\x12\x0b\n\x03\x64\x30\x35\x18\t \x01(\r\x12\x0b\n\x03\x64\x30\x36\x18\n \x01(\r\x12\x0b\n\x03\x64\x30\x37\x18\x0b \x01(\r\x12\x0b\n\x03\x64\x30\x38\x18\x0c \x01(\r\x12\x0b\n\x03\x64\x30\x39\x18\r \x01(\r\x12\x0b\n\x03\x64\x31\x30\x18\x0e \x01(\r\x12\x0b\n\x03\x64\x31\x31\x18\x0f \x01(\r\x12\x0b\n\x03\x64\x31\x32\x18\x10 \x01(\r\x12\x0b\n\x03\x64\x31\x33\x18\x11 \x01(\r\x12\x0b\n\x03\x64\x31\x34\x18\x12 \x01(\r\"\xb4\x01\n\x1dSdeSdePerfCalcCrtcFtraceEvent\x12\x12\n\nbw_ctl_ebi\x18\x01 \x01(\x04\x12\x13\n\x0b\x62w_ctl_llcc\x18\x02 \x01(\x04\x12\x13\n\x0b\x62w_ctl_mnoc\x18\x03 \x01(\x04\x12\x15\n\rcore_clk_rate\x18\x04 \x01(\r\x12\x0c\n\x04\x63rtc\x18\x05 \x01(\r\x12\x0e\n\x06ib_ebi\x18\x06 \x01(\x04\x12\x0f\n\x07ib_llcc\x18\x07 \x01(\x04\x12\x0f\n\x07ib_mnoc\x18\x08 \x01(\x04\"\x9b\x02\n\x1fSdeSdePerfCrtcUpdateFtraceEvent\x12\x12\n\nbw_ctl_ebi\x18\x01 \x01(\x04\x12\x13\n\x0b\x62w_ctl_llcc\x18\x02 \x01(\x04\x12\x13\n\x0b\x62w_ctl_mnoc\x18\x03 \x01(\x04\x12\x15\n\rcore_clk_rate\x18\x04 \x01(\r\x12\x0c\n\x04\x63rtc\x18\x05 \x01(\r\x12\x0e\n\x06params\x18\x06 \x01(\x05\x12\x17\n\x0fper_pipe_ib_ebi\x18\x07 \x01(\x04\x12\x18\n\x10per_pipe_ib_llcc\x18\x08 \x01(\x04\x12\x18\n\x10per_pipe_ib_mnoc\x18\t \x01(\x04\x12\x10\n\x08stop_req\x18\n \x01(\r\x12\x12\n\nupdate_bus\x18\x0b \x01(\r\x12\x12\n\nupdate_clk\x18\x0c \x01(\r\"t\n\x1fSdeSdePerfSetQosLutsFtraceEvent\x12\n\n\x02\x66l\x18\x01 \x01(\r\x12\x0b\n\x03\x66mt\x18\x02 \x01(\r\x12\x0b\n\x03lut\x18\x03 \x01(\x04\x12\x11\n\tlut_usage\x18\x04 \x01(\r\x12\x0c\n\x04pnum\x18\x05 \x01(\r\x12\n\n\x02rt\x18\x06 \x01(\r\"d\n\x1eSdeSdePerfUpdateBusFtraceEvent\x12\x10\n\x08\x61\x62_quota\x18\x01 \x01(\x04\x12\x0e\n\x06\x62us_id\x18\x02 \x01(\r\x12\x0e\n\x06\x63lient\x18\x03 \x01(\x05\x12\x10\n\x08ib_quota\x18\x04 \x01(\x04\"G\n\x18SignalDeliverFtraceEvent\x12\x0c\n\x04\x63ode\x18\x01 \x01(\x05\x12\x10\n\x08sa_flags\x18\x02 \x01(\x04\x12\x0b\n\x03sig\x18\x03 \x01(\x05\"p\n\x19SignalGenerateFtraceEvent\x12\x0c\n\x04\x63ode\x18\x01 \x01(\x05\x12\x0c\n\x04\x63omm\x18\x02 \x01(\t\x12\r\n\x05group\x18\x03 \x01(\x05\x12\x0b\n\x03pid\x18\x04 \x01(\x05\x12\x0e\n\x06result\x18\x05 \x01(\x05\x12\x0b\n\x03sig\x18\x06 \x01(\x05\"J\n\x13KfreeSkbFtraceEvent\x12\x10\n\x08location\x18\x01 \x01(\x04\x12\x10\n\x08protocol\x18\x02 \x01(\r\x12\x0f\n\x07skbaddr\x18\x03 \x01(\x04\"\xaf\x01\n\x1bInetSockSetStateFtraceEvent\x12\r\n\x05\x64\x61\x64\x64r\x18\x01 \x01(\r\x12\r\n\x05\x64port\x18\x02 \x01(\r\x12\x0e\n\x06\x66\x61mily\x18\x03 \x01(\r\x12\x10\n\x08newstate\x18\x04 \x01(\x05\x12\x10\n\x08oldstate\x18\x05 \x01(\x05\x12\x10\n\x08protocol\x18\x06 \x01(\r\x12\r\n\x05saddr\x18\x07 \x01(\r\x12\x0e\n\x06skaddr\x18\x08 \x01(\x04\x12\r\n\x05sport\x18\t \x01(\r\"4\n\x11SyncPtFtraceEvent\x12\x10\n\x08timeline\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t\"6\n\x17SyncTimelineFtraceEvent\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t\"B\n\x13SyncWaitFtraceEvent\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0e\n\x06status\x18\x02 \x01(\x05\x12\r\n\x05\x62\x65gin\x18\x03 \x01(\r\"X\n\x1bRssStatThrottledFtraceEvent\x12\x0c\n\x04\x63urr\x18\x01 \x01(\r\x12\x0e\n\x06member\x18\x02 \x01(\x05\x12\r\n\x05mm_id\x18\x03 \x01(\r\x12\x0c\n\x04size\x18\x04 \x01(\x03\"0\n\x1fSuspendResumeMinimalFtraceEvent\x12\r\n\x05start\x18\x01 \x01(\r\"I\n\x0fZeroFtraceEvent\x12\x0c\n\x04\x66lag\x18\x01 \x01(\x05\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x0b\n\x03pid\x18\x03 \x01(\x05\x12\r\n\x05value\x18\x04 \x01(\x03\"_\n\x16TaskNewtaskFtraceEvent\x12\x0b\n\x03pid\x18\x01 \x01(\x05\x12\x0c\n\x04\x63omm\x18\x02 \x01(\t\x12\x13\n\x0b\x63lone_flags\x18\x03 \x01(\x04\x12\x15\n\room_score_adj\x18\x04 \x01(\x05\"]\n\x15TaskRenameFtraceEvent\x12\x0b\n\x03pid\x18\x01 \x01(\x05\x12\x0f\n\x07oldcomm\x18\x02 \x01(\t\x12\x0f\n\x07newcomm\x18\x03 \x01(\t\x12\x15\n\room_score_adj\x18\x04 \x01(\x05\"\x89\x01\n\x1bTcpRetransmitSkbFtraceEvent\x12\r\n\x05\x64\x61\x64\x64r\x18\x01 \x01(\r\x12\r\n\x05\x64port\x18\x02 \x01(\r\x12\r\n\x05saddr\x18\x03 \x01(\r\x12\x0e\n\x06skaddr\x18\x04 \x01(\x04\x12\x0f\n\x07skbaddr\x18\x05 \x01(\x04\x12\r\n\x05sport\x18\x06 \x01(\r\x12\r\n\x05state\x18\x07 \x01(\x05\"b\n\x1dThermalTemperatureFtraceEvent\x12\n\n\x02id\x18\x01 \x01(\x05\x12\x0c\n\x04temp\x18\x02 \x01(\x05\x12\x11\n\ttemp_prev\x18\x03 \x01(\x05\x12\x14\n\x0cthermal_zone\x18\x04 \x01(\t\"5\n\x15\x43\x64\x65vUpdateFtraceEvent\x12\x0e\n\x06target\x18\x01 \x01(\x04\x12\x0c\n\x04type\x18\x02 \x01(\t\"\xe4\x01\n ThermalExynosAcpmBulkFtraceEvent\x12\r\n\x05tz_id\x18\x01 \x01(\r\x12\x14\n\x0c\x63urrent_temp\x18\x02 \x01(\r\x12\x11\n\tctrl_temp\x18\x03 \x01(\r\x12\x12\n\ncdev_state\x18\x04 \x01(\r\x12\x10\n\x08pid_et_p\x18\x05 \x01(\x05\x12\x17\n\x0fpid_power_range\x18\x06 \x01(\x05\x12\r\n\x05pid_p\x18\x07 \x01(\x05\x12\r\n\x05pid_i\x18\x08 \x01(\x05\x12\x0b\n\x03k_p\x18\t \x01(\x05\x12\x0b\n\x03k_i\x18\n \x01(\x05\x12\x11\n\ttimestamp\x18\x0b \x01(\x04\"\xa2\x01\n(ThermalExynosAcpmHighOverheadFtraceEvent\x12\r\n\x05tz_id\x18\x01 \x01(\x05\x12\x14\n\x0c\x63urrent_temp\x18\x02 \x01(\r\x12\x11\n\tctrl_temp\x18\x03 \x01(\r\x12\x12\n\ncdev_state\x18\x04 \x01(\r\x12\x10\n\x08pid_et_p\x18\x05 \x01(\x05\x12\x0b\n\x03k_p\x18\x06 \x01(\x05\x12\x0b\n\x03k_i\x18\x07 \x01(\x05\"p\n\x17HrtimerStartFtraceEvent\x12\x0f\n\x07hrtimer\x18\x01 \x01(\x04\x12\x10\n\x08\x66unction\x18\x02 \x01(\x04\x12\x0f\n\x07\x65xpires\x18\x03 \x01(\x03\x12\x13\n\x0bsoftexpires\x18\x04 \x01(\x03\x12\x0c\n\x04mode\x18\x05 \x01(\r\"+\n\x18HrtimerCancelFtraceEvent\x12\x0f\n\x07hrtimer\x18\x01 \x01(\x04\"O\n\x1dHrtimerExpireEntryFtraceEvent\x12\x0f\n\x07hrtimer\x18\x01 \x01(\x04\x12\x0b\n\x03now\x18\x02 \x01(\x03\x12\x10\n\x08\x66unction\x18\x03 \x01(\x04\"/\n\x1cHrtimerExpireExitFtraceEvent\x12\x0f\n\x07hrtimer\x18\x01 \x01(\x04\"\x90\x01\n\x15TimerStartFtraceEvent\x12\r\n\x05timer\x18\x01 \x01(\x04\x12\x10\n\x08\x66unction\x18\x02 \x01(\x04\x12\x0f\n\x07\x65xpires\x18\x03 \x01(\x04\x12\x0b\n\x03now\x18\x04 \x01(\x04\x12\x12\n\ndeferrable\x18\x05 \x01(\r\x12\r\n\x05\x66lags\x18\x06 \x01(\r\x12\x15\n\rbucket_expiry\x18\x07 \x01(\x04\"\'\n\x16TimerCancelFtraceEvent\x12\r\n\x05timer\x18\x01 \x01(\x04\"\\\n\x1bTimerExpireEntryFtraceEvent\x12\r\n\x05timer\x18\x01 \x01(\x04\x12\x0b\n\x03now\x18\x02 \x01(\x04\x12\x10\n\x08\x66unction\x18\x03 \x01(\x04\x12\x0f\n\x07\x62\x61seclk\x18\x04 \x01(\x04\"+\n\x1aTimerExpireExitFtraceEvent\x12\r\n\x05timer\x18\x01 \x01(\x04\"F\n\x14TrustySmcFtraceEvent\x12\n\n\x02r0\x18\x01 \x01(\x04\x12\n\n\x02r1\x18\x02 \x01(\x04\x12\n\n\x02r2\x18\x03 \x01(\x04\x12\n\n\x02r3\x18\x04 \x01(\x04\"\'\n\x18TrustySmcDoneFtraceEvent\x12\x0b\n\x03ret\x18\x01 \x01(\x04\"L\n\x1aTrustyStdCall32FtraceEvent\x12\n\n\x02r0\x18\x01 \x01(\x04\x12\n\n\x02r1\x18\x02 \x01(\x04\x12\n\n\x02r2\x18\x03 \x01(\x04\x12\n\n\x02r3\x18\x04 \x01(\x04\"-\n\x1eTrustyStdCall32DoneFtraceEvent\x12\x0b\n\x03ret\x18\x01 \x01(\x03\"H\n\x1cTrustyShareMemoryFtraceEvent\x12\x0b\n\x03len\x18\x01 \x01(\x04\x12\x0c\n\x04lend\x18\x02 \x01(\r\x12\r\n\x05nents\x18\x03 \x01(\r\"i\n TrustyShareMemoryDoneFtraceEvent\x12\x0e\n\x06handle\x18\x01 \x01(\x04\x12\x0b\n\x03len\x18\x02 \x01(\x04\x12\x0c\n\x04lend\x18\x03 \x01(\r\x12\r\n\x05nents\x18\x04 \x01(\r\x12\x0b\n\x03ret\x18\x05 \x01(\x05\",\n\x1eTrustyReclaimMemoryFtraceEvent\x12\n\n\x02id\x18\x01 \x01(\x04\"=\n\"TrustyReclaimMemoryDoneFtraceEvent\x12\n\n\x02id\x18\x01 \x01(\x04\x12\x0b\n\x03ret\x18\x02 \x01(\x05\"#\n\x14TrustyIrqFtraceEvent\x12\x0b\n\x03irq\x18\x01 \x01(\x05\"S\n\x1fTrustyIpcHandleEventFtraceEvent\x12\x0c\n\x04\x63han\x18\x01 \x01(\r\x12\x10\n\x08\x65vent_id\x18\x02 \x01(\r\x12\x10\n\x08srv_name\x18\x03 \x01(\t\"H\n\x1bTrustyIpcConnectFtraceEvent\x12\x0c\n\x04\x63han\x18\x01 \x01(\r\x12\x0c\n\x04port\x18\x02 \x01(\t\x12\r\n\x05state\x18\x03 \x01(\x05\"J\n\x1eTrustyIpcConnectEndFtraceEvent\x12\x0c\n\x04\x63han\x18\x01 \x01(\r\x12\x0b\n\x03\x65rr\x18\x02 \x01(\x05\x12\r\n\x05state\x18\x03 \x01(\x05\"\x82\x01\n\x19TrustyIpcWriteFtraceEvent\x12\x0e\n\x06\x62uf_id\x18\x01 \x01(\x04\x12\x0c\n\x04\x63han\x18\x02 \x01(\r\x12\x10\n\x08kind_shm\x18\x03 \x01(\x05\x12\x12\n\nlen_or_err\x18\x04 \x01(\x05\x12\x0f\n\x07shm_cnt\x18\x05 \x01(\x04\x12\x10\n\x08srv_name\x18\x06 \x01(\t\"M\n\x18TrustyIpcPollFtraceEvent\x12\x0c\n\x04\x63han\x18\x01 \x01(\r\x12\x11\n\tpoll_mask\x18\x02 \x01(\r\x12\x10\n\x08srv_name\x18\x03 \x01(\t\":\n\x18TrustyIpcReadFtraceEvent\x12\x0c\n\x04\x63han\x18\x01 \x01(\r\x12\x10\n\x08srv_name\x18\x02 \x01(\t\"r\n\x1bTrustyIpcReadEndFtraceEvent\x12\x0e\n\x06\x62uf_id\x18\x01 \x01(\x04\x12\x0c\n\x04\x63han\x18\x02 \x01(\r\x12\x12\n\nlen_or_err\x18\x03 \x01(\x05\x12\x0f\n\x07shm_cnt\x18\x04 \x01(\x04\x12\x10\n\x08srv_name\x18\x05 \x01(\t\"H\n\x16TrustyIpcRxFtraceEvent\x12\x0e\n\x06\x62uf_id\x18\x01 \x01(\x04\x12\x0c\n\x04\x63han\x18\x02 \x01(\r\x12\x10\n\x08srv_name\x18\x03 \x01(\t\"G\n\x1bTrustyEnqueueNopFtraceEvent\x12\x0c\n\x04\x61rg1\x18\x01 \x01(\r\x12\x0c\n\x04\x61rg2\x18\x02 \x01(\r\x12\x0c\n\x04\x61rg3\x18\x03 \x01(\r\"\xba\x01\n\x18UfshcdCommandFtraceEvent\x12\x10\n\x08\x64\x65v_name\x18\x01 \x01(\t\x12\x10\n\x08\x64oorbell\x18\x02 \x01(\r\x12\x0c\n\x04intr\x18\x03 \x01(\r\x12\x0b\n\x03lba\x18\x04 \x01(\x04\x12\x0e\n\x06opcode\x18\x05 \x01(\r\x12\x0b\n\x03str\x18\x06 \x01(\t\x12\x0b\n\x03tag\x18\x07 \x01(\r\x12\x14\n\x0ctransfer_len\x18\x08 \x01(\x05\x12\x10\n\x08group_id\x18\t \x01(\r\x12\r\n\x05str_t\x18\n \x01(\r\"=\n\x1aUfshcdClkGatingFtraceEvent\x12\x10\n\x08\x64\x65v_name\x18\x01 \x01(\t\x12\r\n\x05state\x18\x02 \x01(\x05\"\x9b\x03\n\x13V4l2QbufFtraceEvent\x12\x11\n\tbytesused\x18\x01 \x01(\r\x12\r\n\x05\x66ield\x18\x02 \x01(\r\x12\r\n\x05\x66lags\x18\x03 \x01(\r\x12\r\n\x05index\x18\x04 \x01(\r\x12\r\n\x05minor\x18\x05 \x01(\x05\x12\x10\n\x08sequence\x18\x06 \x01(\r\x12\x16\n\x0etimecode_flags\x18\x07 \x01(\r\x12\x17\n\x0ftimecode_frames\x18\x08 \x01(\r\x12\x16\n\x0etimecode_hours\x18\t \x01(\r\x12\x18\n\x10timecode_minutes\x18\n \x01(\r\x12\x18\n\x10timecode_seconds\x18\x0b \x01(\r\x12\x15\n\rtimecode_type\x18\x0c \x01(\r\x12\x1a\n\x12timecode_userbits0\x18\r \x01(\r\x12\x1a\n\x12timecode_userbits1\x18\x0e \x01(\r\x12\x1a\n\x12timecode_userbits2\x18\x0f \x01(\r\x12\x1a\n\x12timecode_userbits3\x18\x10 \x01(\r\x12\x11\n\ttimestamp\x18\x11 \x01(\x03\x12\x0c\n\x04type\x18\x12 \x01(\r\"\x9c\x03\n\x14V4l2DqbufFtraceEvent\x12\x11\n\tbytesused\x18\x01 \x01(\r\x12\r\n\x05\x66ield\x18\x02 \x01(\r\x12\r\n\x05\x66lags\x18\x03 \x01(\r\x12\r\n\x05index\x18\x04 \x01(\r\x12\r\n\x05minor\x18\x05 \x01(\x05\x12\x10\n\x08sequence\x18\x06 \x01(\r\x12\x16\n\x0etimecode_flags\x18\x07 \x01(\r\x12\x17\n\x0ftimecode_frames\x18\x08 \x01(\r\x12\x16\n\x0etimecode_hours\x18\t \x01(\r\x12\x18\n\x10timecode_minutes\x18\n \x01(\r\x12\x18\n\x10timecode_seconds\x18\x0b \x01(\r\x12\x15\n\rtimecode_type\x18\x0c \x01(\r\x12\x1a\n\x12timecode_userbits0\x18\r \x01(\r\x12\x1a\n\x12timecode_userbits1\x18\x0e \x01(\r\x12\x1a\n\x12timecode_userbits2\x18\x0f \x01(\r\x12\x1a\n\x12timecode_userbits3\x18\x10 \x01(\r\x12\x11\n\ttimestamp\x18\x11 \x01(\x03\x12\x0c\n\x04type\x18\x12 \x01(\r\"\xf2\x02\n\x1aVb2V4l2BufQueueFtraceEvent\x12\r\n\x05\x66ield\x18\x01 \x01(\r\x12\r\n\x05\x66lags\x18\x02 \x01(\r\x12\r\n\x05minor\x18\x03 \x01(\x05\x12\x10\n\x08sequence\x18\x04 \x01(\r\x12\x16\n\x0etimecode_flags\x18\x05 \x01(\r\x12\x17\n\x0ftimecode_frames\x18\x06 \x01(\r\x12\x16\n\x0etimecode_hours\x18\x07 \x01(\r\x12\x18\n\x10timecode_minutes\x18\x08 \x01(\r\x12\x18\n\x10timecode_seconds\x18\t \x01(\r\x12\x15\n\rtimecode_type\x18\n \x01(\r\x12\x1a\n\x12timecode_userbits0\x18\x0b \x01(\r\x12\x1a\n\x12timecode_userbits1\x18\x0c \x01(\r\x12\x1a\n\x12timecode_userbits2\x18\r \x01(\r\x12\x1a\n\x12timecode_userbits3\x18\x0e \x01(\r\x12\x11\n\ttimestamp\x18\x0f \x01(\x03\"\xf1\x02\n\x19Vb2V4l2BufDoneFtraceEvent\x12\r\n\x05\x66ield\x18\x01 \x01(\r\x12\r\n\x05\x66lags\x18\x02 \x01(\r\x12\r\n\x05minor\x18\x03 \x01(\x05\x12\x10\n\x08sequence\x18\x04 \x01(\r\x12\x16\n\x0etimecode_flags\x18\x05 \x01(\r\x12\x17\n\x0ftimecode_frames\x18\x06 \x01(\r\x12\x16\n\x0etimecode_hours\x18\x07 \x01(\r\x12\x18\n\x10timecode_minutes\x18\x08 \x01(\r\x12\x18\n\x10timecode_seconds\x18\t \x01(\r\x12\x15\n\rtimecode_type\x18\n \x01(\r\x12\x1a\n\x12timecode_userbits0\x18\x0b \x01(\r\x12\x1a\n\x12timecode_userbits1\x18\x0c \x01(\r\x12\x1a\n\x12timecode_userbits2\x18\r \x01(\r\x12\x1a\n\x12timecode_userbits3\x18\x0e \x01(\r\x12\x11\n\ttimestamp\x18\x0f \x01(\x03\"\xee\x02\n\x16Vb2V4l2QbufFtraceEvent\x12\r\n\x05\x66ield\x18\x01 \x01(\r\x12\r\n\x05\x66lags\x18\x02 \x01(\r\x12\r\n\x05minor\x18\x03 \x01(\x05\x12\x10\n\x08sequence\x18\x04 \x01(\r\x12\x16\n\x0etimecode_flags\x18\x05 \x01(\r\x12\x17\n\x0ftimecode_frames\x18\x06 \x01(\r\x12\x16\n\x0etimecode_hours\x18\x07 \x01(\r\x12\x18\n\x10timecode_minutes\x18\x08 \x01(\r\x12\x18\n\x10timecode_seconds\x18\t \x01(\r\x12\x15\n\rtimecode_type\x18\n \x01(\r\x12\x1a\n\x12timecode_userbits0\x18\x0b \x01(\r\x12\x1a\n\x12timecode_userbits1\x18\x0c \x01(\r\x12\x1a\n\x12timecode_userbits2\x18\r \x01(\r\x12\x1a\n\x12timecode_userbits3\x18\x0e \x01(\r\x12\x11\n\ttimestamp\x18\x0f \x01(\x03\"\xef\x02\n\x17Vb2V4l2DqbufFtraceEvent\x12\r\n\x05\x66ield\x18\x01 \x01(\r\x12\r\n\x05\x66lags\x18\x02 \x01(\r\x12\r\n\x05minor\x18\x03 \x01(\x05\x12\x10\n\x08sequence\x18\x04 \x01(\r\x12\x16\n\x0etimecode_flags\x18\x05 \x01(\r\x12\x17\n\x0ftimecode_frames\x18\x06 \x01(\r\x12\x16\n\x0etimecode_hours\x18\x07 \x01(\r\x12\x18\n\x10timecode_minutes\x18\x08 \x01(\r\x12\x18\n\x10timecode_seconds\x18\t \x01(\r\x12\x15\n\rtimecode_type\x18\n \x01(\r\x12\x1a\n\x12timecode_userbits0\x18\x0b \x01(\r\x12\x1a\n\x12timecode_userbits1\x18\x0c \x01(\r\x12\x1a\n\x12timecode_userbits2\x18\r \x01(\r\x12\x1a\n\x12timecode_userbits3\x18\x0e \x01(\r\x12\x11\n\ttimestamp\x18\x0f \x01(\x03\"\xa5\x01\n\x1cVirtioGpuCmdQueueFtraceEvent\x12\x0e\n\x06\x63tx_id\x18\x01 \x01(\r\x12\x0b\n\x03\x64\x65v\x18\x02 \x01(\x05\x12\x10\n\x08\x66\x65nce_id\x18\x03 \x01(\x04\x12\r\n\x05\x66lags\x18\x04 \x01(\r\x12\x0c\n\x04name\x18\x05 \x01(\t\x12\x10\n\x08num_free\x18\x06 \x01(\r\x12\r\n\x05seqno\x18\x07 \x01(\r\x12\x0c\n\x04type\x18\x08 \x01(\r\x12\n\n\x02vq\x18\t \x01(\r\"\xa8\x01\n\x1fVirtioGpuCmdResponseFtraceEvent\x12\x0e\n\x06\x63tx_id\x18\x01 \x01(\r\x12\x0b\n\x03\x64\x65v\x18\x02 \x01(\x05\x12\x10\n\x08\x66\x65nce_id\x18\x03 \x01(\x04\x12\r\n\x05\x66lags\x18\x04 \x01(\r\x12\x0c\n\x04name\x18\x05 \x01(\t\x12\x10\n\x08num_free\x18\x06 \x01(\r\x12\r\n\x05seqno\x18\x07 \x01(\r\x12\x0c\n\x04type\x18\x08 \x01(\r\x12\n\n\x02vq\x18\t \x01(\r\"<\n\x19VirtioVideoCmdFtraceEvent\x12\x11\n\tstream_id\x18\x01 \x01(\r\x12\x0c\n\x04type\x18\x02 \x01(\r\"@\n\x1dVirtioVideoCmdDoneFtraceEvent\x12\x11\n\tstream_id\x18\x01 \x01(\r\x12\x0c\n\x04type\x18\x02 \x01(\r\"\xc4\x01\n#VirtioVideoResourceQueueFtraceEvent\x12\x12\n\ndata_size0\x18\x01 \x01(\r\x12\x12\n\ndata_size1\x18\x02 \x01(\r\x12\x12\n\ndata_size2\x18\x03 \x01(\r\x12\x12\n\ndata_size3\x18\x04 \x01(\r\x12\x12\n\nqueue_type\x18\x05 \x01(\r\x12\x13\n\x0bresource_id\x18\x06 \x01(\x05\x12\x11\n\tstream_id\x18\x07 \x01(\x05\x12\x11\n\ttimestamp\x18\x08 \x01(\x04\"\xc8\x01\n\'VirtioVideoResourceQueueDoneFtraceEvent\x12\x12\n\ndata_size0\x18\x01 \x01(\r\x12\x12\n\ndata_size1\x18\x02 \x01(\r\x12\x12\n\ndata_size2\x18\x03 \x01(\r\x12\x12\n\ndata_size3\x18\x04 \x01(\r\x12\x12\n\nqueue_type\x18\x05 \x01(\r\x12\x13\n\x0bresource_id\x18\x06 \x01(\x05\x12\x11\n\tstream_id\x18\x07 \x01(\x05\x12\x11\n\ttimestamp\x18\x08 \x01(\x04\"`\n%MmVmscanDirectReclaimBeginFtraceEvent\x12\r\n\x05order\x18\x01 \x01(\x05\x12\x15\n\rmay_writepage\x18\x02 \x01(\x05\x12\x11\n\tgfp_flags\x18\x03 \x01(\r\";\n#MmVmscanDirectReclaimEndFtraceEvent\x12\x14\n\x0cnr_reclaimed\x18\x01 \x01(\x04\"H\n\x1dMmVmscanKswapdWakeFtraceEvent\x12\x0b\n\x03nid\x18\x01 \x01(\x05\x12\r\n\x05order\x18\x02 \x01(\x05\x12\x0b\n\x03zid\x18\x03 \x01(\x05\"-\n\x1eMmVmscanKswapdSleepFtraceEvent\x12\x0b\n\x03nid\x18\x01 \x01(\x05\"\xe9\x01\n\x1cMmShrinkSlabStartFtraceEvent\x12\x13\n\x0b\x63\x61\x63he_items\x18\x01 \x01(\x04\x12\r\n\x05\x64\x65lta\x18\x02 \x01(\x04\x12\x11\n\tgfp_flags\x18\x03 \x01(\r\x12\x0f\n\x07lru_pgs\x18\x04 \x01(\x04\x12\x1c\n\x14nr_objects_to_shrink\x18\x05 \x01(\x03\x12\x13\n\x0bpgs_scanned\x18\x06 \x01(\x04\x12\x0b\n\x03shr\x18\x07 \x01(\x04\x12\x0e\n\x06shrink\x18\x08 \x01(\x04\x12\x12\n\ntotal_scan\x18\t \x01(\x04\x12\x0b\n\x03nid\x18\n \x01(\x05\x12\x10\n\x08priority\x18\x0b \x01(\x05\"\x91\x01\n\x1aMmShrinkSlabEndFtraceEvent\x12\x10\n\x08new_scan\x18\x01 \x01(\x03\x12\x0e\n\x06retval\x18\x02 \x01(\x05\x12\x0b\n\x03shr\x18\x03 \x01(\x04\x12\x0e\n\x06shrink\x18\x04 \x01(\x04\x12\x12\n\ntotal_scan\x18\x05 \x01(\x03\x12\x13\n\x0bunused_scan\x18\x06 \x01(\x03\x12\x0b\n\x03nid\x18\x07 \x01(\x05\"_\n$MmVmscanMemcgReclaimBeginFtraceEvent\x12\r\n\x05order\x18\x01 \x01(\x05\x12\x15\n\rmay_writepage\x18\x02 \x01(\x05\x12\x11\n\tgfp_flags\x18\x03 \x01(\x04\":\n\"MmVmscanMemcgReclaimEndFtraceEvent\x12\x14\n\x0cnr_reclaimed\x18\x01 \x01(\x04\"B\n WorkqueueActivateWorkFtraceEvent\x12\x0c\n\x04work\x18\x01 \x01(\x04\x12\x10\n\x08\x66unction\x18\x02 \x01(\x04\"@\n\x1eWorkqueueExecuteEndFtraceEvent\x12\x0c\n\x04work\x18\x01 \x01(\x04\x12\x10\n\x08\x66unction\x18\x02 \x01(\x04\"B\n WorkqueueExecuteStartFtraceEvent\x12\x0c\n\x04work\x18\x01 \x01(\x04\x12\x10\n\x08\x66unction\x18\x02 \x01(\x04\"p\n\x1dWorkqueueQueueWorkFtraceEvent\x12\x0c\n\x04work\x18\x01 \x01(\x04\x12\x10\n\x08\x66unction\x18\x02 \x01(\x04\x12\x0f\n\x07req_cpu\x18\x04 \x01(\x05\x12\x0b\n\x03\x63pu\x18\x05 \x01(\x05\x12\x11\n\tworkqueue\x18\x06 \x01(\t\"\xff\xec\x02\n\x0b\x46traceEvent\x12\x11\n\ttimestamp\x18\x01 \x01(\x04\x12\x0b\n\x03pid\x18\x02 \x01(\r\x12\x14\n\x0c\x63ommon_flags\x18\x05 \x01(\r\x12\x32\n\x05print\x18\x03 \x01(\x0b\x32!.perfetto.protos.PrintFtraceEventH\x00\x12?\n\x0csched_switch\x18\x04 \x01(\x0b\x32\'.perfetto.protos.SchedSwitchFtraceEventH\x00\x12\x41\n\rcpu_frequency\x18\x0b \x01(\x0b\x32(.perfetto.protos.CpuFrequencyFtraceEventH\x00\x12N\n\x14\x63pu_frequency_limits\x18\x0c \x01(\x0b\x32..perfetto.protos.CpuFrequencyLimitsFtraceEventH\x00\x12\x37\n\x08\x63pu_idle\x18\r \x01(\x0b\x32#.perfetto.protos.CpuIdleFtraceEventH\x00\x12?\n\x0c\x63lock_enable\x18\x0e \x01(\x0b\x32\'.perfetto.protos.ClockEnableFtraceEventH\x00\x12\x41\n\rclock_disable\x18\x0f \x01(\x0b\x32(.perfetto.protos.ClockDisableFtraceEventH\x00\x12\x42\n\x0e\x63lock_set_rate\x18\x10 \x01(\x0b\x32(.perfetto.protos.ClockSetRateFtraceEventH\x00\x12?\n\x0csched_wakeup\x18\x11 \x01(\x0b\x32\'.perfetto.protos.SchedWakeupFtraceEventH\x00\x12N\n\x14sched_blocked_reason\x18\x12 \x01(\x0b\x32..perfetto.protos.SchedBlockedReasonFtraceEventH\x00\x12H\n\x11sched_cpu_hotplug\x18\x13 \x01(\x0b\x32+.perfetto.protos.SchedCpuHotplugFtraceEventH\x00\x12?\n\x0csched_waking\x18\x14 \x01(\x0b\x32\'.perfetto.protos.SchedWakingFtraceEventH\x00\x12\x39\n\tipi_entry\x18\x15 \x01(\x0b\x32$.perfetto.protos.IpiEntryFtraceEventH\x00\x12\x37\n\x08ipi_exit\x18\x16 \x01(\x0b\x32#.perfetto.protos.IpiExitFtraceEventH\x00\x12\x39\n\tipi_raise\x18\x17 \x01(\x0b\x32$.perfetto.protos.IpiRaiseFtraceEventH\x00\x12\x41\n\rsoftirq_entry\x18\x18 \x01(\x0b\x32(.perfetto.protos.SoftirqEntryFtraceEventH\x00\x12?\n\x0csoftirq_exit\x18\x19 \x01(\x0b\x32\'.perfetto.protos.SoftirqExitFtraceEventH\x00\x12\x41\n\rsoftirq_raise\x18\x1a \x01(\x0b\x32(.perfetto.protos.SoftirqRaiseFtraceEventH\x00\x12\x37\n\x08i2c_read\x18\x1b \x01(\x0b\x32#.perfetto.protos.I2cReadFtraceEventH\x00\x12\x39\n\ti2c_write\x18\x1c \x01(\x0b\x32$.perfetto.protos.I2cWriteFtraceEventH\x00\x12;\n\ni2c_result\x18\x1d \x01(\x0b\x32%.perfetto.protos.I2cResultFtraceEventH\x00\x12\x39\n\ti2c_reply\x18\x1e \x01(\x0b\x32$.perfetto.protos.I2cReplyFtraceEventH\x00\x12;\n\nsmbus_read\x18\x1f \x01(\x0b\x32%.perfetto.protos.SmbusReadFtraceEventH\x00\x12=\n\x0bsmbus_write\x18  \x01(\x0b\x32&.perfetto.protos.SmbusWriteFtraceEventH\x00\x12?\n\x0csmbus_result\x18! \x01(\x0b\x32\'.perfetto.protos.SmbusResultFtraceEventH\x00\x12=\n\x0bsmbus_reply\x18\" \x01(\x0b\x32&.perfetto.protos.SmbusReplyFtraceEventH\x00\x12\x43\n\x0elowmemory_kill\x18# \x01(\x0b\x32).perfetto.protos.LowmemoryKillFtraceEventH\x00\x12H\n\x11irq_handler_entry\x18$ \x01(\x0b\x32+.perfetto.protos.IrqHandlerEntryFtraceEventH\x00\x12\x46\n\x10irq_handler_exit\x18% \x01(\x0b\x32*.perfetto.protos.IrqHandlerExitFtraceEventH\x00\x12\x35\n\x07sync_pt\x18& \x01(\x0b\x32\".perfetto.protos.SyncPtFtraceEventH\x00\x12\x41\n\rsync_timeline\x18\' \x01(\x0b\x32(.perfetto.protos.SyncTimelineFtraceEventH\x00\x12\x39\n\tsync_wait\x18( \x01(\x0b\x32$.perfetto.protos.SyncWaitFtraceEventH\x00\x12K\n\x13\x65xt4_da_write_begin\x18) \x01(\x0b\x32,.perfetto.protos.Ext4DaWriteBeginFtraceEventH\x00\x12G\n\x11\x65xt4_da_write_end\x18* \x01(\x0b\x32*.perfetto.protos.Ext4DaWriteEndFtraceEventH\x00\x12M\n\x14\x65xt4_sync_file_enter\x18+ \x01(\x0b\x32-.perfetto.protos.Ext4SyncFileEnterFtraceEventH\x00\x12K\n\x13\x65xt4_sync_file_exit\x18, \x01(\x0b\x32,.perfetto.protos.Ext4SyncFileExitFtraceEventH\x00\x12\x42\n\x0e\x62lock_rq_issue\x18- \x01(\x0b\x32(.perfetto.protos.BlockRqIssueFtraceEventH\x00\x12`\n\x1emm_vmscan_direct_reclaim_begin\x18. \x01(\x0b\x32\x36.perfetto.protos.MmVmscanDirectReclaimBeginFtraceEventH\x00\x12\\\n\x1cmm_vmscan_direct_reclaim_end\x18/ \x01(\x0b\x32\x34.perfetto.protos.MmVmscanDirectReclaimEndFtraceEventH\x00\x12O\n\x15mm_vmscan_kswapd_wake\x18\x30 \x01(\x0b\x32..perfetto.protos.MmVmscanKswapdWakeFtraceEventH\x00\x12Q\n\x16mm_vmscan_kswapd_sleep\x18\x31 \x01(\x0b\x32/.perfetto.protos.MmVmscanKswapdSleepFtraceEventH\x00\x12K\n\x12\x62inder_transaction\x18\x32 \x01(\x0b\x32-.perfetto.protos.BinderTransactionFtraceEventH\x00\x12\\\n\x1b\x62inder_transaction_received\x18\x33 \x01(\x0b\x32\x35.perfetto.protos.BinderTransactionReceivedFtraceEventH\x00\x12L\n\x13\x62inder_set_priority\x18\x34 \x01(\x0b\x32-.perfetto.protos.BinderSetPriorityFtraceEventH\x00\x12=\n\x0b\x62inder_lock\x18\x35 \x01(\x0b\x32&.perfetto.protos.BinderLockFtraceEventH\x00\x12\x41\n\rbinder_locked\x18\x36 \x01(\x0b\x32(.perfetto.protos.BinderLockedFtraceEventH\x00\x12\x41\n\rbinder_unlock\x18\x37 \x01(\x0b\x32(.perfetto.protos.BinderUnlockFtraceEventH\x00\x12T\n\x17workqueue_activate_work\x18\x38 \x01(\x0b\x32\x31.perfetto.protos.WorkqueueActivateWorkFtraceEventH\x00\x12P\n\x15workqueue_execute_end\x18\x39 \x01(\x0b\x32/.perfetto.protos.WorkqueueExecuteEndFtraceEventH\x00\x12T\n\x17workqueue_execute_start\x18: \x01(\x0b\x32\x31.perfetto.protos.WorkqueueExecuteStartFtraceEventH\x00\x12N\n\x14workqueue_queue_work\x18; \x01(\x0b\x32..perfetto.protos.WorkqueueQueueWorkFtraceEventH\x00\x12I\n\x11regulator_disable\x18< \x01(\x0b\x32,.perfetto.protos.RegulatorDisableFtraceEventH\x00\x12Z\n\x1aregulator_disable_complete\x18= \x01(\x0b\x32\x34.perfetto.protos.RegulatorDisableCompleteFtraceEventH\x00\x12G\n\x10regulator_enable\x18> \x01(\x0b\x32+.perfetto.protos.RegulatorEnableFtraceEventH\x00\x12X\n\x19regulator_enable_complete\x18? \x01(\x0b\x32\x33.perfetto.protos.RegulatorEnableCompleteFtraceEventH\x00\x12R\n\x16regulator_enable_delay\x18@ \x01(\x0b\x32\x30.perfetto.protos.RegulatorEnableDelayFtraceEventH\x00\x12P\n\x15regulator_set_voltage\x18\x41 \x01(\x0b\x32/.perfetto.protos.RegulatorSetVoltageFtraceEventH\x00\x12\x61\n\x1eregulator_set_voltage_complete\x18\x42 \x01(\x0b\x32\x37.perfetto.protos.RegulatorSetVoltageCompleteFtraceEventH\x00\x12J\n\x12\x63group_attach_task\x18\x43 \x01(\x0b\x32,.perfetto.protos.CgroupAttachTaskFtraceEventH\x00\x12?\n\x0c\x63group_mkdir\x18\x44 \x01(\x0b\x32\'.perfetto.protos.CgroupMkdirFtraceEventH\x00\x12\x43\n\x0e\x63group_remount\x18\x45 \x01(\x0b\x32).perfetto.protos.CgroupRemountFtraceEventH\x00\x12?\n\x0c\x63group_rmdir\x18\x46 \x01(\x0b\x32\'.perfetto.protos.CgroupRmdirFtraceEventH\x00\x12P\n\x15\x63group_transfer_tasks\x18G \x01(\x0b\x32/.perfetto.protos.CgroupTransferTasksFtraceEventH\x00\x12L\n\x13\x63group_destroy_root\x18H \x01(\x0b\x32-.perfetto.protos.CgroupDestroyRootFtraceEventH\x00\x12\x43\n\x0e\x63group_release\x18I \x01(\x0b\x32).perfetto.protos.CgroupReleaseFtraceEventH\x00\x12\x41\n\rcgroup_rename\x18J \x01(\x0b\x32(.perfetto.protos.CgroupRenameFtraceEventH\x00\x12H\n\x11\x63group_setup_root\x18K \x01(\x0b\x32+.perfetto.protos.CgroupSetupRootFtraceEventH\x00\x12\x44\n\x0fmdp_cmd_kickoff\x18L \x01(\x0b\x32).perfetto.protos.MdpCmdKickoffFtraceEventH\x00\x12;\n\nmdp_commit\x18M \x01(\x0b\x32%.perfetto.protos.MdpCommitFtraceEventH\x00\x12\x43\n\x0fmdp_perf_set_ot\x18N \x01(\x0b\x32(.perfetto.protos.MdpPerfSetOtFtraceEventH\x00\x12\x44\n\x0fmdp_sspp_change\x18O \x01(\x0b\x32).perfetto.protos.MdpSsppChangeFtraceEventH\x00\x12J\n\x12tracing_mark_write\x18P \x01(\x0b\x32,.perfetto.protos.TracingMarkWriteFtraceEventH\x00\x12O\n\x15mdp_cmd_pingpong_done\x18Q \x01(\x0b\x32..perfetto.protos.MdpCmdPingpongDoneFtraceEventH\x00\x12\x42\n\x0emdp_compare_bw\x18R \x01(\x0b\x32(.perfetto.protos.MdpCompareBwFtraceEventH\x00\x12R\n\x17mdp_perf_set_panic_luts\x18S \x01(\x0b\x32/.perfetto.protos.MdpPerfSetPanicLutsFtraceEventH\x00\x12>\n\x0cmdp_sspp_set\x18T \x01(\x0b\x32&.perfetto.protos.MdpSsppSetFtraceEventH\x00\x12M\n\x14mdp_cmd_readptr_done\x18U \x01(\x0b\x32-.perfetto.protos.MdpCmdReadptrDoneFtraceEventH\x00\x12>\n\x0cmdp_misr_crc\x18V \x01(\x0b\x32&.perfetto.protos.MdpMisrCrcFtraceEventH\x00\x12N\n\x15mdp_perf_set_qos_luts\x18W \x01(\x0b\x32-.perfetto.protos.MdpPerfSetQosLutsFtraceEventH\x00\x12H\n\x11mdp_trace_counter\x18X \x01(\x0b\x32+.perfetto.protos.MdpTraceCounterFtraceEventH\x00\x12I\n\x12mdp_cmd_release_bw\x18Y \x01(\x0b\x32+.perfetto.protos.MdpCmdReleaseBwFtraceEventH\x00\x12\x46\n\x10mdp_mixer_update\x18Z \x01(\x0b\x32*.perfetto.protos.MdpMixerUpdateFtraceEventH\x00\x12P\n\x16mdp_perf_set_wm_levels\x18[ \x01(\x0b\x32..perfetto.protos.MdpPerfSetWmLevelsFtraceEventH\x00\x12S\n\x17mdp_video_underrun_done\x18\\ \x01(\x0b\x32\x30.perfetto.protos.MdpVideoUnderrunDoneFtraceEventH\x00\x12O\n\x15mdp_cmd_wait_pingpong\x18] \x01(\x0b\x32..perfetto.protos.MdpCmdWaitPingpongFtraceEventH\x00\x12O\n\x15mdp_perf_prefill_calc\x18^ \x01(\x0b\x32..perfetto.protos.MdpPerfPrefillCalcFtraceEventH\x00\x12K\n\x13mdp_perf_update_bus\x18_ \x01(\x0b\x32,.perfetto.protos.MdpPerfUpdateBusFtraceEventH\x00\x12T\n\x18rotator_bw_ao_as_context\x18` \x01(\x0b\x32\x30.perfetto.protos.RotatorBwAoAsContextFtraceEventH\x00\x12[\n\x1cmm_filemap_add_to_page_cache\x18\x61 \x01(\x0b\x32\x33.perfetto.protos.MmFilemapAddToPageCacheFtraceEventH\x00\x12\x65\n!mm_filemap_delete_from_page_cache\x18\x62 \x01(\x0b\x32\x38.perfetto.protos.MmFilemapDeleteFromPageCacheFtraceEventH\x00\x12L\n\x13mm_compaction_begin\x18\x63 \x01(\x0b\x32-.perfetto.protos.MmCompactionBeginFtraceEventH\x00\x12\x61\n\x1emm_compaction_defer_compaction\x18\x64 \x01(\x0b\x32\x37.perfetto.protos.MmCompactionDeferCompactionFtraceEventH\x00\x12R\n\x16mm_compaction_deferred\x18\x65 \x01(\x0b\x32\x30.perfetto.protos.MmCompactionDeferredFtraceEventH\x00\x12W\n\x19mm_compaction_defer_reset\x18\x66 \x01(\x0b\x32\x32.perfetto.protos.MmCompactionDeferResetFtraceEventH\x00\x12H\n\x11mm_compaction_end\x18g \x01(\x0b\x32+.perfetto.protos.MmCompactionEndFtraceEventH\x00\x12R\n\x16mm_compaction_finished\x18h \x01(\x0b\x32\x30.perfetto.protos.MmCompactionFinishedFtraceEventH\x00\x12\x63\n\x1fmm_compaction_isolate_freepages\x18i \x01(\x0b\x32\x38.perfetto.protos.MmCompactionIsolateFreepagesFtraceEventH\x00\x12i\n\"mm_compaction_isolate_migratepages\x18j \x01(\x0b\x32;.perfetto.protos.MmCompactionIsolateMigratepagesFtraceEventH\x00\x12_\n\x1dmm_compaction_kcompactd_sleep\x18k \x01(\x0b\x32\x36.perfetto.protos.MmCompactionKcompactdSleepFtraceEventH\x00\x12]\n\x1cmm_compaction_kcompactd_wake\x18l \x01(\x0b\x32\x35.perfetto.protos.MmCompactionKcompactdWakeFtraceEventH\x00\x12Z\n\x1amm_compaction_migratepages\x18m \x01(\x0b\x32\x34.perfetto.protos.MmCompactionMigratepagesFtraceEventH\x00\x12R\n\x16mm_compaction_suitable\x18n \x01(\x0b\x32\x30.perfetto.protos.MmCompactionSuitableFtraceEventH\x00\x12g\n\"mm_compaction_try_to_compact_pages\x18o \x01(\x0b\x32\x39.perfetto.protos.MmCompactionTryToCompactPagesFtraceEventH\x00\x12\x61\n\x1emm_compaction_wakeup_kcompactd\x18p \x01(\x0b\x32\x37.perfetto.protos.MmCompactionWakeupKcompactdFtraceEventH\x00\x12\x43\n\x0esuspend_resume\x18q \x01(\x0b\x32).perfetto.protos.SuspendResumeFtraceEventH\x00\x12\x46\n\x10sched_wakeup_new\x18r \x01(\x0b\x32*.perfetto.protos.SchedWakeupNewFtraceEventH\x00\x12L\n\x13\x62lock_bio_backmerge\x18s \x01(\x0b\x32-.perfetto.protos.BlockBioBackmergeFtraceEventH\x00\x12\x46\n\x10\x62lock_bio_bounce\x18t \x01(\x0b\x32*.perfetto.protos.BlockBioBounceFtraceEventH\x00\x12J\n\x12\x62lock_bio_complete\x18u \x01(\x0b\x32,.perfetto.protos.BlockBioCompleteFtraceEventH\x00\x12N\n\x14\x62lock_bio_frontmerge\x18v \x01(\x0b\x32..perfetto.protos.BlockBioFrontmergeFtraceEventH\x00\x12\x44\n\x0f\x62lock_bio_queue\x18w \x01(\x0b\x32).perfetto.protos.BlockBioQueueFtraceEventH\x00\x12\x44\n\x0f\x62lock_bio_remap\x18x \x01(\x0b\x32).perfetto.protos.BlockBioRemapFtraceEventH\x00\x12J\n\x12\x62lock_dirty_buffer\x18y \x01(\x0b\x32,.perfetto.protos.BlockDirtyBufferFtraceEventH\x00\x12=\n\x0b\x62lock_getrq\x18z \x01(\x0b\x32&.perfetto.protos.BlockGetrqFtraceEventH\x00\x12;\n\nblock_plug\x18{ \x01(\x0b\x32%.perfetto.protos.BlockPlugFtraceEventH\x00\x12\x42\n\x0e\x62lock_rq_abort\x18| \x01(\x0b\x32(.perfetto.protos.BlockRqAbortFtraceEventH\x00\x12H\n\x11\x62lock_rq_complete\x18} \x01(\x0b\x32+.perfetto.protos.BlockRqCompleteFtraceEventH\x00\x12\x44\n\x0f\x62lock_rq_insert\x18~ \x01(\x0b\x32).perfetto.protos.BlockRqInsertFtraceEventH\x00\x12\x43\n\x0e\x62lock_rq_remap\x18\x80\x01 \x01(\x0b\x32(.perfetto.protos.BlockRqRemapFtraceEventH\x00\x12G\n\x10\x62lock_rq_requeue\x18\x81\x01 \x01(\x0b\x32*.perfetto.protos.BlockRqRequeueFtraceEventH\x00\x12\x42\n\rblock_sleeprq\x18\x82\x01 \x01(\x0b\x32(.perfetto.protos.BlockSleeprqFtraceEventH\x00\x12>\n\x0b\x62lock_split\x18\x83\x01 \x01(\x0b\x32&.perfetto.protos.BlockSplitFtraceEventH\x00\x12K\n\x12\x62lock_touch_buffer\x18\x84\x01 \x01(\x0b\x32,.perfetto.protos.BlockTouchBufferFtraceEventH\x00\x12@\n\x0c\x62lock_unplug\x18\x85\x01 \x01(\x0b\x32\'.perfetto.protos.BlockUnplugFtraceEventH\x00\x12N\n\x14\x65xt4_alloc_da_blocks\x18\x86\x01 \x01(\x0b\x32-.perfetto.protos.Ext4AllocDaBlocksFtraceEventH\x00\x12O\n\x14\x65xt4_allocate_blocks\x18\x87\x01 \x01(\x0b\x32..perfetto.protos.Ext4AllocateBlocksFtraceEventH\x00\x12M\n\x13\x65xt4_allocate_inode\x18\x88\x01 \x01(\x0b\x32-.perfetto.protos.Ext4AllocateInodeFtraceEventH\x00\x12\\\n\x1b\x65xt4_begin_ordered_truncate\x18\x89\x01 \x01(\x0b\x32\x34.perfetto.protos.Ext4BeginOrderedTruncateFtraceEventH\x00\x12M\n\x13\x65xt4_collapse_range\x18\x8a\x01 \x01(\x0b\x32-.perfetto.protos.Ext4CollapseRangeFtraceEventH\x00\x12P\n\x15\x65xt4_da_release_space\x18\x8b\x01 \x01(\x0b\x32..perfetto.protos.Ext4DaReleaseSpaceFtraceEventH\x00\x12P\n\x15\x65xt4_da_reserve_space\x18\x8c\x01 \x01(\x0b\x32..perfetto.protos.Ext4DaReserveSpaceFtraceEventH\x00\x12]\n\x1c\x65xt4_da_update_reserve_space\x18\x8d\x01 \x01(\x0b\x32\x34.perfetto.protos.Ext4DaUpdateReserveSpaceFtraceEventH\x00\x12L\n\x13\x65xt4_da_write_pages\x18\x8e\x01 \x01(\x0b\x32,.perfetto.protos.Ext4DaWritePagesFtraceEventH\x00\x12Y\n\x1a\x65xt4_da_write_pages_extent\x18\x8f\x01 \x01(\x0b\x32\x32.perfetto.protos.Ext4DaWritePagesExtentFtraceEventH\x00\x12N\n\x14\x65xt4_direct_IO_enter\x18\x90\x01 \x01(\x0b\x32-.perfetto.protos.Ext4DirectIOEnterFtraceEventH\x00\x12L\n\x13\x65xt4_direct_IO_exit\x18\x91\x01 \x01(\x0b\x32,.perfetto.protos.Ext4DirectIOExitFtraceEventH\x00\x12M\n\x13\x65xt4_discard_blocks\x18\x92\x01 \x01(\x0b\x32-.perfetto.protos.Ext4DiscardBlocksFtraceEventH\x00\x12]\n\x1b\x65xt4_discard_preallocations\x18\x93\x01 \x01(\x0b\x32\x35.perfetto.protos.Ext4DiscardPreallocationsFtraceEventH\x00\x12\x45\n\x0f\x65xt4_drop_inode\x18\x94\x01 \x01(\x0b\x32).perfetto.protos.Ext4DropInodeFtraceEventH\x00\x12N\n\x14\x65xt4_es_cache_extent\x18\x95\x01 \x01(\x0b\x32-.perfetto.protos.Ext4EsCacheExtentFtraceEventH\x00\x12q\n\'ext4_es_find_delayed_extent_range_enter\x18\x96\x01 \x01(\x0b\x32=.perfetto.protos.Ext4EsFindDelayedExtentRangeEnterFtraceEventH\x00\x12o\n&ext4_es_find_delayed_extent_range_exit\x18\x97\x01 \x01(\x0b\x32<.perfetto.protos.Ext4EsFindDelayedExtentRangeExitFtraceEventH\x00\x12P\n\x15\x65xt4_es_insert_extent\x18\x98\x01 \x01(\x0b\x32..perfetto.protos.Ext4EsInsertExtentFtraceEventH\x00\x12[\n\x1b\x65xt4_es_lookup_extent_enter\x18\x99\x01 \x01(\x0b\x32\x33.perfetto.protos.Ext4EsLookupExtentEnterFtraceEventH\x00\x12Y\n\x1a\x65xt4_es_lookup_extent_exit\x18\x9a\x01 \x01(\x0b\x32\x32.perfetto.protos.Ext4EsLookupExtentExitFtraceEventH\x00\x12P\n\x15\x65xt4_es_remove_extent\x18\x9b\x01 \x01(\x0b\x32..perfetto.protos.Ext4EsRemoveExtentFtraceEventH\x00\x12\x43\n\x0e\x65xt4_es_shrink\x18\x9c\x01 \x01(\x0b\x32(.perfetto.protos.Ext4EsShrinkFtraceEventH\x00\x12N\n\x14\x65xt4_es_shrink_count\x18\x9d\x01 \x01(\x0b\x32-.perfetto.protos.Ext4EsShrinkCountFtraceEventH\x00\x12W\n\x19\x65xt4_es_shrink_scan_enter\x18\x9e\x01 \x01(\x0b\x32\x31.perfetto.protos.Ext4EsShrinkScanEnterFtraceEventH\x00\x12U\n\x18\x65xt4_es_shrink_scan_exit\x18\x9f\x01 \x01(\x0b\x32\x30.perfetto.protos.Ext4EsShrinkScanExitFtraceEventH\x00\x12G\n\x10\x65xt4_evict_inode\x18\xa0\x01 \x01(\x0b\x32*.perfetto.protos.Ext4EvictInodeFtraceEventH\x00\x12n\n%ext4_ext_convert_to_initialized_enter\x18\xa1\x01 \x01(\x0b\x32<.perfetto.protos.Ext4ExtConvertToInitializedEnterFtraceEventH\x00\x12t\n(ext4_ext_convert_to_initialized_fastpath\x18\xa2\x01 \x01(\x0b\x32?.perfetto.protos.Ext4ExtConvertToInitializedFastpathFtraceEventH\x00\x12g\n!ext4_ext_handle_unwritten_extents\x18\xa3\x01 \x01(\x0b\x32\x39.perfetto.protos.Ext4ExtHandleUnwrittenExtentsFtraceEventH\x00\x12H\n\x11\x65xt4_ext_in_cache\x18\xa4\x01 \x01(\x0b\x32*.perfetto.protos.Ext4ExtInCacheFtraceEventH\x00\x12N\n\x14\x65xt4_ext_load_extent\x18\xa5\x01 \x01(\x0b\x32-.perfetto.protos.Ext4ExtLoadExtentFtraceEventH\x00\x12W\n\x19\x65xt4_ext_map_blocks_enter\x18\xa6\x01 \x01(\x0b\x32\x31.perfetto.protos.Ext4ExtMapBlocksEnterFtraceEventH\x00\x12U\n\x18\x65xt4_ext_map_blocks_exit\x18\xa7\x01 \x01(\x0b\x32\x30.perfetto.protos.Ext4ExtMapBlocksExitFtraceEventH\x00\x12O\n\x15\x65xt4_ext_put_in_cache\x18\xa8\x01 \x01(\x0b\x32-.perfetto.protos.Ext4ExtPutInCacheFtraceEventH\x00\x12P\n\x15\x65xt4_ext_remove_space\x18\xa9\x01 \x01(\x0b\x32..perfetto.protos.Ext4ExtRemoveSpaceFtraceEventH\x00\x12Y\n\x1a\x65xt4_ext_remove_space_done\x18\xaa\x01 \x01(\x0b\x32\x32.perfetto.protos.Ext4ExtRemoveSpaceDoneFtraceEventH\x00\x12\x44\n\x0f\x65xt4_ext_rm_idx\x18\xab\x01 \x01(\x0b\x32(.perfetto.protos.Ext4ExtRmIdxFtraceEventH\x00\x12\x46\n\x10\x65xt4_ext_rm_leaf\x18\xac\x01 \x01(\x0b\x32).perfetto.protos.Ext4ExtRmLeafFtraceEventH\x00\x12N\n\x14\x65xt4_ext_show_extent\x18\xad\x01 \x01(\x0b\x32-.perfetto.protos.Ext4ExtShowExtentFtraceEventH\x00\x12O\n\x14\x65xt4_fallocate_enter\x18\xae\x01 \x01(\x0b\x32..perfetto.protos.Ext4FallocateEnterFtraceEventH\x00\x12M\n\x13\x65xt4_fallocate_exit\x18\xaf\x01 \x01(\x0b\x32-.perfetto.protos.Ext4FallocateExitFtraceEventH\x00\x12V\n\x18\x65xt4_find_delalloc_range\x18\xb0\x01 \x01(\x0b\x32\x31.perfetto.protos.Ext4FindDelallocRangeFtraceEventH\x00\x12>\n\x0b\x65xt4_forget\x18\xb1\x01 \x01(\x0b\x32&.perfetto.protos.Ext4ForgetFtraceEventH\x00\x12G\n\x10\x65xt4_free_blocks\x18\xb2\x01 \x01(\x0b\x32*.perfetto.protos.Ext4FreeBlocksFtraceEventH\x00\x12\x45\n\x0f\x65xt4_free_inode\x18\xb3\x01 \x01(\x0b\x32).perfetto.protos.Ext4FreeInodeFtraceEventH\x00\x12j\n#ext4_get_implied_cluster_alloc_exit\x18\xb4\x01 \x01(\x0b\x32:.perfetto.protos.Ext4GetImpliedClusterAllocExitFtraceEventH\x00\x12\x63\n\x1f\x65xt4_get_reserved_cluster_alloc\x18\xb5\x01 \x01(\x0b\x32\x37.perfetto.protos.Ext4GetReservedClusterAllocFtraceEventH\x00\x12W\n\x19\x65xt4_ind_map_blocks_enter\x18\xb6\x01 \x01(\x0b\x32\x31.perfetto.protos.Ext4IndMapBlocksEnterFtraceEventH\x00\x12U\n\x18\x65xt4_ind_map_blocks_exit\x18\xb7\x01 \x01(\x0b\x32\x30.perfetto.protos.Ext4IndMapBlocksExitFtraceEventH\x00\x12I\n\x11\x65xt4_insert_range\x18\xb8\x01 \x01(\x0b\x32+.perfetto.protos.Ext4InsertRangeFtraceEventH\x00\x12N\n\x13\x65xt4_invalidatepage\x18\xb9\x01 \x01(\x0b\x32..perfetto.protos.Ext4InvalidatepageFtraceEventH\x00\x12K\n\x12\x65xt4_journal_start\x18\xba\x01 \x01(\x0b\x32,.perfetto.protos.Ext4JournalStartFtraceEventH\x00\x12\\\n\x1b\x65xt4_journal_start_reserved\x18\xbb\x01 \x01(\x0b\x32\x34.perfetto.protos.Ext4JournalStartReservedFtraceEventH\x00\x12\x63\n\x1e\x65xt4_journalled_invalidatepage\x18\xbc\x01 \x01(\x0b\x32\x38.perfetto.protos.Ext4JournalledInvalidatepageFtraceEventH\x00\x12X\n\x19\x65xt4_journalled_write_end\x18\xbd\x01 \x01(\x0b\x32\x32.perfetto.protos.Ext4JournalledWriteEndFtraceEventH\x00\x12\x45\n\x0f\x65xt4_load_inode\x18\xbe\x01 \x01(\x0b\x32).perfetto.protos.Ext4LoadInodeFtraceEventH\x00\x12R\n\x16\x65xt4_load_inode_bitmap\x18\xbf\x01 \x01(\x0b\x32/.perfetto.protos.Ext4LoadInodeBitmapFtraceEventH\x00\x12P\n\x15\x65xt4_mark_inode_dirty\x18\xc0\x01 \x01(\x0b\x32..perfetto.protos.Ext4MarkInodeDirtyFtraceEventH\x00\x12L\n\x13\x65xt4_mb_bitmap_load\x18\xc1\x01 \x01(\x0b\x32,.perfetto.protos.Ext4MbBitmapLoadFtraceEventH\x00\x12W\n\x19\x65xt4_mb_buddy_bitmap_load\x18\xc2\x01 \x01(\x0b\x32\x31.perfetto.protos.Ext4MbBuddyBitmapLoadFtraceEventH\x00\x12\x62\n\x1e\x65xt4_mb_discard_preallocations\x18\xc3\x01 \x01(\x0b\x32\x37.perfetto.protos.Ext4MbDiscardPreallocationsFtraceEventH\x00\x12M\n\x14\x65xt4_mb_new_group_pa\x18\xc4\x01 \x01(\x0b\x32,.perfetto.protos.Ext4MbNewGroupPaFtraceEventH\x00\x12M\n\x14\x65xt4_mb_new_inode_pa\x18\xc5\x01 \x01(\x0b\x32,.perfetto.protos.Ext4MbNewInodePaFtraceEventH\x00\x12U\n\x18\x65xt4_mb_release_group_pa\x18\xc6\x01 \x01(\x0b\x32\x30.perfetto.protos.Ext4MbReleaseGroupPaFtraceEventH\x00\x12U\n\x18\x65xt4_mb_release_inode_pa\x18\xc7\x01 \x01(\x0b\x32\x30.perfetto.protos.Ext4MbReleaseInodePaFtraceEventH\x00\x12K\n\x12\x65xt4_mballoc_alloc\x18\xc8\x01 \x01(\x0b\x32,.perfetto.protos.Ext4MballocAllocFtraceEventH\x00\x12O\n\x14\x65xt4_mballoc_discard\x18\xc9\x01 \x01(\x0b\x32..perfetto.protos.Ext4MballocDiscardFtraceEventH\x00\x12I\n\x11\x65xt4_mballoc_free\x18\xca\x01 \x01(\x0b\x32+.perfetto.protos.Ext4MballocFreeFtraceEventH\x00\x12Q\n\x15\x65xt4_mballoc_prealloc\x18\xcb\x01 \x01(\x0b\x32/.perfetto.protos.Ext4MballocPreallocFtraceEventH\x00\x12]\n\x1c\x65xt4_other_inode_update_time\x18\xcc\x01 \x01(\x0b\x32\x34.perfetto.protos.Ext4OtherInodeUpdateTimeFtraceEventH\x00\x12\x45\n\x0f\x65xt4_punch_hole\x18\xcd\x01 \x01(\x0b\x32).perfetto.protos.Ext4PunchHoleFtraceEventH\x00\x12[\n\x1b\x65xt4_read_block_bitmap_load\x18\xce\x01 \x01(\x0b\x32\x33.perfetto.protos.Ext4ReadBlockBitmapLoadFtraceEventH\x00\x12\x42\n\rext4_readpage\x18\xcf\x01 \x01(\x0b\x32(.perfetto.protos.Ext4ReadpageFtraceEventH\x00\x12H\n\x10\x65xt4_releasepage\x18\xd0\x01 \x01(\x0b\x32+.perfetto.protos.Ext4ReleasepageFtraceEventH\x00\x12K\n\x12\x65xt4_remove_blocks\x18\xd1\x01 \x01(\x0b\x32,.perfetto.protos.Ext4RemoveBlocksFtraceEventH\x00\x12M\n\x13\x65xt4_request_blocks\x18\xd2\x01 \x01(\x0b\x32-.perfetto.protos.Ext4RequestBlocksFtraceEventH\x00\x12K\n\x12\x65xt4_request_inode\x18\xd3\x01 \x01(\x0b\x32,.perfetto.protos.Ext4RequestInodeFtraceEventH\x00\x12?\n\x0c\x65xt4_sync_fs\x18\xd4\x01 \x01(\x0b\x32&.perfetto.protos.Ext4SyncFsFtraceEventH\x00\x12J\n\x12\x65xt4_trim_all_free\x18\xd5\x01 \x01(\x0b\x32+.perfetto.protos.Ext4TrimAllFreeFtraceEventH\x00\x12G\n\x10\x65xt4_trim_extent\x18\xd6\x01 \x01(\x0b\x32*.perfetto.protos.Ext4TrimExtentFtraceEventH\x00\x12M\n\x13\x65xt4_truncate_enter\x18\xd7\x01 \x01(\x0b\x32-.perfetto.protos.Ext4TruncateEnterFtraceEventH\x00\x12K\n\x12\x65xt4_truncate_exit\x18\xd8\x01 \x01(\x0b\x32,.perfetto.protos.Ext4TruncateExitFtraceEventH\x00\x12I\n\x11\x65xt4_unlink_enter\x18\xd9\x01 \x01(\x0b\x32+.perfetto.protos.Ext4UnlinkEnterFtraceEventH\x00\x12G\n\x10\x65xt4_unlink_exit\x18\xda\x01 \x01(\x0b\x32*.perfetto.protos.Ext4UnlinkExitFtraceEventH\x00\x12G\n\x10\x65xt4_write_begin\x18\xdb\x01 \x01(\x0b\x32*.perfetto.protos.Ext4WriteBeginFtraceEventH\x00\x12\x43\n\x0e\x65xt4_write_end\x18\xe6\x01 \x01(\x0b\x32(.perfetto.protos.Ext4WriteEndFtraceEventH\x00\x12\x44\n\x0e\x65xt4_writepage\x18\xe7\x01 \x01(\x0b\x32).perfetto.protos.Ext4WritepageFtraceEventH\x00\x12\x46\n\x0f\x65xt4_writepages\x18\xe8\x01 \x01(\x0b\x32*.perfetto.protos.Ext4WritepagesFtraceEventH\x00\x12S\n\x16\x65xt4_writepages_result\x18\xe9\x01 \x01(\x0b\x32\x30.perfetto.protos.Ext4WritepagesResultFtraceEventH\x00\x12\x45\n\x0f\x65xt4_zero_range\x18\xea\x01 \x01(\x0b\x32).perfetto.protos.Ext4ZeroRangeFtraceEventH\x00\x12@\n\x0ctask_newtask\x18\xeb\x01 \x01(\x0b\x32\'.perfetto.protos.TaskNewtaskFtraceEventH\x00\x12>\n\x0btask_rename\x18\xec\x01 \x01(\x0b\x32&.perfetto.protos.TaskRenameFtraceEventH\x00\x12K\n\x12sched_process_exec\x18\xed\x01 \x01(\x0b\x32,.perfetto.protos.SchedProcessExecFtraceEventH\x00\x12K\n\x12sched_process_exit\x18\xee\x01 \x01(\x0b\x32,.perfetto.protos.SchedProcessExitFtraceEventH\x00\x12K\n\x12sched_process_fork\x18\xef\x01 \x01(\x0b\x32,.perfetto.protos.SchedProcessForkFtraceEventH\x00\x12K\n\x12sched_process_free\x18\xf0\x01 \x01(\x0b\x32,.perfetto.protos.SchedProcessFreeFtraceEventH\x00\x12K\n\x12sched_process_hang\x18\xf1\x01 \x01(\x0b\x32,.perfetto.protos.SchedProcessHangFtraceEventH\x00\x12K\n\x12sched_process_wait\x18\xf2\x01 \x01(\x0b\x32,.perfetto.protos.SchedProcessWaitFtraceEventH\x00\x12J\n\x12\x66\x32\x66s_do_submit_bio\x18\xf3\x01 \x01(\x0b\x32+.perfetto.protos.F2fsDoSubmitBioFtraceEventH\x00\x12G\n\x10\x66\x32\x66s_evict_inode\x18\xf4\x01 \x01(\x0b\x32*.perfetto.protos.F2fsEvictInodeFtraceEventH\x00\x12\x44\n\x0e\x66\x32\x66s_fallocate\x18\xf5\x01 \x01(\x0b\x32).perfetto.protos.F2fsFallocateFtraceEventH\x00\x12L\n\x13\x66\x32\x66s_get_data_block\x18\xf6\x01 \x01(\x0b\x32,.perfetto.protos.F2fsGetDataBlockFtraceEventH\x00\x12\x45\n\x0f\x66\x32\x66s_get_victim\x18\xf7\x01 \x01(\x0b\x32).perfetto.protos.F2fsGetVictimFtraceEventH\x00\x12:\n\tf2fs_iget\x18\xf8\x01 \x01(\x0b\x32$.perfetto.protos.F2fsIgetFtraceEventH\x00\x12\x43\n\x0e\x66\x32\x66s_iget_exit\x18\xf9\x01 \x01(\x0b\x32(.perfetto.protos.F2fsIgetExitFtraceEventH\x00\x12\x43\n\x0e\x66\x32\x66s_new_inode\x18\xfa\x01 \x01(\x0b\x32(.perfetto.protos.F2fsNewInodeFtraceEventH\x00\x12\x42\n\rf2fs_readpage\x18\xfb\x01 \x01(\x0b\x32(.perfetto.protos.F2fsReadpageFtraceEventH\x00\x12R\n\x16\x66\x32\x66s_reserve_new_block\x18\xfc\x01 \x01(\x0b\x32/.perfetto.protos.F2fsReserveNewBlockFtraceEventH\x00\x12L\n\x13\x66\x32\x66s_set_page_dirty\x18\xfd\x01 \x01(\x0b\x32,.perfetto.protos.F2fsSetPageDirtyFtraceEventH\x00\x12R\n\x16\x66\x32\x66s_submit_write_page\x18\xfe\x01 \x01(\x0b\x32/.perfetto.protos.F2fsSubmitWritePageFtraceEventH\x00\x12N\n\x14\x66\x32\x66s_sync_file_enter\x18\xff\x01 \x01(\x0b\x32-.perfetto.protos.F2fsSyncFileEnterFtraceEventH\x00\x12L\n\x13\x66\x32\x66s_sync_file_exit\x18\x80\x02 \x01(\x0b\x32,.perfetto.protos.F2fsSyncFileExitFtraceEventH\x00\x12?\n\x0c\x66\x32\x66s_sync_fs\x18\x81\x02 \x01(\x0b\x32&.perfetto.protos.F2fsSyncFsFtraceEventH\x00\x12\x42\n\rf2fs_truncate\x18\x82\x02 \x01(\x0b\x32(.perfetto.protos.F2fsTruncateFtraceEventH\x00\x12Z\n\x1a\x66\x32\x66s_truncate_blocks_enter\x18\x83\x02 \x01(\x0b\x32\x33.perfetto.protos.F2fsTruncateBlocksEnterFtraceEventH\x00\x12X\n\x19\x66\x32\x66s_truncate_blocks_exit\x18\x84\x02 \x01(\x0b\x32\x32.perfetto.protos.F2fsTruncateBlocksExitFtraceEventH\x00\x12\x63\n\x1f\x66\x32\x66s_truncate_data_blocks_range\x18\x85\x02 \x01(\x0b\x32\x37.perfetto.protos.F2fsTruncateDataBlocksRangeFtraceEventH\x00\x12\x65\n f2fs_truncate_inode_blocks_enter\x18\x86\x02 \x01(\x0b\x32\x38.perfetto.protos.F2fsTruncateInodeBlocksEnterFtraceEventH\x00\x12\x63\n\x1f\x66\x32\x66s_truncate_inode_blocks_exit\x18\x87\x02 \x01(\x0b\x32\x37.perfetto.protos.F2fsTruncateInodeBlocksExitFtraceEventH\x00\x12K\n\x12\x66\x32\x66s_truncate_node\x18\x88\x02 \x01(\x0b\x32,.perfetto.protos.F2fsTruncateNodeFtraceEventH\x00\x12X\n\x19\x66\x32\x66s_truncate_nodes_enter\x18\x89\x02 \x01(\x0b\x32\x32.perfetto.protos.F2fsTruncateNodesEnterFtraceEventH\x00\x12V\n\x18\x66\x32\x66s_truncate_nodes_exit\x18\x8a\x02 \x01(\x0b\x32\x31.perfetto.protos.F2fsTruncateNodesExitFtraceEventH\x00\x12\\\n\x1b\x66\x32\x66s_truncate_partial_nodes\x18\x8b\x02 \x01(\x0b\x32\x34.perfetto.protos.F2fsTruncatePartialNodesFtraceEventH\x00\x12I\n\x11\x66\x32\x66s_unlink_enter\x18\x8c\x02 \x01(\x0b\x32+.perfetto.protos.F2fsUnlinkEnterFtraceEventH\x00\x12G\n\x10\x66\x32\x66s_unlink_exit\x18\x8d\x02 \x01(\x0b\x32*.perfetto.protos.F2fsUnlinkExitFtraceEventH\x00\x12N\n\x14\x66\x32\x66s_vm_page_mkwrite\x18\x8e\x02 \x01(\x0b\x32-.perfetto.protos.F2fsVmPageMkwriteFtraceEventH\x00\x12G\n\x10\x66\x32\x66s_write_begin\x18\x8f\x02 \x01(\x0b\x32*.perfetto.protos.F2fsWriteBeginFtraceEventH\x00\x12Q\n\x15\x66\x32\x66s_write_checkpoint\x18\x90\x02 \x01(\x0b\x32/.perfetto.protos.F2fsWriteCheckpointFtraceEventH\x00\x12\x43\n\x0e\x66\x32\x66s_write_end\x18\x91\x02 \x01(\x0b\x32(.perfetto.protos.F2fsWriteEndFtraceEventH\x00\x12P\n\x15\x61lloc_pages_iommu_end\x18\x92\x02 \x01(\x0b\x32..perfetto.protos.AllocPagesIommuEndFtraceEventH\x00\x12R\n\x16\x61lloc_pages_iommu_fail\x18\x93\x02 \x01(\x0b\x32/.perfetto.protos.AllocPagesIommuFailFtraceEventH\x00\x12T\n\x17\x61lloc_pages_iommu_start\x18\x94\x02 \x01(\x0b\x32\x30.perfetto.protos.AllocPagesIommuStartFtraceEventH\x00\x12L\n\x13\x61lloc_pages_sys_end\x18\x95\x02 \x01(\x0b\x32,.perfetto.protos.AllocPagesSysEndFtraceEventH\x00\x12N\n\x14\x61lloc_pages_sys_fail\x18\x96\x02 \x01(\x0b\x32-.perfetto.protos.AllocPagesSysFailFtraceEventH\x00\x12P\n\x15\x61lloc_pages_sys_start\x18\x97\x02 \x01(\x0b\x32..perfetto.protos.AllocPagesSysStartFtraceEventH\x00\x12Z\n\x1a\x64ma_alloc_contiguous_retry\x18\x98\x02 \x01(\x0b\x32\x33.perfetto.protos.DmaAllocContiguousRetryFtraceEventH\x00\x12\x45\n\x0fiommu_map_range\x18\x99\x02 \x01(\x0b\x32).perfetto.protos.IommuMapRangeFtraceEventH\x00\x12\\\n\x1ciommu_sec_ptbl_map_range_end\x18\x9a\x02 \x01(\x0b\x32\x33.perfetto.protos.IommuSecPtblMapRangeEndFtraceEventH\x00\x12`\n\x1eiommu_sec_ptbl_map_range_start\x18\x9b\x02 \x01(\x0b\x32\x35.perfetto.protos.IommuSecPtblMapRangeStartFtraceEventH\x00\x12N\n\x14ion_alloc_buffer_end\x18\x9c\x02 \x01(\x0b\x32-.perfetto.protos.IonAllocBufferEndFtraceEventH\x00\x12P\n\x15ion_alloc_buffer_fail\x18\x9d\x02 \x01(\x0b\x32..perfetto.protos.IonAllocBufferFailFtraceEventH\x00\x12X\n\x19ion_alloc_buffer_fallback\x18\x9e\x02 \x01(\x0b\x32\x32.perfetto.protos.IonAllocBufferFallbackFtraceEventH\x00\x12R\n\x16ion_alloc_buffer_start\x18\x9f\x02 \x01(\x0b\x32/.perfetto.protos.IonAllocBufferStartFtraceEventH\x00\x12J\n\x12ion_cp_alloc_retry\x18\xa0\x02 \x01(\x0b\x32+.perfetto.protos.IonCpAllocRetryFtraceEventH\x00\x12U\n\x18ion_cp_secure_buffer_end\x18\xa1\x02 \x01(\x0b\x32\x30.perfetto.protos.IonCpSecureBufferEndFtraceEventH\x00\x12Y\n\x1aion_cp_secure_buffer_start\x18\xa2\x02 \x01(\x0b\x32\x32.perfetto.protos.IonCpSecureBufferStartFtraceEventH\x00\x12\x46\n\x0fion_prefetching\x18\xa3\x02 \x01(\x0b\x32*.perfetto.protos.IonPrefetchingFtraceEventH\x00\x12_\n\x1eion_secure_cma_add_to_pool_end\x18\xa4\x02 \x01(\x0b\x32\x34.perfetto.protos.IonSecureCmaAddToPoolEndFtraceEventH\x00\x12\x63\n ion_secure_cma_add_to_pool_start\x18\xa5\x02 \x01(\x0b\x32\x36.perfetto.protos.IonSecureCmaAddToPoolStartFtraceEventH\x00\x12[\n\x1bion_secure_cma_allocate_end\x18\xa6\x02 \x01(\x0b\x32\x33.perfetto.protos.IonSecureCmaAllocateEndFtraceEventH\x00\x12_\n\x1dion_secure_cma_allocate_start\x18\xa7\x02 \x01(\x0b\x32\x35.perfetto.protos.IonSecureCmaAllocateStartFtraceEventH\x00\x12`\n\x1eion_secure_cma_shrink_pool_end\x18\xa8\x02 \x01(\x0b\x32\x35.perfetto.protos.IonSecureCmaShrinkPoolEndFtraceEventH\x00\x12\x64\n ion_secure_cma_shrink_pool_start\x18\xa9\x02 \x01(\x0b\x32\x37.perfetto.protos.IonSecureCmaShrinkPoolStartFtraceEventH\x00\x12\x33\n\x05kfree\x18\xaa\x02 \x01(\x0b\x32!.perfetto.protos.KfreeFtraceEventH\x00\x12\x37\n\x07kmalloc\x18\xab\x02 \x01(\x0b\x32#.perfetto.protos.KmallocFtraceEventH\x00\x12@\n\x0ckmalloc_node\x18\xac\x02 \x01(\x0b\x32\'.perfetto.protos.KmallocNodeFtraceEventH\x00\x12G\n\x10kmem_cache_alloc\x18\xad\x02 \x01(\x0b\x32*.perfetto.protos.KmemCacheAllocFtraceEventH\x00\x12P\n\x15kmem_cache_alloc_node\x18\xae\x02 \x01(\x0b\x32..perfetto.protos.KmemCacheAllocNodeFtraceEventH\x00\x12\x45\n\x0fkmem_cache_free\x18\xaf\x02 \x01(\x0b\x32).perfetto.protos.KmemCacheFreeFtraceEventH\x00\x12I\n\x11migrate_pages_end\x18\xb0\x02 \x01(\x0b\x32+.perfetto.protos.MigratePagesEndFtraceEventH\x00\x12M\n\x13migrate_pages_start\x18\xb1\x02 \x01(\x0b\x32-.perfetto.protos.MigratePagesStartFtraceEventH\x00\x12\x42\n\rmigrate_retry\x18\xb2\x02 \x01(\x0b\x32(.perfetto.protos.MigrateRetryFtraceEventH\x00\x12\x41\n\rmm_page_alloc\x18\xb3\x02 \x01(\x0b\x32\'.perfetto.protos.MmPageAllocFtraceEventH\x00\x12P\n\x15mm_page_alloc_extfrag\x18\xb4\x02 \x01(\x0b\x32..perfetto.protos.MmPageAllocExtfragFtraceEventH\x00\x12W\n\x19mm_page_alloc_zone_locked\x18\xb5\x02 \x01(\x0b\x32\x31.perfetto.protos.MmPageAllocZoneLockedFtraceEventH\x00\x12?\n\x0cmm_page_free\x18\xb6\x02 \x01(\x0b\x32&.perfetto.protos.MmPageFreeFtraceEventH\x00\x12N\n\x14mm_page_free_batched\x18\xb7\x02 \x01(\x0b\x32-.perfetto.protos.MmPageFreeBatchedFtraceEventH\x00\x12J\n\x12mm_page_pcpu_drain\x18\xb8\x02 \x01(\x0b\x32+.perfetto.protos.MmPagePcpuDrainFtraceEventH\x00\x12\x38\n\x08rss_stat\x18\xb9\x02 \x01(\x0b\x32#.perfetto.protos.RssStatFtraceEventH\x00\x12\x45\n\x0fion_heap_shrink\x18\xba\x02 \x01(\x0b\x32).perfetto.protos.IonHeapShrinkFtraceEventH\x00\x12\x41\n\rion_heap_grow\x18\xbb\x02 \x01(\x0b\x32\'.perfetto.protos.IonHeapGrowFtraceEventH\x00\x12<\n\nfence_init\x18\xbc\x02 \x01(\x0b\x32%.perfetto.protos.FenceInitFtraceEventH\x00\x12\x42\n\rfence_destroy\x18\xbd\x02 \x01(\x0b\x32(.perfetto.protos.FenceDestroyFtraceEventH\x00\x12M\n\x13\x66\x65nce_enable_signal\x18\xbe\x02 \x01(\x0b\x32-.perfetto.protos.FenceEnableSignalFtraceEventH\x00\x12\x44\n\x0e\x66\x65nce_signaled\x18\xbf\x02 \x01(\x0b\x32).perfetto.protos.FenceSignaledFtraceEventH\x00\x12<\n\nclk_enable\x18\xc0\x02 \x01(\x0b\x32%.perfetto.protos.ClkEnableFtraceEventH\x00\x12>\n\x0b\x63lk_disable\x18\xc1\x02 \x01(\x0b\x32&.perfetto.protos.ClkDisableFtraceEventH\x00\x12?\n\x0c\x63lk_set_rate\x18\xc2\x02 \x01(\x0b\x32&.perfetto.protos.ClkSetRateFtraceEventH\x00\x12^\n\x1c\x62inder_transaction_alloc_buf\x18\xc3\x02 \x01(\x0b\x32\x35.perfetto.protos.BinderTransactionAllocBufFtraceEventH\x00\x12\x44\n\x0esignal_deliver\x18\xc4\x02 \x01(\x0b\x32).perfetto.protos.SignalDeliverFtraceEventH\x00\x12\x46\n\x0fsignal_generate\x18\xc5\x02 \x01(\x0b\x32*.perfetto.protos.SignalGenerateFtraceEventH\x00\x12N\n\x14oom_score_adj_update\x18\xc6\x02 \x01(\x0b\x32-.perfetto.protos.OomScoreAdjUpdateFtraceEventH\x00\x12\x37\n\x07generic\x18\xc7\x02 \x01(\x0b\x32#.perfetto.protos.GenericFtraceEventH\x00\x12\x45\n\x0fmm_event_record\x18\xc8\x02 \x01(\x0b\x32).perfetto.protos.MmEventRecordFtraceEventH\x00\x12:\n\tsys_enter\x18\xc9\x02 \x01(\x0b\x32$.perfetto.protos.SysEnterFtraceEventH\x00\x12\x38\n\x08sys_exit\x18\xca\x02 \x01(\x0b\x32#.perfetto.protos.SysExitFtraceEventH\x00\x12\x31\n\x04zero\x18\xcb\x02 \x01(\x0b\x32 .perfetto.protos.ZeroFtraceEventH\x00\x12\x42\n\rgpu_frequency\x18\xcc\x02 \x01(\x0b\x32(.perfetto.protos.GpuFrequencyFtraceEventH\x00\x12R\n\x16sde_tracing_mark_write\x18\xcd\x02 \x01(\x0b\x32/.perfetto.protos.SdeTracingMarkWriteFtraceEventH\x00\x12>\n\x0bmark_victim\x18\xce\x02 \x01(\x0b\x32&.perfetto.protos.MarkVictimFtraceEventH\x00\x12\x38\n\x08ion_stat\x18\xcf\x02 \x01(\x0b\x32#.perfetto.protos.IonStatFtraceEventH\x00\x12I\n\x11ion_buffer_create\x18\xd0\x02 \x01(\x0b\x32+.perfetto.protos.IonBufferCreateFtraceEventH\x00\x12K\n\x12ion_buffer_destroy\x18\xd1\x02 \x01(\x0b\x32,.perfetto.protos.IonBufferDestroyFtraceEventH\x00\x12\x43\n\x0escm_call_start\x18\xd2\x02 \x01(\x0b\x32(.perfetto.protos.ScmCallStartFtraceEventH\x00\x12?\n\x0cscm_call_end\x18\xd3\x02 \x01(\x0b\x32&.perfetto.protos.ScmCallEndFtraceEventH\x00\x12\x41\n\rgpu_mem_total\x18\xd4\x02 \x01(\x0b\x32\'.perfetto.protos.GpuMemTotalFtraceEventH\x00\x12N\n\x13thermal_temperature\x18\xd5\x02 \x01(\x0b\x32..perfetto.protos.ThermalTemperatureFtraceEventH\x00\x12>\n\x0b\x63\x64\x65v_update\x18\xd6\x02 \x01(\x0b\x32&.perfetto.protos.CdevUpdateFtraceEventH\x00\x12<\n\ncpuhp_exit\x18\xd7\x02 \x01(\x0b\x32%.perfetto.protos.CpuhpExitFtraceEventH\x00\x12I\n\x11\x63puhp_multi_enter\x18\xd8\x02 \x01(\x0b\x32+.perfetto.protos.CpuhpMultiEnterFtraceEventH\x00\x12>\n\x0b\x63puhp_enter\x18\xd9\x02 \x01(\x0b\x32&.perfetto.protos.CpuhpEnterFtraceEventH\x00\x12\x42\n\rcpuhp_latency\x18\xda\x02 \x01(\x0b\x32(.perfetto.protos.CpuhpLatencyFtraceEventH\x00\x12G\n\x10\x66\x61strpc_dma_stat\x18\xdb\x02 \x01(\x0b\x32*.perfetto.protos.FastrpcDmaStatFtraceEventH\x00\x12R\n\x16\x64pu_tracing_mark_write\x18\xdc\x02 \x01(\x0b\x32/.perfetto.protos.DpuTracingMarkWriteFtraceEventH\x00\x12R\n\x16g2d_tracing_mark_write\x18\xdd\x02 \x01(\x0b\x32/.perfetto.protos.G2dTracingMarkWriteFtraceEventH\x00\x12T\n\x17mali_tracing_mark_write\x18\xde\x02 \x01(\x0b\x32\x30.perfetto.protos.MaliTracingMarkWriteFtraceEventH\x00\x12\x41\n\rdma_heap_stat\x18\xdf\x02 \x01(\x0b\x32\'.perfetto.protos.DmaHeapStatFtraceEventH\x00\x12>\n\x0b\x63puhp_pause\x18\xe0\x02 \x01(\x0b\x32&.perfetto.protos.CpuhpPauseFtraceEventH\x00\x12G\n\x10sched_pi_setprio\x18\xe1\x02 \x01(\x0b\x32*.perfetto.protos.SchedPiSetprioFtraceEventH\x00\x12\x43\n\x0esde_sde_evtlog\x18\xe2\x02 \x01(\x0b\x32(.perfetto.protos.SdeSdeEvtlogFtraceEventH\x00\x12Q\n\x16sde_sde_perf_calc_crtc\x18\xe3\x02 \x01(\x0b\x32..perfetto.protos.SdeSdePerfCalcCrtcFtraceEventH\x00\x12U\n\x18sde_sde_perf_crtc_update\x18\xe4\x02 \x01(\x0b\x32\x30.perfetto.protos.SdeSdePerfCrtcUpdateFtraceEventH\x00\x12V\n\x19sde_sde_perf_set_qos_luts\x18\xe5\x02 \x01(\x0b\x32\x30.perfetto.protos.SdeSdePerfSetQosLutsFtraceEventH\x00\x12S\n\x17sde_sde_perf_update_bus\x18\xe6\x02 \x01(\x0b\x32/.perfetto.protos.SdeSdePerfUpdateBusFtraceEventH\x00\x12K\n\x12rss_stat_throttled\x18\xe7\x02 \x01(\x0b\x32,.perfetto.protos.RssStatThrottledFtraceEventH\x00\x12I\n\x11netif_receive_skb\x18\xe8\x02 \x01(\x0b\x32+.perfetto.protos.NetifReceiveSkbFtraceEventH\x00\x12?\n\x0cnet_dev_xmit\x18\xe9\x02 \x01(\x0b\x32&.perfetto.protos.NetDevXmitFtraceEventH\x00\x12L\n\x13inet_sock_set_state\x18\xea\x02 \x01(\x0b\x32,.perfetto.protos.InetSockSetStateFtraceEventH\x00\x12K\n\x12tcp_retransmit_skb\x18\xeb\x02 \x01(\x0b\x32,.perfetto.protos.TcpRetransmitSkbFtraceEventH\x00\x12R\n\x16\x63ros_ec_sensorhub_data\x18\xec\x02 \x01(\x0b\x32/.perfetto.protos.CrosEcSensorhubDataFtraceEventH\x00\x12R\n\x16napi_gro_receive_entry\x18\xed\x02 \x01(\x0b\x32/.perfetto.protos.NapiGroReceiveEntryFtraceEventH\x00\x12P\n\x15napi_gro_receive_exit\x18\xee\x02 \x01(\x0b\x32..perfetto.protos.NapiGroReceiveExitFtraceEventH\x00\x12:\n\tkfree_skb\x18\xef\x02 \x01(\x0b\x32$.perfetto.protos.KfreeSkbFtraceEventH\x00\x12G\n\x10kvm_access_fault\x18\xf0\x02 \x01(\x0b\x32*.perfetto.protos.KvmAccessFaultFtraceEventH\x00\x12=\n\x0bkvm_ack_irq\x18\xf1\x02 \x01(\x0b\x32%.perfetto.protos.KvmAckIrqFtraceEventH\x00\x12=\n\x0bkvm_age_hva\x18\xf2\x02 \x01(\x0b\x32%.perfetto.protos.KvmAgeHvaFtraceEventH\x00\x12?\n\x0ckvm_age_page\x18\xf3\x02 \x01(\x0b\x32&.perfetto.protos.KvmAgePageFtraceEventH\x00\x12L\n\x13kvm_arm_clear_debug\x18\xf4\x02 \x01(\x0b\x32,.perfetto.protos.KvmArmClearDebugFtraceEventH\x00\x12J\n\x12kvm_arm_set_dreg32\x18\xf5\x02 \x01(\x0b\x32+.perfetto.protos.KvmArmSetDreg32FtraceEventH\x00\x12J\n\x12kvm_arm_set_regset\x18\xf6\x02 \x01(\x0b\x32+.perfetto.protos.KvmArmSetRegsetFtraceEventH\x00\x12L\n\x13kvm_arm_setup_debug\x18\xf7\x02 \x01(\x0b\x32,.perfetto.protos.KvmArmSetupDebugFtraceEventH\x00\x12:\n\tkvm_entry\x18\xf8\x02 \x01(\x0b\x32$.perfetto.protos.KvmEntryFtraceEventH\x00\x12\x38\n\x08kvm_exit\x18\xf9\x02 \x01(\x0b\x32#.perfetto.protos.KvmExitFtraceEventH\x00\x12\x36\n\x07kvm_fpu\x18\xfa\x02 \x01(\x0b\x32\".perfetto.protos.KvmFpuFtraceEventH\x00\x12H\n\x11kvm_get_timer_map\x18\xfb\x02 \x01(\x0b\x32*.perfetto.protos.KvmGetTimerMapFtraceEventH\x00\x12\x45\n\x0fkvm_guest_fault\x18\xfc\x02 \x01(\x0b\x32).perfetto.protos.KvmGuestFaultFtraceEventH\x00\x12J\n\x12kvm_handle_sys_reg\x18\xfd\x02 \x01(\x0b\x32+.perfetto.protos.KvmHandleSysRegFtraceEventH\x00\x12\x41\n\rkvm_hvc_arm64\x18\xfe\x02 \x01(\x0b\x32\'.perfetto.protos.KvmHvcArm64FtraceEventH\x00\x12?\n\x0ckvm_irq_line\x18\xff\x02 \x01(\x0b\x32&.perfetto.protos.KvmIrqLineFtraceEventH\x00\x12\x38\n\x08kvm_mmio\x18\x80\x03 \x01(\x0b\x32#.perfetto.protos.KvmMmioFtraceEventH\x00\x12G\n\x10kvm_mmio_emulate\x18\x81\x03 \x01(\x0b\x32*.perfetto.protos.KvmMmioEmulateFtraceEventH\x00\x12L\n\x13kvm_set_guest_debug\x18\x82\x03 \x01(\x0b\x32,.perfetto.protos.KvmSetGuestDebugFtraceEventH\x00\x12=\n\x0bkvm_set_irq\x18\x83\x03 \x01(\x0b\x32%.perfetto.protos.KvmSetIrqFtraceEventH\x00\x12\x46\n\x10kvm_set_spte_hva\x18\x84\x03 \x01(\x0b\x32).perfetto.protos.KvmSetSpteHvaFtraceEventH\x00\x12H\n\x11kvm_set_way_flush\x18\x85\x03 \x01(\x0b\x32*.perfetto.protos.KvmSetWayFlushFtraceEventH\x00\x12\x43\n\x0ekvm_sys_access\x18\x86\x03 \x01(\x0b\x32(.perfetto.protos.KvmSysAccessFtraceEventH\x00\x12\x46\n\x10kvm_test_age_hva\x18\x87\x03 \x01(\x0b\x32).perfetto.protos.KvmTestAgeHvaFtraceEventH\x00\x12I\n\x11kvm_timer_emulate\x18\x88\x03 \x01(\x0b\x32+.perfetto.protos.KvmTimerEmulateFtraceEventH\x00\x12V\n\x18kvm_timer_hrtimer_expire\x18\x89\x03 \x01(\x0b\x32\x31.perfetto.protos.KvmTimerHrtimerExpireFtraceEventH\x00\x12T\n\x17kvm_timer_restore_state\x18\x8a\x03 \x01(\x0b\x32\x30.perfetto.protos.KvmTimerRestoreStateFtraceEventH\x00\x12N\n\x14kvm_timer_save_state\x18\x8b\x03 \x01(\x0b\x32-.perfetto.protos.KvmTimerSaveStateFtraceEventH\x00\x12N\n\x14kvm_timer_update_irq\x18\x8c\x03 \x01(\x0b\x32-.perfetto.protos.KvmTimerUpdateIrqFtraceEventH\x00\x12G\n\x10kvm_toggle_cache\x18\x8d\x03 \x01(\x0b\x32*.perfetto.protos.KvmToggleCacheFtraceEventH\x00\x12L\n\x13kvm_unmap_hva_range\x18\x8e\x03 \x01(\x0b\x32,.perfetto.protos.KvmUnmapHvaRangeFtraceEventH\x00\x12K\n\x12kvm_userspace_exit\x18\x8f\x03 \x01(\x0b\x32,.perfetto.protos.KvmUserspaceExitFtraceEventH\x00\x12\x45\n\x0fkvm_vcpu_wakeup\x18\x90\x03 \x01(\x0b\x32).perfetto.protos.KvmVcpuWakeupFtraceEventH\x00\x12\x41\n\rkvm_wfx_arm64\x18\x91\x03 \x01(\x0b\x32\'.perfetto.protos.KvmWfxArm64FtraceEventH\x00\x12\x38\n\x08trap_reg\x18\x92\x03 \x01(\x0b\x32#.perfetto.protos.TrapRegFtraceEventH\x00\x12T\n\x17vgic_update_irq_pending\x18\x93\x03 \x01(\x0b\x32\x30.perfetto.protos.VgicUpdateIrqPendingFtraceEventH\x00\x12S\n\x16wakeup_source_activate\x18\x94\x03 \x01(\x0b\x32\x30.perfetto.protos.WakeupSourceActivateFtraceEventH\x00\x12W\n\x18wakeup_source_deactivate\x18\x95\x03 \x01(\x0b\x32\x32.perfetto.protos.WakeupSourceDeactivateFtraceEventH\x00\x12\x44\n\x0eufshcd_command\x18\x96\x03 \x01(\x0b\x32).perfetto.protos.UfshcdCommandFtraceEventH\x00\x12I\n\x11ufshcd_clk_gating\x18\x97\x03 \x01(\x0b\x32+.perfetto.protos.UfshcdClkGatingFtraceEventH\x00\x12\x37\n\x07\x63onsole\x18\x98\x03 \x01(\x0b\x32#.perfetto.protos.ConsoleFtraceEventH\x00\x12G\n\x10\x64rm_vblank_event\x18\x99\x03 \x01(\x0b\x32*.perfetto.protos.DrmVblankEventFtraceEventH\x00\x12Z\n\x1a\x64rm_vblank_event_delivered\x18\x9a\x03 \x01(\x0b\x32\x33.perfetto.protos.DrmVblankEventDeliveredFtraceEventH\x00\x12\x41\n\rdrm_sched_job\x18\x9b\x03 \x01(\x0b\x32\'.perfetto.protos.DrmSchedJobFtraceEventH\x00\x12=\n\x0b\x64rm_run_job\x18\x9c\x03 \x01(\x0b\x32%.perfetto.protos.DrmRunJobFtraceEventH\x00\x12P\n\x15\x64rm_sched_process_job\x18\x9d\x03 \x01(\x0b\x32..perfetto.protos.DrmSchedProcessJobFtraceEventH\x00\x12\x43\n\x0e\x64ma_fence_init\x18\x9e\x03 \x01(\x0b\x32(.perfetto.protos.DmaFenceInitFtraceEventH\x00\x12\x43\n\x0e\x64ma_fence_emit\x18\x9f\x03 \x01(\x0b\x32(.perfetto.protos.DmaFenceEmitFtraceEventH\x00\x12K\n\x12\x64ma_fence_signaled\x18\xa0\x03 \x01(\x0b\x32,.perfetto.protos.DmaFenceSignaledFtraceEventH\x00\x12N\n\x14\x64ma_fence_wait_start\x18\xa1\x03 \x01(\x0b\x32-.perfetto.protos.DmaFenceWaitStartFtraceEventH\x00\x12J\n\x12\x64ma_fence_wait_end\x18\xa2\x03 \x01(\x0b\x32+.perfetto.protos.DmaFenceWaitEndFtraceEventH\x00\x12>\n\x0b\x66\x32\x66s_iostat\x18\xa3\x03 \x01(\x0b\x32&.perfetto.protos.F2fsIostatFtraceEventH\x00\x12M\n\x13\x66\x32\x66s_iostat_latency\x18\xa4\x03 \x01(\x0b\x32-.perfetto.protos.F2fsIostatLatencyFtraceEventH\x00\x12J\n\x12sched_cpu_util_cfs\x18\xa5\x03 \x01(\x0b\x32+.perfetto.protos.SchedCpuUtilCfsFtraceEventH\x00\x12:\n\tv4l2_qbuf\x18\xa6\x03 \x01(\x0b\x32$.perfetto.protos.V4l2QbufFtraceEventH\x00\x12<\n\nv4l2_dqbuf\x18\xa7\x03 \x01(\x0b\x32%.perfetto.protos.V4l2DqbufFtraceEventH\x00\x12J\n\x12vb2_v4l2_buf_queue\x18\xa8\x03 \x01(\x0b\x32+.perfetto.protos.Vb2V4l2BufQueueFtraceEventH\x00\x12H\n\x11vb2_v4l2_buf_done\x18\xa9\x03 \x01(\x0b\x32*.perfetto.protos.Vb2V4l2BufDoneFtraceEventH\x00\x12\x41\n\rvb2_v4l2_qbuf\x18\xaa\x03 \x01(\x0b\x32\'.perfetto.protos.Vb2V4l2QbufFtraceEventH\x00\x12\x43\n\x0evb2_v4l2_dqbuf\x18\xab\x03 \x01(\x0b\x32(.perfetto.protos.Vb2V4l2DqbufFtraceEventH\x00\x12L\n\x13\x64si_cmd_fifo_status\x18\xac\x03 \x01(\x0b\x32,.perfetto.protos.DsiCmdFifoStatusFtraceEventH\x00\x12\x34\n\x06\x64si_rx\x18\xad\x03 \x01(\x0b\x32!.perfetto.protos.DsiRxFtraceEventH\x00\x12\x34\n\x06\x64si_tx\x18\xae\x03 \x01(\x0b\x32!.perfetto.protos.DsiTxFtraceEventH\x00\x12T\n\x17\x61ndroid_fs_dataread_end\x18\xaf\x03 \x01(\x0b\x32\x30.perfetto.protos.AndroidFsDatareadEndFtraceEventH\x00\x12X\n\x19\x61ndroid_fs_dataread_start\x18\xb0\x03 \x01(\x0b\x32\x32.perfetto.protos.AndroidFsDatareadStartFtraceEventH\x00\x12V\n\x18\x61ndroid_fs_datawrite_end\x18\xb1\x03 \x01(\x0b\x32\x31.perfetto.protos.AndroidFsDatawriteEndFtraceEventH\x00\x12Z\n\x1a\x61ndroid_fs_datawrite_start\x18\xb2\x03 \x01(\x0b\x32\x33.perfetto.protos.AndroidFsDatawriteStartFtraceEventH\x00\x12N\n\x14\x61ndroid_fs_fsync_end\x18\xb3\x03 \x01(\x0b\x32-.perfetto.protos.AndroidFsFsyncEndFtraceEventH\x00\x12R\n\x16\x61ndroid_fs_fsync_start\x18\xb4\x03 \x01(\x0b\x32/.perfetto.protos.AndroidFsFsyncStartFtraceEventH\x00\x12\x46\n\x0f\x66uncgraph_entry\x18\xb5\x03 \x01(\x0b\x32*.perfetto.protos.FuncgraphEntryFtraceEventH\x00\x12\x44\n\x0e\x66uncgraph_exit\x18\xb6\x03 \x01(\x0b\x32).perfetto.protos.FuncgraphExitFtraceEventH\x00\x12G\n\x10virtio_video_cmd\x18\xb7\x03 \x01(\x0b\x32*.perfetto.protos.VirtioVideoCmdFtraceEventH\x00\x12P\n\x15virtio_video_cmd_done\x18\xb8\x03 \x01(\x0b\x32..perfetto.protos.VirtioVideoCmdDoneFtraceEventH\x00\x12\\\n\x1bvirtio_video_resource_queue\x18\xb9\x03 \x01(\x0b\x32\x34.perfetto.protos.VirtioVideoResourceQueueFtraceEventH\x00\x12\x65\n virtio_video_resource_queue_done\x18\xba\x03 \x01(\x0b\x32\x38.perfetto.protos.VirtioVideoResourceQueueDoneFtraceEventH\x00\x12N\n\x14mm_shrink_slab_start\x18\xbb\x03 \x01(\x0b\x32-.perfetto.protos.MmShrinkSlabStartFtraceEventH\x00\x12J\n\x12mm_shrink_slab_end\x18\xbc\x03 \x01(\x0b\x32+.perfetto.protos.MmShrinkSlabEndFtraceEventH\x00\x12<\n\ntrusty_smc\x18\xbd\x03 \x01(\x0b\x32%.perfetto.protos.TrustySmcFtraceEventH\x00\x12\x45\n\x0ftrusty_smc_done\x18\xbe\x03 \x01(\x0b\x32).perfetto.protos.TrustySmcDoneFtraceEventH\x00\x12I\n\x11trusty_std_call32\x18\xbf\x03 \x01(\x0b\x32+.perfetto.protos.TrustyStdCall32FtraceEventH\x00\x12R\n\x16trusty_std_call32_done\x18\xc0\x03 \x01(\x0b\x32/.perfetto.protos.TrustyStdCall32DoneFtraceEventH\x00\x12M\n\x13trusty_share_memory\x18\xc1\x03 \x01(\x0b\x32-.perfetto.protos.TrustyShareMemoryFtraceEventH\x00\x12V\n\x18trusty_share_memory_done\x18\xc2\x03 \x01(\x0b\x32\x31.perfetto.protos.TrustyShareMemoryDoneFtraceEventH\x00\x12Q\n\x15trusty_reclaim_memory\x18\xc3\x03 \x01(\x0b\x32/.perfetto.protos.TrustyReclaimMemoryFtraceEventH\x00\x12Z\n\x1atrusty_reclaim_memory_done\x18\xc4\x03 \x01(\x0b\x32\x33.perfetto.protos.TrustyReclaimMemoryDoneFtraceEventH\x00\x12<\n\ntrusty_irq\x18\xc5\x03 \x01(\x0b\x32%.perfetto.protos.TrustyIrqFtraceEventH\x00\x12T\n\x17trusty_ipc_handle_event\x18\xc6\x03 \x01(\x0b\x32\x30.perfetto.protos.TrustyIpcHandleEventFtraceEventH\x00\x12K\n\x12trusty_ipc_connect\x18\xc7\x03 \x01(\x0b\x32,.perfetto.protos.TrustyIpcConnectFtraceEventH\x00\x12R\n\x16trusty_ipc_connect_end\x18\xc8\x03 \x01(\x0b\x32/.perfetto.protos.TrustyIpcConnectEndFtraceEventH\x00\x12G\n\x10trusty_ipc_write\x18\xc9\x03 \x01(\x0b\x32*.perfetto.protos.TrustyIpcWriteFtraceEventH\x00\x12\x45\n\x0ftrusty_ipc_poll\x18\xca\x03 \x01(\x0b\x32).perfetto.protos.TrustyIpcPollFtraceEventH\x00\x12\x45\n\x0ftrusty_ipc_read\x18\xcc\x03 \x01(\x0b\x32).perfetto.protos.TrustyIpcReadFtraceEventH\x00\x12L\n\x13trusty_ipc_read_end\x18\xcd\x03 \x01(\x0b\x32,.perfetto.protos.TrustyIpcReadEndFtraceEventH\x00\x12\x41\n\rtrusty_ipc_rx\x18\xce\x03 \x01(\x0b\x32\'.perfetto.protos.TrustyIpcRxFtraceEventH\x00\x12K\n\x12trusty_enqueue_nop\x18\xd0\x03 \x01(\x0b\x32,.perfetto.protos.TrustyEnqueueNopFtraceEventH\x00\x12\x45\n\x0f\x63ma_alloc_start\x18\xd1\x03 \x01(\x0b\x32).perfetto.protos.CmaAllocStartFtraceEventH\x00\x12\x43\n\x0e\x63ma_alloc_info\x18\xd2\x03 \x01(\x0b\x32(.perfetto.protos.CmaAllocInfoFtraceEventH\x00\x12T\n\x17lwis_tracing_mark_write\x18\xd3\x03 \x01(\x0b\x32\x30.perfetto.protos.LwisTracingMarkWriteFtraceEventH\x00\x12N\n\x14virtio_gpu_cmd_queue\x18\xd4\x03 \x01(\x0b\x32-.perfetto.protos.VirtioGpuCmdQueueFtraceEventH\x00\x12T\n\x17virtio_gpu_cmd_response\x18\xd5\x03 \x01(\x0b\x32\x30.perfetto.protos.VirtioGpuCmdResponseFtraceEventH\x00\x12Q\n\x16mali_mali_KCPU_CQS_SET\x18\xd6\x03 \x01(\x0b\x32..perfetto.protos.MaliMaliKCPUCQSSETFtraceEventH\x00\x12^\n\x1dmali_mali_KCPU_CQS_WAIT_START\x18\xd7\x03 \x01(\x0b\x32\x34.perfetto.protos.MaliMaliKCPUCQSWAITSTARTFtraceEventH\x00\x12Z\n\x1bmali_mali_KCPU_CQS_WAIT_END\x18\xd8\x03 \x01(\x0b\x32\x32.perfetto.protos.MaliMaliKCPUCQSWAITENDFtraceEventH\x00\x12[\n\x1bmali_mali_KCPU_FENCE_SIGNAL\x18\xd9\x03 \x01(\x0b\x32\x33.perfetto.protos.MaliMaliKCPUFENCESIGNALFtraceEventH\x00\x12\x62\n\x1fmali_mali_KCPU_FENCE_WAIT_START\x18\xda\x03 \x01(\x0b\x32\x36.perfetto.protos.MaliMaliKCPUFENCEWAITSTARTFtraceEventH\x00\x12^\n\x1dmali_mali_KCPU_FENCE_WAIT_END\x18\xdb\x03 \x01(\x0b\x32\x34.perfetto.protos.MaliMaliKCPUFENCEWAITENDFtraceEventH\x00\x12:\n\thyp_enter\x18\xdc\x03 \x01(\x0b\x32$.perfetto.protos.HypEnterFtraceEventH\x00\x12\x38\n\x08hyp_exit\x18\xdd\x03 \x01(\x0b\x32#.perfetto.protos.HypExitFtraceEventH\x00\x12<\n\nhost_hcall\x18\xde\x03 \x01(\x0b\x32%.perfetto.protos.HostHcallFtraceEventH\x00\x12\x38\n\x08host_smc\x18\xdf\x03 \x01(\x0b\x32#.perfetto.protos.HostSmcFtraceEventH\x00\x12\x43\n\x0ehost_mem_abort\x18\xe0\x03 \x01(\x0b\x32(.perfetto.protos.HostMemAbortFtraceEventH\x00\x12S\n\x16suspend_resume_minimal\x18\xe1\x03 \x01(\x0b\x32\x30.perfetto.protos.SuspendResumeMinimalFtraceEventH\x00\x12_\n\x1dmali_mali_CSF_INTERRUPT_START\x18\xe2\x03 \x01(\x0b\x32\x35.perfetto.protos.MaliMaliCSFINTERRUPTSTARTFtraceEventH\x00\x12[\n\x1bmali_mali_CSF_INTERRUPT_END\x18\xe3\x03 \x01(\x0b\x32\x33.perfetto.protos.MaliMaliCSFINTERRUPTENDFtraceEventH\x00\x12Z\n\x1asamsung_tracing_mark_write\x18\xe4\x03 \x01(\x0b\x32\x33.perfetto.protos.SamsungTracingMarkWriteFtraceEventH\x00\x12\x44\n\x0e\x62inder_command\x18\xe5\x03 \x01(\x0b\x32).perfetto.protos.BinderCommandFtraceEventH\x00\x12\x42\n\rbinder_return\x18\xe6\x03 \x01(\x0b\x32(.perfetto.protos.BinderReturnFtraceEventH\x00\x12R\n\x16sched_switch_with_ctrs\x18\xe7\x03 \x01(\x0b\x32/.perfetto.protos.SchedSwitchWithCtrsFtraceEventH\x00\x12\x45\n\x0fgpu_work_period\x18\xe8\x03 \x01(\x0b\x32).perfetto.protos.GpuWorkPeriodFtraceEventH\x00\x12<\n\nrpm_status\x18\xe9\x03 \x01(\x0b\x32%.perfetto.protos.RpmStatusFtraceEventH\x00\x12M\n\x13panel_write_generic\x18\xea\x03 \x01(\x0b\x32-.perfetto.protos.PanelWriteGenericFtraceEventH\x00\x12K\n\x12sched_migrate_task\x18\xeb\x03 \x01(\x0b\x32,.perfetto.protos.SchedMigrateTaskFtraceEventH\x00\x12S\n\x17\x64pu_dsi_cmd_fifo_status\x18\xec\x03 \x01(\x0b\x32/.perfetto.protos.DpuDsiCmdFifoStatusFtraceEventH\x00\x12;\n\ndpu_dsi_rx\x18\xed\x03 \x01(\x0b\x32$.perfetto.protos.DpuDsiRxFtraceEventH\x00\x12;\n\ndpu_dsi_tx\x18\xee\x03 \x01(\x0b\x32$.perfetto.protos.DpuDsiTxFtraceEventH\x00\x12K\n\x12\x66\x32\x66s_background_gc\x18\xef\x03 \x01(\x0b\x32,.perfetto.protos.F2fsBackgroundGcFtraceEventH\x00\x12\x41\n\rf2fs_gc_begin\x18\xf0\x03 \x01(\x0b\x32\'.perfetto.protos.F2fsGcBeginFtraceEventH\x00\x12=\n\x0b\x66\x32\x66s_gc_end\x18\xf1\x03 \x01(\x0b\x32%.perfetto.protos.F2fsGcEndFtraceEventH\x00\x12G\n\x10\x66\x61strpc_dma_free\x18\xf2\x03 \x01(\x0b\x32*.perfetto.protos.FastrpcDmaFreeFtraceEventH\x00\x12I\n\x11\x66\x61strpc_dma_alloc\x18\xf3\x03 \x01(\x0b\x32+.perfetto.protos.FastrpcDmaAllocFtraceEventH\x00\x12I\n\x11\x66\x61strpc_dma_unmap\x18\xf4\x03 \x01(\x0b\x32+.perfetto.protos.FastrpcDmaUnmapFtraceEventH\x00\x12\x45\n\x0f\x66\x61strpc_dma_map\x18\xf5\x03 \x01(\x0b\x32).perfetto.protos.FastrpcDmaMapFtraceEventH\x00\x12G\n\x10google_icc_event\x18\xf6\x03 \x01(\x0b\x32*.perfetto.protos.GoogleIccEventFtraceEventH\x00\x12G\n\x10google_irm_event\x18\xf7\x03 \x01(\x0b\x32*.perfetto.protos.GoogleIrmEventFtraceEventH\x00\x12V\n\x18\x64\x65vice_pm_callback_start\x18\xf8\x03 \x01(\x0b\x32\x31.perfetto.protos.DevicePmCallbackStartFtraceEventH\x00\x12R\n\x16\x64\x65vice_pm_callback_end\x18\xf9\x03 \x01(\x0b\x32/.perfetto.protos.DevicePmCallbackEndFtraceEventH\x00\x12V\n\x18thermal_exynos_acpm_bulk\x18\xfa\x03 \x01(\x0b\x32\x31.perfetto.protos.ThermalExynosAcpmBulkFtraceEventH\x00\x12g\n!thermal_exynos_acpm_high_overhead\x18\xfb\x03 \x01(\x0b\x32\x39.perfetto.protos.ThermalExynosAcpmHighOverheadFtraceEventH\x00\x12<\n\ndcvsh_freq\x18\xfc\x03 \x01(\x0b\x32%.perfetto.protos.DcvshFreqFtraceEventH\x00\x12K\n\x12kgsl_gpu_frequency\x18\xfd\x03 \x01(\x0b\x32,.perfetto.protos.KgslGpuFrequencyFtraceEventH\x00\x12\x84\x01\n2mali_mali_PM_MCU_HCTL_CORES_DOWN_SCALE_NOTIFY_PEND\x18\xfe\x03 \x01(\x0b\x32\x45.perfetto.protos.MaliMaliPMMCUHCTLCORESDOWNSCALENOTIFYPENDFtraceEventH\x00\x12p\n\'mali_mali_PM_MCU_HCTL_CORES_NOTIFY_PEND\x18\xff\x03 \x01(\x0b\x32<.perfetto.protos.MaliMaliPMMCUHCTLCORESNOTIFYPENDFtraceEventH\x00\x12r\n(mali_mali_PM_MCU_HCTL_CORE_INACTIVE_PEND\x18\x80\x04 \x01(\x0b\x32=.perfetto.protos.MaliMaliPMMCUHCTLCOREINACTIVEPENDFtraceEventH\x00\x12j\n$mali_mali_PM_MCU_HCTL_MCU_ON_RECHECK\x18\x81\x04 \x01(\x0b\x32\x39.perfetto.protos.MaliMaliPMMCUHCTLMCUONRECHECKFtraceEventH\x00\x12w\n+mali_mali_PM_MCU_HCTL_SHADERS_CORE_OFF_PEND\x18\x82\x04 \x01(\x0b\x32?.perfetto.protos.MaliMaliPMMCUHCTLSHADERSCOREOFFPENDFtraceEventH\x00\x12n\n&mali_mali_PM_MCU_HCTL_SHADERS_PEND_OFF\x18\x83\x04 \x01(\x0b\x32;.perfetto.protos.MaliMaliPMMCUHCTLSHADERSPENDOFFFtraceEventH\x00\x12l\n%mali_mali_PM_MCU_HCTL_SHADERS_PEND_ON\x18\x84\x04 \x01(\x0b\x32:.perfetto.protos.MaliMaliPMMCUHCTLSHADERSPENDONFtraceEventH\x00\x12p\n\'mali_mali_PM_MCU_HCTL_SHADERS_READY_OFF\x18\x85\x04 \x01(\x0b\x32<.perfetto.protos.MaliMaliPMMCUHCTLSHADERSREADYOFFFtraceEventH\x00\x12V\n\x19mali_mali_PM_MCU_IN_SLEEP\x18\x86\x04 \x01(\x0b\x32\x30.perfetto.protos.MaliMaliPMMCUINSLEEPFtraceEventH\x00\x12M\n\x14mali_mali_PM_MCU_OFF\x18\x87\x04 \x01(\x0b\x32,.perfetto.protos.MaliMaliPMMCUOFFFtraceEventH\x00\x12K\n\x13mali_mali_PM_MCU_ON\x18\x88\x04 \x01(\x0b\x32+.perfetto.protos.MaliMaliPMMCUONFtraceEventH\x00\x12s\n)mali_mali_PM_MCU_ON_CORE_ATTR_UPDATE_PEND\x18\x89\x04 \x01(\x0b\x32=.perfetto.protos.MaliMaliPMMCUONCOREATTRUPDATEPENDFtraceEventH\x00\x12h\n#mali_mali_PM_MCU_ON_GLB_REINIT_PEND\x18\x8a\x04 \x01(\x0b\x32\x38.perfetto.protos.MaliMaliPMMCUONGLBREINITPENDFtraceEventH\x00\x12T\n\x18mali_mali_PM_MCU_ON_HALT\x18\x8b\x04 \x01(\x0b\x32/.perfetto.protos.MaliMaliPMMCUONHALTFtraceEventH\x00\x12\x65\n!mali_mali_PM_MCU_ON_HWCNT_DISABLE\x18\x8c\x04 \x01(\x0b\x32\x37.perfetto.protos.MaliMaliPMMCUONHWCNTDISABLEFtraceEventH\x00\x12\x63\n mali_mali_PM_MCU_ON_HWCNT_ENABLE\x18\x8d\x04 \x01(\x0b\x32\x36.perfetto.protos.MaliMaliPMMCUONHWCNTENABLEFtraceEventH\x00\x12]\n\x1dmali_mali_PM_MCU_ON_PEND_HALT\x18\x8e\x04 \x01(\x0b\x32\x33.perfetto.protos.MaliMaliPMMCUONPENDHALTFtraceEventH\x00\x12_\n\x1emali_mali_PM_MCU_ON_PEND_SLEEP\x18\x8f\x04 \x01(\x0b\x32\x34.perfetto.protos.MaliMaliPMMCUONPENDSLEEPFtraceEventH\x00\x12g\n\"mali_mali_PM_MCU_ON_SLEEP_INITIATE\x18\x90\x04 \x01(\x0b\x32\x38.perfetto.protos.MaliMaliPMMCUONSLEEPINITIATEFtraceEventH\x00\x12V\n\x19mali_mali_PM_MCU_PEND_OFF\x18\x91\x04 \x01(\x0b\x32\x30.perfetto.protos.MaliMaliPMMCUPENDOFFFtraceEventH\x00\x12\x61\n\x1fmali_mali_PM_MCU_PEND_ON_RELOAD\x18\x92\x04 \x01(\x0b\x32\x35.perfetto.protos.MaliMaliPMMCUPENDONRELOADFtraceEventH\x00\x12Z\n\x1bmali_mali_PM_MCU_POWER_DOWN\x18\x93\x04 \x01(\x0b\x32\x32.perfetto.protos.MaliMaliPMMCUPOWERDOWNFtraceEventH\x00\x12Z\n\x1bmali_mali_PM_MCU_RESET_WAIT\x18\x94\x04 \x01(\x0b\x32\x32.perfetto.protos.MaliMaliPMMCURESETWAITFtraceEventH\x00\x12\x45\n\x0f\x62\x63l_irq_trigger\x18\x95\x04 \x01(\x0b\x32).perfetto.protos.BclIrqTriggerFtraceEventH\x00\x12\\\n\x1bkgsl_adreno_cmdbatch_queued\x18\x96\x04 \x01(\x0b\x32\x34.perfetto.protos.KgslAdrenoCmdbatchQueuedFtraceEventH\x00\x12\x62\n\x1ekgsl_adreno_cmdbatch_submitted\x18\x97\x04 \x01(\x0b\x32\x37.perfetto.protos.KgslAdrenoCmdbatchSubmittedFtraceEventH\x00\x12X\n\x19kgsl_adreno_cmdbatch_sync\x18\x98\x04 \x01(\x0b\x32\x32.perfetto.protos.KgslAdrenoCmdbatchSyncFtraceEventH\x00\x12^\n\x1ckgsl_adreno_cmdbatch_retired\x18\x99\x04 \x01(\x0b\x32\x35.perfetto.protos.KgslAdrenoCmdbatchRetiredFtraceEventH\x00\x12N\n\x14pixel_mm_kswapd_wake\x18\x9a\x04 \x01(\x0b\x32-.perfetto.protos.PixelMmKswapdWakeFtraceEventH\x00\x12N\n\x14pixel_mm_kswapd_done\x18\x9b\x04 \x01(\x0b\x32-.perfetto.protos.PixelMmKswapdDoneFtraceEventH\x00\x12R\n\x16sched_wakeup_task_attr\x18\x9c\x04 \x01(\x0b\x32/.perfetto.protos.SchedWakeupTaskAttrFtraceEventH\x00\x12J\n\x11\x64\x65vfreq_frequency\x18\x9d\x04 \x01(\x0b\x32,.perfetto.protos.DevfreqFrequencyFtraceEventH\x00\x12\x35\n\x0ckprobe_event\x18\x9e\x04 \x01(\x0b\x32\x1c.perfetto.protos.KprobeEventH\x00\x12L\n\x13param_set_value_cpm\x18\x9f\x04 \x01(\x0b\x32,.perfetto.protos.ParamSetValueCpmFtraceEventH\x00\x12=\n\x0b\x64o_sys_open\x18\xa0\x04 \x01(\x0b\x32%.perfetto.protos.DoSysOpenFtraceEventH\x00\x12:\n\topen_exec\x18\xa1\x04 \x01(\x0b\x32$.perfetto.protos.OpenExecFtraceEventH\x00\x12\x43\n\x0e\x62lock_io_start\x18\xa2\x04 \x01(\x0b\x32(.perfetto.protos.BlockIoStartFtraceEventH\x00\x12\x41\n\rblock_io_done\x18\xa3\x04 \x01(\x0b\x32\'.perfetto.protos.BlockIoDoneFtraceEventH\x00\x12N\n\x14mali_gpu_power_state\x18\xa4\x04 \x01(\x0b\x32-.perfetto.protos.MaliGpuPowerStateFtraceEventH\x00\x12P\n\x15\x64pu_disp_dpu_underrun\x18\xa5\x04 \x01(\x0b\x32..perfetto.protos.DpuDispDpuUnderrunFtraceEventH\x00\x12Y\n\x1a\x64pu_disp_vblank_irq_enable\x18\xa6\x04 \x01(\x0b\x32\x32.perfetto.protos.DpuDispVblankIrqEnableFtraceEventH\x00\x12\x42\n\rhrtimer_start\x18\xa7\x04 \x01(\x0b\x32(.perfetto.protos.HrtimerStartFtraceEventH\x00\x12\x44\n\x0ehrtimer_cancel\x18\xa8\x04 \x01(\x0b\x32).perfetto.protos.HrtimerCancelFtraceEventH\x00\x12O\n\x14hrtimer_expire_entry\x18\xa9\x04 \x01(\x0b\x32..perfetto.protos.HrtimerExpireEntryFtraceEventH\x00\x12M\n\x13hrtimer_expire_exit\x18\xaa\x04 \x01(\x0b\x32-.perfetto.protos.HrtimerExpireExitFtraceEventH\x00\x12>\n\x0btimer_start\x18\xab\x04 \x01(\x0b\x32&.perfetto.protos.TimerStartFtraceEventH\x00\x12@\n\x0ctimer_cancel\x18\xac\x04 \x01(\x0b\x32\'.perfetto.protos.TimerCancelFtraceEventH\x00\x12K\n\x12timer_expire_entry\x18\xad\x04 \x01(\x0b\x32,.perfetto.protos.TimerExpireEntryFtraceEventH\x00\x12I\n\x11timer_expire_exit\x18\xae\x04 \x01(\x0b\x32+.perfetto.protos.TimerExpireExitFtraceEventH\x00\x12I\n\x11local_timer_entry\x18\xaf\x04 \x01(\x0b\x32+.perfetto.protos.LocalTimerEntryFtraceEventH\x00\x12G\n\x10local_timer_exit\x18\xb0\x04 \x01(\x0b\x32*.perfetto.protos.LocalTimerExitFtraceEventH\x00\x12K\n\x12\x64wc3_alloc_request\x18\xb1\x04 \x01(\x0b\x32,.perfetto.protos.Dwc3AllocRequestFtraceEventH\x00\x12I\n\x11\x64wc3_complete_trb\x18\xb2\x04 \x01(\x0b\x32+.perfetto.protos.Dwc3CompleteTrbFtraceEventH\x00\x12\x41\n\rdwc3_ctrl_req\x18\xb3\x04 \x01(\x0b\x32\'.perfetto.protos.Dwc3CtrlReqFtraceEventH\x00\x12\x45\n\x0f\x64wc3_ep_dequeue\x18\xb4\x04 \x01(\x0b\x32).perfetto.protos.Dwc3EpDequeueFtraceEventH\x00\x12\x41\n\rdwc3_ep_queue\x18\xb5\x04 \x01(\x0b\x32\'.perfetto.protos.Dwc3EpQueueFtraceEventH\x00\x12<\n\ndwc3_event\x18\xb6\x04 \x01(\x0b\x32%.perfetto.protos.Dwc3EventFtraceEventH\x00\x12I\n\x11\x64wc3_free_request\x18\xb7\x04 \x01(\x0b\x32+.perfetto.protos.Dwc3FreeRequestFtraceEventH\x00\x12J\n\x12\x64wc3_gadget_ep_cmd\x18\xb8\x04 \x01(\x0b\x32+.perfetto.protos.Dwc3GadgetEpCmdFtraceEventH\x00\x12R\n\x16\x64wc3_gadget_ep_disable\x18\xb9\x04 \x01(\x0b\x32/.perfetto.protos.Dwc3GadgetEpDisableFtraceEventH\x00\x12P\n\x15\x64wc3_gadget_ep_enable\x18\xba\x04 \x01(\x0b\x32..perfetto.protos.Dwc3GadgetEpEnableFtraceEventH\x00\x12T\n\x17\x64wc3_gadget_generic_cmd\x18\xbb\x04 \x01(\x0b\x32\x30.perfetto.protos.Dwc3GadgetGenericCmdFtraceEventH\x00\x12O\n\x14\x64wc3_gadget_giveback\x18\xbc\x04 \x01(\x0b\x32..perfetto.protos.Dwc3GadgetGivebackFtraceEventH\x00\x12G\n\x10\x64wc3_prepare_trb\x18\xbd\x04 \x01(\x0b\x32*.perfetto.protos.Dwc3PrepareTrbFtraceEventH\x00\x12<\n\ndwc3_readl\x18\xbe\x04 \x01(\x0b\x32%.perfetto.protos.Dwc3ReadlFtraceEventH\x00\x12>\n\x0b\x64wc3_writel\x18\xbf\x04 \x01(\x0b\x32&.perfetto.protos.Dwc3WritelFtraceEventH\x00\x12G\n\x10\x63ma_alloc_finish\x18\xc0\x04 \x01(\x0b\x32*.perfetto.protos.CmaAllocFinishFtraceEventH\x00\x12h\n\"mm_alloc_contig_migrate_range_info\x18\xc1\x04 \x01(\x0b\x32\x39.perfetto.protos.MmAllocContigMigrateRangeInfoFtraceEventH\x00\x12\x41\n\rhost_ffa_call\x18\xc2\x04 \x01(\x0b\x32\'.perfetto.protos.HostFfaCallFtraceEventH\x00\x12\x45\n\x0f\x64mabuf_rss_stat\x18\xc3\x04 \x01(\x0b\x32).perfetto.protos.DmabufRssStatFtraceEventH\x00\x12>\n\x0biommu_idmap\x18\xc4\x04 \x01(\x0b\x32&.perfetto.protos.IommuIdmapFtraceEventH\x00\x12G\n\x10psci_mem_protect\x18\xc5\x04 \x01(\x0b\x32*.perfetto.protos.PsciMemProtectFtraceEventH\x00\x12Q\n\x15hypervisor_host_hcall\x18\xc6\x04 \x01(\x0b\x32/.perfetto.protos.HypervisorHostHcallFtraceEventH\x00\x12M\n\x13hypervisor_host_smc\x18\xc7\x04 \x01(\x0b\x32-.perfetto.protos.HypervisorHostSmcFtraceEventH\x00\x12M\n\x13hypervisor_hyp_exit\x18\xc8\x04 \x01(\x0b\x32-.perfetto.protos.HypervisorHypExitFtraceEventH\x00\x12S\n\x16hypervisor_iommu_idmap\x18\xc9\x04 \x01(\x0b\x32\x30.perfetto.protos.HypervisorIommuIdmapFtraceEventH\x00\x12\\\n\x1bhypervisor_psci_mem_protect\x18\xca\x04 \x01(\x0b\x32\x34.perfetto.protos.HypervisorPsciMemProtectFtraceEventH\x00\x12X\n\x19hypervisor_host_mem_abort\x18\xcb\x04 \x01(\x0b\x32\x32.perfetto.protos.HypervisorHostMemAbortFtraceEventH\x00\x12O\n\x14hypervisor_hyp_enter\x18\xcc\x04 \x01(\x0b\x32..perfetto.protos.HypervisorHypEnterFtraceEventH\x00\x12\x64\n\x1fhypervisor_iommu_idmap_complete\x18\xcd\x04 \x01(\x0b\x32\x38.perfetto.protos.HypervisorIommuIdmapCompleteFtraceEventH\x00\x12^\n\x1chypervisor_vcpu_illegal_trap\x18\xce\x04 \x01(\x0b\x32\x35.perfetto.protos.HypervisorVcpuIllegalTrapFtraceEventH\x00\x12O\n\x15\x64rm_sched_job_add_dep\x18\xcf\x04 \x01(\x0b\x32-.perfetto.protos.DrmSchedJobAddDepFtraceEventH\x00\x12J\n\x12\x64rm_sched_job_done\x18\xd0\x04 \x01(\x0b\x32+.perfetto.protos.DrmSchedJobDoneFtraceEventH\x00\x12L\n\x13\x64rm_sched_job_queue\x18\xd1\x04 \x01(\x0b\x32,.perfetto.protos.DrmSchedJobQueueFtraceEventH\x00\x12H\n\x11\x64rm_sched_job_run\x18\xd2\x04 \x01(\x0b\x32*.perfetto.protos.DrmSchedJobRunFtraceEventH\x00\x12\\\n\x1b\x64rm_sched_job_unschedulable\x18\xd3\x04 \x01(\x0b\x32\x34.perfetto.protos.DrmSchedJobUnschedulableFtraceEventH\x00\x12Q\n\x15\x66wtp_perfetto_counter\x18\xd4\x04 \x01(\x0b\x32/.perfetto.protos.FwtpPerfettoCounterFtraceEventH\x00\x12T\n\x17scsi_dispatch_cmd_error\x18\xd5\x04 \x01(\x0b\x32\x30.perfetto.protos.ScsiDispatchCmdErrorFtraceEventH\x00\x12X\n\x19scsi_dispatch_cmd_timeout\x18\xd6\x04 \x01(\x0b\x32\x32.perfetto.protos.ScsiDispatchCmdTimeoutFtraceEventH\x00\x12\x43\n\x0escsi_eh_wakeup\x18\xd7\x04 \x01(\x0b\x32(.perfetto.protos.ScsiEhWakeupFtraceEventH\x00\x12M\n\x13\x66wtp_perfetto_slice\x18\xd8\x04 \x01(\x0b\x32-.perfetto.protos.FwtpPerfettoSliceFtraceEventH\x00\x12\x45\n\x0fgpu_power_state\x18\xd9\x04 \x01(\x0b\x32).perfetto.protos.GpuPowerStateFtraceEventH\x00\x12\x44\n\x0egram_collision\x18\xda\x04 \x01(\x0b\x32).perfetto.protos.GramCollisionFtraceEventH\x00\x12R\n\x16\x66\x32\x66s_lock_elapsed_time\x18\xdb\x04 \x01(\x0b\x32/.perfetto.protos.F2fsLockElapsedTimeFtraceEventH\x00\x12M\n\x13sched_group_tracker\x18\xdc\x04 \x01(\x0b\x32-.perfetto.protos.SchedGroupTrackerFtraceEventH\x00\x12[\n\x1b\x64pu_disp_frame_done_timeout\x18\xdd\x04 \x01(\x0b\x32\x33.perfetto.protos.DpuDispFrameDoneTimeoutFtraceEventH\x00\x12]\n\x1c\x64pu_disp_frame_start_timeout\x18\xde\x04 \x01(\x0b\x32\x34.perfetto.protos.DpuDispFrameStartTimeoutFtraceEventH\x00\x12_\n\x1dmm_vmscan_memcg_reclaim_begin\x18\xdf\x04 \x01(\x0b\x32\x35.perfetto.protos.MmVmscanMemcgReclaimBeginFtraceEventH\x00\x12[\n\x1bmm_vmscan_memcg_reclaim_end\x18\xe0\x04 \x01(\x0b\x32\x33.perfetto.protos.MmVmscanMemcgReclaimEndFtraceEventH\x00\x12[\n\x1b\x64pu_disp_frame_done_missing\x18\xe1\x04 \x01(\x0b\x32\x33.perfetto.protos.DpuDispFrameDoneMissingFtraceEventH\x00\x12]\n\x1c\x64pu_disp_frame_start_missing\x18\xe2\x04 \x01(\x0b\x32\x34.perfetto.protos.DpuDispFrameStartMissingFtraceEventH\x00\x12M\n\x13panel_settings_full\x18\xe3\x04 \x01(\x0b\x32-.perfetto.protos.PanelSettingsFullFtraceEventH\x00\x12M\n\x13panel_settings_lite\x18\xe4\x04 \x01(\x0b\x32-.perfetto.protos.PanelSettingsLiteFtraceEventH\x00\x12Y\n\x1a\x64pu_disp_dpu_line_underrun\x18\xe5\x04 \x01(\x0b\x32\x32.perfetto.protos.DpuDispDpuLineUnderrunFtraceEventH\x00\x12P\n\x15psci_domain_idle_exit\x18\xe6\x04 \x01(\x0b\x32..perfetto.protos.PsciDomainIdleExitFtraceEventH\x00\x12R\n\x16psci_domain_idle_enter\x18\xe7\x04 \x01(\x0b\x32/.perfetto.protos.PsciDomainIdleEnterFtraceEventH\x00\x12\x38\n\x08long_irq\x18\xe8\x04 \x01(\x0b\x32#.perfetto.protos.LongIrqFtraceEventH\x00\x12@\n\x0clong_softirq\x18\xe9\x04 \x01(\x0b\x32\'.perfetto.protos.LongSoftirqFtraceEventH\x00\x42\x07\n\x05\x65ventJ\x08\x08\x80\x80\x04\x10\x81\x80\x08\"\xc1\x01\n\x0e\x46traceCpuStats\x12\x0b\n\x03\x63pu\x18\x01 \x01(\x04\x12\x0f\n\x07\x65ntries\x18\x02 \x01(\x04\x12\x0f\n\x07overrun\x18\x03 \x01(\x04\x12\x16\n\x0e\x63ommit_overrun\x18\x04 \x01(\x04\x12\x12\n\nbytes_read\x18\x05 \x01(\x04\x12\x17\n\x0foldest_event_ts\x18\x06 \x01(\x01\x12\x0e\n\x06now_ts\x18\x07 \x01(\x01\x12\x16\n\x0e\x64ropped_events\x18\x08 \x01(\x04\x12\x13\n\x0bread_events\x18\t \x01(\x04\"1\n\x11\x46traceKprobeStats\x12\x0c\n\x04hits\x18\x01 \x01(\x03\x12\x0e\n\x06misses\x18\x02 \x01(\x03\"\xc7\x04\n\x0b\x46traceStats\x12\x31\n\x05phase\x18\x01 \x01(\x0e\x32\".perfetto.protos.FtraceStats.Phase\x12\x32\n\tcpu_stats\x18\x02 \x03(\x0b\x32\x1f.perfetto.protos.FtraceCpuStats\x12\x1d\n\x15kernel_symbols_parsed\x18\x03 \x01(\r\x12\x1d\n\x15kernel_symbols_mem_kb\x18\x04 \x01(\r\x12\x15\n\ratrace_errors\x18\x05 \x01(\t\x12\x1f\n\x17\x65xclusive_feature_error\x18\r \x01(\t\x12\x1d\n\x15unknown_ftrace_events\x18\x06 \x03(\t\x12\x1c\n\x14\x66\x61iled_ftrace_events\x18\x07 \x03(\t\x12\x1e\n\x16preserve_ftrace_buffer\x18\x08 \x01(\x08\x12?\n\x13\x66trace_parse_errors\x18\t \x03(\x0e\x32\".perfetto.protos.FtraceParseStatus\x12\x38\n\x0ckprobe_stats\x18\n \x01(\x0b\x32\".perfetto.protos.FtraceKprobeStats\x12\x1d\n\x15\x63pu_buffer_size_pages\x18\x0b \x01(\r\x12$\n\x1c\x63\x61\x63hed_cpu_buffer_size_pages\x18\x0c \x01(\r\">\n\x05Phase\x12\x0f\n\x0bUNSPECIFIED\x10\x00\x12\x12\n\x0eSTART_OF_TRACE\x10\x01\x12\x10\n\x0c\x45ND_OF_TRACE\x10\x02\"\xb8\x08\n\x11\x46traceEventBundle\x12\x0b\n\x03\x63pu\x18\x01 \x01(\r\x12+\n\x05\x65vent\x18\x02 \x03(\x0b\x32\x1c.perfetto.protos.FtraceEvent\x12\x13\n\x0blost_events\x18\x03 \x01(\x08\x12\x46\n\rcompact_sched\x18\x04 \x01(\x0b\x32/.perfetto.protos.FtraceEventBundle.CompactSched\x12\x32\n\x0c\x66trace_clock\x18\x05 \x01(\x0e\x32\x1c.perfetto.protos.FtraceClock\x12\x18\n\x10\x66trace_timestamp\x18\x06 \x01(\x03\x12\x16\n\x0e\x62oot_timestamp\x18\x07 \x01(\x03\x12=\n\x05\x65rror\x18\x08 \x03(\x0b\x32..perfetto.protos.FtraceEventBundle.FtraceError\x12!\n\x19last_read_event_timestamp\x18\t \x01(\x04\x12%\n\x1dprevious_bundle_end_timestamp\x18\n \x01(\x04\x12\\\n\x19generic_event_descriptors\x18\x0b \x03(\x0b\x32\x39.perfetto.protos.FtraceEventBundle.GenericEventDescriptor\x12\x1e\n\x15\x62roken_abi_trace_page\x18\x80\x04 \x01(\x0c\x1a\xee\x02\n\x0c\x43ompactSched\x12\x14\n\x0cintern_table\x18\x05 \x03(\t\x12\x1c\n\x10switch_timestamp\x18\x01 \x03(\x04\x42\x02\x10\x01\x12\x1d\n\x11switch_prev_state\x18\x02 \x03(\x03\x42\x02\x10\x01\x12\x1b\n\x0fswitch_next_pid\x18\x03 \x03(\x05\x42\x02\x10\x01\x12\x1c\n\x10switch_next_prio\x18\x04 \x03(\x05\x42\x02\x10\x01\x12\"\n\x16switch_next_comm_index\x18\x06 \x03(\rB\x02\x10\x01\x12\x1c\n\x10waking_timestamp\x18\x07 \x03(\x04\x42\x02\x10\x01\x12\x16\n\nwaking_pid\x18\x08 \x03(\x05\x42\x02\x10\x01\x12\x1d\n\x11waking_target_cpu\x18\t \x03(\x05\x42\x02\x10\x01\x12\x17\n\x0bwaking_prio\x18\n \x03(\x05\x42\x02\x10\x01\x12\x1d\n\x11waking_comm_index\x18\x0b \x03(\rB\x02\x10\x01\x12\x1f\n\x13waking_common_flags\x18\x0c \x03(\rB\x02\x10\x01\x1aT\n\x0b\x46traceError\x12\x11\n\ttimestamp\x18\x01 \x01(\x04\x12\x32\n\x06status\x18\x02 \x01(\x0e\x32\".perfetto.protos.FtraceParseStatus\x1aX\n\x16GenericEventDescriptor\x12\x10\n\x08\x66ield_id\x18\x01 \x01(\x05\x12\x12\n\ngroup_name\x18\x03 \x01(\t\x12\x18\n\x10\x65vent_descriptor\x18\x02 \x01(\x0c\"A\n\x18GenericGpuFrequencyEvent\x12\x0e\n\x06gpu_id\x18\x01 \x01(\r\x12\x15\n\rfrequency_khz\x18\x02 \x01(\r\">\n\x1eGenericKernelCpuFrequencyEvent\x12\x0b\n\x03\x63pu\x18\x01 \x01(\x05\x12\x0f\n\x07\x66req_hz\x18\x02 \x01(\x03\"\xa2\x03\n\x1bGenericKernelTaskStateEvent\x12\x0b\n\x03\x63pu\x18\x01 \x01(\x05\x12\x0c\n\x04\x63omm\x18\x02 \x01(\t\x12\x0b\n\x03tid\x18\x03 \x01(\x03\x12I\n\x05state\x18\x04 \x01(\x0e\x32:.perfetto.protos.GenericKernelTaskStateEvent.TaskStateEnum\x12\x0c\n\x04prio\x18\x05 \x01(\x05\"\x81\x02\n\rTaskStateEnum\x12\x16\n\x12TASK_STATE_UNKNOWN\x10\x00\x12\x16\n\x12TASK_STATE_CREATED\x10\x01\x12\x17\n\x13TASK_STATE_RUNNABLE\x10\x02\x12\x16\n\x12TASK_STATE_RUNNING\x10\x03\x12\"\n\x1eTASK_STATE_INTERRUPTIBLE_SLEEP\x10\x04\x12$\n TASK_STATE_UNINTERRUPTIBLE_SLEEP\x10\x05\x12\x16\n\x12TASK_STATE_STOPPED\x10\x06\x12\x13\n\x0fTASK_STATE_DEAD\x10\x07\x12\x18\n\x14TASK_STATE_DESTROYED\x10\x08\"9\n\x1cGenericKernelTaskRenameEvent\x12\x0b\n\x03tid\x18\x01 \x01(\x03\x12\x0c\n\x04\x63omm\x18\x02 \x01(\t\"\xb5\x02\n\x18GenericKernelProcessTree\x12\x44\n\tprocesses\x18\x01 \x03(\x0b\x32\x31.perfetto.protos.GenericKernelProcessTree.Process\x12\x41\n\x07threads\x18\x02 \x03(\x0b\x32\x30.perfetto.protos.GenericKernelProcessTree.Thread\x1aY\n\x06Thread\x12\x0b\n\x03tid\x18\x01 \x01(\x03\x12\x0b\n\x03pid\x18\x02 \x01(\x03\x12\x0c\n\x04\x63omm\x18\x03 \x01(\t\x12\x16\n\x0eis_main_thread\x18\x04 \x01(\x08\x12\x0f\n\x07is_idle\x18\x05 \x01(\x08\x1a\x35\n\x07Process\x12\x0b\n\x03pid\x18\x01 \x01(\x03\x12\x0c\n\x04ppid\x18\x02 \x01(\x03\x12\x0f\n\x07\x63mdline\x18\x03 \x01(\t\"\xa7\x02\n\x0fGpuCounterEvent\x12\x43\n\x12\x63ounter_descriptor\x18\x01 \x01(\x0b\x32%.perfetto.protos.GpuCounterDescriptorH\x00\x12 \n\x16\x63ounter_descriptor_iid\x18\x04 \x01(\x04H\x00\x12=\n\x08\x63ounters\x18\x02 \x03(\x0b\x32+.perfetto.protos.GpuCounterEvent.GpuCounter\x12\x0e\n\x06gpu_id\x18\x03 \x01(\x05\x1aV\n\nGpuCounter\x12\x12\n\ncounter_id\x18\x01 \x01(\r\x12\x13\n\tint_value\x18\x02 \x01(\x03H\x00\x12\x16\n\x0c\x64ouble_value\x18\x03 \x01(\x01H\x00\x42\x07\n\x05valueB\x06\n\x04\x64\x65sc\"~\n\x1cInternedGpuCounterDescriptor\x12\x0b\n\x03iid\x18\x01 \x01(\x04\x12\x41\n\x12\x63ounter_descriptor\x18\x02 \x01(\x0b\x32%.perfetto.protos.GpuCounterDescriptor\x12\x0e\n\x06gpu_id\x18\x03 \x01(\x05\"\x84\x02\n\x06GpuLog\x12\x32\n\x08severity\x18\x01 \x01(\x0e\x32 .perfetto.protos.GpuLog.Severity\x12\x0b\n\x03tag\x18\x02 \x01(\t\x12\x13\n\x0blog_message\x18\x03 \x01(\t\"\xa3\x01\n\x08Severity\x12\x1c\n\x18LOG_SEVERITY_UNSPECIFIED\x10\x00\x12\x18\n\x14LOG_SEVERITY_VERBOSE\x10\x01\x12\x16\n\x12LOG_SEVERITY_DEBUG\x10\x02\x12\x15\n\x11LOG_SEVERITY_INFO\x10\x03\x12\x18\n\x14LOG_SEVERITY_WARNING\x10\x04\x12\x16\n\x12LOG_SEVERITY_ERROR\x10\x05\"=\n\x10GpuMemTotalEvent\x12\x0e\n\x06gpu_id\x18\x01 \x01(\r\x12\x0b\n\x03pid\x18\x02 \x01(\r\x12\x0c\n\x04size\x18\x03 \x01(\x04\"\x8b\x0c\n\x13GpuRenderStageEvent\x12\x10\n\x08\x65vent_id\x18\x01 \x01(\x04\x12\x10\n\x08\x64uration\x18\x02 \x01(\x04\x12\x14\n\x0chw_queue_iid\x18\r \x01(\x04\x12\x11\n\tstage_iid\x18\x0e \x01(\x04\x12\x0e\n\x06gpu_id\x18\x0b \x01(\x05\x12\x0f\n\x07\x63ontext\x18\x05 \x01(\x04\x12\x1c\n\x14render_target_handle\x18\x08 \x01(\x04\x12\x15\n\rsubmission_id\x18\n \x01(\r\x12\x42\n\nextra_data\x18\x06 \x03(\x0b\x32..perfetto.protos.GpuRenderStageEvent.ExtraData\x12\x1a\n\x12render_pass_handle\x18\t \x01(\x04\x12\x1f\n\x17render_pass_instance_id\x18\x10 \x01(\x04\x12!\n\x19render_subpass_index_mask\x18\x0f \x03(\x04\x12\x1d\n\x15\x63ommand_buffer_handle\x18\x0c \x01(\x04\x12\x0e\n\x04name\x18\x11 \x01(\tH\x00\x12\x12\n\x08name_iid\x18\x14 \x01(\x04H\x00\x12\x16\n\x0e\x65vent_wait_ids\x18\x12 \x03(\x04\x12\x12\n\nkernel_iid\x18\x13 \x01(\x04\x12H\n\x06launch\x18\x15 \x01(\x0b\x32\x38.perfetto.protos.GpuRenderStageEvent.ComputeKernelLaunch\x12O\n\x0especifications\x18\x07 \x01(\x0b\x32\x33.perfetto.protos.GpuRenderStageEvent.SpecificationsB\x02\x18\x01\x12\x17\n\x0bhw_queue_id\x18\x03 \x01(\x05\x42\x02\x18\x01\x12\x14\n\x08stage_id\x18\x04 \x01(\x05\x42\x02\x18\x01\x1a(\n\tExtraData\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t\x1a\'\n\x04\x44im3\x12\t\n\x01x\x18\x01 \x01(\r\x12\t\n\x01y\x18\x02 \x01(\r\x12\t\n\x01z\x18\x03 \x01(\r\x1a\xc3\x01\n\x0f\x45xtraComputeArg\x12\x12\n\x08name_iid\x18\x01 \x01(\x04H\x00\x12\x0e\n\x04name\x18\x02 \x01(\tH\x00\x12\x13\n\tint_value\x18\x03 \x01(\x03H\x01\x12\x14\n\nuint_value\x18\x04 \x01(\x04H\x01\x12\x16\n\x0c\x64ouble_value\x18\x05 \x01(\x01H\x01\x12\x16\n\x0cstring_value\x18\x06 \x01(\tH\x01\x12\x1a\n\x10string_value_iid\x18\x07 \x01(\x04H\x01\x42\x0c\n\nname_fieldB\x07\n\x05value\x1a\xda\x01\n\x13\x43omputeKernelLaunch\x12<\n\tgrid_size\x18\x01 \x01(\x0b\x32).perfetto.protos.GpuRenderStageEvent.Dim3\x12\x41\n\x0eworkgroup_size\x18\x02 \x01(\x0b\x32).perfetto.protos.GpuRenderStageEvent.Dim3\x12\x42\n\x04\x61rgs\x18\x03 \x03(\x0b\x32\x34.perfetto.protos.GpuRenderStageEvent.ExtraComputeArg\x1a\xe9\x02\n\x0eSpecifications\x12U\n\x0c\x63ontext_spec\x18\x01 \x01(\x0b\x32?.perfetto.protos.GpuRenderStageEvent.Specifications.ContextSpec\x12Q\n\x08hw_queue\x18\x02 \x03(\x0b\x32?.perfetto.protos.GpuRenderStageEvent.Specifications.Description\x12N\n\x05stage\x18\x03 \x03(\x0b\x32?.perfetto.protos.GpuRenderStageEvent.Specifications.Description\x1a+\n\x0b\x43ontextSpec\x12\x0f\n\x07\x63ontext\x18\x01 \x01(\x04\x12\x0b\n\x03pid\x18\x02 \x01(\x05\x1a\x30\n\x0b\x44\x65scription\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x13\n\x0b\x64\x65scription\x18\x02 \x01(\t*\x04\x08\x64\x10\x65\x42\x0c\n\nname_field\"\xbd\x01\n\x17InternedGraphicsContext\x12\x0b\n\x03iid\x18\x01 \x01(\x04\x12\x0b\n\x03pid\x18\x02 \x01(\x05\x12\x39\n\x03\x61pi\x18\x03 \x01(\x0e\x32,.perfetto.protos.InternedGraphicsContext.Api\"M\n\x03\x41pi\x12\r\n\tUNDEFINED\x10\x00\x12\x0b\n\x07OPEN_GL\x10\x01\x12\n\n\x06VULKAN\x10\x02\x12\x0b\n\x07OPEN_CL\x10\x03\x12\x08\n\x04\x43UDA\x10\x04\x12\x07\n\x03HIP\x10\x05\"\xee\x01\n#InternedGpuRenderStageSpecification\x12\x0b\n\x03iid\x18\x01 \x01(\x04\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x13\n\x0b\x64\x65scription\x18\x03 \x01(\t\x12Z\n\x08\x63\x61tegory\x18\x04 \x01(\x0e\x32H.perfetto.protos.InternedGpuRenderStageSpecification.RenderStageCategory\";\n\x13RenderStageCategory\x12\t\n\x05OTHER\x10\x00\x12\x0c\n\x08GRAPHICS\x10\x01\x12\x0b\n\x07\x43OMPUTE\x10\x02\"\x9c\x01\n\x15InternedComputeKernel\x12\x0b\n\x03iid\x18\x01 \x01(\x04\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x16\n\x0e\x64\x65mangled_name\x18\x03 \x01(\t\x12\x0c\n\x04\x61rch\x18\x04 \x01(\t\x12\x42\n\x04\x61rgs\x18\x05 \x03(\x0b\x32\x34.perfetto.protos.GpuRenderStageEvent.ExtraComputeArg\"3\n\x16InternedComputeArgName\x12\x0b\n\x03iid\x18\x01 \x01(\x04\x12\x0c\n\x04name\x18\x02 \x01(\t\"\xbb\x03\n\x0eVulkanApiEvent\x12\\\n\x1avk_debug_utils_object_name\x18\x01 \x01(\x0b\x32\x36.perfetto.protos.VulkanApiEvent.VkDebugUtilsObjectNameH\x00\x12H\n\x0fvk_queue_submit\x18\x02 \x01(\x0b\x32-.perfetto.protos.VulkanApiEvent.VkQueueSubmitH\x00\x1ar\n\x16VkDebugUtilsObjectName\x12\x0b\n\x03pid\x18\x01 \x01(\r\x12\x11\n\tvk_device\x18\x02 \x01(\x04\x12\x13\n\x0bobject_type\x18\x03 \x01(\x05\x12\x0e\n\x06object\x18\x04 \x01(\x04\x12\x13\n\x0bobject_name\x18\x05 \x01(\t\x1a\x83\x01\n\rVkQueueSubmit\x12\x13\n\x0b\x64uration_ns\x18\x01 \x01(\x04\x12\x0b\n\x03pid\x18\x02 \x01(\r\x12\x0b\n\x03tid\x18\x03 \x01(\r\x12\x10\n\x08vk_queue\x18\x04 \x01(\x04\x12\x1a\n\x12vk_command_buffers\x18\x05 \x03(\x04\x12\x15\n\rsubmission_id\x18\x06 \x01(\rB\x07\n\x05\x65vent\"z\n\x1bVulkanMemoryEventAnnotation\x12\x0f\n\x07key_iid\x18\x01 \x01(\x04\x12\x13\n\tint_value\x18\x02 \x01(\x03H\x00\x12\x16\n\x0c\x64ouble_value\x18\x03 \x01(\x01H\x00\x12\x14\n\nstring_iid\x18\x04 \x01(\x04H\x00\x42\x07\n\x05value\"\xe8\x06\n\x11VulkanMemoryEvent\x12\x39\n\x06source\x18\x01 \x01(\x0e\x32).perfetto.protos.VulkanMemoryEvent.Source\x12?\n\toperation\x18\x02 \x01(\x0e\x32,.perfetto.protos.VulkanMemoryEvent.Operation\x12\x11\n\ttimestamp\x18\x03 \x01(\x03\x12\x0b\n\x03pid\x18\x04 \x01(\r\x12\x16\n\x0ememory_address\x18\x05 \x01(\x06\x12\x13\n\x0bmemory_size\x18\x06 \x01(\x04\x12\x12\n\ncaller_iid\x18\x07 \x01(\x04\x12L\n\x10\x61llocation_scope\x18\x08 \x01(\x0e\x32\x32.perfetto.protos.VulkanMemoryEvent.AllocationScope\x12\x41\n\x0b\x61nnotations\x18\t \x03(\x0b\x32,.perfetto.protos.VulkanMemoryEventAnnotation\x12\x0e\n\x06\x64\x65vice\x18\x10 \x01(\x06\x12\x15\n\rdevice_memory\x18\x11 \x01(\x06\x12\x13\n\x0bmemory_type\x18\x12 \x01(\r\x12\x0c\n\x04heap\x18\x13 \x01(\r\x12\x15\n\robject_handle\x18\x14 \x01(\x06\"\x85\x01\n\x06Source\x12\x16\n\x12SOURCE_UNSPECIFIED\x10\x00\x12\x11\n\rSOURCE_DRIVER\x10\x01\x12\x11\n\rSOURCE_DEVICE\x10\x02\x12\x18\n\x14SOURCE_DEVICE_MEMORY\x10\x03\x12\x11\n\rSOURCE_BUFFER\x10\x04\x12\x10\n\x0cSOURCE_IMAGE\x10\x05\"u\n\tOperation\x12\x12\n\x0eOP_UNSPECIFIED\x10\x00\x12\r\n\tOP_CREATE\x10\x01\x12\x0e\n\nOP_DESTROY\x10\x02\x12\x0b\n\x07OP_BIND\x10\x03\x12\x14\n\x10OP_DESTROY_BOUND\x10\x04\x12\x12\n\x0eOP_ANNOTATIONS\x10\x05\"\x84\x01\n\x0f\x41llocationScope\x12\x15\n\x11SCOPE_UNSPECIFIED\x10\x00\x12\x11\n\rSCOPE_COMMAND\x10\x01\x12\x10\n\x0cSCOPE_OBJECT\x10\x02\x12\x0f\n\x0bSCOPE_CACHE\x10\x03\x12\x10\n\x0cSCOPE_DEVICE\x10\x04\x12\x12\n\x0eSCOPE_INSTANCE\x10\x05\"*\n\x0eInternedString\x12\x0b\n\x03iid\x18\x01 \x01(\x04\x12\x0b\n\x03str\x18\x02 \x01(\x0c\"L\n\x04Line\x12\x15\n\rfunction_name\x18\x01 \x01(\t\x12\x18\n\x10source_file_name\x18\x02 \x01(\t\x12\x13\n\x0bline_number\x18\x03 \x01(\r\"G\n\x0e\x41\x64\x64ressSymbols\x12\x0f\n\x07\x61\x64\x64ress\x18\x01 \x01(\x04\x12$\n\x05lines\x18\x02 \x03(\x0b\x32\x15.perfetto.protos.Line\"i\n\rModuleSymbols\x12\x0c\n\x04path\x18\x01 \x01(\t\x12\x10\n\x08\x62uild_id\x18\x02 \x01(\t\x12\x38\n\x0f\x61\x64\x64ress_symbols\x18\x03 \x03(\x0b\x32\x1f.perfetto.protos.AddressSymbols\"\x9c\x01\n\x07Mapping\x12\x0b\n\x03iid\x18\x01 \x01(\x04\x12\x10\n\x08\x62uild_id\x18\x02 \x01(\x04\x12\x14\n\x0c\x65xact_offset\x18\x08 \x01(\x04\x12\x14\n\x0cstart_offset\x18\x03 \x01(\x04\x12\r\n\x05start\x18\x04 \x01(\x04\x12\x0b\n\x03\x65nd\x18\x05 \x01(\x04\x12\x11\n\tload_bias\x18\x06 \x01(\x04\x12\x17\n\x0fpath_string_ids\x18\x07 \x03(\x04\"\xce\x02\n\x05\x46rame\x12\x0b\n\x03iid\x18\x01 \x01(\x04\x12\x18\n\x10\x66unction_name_id\x18\x02 \x01(\x04\x12\x12\n\nmapping_id\x18\x03 \x01(\x04\x12\x0e\n\x06rel_pc\x18\x04 \x01(\x04\x12\x17\n\x0fsource_path_iid\x18\x05 \x01(\x04\x12\x13\n\x0bline_number\x18\x06 \x01(\r\x12+\n\x04kind\x18\x07 \x01(\x0e\x32\x1b.perfetto.protos.Frame.KindH\x00\x12\x12\n\x08kind_str\x18\x08 \x01(\tH\x00\"}\n\x04Kind\x12\x10\n\x0cKIND_UNKNOWN\x10\x00\x12\x0f\n\x0bKIND_NATIVE\x10\x01\x12\x0f\n\x0bKIND_KERNEL\x10\x02\x12\x14\n\x10KIND_INTERPRETED\x10\x03\x12\x0c\n\x08KIND_JIT\x10\x04\x12\x0b\n\x07KIND_GC\x10\x05\x12\x10\n\x0cKIND_RUNTIME\x10\x06\x42\x0c\n\nkind_field\"+\n\tCallstack\x12\x0b\n\x03iid\x18\x01 \x01(\x04\x12\x11\n\tframe_ids\x18\x02 \x03(\x04\"\x93\x01\n\x0fInlineCallstack\x12\x36\n\x06\x66rames\x18\x01 \x03(\x0b\x32&.perfetto.protos.InlineCallstack.Frame\x1aH\n\x05\x46rame\x12\x15\n\rfunction_name\x18\x01 \x01(\t\x12\x13\n\x0bsource_file\x18\x02 \x01(\t\x12\x13\n\x0bline_number\x18\x03 \x01(\r\"\x80\r\n\x0bStackSample\x12@\n\x0ctask_context\x18\x01 \x01(\x0b\x32(.perfetto.protos.StackSample.TaskContextH\x00\x12\x1a\n\x10task_context_iid\x18\x02 \x01(\x04H\x00\x12J\n\x11\x65xecution_context\x18\x03 \x01(\x0b\x32-.perfetto.protos.StackSample.ExecutionContextH\x01\x12\x1f\n\x15\x65xecution_context_iid\x18\x04 \x01(\x04H\x01\x12\x35\n\tcallstack\x18\x05 \x01(\x0b\x32 .perfetto.protos.InlineCallstackH\x02\x12\x17\n\rcallstack_iid\x18\x06 \x01(\x04H\x02\x12\x16\n\x0cunwind_error\x18\x07 \x01(\tH\x03\x12\x1a\n\x10unwind_error_iid\x18\x08 \x01(\x04H\x03\x12L\n\x12primary_descriptor\x18\t \x01(\x0b\x32..perfetto.protos.StackSample.CounterDescriptorH\x04\x12 \n\x16primary_descriptor_iid\x18\n \x01(\x04H\x04\x12\x16\n\x0eprimary_weight\x18\x0b \x01(\x04\x12L\n\x14\x66ollower_descriptors\x18\x0c \x03(\x0b\x32..perfetto.protos.StackSample.CounterDescriptor\x12$\n\x18\x66ollower_descriptor_iids\x18\r \x03(\x04\x42\x02\x10\x01\x12\x1c\n\x10\x66ollower_weights\x18\x0e \x03(\x04\x42\x02\x10\x01\x1a\x46\n\x0bTaskContext\x12\x0b\n\x03iid\x18\x01 \x01(\x04\x12\x0b\n\x03pid\x18\x02 \x01(\r\x12\x0b\n\x03tid\x18\x03 \x01(\r\x12\x10\n\x08\x61sync_id\x18\x04 \x01(\x04\x1aU\n\x16\x41syncContextDescriptor\x12\x0b\n\x03iid\x18\x01 \x01(\x04\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x0c\n\x04kind\x18\x03 \x01(\t\x12\x12\n\nparent_iid\x18\x04 \x01(\x04\x1a]\n\x10\x45xecutionContext\x12\x0b\n\x03iid\x18\x01 \x01(\x04\x12\x0b\n\x03\x63pu\x18\x02 \x01(\r\x12/\n\x04mode\x18\x03 \x01(\x0e\x32!.perfetto.protos.StackSample.Mode\x1a\xb7\x02\n\x11\x43ounterDescriptor\x12\x0b\n\x03iid\x18\x01 \x01(\x04\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x31\n\x04unit\x18\x03 \x01(\x0e\x32!.perfetto.protos.StackSample.UnitH\x00\x12\x12\n\x08unit_str\x18\x04 \x01(\tH\x00\x12\x17\n\x0funit_multiplier\x18\x05 \x01(\x04\x12\x13\n\x0b\x64\x65scription\x18\x06 \x01(\t\x12\x43\n\x05scope\x18\x07 \x01(\x0e\x32\x34.perfetto.protos.StackSample.CounterDescriptor.Scope\"?\n\x05Scope\x12\x15\n\x11SCOPE_UNSPECIFIED\x10\x00\x12\x10\n\x0cSCOPE_GLOBAL\x10\x01\x12\r\n\tSCOPE_CPU\x10\x02\x42\x0c\n\nunit_field\"y\n\x04Mode\x12\x10\n\x0cMODE_UNKNOWN\x10\x00\x12\r\n\tMODE_USER\x10\x01\x12\x0f\n\x0bMODE_KERNEL\x10\x02\x12\x13\n\x0fMODE_HYPERVISOR\x10\x03\x12\x13\n\x0fMODE_GUEST_USER\x10\x04\x12\x15\n\x11MODE_GUEST_KERNEL\x10\x05\"\xde\x01\n\x04Unit\x12\x14\n\x10UNIT_UNSPECIFIED\x10\x00\x12\x14\n\x10UNIT_NANOSECONDS\x10\x01\x12\x13\n\x0fUNIT_CPU_CYCLES\x10\x02\x12\x15\n\x11UNIT_INSTRUCTIONS\x10\x03\x12\x0e\n\nUNIT_BYTES\x10\x04\x12\x14\n\x10UNIT_PAGE_FAULTS\x10\x05\x12\x15\n\x11UNIT_CACHE_MISSES\x10\x06\x12\x19\n\x15UNIT_CACHE_REFERENCES\x10\x07\x12\x16\n\x12UNIT_BRANCH_MISSES\x10\x08\x12\x0e\n\nUNIT_COUNT\x10\tB\x14\n\x12task_context_fieldB\x19\n\x17\x65xecution_context_fieldB\x11\n\x0f\x63\x61llstack_fieldB\x14\n\x12unwind_error_fieldB\x1a\n\x18primary_descriptor_field\"\xbf\x01\n\x13StackSampleDefaults\x12\x0e\n\x06source\x18\x01 \x01(\t\x12J\n\x12primary_descriptor\x18\x02 \x01(\x0b\x32..perfetto.protos.StackSample.CounterDescriptor\x12L\n\x14\x66ollower_descriptors\x18\x03 \x03(\x0b\x32..perfetto.protos.StackSample.CounterDescriptor\"*\n\rHistogramName\x12\x0b\n\x03iid\x18\x01 \x01(\x04\x12\x0c\n\x04name\x18\x02 \x01(\t\"Z\n\x15\x43hromeHistogramSample\x12\x11\n\tname_hash\x18\x01 \x01(\x04\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x0e\n\x06sample\x18\x03 \x01(\x03\x12\x10\n\x08name_iid\x18\x04 \x01(\x04\"\xac\x07\n\x0f\x44\x65\x62ugAnnotation\x12\x12\n\x08name_iid\x18\x01 \x01(\x04H\x00\x12\x0e\n\x04name\x18\n \x01(\tH\x00\x12\x14\n\nbool_value\x18\x02 \x01(\x08H\x01\x12\x14\n\nuint_value\x18\x03 \x01(\x04H\x01\x12\x13\n\tint_value\x18\x04 \x01(\x03H\x01\x12\x16\n\x0c\x64ouble_value\x18\x05 \x01(\x01H\x01\x12\x17\n\rpointer_value\x18\x07 \x01(\x04H\x01\x12\x44\n\x0cnested_value\x18\x08 \x01(\x0b\x32,.perfetto.protos.DebugAnnotation.NestedValueH\x01\x12\x1b\n\x11legacy_json_value\x18\t \x01(\tH\x01\x12\x16\n\x0cstring_value\x18\x06 \x01(\tH\x01\x12\x1a\n\x10string_value_iid\x18\x11 \x01(\x04H\x01\x12\x19\n\x0fproto_type_name\x18\x10 \x01(\tH\x02\x12\x1d\n\x13proto_type_name_iid\x18\r \x01(\x04H\x02\x12\x13\n\x0bproto_value\x18\x0e \x01(\x0c\x12\x36\n\x0c\x64ict_entries\x18\x0b \x03(\x0b\x32 .perfetto.protos.DebugAnnotation\x12\x36\n\x0c\x61rray_values\x18\x0c \x03(\x0b\x32 .perfetto.protos.DebugAnnotation\x1a\xfc\x02\n\x0bNestedValue\x12L\n\x0bnested_type\x18\x01 \x01(\x0e\x32\x37.perfetto.protos.DebugAnnotation.NestedValue.NestedType\x12\x11\n\tdict_keys\x18\x02 \x03(\t\x12\x41\n\x0b\x64ict_values\x18\x03 \x03(\x0b\x32,.perfetto.protos.DebugAnnotation.NestedValue\x12\x42\n\x0c\x61rray_values\x18\x04 \x03(\x0b\x32,.perfetto.protos.DebugAnnotation.NestedValue\x12\x11\n\tint_value\x18\x05 \x01(\x03\x12\x14\n\x0c\x64ouble_value\x18\x06 \x01(\x01\x12\x12\n\nbool_value\x18\x07 \x01(\x08\x12\x14\n\x0cstring_value\x18\x08 \x01(\t\"2\n\nNestedType\x12\x0f\n\x0bUNSPECIFIED\x10\x00\x12\x08\n\x04\x44ICT\x10\x01\x12\t\n\x05\x41RRAY\x10\x02\x42\x0c\n\nname_fieldB\x07\n\x05valueB\x17\n\x15proto_type_descriptor\"0\n\x13\x44\x65\x62ugAnnotationName\x12\x0b\n\x03iid\x18\x01 \x01(\x04\x12\x0c\n\x04name\x18\x02 \x01(\t\"9\n\x1c\x44\x65\x62ugAnnotationValueTypeName\x12\x0b\n\x03iid\x18\x01 \x01(\x04\x12\x0c\n\x04name\x18\x02 \x01(\t\"\x83\x02\n\nLogMessage\x12\x1b\n\x13source_location_iid\x18\x01 \x01(\x04\x12\x10\n\x08\x62ody_iid\x18\x02 \x01(\x04\x12\x32\n\x04prio\x18\x03 \x01(\x0e\x32$.perfetto.protos.LogMessage.Priority\"\x91\x01\n\x08Priority\x12\x14\n\x10PRIO_UNSPECIFIED\x10\x00\x12\x0f\n\x0bPRIO_UNUSED\x10\x01\x12\x10\n\x0cPRIO_VERBOSE\x10\x02\x12\x0e\n\nPRIO_DEBUG\x10\x03\x12\r\n\tPRIO_INFO\x10\x04\x12\r\n\tPRIO_WARN\x10\x05\x12\x0e\n\nPRIO_ERROR\x10\x06\x12\x0e\n\nPRIO_FATAL\x10\x07\"+\n\x0eLogMessageBody\x12\x0b\n\x03iid\x18\x01 \x01(\x04\x12\x0c\n\x04\x62ody\x18\x02 \x01(\t\"M\n\x1aUnsymbolizedSourceLocation\x12\x0b\n\x03iid\x18\x01 \x01(\x04\x12\x12\n\nmapping_id\x18\x02 \x01(\x04\x12\x0e\n\x06rel_pc\x18\x03 \x01(\x04\"\\\n\x0eSourceLocation\x12\x0b\n\x03iid\x18\x01 \x01(\x04\x12\x11\n\tfile_name\x18\x02 \x01(\t\x12\x15\n\rfunction_name\x18\x03 \x01(\t\x12\x13\n\x0bline_number\x18\x04 \x01(\r\"$\n\x15\x43hromeActiveProcesses\x12\x0b\n\x03pid\x18\x01 \x03(\x05\"\xee\x02\n\x1a\x43hromeApplicationStateInfo\x12]\n\x11\x61pplication_state\x18\x01 \x01(\x0e\x32\x42.perfetto.protos.ChromeApplicationStateInfo.ChromeApplicationState\"\xf0\x01\n\x16\x43hromeApplicationState\x12\x1d\n\x19\x41PPLICATION_STATE_UNKNOWN\x10\x00\x12,\n(APPLICATION_STATE_HAS_RUNNING_ACTIVITIES\x10\x01\x12+\n\'APPLICATION_STATE_HAS_PAUSED_ACTIVITIES\x10\x02\x12,\n(APPLICATION_STATE_HAS_STOPPED_ACTIVITIES\x10\x03\x12.\n*APPLICATION_STATE_HAS_DESTROYED_ACTIVITIES\x10\x04\"\xbf\x08\n\x1e\x43hromeCompositorSchedulerState\x12\x44\n\rstate_machine\x18\x01 \x01(\x0b\x32-.perfetto.protos.ChromeCompositorStateMachine\x12$\n\x1cobserving_begin_frame_source\x18\x02 \x01(\x08\x12&\n\x1e\x62\x65gin_impl_frame_deadline_task\x18\x03 \x01(\x08\x12 \n\x18pending_begin_frame_task\x18\x04 \x01(\x08\x12\x33\n+skipped_last_frame_missed_exceeded_deadline\x18\x05 \x01(\x08\x12G\n\rinside_action\x18\x07 \x01(\x0e\x32\x30.perfetto.protos.ChromeCompositorSchedulerAction\x12\x61\n\rdeadline_mode\x18\x08 \x01(\x0e\x32J.perfetto.protos.ChromeCompositorSchedulerState.BeginImplFrameDeadlineMode\x12\x13\n\x0b\x64\x65\x61\x64line_us\x18\t \x01(\x03\x12 \n\x18\x64\x65\x61\x64line_scheduled_at_us\x18\n \x01(\x03\x12\x0e\n\x06now_us\x18\x0b \x01(\x03\x12 \n\x18now_to_deadline_delta_us\x18\x0c \x01(\x03\x12-\n%now_to_deadline_scheduled_at_delta_us\x18\r \x01(\x03\x12\x42\n\x15\x62\x65gin_impl_frame_args\x18\x0e \x01(\x0b\x32#.perfetto.protos.BeginImplFrameArgs\x12L\n\x1a\x62\x65gin_frame_observer_state\x18\x0f \x01(\x0b\x32(.perfetto.protos.BeginFrameObserverState\x12H\n\x18\x62\x65gin_frame_source_state\x18\x10 \x01(\x0b\x32&.perfetto.protos.BeginFrameSourceState\x12K\n\x19\x63ompositor_timing_history\x18\x11 \x01(\x0b\x32(.perfetto.protos.CompositorTimingHistory\"\xbe\x01\n\x1a\x42\x65ginImplFrameDeadlineMode\x12\x1d\n\x19\x44\x45\x41\x44LINE_MODE_UNSPECIFIED\x10\x00\x12\x16\n\x12\x44\x45\x41\x44LINE_MODE_NONE\x10\x01\x12\x1b\n\x17\x44\x45\x41\x44LINE_MODE_IMMEDIATE\x10\x02\x12\x19\n\x15\x44\x45\x41\x44LINE_MODE_REGULAR\x10\x03\x12\x16\n\x12\x44\x45\x41\x44LINE_MODE_LATE\x10\x04\x12\x19\n\x15\x44\x45\x41\x44LINE_MODE_BLOCKED\x10\x05J\x04\x08\x06\x10\x07\"\xfe\x1c\n\x1c\x43hromeCompositorStateMachine\x12M\n\x0bmajor_state\x18\x01 \x01(\x0b\x32\x38.perfetto.protos.ChromeCompositorStateMachine.MajorState\x12M\n\x0bminor_state\x18\x02 \x01(\x0b\x32\x38.perfetto.protos.ChromeCompositorStateMachine.MinorState\x1a\x93\n\n\nMajorState\x12\x45\n\x0bnext_action\x18\x01 \x01(\x0e\x32\x30.perfetto.protos.ChromeCompositorSchedulerAction\x12l\n\x16\x62\x65gin_impl_frame_state\x18\x02 \x01(\x0e\x32L.perfetto.protos.ChromeCompositorStateMachine.MajorState.BeginImplFrameState\x12l\n\x16\x62\x65gin_main_frame_state\x18\x03 \x01(\x0e\x32L.perfetto.protos.ChromeCompositorStateMachine.MajorState.BeginMainFrameState\x12u\n\x1blayer_tree_frame_sink_state\x18\x04 \x01(\x0e\x32P.perfetto.protos.ChromeCompositorStateMachine.MajorState.LayerTreeFrameSinkState\x12p\n\x13\x66orced_redraw_state\x18\x05 \x01(\x0e\x32S.perfetto.protos.ChromeCompositorStateMachine.MajorState.ForcedRedrawOnTimeoutState\"\xa1\x01\n\x13\x42\x65ginImplFrameState\x12 \n\x1c\x42\x45GIN_IMPL_FRAME_UNSPECIFIED\x10\x00\x12\x19\n\x15\x42\x45GIN_IMPL_FRAME_IDLE\x10\x01\x12\'\n#BEGIN_IMPL_FRAME_INSIDE_BEGIN_FRAME\x10\x02\x12$\n BEGIN_IMPL_FRAME_INSIDE_DEADLINE\x10\x03\"\x93\x01\n\x13\x42\x65ginMainFrameState\x12 \n\x1c\x42\x45GIN_MAIN_FRAME_UNSPECIFIED\x10\x00\x12\x19\n\x15\x42\x45GIN_MAIN_FRAME_IDLE\x10\x01\x12\x19\n\x15\x42\x45GIN_MAIN_FRAME_SENT\x10\x02\x12$\n BEGIN_MAIN_FRAME_READY_TO_COMMIT\x10\x03\"\xf4\x01\n\x17LayerTreeFrameSinkState\x12 \n\x1cLAYER_TREE_FRAME_UNSPECIFIED\x10\x00\x12\x19\n\x15LAYER_TREE_FRAME_NONE\x10\x01\x12\x1b\n\x17LAYER_TREE_FRAME_ACTIVE\x10\x02\x12\x1d\n\x19LAYER_TREE_FRAME_CREATING\x10\x03\x12-\n)LAYER_TREE_FRAME_WAITING_FOR_FIRST_COMMIT\x10\x04\x12\x31\n-LAYER_TREE_FRAME_WAITING_FOR_FIRST_ACTIVATION\x10\x05\"\xc7\x01\n\x1a\x46orcedRedrawOnTimeoutState\x12\x1d\n\x19\x46ORCED_REDRAW_UNSPECIFIED\x10\x00\x12\x16\n\x12\x46ORCED_REDRAW_IDLE\x10\x01\x12$\n FORCED_REDRAW_WAITING_FOR_COMMIT\x10\x02\x12(\n$FORCED_REDRAW_WAITING_FOR_ACTIVATION\x10\x03\x12\"\n\x1e\x46ORCED_REDRAW_WAITING_FOR_DRAW\x10\x04\x1a\xa9\x11\n\nMinorState\x12\x14\n\x0c\x63ommit_count\x18\x01 \x01(\x05\x12\x1c\n\x14\x63urrent_frame_number\x18\x02 \x01(\x05\x12*\n\"last_frame_number_submit_performed\x18\x03 \x01(\x05\x12(\n last_frame_number_draw_performed\x18\x04 \x01(\x05\x12/\n\'last_frame_number_begin_main_frame_sent\x18\x05 \x01(\x05\x12\x10\n\x08\x64id_draw\x18\x06 \x01(\x08\x12\x33\n+did_send_begin_main_frame_for_current_frame\x18\x07 \x01(\x08\x12\x36\n.did_notify_begin_main_frame_not_expected_until\x18\x08 \x01(\x08\x12\x35\n-did_notify_begin_main_frame_not_expected_soon\x18\t \x01(\x08\x12+\n#wants_begin_main_frame_not_expected\x18\n \x01(\x08\x12\x1f\n\x17\x64id_commit_during_frame\x18\x0b \x01(\x08\x12,\n$did_invalidate_layer_tree_frame_sink\x18\x0c \x01(\x08\x12)\n!did_perform_impl_side_invalidaion\x18\r \x01(\x08\x12\x19\n\x11\x64id_prepare_tiles\x18\x0e \x01(\x08\x12+\n#consecutive_checkerboard_animations\x18\x0f \x01(\x05\x12\x1d\n\x15pending_submit_frames\x18\x10 \x01(\x05\x12\x38\n0submit_frames_with_current_layer_tree_frame_sink\x18\x11 \x01(\x05\x12\x14\n\x0cneeds_redraw\x18\x12 \x01(\x08\x12\x1b\n\x13needs_prepare_tiles\x18\x13 \x01(\x08\x12\x1e\n\x16needs_begin_main_frame\x18\x14 \x01(\x08\x12\"\n\x1aneeds_one_begin_impl_frame\x18\x15 \x01(\x08\x12\x0f\n\x07visible\x18\x16 \x01(\x08\x12!\n\x19\x62\x65gin_frame_source_paused\x18\x17 \x01(\x08\x12\x10\n\x08\x63\x61n_draw\x18\x18 \x01(\x08\x12\x19\n\x11resourceless_draw\x18\x19 \x01(\x08\x12\x18\n\x10has_pending_tree\x18\x1a \x01(\x08\x12,\n$pending_tree_is_ready_for_activation\x18\x1b \x01(\x08\x12$\n\x1c\x61\x63tive_tree_needs_first_draw\x18\x1c \x01(\x08\x12$\n\x1c\x61\x63tive_tree_is_ready_to_draw\x18\x1d \x01(\x08\x12=\n5did_create_and_initialize_first_layer_tree_frame_sink\x18\x1e \x01(\x08\x12\\\n\rtree_priority\x18\x1f \x01(\x0e\x32\x45.perfetto.protos.ChromeCompositorStateMachine.MinorState.TreePriority\x12i\n\x14scroll_handler_state\x18  \x01(\x0e\x32K.perfetto.protos.ChromeCompositorStateMachine.MinorState.ScrollHandlerState\x12\x35\n-critical_begin_main_frame_to_activate_is_fast\x18! \x01(\x08\x12(\n main_thread_missed_last_deadline\x18\" \x01(\x08\x12 \n\x18video_needs_begin_frames\x18$ \x01(\x08\x12\x1e\n\x16\x64\x65\x66\x65r_begin_main_frame\x18% \x01(\x08\x12\"\n\x1alast_commit_had_no_updates\x18& \x01(\x08\x12\x1e\n\x16\x64id_draw_in_last_frame\x18\' \x01(\x08\x12 \n\x18\x64id_submit_in_last_frame\x18( \x01(\x08\x12$\n\x1cneeds_impl_side_invalidation\x18) \x01(\x08\x12)\n!current_pending_tree_is_impl_side\x18* \x01(\x08\x12+\n#previous_pending_tree_was_impl_side\x18+ \x01(\x08\x12\x35\n-processing_animation_worklets_for_active_tree\x18, \x01(\x08\x12\x36\n.processing_animation_worklets_for_pending_tree\x18- \x01(\x08\x12\x32\n*processing_paint_worklets_for_pending_tree\x18. \x01(\x08\"\xb8\x01\n\x0cTreePriority\x12\x1d\n\x19TREE_PRIORITY_UNSPECIFIED\x10\x00\x12.\n*TREE_PRIORITY_SAME_PRIORITY_FOR_BOTH_TREES\x10\x01\x12+\n\'TREE_PRIORITY_SMOOTHNESS_TAKES_PRIORITY\x10\x02\x12,\n(TREE_PRIORITY_NEW_CONTENT_TAKES_PRIORITY\x10\x03\"\x82\x01\n\x12ScrollHandlerState\x12\x1e\n\x1aSCROLL_HANDLER_UNSPECIFIED\x10\x00\x12!\n\x1dSCROLL_AFFECTS_SCROLL_HANDLER\x10\x01\x12)\n%SCROLL_DOES_NOT_AFFECT_SCROLL_HANDLER\x10\x02J\x04\x08#\x10$\"\xaa\x04\n\x0e\x42\x65ginFrameArgs\x12@\n\x04type\x18\x01 \x01(\x0e\x32\x32.perfetto.protos.BeginFrameArgs.BeginFrameArgsType\x12\x11\n\tsource_id\x18\x02 \x01(\x04\x12\x17\n\x0fsequence_number\x18\x03 \x01(\x04\x12\x15\n\rframe_time_us\x18\x04 \x01(\x03\x12\x13\n\x0b\x64\x65\x61\x64line_us\x18\x05 \x01(\x03\x12\x19\n\x11interval_delta_us\x18\x06 \x01(\x03\x12\x18\n\x10on_critical_path\x18\x07 \x01(\x08\x12\x14\n\x0c\x61nimate_only\x18\x08 \x01(\x08\x12\x1d\n\x13source_location_iid\x18\t \x01(\x04H\x00\x12:\n\x0fsource_location\x18\n \x01(\x0b\x32\x1f.perfetto.protos.SourceLocationH\x00\x12#\n\x1b\x66rames_throttled_since_last\x18\x0c \x01(\x03\"\xa2\x01\n\x12\x42\x65ginFrameArgsType\x12%\n!BEGIN_FRAME_ARGS_TYPE_UNSPECIFIED\x10\x00\x12!\n\x1d\x42\x45GIN_FRAME_ARGS_TYPE_INVALID\x10\x01\x12 \n\x1c\x42\x45GIN_FRAME_ARGS_TYPE_NORMAL\x10\x02\x12 \n\x1c\x42\x45GIN_FRAME_ARGS_TYPE_MISSED\x10\x03\x42\x0e\n\x0c\x63reated_from\"\xc0\x04\n\x12\x42\x65ginImplFrameArgs\x12\x15\n\rupdated_at_us\x18\x01 \x01(\x03\x12\x16\n\x0e\x66inished_at_us\x18\x02 \x01(\x03\x12\x38\n\x05state\x18\x03 \x01(\x0e\x32).perfetto.protos.BeginImplFrameArgs.State\x12\x37\n\x0c\x63urrent_args\x18\x04 \x01(\x0b\x32\x1f.perfetto.protos.BeginFrameArgsH\x00\x12\x34\n\tlast_args\x18\x05 \x01(\x0b\x32\x1f.perfetto.protos.BeginFrameArgsH\x00\x12L\n\x10timestamps_in_us\x18\x06 \x01(\x0b\x32\x32.perfetto.protos.BeginImplFrameArgs.TimestampsInUs\x1a\xc1\x01\n\x0eTimestampsInUs\x12\x16\n\x0einterval_delta\x18\x01 \x01(\x03\x12\x1d\n\x15now_to_deadline_delta\x18\x02 \x01(\x03\x12\x1f\n\x17\x66rame_time_to_now_delta\x18\x03 \x01(\x03\x12$\n\x1c\x66rame_time_to_deadline_delta\x18\x04 \x01(\x03\x12\x0b\n\x03now\x18\x05 \x01(\x03\x12\x12\n\nframe_time\x18\x06 \x01(\x03\x12\x10\n\x08\x64\x65\x61\x64line\x18\x07 \x01(\x03\"8\n\x05State\x12\x18\n\x14\x42\x45GIN_FRAME_FINISHED\x10\x00\x12\x15\n\x11\x42\x45GIN_FRAME_USING\x10\x01\x42\x06\n\x04\x61rgs\"{\n\x17\x42\x65ginFrameObserverState\x12 \n\x18\x64ropped_begin_frame_args\x18\x01 \x01(\x03\x12>\n\x15last_begin_frame_args\x18\x02 \x01(\x0b\x32\x1f.perfetto.protos.BeginFrameArgs\"\x91\x01\n\x15\x42\x65ginFrameSourceState\x12\x11\n\tsource_id\x18\x01 \x01(\r\x12\x0e\n\x06paused\x18\x02 \x01(\x08\x12\x15\n\rnum_observers\x18\x03 \x01(\r\x12>\n\x15last_begin_frame_args\x18\x04 \x01(\x0b\x32\x1f.perfetto.protos.BeginFrameArgs\"\xfc\x02\n\x17\x43ompositorTimingHistory\x12\x39\n1begin_main_frame_queue_critical_estimate_delta_us\x18\x01 \x01(\x03\x12=\n5begin_main_frame_queue_not_critical_estimate_delta_us\x18\x02 \x01(\x03\x12\x43\n;begin_main_frame_start_to_ready_to_commit_estimate_delta_us\x18\x03 \x01(\x03\x12\x35\n-commit_to_ready_to_activate_estimate_delta_us\x18\x04 \x01(\x03\x12\'\n\x1fprepare_tiles_estimate_delta_us\x18\x05 \x01(\x03\x12\"\n\x1a\x61\x63tivate_estimate_delta_us\x18\x06 \x01(\x03\x12\x1e\n\x16\x64raw_estimate_delta_us\x18\x07 \x01(\x03\">\n\x1e\x43hromeContentSettingsEventInfo\x12\x1c\n\x14number_of_exceptions\x18\x01 \x01(\r\"\xe0\x08\n\x13\x43hromeFrameReporter\x12\x39\n\x05state\x18\x01 \x01(\x0e\x32*.perfetto.protos.ChromeFrameReporter.State\x12\x44\n\x06reason\x18\x02 \x01(\x0e\x32\x34.perfetto.protos.ChromeFrameReporter.FrameDropReason\x12\x14\n\x0c\x66rame_source\x18\x03 \x01(\x04\x12\x16\n\x0e\x66rame_sequence\x18\x04 \x01(\x04\x12\x1a\n\x12\x61\x66\x66\x65\x63ts_smoothness\x18\x05 \x01(\x08\x12\x46\n\x0cscroll_state\x18\x06 \x01(\x0e\x32\x30.perfetto.protos.ChromeFrameReporter.ScrollState\x12\x1a\n\x12has_main_animation\x18\x07 \x01(\x08\x12 \n\x18has_compositor_animation\x18\x08 \x01(\x08\x12\x1d\n\x15has_smooth_input_main\x18\t \x01(\x08\x12\x1b\n\x13has_missing_content\x18\n \x01(\x08\x12\x1a\n\x12layer_tree_host_id\x18\x0b \x01(\x04\x12\x18\n\x10has_high_latency\x18\x0c \x01(\x08\x12\x42\n\nframe_type\x18\r \x01(\x0e\x32..perfetto.protos.ChromeFrameReporter.FrameType\x12\'\n\x1fhigh_latency_contribution_stage\x18\x0e \x03(\t\x12#\n\x1b\x63heckerboarded_needs_raster\x18\x0f \x01(\x08\x12#\n\x1b\x63heckerboarded_needs_record\x18\x10 \x01(\x08\x12\x1e\n\x16surface_frame_trace_id\x18\x11 \x01(\x03\x12\x18\n\x10\x64isplay_trace_id\x18\x12 \x01(\x03\"m\n\x05State\x12\x1b\n\x17STATE_NO_UPDATE_DESIRED\x10\x00\x12\x17\n\x13STATE_PRESENTED_ALL\x10\x01\x12\x1b\n\x17STATE_PRESENTED_PARTIAL\x10\x02\x12\x11\n\rSTATE_DROPPED\x10\x03\"~\n\x0f\x46rameDropReason\x12\x16\n\x12REASON_UNSPECIFIED\x10\x00\x12\x1d\n\x19REASON_DISPLAY_COMPOSITOR\x10\x01\x12\x16\n\x12REASON_MAIN_THREAD\x10\x02\x12\x1c\n\x18REASON_CLIENT_COMPOSITOR\x10\x03\"{\n\x0bScrollState\x12\x0f\n\x0bSCROLL_NONE\x10\x00\x12\x16\n\x12SCROLL_MAIN_THREAD\x10\x01\x12\x1c\n\x18SCROLL_COMPOSITOR_THREAD\x10\x02\x12\x11\n\rSCROLL_RASTER\x10\x03\x12\x12\n\x0eSCROLL_UNKNOWN\x10\x04\"%\n\tFrameType\x12\n\n\x06\x46ORKED\x10\x00\x12\x0c\n\x08\x42\x41\x43KFILL\x10\x01:\x02\x18\x01\"\"\n\x12\x43hromeKeyedService\x12\x0c\n\x04name\x18\x01 \x01(\t\"\xf6\r\n\x11\x43hromeLatencyInfo\x12\x10\n\x08trace_id\x18\x01 \x01(\x03\x12\x35\n\x04step\x18\x02 \x01(\x0e\x32\'.perfetto.protos.ChromeLatencyInfo.Step\x12\x1a\n\x12\x66rame_tree_node_id\x18\x03 \x01(\x05\x12H\n\x0e\x63omponent_info\x18\x04 \x03(\x0b\x32\x30.perfetto.protos.ChromeLatencyInfo.ComponentInfo\x12\x14\n\x0cis_coalesced\x18\x05 \x01(\x08\x12\x19\n\x11gesture_scroll_id\x18\x06 \x01(\x03\x12\x10\n\x08touch_id\x18\x07 \x01(\x03\x12@\n\ninput_type\x18\x08 \x01(\x0e\x32,.perfetto.protos.ChromeLatencyInfo.InputType\x1aq\n\rComponentInfo\x12O\n\x0e\x63omponent_type\x18\x01 \x01(\x0e\x32\x37.perfetto.protos.ChromeLatencyInfo.LatencyComponentType\x12\x0f\n\x07time_us\x18\x02 \x01(\x04\"\x92\x03\n\x04Step\x12\x14\n\x10STEP_UNSPECIFIED\x10\x00\x12\x1c\n\x18STEP_SEND_INPUT_EVENT_UI\x10\x03\x12 \n\x1cSTEP_HANDLE_INPUT_EVENT_IMPL\x10\x05\x12(\n$STEP_DID_HANDLE_INPUT_AND_OVERSCROLL\x10\x08\x12 \n\x1cSTEP_HANDLE_INPUT_EVENT_MAIN\x10\x04\x12\"\n\x1eSTEP_MAIN_THREAD_SCROLL_UPDATE\x10\x02\x12\'\n#STEP_HANDLE_INPUT_EVENT_MAIN_COMMIT\x10\x01\x12)\n%STEP_HANDLED_INPUT_EVENT_MAIN_OR_IMPL\x10\t\x12!\n\x1dSTEP_HANDLED_INPUT_EVENT_IMPL\x10\n\x12\x15\n\x11STEP_SWAP_BUFFERS\x10\x06\x12\x16\n\x12STEP_DRAW_AND_SWAP\x10\x07\x12\x1e\n\x1aSTEP_FINISHED_SWAP_BUFFERS\x10\x0b\"\xf5\x05\n\x14LatencyComponentType\x12\x19\n\x15\x43OMPONENT_UNSPECIFIED\x10\x00\x12+\n\'COMPONENT_INPUT_EVENT_LATENCY_BEGIN_RWH\x10\x01\x12\x38\n4COMPONENT_INPUT_EVENT_LATENCY_SCROLL_UPDATE_ORIGINAL\x10\x02\x12>\n:COMPONENT_INPUT_EVENT_LATENCY_FIRST_SCROLL_UPDATE_ORIGINAL\x10\x03\x12*\n&COMPONENT_INPUT_EVENT_LATENCY_ORIGINAL\x10\x04\x12$\n COMPONENT_INPUT_EVENT_LATENCY_UI\x10\x05\x12/\n+COMPONENT_INPUT_EVENT_LATENCY_RENDERER_MAIN\x10\x06\x12:\n6COMPONENT_INPUT_EVENT_LATENCY_RENDERING_SCHEDULED_MAIN\x10\x07\x12:\n6COMPONENT_INPUT_EVENT_LATENCY_RENDERING_SCHEDULED_IMPL\x10\x08\x12:\n6COMPONENT_INPUT_EVENT_LATENCY_SCROLL_UPDATE_LAST_EVENT\x10\t\x12)\n%COMPONENT_INPUT_EVENT_LATENCY_ACK_RWH\x10\n\x12/\n+COMPONENT_INPUT_EVENT_LATENCY_RENDERER_SWAP\x10\x0b\x12/\n+COMPONENT_DISPLAY_COMPOSITOR_RECEIVED_FRAME\x10\x0c\x12)\n%COMPONENT_INPUT_EVENT_GPU_SWAP_BUFFER\x10\r\x12,\n(COMPONENT_INPUT_EVENT_LATENCY_FRAME_SWAP\x10\x0e\"\xac\x01\n\tInputType\x12\x18\n\x14UNSPECIFIED_OR_OTHER\x10\x00\x12\x0f\n\x0bTOUCH_MOVED\x10\x01\x12\x18\n\x14GESTURE_SCROLL_BEGIN\x10\x02\x12\x19\n\x15GESTURE_SCROLL_UPDATE\x10\x03\x12\x16\n\x12GESTURE_SCROLL_END\x10\x04\x12\x0f\n\x0bGESTURE_TAP\x10\x05\x12\x16\n\x12GESTURE_TAP_CANCEL\x10\x06\"\xce\x07\n\x0f\x43hromeLegacyIpc\x12\x44\n\rmessage_class\x18\x01 \x01(\x0e\x32-.perfetto.protos.ChromeLegacyIpc.MessageClass\x12\x14\n\x0cmessage_line\x18\x02 \x01(\r\"\xde\x06\n\x0cMessageClass\x12\x15\n\x11\x43LASS_UNSPECIFIED\x10\x00\x12\x14\n\x10\x43LASS_AUTOMATION\x10\x01\x12\x0f\n\x0b\x43LASS_FRAME\x10\x02\x12\x0e\n\nCLASS_PAGE\x10\x03\x12\x0e\n\nCLASS_VIEW\x10\x04\x12\x10\n\x0c\x43LASS_WIDGET\x10\x05\x12\x0f\n\x0b\x43LASS_INPUT\x10\x06\x12\x0e\n\nCLASS_TEST\x10\x07\x12\x10\n\x0c\x43LASS_WORKER\x10\x08\x12\x0e\n\nCLASS_NACL\x10\t\x12\x15\n\x11\x43LASS_GPU_CHANNEL\x10\n\x12\x0f\n\x0b\x43LASS_MEDIA\x10\x0b\x12\x0f\n\x0b\x43LASS_PPAPI\x10\x0c\x12\x10\n\x0c\x43LASS_CHROME\x10\r\x12\x0e\n\nCLASS_DRAG\x10\x0e\x12\x0f\n\x0b\x43LASS_PRINT\x10\x0f\x12\x13\n\x0f\x43LASS_EXTENSION\x10\x10\x12\x1b\n\x17\x43LASS_TEXT_INPUT_CLIENT\x10\x11\x12\x14\n\x10\x43LASS_BLINK_TEST\x10\x12\x12\x17\n\x13\x43LASS_ACCESSIBILITY\x10\x13\x12\x13\n\x0f\x43LASS_PRERENDER\x10\x14\x12\x14\n\x10\x43LASS_CHROMOTING\x10\x15\x12\x18\n\x14\x43LASS_BROWSER_PLUGIN\x10\x16\x12\x1a\n\x16\x43LASS_ANDROID_WEB_VIEW\x10\x17\x12\x13\n\x0f\x43LASS_NACL_HOST\x10\x18\x12\x19\n\x15\x43LASS_ENCRYPTED_MEDIA\x10\x19\x12\x0e\n\nCLASS_CAST\x10\x1a\x12\x19\n\x15\x43LASS_GIN_JAVA_BRIDGE\x10\x1b\x12!\n\x1d\x43LASS_CHROME_UTILITY_PRINTING\x10\x1c\x12\x13\n\x0f\x43LASS_OZONE_GPU\x10\x1d\x12\x12\n\x0e\x43LASS_WEB_TEST\x10\x1e\x12\x17\n\x13\x43LASS_NETWORK_HINTS\x10\x1f\x12\x1f\n\x1b\x43LASS_EXTENSIONS_GUEST_VIEW\x10 \x12\x14\n\x10\x43LASS_GUEST_VIEW\x10!\x12\x1f\n\x1b\x43LASS_MEDIA_PLAYER_DELEGATE\x10\"\x12\x1a\n\x16\x43LASS_EXTENSION_WORKER\x10#\x12\x1c\n\x18\x43LASS_SUBRESOURCE_FILTER\x10$\x12\x1b\n\x17\x43LASS_UNFREEZABLE_FRAME\x10%\"T\n\x11\x43hromeMessagePump\x12\x1e\n\x16sent_messages_in_queue\x18\x01 \x01(\x08\x12\x1f\n\x17io_handler_location_iid\x18\x02 \x01(\x04\"\xcc\x01\n\x13\x43hromeMojoEventInfo\x12$\n\x1cwatcher_notify_interface_tag\x18\x01 \x01(\t\x12\x10\n\x08ipc_hash\x18\x02 \x01(\r\x12\x1a\n\x12mojo_interface_tag\x18\x03 \x01(\t\x12!\n\x19mojo_interface_method_iid\x18\x04 \x01(\x04\x12\x10\n\x08is_reply\x18\x05 \x01(\x08\x12\x14\n\x0cpayload_size\x18\x06 \x01(\x04\x12\x16\n\x0e\x64\x61ta_num_bytes\x18\x07 \x01(\x04\"~\n\x1c\x43hromeRendererSchedulerState\x12\x32\n\trail_mode\x18\x01 \x01(\x0e\x32\x1f.perfetto.protos.ChromeRAILMode\x12\x17\n\x0fis_backgrounded\x18\x02 \x01(\x08\x12\x11\n\tis_hidden\x18\x03 \x01(\x08\"6\n\x0f\x43hromeUserEvent\x12\x0e\n\x06\x61\x63tion\x18\x01 \x01(\t\x12\x13\n\x0b\x61\x63tion_hash\x18\x02 \x01(\x04\"P\n\x1b\x43hromeWindowHandleEventInfo\x12\x0b\n\x03\x64pi\x18\x01 \x01(\r\x12\x12\n\nmessage_id\x18\x02 \x01(\r\x12\x10\n\x08hwnd_ptr\x18\x03 \x01(\x06\"E\n\nScreenshot\x12\x11\n\tjpg_image\x18\x01 \x01(\x0c\x12\x11\n\tpam_image\x18\x02 \x01(\x0c\x12\x11\n\tppm_image\x18\x03 \x01(\x0c\"(\n\rTaskExecution\x12\x17\n\x0fposted_from_iid\x18\x01 \x01(\x04\"\xf8\x1a\n\nTrackEvent\x12\x15\n\rcategory_iids\x18\x03 \x03(\x04\x12\x12\n\ncategories\x18\x16 \x03(\t\x12\x12\n\x08name_iid\x18\n \x01(\x04H\x00\x12\x0e\n\x04name\x18\x17 \x01(\tH\x00\x12.\n\x04type\x18\t \x01(\x0e\x32 .perfetto.protos.TrackEvent.Type\x12\x12\n\ntrack_uuid\x18\x0b \x01(\x04\x12\x17\n\rcounter_value\x18\x1e \x01(\x03H\x01\x12\x1e\n\x14\x64ouble_counter_value\x18, \x01(\x01H\x01\x12!\n\x19\x65xtra_counter_track_uuids\x18\x1f \x03(\x04\x12\x1c\n\x14\x65xtra_counter_values\x18\x0c \x03(\x03\x12(\n extra_double_counter_track_uuids\x18- \x03(\x04\x12#\n\x1b\x65xtra_double_counter_values\x18. \x03(\x01\x12\x18\n\x0c\x66low_ids_old\x18$ \x03(\x04\x42\x02\x18\x01\x12\x10\n\x08\x66low_ids\x18/ \x03(\x06\x12$\n\x18terminating_flow_ids_old\x18* \x03(\x04\x42\x02\x18\x01\x12\x1c\n\x14terminating_flow_ids\x18\x30 \x03(\x06\x12\x18\n\x0e\x63orrelation_id\x18\x34 \x01(\x04H\x02\x12\x1c\n\x12\x63orrelation_id_str\x18\x35 \x01(\tH\x02\x12 \n\x16\x63orrelation_id_str_iid\x18\x36 \x01(\x04H\x02\x12@\n\tcallstack\x18\x37 \x01(\x0b\x32+.perfetto.protos.TrackEvent.InlineCallstackH\x03\x12\x17\n\rcallstack_iid\x18\x38 \x01(\x04H\x03\x12\x18\n\x10\x63\x61llstack_weight\x18\x39 \x01(\x01\x12;\n\x11\x64\x65\x62ug_annotations\x18\x04 \x03(\x0b\x32 .perfetto.protos.DebugAnnotation\x12\x36\n\x0etask_execution\x18\x05 \x01(\x0b\x32\x1e.perfetto.protos.TaskExecution\x12\x30\n\x0blog_message\x18\x15 \x01(\x0b\x32\x1b.perfetto.protos.LogMessage\x12K\n\x12\x63\x63_scheduler_state\x18\x18 \x01(\x0b\x32/.perfetto.protos.ChromeCompositorSchedulerState\x12;\n\x11\x63hrome_user_event\x18\x19 \x01(\x0b\x32 .perfetto.protos.ChromeUserEvent\x12\x41\n\x14\x63hrome_keyed_service\x18\x1a \x01(\x0b\x32#.perfetto.protos.ChromeKeyedService\x12;\n\x11\x63hrome_legacy_ipc\x18\x1b \x01(\x0b\x32 .perfetto.protos.ChromeLegacyIpc\x12G\n\x17\x63hrome_histogram_sample\x18\x1c \x01(\x0b\x32&.perfetto.protos.ChromeHistogramSample\x12?\n\x13\x63hrome_latency_info\x18\x1d \x01(\x0b\x32\".perfetto.protos.ChromeLatencyInfo\x12G\n\x15\x63hrome_frame_reporter\x18  \x01(\x0b\x32$.perfetto.protos.ChromeFrameReporterB\x02\x18\x01\x12R\n\x1d\x63hrome_application_state_info\x18\' \x01(\x0b\x32+.perfetto.protos.ChromeApplicationStateInfo\x12V\n\x1f\x63hrome_renderer_scheduler_state\x18( \x01(\x0b\x32-.perfetto.protos.ChromeRendererSchedulerState\x12U\n\x1f\x63hrome_window_handle_event_info\x18) \x01(\x0b\x32,.perfetto.protos.ChromeWindowHandleEventInfo\x12[\n\"chrome_content_settings_event_info\x18+ \x01(\x0b\x32/.perfetto.protos.ChromeContentSettingsEventInfo\x12G\n\x17\x63hrome_active_processes\x18\x31 \x01(\x0b\x32&.perfetto.protos.ChromeActiveProcesses\x12/\n\nscreenshot\x18\x32 \x01(\x0b\x32\x1b.perfetto.protos.Screenshot\x12:\n\x0fsource_location\x18! \x01(\x0b\x32\x1f.perfetto.protos.SourceLocationH\x04\x12\x1d\n\x13source_location_iid\x18\" \x01(\x04H\x04\x12?\n\x13\x63hrome_message_pump\x18# \x01(\x0b\x32\".perfetto.protos.ChromeMessagePump\x12\x44\n\x16\x63hrome_mojo_event_info\x18& \x01(\x0b\x32$.perfetto.protos.ChromeMojoEventInfo\x12\x1c\n\x12timestamp_delta_us\x18\x01 \x01(\x03H\x05\x12\x1f\n\x15timestamp_absolute_us\x18\x10 \x01(\x03H\x05\x12\x1e\n\x14thread_time_delta_us\x18\x02 \x01(\x03H\x06\x12!\n\x17thread_time_absolute_us\x18\x11 \x01(\x03H\x06\x12(\n\x1ethread_instruction_count_delta\x18\x08 \x01(\x03H\x07\x12+\n!thread_instruction_count_absolute\x18\x14 \x01(\x03H\x07\x12=\n\x0clegacy_event\x18\x06 \x01(\x0b\x32\'.perfetto.protos.TrackEvent.LegacyEvent\x1a\x9e\x01\n\x0fInlineCallstack\x12\x41\n\x06\x66rames\x18\x01 \x03(\x0b\x32\x31.perfetto.protos.TrackEvent.InlineCallstack.Frame\x1aH\n\x05\x46rame\x12\x15\n\rfunction_name\x18\x01 \x01(\t\x12\x13\n\x0bsource_file\x18\x02 \x01(\t\x12\x13\n\x0bline_number\x18\x03 \x01(\r\x1a\xaa\x05\n\x0bLegacyEvent\x12\x10\n\x08name_iid\x18\x01 \x01(\x04\x12\r\n\x05phase\x18\x02 \x01(\x05\x12\x13\n\x0b\x64uration_us\x18\x03 \x01(\x03\x12\x1a\n\x12thread_duration_us\x18\x04 \x01(\x03\x12 \n\x18thread_instruction_delta\x18\x0f \x01(\x03\x12\x15\n\x0bunscoped_id\x18\x06 \x01(\x04H\x00\x12\x12\n\x08local_id\x18\n \x01(\x04H\x00\x12\x13\n\tglobal_id\x18\x0b \x01(\x04H\x00\x12\x10\n\x08id_scope\x18\x07 \x01(\t\x12\x15\n\ruse_async_tts\x18\t \x01(\x08\x12\x0f\n\x07\x62ind_id\x18\x08 \x01(\x04\x12\x19\n\x11\x62ind_to_enclosing\x18\x0c \x01(\x08\x12M\n\x0e\x66low_direction\x18\r \x01(\x0e\x32\x35.perfetto.protos.TrackEvent.LegacyEvent.FlowDirection\x12V\n\x13instant_event_scope\x18\x0e \x01(\x0e\x32\x39.perfetto.protos.TrackEvent.LegacyEvent.InstantEventScope\x12\x14\n\x0cpid_override\x18\x12 \x01(\x05\x12\x14\n\x0ctid_override\x18\x13 \x01(\x05\"P\n\rFlowDirection\x12\x14\n\x10\x46LOW_UNSPECIFIED\x10\x00\x12\x0b\n\x07\x46LOW_IN\x10\x01\x12\x0c\n\x08\x46LOW_OUT\x10\x02\x12\x0e\n\nFLOW_INOUT\x10\x03\"a\n\x11InstantEventScope\x12\x15\n\x11SCOPE_UNSPECIFIED\x10\x00\x12\x10\n\x0cSCOPE_GLOBAL\x10\x01\x12\x11\n\rSCOPE_PROCESS\x10\x02\x12\x10\n\x0cSCOPE_THREAD\x10\x03\x42\x04\n\x02idJ\x04\x08\x05\x10\x06\"z\n\x04Type\x12\x14\n\x10TYPE_UNSPECIFIED\x10\x00\x12\x14\n\x10TYPE_SLICE_BEGIN\x10\x01\x12\x12\n\x0eTYPE_SLICE_END\x10\x02\x12\x10\n\x0cTYPE_INSTANT\x10\x03\x12\x10\n\x0cTYPE_COUNTER\x10\x04\x12\x0e\n\nTYPE_STATE\x10\x05*\x06\x08\xe8\x07\x10\x90NB\x0c\n\nname_fieldB\x15\n\x13\x63ounter_value_fieldB\x16\n\x14\x63orrelation_id_fieldB\x11\n\x0f\x63\x61llstack_fieldB\x17\n\x15source_location_fieldB\x0b\n\ttimestampB\r\n\x0bthread_timeB\x1a\n\x18thread_instruction_countJ\x04\x08\x33\x10\x34\"u\n\x12TrackEventDefaults\x12\x12\n\ntrack_uuid\x18\x0b \x01(\x04\x12!\n\x19\x65xtra_counter_track_uuids\x18\x1f \x03(\x04\x12(\n extra_double_counter_track_uuids\x18- \x03(\x04\"*\n\rEventCategory\x12\x0b\n\x03iid\x18\x01 \x01(\x04\x12\x0c\n\x04name\x18\x02 \x01(\t\"&\n\tEventName\x12\x0b\n\x03iid\x18\x01 \x01(\x04\x12\x0c\n\x04name\x18\x02 \x01(\t\"\xc5\x10\n\x0cInternedData\x12\x38\n\x10\x65vent_categories\x18\x01 \x03(\x0b\x32\x1e.perfetto.protos.EventCategory\x12/\n\x0b\x65vent_names\x18\x02 \x03(\x0b\x32\x1a.perfetto.protos.EventName\x12\x44\n\x16\x64\x65\x62ug_annotation_names\x18\x03 \x03(\x0b\x32$.perfetto.protos.DebugAnnotationName\x12X\n!debug_annotation_value_type_names\x18\x1b \x03(\x0b\x32-.perfetto.protos.DebugAnnotationValueTypeName\x12G\n\x1e\x64\x65\x62ug_annotation_string_values\x18\x1d \x03(\x0b\x32\x1f.perfetto.protos.InternedString\x12;\n\x12\x63orrelation_id_str\x18+ \x03(\x0b\x32\x1f.perfetto.protos.InternedString\x12\x32\n\tbuild_ids\x18\x10 \x03(\x0b\x32\x1f.perfetto.protos.InternedString\x12\x36\n\rmapping_paths\x18\x11 \x03(\x0b\x32\x1f.perfetto.protos.InternedString\x12\x35\n\x0csource_paths\x18\x12 \x03(\x0b\x32\x1f.perfetto.protos.InternedString\x12\x37\n\x0e\x66unction_names\x18\x05 \x03(\x0b\x32\x1f.perfetto.protos.InternedString\x12*\n\x08mappings\x18\x13 \x03(\x0b\x32\x18.perfetto.protos.Mapping\x12&\n\x06\x66rames\x18\x06 \x03(\x0b\x32\x16.perfetto.protos.Frame\x12.\n\ncallstacks\x18\x07 \x03(\x0b\x32\x1a.perfetto.protos.Callstack\x12L\n\x1astack_sample_task_contexts\x18\x30 \x03(\x0b\x32(.perfetto.protos.StackSample.TaskContext\x12V\n\x1fstack_sample_execution_contexts\x18\x31 \x03(\x0b\x32-.perfetto.protos.StackSample.ExecutionContext\x12X\n stack_sample_counter_descriptors\x18\x32 \x03(\x0b\x32..perfetto.protos.StackSample.CounterDescriptor\x12\x63\n&stack_sample_async_context_descriptors\x18\x33 \x03(\x0b\x32\x33.perfetto.protos.StackSample.AsyncContextDescriptor\x12\x39\n\x10source_locations\x18\x04 \x03(\x0b\x32\x1f.perfetto.protos.SourceLocation\x12R\n\x1dunsymbolized_source_locations\x18\x1c \x03(\x0b\x32+.perfetto.protos.UnsymbolizedSourceLocation\x12\x39\n\x10log_message_body\x18\x14 \x03(\x0b\x32\x1f.perfetto.protos.LogMessageBody\x12\x37\n\x0fhistogram_names\x18\x19 \x03(\x0b\x32\x1e.perfetto.protos.HistogramName\x12;\n\x12vulkan_memory_keys\x18\x16 \x03(\x0b\x32\x1f.perfetto.protos.InternedString\x12\x43\n\x11graphics_contexts\x18\x17 \x03(\x0b\x32(.perfetto.protos.InternedGraphicsContext\x12P\n\x12gpu_specifications\x18\x18 \x03(\x0b\x32\x34.perfetto.protos.InternedGpuRenderStageSpecification\x12N\n\x17gpu_counter_descriptors\x18/ \x03(\x0b\x32-.perfetto.protos.InternedGpuCounterDescriptor\x12\x37\n\x0ekernel_symbols\x18\x1a \x03(\x0b\x32\x1f.perfetto.protos.InternedString\x12>\n\x13v8_js_function_name\x18\x1f \x03(\x0b\x32!.perfetto.protos.InternedV8String\x12=\n\x0ev8_js_function\x18  \x03(\x0b\x32%.perfetto.protos.InternedV8JsFunction\x12\x39\n\x0cv8_js_script\x18! \x03(\x0b\x32#.perfetto.protos.InternedV8JsScript\x12=\n\x0ev8_wasm_script\x18\" \x03(\x0b\x32%.perfetto.protos.InternedV8WasmScript\x12\x36\n\nv8_isolate\x18# \x03(\x0b\x32\".perfetto.protos.InternedV8Isolate*\x04\x08\x1e\x10\x1f*\x04\x08$\x10%*\x04\x08%\x10&*\x04\x08&\x10\'*\x04\x08\'\x10(*\x04\x08(\x10)*\x04\x08)\x10**\x04\x08*\x10+*\x04\x08,\x10-*\x04\x08-\x10.*\x04\x08.\x10/*\x06\x08\xe8\x07\x10\x90NJ\x04\x08\x15\x10\x16\"\xf3\x01\n\x14SystemdJournaldEvent\x12\x0b\n\x03pid\x18\x01 \x01(\r\x12\x0b\n\x03tid\x18\x02 \x01(\r\x12\x0b\n\x03uid\x18\x03 \x01(\r\x12\x0b\n\x03gid\x18\x04 \x01(\r\x12\x0c\n\x04prio\x18\x05 \x01(\r\x12\x0b\n\x03tag\x18\x06 \x01(\t\x12\x0f\n\x07message\x18\x07 \x01(\t\x12\x0c\n\x04\x63omm\x18\x08 \x01(\t\x12\x0b\n\x03\x65xe\x18\t \x01(\t\x12\x14\n\x0csystemd_unit\x18\n \x01(\t\x12\x10\n\x08hostname\x18\x0b \x01(\t\x12\x11\n\ttransport\x18\x0c \x01(\t\x12\x11\n\tnum_total\x18\x14 \x01(\x04\x12\x12\n\nnum_failed\x18\x15 \x01(\x04\"\xf0\x07\n\x15MemoryTrackerSnapshot\x12\x16\n\x0eglobal_dump_id\x18\x01 \x01(\x04\x12M\n\x0flevel_of_detail\x18\x02 \x01(\x0e\x32\x34.perfetto.protos.MemoryTrackerSnapshot.LevelOfDetail\x12T\n\x14process_memory_dumps\x18\x03 \x03(\x0b\x32\x36.perfetto.protos.MemoryTrackerSnapshot.ProcessSnapshot\x1a\xce\x05\n\x0fProcessSnapshot\x12\x0b\n\x03pid\x18\x01 \x01(\x05\x12Z\n\x0f\x61llocator_dumps\x18\x02 \x03(\x0b\x32\x41.perfetto.protos.MemoryTrackerSnapshot.ProcessSnapshot.MemoryNode\x12W\n\x0cmemory_edges\x18\x03 \x03(\x0b\x32\x41.perfetto.protos.MemoryTrackerSnapshot.ProcessSnapshot.MemoryEdge\x1a\x9b\x03\n\nMemoryNode\x12\n\n\x02id\x18\x01 \x01(\x04\x12\x15\n\rabsolute_name\x18\x02 \x01(\t\x12\x0c\n\x04weak\x18\x03 \x01(\x08\x12\x12\n\nsize_bytes\x18\x04 \x01(\x04\x12\x62\n\x07\x65ntries\x18\x05 \x03(\x0b\x32Q.perfetto.protos.MemoryTrackerSnapshot.ProcessSnapshot.MemoryNode.MemoryNodeEntry\x1a\xe3\x01\n\x0fMemoryNodeEntry\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x66\n\x05units\x18\x02 \x01(\x0e\x32W.perfetto.protos.MemoryTrackerSnapshot.ProcessSnapshot.MemoryNode.MemoryNodeEntry.Units\x12\x14\n\x0cvalue_uint64\x18\x03 \x01(\x04\x12\x14\n\x0cvalue_string\x18\x04 \x01(\t\".\n\x05Units\x12\x0f\n\x0bUNSPECIFIED\x10\x00\x12\t\n\x05\x42YTES\x10\x01\x12\t\n\x05\x43OUNT\x10\x02\x1a[\n\nMemoryEdge\x12\x11\n\tsource_id\x18\x01 \x01(\x04\x12\x11\n\ttarget_id\x18\x02 \x01(\x04\x12\x12\n\nimportance\x18\x03 \x01(\r\x12\x13\n\x0boverridable\x18\x04 \x01(\x08\"I\n\rLevelOfDetail\x12\x0f\n\x0b\x44\x45TAIL_FULL\x10\x00\x12\x10\n\x0c\x44\x45TAIL_LIGHT\x10\x01\x12\x15\n\x11\x44\x45TAIL_BACKGROUND\x10\x02\"\xd1\x02\n\x16\x43oncurrentSessionEvent\x12<\n\x05state\x18\x01 \x01(\x0e\x32-.perfetto.protos.ConcurrentSessionEvent.State\x12\x14\n\x0csession_name\x18\x02 \x01(\t\x12\x12\n\nsession_id\x18\x03 \x01(\x04\x12\x14\n\x0c\x63onsumer_uid\x18\x04 \x01(\x05\x12\x18\n\x10num_data_sources\x18\x05 \x01(\r\"\x9e\x01\n\x05State\x12\x15\n\x11STATE_UNSPECIFIED\x10\x00\x12\x12\n\x0eSTATE_DISABLED\x10\x01\x12\x14\n\x10STATE_CONFIGURED\x10\x02\x12\x11\n\rSTATE_STARTED\x10\x03\x12%\n!STATE_DISABLING_WAITING_STOP_ACKS\x10\x04\x12\x1a\n\x16STATE_CLONED_READ_ONLY\x10\x05\"\xa1\x04\n\x11PerfettoMetatrace\x12\x12\n\x08\x65vent_id\x18\x01 \x01(\rH\x00\x12\x14\n\ncounter_id\x18\x02 \x01(\rH\x00\x12\x14\n\nevent_name\x18\x08 \x01(\tH\x00\x12\x18\n\x0e\x65vent_name_iid\x18\x0b \x01(\x04H\x00\x12\x16\n\x0c\x63ounter_name\x18\t \x01(\tH\x00\x12\x19\n\x11\x65vent_duration_ns\x18\x03 \x01(\x04\x12\x15\n\rcounter_value\x18\x04 \x01(\x05\x12\x11\n\tthread_id\x18\x05 \x01(\r\x12\x14\n\x0chas_overruns\x18\x06 \x01(\x08\x12\x34\n\x04\x61rgs\x18\x07 \x03(\x0b\x32&.perfetto.protos.PerfettoMetatrace.Arg\x12K\n\x10interned_strings\x18\n \x03(\x0b\x32\x31.perfetto.protos.PerfettoMetatrace.InternedString\x1a\x7f\n\x03\x41rg\x12\r\n\x03key\x18\x01 \x01(\tH\x00\x12\x11\n\x07key_iid\x18\x03 \x01(\x04H\x00\x12\x0f\n\x05value\x18\x02 \x01(\tH\x01\x12\x13\n\tvalue_iid\x18\x04 \x01(\x04H\x01\x42\x15\n\x13key_or_interned_keyB\x19\n\x17value_or_interned_value\x1a,\n\x0eInternedString\x12\x0b\n\x03iid\x18\x01 \x01(\x04\x12\r\n\x05value\x18\x02 \x01(\tB\r\n\x0brecord_type\"\xc0\x01\n\x0fTraceProvenance\x12\x38\n\x07\x62uffers\x18\x02 \x03(\x0b\x32\'.perfetto.protos.TraceProvenance.Buffer\x1a+\n\x08Sequence\x12\n\n\x02id\x18\x01 \x01(\r\x12\x13\n\x0bproducer_id\x18\x02 \x01(\x05\x1a\x46\n\x06\x42uffer\x12<\n\tsequences\x18\x01 \x03(\x0b\x32).perfetto.protos.TraceProvenance.Sequence\"\x8a\x05\n\x13TracingServiceEvent\x12\x19\n\x0ftracing_started\x18\x02 \x01(\x08H\x00\x12\"\n\x18\x61ll_data_sources_started\x18\x01 \x01(\x08H\x00\x12\x17\n\rflush_started\x18\t \x01(\x08H\x00\x12\"\n\x18\x61ll_data_sources_flushed\x18\x03 \x01(\x08H\x00\x12(\n\x1eread_tracing_buffers_completed\x18\x04 \x01(\x08H\x00\x12\x1a\n\x10tracing_disabled\x18\x05 \x01(\x08H\x00\x12\x1e\n\x14seized_for_bugreport\x18\x06 \x01(\x08H\x00\x12V\n\x1aslow_starting_data_sources\x18\x07 \x01(\x0b\x32\x30.perfetto.protos.TracingServiceEvent.DataSourcesH\x00\x12X\n\x1clast_flush_slow_data_sources\x18\x08 \x01(\x0b\x32\x30.perfetto.protos.TracingServiceEvent.DataSourcesH\x00\x12\x17\n\rclone_started\x18\n \x01(\x08H\x00\x12\x17\n\rbuffer_cloned\x18\x0b \x01(\rH\x00\x1a\x9e\x01\n\x0b\x44\x61taSources\x12P\n\x0b\x64\x61ta_source\x18\x01 \x03(\x0b\x32;.perfetto.protos.TracingServiceEvent.DataSources.DataSource\x1a=\n\nDataSource\x12\x15\n\rproducer_name\x18\x01 \x01(\t\x12\x18\n\x10\x64\x61ta_source_name\x18\x02 \x01(\tB\x0c\n\nevent_type\"`\n\x15\x41ndroidEnergyConsumer\x12\x1a\n\x12\x65nergy_consumer_id\x18\x01 \x01(\x05\x12\x0f\n\x07ordinal\x18\x02 \x01(\x05\x12\x0c\n\x04type\x18\x03 \x01(\t\x12\x0c\n\x04name\x18\x04 \x01(\t\"c\n\x1f\x41ndroidEnergyConsumerDescriptor\x12@\n\x10\x65nergy_consumers\x18\x01 \x03(\x0b\x32&.perfetto.protos.AndroidEnergyConsumer\"\xc0\x02\n AndroidEnergyEstimationBreakdown\x12T\n\x1a\x65nergy_consumer_descriptor\x18\x01 \x01(\x0b\x32\x30.perfetto.protos.AndroidEnergyConsumerDescriptor\x12\x1a\n\x12\x65nergy_consumer_id\x18\x02 \x01(\x05\x12\x12\n\nenergy_uws\x18\x03 \x01(\x03\x12_\n\x11per_uid_breakdown\x18\x04 \x03(\x0b\x32\x44.perfetto.protos.AndroidEnergyEstimationBreakdown.EnergyUidBreakdown\x1a\x35\n\x12\x45nergyUidBreakdown\x12\x0b\n\x03uid\x18\x01 \x01(\x05\x12\x12\n\nenergy_uws\x18\x02 \x01(\x03\"\xbb\x03\n\x14\x45ntityStateResidency\x12R\n\x12power_entity_state\x18\x01 \x03(\x0b\x32\x36.perfetto.protos.EntityStateResidency.PowerEntityState\x12G\n\tresidency\x18\x02 \x03(\x0b\x32\x34.perfetto.protos.EntityStateResidency.StateResidency\x1a\x66\n\x10PowerEntityState\x12\x14\n\x0c\x65ntity_index\x18\x01 \x01(\x05\x12\x13\n\x0bstate_index\x18\x02 \x01(\x05\x12\x13\n\x0b\x65ntity_name\x18\x03 \x01(\t\x12\x12\n\nstate_name\x18\x04 \x01(\t\x1a\x9d\x01\n\x0eStateResidency\x12\x14\n\x0c\x65ntity_index\x18\x01 \x01(\x05\x12\x13\n\x0bstate_index\x18\x02 \x01(\x05\x12\x1e\n\x16total_time_in_state_ms\x18\x03 \x01(\x04\x12\x1f\n\x17total_state_entry_count\x18\x04 \x01(\x04\x12\x1f\n\x17last_entry_timestamp_ms\x18\x05 \x01(\x04\"\xb1\x01\n\x0f\x42\x61tteryCounters\x12\x1a\n\x12\x63harge_counter_uah\x18\x01 \x01(\x03\x12\x18\n\x10\x63\x61pacity_percent\x18\x02 \x01(\x02\x12\x12\n\ncurrent_ua\x18\x03 \x01(\x03\x12\x16\n\x0e\x63urrent_avg_ua\x18\x04 \x01(\x03\x12\x0c\n\x04name\x18\x05 \x01(\t\x12\x1a\n\x12\x65nergy_counter_uwh\x18\x06 \x01(\x03\x12\x12\n\nvoltage_uv\x18\x07 \x01(\x03\"\xc7\x02\n\nPowerRails\x12\x43\n\x0frail_descriptor\x18\x01 \x03(\x0b\x32*.perfetto.protos.PowerRails.RailDescriptor\x12;\n\x0b\x65nergy_data\x18\x02 \x03(\x0b\x32&.perfetto.protos.PowerRails.EnergyData\x12\x14\n\x0csession_uuid\x18\x03 \x01(\x04\x1a^\n\x0eRailDescriptor\x12\r\n\x05index\x18\x01 \x01(\r\x12\x11\n\trail_name\x18\x02 \x01(\t\x12\x13\n\x0bsubsys_name\x18\x03 \x01(\t\x12\x15\n\rsampling_rate\x18\x04 \x01(\r\x1a\x41\n\nEnergyData\x12\r\n\x05index\x18\x01 \x01(\r\x12\x14\n\x0ctimestamp_ms\x18\x02 \x01(\x04\x12\x0e\n\x06\x65nergy\x18\x03 \x01(\x04\"J\n\tJavaFrame\x12\x13\n\x0bmethod_name\x18\x01 \x01(\t\x12\x13\n\x0bsource_file\x18\x02 \x01(\t\x12\x13\n\x0bline_number\x18\x03 \x01(\x05\"7\n\tJavaStack\x12*\n\x06\x66rames\x18\x01 \x03(\x0b\x32\x1a.perfetto.protos.JavaFrame\"\x89\x02\n\x12\x41rtProcessMetadata\x12\x0b\n\x03pid\x18\x01 \x01(\x05\x12\x0b\n\x03uid\x18\x02 \x01(\x05\x12\x14\n\x0cprocess_name\x18\x03 \x01(\t\x12\x14\n\x0cpackage_name\x18\x04 \x01(\t\x12\x1b\n\x13oom_allocation_size\x18\x05 \x01(\x04\x12\x1c\n\x14oom_total_bytes_free\x18\x06 \x01(\x04\x12 \n\x18oom_free_bytes_until_oom\x18\x07 \x01(\x04\x12\x39\n\x15oom_thread_java_stack\x18\x08 \x01(\x0b\x32\x1a.perfetto.protos.JavaStack\x12\x15\n\room_error_msg\x18\t \x01(\t\"\xb6\x01\n\x10ObfuscatedMember\x12\x17\n\x0fobfuscated_name\x18\x01 \x01(\t\x12\x19\n\x11\x64\x65obfuscated_name\x18\x02 \x01(\t\x12\x1d\n\x15obfuscated_line_start\x18\x03 \x01(\r\x12\x1b\n\x13obfuscated_line_end\x18\x04 \x01(\r\x12\x19\n\x11source_line_start\x18\x05 \x01(\r\x12\x17\n\x0fsource_line_end\x18\x06 \x01(\r\"\x97\x04\n\x0fObfuscatedClass\x12\x17\n\x0fobfuscated_name\x18\x01 \x01(\t\x12\x19\n\x11\x64\x65obfuscated_name\x18\x02 \x01(\t\x12=\n\x12obfuscated_members\x18\x03 \x03(\x0b\x32!.perfetto.protos.ObfuscatedMember\x12=\n\x12obfuscated_methods\x18\x04 \x03(\x0b\x32!.perfetto.protos.ObfuscatedMember\x12\x46\n\x0emerged_classes\x18\x05 \x01(\x0b\x32..perfetto.protos.ObfuscatedClass.MergedClasses\x1au\n\x0bMergedClass\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x10\n\x08\x63lass_id\x18\x02 \x01(\x05\x12\x46\n\x0emerged_classes\x18\x03 \x01(\x0b\x32..perfetto.protos.ObfuscatedClass.MergedClasses\x1a\x92\x01\n\rMergedClasses\x12\x1b\n\x13\x63lass_id_field_name\x18\x01 \x01(\t\x12\x44\n\x0emerged_classes\x18\x02 \x03(\x0b\x32,.perfetto.protos.ObfuscatedClass.MergedClass\x12\x1e\n\x16unknown_merged_classes\x18\x03 \x01(\x08\"\x80\x01\n\x14\x44\x65obfuscationMapping\x12\x14\n\x0cpackage_name\x18\x01 \x01(\t\x12\x14\n\x0cversion_code\x18\x02 \x01(\x03\x12<\n\x12obfuscated_classes\x18\x03 \x03(\x0b\x32 .perfetto.protos.ObfuscatedClass\"\xd5\x0b\n\rProfilePacket\x12\x30\n\x07strings\x18\x01 \x03(\x0b\x32\x1f.perfetto.protos.InternedString\x12*\n\x08mappings\x18\x04 \x03(\x0b\x32\x18.perfetto.protos.Mapping\x12&\n\x06\x66rames\x18\x02 \x03(\x0b\x32\x16.perfetto.protos.Frame\x12.\n\ncallstacks\x18\x03 \x03(\x0b\x32\x1a.perfetto.protos.Callstack\x12H\n\rprocess_dumps\x18\x05 \x03(\x0b\x32\x31.perfetto.protos.ProfilePacket.ProcessHeapSamples\x12\x11\n\tcontinued\x18\x06 \x01(\x08\x12\r\n\x05index\x18\x07 \x01(\x04\x1a\xba\x01\n\nHeapSample\x12\x14\n\x0c\x63\x61llstack_id\x18\x01 \x01(\x04\x12\x16\n\x0eself_allocated\x18\x02 \x01(\x04\x12\x12\n\nself_freed\x18\x03 \x01(\x04\x12\x10\n\x08self_max\x18\x08 \x01(\x04\x12\x16\n\x0eself_max_count\x18\t \x01(\x04\x12\x11\n\ttimestamp\x18\x04 \x01(\x04\x12\x13\n\x0b\x61lloc_count\x18\x05 \x01(\x04\x12\x12\n\nfree_count\x18\x06 \x01(\x04J\x04\x08\x07\x10\x08\x1a\x8f\x01\n\tHistogram\x12@\n\x07\x62uckets\x18\x01 \x03(\x0b\x32/.perfetto.protos.ProfilePacket.Histogram.Bucket\x1a@\n\x06\x42ucket\x12\x13\n\x0bupper_limit\x18\x01 \x01(\x04\x12\x12\n\nmax_bucket\x18\x02 \x01(\x08\x12\r\n\x05\x63ount\x18\x03 \x01(\x04\x1a\xde\x01\n\x0cProcessStats\x12\x18\n\x10unwinding_errors\x18\x01 \x01(\x04\x12\x14\n\x0cheap_samples\x18\x02 \x01(\x04\x12\x14\n\x0cmap_reparses\x18\x03 \x01(\x04\x12\x43\n\x11unwinding_time_us\x18\x04 \x01(\x0b\x32(.perfetto.protos.ProfilePacket.Histogram\x12\x1f\n\x17total_unwinding_time_us\x18\x05 \x01(\x04\x12\"\n\x1a\x63lient_spinlock_blocked_us\x18\x06 \x01(\x04\x1a\xf1\x04\n\x12ProcessHeapSamples\x12\x0b\n\x03pid\x18\x01 \x01(\x04\x12\x14\n\x0c\x66rom_startup\x18\x03 \x01(\x08\x12\x1b\n\x13rejected_concurrent\x18\x04 \x01(\x08\x12\x14\n\x0c\x64isconnected\x18\x06 \x01(\x08\x12\x16\n\x0e\x62uffer_overran\x18\x07 \x01(\x08\x12S\n\x0c\x63lient_error\x18\x0e \x01(\x0e\x32=.perfetto.protos.ProfilePacket.ProcessHeapSamples.ClientError\x12\x18\n\x10\x62uffer_corrupted\x18\x08 \x01(\x08\x12\x15\n\rhit_guardrail\x18\n \x01(\x08\x12\x11\n\theap_name\x18\x0b \x01(\t\x12\x1f\n\x17sampling_interval_bytes\x18\x0c \x01(\x04\x12$\n\x1corig_sampling_interval_bytes\x18\r \x01(\x04\x12\x11\n\ttimestamp\x18\t \x01(\x04\x12\x17\n\x0fstart_timestamp\x18\x0f \x01(\x04\x12:\n\x05stats\x18\x05 \x01(\x0b\x32+.perfetto.protos.ProfilePacket.ProcessStats\x12:\n\x07samples\x18\x02 \x03(\x0b\x32).perfetto.protos.ProfilePacket.HeapSample\"i\n\x0b\x43lientError\x12\x15\n\x11\x43LIENT_ERROR_NONE\x10\x00\x12\x1c\n\x18\x43LIENT_ERROR_HIT_TIMEOUT\x10\x01\x12%\n!CLIENT_ERROR_INVALID_STACK_BOUNDS\x10\x02\"\x9d\x01\n\x13StreamingAllocation\x12\x0f\n\x07\x61\x64\x64ress\x18\x01 \x03(\x04\x12\x0c\n\x04size\x18\x02 \x03(\x04\x12\x13\n\x0bsample_size\x18\x03 \x03(\x04\x12(\n clock_monotonic_coarse_timestamp\x18\x04 \x03(\x04\x12\x0f\n\x07heap_id\x18\x05 \x03(\r\x12\x17\n\x0fsequence_number\x18\x06 \x03(\x04\"J\n\rStreamingFree\x12\x0f\n\x07\x61\x64\x64ress\x18\x01 \x03(\x04\x12\x0f\n\x07heap_id\x18\x02 \x03(\r\x12\x17\n\x0fsequence_number\x18\x03 \x03(\x04\"e\n\x16StreamingProfilePacket\x12\x15\n\rcallstack_iid\x18\x01 \x03(\x04\x12\x1a\n\x12timestamp_delta_us\x18\x02 \x03(\x03\x12\x18\n\x10process_priority\x18\x03 \x01(\x05\"\x90\x05\n\tProfiling\"|\n\x07\x43puMode\x12\x10\n\x0cMODE_UNKNOWN\x10\x00\x12\x0f\n\x0bMODE_KERNEL\x10\x01\x12\r\n\tMODE_USER\x10\x02\x12\x13\n\x0fMODE_HYPERVISOR\x10\x03\x12\x15\n\x11MODE_GUEST_KERNEL\x10\x04\x12\x13\n\x0fMODE_GUEST_USER\x10\x05\"\x84\x04\n\x10StackUnwindError\x12\x18\n\x14UNWIND_ERROR_UNKNOWN\x10\x00\x12\x15\n\x11UNWIND_ERROR_NONE\x10\x01\x12\x1f\n\x1bUNWIND_ERROR_MEMORY_INVALID\x10\x02\x12\x1c\n\x18UNWIND_ERROR_UNWIND_INFO\x10\x03\x12\x1c\n\x18UNWIND_ERROR_UNSUPPORTED\x10\x04\x12\x1c\n\x18UNWIND_ERROR_INVALID_MAP\x10\x05\x12$\n UNWIND_ERROR_MAX_FRAMES_EXCEEDED\x10\x06\x12\x1f\n\x1bUNWIND_ERROR_REPEATED_FRAME\x10\x07\x12\x1c\n\x18UNWIND_ERROR_INVALID_ELF\x10\x08\x12\x1c\n\x18UNWIND_ERROR_SYSTEM_CALL\x10\t\x12\x1f\n\x1bUNWIND_ERROR_THREAD_TIMEOUT\x10\n\x12&\n\"UNWIND_ERROR_THREAD_DOES_NOT_EXIST\x10\x0b\x12\x19\n\x15UNWIND_ERROR_BAD_ARCH\x10\x0c\x12\x1b\n\x17UNWIND_ERROR_MAPS_PARSE\x10\r\x12\"\n\x1eUNWIND_ERROR_INVALID_PARAMETER\x10\x0e\x12\x1c\n\x18UNWIND_ERROR_PTRACE_CALL\x10\x0f\"\xef\x06\n\nPerfSample\x12\x0b\n\x03\x63pu\x18\x01 \x01(\r\x12\x0b\n\x03pid\x18\x02 \x01(\r\x12\x0b\n\x03tid\x18\x03 \x01(\r\x12\x34\n\x08\x63pu_mode\x18\x05 \x01(\x0e\x32\".perfetto.protos.Profiling.CpuMode\x12\x16\n\x0etimebase_count\x18\x06 \x01(\x04\x12\x17\n\x0f\x66ollower_counts\x18\x07 \x03(\x04\x12\x15\n\rcallstack_iid\x18\x04 \x01(\x04\x12\x43\n\x0cunwind_error\x18\x10 \x01(\x0e\x32+.perfetto.protos.Profiling.StackUnwindErrorH\x00\x12\x1b\n\x13kernel_records_lost\x18\x11 \x01(\x04\x12M\n\x15sample_skipped_reason\x18\x12 \x01(\x0e\x32,.perfetto.protos.PerfSample.SampleSkipReasonH\x01\x12\x41\n\x0eproducer_event\x18\x13 \x01(\x0b\x32).perfetto.protos.PerfSample.ProducerEvent\x1a\xdc\x01\n\rProducerEvent\x12\\\n\x12source_stop_reason\x18\x01 \x01(\x0e\x32>.perfetto.protos.PerfSample.ProducerEvent.DataSourceStopReasonH\x00\"N\n\x14\x44\x61taSourceStopReason\x12\x19\n\x15PROFILER_STOP_UNKNOWN\x10\x00\x12\x1b\n\x17PROFILER_STOP_GUARDRAIL\x10\x01\x42\x1d\n\x1boptional_source_stop_reason\"\xad\x01\n\x10SampleSkipReason\x12\x19\n\x15PROFILER_SKIP_UNKNOWN\x10\x00\x12\x1c\n\x18PROFILER_SKIP_READ_STAGE\x10\x01\x12\x1e\n\x1aPROFILER_SKIP_UNWIND_STAGE\x10\x02\x12 \n\x1cPROFILER_SKIP_UNWIND_ENQUEUE\x10\x03\x12\x1e\n\x1aPROFILER_SKIP_NOT_IN_SCOPE\x10\x04\x42\x17\n\x15optional_unwind_errorB \n\x1eoptional_sample_skipped_reason\"\xba\x01\n\x12PerfSampleDefaults\x12\x36\n\x08timebase\x18\x01 \x01(\x0b\x32$.perfetto.protos.PerfEvents.Timebase\x12\x31\n\tfollowers\x18\x04 \x03(\x0b\x32\x1e.perfetto.protos.FollowerEvent\x12\x1b\n\x13process_shard_count\x18\x02 \x01(\r\x12\x1c\n\x14\x63hosen_process_shard\x18\x03 \x01(\r\"\x83\x03\n\nSmapsEntry\x12\x0c\n\x04path\x18\x01 \x01(\t\x12\x0f\n\x07size_kb\x18\x02 \x01(\x04\x12\x18\n\x10private_dirty_kb\x18\x03 \x01(\x04\x12\x0f\n\x07swap_kb\x18\x04 \x01(\x04\x12\x11\n\tfile_name\x18\x05 \x01(\t\x12\x15\n\rstart_address\x18\x06 \x01(\x04\x12\x18\n\x10module_timestamp\x18\x07 \x01(\x04\x12\x16\n\x0emodule_debugid\x18\x08 \x01(\t\x12\x19\n\x11module_debug_path\x18\t \x01(\t\x12\x18\n\x10protection_flags\x18\n \x01(\r\x12!\n\x19private_clean_resident_kb\x18\x0b \x01(\x04\x12 \n\x18shared_dirty_resident_kb\x18\x0c \x01(\x04\x12 \n\x18shared_clean_resident_kb\x18\r \x01(\x04\x12\x11\n\tlocked_kb\x18\x0e \x01(\x04\x12 \n\x18proportional_resident_kb\x18\x0f \x01(\x04\"\x81\x03\n\x0bPackedSmaps\x12\x14\n\x0cstring_table\x18\x01 \x03(\t\x12\x13\n\x07name_id\x18\x02 \x03(\rB\x02\x10\x01\x12\x1b\n\x0f\x61ggregate_count\x18\x03 \x03(\rB\x02\x10\x01\x12\x13\n\x07size_kb\x18\x04 \x03(\x04\x42\x02\x10\x01\x12\x12\n\x06rss_kb\x18\x05 \x03(\x04\x42\x02\x10\x01\x12\x18\n\x0c\x61nonymous_kb\x18\x06 \x03(\x04\x42\x02\x10\x01\x12\x13\n\x07swap_kb\x18\x07 \x03(\x04\x42\x02\x10\x01\x12\x1b\n\x0fshared_clean_kb\x18\x08 \x03(\x04\x42\x02\x10\x01\x12\x1b\n\x0fshared_dirty_kb\x18\t \x03(\x04\x42\x02\x10\x01\x12\x1c\n\x10private_clean_kb\x18\n \x03(\x04\x42\x02\x10\x01\x12\x1c\n\x10private_dirty_kb\x18\x0b \x03(\x04\x42\x02\x10\x01\x12\x15\n\tlocked_kb\x18\x0c \x03(\x04\x42\x02\x10\x01\x12\x12\n\x06pss_kb\x18\r \x03(\x04\x42\x02\x10\x01\x12\x18\n\x0cpss_dirty_kb\x18\x0e \x03(\x04\x42\x02\x10\x01\x12\x17\n\x0bswap_pss_kb\x18\x0f \x03(\x04\x42\x02\x10\x01\"\xdc\x02\n\x0bSmapsPacket\x12\x0b\n\x03pid\x18\x01 \x01(\r\x12,\n\x07\x65ntries\x18\x02 \x03(\x0b\x32\x1b.perfetto.protos.SmapsEntry\x12\x34\n\x0epacked_entries\x18\x03 \x01(\x0b\x32\x1c.perfetto.protos.PackedSmaps\x12\x42\n\x0erecording_type\x18\x04 \x01(\x0e\x32*.perfetto.protos.SmapsPacket.RecordingType\"\x97\x01\n\rRecordingType\x12\x1a\n\x16RECORDING_TYPE_UNKNOWN\x10\x00\x12\x1d\n\x19RECORDING_TYPE_STANDALONE\x10\x01\x12%\n!RECORDING_TYPE_ART_HPROF_POSTFORK\x10\x02\x12$\n RECORDING_TYPE_ART_HPROF_PREFORK\x10\x03\"\xbb\x06\n\x0cProcessStats\x12\x38\n\tprocesses\x18\x01 \x03(\x0b\x32%.perfetto.protos.ProcessStats.Process\x12 \n\x18\x63ollection_end_timestamp\x18\x02 \x01(\x04\x1a\'\n\x06Thread\x12\x0b\n\x03tid\x18\x01 \x01(\x05J\x04\x08\x02\x10\x03J\x04\x08\x03\x10\x04J\x04\x08\x04\x10\x05\x1a\"\n\x06\x46\x44Info\x12\n\n\x02\x66\x64\x18\x01 \x01(\x04\x12\x0c\n\x04path\x18\x02 \x01(\t\x1a\x81\x05\n\x07Process\x12\x0b\n\x03pid\x18\x01 \x01(\x05\x12\x35\n\x07threads\x18\x0b \x03(\x0b\x32$.perfetto.protos.ProcessStats.Thread\x12\x12\n\nvm_size_kb\x18\x02 \x01(\x04\x12\x11\n\tvm_rss_kb\x18\x03 \x01(\x04\x12\x13\n\x0brss_anon_kb\x18\x04 \x01(\x04\x12\x13\n\x0brss_file_kb\x18\x05 \x01(\x04\x12\x14\n\x0crss_shmem_kb\x18\x06 \x01(\x04\x12\x12\n\nvm_swap_kb\x18\x07 \x01(\x04\x12\x14\n\x0cvm_locked_kb\x18\x08 \x01(\x04\x12\x11\n\tvm_hwm_kb\x18\t \x01(\x04\x12\x15\n\room_score_adj\x18\n \x01(\x03\x12\x1e\n\x16is_peak_rss_resettable\x18\x0c \x01(\x08\x12#\n\x1b\x63hrome_private_footprint_kb\x18\r \x01(\r\x12#\n\x1b\x63hrome_peak_resident_set_kb\x18\x0e \x01(\r\x12\x31\n\x03\x66\x64s\x18\x0f \x03(\x0b\x32$.perfetto.protos.ProcessStats.FDInfo\x12\x12\n\nsmr_rss_kb\x18\x10 \x01(\x04\x12\x12\n\nsmr_pss_kb\x18\x11 \x01(\x04\x12\x17\n\x0fsmr_pss_anon_kb\x18\x12 \x01(\x04\x12\x17\n\x0fsmr_pss_file_kb\x18\x13 \x01(\x04\x12\x18\n\x10smr_pss_shmem_kb\x18\x14 \x01(\x04\x12\x17\n\x0fsmr_swap_pss_kb\x18\x17 \x01(\x04\x12\x19\n\x11runtime_user_mode\x18\x15 \x01(\x04\x12\x1b\n\x13runtime_kernel_mode\x18\x16 \x01(\x04\x12\x15\n\rdmabuf_rss_kb\x18\x18 \x01(\x04\"\x88\x03\n\x0bProcessTree\x12\x37\n\tprocesses\x18\x01 \x03(\x0b\x32$.perfetto.protos.ProcessTree.Process\x12\x34\n\x07threads\x18\x02 \x03(\x0b\x32#.perfetto.protos.ProcessTree.Thread\x12 \n\x18\x63ollection_end_timestamp\x18\x03 \x01(\x04\x1a@\n\x06Thread\x12\x0b\n\x03tid\x18\x01 \x01(\x05\x12\x0c\n\x04tgid\x18\x03 \x01(\x05\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\r\n\x05nstid\x18\x04 \x03(\x05\x1a\xa5\x01\n\x07Process\x12\x0b\n\x03pid\x18\x01 \x01(\x05\x12\x0c\n\x04ppid\x18\x02 \x01(\x05\x12\x0f\n\x07\x63mdline\x18\x03 \x03(\t\x12\x17\n\x0f\x63mdline_is_comm\x18\t \x01(\x08\x12\x0b\n\x03uid\x18\x05 \x01(\x05\x12\r\n\x05nspid\x18\x06 \x03(\x05\x12\x1f\n\x17process_start_from_boot\x18\x07 \x01(\x04\x12\x12\n\nis_kthread\x18\x08 \x01(\x08J\x04\x08\x04\x10\x05\"\xd3\x01\n\x0fRemoteClockSync\x12\x44\n\rsynced_clocks\x18\x01 \x03(\x0b\x32-.perfetto.protos.RemoteClockSync.SyncedClocks\x1az\n\x0cSyncedClocks\x12\x35\n\rclient_clocks\x18\x02 \x01(\x0b\x32\x1e.perfetto.protos.ClockSnapshot\x12\x33\n\x0bhost_clocks\x18\x03 \x01(\x0b\x32\x1e.perfetto.protos.ClockSnapshot\"\x06\n\x04\x41tom\"J\n\nStatsdAtom\x12#\n\x04\x61tom\x18\x01 \x03(\x0b\x32\x15.perfetto.protos.Atom\x12\x17\n\x0ftimestamp_nanos\x18\x02 \x03(\x03\"\xe4\x10\n\x08SysStats\x12\x37\n\x07meminfo\x18\x01 \x03(\x0b\x32&.perfetto.protos.SysStats.MeminfoValue\x12\x35\n\x06vmstat\x18\x02 \x03(\x0b\x32%.perfetto.protos.SysStats.VmstatValue\x12\x34\n\x08\x63pu_stat\x18\x03 \x03(\x0b\x32\".perfetto.protos.SysStats.CpuTimes\x12\x11\n\tnum_forks\x18\x04 \x01(\x04\x12\x15\n\rnum_irq_total\x18\x05 \x01(\x04\x12\x39\n\x07num_irq\x18\x06 \x03(\x0b\x32(.perfetto.protos.SysStats.InterruptCount\x12\x19\n\x11num_softirq_total\x18\x07 \x01(\x04\x12=\n\x0bnum_softirq\x18\x08 \x03(\x0b\x32(.perfetto.protos.SysStats.InterruptCount\x12 \n\x18\x63ollection_end_timestamp\x18\t \x01(\x04\x12\x37\n\x07\x64\x65vfreq\x18\n \x03(\x0b\x32&.perfetto.protos.SysStats.DevfreqValue\x12\x13\n\x0b\x63pufreq_khz\x18\x0b \x03(\r\x12\x37\n\nbuddy_info\x18\x0c \x03(\x0b\x32#.perfetto.protos.SysStats.BuddyInfo\x12\x35\n\tdisk_stat\x18\r \x03(\x0b\x32\".perfetto.protos.SysStats.DiskStat\x12\x30\n\x03psi\x18\x0e \x03(\x0b\x32#.perfetto.protos.SysStats.PsiSample\x12;\n\x0cthermal_zone\x18\x0f \x03(\x0b\x32%.perfetto.protos.SysStats.ThermalZone\x12=\n\rcpuidle_state\x18\x10 \x03(\x0b\x32&.perfetto.protos.SysStats.CpuIdleState\x12\x13\n\x0bgpufreq_mhz\x18\x11 \x03(\x04\x12\x35\n\tslab_info\x18\x12 \x03(\x0b\x32\".perfetto.protos.SysStats.SlabInfo\x1aL\n\x0cMeminfoValue\x12-\n\x03key\x18\x01 \x01(\x0e\x32 .perfetto.protos.MeminfoCounters\x12\r\n\x05value\x18\x02 \x01(\x04\x1aJ\n\x0bVmstatValue\x12,\n\x03key\x18\x01 \x01(\x0e\x32\x1f.perfetto.protos.VmstatCounters\x12\r\n\x05value\x18\x02 \x01(\x04\x1a\xb4\x01\n\x08\x43puTimes\x12\x0e\n\x06\x63pu_id\x18\x01 \x01(\r\x12\x0f\n\x07user_ns\x18\x02 \x01(\x04\x12\x14\n\x0cuser_nice_ns\x18\x03 \x01(\x04\x12\x16\n\x0esystem_mode_ns\x18\x04 \x01(\x04\x12\x0f\n\x07idle_ns\x18\x05 \x01(\x04\x12\x12\n\nio_wait_ns\x18\x06 \x01(\x04\x12\x0e\n\x06irq_ns\x18\x07 \x01(\x04\x12\x12\n\nsoftirq_ns\x18\x08 \x01(\x04\x12\x10\n\x08steal_ns\x18\t \x01(\x04\x1a,\n\x0eInterruptCount\x12\x0b\n\x03irq\x18\x01 \x01(\x05\x12\r\n\x05\x63ount\x18\x02 \x01(\x04\x1a*\n\x0c\x44\x65vfreqValue\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\x04\x1a<\n\tBuddyInfo\x12\x0c\n\x04node\x18\x01 \x01(\t\x12\x0c\n\x04zone\x18\x02 \x01(\t\x12\x13\n\x0border_pages\x18\x03 \x03(\r\x1a\xd7\x01\n\x08\x44iskStat\x12\x13\n\x0b\x64\x65vice_name\x18\x01 \x01(\t\x12\x14\n\x0cread_sectors\x18\x02 \x01(\x04\x12\x14\n\x0cread_time_ms\x18\x03 \x01(\x04\x12\x15\n\rwrite_sectors\x18\x04 \x01(\x04\x12\x15\n\rwrite_time_ms\x18\x05 \x01(\x04\x12\x17\n\x0f\x64iscard_sectors\x18\x06 \x01(\x04\x12\x17\n\x0f\x64iscard_time_ms\x18\x07 \x01(\x04\x12\x13\n\x0b\x66lush_count\x18\x08 \x01(\x04\x12\x15\n\rflush_time_ms\x18\t \x01(\x04\x1a\xb4\x02\n\tPsiSample\x12\x41\n\x08resource\x18\x01 \x01(\x0e\x32/.perfetto.protos.SysStats.PsiSample.PsiResource\x12\x10\n\x08total_ns\x18\x02 \x01(\x04\"\xd1\x01\n\x0bPsiResource\x12\x1c\n\x18PSI_RESOURCE_UNSPECIFIED\x10\x00\x12\x19\n\x15PSI_RESOURCE_CPU_SOME\x10\x01\x12\x19\n\x15PSI_RESOURCE_CPU_FULL\x10\x02\x12\x18\n\x14PSI_RESOURCE_IO_SOME\x10\x03\x12\x18\n\x14PSI_RESOURCE_IO_FULL\x10\x04\x12\x1c\n\x18PSI_RESOURCE_MEMORY_SOME\x10\x05\x12\x1c\n\x18PSI_RESOURCE_MEMORY_FULL\x10\x06\x1a\x37\n\x0bThermalZone\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0c\n\x04temp\x18\x02 \x01(\x04\x12\x0c\n\x04type\x18\x03 \x01(\t\x1a\x37\n\x11\x43puIdleStateEntry\x12\r\n\x05state\x18\x01 \x01(\t\x12\x13\n\x0b\x64uration_us\x18\x02 \x01(\x04\x1ah\n\x0c\x43puIdleState\x12\x0e\n\x06\x63pu_id\x18\x01 \x01(\r\x12H\n\x13\x63puidle_state_entry\x18\x02 \x03(\x0b\x32+.perfetto.protos.SysStats.CpuIdleStateEntry\x1a\x43\n\x08SlabInfo\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x16\n\x0epages_per_slab\x18\x02 \x01(\r\x12\x11\n\tnum_slabs\x18\x03 \x01(\r\"\xcc\x02\n\x07\x43puInfo\x12*\n\x04\x63pus\x18\x01 \x03(\x0b\x32\x1c.perfetto.protos.CpuInfo.Cpu\x1an\n\x10\x41rmCpuIdentifier\x12\x13\n\x0bimplementer\x18\x01 \x01(\r\x12\x14\n\x0c\x61rchitecture\x18\x02 \x01(\r\x12\x0f\n\x07variant\x18\x03 \x01(\r\x12\x0c\n\x04part\x18\x04 \x01(\r\x12\x10\n\x08revision\x18\x05 \x01(\r\x1a\xa4\x01\n\x03\x43pu\x12\x11\n\tprocessor\x18\x01 \x01(\t\x12\x13\n\x0b\x66requencies\x18\x02 \x03(\r\x12\x10\n\x08\x63\x61pacity\x18\x03 \x01(\r\x12\x43\n\x0e\x61rm_identifier\x18\x04 \x01(\x0b\x32).perfetto.protos.CpuInfo.ArmCpuIdentifierH\x00\x12\x10\n\x08\x66\x65\x61tures\x18\x05 \x01(\x04\x42\x0c\n\nidentifier\"\x82\x02\n\x07GpuInfo\x12*\n\x04gpus\x18\x01 \x03(\x0b\x32\x1c.perfetto.protos.GpuInfo.Gpu\x1a\xca\x01\n\x03Gpu\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0e\n\x06vendor\x18\x02 \x01(\t\x12\r\n\x05model\x18\x03 \x01(\t\x12\x14\n\x0c\x61rchitecture\x18\x04 \x01(\t\x12\x0c\n\x04uuid\x18\x05 \x01(\x0c\x12\x0f\n\x07pci_bdf\x18\x07 \x01(\t\x12\x39\n\nextra_info\x18\x06 \x03(\x0b\x32%.perfetto.protos.GpuInfo.Gpu.KeyValue\x1a&\n\x08KeyValue\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t\"\x87\x01\n\rInterruptInfo\x12\x44\n\x0birq_mapping\x18\x01 \x03(\x0b\x32/.perfetto.protos.InterruptInfo.InterruptMapping\x1a\x30\n\x10InterruptMapping\x12\x0e\n\x06irq_id\x18\x01 \x01(\r\x12\x0c\n\x04name\x18\x02 \x01(\t\"\xce\x08\n\tTestEvent\x12\x0b\n\x03str\x18\x01 \x01(\t\x12\x11\n\tseq_value\x18\x02 \x01(\r\x12\x0f\n\x07\x63ounter\x18\x03 \x01(\x04\x12\x0f\n\x07is_last\x18\x04 \x01(\x08\x12\x37\n\x07payload\x18\x05 \x01(\x0b\x32&.perfetto.protos.TestEvent.TestPayload\x12>\n\rprotovm_patch\x18\x06 \x01(\x0b\x32\'.perfetto.protos.TestEvent.ProtoVmPatch\x12U\n\x19protovm_incremental_state\x18\x07 \x01(\x0b\x32\x32.perfetto.protos.TestEvent.ProtoVmIncrementalState\x1a\xf2\x01\n\x0bTestPayload\x12\x0b\n\x03str\x18\x01 \x03(\t\x12\x36\n\x06nested\x18\x02 \x03(\x0b\x32&.perfetto.protos.TestEvent.TestPayload\x12\x15\n\rsingle_string\x18\x04 \x01(\t\x12\x12\n\nsingle_int\x18\x05 \x01(\x05\x12\x15\n\rrepeated_ints\x18\x06 \x03(\x05\x12\x1f\n\x17remaining_nesting_depth\x18\x03 \x01(\r\x12;\n\x11\x64\x65\x62ug_annotations\x18\x07 \x03(\x0b\x32 .perfetto.protos.DebugAnnotation\x1a\x96\x01\n\x0eProtoVmMessage\x12\n\n\x02id\x18\x01 \x01(\r\x12O\n\nsubmessage\x18\x02 \x01(\x0b\x32;.perfetto.protos.TestEvent.ProtoVmMessage.ProtoVmSubmessage\x1a\'\n\x11ProtoVmSubmessage\x12\x12\n\nsingle_int\x18\x01 \x01(\r\x1a\xd9\x01\n\x0cProtoVmPatch\x12\x17\n\x0fstring_to_merge\x18\x01 \x01(\t\x12\x14\n\x0cint_to_merge\x18\x02 \x01(\x05\x12\x41\n\x0esingle_message\x18\x03 \x01(\x0b\x32).perfetto.protos.TestEvent.ProtoVmMessage\x12;\n\x08messages\x18\x04 \x03(\x0b\x32).perfetto.protos.TestEvent.ProtoVmMessage\x12\x1a\n\x12\x64\x65lete_message_ids\x18\x05 \x03(\r\x1a\xc4\x01\n\x17ProtoVmIncrementalState\x12\x15\n\rstring_merged\x18\x01 \x01(\t\x12\x12\n\nint_merged\x18\x02 \x01(\x05\x12\x41\n\x0esingle_message\x18\x03 \x01(\x0b\x32).perfetto.protos.TestEvent.ProtoVmMessage\x12;\n\x08messages\x18\x04 \x03(\x0b\x32).perfetto.protos.TestEvent.ProtoVmMessage\"\xb7\x02\n\x13TracePacketDefaults\x12\x1a\n\x12timestamp_clock_id\x18: \x01(\r\x12\x41\n\x14track_event_defaults\x18\x0b \x01(\x0b\x32#.perfetto.protos.TrackEventDefaults\x12\x41\n\x14perf_sample_defaults\x18\x0c \x01(\x0b\x32#.perfetto.protos.PerfSampleDefaults\x12\x43\n\x15stack_sample_defaults\x18\x64 \x01(\x0b\x32$.perfetto.protos.StackSampleDefaults\x12\x39\n\x10v8_code_defaults\x18\x63 \x01(\x0b\x32\x1f.perfetto.protos.V8CodeDefaults\"%\n\tTraceUuid\x12\x0b\n\x03msb\x18\x01 \x01(\x03\x12\x0b\n\x03lsb\x18\x02 \x01(\x03\"\xe7\x03\n\x11ProcessDescriptor\x12\x0b\n\x03pid\x18\x01 \x01(\x05\x12\x0f\n\x07\x63mdline\x18\x02 \x03(\t\x12\x14\n\x0cprocess_name\x18\x06 \x01(\t\x12\x18\n\x10process_priority\x18\x05 \x01(\x05\x12\x1a\n\x12start_timestamp_ns\x18\x07 \x01(\x03\x12Q\n\x13\x63hrome_process_type\x18\x04 \x01(\x0e\x32\x34.perfetto.protos.ProcessDescriptor.ChromeProcessType\x12\x19\n\x11legacy_sort_index\x18\x03 \x01(\x05\x12\x16\n\x0eprocess_labels\x18\x08 \x03(\t\"\xe1\x01\n\x11\x43hromeProcessType\x12\x17\n\x13PROCESS_UNSPECIFIED\x10\x00\x12\x13\n\x0fPROCESS_BROWSER\x10\x01\x12\x14\n\x10PROCESS_RENDERER\x10\x02\x12\x13\n\x0fPROCESS_UTILITY\x10\x03\x12\x12\n\x0ePROCESS_ZYGOTE\x10\x04\x12\x1a\n\x16PROCESS_SANDBOX_HELPER\x10\x05\x12\x0f\n\x0bPROCESS_GPU\x10\x06\x12\x18\n\x14PROCESS_PPAPI_PLUGIN\x10\x07\x12\x18\n\x14PROCESS_PPAPI_BROKER\x10\x08\"-\n\x19TrackEventRangeOfInterest\x12\x10\n\x08start_us\x18\x01 \x01(\x03\"\xf4\x05\n\x10ThreadDescriptor\x12\x0b\n\x03pid\x18\x01 \x01(\x05\x12\x0b\n\x03tid\x18\x02 \x01(\x03\x12\x13\n\x0bthread_name\x18\x05 \x01(\t\x12N\n\x12\x63hrome_thread_type\x18\x04 \x01(\x0e\x32\x32.perfetto.protos.ThreadDescriptor.ChromeThreadType\x12\x1e\n\x16reference_timestamp_us\x18\x06 \x01(\x03\x12 \n\x18reference_thread_time_us\x18\x07 \x01(\x03\x12*\n\"reference_thread_instruction_count\x18\x08 \x01(\x03\x12\x19\n\x11legacy_sort_index\x18\x03 \x01(\x05\"\xd7\x03\n\x10\x43hromeThreadType\x12\x1d\n\x19\x43HROME_THREAD_UNSPECIFIED\x10\x00\x12\x16\n\x12\x43HROME_THREAD_MAIN\x10\x01\x12\x14\n\x10\x43HROME_THREAD_IO\x10\x02\x12 \n\x1c\x43HROME_THREAD_POOL_BG_WORKER\x10\x03\x12 \n\x1c\x43HROME_THREAD_POOL_FG_WORKER\x10\x04\x12\"\n\x1e\x43HROME_THREAD_POOL_FB_BLOCKING\x10\x05\x12\"\n\x1e\x43HROME_THREAD_POOL_BG_BLOCKING\x10\x06\x12\x1e\n\x1a\x43HROME_THREAD_POOL_SERVICE\x10\x07\x12\x1c\n\x18\x43HROME_THREAD_COMPOSITOR\x10\x08\x12 \n\x1c\x43HROME_THREAD_VIZ_COMPOSITOR\x10\t\x12#\n\x1f\x43HROME_THREAD_COMPOSITOR_WORKER\x10\n\x12 \n\x1c\x43HROME_THREAD_SERVICE_WORKER\x10\x0b\x12\x1e\n\x1a\x43HROME_THREAD_MEMORY_INFRA\x10\x32\x12#\n\x1f\x43HROME_THREAD_SAMPLING_PROFILER\x10\x33\"\x9b\x01\n\x17\x43hromeProcessDescriptor\x12\x14\n\x0cprocess_type\x18\x01 \x01(\x05\x12\x18\n\x10process_priority\x18\x02 \x01(\x05\x12\x19\n\x11legacy_sort_index\x18\x03 \x01(\x05\x12\x1d\n\x15host_app_package_name\x18\x04 \x01(\t\x12\x16\n\x0e\x63rash_trace_id\x18\x05 \x01(\x04\"b\n\x16\x43hromeThreadDescriptor\x12\x13\n\x0bthread_type\x18\x01 \x01(\x05\x12\x19\n\x11legacy_sort_index\x18\x02 \x01(\x05\x12\x18\n\x10is_sandboxed_tid\x18\x03 \x01(\x08\"\xc7\x03\n\x11\x43ounterDescriptor\x12\x43\n\x04type\x18\x01 \x01(\x0e\x32\x35.perfetto.protos.CounterDescriptor.BuiltinCounterType\x12\x12\n\ncategories\x18\x02 \x03(\t\x12\x35\n\x04unit\x18\x03 \x01(\x0e\x32\'.perfetto.protos.CounterDescriptor.Unit\x12\x11\n\tunit_name\x18\x06 \x01(\t\x12\x17\n\x0funit_multiplier\x18\x04 \x01(\x03\x12\x16\n\x0eis_incremental\x18\x05 \x01(\x08\x12\x18\n\x10y_axis_share_key\x18\x07 \x01(\t\"o\n\x12\x42uiltinCounterType\x12\x17\n\x13\x43OUNTER_UNSPECIFIED\x10\x00\x12\x1a\n\x16\x43OUNTER_THREAD_TIME_NS\x10\x01\x12$\n COUNTER_THREAD_INSTRUCTION_COUNT\x10\x02\"S\n\x04Unit\x12\x14\n\x10UNIT_UNSPECIFIED\x10\x00\x12\x10\n\x0cUNIT_TIME_NS\x10\x01\x12\x0e\n\nUNIT_COUNT\x10\x02\x12\x13\n\x0fUNIT_SIZE_BYTES\x10\x03\"\x11\n\x0fStateDescriptor\"\x88\x0b\n\x0fTrackDescriptor\x12\x0c\n\x04uuid\x18\x01 \x01(\x04\x12\x13\n\x0bparent_uuid\x18\x05 \x01(\x04\x12\x0e\n\x04name\x18\x02 \x01(\tH\x00\x12\x15\n\x0bstatic_name\x18\n \x01(\tH\x00\x12\x15\n\x0b\x61trace_name\x18\r \x01(\tH\x00\x12\x13\n\x0b\x64\x65scription\x18\x0e \x01(\t\x12\x33\n\x07process\x18\x03 \x01(\x0b\x32\".perfetto.protos.ProcessDescriptor\x12@\n\x0e\x63hrome_process\x18\x06 \x01(\x0b\x32(.perfetto.protos.ChromeProcessDescriptor\x12\x31\n\x06thread\x18\x04 \x01(\x0b\x32!.perfetto.protos.ThreadDescriptor\x12>\n\rchrome_thread\x18\x07 \x01(\x0b\x32\'.perfetto.protos.ChromeThreadDescriptor\x12\x33\n\x07\x63ounter\x18\x08 \x01(\x0b\x32\".perfetto.protos.CounterDescriptor\x12/\n\x05state\x18\x12 \x01(\x0b\x32 .perfetto.protos.StateDescriptor\x12+\n#disallow_merging_with_system_tracks\x18\t \x01(\x08\x12L\n\x0e\x63hild_ordering\x18\x0b \x01(\x0e\x32\x34.perfetto.protos.TrackDescriptor.ChildTracksOrdering\x12\x1a\n\x12sibling_order_rank\x18\x0c \x01(\x05\x12U\n\x16sibling_merge_behavior\x18\x0f \x01(\x0e\x32\x35.perfetto.protos.TrackDescriptor.SiblingMergeBehavior\x12\x1b\n\x11sibling_merge_key\x18\x10 \x01(\tH\x01\x12\x1f\n\x15sibling_merge_key_int\x18\x11 \x01(\x04H\x01\x12J\n\x10process_ordering\x18\x13 \x01(\x0e\x32\x30.perfetto.protos.TrackDescriptor.ProcessOrdering\x12H\n\x0fthread_ordering\x18\x14 \x01(\x0e\x32/.perfetto.protos.TrackDescriptor.ThreadOrdering\"V\n\x13\x43hildTracksOrdering\x12\x0b\n\x07UNKNOWN\x10\x00\x12\x11\n\rLEXICOGRAPHIC\x10\x01\x12\x11\n\rCHRONOLOGICAL\x10\x02\x12\x0c\n\x08\x45XPLICIT\x10\x03\"\xba\x01\n\x14SiblingMergeBehavior\x12&\n\"SIBLING_MERGE_BEHAVIOR_UNSPECIFIED\x10\x00\x12(\n$SIBLING_MERGE_BEHAVIOR_BY_TRACK_NAME\x10\x01\x12\x1f\n\x1bSIBLING_MERGE_BEHAVIOR_NONE\x10\x02\x12/\n+SIBLING_MERGE_BEHAVIOR_BY_SIBLING_MERGE_KEY\x10\x03\"R\n\x0fProcessOrdering\x12 \n\x1cPROCESS_ORDERING_UNSPECIFIED\x10\x00\x12\x1d\n\x19PROCESS_ORDERING_EXPLICIT\x10\x01\"O\n\x0eThreadOrdering\x12\x1f\n\x1bTHREAD_ORDERING_UNSPECIFIED\x10\x00\x12\x1c\n\x18THREAD_ORDERING_EXPLICIT\x10\x01\x42\x18\n\x16static_or_dynamic_nameB\x19\n\x17sibling_merge_key_field\"\xed\x03\n\x10TranslationTable\x12M\n\x10\x63hrome_histogram\x18\x01 \x01(\x0b\x32\x31.perfetto.protos.ChromeHistorgramTranslationTableH\x00\x12M\n\x11\x63hrome_user_event\x18\x02 \x01(\x0b\x32\x30.perfetto.protos.ChromeUserEventTranslationTableH\x00\x12Y\n\x17\x63hrome_performance_mark\x18\x03 \x01(\x0b\x32\x36.perfetto.protos.ChromePerformanceMarkTranslationTableH\x00\x12@\n\nslice_name\x18\x04 \x01(\x0b\x32*.perfetto.protos.SliceNameTranslationTableH\x00\x12O\n\x12process_track_name\x18\x05 \x01(\x0b\x32\x31.perfetto.protos.ProcessTrackNameTranslationTableH\x00\x12\x44\n\x0c\x63hrome_study\x18\x06 \x01(\x0b\x32,.perfetto.protos.ChromeStudyTranslationTableH\x00\x42\x07\n\x05table\"\xae\x01\n ChromeHistorgramTranslationTable\x12W\n\x0chash_to_name\x18\x01 \x03(\x0b\x32\x41.perfetto.protos.ChromeHistorgramTranslationTable.HashToNameEntry\x1a\x31\n\x0fHashToNameEntry\x12\x0b\n\x03key\x18\x01 \x01(\x04\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"\xbf\x01\n\x1f\x43hromeUserEventTranslationTable\x12\x63\n\x13\x61\x63tion_hash_to_name\x18\x01 \x03(\x0b\x32\x46.perfetto.protos.ChromeUserEventTranslationTable.ActionHashToNameEntry\x1a\x37\n\x15\x41\x63tionHashToNameEntry\x12\x0b\n\x03key\x18\x01 \x01(\x04\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"\xe3\x02\n%ChromePerformanceMarkTranslationTable\x12\x65\n\x11site_hash_to_name\x18\x01 \x03(\x0b\x32J.perfetto.protos.ChromePerformanceMarkTranslationTable.SiteHashToNameEntry\x12\x65\n\x11mark_hash_to_name\x18\x02 \x03(\x0b\x32J.perfetto.protos.ChromePerformanceMarkTranslationTable.MarkHashToNameEntry\x1a\x35\n\x13SiteHashToNameEntry\x12\x0b\n\x03key\x18\x01 \x01(\r\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\x1a\x35\n\x13MarkHashToNameEntry\x12\x0b\n\x03key\x18\x01 \x01(\r\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"\xc2\x01\n\x19SliceNameTranslationTable\x12g\n\x18raw_to_deobfuscated_name\x18\x01 \x03(\x0b\x32\x45.perfetto.protos.SliceNameTranslationTable.RawToDeobfuscatedNameEntry\x1a<\n\x1aRawToDeobfuscatedNameEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"\xd0\x01\n ProcessTrackNameTranslationTable\x12n\n\x18raw_to_deobfuscated_name\x18\x01 \x03(\x0b\x32L.perfetto.protos.ProcessTrackNameTranslationTable.RawToDeobfuscatedNameEntry\x1a<\n\x1aRawToDeobfuscatedNameEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"\xa4\x01\n\x1b\x43hromeStudyTranslationTable\x12R\n\x0chash_to_name\x18\x01 \x03(\x0b\x32<.perfetto.protos.ChromeStudyTranslationTable.HashToNameEntry\x1a\x31\n\x0fHashToNameEntry\x12\x0b\n\x03key\x18\x01 \x01(\x04\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"k\n\x07Trigger\x12\x14\n\x0ctrigger_name\x18\x01 \x01(\t\x12\x15\n\rproducer_name\x18\x02 \x01(\t\x12\x1c\n\x14trusted_producer_uid\x18\x03 \x01(\x05\x12\x15\n\rstop_delay_ms\x18\x04 \x01(\x04\"\xc5\x01\n\x07UiState\x12\x19\n\x11timeline_start_ts\x18\x01 \x01(\x03\x12\x17\n\x0ftimeline_end_ts\x18\x02 \x01(\x03\x12\x44\n\x11highlight_process\x18\x03 \x01(\x0b\x32).perfetto.protos.UiState.HighlightProcess\x1a@\n\x10HighlightProcess\x12\r\n\x03pid\x18\x01 \x01(\rH\x00\x12\x11\n\x07\x63mdline\x18\x02 \x01(\tH\x00\x42\n\n\x08selector\"\xb3\x33\n\x0bTracePacket\x12\x11\n\ttimestamp\x18\x08 \x01(\x04\x12\x1a\n\x12timestamp_clock_id\x18: \x01(\r\x12\x32\n\x0btrack_event\x18\x0b \x01(\x0b\x32\x1b.perfetto.protos.TrackEventH\x00\x12<\n\x10track_descriptor\x18< \x01(\x0b\x32 .perfetto.protos.TrackDescriptorH\x00\x12W\n\x1fgeneric_kernel_task_state_event\x18u \x01(\x0b\x32,.perfetto.protos.GenericKernelTaskStateEventH\x00\x12X\n\x1dgeneric_kernel_cpu_freq_event\x18v \x01(\x0b\x32/.perfetto.protos.GenericKernelCpuFrequencyEventH\x00\x12Y\n generic_kernel_task_rename_event\x18x \x01(\x0b\x32-.perfetto.protos.GenericKernelTaskRenameEventH\x00\x12P\n\x1bgeneric_kernel_process_tree\x18z \x01(\x0b\x32).perfetto.protos.GenericKernelProcessTreeH\x00\x12Q\n\x1bgeneric_gpu_frequency_event\x18\x81\x01 \x01(\x0b\x32).perfetto.protos.GenericGpuFrequencyEventH\x00\x12\x34\n\x0cprocess_tree\x18\x02 \x01(\x0b\x32\x1c.perfetto.protos.ProcessTreeH\x00\x12S\n\x1dtrack_event_range_of_interest\x18Z \x01(\x0b\x32*.perfetto.protos.TrackEventRangeOfInterestH\x00\x12\x36\n\rprocess_stats\x18\t \x01(\x0b\x32\x1d.perfetto.protos.ProcessStatsH\x00\x12\x37\n\x0einode_file_map\x18\x04 \x01(\x0b\x32\x1d.perfetto.protos.InodeFileMapH\x00\x12;\n\rchrome_events\x18\x05 \x01(\x0b\x32\".perfetto.protos.ChromeEventBundleH\x00\x12\x38\n\x0e\x63lock_snapshot\x18\x06 \x01(\x0b\x32\x1e.perfetto.protos.ClockSnapshotH\x00\x12.\n\tsys_stats\x18\x07 \x01(\x0b\x32\x19.perfetto.protos.SysStatsH\x00\x12\x30\n\ntrace_uuid\x18Y \x01(\x0b\x32\x1a.perfetto.protos.TraceUuidH\x00\x12\x34\n\x0ctrace_config\x18! \x01(\x0b\x32\x1c.perfetto.protos.TraceConfigH\x00\x12\x34\n\x0c\x66trace_stats\x18\" \x01(\x0b\x32\x1c.perfetto.protos.FtraceStatsH\x00\x12\x32\n\x0btrace_stats\x18# \x01(\x0b\x32\x1b.perfetto.protos.TraceStatsH\x00\x12\x38\n\x0eprofile_packet\x18% \x01(\x0b\x32\x1e.perfetto.protos.ProfilePacketH\x00\x12\x44\n\x14streaming_allocation\x18J \x01(\x0b\x32$.perfetto.protos.StreamingAllocationH\x00\x12\x38\n\x0estreaming_free\x18K \x01(\x0b\x32\x1e.perfetto.protos.StreamingFreeH\x00\x12\x33\n\x07\x62\x61ttery\x18& \x01(\x0b\x32 .perfetto.protos.BatteryCountersH\x00\x12\x32\n\x0bpower_rails\x18( \x01(\x0b\x32\x1b.perfetto.protos.PowerRailsH\x00\x12\x38\n\x0b\x61ndroid_log\x18\' \x01(\x0b\x32!.perfetto.protos.AndroidLogPacketH\x00\x12\x32\n\x0bsystem_info\x18- \x01(\x0b\x32\x1b.perfetto.protos.SystemInfoH\x00\x12+\n\x07trigger\x18. \x01(\x0b\x32\x18.perfetto.protos.TriggerH\x00\x12\x38\n\x0e\x63hrome_trigger\x18m \x01(\x0b\x32\x1e.perfetto.protos.ChromeTriggerH\x00\x12\x36\n\rpackages_list\x18/ \x01(\x0b\x32\x1d.perfetto.protos.PackagesListH\x00\x12M\n\x19\x63hrome_benchmark_metadata\x18\x30 \x01(\x0b\x32(.perfetto.protos.ChromeBenchmarkMetadataH\x00\x12@\n\x12perfetto_metatrace\x18\x31 \x01(\x0b\x32\".perfetto.protos.PerfettoMetatraceH\x00\x12@\n\x0f\x63hrome_metadata\x18\x33 \x01(\x0b\x32%.perfetto.protos.ChromeMetadataPacketH\x00\x12=\n\x11gpu_counter_event\x18\x34 \x01(\x0b\x32 .perfetto.protos.GpuCounterEventH\x00\x12\x46\n\x16gpu_render_stage_event\x18\x35 \x01(\x0b\x32$.perfetto.protos.GpuRenderStageEventH\x00\x12K\n\x18streaming_profile_packet\x18\x36 \x01(\x0b\x32\'.perfetto.protos.StreamingProfilePacketH\x00\x12\x44\n\x14\x61rt_process_metadata\x18\x83\x01 \x01(\x0b\x32#.perfetto.protos.ArtProcessMetadataH\x00\x12\x43\n\x14graphics_frame_event\x18\x39 \x01(\x0b\x32#.perfetto.protos.GraphicsFrameEventH\x00\x12\x41\n\x13vulkan_memory_event\x18> \x01(\x0b\x32\".perfetto.protos.VulkanMemoryEventH\x00\x12*\n\x07gpu_log\x18? \x01(\x0b\x32\x17.perfetto.protos.GpuLogH\x00\x12;\n\x10vulkan_api_event\x18\x41 \x01(\x0b\x32\x1f.perfetto.protos.VulkanApiEventH\x00\x12\x32\n\x0bperf_sample\x18\x42 \x01(\x0b\x32\x1b.perfetto.protos.PerfSampleH\x00\x12,\n\x08\x63pu_info\x18\x43 \x01(\x0b\x32\x18.perfetto.protos.CpuInfoH\x00\x12\x34\n\x0csmaps_packet\x18\x44 \x01(\x0b\x32\x1c.perfetto.protos.SmapsPacketH\x00\x12=\n\rservice_event\x18\x45 \x01(\x0b\x32$.perfetto.protos.TracingServiceEventH\x00\x12L\n\x18\x63oncurrent_session_event\x18\x86\x01 \x01(\x0b\x32\'.perfetto.protos.ConcurrentSessionEventH\x00\x12\x35\n\x0cstack_sample\x18\x87\x01 \x01(\x0b\x32\x1c.perfetto.protos.StackSampleH\x00\x12\x45\n\x15initial_display_state\x18\x46 \x01(\x0b\x32$.perfetto.protos.InitialDisplayStateH\x00\x12@\n\x13gpu_mem_total_event\x18G \x01(\x0b\x32!.perfetto.protos.GpuMemTotalEventH\x00\x12I\n\x17memory_tracker_snapshot\x18I \x01(\x0b\x32&.perfetto.protos.MemoryTrackerSnapshotH\x00\x12`\n#android_energy_estimation_breakdown\x18M \x01(\x0b\x32\x31.perfetto.protos.AndroidEnergyEstimationBreakdownH\x00\x12,\n\x08ui_state\x18N \x01(\x0b\x32\x18.perfetto.protos.UiStateH\x00\x12>\n\x11translation_table\x18R \x01(\x0b\x32!.perfetto.protos.TranslationTableH\x00\x12V\n\x1e\x61ndroid_game_intervention_list\x18S \x01(\x0b\x32,.perfetto.protos.AndroidGameInterventionListH\x00\x12\x32\n\x0bstatsd_atom\x18T \x01(\x0b\x32\x1b.perfetto.protos.StatsdAtomH\x00\x12I\n\x17\x61ndroid_system_property\x18V \x01(\x0b\x32&.perfetto.protos.AndroidSystemPropertyH\x00\x12G\n\x16\x65ntity_state_residency\x18[ \x01(\x0b\x32%.perfetto.protos.EntityStateResidencyH\x00\x12<\n\x10trace_provenance\x18| \x01(\x0b\x32 .perfetto.protos.TraceProvenanceH\x00\x12\x39\n\x08protovms\x18} \x01(\x0b\x32%.perfetto.protos.TracePacket.ProtoVmsH\x00\x12<\n\x10trace_attributes\x18~ \x01(\x0b\x32 .perfetto.protos.TraceAttributesH\x00\x12\x38\n\x0e\x61ndroid_aflags\x18\x7f \x01(\x0b\x32\x1e.perfetto.protos.AndroidAflagsH\x00\x12-\n\x08gpu_info\x18\x80\x01 \x01(\x0b\x32\x18.perfetto.protos.GpuInfoH\x00\x12\x39\n\x0einterrupt_info\x18\x82\x01 \x01(\x0b\x32\x1e.perfetto.protos.InterruptInfoH\x00\x12\x38\n\x0emodule_symbols\x18= \x01(\x0b\x32\x1e.perfetto.protos.ModuleSymbolsH\x00\x12\x46\n\x15\x64\x65obfuscation_mapping\x18@ \x01(\x0b\x32%.perfetto.protos.DeobfuscationMappingH\x00\x12@\n\x12process_descriptor\x18+ \x01(\x0b\x32\".perfetto.protos.ProcessDescriptorH\x00\x12>\n\x11thread_descriptor\x18, \x01(\x0b\x32!.perfetto.protos.ThreadDescriptorH\x00\x12;\n\rftrace_events\x18\x01 \x01(\x0b\x32\".perfetto.protos.FtraceEventBundleH\x00\x12 \n\x16synchronization_marker\x18$ \x01(\x0cH\x00\x12\x1c\n\x12\x63ompressed_packets\x18\x32 \x01(\x0cH\x00\x12\"\n\x17zstd_compressed_packets\x18\x85\x01 \x01(\x0cH\x00\x12\x44\n\x14\x65xtension_descriptor\x18H \x01(\x0b\x32$.perfetto.protos.ExtensionDescriptorH\x00\x12:\n\netw_events\x18_ \x01(\x0b\x32$.perfetto.protos.EtwTraceEventBundleH\x00\x12/\n\nv8_js_code\x18\x63 \x01(\x0b\x32\x19.perfetto.protos.V8JsCodeH\x00\x12;\n\x10v8_internal_code\x18\x64 \x01(\x0b\x32\x1f.perfetto.protos.V8InternalCodeH\x00\x12\x33\n\x0cv8_wasm_code\x18\x65 \x01(\x0b\x32\x1b.perfetto.protos.V8WasmCodeH\x00\x12\x38\n\x0fv8_reg_exp_code\x18\x66 \x01(\x0b\x32\x1d.perfetto.protos.V8RegExpCodeH\x00\x12\x33\n\x0cv8_code_move\x18g \x01(\x0b\x32\x1b.perfetto.protos.V8CodeMoveH\x00\x12=\n\x11remote_clock_sync\x18k \x01(\x0b\x32 .perfetto.protos.RemoteClockSyncH\x00\x12?\n\x12pixel_modem_events\x18n \x01(\x0b\x32!.perfetto.protos.PixelModemEventsH\x00\x12N\n\x1apixel_modem_token_database\x18o \x01(\x0b\x32(.perfetto.protos.PixelModemTokenDatabaseH\x00\x12:\n\x16\x63lone_snapshot_trigger\x18q \x01(\x0b\x32\x18.perfetto.protos.TriggerH\x00\x12\x43\n\x14kernel_wakelock_data\x18s \x01(\x0b\x32#.perfetto.protos.KernelWakelockDataH\x00\x12:\n\x10\x63pu_per_uid_data\x18w \x01(\x0b\x32\x1e.perfetto.protos.CpuPerUidDataH\x00\x12\x35\n\tuser_list\x18{ \x01(\x0b\x32 .perfetto.protos.AndroidUserListH\x00\x12@\n\x0ejournald_event\x18\x84\x01 \x01(\x0b\x32%.perfetto.protos.SystemdJournaldEventH\x00\x12\x44\n\x14recovered_trace_info\x18\x8a\x01 \x01(\x0b\x32#.perfetto.protos.RecoveredTraceInfoH\x00\x12\x32\n\x0b\x66or_testing\x18\x84\x07 \x01(\x0b\x32\x1a.perfetto.protos.TestEventH\x00\x12\x15\n\x0btrusted_uid\x18\x03 \x01(\x05H\x01\x12$\n\x1atrusted_packet_sequence_id\x18\n \x01(\rH\x02\x12\x13\n\x0btrusted_pid\x18O \x01(\x05\x12\x34\n\rinterned_data\x18\x0c \x01(\x0b\x32\x1d.perfetto.protos.InternedData\x12\x16\n\x0esequence_flags\x18\r \x01(\r\x12!\n\x19incremental_state_cleared\x18) \x01(\x08\x12\x43\n\x15trace_packet_defaults\x18; \x01(\x0b\x32$.perfetto.protos.TracePacketDefaults\x12\x1f\n\x17previous_packet_dropped\x18* \x01(\r\x12 \n\x18\x66irst_packet_on_sequence\x18W \x01(\x08\x12\x12\n\nmachine_id\x18\x62 \x01(\r\x1a\xe1\x01\n\x08ProtoVms\x12@\n\x08instance\x18\x01 \x03(\x0b\x32..perfetto.protos.TracePacket.ProtoVms.Instance\x1a\x92\x01\n\x08Instance\x12+\n\x07program\x18\x01 \x01(\x0b\x32\x1a.perfetto.protos.VmProgram\x12+\n\x05state\x18\x02 \x01(\x0b\x32\x1c.perfetto.protos.TracePacket\x12\x17\n\x0fmemory_limit_kb\x18\x03 \x01(\r\x12\x13\n\x0bproducer_id\x18\x04 \x03(\x05\"h\n\rSequenceFlags\x12\x13\n\x0fSEQ_UNSPECIFIED\x10\x00\x12!\n\x1dSEQ_INCREMENTAL_STATE_CLEARED\x10\x01\x12\x1f\n\x1bSEQ_NEEDS_INCREMENTAL_STATE\x10\x02\"\xb0\x02\n\x0e\x44\x61taLossReason\x12\x19\n\x15\x44\x41TA_LOSS_UNSPECIFIED\x10\x00\x12\x15\n\x11\x44\x41TA_LOSS_PRESENT\x10\x01\x12\x16\n\x12\x44\x41TA_LOSS_READ_GAP\x10\x02\x12\x1d\n\x19\x44\x41TA_LOSS_CHUNK_CORRUPTED\x10\x04\x12!\n\x1d\x44\x41TA_LOSS_ORPHAN_CONTINUATION\x10\x08\x12\x1c\n\x18\x44\x41TA_LOSS_REASSEMBLY_GAP\x10\x10\x12%\n!DATA_LOSS_REASSEMBLY_BROKEN_CHAIN\x10 \x12\x17\n\x13\x44\x41TA_LOSS_OVERWRITE\x10@\x12\x1b\n\x16\x44\x41TA_LOSS_WRITER_ABORT\x10\x80\x01\x12\x17\n\x12\x44\x41TA_LOSS_SMB_FULL\x10\x80\x02*\x04\x08\x38\x10\x39*\x04\x08L\x10M*\x04\x08X\x10Y*\x04\x08\\\x10]*\x04\x08]\x10^*\x04\x08^\x10_*\x04\x08`\x10\x61*\x04\x08\x61\x10\x62*\x04\x08h\x10i*\x04\x08i\x10j*\x04\x08p\x10q*\x04\x08r\x10s*\x04\x08t\x10u*\x04\x08y\x10z*\x06\x08\xe8\x07\x10\xd0\x0f\x42\x06\n\x04\x64\x61taB\x16\n\x14optional_trusted_uidB%\n#optional_trusted_packet_sequence_idJ\x04\x08j\x10kJ\x04\x08\x37\x10\x38J\x04\x08P\x10QJ\x04\x08Q\x10R\"5\n\x05Trace\x12,\n\x06packet\x18\x01 \x03(\x0b\x32\x1c.perfetto.protos.TracePacket*c\n\x0cVmCursorEnum\x12\x19\n\x15VM_CURSOR_UNSPECIFIED\x10\x00\x12\x11\n\rVM_CURSOR_SRC\x10\x01\x12\x11\n\rVM_CURSOR_DST\x10\x02\x12\x12\n\x0eVM_CURSOR_BOTH\x10\x03*\xd9\x02\n\x0c\x42uiltinClock\x12\x19\n\x15\x42UILTIN_CLOCK_UNKNOWN\x10\x00\x12\x1a\n\x16\x42UILTIN_CLOCK_REALTIME\x10\x01\x12!\n\x1d\x42UILTIN_CLOCK_REALTIME_COARSE\x10\x02\x12\x1b\n\x17\x42UILTIN_CLOCK_MONOTONIC\x10\x03\x12\"\n\x1e\x42UILTIN_CLOCK_MONOTONIC_COARSE\x10\x04\x12\x1f\n\x1b\x42UILTIN_CLOCK_MONOTONIC_RAW\x10\x05\x12\x1a\n\x16\x42UILTIN_CLOCK_BOOTTIME\x10\x06\x12\x15\n\x11\x42UILTIN_CLOCK_TSC\x10\t\x12\x16\n\x12\x42UILTIN_CLOCK_PERF\x10\n\x12\x1c\n\x18\x42UILTIN_CLOCK_TRACE_FILE\x10\x0b\x12\x18\n\x14\x42UILTIN_CLOCK_MAX_ID\x10?\"\x04\x08\x07\x10\x07\"\x04\x08\x08\x10\x08*z\n\x0cSemanticType\x12\x1d\n\x19SEMANTIC_TYPE_UNSPECIFIED\x10\x00\x12\x18\n\x14SEMANTIC_TYPE_ATRACE\x10\x01\x12\x15\n\x11SEMANTIC_TYPE_JOB\x10\x02\x12\x1a\n\x16SEMANTIC_TYPE_WAKELOCK\x10\x03*\x8e\x01\n\x0c\x41ndroidLogId\x12\x0f\n\x0bLID_DEFAULT\x10\x00\x12\r\n\tLID_RADIO\x10\x01\x12\x0e\n\nLID_EVENTS\x10\x02\x12\x0e\n\nLID_SYSTEM\x10\x03\x12\r\n\tLID_CRASH\x10\x04\x12\r\n\tLID_STATS\x10\x05\x12\x10\n\x0cLID_SECURITY\x10\x06\x12\x0e\n\nLID_KERNEL\x10\x07*\x9b\x01\n\x12\x41ndroidLogPriority\x12\x14\n\x10PRIO_UNSPECIFIED\x10\x00\x12\x0f\n\x0bPRIO_UNUSED\x10\x01\x12\x10\n\x0cPRIO_VERBOSE\x10\x02\x12\x0e\n\nPRIO_DEBUG\x10\x03\x12\r\n\tPRIO_INFO\x10\x04\x12\r\n\tPRIO_WARN\x10\x05\x12\x0e\n\nPRIO_ERROR\x10\x06\x12\x0e\n\nPRIO_FATAL\x10\x07*\xc7\x01\n\rProtoLogLevel\x12\x1c\n\x18PROTOLOG_LEVEL_UNDEFINED\x10\x00\x12\x18\n\x14PROTOLOG_LEVEL_DEBUG\x10\x01\x12\x1a\n\x16PROTOLOG_LEVEL_VERBOSE\x10\x02\x12\x17\n\x13PROTOLOG_LEVEL_INFO\x10\x03\x12\x17\n\x13PROTOLOG_LEVEL_WARN\x10\x04\x12\x18\n\x14PROTOLOG_LEVEL_ERROR\x10\x05\x12\x16\n\x12PROTOLOG_LEVEL_WTF\x10\x06*\xf3\xfb\x02\n\x06\x41tomId\x12\x14\n\x10\x41TOM_UNSPECIFIED\x10\x00\x12\x1f\n\x1b\x41TOM_BLE_SCAN_STATE_CHANGED\x10\x02\x12\x1e\n\x1a\x41TOM_PROCESS_STATE_CHANGED\x10\x03\x12!\n\x1d\x41TOM_BLE_SCAN_RESULT_RECEIVED\x10\x04\x12\x1d\n\x19\x41TOM_SENSOR_STATE_CHANGED\x10\x05\x12\x1f\n\x1b\x41TOM_GPS_SCAN_STATE_CHANGED\x10\x06\x12\x1b\n\x17\x41TOM_SYNC_STATE_CHANGED\x10\x07\x12$\n ATOM_SCHEDULED_JOB_STATE_CHANGED\x10\x08\x12\"\n\x1e\x41TOM_SCREEN_BRIGHTNESS_CHANGED\x10\t\x12\x1f\n\x1b\x41TOM_WAKELOCK_STATE_CHANGED\x10\n\x12,\n(ATOM_LONG_PARTIAL_WAKELOCK_STATE_CHANGED\x10\x0b\x12)\n%ATOM_MOBILE_RADIO_POWER_STATE_CHANGED\x10\x0c\x12\'\n#ATOM_WIFI_RADIO_POWER_STATE_CHANGED\x10\r\x12-\n)ATOM_ACTIVITY_MANAGER_SLEEP_STATE_CHANGED\x10\x0e\x12$\n ATOM_MEMORY_FACTOR_STATE_CHANGED\x10\x0f\x12%\n!ATOM_EXCESSIVE_CPU_USAGE_REPORTED\x10\x10\x12\x1d\n\x19\x41TOM_CACHED_KILL_REPORTED\x10\x11\x12%\n!ATOM_PROCESS_MEMORY_STAT_REPORTED\x10\x12\x12\x17\n\x13\x41TOM_LAUNCHER_EVENT\x10\x13\x12)\n%ATOM_BATTERY_SAVER_MODE_STATE_CHANGED\x10\x14\x12\'\n#ATOM_DEVICE_IDLE_MODE_STATE_CHANGED\x10\x15\x12)\n%ATOM_DEVICE_IDLING_MODE_STATE_CHANGED\x10\x16\x12\x1c\n\x18\x41TOM_AUDIO_STATE_CHANGED\x10\x17\x12\"\n\x1e\x41TOM_MEDIA_CODEC_STATE_CHANGED\x10\x18\x12\x1d\n\x19\x41TOM_CAMERA_STATE_CHANGED\x10\x19\x12!\n\x1d\x41TOM_FLASHLIGHT_STATE_CHANGED\x10\x1a\x12\"\n\x1e\x41TOM_UID_PROCESS_STATE_CHANGED\x10\x1b\x12)\n%ATOM_PROCESS_LIFE_CYCLE_STATE_CHANGED\x10\x1c\x12\x1d\n\x19\x41TOM_SCREEN_STATE_CHANGED\x10\x1d\x12\x1e\n\x1a\x41TOM_BATTERY_LEVEL_CHANGED\x10\x1e\x12\x1f\n\x1b\x41TOM_CHARGING_STATE_CHANGED\x10\x1f\x12\x1e\n\x1a\x41TOM_PLUGGED_STATE_CHANGED\x10 \x12\"\n\x1e\x41TOM_INTERACTIVE_STATE_CHANGED\x10!\x12\x1d\n\x19\x41TOM_TOUCH_EVENT_REPORTED\x10\"\x12\x1e\n\x1a\x41TOM_WAKEUP_ALARM_OCCURRED\x10#\x12\x1f\n\x1b\x41TOM_KERNEL_WAKEUP_REPORTED\x10$\x12 \n\x1c\x41TOM_WIFI_LOCK_STATE_CHANGED\x10%\x12%\n!ATOM_WIFI_SIGNAL_STRENGTH_CHANGED\x10&\x12 \n\x1c\x41TOM_WIFI_SCAN_STATE_CHANGED\x10\'\x12&\n\"ATOM_PHONE_SIGNAL_STRENGTH_CHANGED\x10(\x12\x18\n\x14\x41TOM_SETTING_CHANGED\x10)\x12*\n&ATOM_ACTIVITY_FOREGROUND_STATE_CHANGED\x10*\x12\x1d\n\x19\x41TOM_ISOLATED_UID_CHANGED\x10+\x12\x1f\n\x1b\x41TOM_PACKET_WAKEUP_OCCURRED\x10,\x12 \n\x1c\x41TOM_WALL_CLOCK_TIME_SHIFTED\x10-\x12\x19\n\x15\x41TOM_ANOMALY_DETECTED\x10.\x12 \n\x1c\x41TOM_APP_BREADCRUMB_REPORTED\x10/\x12\x1b\n\x17\x41TOM_APP_START_OCCURRED\x10\x30\x12\x1b\n\x17\x41TOM_APP_START_CANCELED\x10\x31\x12\x1e\n\x1a\x41TOM_APP_START_FULLY_DRAWN\x10\x32\x12\x1a\n\x16\x41TOM_LMK_KILL_OCCURRED\x10\x33\x12)\n%ATOM_PICTURE_IN_PICTURE_STATE_CHANGED\x10\x34\x12*\n&ATOM_WIFI_MULTICAST_LOCK_STATE_CHANGED\x10\x35\x12(\n$ATOM_APP_START_MEMORY_STATE_CAPTURED\x10\x37\x12#\n\x1f\x41TOM_SHUTDOWN_SEQUENCE_REPORTED\x10\x38\x12\x1f\n\x1b\x41TOM_BOOT_SEQUENCE_REPORTED\x10\x39\x12\x1e\n\x1a\x41TOM_OVERLAY_STATE_CHANGED\x10;\x12)\n%ATOM_FOREGROUND_SERVICE_STATE_CHANGED\x10<\x12\x1b\n\x17\x41TOM_CALL_STATE_CHANGED\x10=\x12\x1f\n\x1b\x41TOM_KEYGUARD_STATE_CHANGED\x10>\x12\'\n#ATOM_KEYGUARD_BOUNCER_STATE_CHANGED\x10?\x12*\n&ATOM_KEYGUARD_BOUNCER_PASSWORD_ENTERED\x10@\x12\x11\n\rATOM_APP_DIED\x10\x41\x12\'\n#ATOM_RESOURCE_CONFIGURATION_CHANGED\x10\x42\x12(\n$ATOM_BLUETOOTH_ENABLED_STATE_CHANGED\x10\x43\x12+\n\'ATOM_BLUETOOTH_CONNECTION_STATE_CHANGED\x10\x44\x12#\n\x1f\x41TOM_GPS_SIGNAL_QUALITY_CHANGED\x10\x45\x12$\n ATOM_USB_CONNECTOR_STATE_CHANGED\x10\x46\x12#\n\x1f\x41TOM_SPEAKER_IMPEDANCE_REPORTED\x10G\x12\x18\n\x14\x41TOM_HARDWARE_FAILED\x10H\x12\x1f\n\x1b\x41TOM_PHYSICAL_DROP_DETECTED\x10I\x12\x1f\n\x1b\x41TOM_CHARGE_CYCLES_REPORTED\x10J\x12(\n$ATOM_MOBILE_CONNECTION_STATE_CHANGED\x10K\x12(\n$ATOM_MOBILE_RADIO_TECHNOLOGY_CHANGED\x10L\x12\x1c\n\x18\x41TOM_USB_DEVICE_ATTACHED\x10M\x12\x1b\n\x17\x41TOM_APP_CRASH_OCCURRED\x10N\x12\x15\n\x11\x41TOM_ANR_OCCURRED\x10O\x12\x15\n\x11\x41TOM_WTF_OCCURRED\x10P\x12\x19\n\x15\x41TOM_LOW_MEM_REPORTED\x10Q\x12\x15\n\x11\x41TOM_GENERIC_ATOM\x10R\x12\x1f\n\x1b\x41TOM_VIBRATOR_STATE_CHANGED\x10T\x12$\n ATOM_DEFERRED_JOB_STATS_REPORTED\x10U\x12\x1b\n\x17\x41TOM_THERMAL_THROTTLING\x10V\x12\x1b\n\x17\x41TOM_BIOMETRIC_ACQUIRED\x10W\x12 \n\x1c\x41TOM_BIOMETRIC_AUTHENTICATED\x10X\x12!\n\x1d\x41TOM_BIOMETRIC_ERROR_OCCURRED\x10Y\x12\x1a\n\x16\x41TOM_UI_EVENT_REPORTED\x10Z\x12 \n\x1c\x41TOM_BATTERY_HEALTH_SNAPSHOT\x10[\x12\x10\n\x0c\x41TOM_SLOW_IO\x10\\\x12 \n\x1c\x41TOM_BATTERY_CAUSED_SHUTDOWN\x10]\x12$\n ATOM_PHONE_SERVICE_STATE_CHANGED\x10^\x12\x1c\n\x18\x41TOM_PHONE_STATE_CHANGED\x10_\x12!\n\x1d\x41TOM_USER_RESTRICTION_CHANGED\x10`\x12\x1c\n\x18\x41TOM_SETTINGS_UI_CHANGED\x10\x61\x12#\n\x1f\x41TOM_CONNECTIVITY_STATE_CHANGED\x10\x62\x12\x1e\n\x1a\x41TOM_SERVICE_STATE_CHANGED\x10\x63\x12 \n\x1c\x41TOM_SERVICE_LAUNCH_REPORTED\x10\x64\x12\"\n\x1e\x41TOM_FLAG_FLIP_UPDATE_OCCURRED\x10\x65\x12\"\n\x1e\x41TOM_BINARY_PUSH_STATE_CHANGED\x10\x66\x12\x1c\n\x18\x41TOM_DEVICE_POLICY_EVENT\x10g\x12!\n\x1d\x41TOM_DOCS_UI_FILE_OP_CANCELED\x10h\x12\x30\n,ATOM_DOCS_UI_FILE_OP_COPY_MOVE_MODE_REPORTED\x10i\x12 \n\x1c\x41TOM_DOCS_UI_FILE_OP_FAILURE\x10j\x12!\n\x1d\x41TOM_DOCS_UI_PROVIDER_FILE_OP\x10k\x12.\n*ATOM_DOCS_UI_INVALID_SCOPED_ACCESS_REQUEST\x10l\x12 \n\x1c\x41TOM_DOCS_UI_LAUNCH_REPORTED\x10m\x12\x1d\n\x19\x41TOM_DOCS_UI_ROOT_VISITED\x10n\x12\x1b\n\x17\x41TOM_DOCS_UI_STARTUP_MS\x10o\x12%\n!ATOM_DOCS_UI_USER_ACTION_REPORTED\x10p\x12#\n\x1f\x41TOM_WIFI_ENABLED_STATE_CHANGED\x10q\x12#\n\x1f\x41TOM_WIFI_RUNNING_STATE_CHANGED\x10r\x12\x16\n\x12\x41TOM_APP_COMPACTED\x10s\x12#\n\x1f\x41TOM_NETWORK_DNS_EVENT_REPORTED\x10t\x12.\n*ATOM_DOCS_UI_PICKER_LAUNCHED_FROM_REPORTED\x10u\x12%\n!ATOM_DOCS_UI_PICK_RESULT_REPORTED\x10v\x12%\n!ATOM_DOCS_UI_SEARCH_MODE_REPORTED\x10w\x12%\n!ATOM_DOCS_UI_SEARCH_TYPE_REPORTED\x10x\x12\x19\n\x15\x41TOM_DATA_STALL_EVENT\x10y\x12$\n ATOM_RESCUE_PARTY_RESET_REPORTED\x10z\x12\x1f\n\x1b\x41TOM_SIGNED_CONFIG_REPORTED\x10{\x12\x1f\n\x1b\x41TOM_GNSS_NI_EVENT_REPORTED\x10|\x12.\n*ATOM_BLUETOOTH_LINK_LAYER_CONNECTION_EVENT\x10}\x12/\n+ATOM_BLUETOOTH_ACL_CONNECTION_STATE_CHANGED\x10~\x12/\n+ATOM_BLUETOOTH_SCO_CONNECTION_STATE_CHANGED\x10\x7f\x12\x18\n\x13\x41TOM_APP_DOWNGRADED\x10\x80\x01\x12(\n#ATOM_APP_OPTIMIZED_AFTER_DOWNGRADED\x10\x81\x01\x12#\n\x1e\x41TOM_LOW_STORAGE_STATE_CHANGED\x10\x82\x01\x12(\n#ATOM_GNSS_NFW_NOTIFICATION_REPORTED\x10\x83\x01\x12%\n ATOM_GNSS_CONFIGURATION_REPORTED\x10\x84\x01\x12*\n%ATOM_USB_PORT_OVERHEAT_EVENT_REPORTED\x10\x85\x01\x12\x1c\n\x17\x41TOM_NFC_ERROR_OCCURRED\x10\x86\x01\x12\x1b\n\x16\x41TOM_NFC_STATE_CHANGED\x10\x87\x01\x12\x1b\n\x16\x41TOM_NFC_BEAM_OCCURRED\x10\x88\x01\x12$\n\x1f\x41TOM_NFC_CARDEMULATION_OCCURRED\x10\x89\x01\x12\x1a\n\x15\x41TOM_NFC_TAG_OCCURRED\x10\x8a\x01\x12&\n!ATOM_NFC_HCE_TRANSACTION_OCCURRED\x10\x8b\x01\x12\x1a\n\x15\x41TOM_SE_STATE_CHANGED\x10\x8c\x01\x12\x1b\n\x16\x41TOM_SE_OMAPI_REPORTED\x10\x8d\x01\x12-\n(ATOM_BROADCAST_DISPATCH_LATENCY_REPORTED\x10\x8e\x01\x12\x33\n.ATOM_ATTENTION_MANAGER_SERVICE_RESULT_REPORTED\x10\x8f\x01\x12 \n\x1b\x41TOM_ADB_CONNECTION_CHANGED\x10\x90\x01\x12\"\n\x1d\x41TOM_SPEECH_DSP_STAT_REPORTED\x10\x91\x01\x12\"\n\x1d\x41TOM_USB_CONTAMINANT_REPORTED\x10\x92\x01\x12$\n\x1f\x41TOM_WATCHDOG_ROLLBACK_OCCURRED\x10\x93\x01\x12\x30\n+ATOM_BIOMETRIC_SYSTEM_HEALTH_ISSUE_DETECTED\x10\x94\x01\x12\x1b\n\x16\x41TOM_BUBBLE_UI_CHANGED\x10\x95\x01\x12*\n%ATOM_SCHEDULED_JOB_CONSTRAINT_CHANGED\x10\x96\x01\x12)\n$ATOM_BLUETOOTH_ACTIVE_DEVICE_CHANGED\x10\x97\x01\x12/\n*ATOM_BLUETOOTH_A2DP_PLAYBACK_STATE_CHANGED\x10\x98\x01\x12-\n(ATOM_BLUETOOTH_A2DP_CODEC_CONFIG_CHANGED\x10\x99\x01\x12\x31\n,ATOM_BLUETOOTH_A2DP_CODEC_CAPABILITY_CHANGED\x10\x9a\x01\x12\x30\n+ATOM_BLUETOOTH_A2DP_AUDIO_UNDERRUN_REPORTED\x10\x9b\x01\x12/\n*ATOM_BLUETOOTH_A2DP_AUDIO_OVERRUN_REPORTED\x10\x9c\x01\x12(\n#ATOM_BLUETOOTH_DEVICE_RSSI_REPORTED\x10\x9d\x01\x12:\n5ATOM_BLUETOOTH_DEVICE_FAILED_CONTACT_COUNTER_REPORTED\x10\x9e\x01\x12\x32\n-ATOM_BLUETOOTH_DEVICE_TX_POWER_LEVEL_REPORTED\x10\x9f\x01\x12(\n#ATOM_BLUETOOTH_HCI_TIMEOUT_REPORTED\x10\xa0\x01\x12+\n&ATOM_BLUETOOTH_QUALITY_REPORT_REPORTED\x10\xa1\x01\x12(\n#ATOM_BLUETOOTH_DEVICE_INFO_REPORTED\x10\xa2\x01\x12\x30\n+ATOM_BLUETOOTH_REMOTE_VERSION_INFO_REPORTED\x10\xa3\x01\x12*\n%ATOM_BLUETOOTH_SDP_ATTRIBUTE_REPORTED\x10\xa4\x01\x12&\n!ATOM_BLUETOOTH_BOND_STATE_CHANGED\x10\xa5\x01\x12\x32\n-ATOM_BLUETOOTH_CLASSIC_PAIRING_EVENT_REPORTED\x10\xa6\x01\x12.\n)ATOM_BLUETOOTH_SMP_PAIRING_EVENT_REPORTED\x10\xa7\x01\x12+\n&ATOM_SCREEN_TIMEOUT_EXTENSION_REPORTED\x10\xa8\x01\x12\x1c\n\x17\x41TOM_PROCESS_START_TIME\x10\xa9\x01\x12\x32\n-ATOM_PERMISSION_GRANT_REQUEST_RESULT_REPORTED\x10\xaa\x01\x12\x33\n.ATOM_BLUETOOTH_SOCKET_CONNECTION_STATE_CHANGED\x10\xab\x01\x12)\n$ATOM_DEVICE_IDENTIFIER_ACCESS_DENIED\x10\xac\x01\x12)\n$ATOM_BUBBLE_DEVELOPER_ERROR_REPORTED\x10\xad\x01\x12\'\n\"ATOM_ASSIST_GESTURE_STAGE_REPORTED\x10\xae\x01\x12*\n%ATOM_ASSIST_GESTURE_FEEDBACK_REPORTED\x10\xaf\x01\x12*\n%ATOM_ASSIST_GESTURE_PROGRESS_REPORTED\x10\xb0\x01\x12\"\n\x1d\x41TOM_TOUCH_GESTURE_CLASSIFIED\x10\xb1\x01\x12\x19\n\x14\x41TOM_HIDDEN_API_USED\x10\xb2\x01\x12\x1a\n\x15\x41TOM_STYLE_UI_CHANGED\x10\xb3\x01\x12\'\n\"ATOM_PRIVACY_INDICATORS_INTERACTED\x10\xb4\x01\x12\x32\n-ATOM_APP_INSTALL_ON_EXTERNAL_STORAGE_REPORTED\x10\xb5\x01\x12 \n\x1b\x41TOM_NETWORK_STACK_REPORTED\x10\xb6\x01\x12$\n\x1f\x41TOM_APP_MOVED_STORAGE_REPORTED\x10\xb7\x01\x12\x1c\n\x17\x41TOM_BIOMETRIC_ENROLLED\x10\xb8\x01\x12)\n$ATOM_SYSTEM_SERVER_WATCHDOG_OCCURRED\x10\xb9\x01\x12\x1d\n\x18\x41TOM_TOMB_STONE_OCCURRED\x10\xba\x01\x12,\n\'ATOM_BLUETOOTH_CLASS_OF_DEVICE_REPORTED\x10\xbb\x01\x12%\n ATOM_INTELLIGENCE_EVENT_REPORTED\x10\xbc\x01\x12\x33\n.ATOM_THERMAL_THROTTLING_SEVERITY_STATE_CHANGED\x10\xbd\x01\x12&\n!ATOM_ROLE_REQUEST_RESULT_REPORTED\x10\xbe\x01\x12+\n&ATOM_MEDIAMETRICS_AUDIOPOLICY_REPORTED\x10\xbf\x01\x12+\n&ATOM_MEDIAMETRICS_AUDIORECORD_REPORTED\x10\xc0\x01\x12+\n&ATOM_MEDIAMETRICS_AUDIOTHREAD_REPORTED\x10\xc1\x01\x12*\n%ATOM_MEDIAMETRICS_AUDIOTRACK_REPORTED\x10\xc2\x01\x12%\n ATOM_MEDIAMETRICS_CODEC_REPORTED\x10\xc3\x01\x12,\n\'ATOM_MEDIAMETRICS_DRM_WIDEVINE_REPORTED\x10\xc4\x01\x12)\n$ATOM_MEDIAMETRICS_EXTRACTOR_REPORTED\x10\xc5\x01\x12(\n#ATOM_MEDIAMETRICS_MEDIADRM_REPORTED\x10\xc6\x01\x12(\n#ATOM_MEDIAMETRICS_NUPLAYER_REPORTED\x10\xc7\x01\x12(\n#ATOM_MEDIAMETRICS_RECORDER_REPORTED\x10\xc8\x01\x12*\n%ATOM_MEDIAMETRICS_DRMMANAGER_REPORTED\x10\xc9\x01\x12!\n\x1c\x41TOM_CAR_POWER_STATE_CHANGED\x10\xcb\x01\x12\x1a\n\x15\x41TOM_GARAGE_MODE_INFO\x10\xcc\x01\x12\x1c\n\x17\x41TOM_TEST_ATOM_REPORTED\x10\xcd\x01\x12\x32\n-ATOM_CONTENT_CAPTURE_CALLER_MISMATCH_REPORTED\x10\xce\x01\x12(\n#ATOM_CONTENT_CAPTURE_SERVICE_EVENTS\x10\xcf\x01\x12(\n#ATOM_CONTENT_CAPTURE_SESSION_EVENTS\x10\xd0\x01\x12!\n\x1c\x41TOM_CONTENT_CAPTURE_FLUSHED\x10\xd1\x01\x12-\n(ATOM_LOCATION_MANAGER_API_USAGE_REPORTED\x10\xd2\x01\x12\x35\n0ATOM_REVIEW_PERMISSIONS_FRAGMENT_RESULT_REPORTED\x10\xd3\x01\x12,\n\'ATOM_RUNTIME_PERMISSIONS_UPGRADE_RESULT\x10\xd4\x01\x12\x33\n.ATOM_GRANT_PERMISSIONS_ACTIVITY_BUTTON_ACTIONS\x10\xd5\x01\x12\x33\n.ATOM_LOCATION_ACCESS_CHECK_NOTIFICATION_ACTION\x10\xd6\x01\x12\x31\n,ATOM_APP_PERMISSION_FRAGMENT_ACTION_REPORTED\x10\xd7\x01\x12(\n#ATOM_APP_PERMISSION_FRAGMENT_VIEWED\x10\xd8\x01\x12)\n$ATOM_APP_PERMISSIONS_FRAGMENT_VIEWED\x10\xd9\x01\x12)\n$ATOM_PERMISSION_APPS_FRAGMENT_VIEWED\x10\xda\x01\x12\x1e\n\x19\x41TOM_TEXT_SELECTION_EVENT\x10\xdb\x01\x12\x1c\n\x17\x41TOM_TEXT_LINKIFY_EVENT\x10\xdc\x01\x12$\n\x1f\x41TOM_CONVERSATION_ACTIONS_EVENT\x10\xdd\x01\x12\"\n\x1d\x41TOM_LANGUAGE_DETECTION_EVENT\x10\xde\x01\x12&\n!ATOM_EXCLUSION_RECT_STATE_CHANGED\x10\xdf\x01\x12(\n#ATOM_BACK_GESTURE_REPORTED_REPORTED\x10\xe0\x01\x12/\n*ATOM_UPDATE_ENGINE_UPDATE_ATTEMPT_REPORTED\x10\xe1\x01\x12\x32\n-ATOM_UPDATE_ENGINE_SUCCESSFUL_UPDATE_REPORTED\x10\xe2\x01\x12\x1d\n\x18\x41TOM_CAMERA_ACTION_EVENT\x10\xe3\x01\x12+\n&ATOM_APP_COMPATIBILITY_CHANGE_REPORTED\x10\xe4\x01\x12\x1b\n\x16\x41TOM_PERFETTO_UPLOADED\x10\xe5\x01\x12-\n(ATOM_VMS_CLIENT_CONNECTION_STATE_CHANGED\x10\xe6\x01\x12&\n!ATOM_MEDIA_PROVIDER_SCAN_OCCURRED\x10\xe9\x01\x12\x1f\n\x1a\x41TOM_MEDIA_CONTENT_DELETED\x10\xea\x01\x12-\n(ATOM_MEDIA_PROVIDER_PERMISSION_REQUESTED\x10\xeb\x01\x12\'\n\"ATOM_MEDIA_PROVIDER_SCHEMA_CHANGED\x10\xec\x01\x12\x32\n-ATOM_MEDIA_PROVIDER_IDLE_MAINTENANCE_FINISHED\x10\xed\x01\x12)\n$ATOM_REBOOT_ESCROW_RECOVERY_REPORTED\x10\xee\x01\x12+\n&ATOM_BOOT_TIME_EVENT_DURATION_REPORTED\x10\xef\x01\x12/\n*ATOM_BOOT_TIME_EVENT_ELAPSED_TIME_REPORTED\x10\xf0\x01\x12+\n&ATOM_BOOT_TIME_EVENT_UTC_TIME_REPORTED\x10\xf1\x01\x12-\n(ATOM_BOOT_TIME_EVENT_ERROR_CODE_REPORTED\x10\xf2\x01\x12#\n\x1e\x41TOM_USERSPACE_REBOOT_REPORTED\x10\xf3\x01\x12\x1f\n\x1a\x41TOM_NOTIFICATION_REPORTED\x10\xf4\x01\x12%\n ATOM_NOTIFICATION_PANEL_REPORTED\x10\xf5\x01\x12\'\n\"ATOM_NOTIFICATION_CHANNEL_MODIFIED\x10\xf6\x01\x12)\n$ATOM_INTEGRITY_CHECK_RESULT_REPORTED\x10\xf7\x01\x12 \n\x1b\x41TOM_INTEGRITY_RULES_PUSHED\x10\xf8\x01\x12\x1d\n\x18\x41TOM_CB_MESSAGE_REPORTED\x10\xf9\x01\x12\x1a\n\x15\x41TOM_CB_MESSAGE_ERROR\x10\xfa\x01\x12#\n\x1e\x41TOM_WIFI_HEALTH_STAT_REPORTED\x10\xfb\x01\x12$\n\x1f\x41TOM_WIFI_FAILURE_STAT_REPORTED\x10\xfc\x01\x12)\n$ATOM_WIFI_CONNECTION_RESULT_REPORTED\x10\xfd\x01\x12\x1c\n\x17\x41TOM_APP_FREEZE_CHANGED\x10\xfe\x01\x12!\n\x1c\x41TOM_SNAPSHOT_MERGE_REPORTED\x10\xff\x01\x12\x31\n,ATOM_FOREGROUND_SERVICE_APP_OP_SESSION_ENDED\x10\x80\x02\x12\x1f\n\x1a\x41TOM_DISPLAY_JANK_REPORTED\x10\x81\x02\x12$\n\x1f\x41TOM_APP_STANDBY_BUCKET_CHANGED\x10\x82\x02\x12\x1c\n\x17\x41TOM_SHARESHEET_STARTED\x10\x83\x02\x12\x1a\n\x15\x41TOM_RANKING_SELECTED\x10\x84\x02\x12\"\n\x1d\x41TOM_TVSETTINGS_UI_INTERACTED\x10\x85\x02\x12\x1b\n\x16\x41TOM_LAUNCHER_SNAPSHOT\x10\x86\x02\x12\'\n\"ATOM_PACKAGE_INSTALLER_V2_REPORTED\x10\x87\x02\x12)\n$ATOM_USER_LIFECYCLE_JOURNEY_REPORTED\x10\x88\x02\x12\'\n\"ATOM_USER_LIFECYCLE_EVENT_OCCURRED\x10\x89\x02\x12)\n$ATOM_ACCESSIBILITY_SHORTCUT_REPORTED\x10\x8a\x02\x12(\n#ATOM_ACCESSIBILITY_SERVICE_REPORTED\x10\x8b\x02\x12(\n#ATOM_DOCS_UI_DRAG_AND_DROP_REPORTED\x10\x8c\x02\x12\"\n\x1d\x41TOM_APP_USAGE_EVENT_OCCURRED\x10\x8d\x02\x12*\n%ATOM_AUTO_REVOKE_NOTIFICATION_CLICKED\x10\x8e\x02\x12)\n$ATOM_AUTO_REVOKE_FRAGMENT_APP_VIEWED\x10\x8f\x02\x12&\n!ATOM_AUTO_REVOKED_APP_INTERACTION\x10\x90\x02\x12;\n6ATOM_APP_PERMISSION_GROUPS_FRAGMENT_AUTO_REVOKE_ACTION\x10\x91\x02\x12\"\n\x1d\x41TOM_EVS_USAGE_STATS_REPORTED\x10\x92\x02\x12)\n$ATOM_AUDIO_POWER_USAGE_DATA_REPORTED\x10\x93\x02\x12 \n\x1b\x41TOM_TV_TUNER_STATE_CHANGED\x10\x94\x02\x12(\n#ATOM_MEDIAOUTPUT_OP_SWITCH_REPORTED\x10\x95\x02\x12\x1d\n\x18\x41TOM_CB_MESSAGE_FILTERED\x10\x96\x02\x12\x1d\n\x18\x41TOM_TV_TUNER_DVR_STATUS\x10\x97\x02\x12$\n\x1f\x41TOM_TV_CAS_SESSION_OPEN_STATUS\x10\x98\x02\x12\'\n\"ATOM_ASSISTANT_INVOCATION_REPORTED\x10\x99\x02\x12\x1f\n\x1a\x41TOM_DISPLAY_WAKE_REPORTED\x10\x9a\x02\x12\x33\n.ATOM_CAR_USER_HAL_MODIFY_USER_REQUEST_REPORTED\x10\x9b\x02\x12\x34\n/ATOM_CAR_USER_HAL_MODIFY_USER_RESPONSE_REPORTED\x10\x9c\x02\x12\x34\n/ATOM_CAR_USER_HAL_POST_SWITCH_RESPONSE_REPORTED\x10\x9d\x02\x12\x39\n4ATOM_CAR_USER_HAL_INITIAL_USER_INFO_REQUEST_REPORTED\x10\x9e\x02\x12:\n5ATOM_CAR_USER_HAL_INITIAL_USER_INFO_RESPONSE_REPORTED\x10\x9f\x02\x12\x38\n3ATOM_CAR_USER_HAL_USER_ASSOCIATION_REQUEST_REPORTED\x10\xa0\x02\x12=\n8ATOM_CAR_USER_HAL_SET_USER_ASSOCIATION_RESPONSE_REPORTED\x10\xa1\x02\x12*\n%ATOM_NETWORK_IP_PROVISIONING_REPORTED\x10\xa2\x02\x12%\n ATOM_NETWORK_DHCP_RENEW_REPORTED\x10\xa3\x02\x12%\n ATOM_NETWORK_VALIDATION_REPORTED\x10\xa4\x02\x12&\n!ATOM_NETWORK_STACK_QUIRK_REPORTED\x10\xa5\x02\x12\x36\n1ATOM_MEDIAMETRICS_AUDIORECORDDEVICEUSAGE_REPORTED\x10\xa6\x02\x12\x36\n1ATOM_MEDIAMETRICS_AUDIOTHREADDEVICEUSAGE_REPORTED\x10\xa7\x02\x12\x35\n0ATOM_MEDIAMETRICS_AUDIOTRACKDEVICEUSAGE_REPORTED\x10\xa8\x02\x12\x35\n0ATOM_MEDIAMETRICS_AUDIODEVICECONNECTION_REPORTED\x10\xa9\x02\x12\x18\n\x13\x41TOM_BLOB_COMMITTED\x10\xaa\x02\x12\x15\n\x10\x41TOM_BLOB_LEASED\x10\xab\x02\x12\x15\n\x10\x41TOM_BLOB_OPENED\x10\xac\x02\x12+\n&ATOM_CONTACTS_PROVIDER_STATUS_REPORTED\x10\xad\x02\x12%\n ATOM_KEYSTORE_KEY_EVENT_REPORTED\x10\xae\x02\x12$\n\x1f\x41TOM_NETWORK_TETHERING_REPORTED\x10\xaf\x02\x12\x1c\n\x17\x41TOM_IME_TOUCH_REPORTED\x10\xb0\x02\x12,\n\'ATOM_UI_INTERACTION_FRAME_INFO_REPORTED\x10\xb1\x02\x12$\n\x1f\x41TOM_UI_ACTION_LATENCY_REPORTED\x10\xb2\x02\x12\"\n\x1d\x41TOM_WIFI_DISCONNECT_REPORTED\x10\xb3\x02\x12\'\n\"ATOM_WIFI_CONNECTION_STATE_CHANGED\x10\xb4\x02\x12(\n#ATOM_HDMI_CEC_ACTIVE_SOURCE_CHANGED\x10\xb5\x02\x12#\n\x1e\x41TOM_HDMI_CEC_MESSAGE_REPORTED\x10\xb6\x02\x12\x17\n\x12\x41TOM_AIRPLANE_MODE\x10\xb7\x02\x12\x17\n\x12\x41TOM_MODEM_RESTART\x10\xb8\x02\x12&\n!ATOM_CARRIER_ID_MISMATCH_REPORTED\x10\xb9\x02\x12\"\n\x1d\x41TOM_CARRIER_ID_TABLE_UPDATED\x10\xba\x02\x12&\n!ATOM_DATA_STALL_RECOVERY_REPORTED\x10\xbb\x02\x12+\n&ATOM_MEDIAMETRICS_MEDIAPARSER_REPORTED\x10\xbc\x02\x12 \n\x1b\x41TOM_TLS_HANDSHAKE_REPORTED\x10\xbd\x02\x12,\n\'ATOM_TEXT_CLASSIFIER_API_USAGE_REPORTED\x10\xbe\x02\x12*\n%ATOM_CAR_WATCHDOG_KILL_STATS_REPORTED\x10\xbf\x02\x12(\n#ATOM_MEDIAMETRICS_PLAYBACK_REPORTED\x10\xc0\x02\x12$\n\x1f\x41TOM_MEDIA_NETWORK_INFO_CHANGED\x10\xc1\x02\x12&\n!ATOM_MEDIA_PLAYBACK_STATE_CHANGED\x10\xc2\x02\x12\'\n\"ATOM_MEDIA_PLAYBACK_ERROR_REPORTED\x10\xc3\x02\x12&\n!ATOM_MEDIA_PLAYBACK_TRACK_CHANGED\x10\xc4\x02\x12\x1c\n\x17\x41TOM_WIFI_SCAN_REPORTED\x10\xc5\x02\x12 \n\x1b\x41TOM_WIFI_PNO_SCAN_REPORTED\x10\xc6\x02\x12\x1a\n\x15\x41TOM_TIF_TUNE_CHANGED\x10\xc7\x02\x12\x1e\n\x19\x41TOM_AUTO_ROTATE_REPORTED\x10\xc8\x02\x12\x1a\n\x15\x41TOM_PERFETTO_TRIGGER\x10\xc9\x02\x12\x1a\n\x15\x41TOM_TRANSCODING_DATA\x10\xca\x02\x12)\n$ATOM_IMS_SERVICE_ENTITLEMENT_UPDATED\x10\xcb\x02\x12\x18\n\x13\x41TOM_DEVICE_ROTATED\x10\xcd\x02\x12(\n#ATOM_SIM_SPECIFIC_SETTINGS_RESTORED\x10\xce\x02\x12+\n&ATOM_TEXT_CLASSIFIER_DOWNLOAD_REPORTED\x10\xcf\x02\x12\x1b\n\x16\x41TOM_PIN_STORAGE_EVENT\x10\xd0\x02\x12\x1c\n\x17\x41TOM_FACE_DOWN_REPORTED\x10\xd1\x02\x12-\n(ATOM_BLUETOOTH_HAL_CRASH_REASON_REPORTED\x10\xd2\x02\x12,\n\'ATOM_REBOOT_ESCROW_PREPARATION_REPORTED\x10\xd3\x02\x12-\n(ATOM_REBOOT_ESCROW_LSKF_CAPTURE_REPORTED\x10\xd4\x02\x12\'\n\"ATOM_REBOOT_ESCROW_REBOOT_REPORTED\x10\xd5\x02\x12!\n\x1c\x41TOM_BINDER_LATENCY_REPORTED\x10\xd6\x02\x12,\n\'ATOM_MEDIAMETRICS_AAUDIOSTREAM_REPORTED\x10\xd7\x02\x12)\n$ATOM_MEDIA_TRANSCODING_SESSION_ENDED\x10\xd8\x02\x12&\n!ATOM_MAGNIFICATION_USAGE_REPORTED\x10\xd9\x02\x12\x31\n,ATOM_MAGNIFICATION_MODE_WITH_IME_ON_REPORTED\x10\xda\x02\x12(\n#ATOM_APP_SEARCH_CALL_STATS_REPORTED\x10\xdb\x02\x12\x30\n+ATOM_APP_SEARCH_PUT_DOCUMENT_STATS_REPORTED\x10\xdc\x02\x12 \n\x1b\x41TOM_DEVICE_CONTROL_CHANGED\x10\xdd\x02\x12\x1e\n\x19\x41TOM_DEVICE_STATE_CHANGED\x10\xde\x02\x12 \n\x1b\x41TOM_INPUTDEVICE_REGISTERED\x10\xdf\x02\x12\"\n\x1d\x41TOM_SMARTSPACE_CARD_REPORTED\x10\xe0\x02\x12*\n%ATOM_AUTH_PROMPT_AUTHENTICATE_INVOKED\x10\xe1\x02\x12/\n*ATOM_AUTH_MANAGER_CAN_AUTHENTICATE_INVOKED\x10\xe2\x02\x12$\n\x1f\x41TOM_AUTH_ENROLL_ACTION_INVOKED\x10\xe3\x02\x12\"\n\x1d\x41TOM_AUTH_DEPRECATED_API_USED\x10\xe4\x02\x12$\n\x1f\x41TOM_UNATTENDED_REBOOT_OCCURRED\x10\xe5\x02\x12\'\n\"ATOM_LONG_REBOOT_BLOCKING_REPORTED\x10\xe6\x02\x12\x33\n.ATOM_LOCATION_TIME_ZONE_PROVIDER_STATE_CHANGED\x10\xe7\x02\x12 \n\x1b\x41TOM_FDTRACK_EVENT_OCCURRED\x10\xec\x02\x12(\n#ATOM_TIMEOUT_AUTO_EXTENDED_REPORTED\x10\xed\x02\x12\x1f\n\x1a\x41TOM_ALARM_BATCH_DELIVERED\x10\xef\x02\x12\x19\n\x14\x41TOM_ALARM_SCHEDULED\x10\xf0\x02\x12\x30\n+ATOM_CAR_WATCHDOG_IO_OVERUSE_STATS_REPORTED\x10\xf1\x02\x12.\n)ATOM_USER_LEVEL_HIBERNATION_STATE_CHANGED\x10\xf2\x02\x12.\n)ATOM_APP_SEARCH_INITIALIZE_STATS_REPORTED\x10\xf3\x02\x12)\n$ATOM_APP_SEARCH_QUERY_STATS_REPORTED\x10\xf4\x02\x12\x1a\n\x15\x41TOM_APP_PROCESS_DIED\x10\xf5\x02\x12\x32\n-ATOM_NETWORK_IP_REACHABILITY_MONITOR_REPORTED\x10\xf6\x02\x12#\n\x1e\x41TOM_SLOW_INPUT_EVENT_REPORTED\x10\xf7\x02\x12)\n$ATOM_ANR_OCCURRED_PROCESSING_STARTED\x10\xf8\x02\x12*\n%ATOM_APP_SEARCH_REMOVE_STATS_REPORTED\x10\xf9\x02\x12\x1e\n\x19\x41TOM_MEDIA_CODEC_REPORTED\x10\xfa\x02\x12/\n*ATOM_PERMISSION_USAGE_FRAGMENT_INTERACTION\x10\xfb\x02\x12(\n#ATOM_PERMISSION_DETAILS_INTERACTION\x10\xfc\x02\x12+\n&ATOM_PRIVACY_SENSOR_TOGGLE_INTERACTION\x10\xfd\x02\x12+\n&ATOM_PRIVACY_TOGGLE_DIALOG_INTERACTION\x10\xfe\x02\x12,\n\'ATOM_APP_SEARCH_OPTIMIZE_STATS_REPORTED\x10\xff\x02\x12.\n)ATOM_NON_A11Y_TOOL_SERVICE_WARNING_REPORT\x10\x80\x03\x12\"\n\x1d\x41TOM_APP_COMPAT_STATE_CHANGED\x10\x82\x03\x12\x33\n.ATOM_SIZE_COMPAT_RESTART_BUTTON_EVENT_REPORTED\x10\x83\x03\x12 \n\x1b\x41TOM_SPLITSCREEN_UI_CHANGED\x10\x84\x03\x12(\n#ATOM_NETWORK_DNS_HANDSHAKE_REPORTED\x10\x85\x03\x12%\n ATOM_BLUETOOTH_CODE_PATH_COUNTER\x10\x86\x03\x12.\n)ATOM_BLUETOOTH_LE_BATCH_SCAN_REPORT_DELAY\x10\x88\x03\x12\x30\n+ATOM_ACCESSIBILITY_FLOATING_MENU_UI_CHANGED\x10\x89\x03\x12.\n)ATOM_NEURALNETWORKS_COMPILATION_COMPLETED\x10\x8a\x03\x12,\n\'ATOM_NEURALNETWORKS_EXECUTION_COMPLETED\x10\x8b\x03\x12+\n&ATOM_NEURALNETWORKS_COMPILATION_FAILED\x10\x8c\x03\x12)\n$ATOM_NEURALNETWORKS_EXECUTION_FAILED\x10\x8d\x03\x12\x1c\n\x17\x41TOM_CONTEXT_HUB_BOOTED\x10\x8e\x03\x12\x1f\n\x1a\x41TOM_CONTEXT_HUB_RESTARTED\x10\x8f\x03\x12\x36\n1ATOM_CONTEXT_HUB_LOADED_NANOAPP_SNAPSHOT_REPORTED\x10\x90\x03\x12\'\n\"ATOM_CHRE_CODE_DOWNLOAD_TRANSACTED\x10\x91\x03\x12\x1c\n\x17\x41TOM_UWB_SESSION_INITED\x10\x92\x03\x12\x1c\n\x17\x41TOM_UWB_SESSION_CLOSED\x10\x93\x03\x12$\n\x1f\x41TOM_UWB_FIRST_RANGING_RECEIVED\x10\x94\x03\x12*\n%ATOM_UWB_RANGING_MEASUREMENT_RECEIVED\x10\x95\x03\x12\x31\n,ATOM_TEXT_CLASSIFIER_DOWNLOAD_WORK_SCHEDULED\x10\x96\x03\x12\x31\n,ATOM_TEXT_CLASSIFIER_DOWNLOAD_WORK_COMPLETED\x10\x97\x03\x12\x1b\n\x16\x41TOM_CLIPBOARD_CLEARED\x10\x98\x03\x12\x1f\n\x1a\x41TOM_VM_CREATION_REQUESTED\x10\x99\x03\x12*\n%ATOM_NEARBY_DEVICE_SCAN_STATE_CHANGED\x10\x9a\x03\x12%\n ATOM_APPLICATION_LOCALES_CHANGED\x10\x9c\x03\x12\x30\n+ATOM_MEDIAMETRICS_AUDIOTRACKSTATUS_REPORTED\x10\x9d\x03\x12&\n!ATOM_FOLD_STATE_DURATION_REPORTED\x10\x9e\x03\x12>\n9ATOM_LOCATION_TIME_ZONE_PROVIDER_CONTROLLER_STATE_CHANGED\x10\x9f\x03\x12#\n\x1e\x41TOM_DISPLAY_HBM_STATE_CHANGED\x10\xa0\x03\x12(\n#ATOM_DISPLAY_HBM_BRIGHTNESS_CHANGED\x10\xa1\x03\x12,\n\'ATOM_PERSISTENT_URI_PERMISSIONS_FLUSHED\x10\xa2\x03\x12\x35\n0ATOM_EARLY_BOOT_COMP_OS_ARTIFACTS_CHECK_REPORTED\x10\xa3\x03\x12 \n\x1b\x41TOM_VBMETA_DIGEST_REPORTED\x10\xa4\x03\x12\x1c\n\x17\x41TOM_APEX_INFO_GATHERED\x10\xa5\x03\x12\x1b\n\x16\x41TOM_PVM_INFO_GATHERED\x10\xa6\x03\x12%\n ATOM_WEAR_SETTINGS_UI_INTERACTED\x10\xa7\x03\x12&\n!ATOM_TRACING_SERVICE_REPORT_EVENT\x10\xa8\x03\x12\x31\n,ATOM_MEDIAMETRICS_AUDIORECORDSTATUS_REPORTED\x10\xa9\x03\x12\x1a\n\x15\x41TOM_LAUNCHER_LATENCY\x10\xaa\x03\x12\x1f\n\x1a\x41TOM_DROPBOX_ENTRY_DROPPED\x10\xab\x03\x12&\n!ATOM_WIFI_P2P_CONNECTION_REPORTED\x10\xac\x03\x12\x1c\n\x17\x41TOM_GAME_STATE_CHANGED\x10\xad\x03\x12+\n&ATOM_HOTWORD_DETECTOR_CREATE_REQUESTED\x10\xae\x03\x12\x38\n3ATOM_HOTWORD_DETECTION_SERVICE_INIT_RESULT_REPORTED\x10\xaf\x03\x12-\n(ATOM_HOTWORD_DETECTION_SERVICE_RESTARTED\x10\xb0\x03\x12.\n)ATOM_HOTWORD_DETECTOR_KEYPHRASE_TRIGGERED\x10\xb1\x03\x12!\n\x1c\x41TOM_HOTWORD_DETECTOR_EVENTS\x10\xb2\x03\x12>\n9ATOM_BOOT_COMPLETED_BROADCAST_COMPLETION_LATENCY_REPORTED\x10\xb5\x03\x12\x30\n+ATOM_CONTACTS_INDEXER_UPDATE_STATS_REPORTED\x10\xb8\x03\x12*\n%ATOM_APP_BACKGROUND_RESTRICTIONS_INFO\x10\xb9\x03\x12/\n*ATOM_MMS_SMS_PROVIDER_GET_THREAD_ID_FAILED\x10\xba\x03\x12\x33\n.ATOM_MMS_SMS_DATABASE_HELPER_ON_UPGRADE_FAILED\x10\xbb\x03\x12\x35\n0ATOM_PERMISSION_REMINDER_NOTIFICATION_INTERACTED\x10\xbc\x03\x12\x30\n+ATOM_RECENT_PERMISSION_DECISIONS_INTERACTED\x10\xbd\x03\x12%\n ATOM_GNSS_PSDS_DOWNLOAD_REPORTED\x10\xbe\x03\x12.\n)ATOM_LE_AUDIO_CONNECTION_SESSION_REPORTED\x10\xbf\x03\x12-\n(ATOM_LE_AUDIO_BROADCAST_SESSION_REPORTED\x10\xc0\x03\x12!\n\x1c\x41TOM_DREAM_UI_EVENT_REPORTED\x10\xc1\x03\x12%\n ATOM_TASK_MANAGER_EVENT_REPORTED\x10\xc2\x03\x12 \n\x1b\x41TOM_CDM_ASSOCIATION_ACTION\x10\xc3\x03\x12\x46\nAATOM_MAGNIFICATION_TRIPLE_TAP_AND_HOLD_ACTIVATED_SESSION_REPORTED\x10\xc4\x03\x12\x46\nAATOM_MAGNIFICATION_FOLLOW_TYPING_FOCUS_ACTIVATED_SESSION_REPORTED\x10\xc5\x03\x12\x34\n/ATOM_ACCESSIBILITY_TEXT_READING_OPTIONS_CHANGED\x10\xc6\x03\x12+\n&ATOM_WIFI_SETUP_FAILURE_CRASH_REPORTED\x10\xc7\x03\x12#\n\x1e\x41TOM_UWB_DEVICE_ERROR_REPORTED\x10\xc8\x03\x12(\n#ATOM_ISOLATED_COMPILATION_SCHEDULED\x10\xc9\x03\x12$\n\x1f\x41TOM_ISOLATED_COMPILATION_ENDED\x10\xca\x03\x12\x36\n1ATOM_ONS_OPPORTUNISTIC_ESIM_PROVISIONING_COMPLETE\x10\xcb\x03\x12-\n(ATOM_SYSTEM_SERVER_PRE_WATCHDOG_OCCURRED\x10\xcc\x03\x12$\n\x1f\x41TOM_TELEPHONY_ANOMALY_DETECTED\x10\xcd\x03\x12$\n\x1f\x41TOM_LETTERBOX_POSITION_CHANGED\x10\xce\x03\x12)\n$ATOM_REMOTE_KEY_PROVISIONING_ATTEMPT\x10\xcf\x03\x12.\n)ATOM_REMOTE_KEY_PROVISIONING_NETWORK_INFO\x10\xd0\x03\x12(\n#ATOM_REMOTE_KEY_PROVISIONING_TIMING\x10\xd1\x03\x12+\n&ATOM_MEDIAOUTPUT_OP_INTERACTION_REPORT\x10\xd2\x03\x12!\n\x1c\x41TOM_SYNC_EXEMPTION_OCCURRED\x10\xd4\x03\x12.\n)ATOM_AUTOFILL_PRESENTATION_EVENT_REPORTED\x10\xd5\x03\x12\x1c\n\x17\x41TOM_DOCK_STATE_CHANGED\x10\xd6\x03\x12\'\n\"ATOM_SAFETY_SOURCE_STATE_COLLECTED\x10\xd7\x03\x12-\n(ATOM_SAFETY_CENTER_SYSTEM_EVENT_REPORTED\x10\xd8\x03\x12,\n\'ATOM_SAFETY_CENTER_INTERACTION_REPORTED\x10\xd9\x03\x12+\n&ATOM_SETTINGS_PROVIDER_SETTING_CHANGED\x10\xda\x03\x12+\n&ATOM_BROADCAST_DELIVERY_EVENT_REPORTED\x10\xdb\x03\x12(\n#ATOM_SERVICE_REQUEST_EVENT_REPORTED\x10\xdc\x03\x12-\n(ATOM_PROVIDER_ACQUISITION_EVENT_REPORTED\x10\xdd\x03\x12(\n#ATOM_BLUETOOTH_DEVICE_NAME_REPORTED\x10\xde\x03\x12\x1b\n\x16\x41TOM_CB_CONFIG_UPDATED\x10\xdf\x03\x12\"\n\x1d\x41TOM_CB_MODULE_ERROR_REPORTED\x10\xe0\x03\x12$\n\x1f\x41TOM_CB_SERVICE_FEATURE_CHANGED\x10\xe1\x03\x12%\n ATOM_CB_RECEIVER_FEATURE_CHANGED\x10\xe2\x03\x12\x31\n,ATOM_PRIVACY_SIGNAL_NOTIFICATION_INTERACTION\x10\xe4\x03\x12/\n*ATOM_PRIVACY_SIGNAL_ISSUE_CARD_INTERACTION\x10\xe5\x03\x12%\n ATOM_PRIVACY_SIGNALS_JOB_FAILURE\x10\xe6\x03\x12\x1c\n\x17\x41TOM_VIBRATION_REPORTED\x10\xe7\x03\x12\x1b\n\x16\x41TOM_UWB_RANGING_START\x10\xe9\x03\x12\x1a\n\x15\x41TOM_APP_COMPACTED_V2\x10\xeb\x03\x12$\n\x1f\x41TOM_DISPLAY_BRIGHTNESS_CHANGED\x10\xee\x03\x12!\n\x1c\x41TOM_ACTIVITY_ACTION_BLOCKED\x10\xef\x03\x12-\n(ATOM_NETWORK_DNS_SERVER_SUPPORT_REPORTED\x10\xf8\x03\x12\x13\n\x0e\x41TOM_VM_BOOTED\x10\xf9\x03\x12\x13\n\x0e\x41TOM_VM_EXITED\x10\xfa\x03\x12+\n&ATOM_AMBIENT_BRIGHTNESS_STATS_REPORTED\x10\xfb\x03\x12\x37\n2ATOM_MEDIAMETRICS_SPATIALIZERCAPABILITIES_REPORTED\x10\xfc\x03\x12\x38\n3ATOM_MEDIAMETRICS_SPATIALIZERDEVICEENABLED_REPORTED\x10\xfd\x03\x12\x38\n3ATOM_MEDIAMETRICS_HEADTRACKERDEVICEENABLED_REPORTED\x10\xfe\x03\x12:\n5ATOM_MEDIAMETRICS_HEADTRACKERDEVICESUPPORTED_REPORTED\x10\xff\x03\x12#\n\x1e\x41TOM_HEARING_AID_INFO_REPORTED\x10\x81\x04\x12,\n\'ATOM_DEVICE_WIDE_JOB_CONSTRAINT_CHANGED\x10\x82\x04\x12\x1e\n\x19\x41TOM_AMBIENT_MODE_CHANGED\x10\x83\x04\x12\x1e\n\x19\x41TOM_ANR_LATENCY_REPORTED\x10\x84\x04\x12\x1b\n\x16\x41TOM_RESOURCE_API_INFO\x10\x85\x04\x12(\n#ATOM_SYSTEM_DEFAULT_NETWORK_CHANGED\x10\x86\x04\x12/\n*ATOM_IWLAN_SETUP_DATA_CALL_RESULT_REPORTED\x10\x87\x04\x12\x30\n+ATOM_IWLAN_PDN_DISCONNECTED_REASON_REPORTED\x10\x88\x04\x12(\n#ATOM_AIRPLANE_MODE_SESSION_REPORTED\x10\x89\x04\x12 \n\x1b\x41TOM_VM_CPU_STATUS_REPORTED\x10\x8a\x04\x12 \n\x1b\x41TOM_VM_MEM_STATUS_REPORTED\x10\x8b\x04\x12/\n*ATOM_PACKAGE_INSTALLATION_SESSION_REPORTED\x10\x8c\x04\x12&\n!ATOM_DEFAULT_NETWORK_REMATCH_INFO\x10\x8d\x04\x12\'\n\"ATOM_NETWORK_SELECTION_PERFORMANCE\x10\x8e\x04\x12\x1e\n\x19\x41TOM_NETWORK_NSD_REPORTED\x10\x8f\x04\x12\x31\n,ATOM_BLUETOOTH_DISCONNECTION_REASON_REPORTED\x10\x91\x04\x12+\n&ATOM_BLUETOOTH_LOCAL_VERSIONS_REPORTED\x10\x92\x04\x12\x36\n1ATOM_BLUETOOTH_REMOTE_SUPPORTED_FEATURES_REPORTED\x10\x93\x04\x12\x35\n0ATOM_BLUETOOTH_LOCAL_SUPPORTED_FEATURES_REPORTED\x10\x94\x04\x12!\n\x1c\x41TOM_BLUETOOTH_GATT_APP_INFO\x10\x95\x04\x12*\n%ATOM_BRIGHTNESS_CONFIGURATION_UPDATED\x10\x96\x04\x12-\n(ATOM_WEAR_MEDIA_OUTPUT_SWITCHER_LAUNCHED\x10\x9a\x04\x12-\n(ATOM_WEAR_MEDIA_OUTPUT_SWITCHER_FINISHED\x10\x9b\x04\x12\x38\n3ATOM_WEAR_MEDIA_OUTPUT_SWITCHER_CONNECTION_REPORTED\x10\x9c\x04\x12:\n5ATOM_WEAR_MEDIA_OUTPUT_SWITCHER_DEVICE_SCAN_TRIGGERED\x10\x9d\x04\x12>\n9ATOM_WEAR_MEDIA_OUTPUT_SWITCHER_FIRST_DEVICE_SCAN_LATENCY\x10\x9e\x04\x12;\n6ATOM_WEAR_MEDIA_OUTPUT_SWITCHER_CONNECT_DEVICE_LATENCY\x10\x9f\x04\x12+\n&ATOM_PACKAGE_MANAGER_SNAPSHOT_REPORTED\x10\xa0\x04\x12:\n5ATOM_PACKAGE_MANAGER_APPS_FILTER_CACHE_BUILD_REPORTED\x10\xa1\x04\x12;\n6ATOM_PACKAGE_MANAGER_APPS_FILTER_CACHE_UPDATE_REPORTED\x10\xa2\x04\x12#\n\x1e\x41TOM_LAUNCHER_IMPRESSION_EVENT\x10\xa3\x04\x12=\n8ATOM_WEAR_MEDIA_OUTPUT_SWITCHER_ALL_DEVICES_SCAN_LATENCY\x10\xa5\x04\x12\x1e\n\x19\x41TOM_WS_WATCH_FACE_EDITED\x10\xa7\x04\x12\x30\n+ATOM_WS_WATCH_FACE_FAVORITE_ACTION_REPORTED\x10\xa8\x04\x12+\n&ATOM_WS_WATCH_FACE_SET_ACTION_REPORTED\x10\xa9\x04\x12)\n$ATOM_PACKAGE_UNINSTALLATION_REPORTED\x10\xaa\x04\x12\x1b\n\x16\x41TOM_GAME_MODE_CHANGED\x10\xab\x04\x12)\n$ATOM_GAME_MODE_CONFIGURATION_CHANGED\x10\xac\x04\x12$\n\x1f\x41TOM_BEDTIME_MODE_STATE_CHANGED\x10\xad\x04\x12%\n ATOM_NETWORK_SLICE_SESSION_ENDED\x10\xae\x04\x12\x31\n,ATOM_NETWORK_SLICE_DAILY_DATA_USAGE_REPORTED\x10\xaf\x04\x12\x1f\n\x1a\x41TOM_NFC_TAG_TYPE_OCCURRED\x10\xb0\x04\x12#\n\x1e\x41TOM_NFC_AID_CONFLICT_OCCURRED\x10\xb1\x04\x12&\n!ATOM_NFC_READER_CONFLICT_OCCURRED\x10\xb2\x04\x12\x1e\n\x19\x41TOM_WS_TILE_LIST_CHANGED\x10\xb3\x04\x12.\n)ATOM_GET_TYPE_ACCESSED_WITHOUT_PERMISSION\x10\xb4\x04\x12*\n%ATOM_MOBILE_BUNDLED_APP_INFO_GATHERED\x10\xb6\x04\x12\x30\n+ATOM_WS_WATCH_FACE_COMPLICATION_SET_CHANGED\x10\xb7\x04\x12\x1b\n\x16\x41TOM_MEDIA_DRM_CREATED\x10\xb8\x04\x12\x1b\n\x16\x41TOM_MEDIA_DRM_ERRORED\x10\xb9\x04\x12\"\n\x1d\x41TOM_MEDIA_DRM_SESSION_OPENED\x10\xba\x04\x12\"\n\x1d\x41TOM_MEDIA_DRM_SESSION_CLOSED\x10\xbb\x04\x12\"\n\x1d\x41TOM_USER_SELECTED_RESOLUTION\x10\xbc\x04\x12&\n!ATOM_UNSAFE_INTENT_EVENT_REPORTED\x10\xbd\x04\x12+\n&ATOM_PERFORMANCE_HINT_SESSION_REPORTED\x10\xbe\x04\x12\x31\n,ATOM_MEDIAMETRICS_MIDI_DEVICE_CLOSE_REPORTED\x10\xc0\x04\x12\"\n\x1d\x41TOM_BIOMETRIC_TOUCH_REPORTED\x10\xc1\x04\x12-\n(ATOM_HOTWORD_AUDIO_EGRESS_EVENT_REPORTED\x10\xc2\x04\x12(\n#ATOM_LOCATION_ENABLED_STATE_CHANGED\x10\xc4\x04\x12\x1e\n\x19\x41TOM_IME_REQUEST_FINISHED\x10\xc5\x04\x12*\n%ATOM_USB_COMPLIANCE_WARNINGS_REPORTED\x10\xc6\x04\x12\'\n\"ATOM_APP_SUPPORTED_LOCALES_CHANGED\x10\xc7\x04\x12\x31\n,ATOM_MEDIA_PROVIDER_VOLUME_RECOVERY_REPORTED\x10\xca\x04\x12(\n#ATOM_BIOMETRIC_PROPERTIES_COLLECTED\x10\xcb\x04\x12\"\n\x1d\x41TOM_KERNEL_WAKEUP_ATTRIBUTED\x10\xcc\x04\x12!\n\x1c\x41TOM_SCREEN_STATE_CHANGED_V2\x10\xcd\x04\x12#\n\x1e\x41TOM_WS_BACKUP_ACTION_REPORTED\x10\xce\x04\x12$\n\x1f\x41TOM_WS_RESTORE_ACTION_REPORTED\x10\xcf\x04\x12*\n%ATOM_DEVICE_LOG_ACCESS_EVENT_REPORTED\x10\xd0\x04\x12\x1f\n\x1a\x41TOM_MEDIA_SESSION_UPDATED\x10\xd2\x04\x12!\n\x1c\x41TOM_WEAR_OOBE_STATE_CHANGED\x10\xd3\x04\x12!\n\x1c\x41TOM_WS_NOTIFICATION_UPDATED\x10\xd4\x04\x12\x39\n4ATOM_NETWORK_VALIDATION_FAILURE_STATS_DAILY_REPORTED\x10\xd9\x04\x12 \n\x1b\x41TOM_WS_COMPLICATION_TAPPED\x10\xda\x04\x12\"\n\x1d\x41TOM_WS_NOTIFICATION_BLOCKING\x10\x8c\x06\x12,\n\'ATOM_WS_NOTIFICATION_BRIDGEMODE_UPDATED\x10\xb6\x06\x12,\n\'ATOM_WS_NOTIFICATION_DISMISSAL_ACTIONED\x10\xb7\x06\x12\"\n\x1d\x41TOM_WS_NOTIFICATION_ACTIONED\x10\xb8\x06\x12!\n\x1c\x41TOM_WS_NOTIFICATION_LATENCY\x10\xf0\x06\x12\x1d\n\x18\x41TOM_WIFI_BYTES_TRANSFER\x10\x90N\x12&\n!ATOM_WIFI_BYTES_TRANSFER_BY_FG_BG\x10\x91N\x12\x1f\n\x1a\x41TOM_MOBILE_BYTES_TRANSFER\x10\x92N\x12(\n#ATOM_MOBILE_BYTES_TRANSFER_BY_FG_BG\x10\x93N\x12\"\n\x1d\x41TOM_BLUETOOTH_BYTES_TRANSFER\x10\x96N\x12\x19\n\x14\x41TOM_KERNEL_WAKELOCK\x10\x94N\x12\x1f\n\x1a\x41TOM_SUBSYSTEM_SLEEP_STATE\x10\x95N\x12\x1a\n\x15\x41TOM_CPU_TIME_PER_UID\x10\x99N\x12\x1f\n\x1a\x41TOM_CPU_TIME_PER_UID_FREQ\x10\x9aN\x12\x1c\n\x17\x41TOM_WIFI_ACTIVITY_INFO\x10\x9bN\x12\x1d\n\x18\x41TOM_MODEM_ACTIVITY_INFO\x10\x9cN\x12!\n\x1c\x41TOM_BLUETOOTH_ACTIVITY_INFO\x10\x97N\x12\x1e\n\x19\x41TOM_PROCESS_MEMORY_STATE\x10\x9dN\x12!\n\x1c\x41TOM_SYSTEM_ELAPSED_REALTIME\x10\x9eN\x12\x17\n\x12\x41TOM_SYSTEM_UPTIME\x10\x9fN\x12\x19\n\x14\x41TOM_CPU_ACTIVE_TIME\x10\xa0N\x12\x1a\n\x15\x41TOM_CPU_CLUSTER_TIME\x10\xa1N\x12\x14\n\x0f\x41TOM_DISK_SPACE\x10\xa2N\x12$\n\x1f\x41TOM_REMAINING_BATTERY_CAPACITY\x10\xa3N\x12\x1f\n\x1a\x41TOM_FULL_BATTERY_CAPACITY\x10\xa4N\x12\x15\n\x10\x41TOM_TEMPERATURE\x10\xa5N\x12\x16\n\x11\x41TOM_BINDER_CALLS\x10\xa6N\x12!\n\x1c\x41TOM_BINDER_CALLS_EXCEPTIONS\x10\xa7N\x12\x16\n\x11\x41TOM_LOOPER_STATS\x10\xa8N\x12\x14\n\x0f\x41TOM_DISK_STATS\x10\xa9N\x12\x19\n\x14\x41TOM_DIRECTORY_USAGE\x10\xaaN\x12\x12\n\rATOM_APP_SIZE\x10\xabN\x12\x17\n\x12\x41TOM_CATEGORY_SIZE\x10\xacN\x12\x14\n\x0f\x41TOM_PROC_STATS\x10\xadN\x12\x19\n\x14\x41TOM_BATTERY_VOLTAGE\x10\xaeN\x12#\n\x1e\x41TOM_NUM_FINGERPRINTS_ENROLLED\x10\xafN\x12\x11\n\x0c\x41TOM_DISK_IO\x10\xb0N\x12\x17\n\x12\x41TOM_POWER_PROFILE\x10\xb1N\x12\x1d\n\x18\x41TOM_PROC_STATS_PKG_PROC\x10\xb2N\x12\x1a\n\x15\x41TOM_PROCESS_CPU_TIME\x10\xb3N\x12\"\n\x1d\x41TOM_CPU_TIME_PER_THREAD_FREQ\x10\xb5N\x12%\n ATOM_ON_DEVICE_POWER_MEASUREMENT\x10\xb6N\x12%\n ATOM_DEVICE_CALCULATED_POWER_USE\x10\xb7N\x12(\n#ATOM_PROCESS_MEMORY_HIGH_WATER_MARK\x10\xbaN\x12\x17\n\x12\x41TOM_BATTERY_LEVEL\x10\xbbN\x12\x1b\n\x16\x41TOM_BUILD_INFORMATION\x10\xbcN\x12\x1d\n\x18\x41TOM_BATTERY_CYCLE_COUNT\x10\xbdN\x12\x1d\n\x18\x41TOM_DEBUG_ELAPSED_CLOCK\x10\xbeN\x12%\n ATOM_DEBUG_FAILING_ELAPSED_CLOCK\x10\xbfN\x12\x1c\n\x17\x41TOM_NUM_FACES_ENROLLED\x10\xc0N\x12\x15\n\x10\x41TOM_ROLE_HOLDER\x10\xc1N\x12$\n\x1f\x41TOM_DANGEROUS_PERMISSION_STATE\x10\xc2N\x12\x14\n\x0f\x41TOM_TRAIN_INFO\x10\xc3N\x12\x1d\n\x18\x41TOM_TIME_ZONE_DATA_INFO\x10\xc4N\x12\x1f\n\x1a\x41TOM_EXTERNAL_STORAGE_INFO\x10\xc5N\x12\x1f\n\x1a\x41TOM_GPU_STATS_GLOBAL_INFO\x10\xc6N\x12\x1c\n\x17\x41TOM_GPU_STATS_APP_INFO\x10\xc7N\x12\x1e\n\x19\x41TOM_SYSTEM_ION_HEAP_SIZE\x10\xc8N\x12\'\n\"ATOM_APPS_ON_EXTERNAL_STORAGE_INFO\x10\xc9N\x12\x17\n\x12\x41TOM_FACE_SETTINGS\x10\xcaN\x12\x18\n\x13\x41TOM_COOLING_DEVICE\x10\xcbN\x12\x11\n\x0c\x41TOM_APP_OPS\x10\xccN\x12&\n!ATOM_PROCESS_SYSTEM_ION_HEAP_SIZE\x10\xcdN\x12*\n%ATOM_SURFACEFLINGER_STATS_GLOBAL_INFO\x10\xceN\x12)\n$ATOM_SURFACEFLINGER_STATS_LAYER_INFO\x10\xcfN\x12!\n\x1c\x41TOM_PROCESS_MEMORY_SNAPSHOT\x10\xd0N\x12\x1a\n\x15\x41TOM_VMS_CLIENT_STATS\x10\xd1N\x12#\n\x1e\x41TOM_NOTIFICATION_REMOTE_VIEWS\x10\xd2N\x12,\n\'ATOM_DANGEROUS_PERMISSION_STATE_SAMPLED\x10\xd3N\x12\x18\n\x13\x41TOM_GRAPHICS_STATS\x10\xd4N\x12\x1f\n\x1a\x41TOM_RUNTIME_APP_OP_ACCESS\x10\xd5N\x12\x17\n\x12\x41TOM_ION_HEAP_SIZE\x10\xd6N\x12*\n%ATOM_PACKAGE_NOTIFICATION_PREFERENCES\x10\xd7N\x12\x32\n-ATOM_PACKAGE_NOTIFICATION_CHANNEL_PREFERENCES\x10\xd8N\x12\x38\n3ATOM_PACKAGE_NOTIFICATION_CHANNEL_GROUP_PREFERENCES\x10\xd9N\x12\x14\n\x0f\x41TOM_GNSS_STATS\x10\xdaN\x12\x1c\n\x17\x41TOM_ATTRIBUTED_APP_OPS\x10\xdbN\x12\x1c\n\x17\x41TOM_VOICE_CALL_SESSION\x10\xdcN\x12\x1e\n\x19\x41TOM_VOICE_CALL_RAT_USAGE\x10\xddN\x12\x18\n\x13\x41TOM_SIM_SLOT_STATE\x10\xdeN\x12\'\n\"ATOM_SUPPORTED_RADIO_ACCESS_FAMILY\x10\xdfN\x12\x1a\n\x15\x41TOM_SETTING_SNAPSHOT\x10\xe0N\x12\x13\n\x0e\x41TOM_BLOB_INFO\x10\xe1N\x12#\n\x1e\x41TOM_DATA_USAGE_BYTES_TRANSFER\x10\xe2N\x12+\n&ATOM_BYTES_TRANSFER_BY_TAG_AND_METERED\x10\xe3N\x12\x17\n\x12\x41TOM_DND_MODE_RULE\x10\xe4N\x12/\n*ATOM_GENERAL_EXTERNAL_STORAGE_ACCESS_STATS\x10\xe5N\x12\x16\n\x11\x41TOM_INCOMING_SMS\x10\xe6N\x12\x16\n\x11\x41TOM_OUTGOING_SMS\x10\xe7N\x12\"\n\x1d\x41TOM_CARRIER_ID_TABLE_VERSION\x10\xe8N\x12\x1b\n\x16\x41TOM_DATA_CALL_SESSION\x10\xe9N\x12 \n\x1b\x41TOM_CELLULAR_SERVICE_STATE\x10\xeaN\x12&\n!ATOM_CELLULAR_DATA_SERVICE_SWITCH\x10\xebN\x12\x17\n\x12\x41TOM_SYSTEM_MEMORY\x10\xecN\x12&\n!ATOM_IMS_REGISTRATION_TERMINATION\x10\xedN\x12 \n\x1b\x41TOM_IMS_REGISTRATION_STATS\x10\xeeN\x12#\n\x1e\x41TOM_CPU_TIME_PER_CLUSTER_FREQ\x10\xefN\x12$\n\x1f\x41TOM_CPU_CYCLES_PER_UID_CLUSTER\x10\xf0N\x12\x1d\n\x18\x41TOM_DEVICE_ROTATED_DATA\x10\xf1N\x12-\n(ATOM_CPU_CYCLES_PER_THREAD_GROUP_CLUSTER\x10\xf2N\x12!\n\x1c\x41TOM_MEDIA_DRM_ACTIVITY_INFO\x10\xf3N\x12$\n\x1f\x41TOM_OEM_MANAGED_BYTES_TRANSFER\x10\xf4N\x12\x1a\n\x15\x41TOM_GNSS_POWER_STATS\x10\xf5N\x12\"\n\x1d\x41TOM_TIME_ZONE_DETECTOR_STATE\x10\xf6N\x12!\n\x1c\x41TOM_KEYSTORE2_STORAGE_STATS\x10\xf7N\x12\x18\n\x13\x41TOM_RKP_POOL_STATS\x10\xf8N\x12\x1f\n\x1a\x41TOM_PROCESS_DMABUF_MEMORY\x10\xf9N\x12\x1c\n\x17\x41TOM_PENDING_ALARM_INFO\x10\xfaN\x12$\n\x1f\x41TOM_USER_LEVEL_HIBERNATED_APPS\x10\xfbN\x12\"\n\x1d\x41TOM_LAUNCHER_LAYOUT_SNAPSHOT\x10\xfcN\x12 \n\x1b\x41TOM_GLOBAL_HIBERNATED_APPS\x10\xfdN\x12$\n\x1f\x41TOM_INPUT_EVENT_LATENCY_SKETCH\x10\xfeN\x12*\n%ATOM_BATTERY_USAGE_STATS_BEFORE_RESET\x10\xffN\x12)\n$ATOM_BATTERY_USAGE_STATS_SINCE_RESET\x10\x80O\x12\x43\n>ATOM_BATTERY_USAGE_STATS_SINCE_RESET_USING_POWER_PROFILE_MODEL\x10\x81O\x12\'\n\"ATOM_INSTALLED_INCREMENTAL_PACKAGE\x10\x82O\x12$\n\x1f\x41TOM_TELEPHONY_NETWORK_REQUESTS\x10\x83O\x12!\n\x1c\x41TOM_APP_SEARCH_STORAGE_INFO\x10\x84O\x12\x10\n\x0b\x41TOM_VMSTAT\x10\x85O\x12\x32\n-ATOM_KEYSTORE2_KEY_CREATION_WITH_GENERAL_INFO\x10\x86O\x12/\n*ATOM_KEYSTORE2_KEY_CREATION_WITH_AUTH_INFO\x10\x87O\x12<\n7ATOM_KEYSTORE2_KEY_CREATION_WITH_PURPOSE_AND_MODES_INFO\x10\x88O\x12&\n!ATOM_KEYSTORE2_ATOM_WITH_OVERFLOW\x10\x89O\x12=\n8ATOM_KEYSTORE2_KEY_OPERATION_WITH_PURPOSE_AND_MODES_INFO\x10\x8aO\x12\x33\n.ATOM_KEYSTORE2_KEY_OPERATION_WITH_GENERAL_INFO\x10\x8bO\x12\x19\n\x14\x41TOM_RKP_ERROR_STATS\x10\x8cO\x12\x1f\n\x1a\x41TOM_KEYSTORE2_CRASH_STATS\x10\x8dO\x12\x1a\n\x15\x41TOM_VENDOR_APEX_INFO\x10\x8eO\x12&\n!ATOM_ACCESSIBILITY_SHORTCUT_STATS\x10\x8fO\x12+\n&ATOM_ACCESSIBILITY_FLOATING_MENU_STATS\x10\x90O\x12&\n!ATOM_DATA_USAGE_BYTES_TRANSFER_V2\x10\x91O\x12\x1c\n\x17\x41TOM_MEDIA_CAPABILITIES\x10\x92O\x12.\n)ATOM_CAR_WATCHDOG_SYSTEM_IO_USAGE_SUMMARY\x10\x93O\x12+\n&ATOM_CAR_WATCHDOG_UID_IO_USAGE_SUMMARY\x10\x94O\x12,\n\'ATOM_IMS_REGISTRATION_FEATURE_TAG_STATS\x10\x95O\x12\'\n\"ATOM_RCS_CLIENT_PROVISIONING_STATS\x10\x96O\x12$\n\x1f\x41TOM_RCS_ACS_PROVISIONING_STATS\x10\x97O\x12\x1c\n\x17\x41TOM_SIP_DELEGATE_STATS\x10\x98O\x12)\n$ATOM_SIP_TRANSPORT_FEATURE_TAG_STATS\x10\x99O\x12\x1e\n\x19\x41TOM_SIP_MESSAGE_RESPONSE\x10\x9aO\x12\x1f\n\x1a\x41TOM_SIP_TRANSPORT_SESSION\x10\x9bO\x12-\n(ATOM_IMS_DEDICATED_BEARER_LISTENER_EVENT\x10\x9cO\x12$\n\x1f\x41TOM_IMS_DEDICATED_BEARER_EVENT\x10\x9dO\x12-\n(ATOM_IMS_REGISTRATION_SERVICE_DESC_STATS\x10\x9eO\x12\x19\n\x14\x41TOM_UCE_EVENT_STATS\x10\x9fO\x12\x1f\n\x1a\x41TOM_PRESENCE_NOTIFY_EVENT\x10\xa0O\x12\x13\n\x0e\x41TOM_GBA_EVENT\x10\xa1O\x12\x18\n\x13\x41TOM_PER_SIM_STATUS\x10\xa2O\x12\x1a\n\x15\x41TOM_GPU_WORK_PER_UID\x10\xa3O\x12\x37\n2ATOM_PERSISTENT_URI_PERMISSIONS_AMOUNT_PER_PACKAGE\x10\xa4O\x12\x1f\n\x1a\x41TOM_SIGNED_PARTITION_INFO\x10\xa5O\x12\'\n\"ATOM_PINNED_FILE_SIZES_PER_PACKAGE\x10\xa6O\x12%\n ATOM_PENDING_INTENTS_PER_PACKAGE\x10\xa7O\x12\x13\n\x0e\x41TOM_USER_INFO\x10\xa8O\x12\'\n\"ATOM_TELEPHONY_NETWORK_REQUESTS_V2\x10\xa9O\x12%\n ATOM_DEVICE_TELEPHONY_PROPERTIES\x10\xaaO\x12.\n)ATOM_REMOTE_KEY_PROVISIONING_ERROR_COUNTS\x10\xabO\x12\x16\n\x11\x41TOM_SAFETY_STATE\x10\xacO\x12\x16\n\x11\x41TOM_INCOMING_MMS\x10\xadO\x12\x16\n\x11\x41TOM_OUTGOING_MMS\x10\xaeO\x12\x19\n\x14\x41TOM_MULTI_USER_INFO\x10\xb0O\x12\x1e\n\x19\x41TOM_NETWORK_BPF_MAP_INFO\x10\xb1O\x12!\n\x1c\x41TOM_OUTGOING_SHORT_CODE_SMS\x10\xb2O\x12#\n\x1e\x41TOM_CONNECTIVITY_STATE_SAMPLE\x10\xb3O\x12\x30\n+ATOM_NETWORK_SELECTION_REMATCH_REASONS_INFO\x10\xb4O\x12\x18\n\x13\x41TOM_GAME_MODE_INFO\x10\xb5O\x12!\n\x1c\x41TOM_GAME_MODE_CONFIGURATION\x10\xb6O\x12\x1c\n\x17\x41TOM_GAME_MODE_LISTENER\x10\xb7O\x12%\n ATOM_NETWORK_SLICE_REQUEST_COUNT\x10\xb8O\x12\x1a\n\x15\x41TOM_WS_TILE_SNAPSHOT\x10\xb9O\x12\x38\n3ATOM_WS_ACTIVE_WATCH_FACE_COMPLICATION_SET_SNAPSHOT\x10\xbaO\x12\x17\n\x12\x41TOM_PROCESS_STATE\x10\xbbO\x12\x1d\n\x18\x41TOM_PROCESS_ASSOCIATION\x10\xbcO\x12$\n\x1f\x41TOM_ADPF_SYSTEM_COMPONENT_INFO\x10\xbdO\x12!\n\x1c\x41TOM_NOTIFICATION_MEMORY_USE\x10\xbeO\x12\x1a\n\x15\x41TOM_HDR_CAPABILITIES\x10\xbfO\x12/\n*ATOM_WS_FAVOURITE_WATCH_FACE_LIST_SNAPSHOT\x10\xc0O\x12!\n\x1c\x41TOM_WIFI_AWARE_NDP_REPORTED\x10\xfe\x04\x12$\n\x1f\x41TOM_WIFI_AWARE_ATTACH_REPORTED\x10\xff\x04\x12&\n!ATOM_WIFI_SELF_RECOVERY_TRIGGERED\x10\x95\x05\x12\x19\n\x14\x41TOM_SOFT_AP_STARTED\x10\xa8\x05\x12\x19\n\x14\x41TOM_SOFT_AP_STOPPED\x10\xa9\x05\x12\x1c\n\x17\x41TOM_WIFI_LOCK_RELEASED\x10\xaf\x05\x12\x1f\n\x1a\x41TOM_WIFI_LOCK_DEACTIVATED\x10\xb0\x05\x12\x1b\n\x16\x41TOM_WIFI_CONFIG_SAVED\x10\xb1\x05\x12+\n&ATOM_WIFI_AWARE_RESOURCE_USING_CHANGED\x10\xb2\x05\x12#\n\x1e\x41TOM_WIFI_AWARE_HAL_API_CALLED\x10\xb3\x05\x12*\n%ATOM_WIFI_LOCAL_ONLY_REQUEST_RECEIVED\x10\xb4\x05\x12\x30\n+ATOM_WIFI_LOCAL_ONLY_REQUEST_SCAN_TRIGGERED\x10\xb5\x05\x12#\n\x1e\x41TOM_WIFI_THREAD_TASK_EXECUTED\x10\xb6\x05\x12\x1c\n\x17\x41TOM_WIFI_STATE_CHANGED\x10\xbc\x05\x12\x1a\n\x15\x41TOM_PNO_SCAN_STARTED\x10\xcf\x05\x12\x1a\n\x15\x41TOM_PNO_SCAN_STOPPED\x10\xd0\x05\x12#\n\x1e\x41TOM_WIFI_IS_UNUSABLE_REPORTED\x10\xd2\x05\x12\'\n\"ATOM_WIFI_AP_CAPABILITIES_REPORTED\x10\xd3\x05\x12\x1f\n\x1a\x41TOM_SOFT_AP_STATE_CHANGED\x10\xa5\x06\x12+\n&ATOM_SCORER_PREDICTION_RESULT_REPORTED\x10\xf4\x06\x12!\n\x1c\x41TOM_WIFI_AWARE_CAPABILITIES\x10\xceO\x12\x1a\n\x15\x41TOM_WIFI_MODULE_INFO\x10\xd1O\x12\x1b\n\x16\x41TOM_WIFI_SETTING_INFO\x10\xd2O\x12#\n\x1e\x41TOM_WIFI_COMPLEX_SETTING_INFO\x10\xd3O\x12&\n!ATOM_WIFI_CONFIGURED_NETWORK_INFO\x10\xd6O\x12 \n\x1b\x41TOM_WEAR_POWER_MENU_OPENED\x10\xdb\x05\x12\x1f\n\x1a\x41TOM_WEAR_ASSISTANT_OPENED\x10\xf3\x05\x12%\n ATOM_FIRST_OVERLAY_STATE_CHANGED\x10\x95\x07\x12\x1e\n\x19\x41TOM_WS_WEAR_TIME_SESSION\x10\xe2\x04\x12*\n%ATOM_WS_INCOMING_CALL_ACTION_REPORTED\x10\xf2\x04\x12(\n#ATOM_WS_CALL_DISCONNECTION_REPORTED\x10\xf3\x04\x12#\n\x1e\x41TOM_WS_CALL_DURATION_REPORTED\x10\xf4\x04\x12\x32\n-ATOM_WS_CALL_USER_EXPERIENCE_LATENCY_REPORTED\x10\xf5\x04\x12&\n!ATOM_WS_CALL_INTERACTION_REPORTED\x10\xf6\x04\x12\"\n\x1d\x41TOM_WS_ON_BODY_STATE_CHANGED\x10\x93\x06\x12\x39\n4ATOM_WS_WATCH_FACE_RESTRICTED_COMPLICATIONS_IMPACTED\x10\xa2\x06\x12@\n;ATOM_WS_WATCH_FACE_DEFAULT_RESTRICTED_COMPLICATIONS_REMOVED\x10\xa3\x06\x12?\n:ATOM_WS_COMPLICATIONS_IMPACTED_NOTIFICATION_EVENT_REPORTED\x10\xa4\x06\x12(\n#ATOM_WS_REMOTE_EVENT_USAGE_REPORTED\x10\x98\x07\x12\x30\n+ATOM_WS_NOTIFICATION_MANAGED_DISMISSAL_SYNC\x10\xad\x07\x12%\n ATOM_WS_BUGREPORT_EVENT_REPORTED\x10\xc4\x07\x12%\n ATOM_WS_STANDALONE_MODE_SNAPSHOT\x10\xd5O\x12)\n$ATOM_WS_FAVORITE_WATCH_FACE_SNAPSHOT\x10\xdeO\x12/\n*ATOM_WS_PHOTOS_WATCH_FACE_FEATURE_SNAPSHOT\x10\xf1O\x12.\n)ATOM_WS_WATCH_FACE_CUSTOMIZATION_SNAPSHOT\x10\xf3O\x12.\n)ATOM_WEAR_ADAPTIVE_SUSPEND_STATS_REPORTED\x10\xeb\x04\x12?\n:ATOM_WEAR_POWER_ANOMALY_SERVICE_OPERATIONAL_STATS_REPORTED\x10\xec\x04\x12\x39\n4ATOM_WEAR_POWER_ANOMALY_SERVICE_EVENT_STATS_REPORTED\x10\xed\x04\x12\"\n\x1d\x41TOM_WEAR_TIME_SYNC_REQUESTED\x10\x8f\x07\x12\"\n\x1d\x41TOM_WEAR_TIME_UPDATE_STARTED\x10\x90\x07\x12*\n%ATOM_WEAR_TIME_SYNC_ATTEMPT_COMPLETED\x10\x91\x07\x12\x1b\n\x16\x41TOM_WEAR_TIME_CHANGED\x10\x92\x07\x12\x32\n-ATOM_WEAR_SETUP_WIZARD_DEVICE_STATUS_REPORTED\x10\xb9\x07\x12-\n(ATOM_WEAR_SETUP_WIZARD_PAIRING_COMPLETED\x10\xba\x07\x12\x32\n-ATOM_WEAR_SETUP_WIZARD_CONNECTION_ESTABLISHED\x10\xbb\x07\x12-\n(ATOM_WEAR_SETUP_WIZARD_CHECKIN_COMPLETED\x10\xbc\x07\x12\x33\n.ATOM_WEAR_SETUP_WIZARD_COMPANION_TIME_REPORTED\x10\xbd\x07\x12+\n&ATOM_WEAR_SETUP_WIZARD_STATUS_REPORTED\x10\xbe\x07\x12.\n)ATOM_WEAR_SETUP_WIZARD_HEARTBEAT_REPORTED\x10\xbf\x07\x12)\n$ATOM_WEAR_SETUP_WIZARD_FRP_TRIGGERED\x10\xc0\x07\x12\x33\n.ATOM_WEAR_SETUP_WIZARD_SYSTEM_UPDATE_TRIGGERED\x10\xc1\x07\x12\x32\n-ATOM_WEAR_SETUP_WIZARD_PHONE_SWITCH_TRIGGERED\x10\xc2\x07\x12\x1e\n\x19\x41TOM_RENDERER_INITIALIZED\x10\xe0\x05\x12!\n\x1c\x41TOM_SCHEMA_VERSION_RECEIVED\x10\xe1\x05\x12\x1a\n\x15\x41TOM_LAYOUT_INSPECTED\x10\xe5\x05\x12%\n ATOM_LAYOUT_EXPRESSION_INSPECTED\x10\xe6\x05\x12%\n ATOM_LAYOUT_ANIMATIONS_INSPECTED\x10\xe7\x05\x12\'\n\"ATOM_MATERIAL_COMPONENTS_INSPECTED\x10\xe8\x05\x12\x18\n\x13\x41TOM_TILE_REQUESTED\x10\xe9\x05\x12!\n\x1c\x41TOM_STATE_RESPONSE_RECEIVED\x10\xea\x05\x12 \n\x1b\x41TOM_TILE_RESPONSE_RECEIVED\x10\xeb\x05\x12\x1c\n\x17\x41TOM_INFLATION_FINISHED\x10\xec\x05\x12\x1a\n\x15\x41TOM_INFLATION_FAILED\x10\xed\x05\x12-\n(ATOM_IGNORED_INFLATION_FAILURES_REPORTED\x10\xee\x05\x12\x1b\n\x16\x41TOM_DRAWABLE_RENDERED\x10\xef\x05\x12!\n\x1c\x41TOM_WEAR_MODE_STATE_CHANGED\x10\xcb\x05\x12\x1f\n\x1a\x41TOM_MEDIA_ACTION_REPORTED\x10\xe0\x04\x12!\n\x1c\x41TOM_MEDIA_CONTROLS_LAUNCHED\x10\xe1\x04\x12%\n ATOM_MEDIA_SESSION_STATE_CHANGED\x10\xa5\x05\x12*\n%ATOM_MEDIA_CONTROL_API_USAGE_REPORTED\x10\xc6\x07\x12$\n\x1f\x41TOM_MEDIA_SUBSCRIPTION_CHANGED\x10\xde\x07\x12<\n7ATOM_WEAR_MEDIA_OUTPUT_SWITCHER_DEVICE_SCAN_API_LATENCY\x10\xf5\x05\x12<\n7ATOM_WEAR_MEDIA_OUTPUT_SWITCHER_SASS_DEVICE_UNAVAILABLE\x10\xf6\x05\x12\x39\n4ATOM_WEAR_MEDIA_OUTPUT_SWITCHER_FASTPAIR_API_TIMEOUT\x10\xf7\x05\x12\x1a\n\x15\x41TOM_MEDIATOR_UPDATED\x10\xd1\x05\x12+\n&ATOM_SYSPROXY_BLUETOOTH_BYTES_TRANSFER\x10\xd4O\x12%\n ATOM_SYSPROXY_CONNECTION_UPDATED\x10\x92\x06\x12)\n$ATOM_WEAR_COMPANION_CONNECTION_STATE\x10\x99\x07\x12(\n#ATOM_SYSPROXY_SERVICE_STATE_UPDATED\x10\xb5\x07\x12\x1b\n\x16\x41TOM_UWB_ACTIVITY_INFO\x10\xccO\x12(\n#ATOM_TEST_UPROBESTATS_ATOM_REPORTED\x10\x93\x07\x12%\n ATOM_TV_LOW_POWER_STANDBY_POLICY\x10\xa7\x05\x12!\n\x1c\x41TOM_EXTERNAL_TV_INPUT_EVENT\x10\xcd\x05\x12&\n!ATOM_BOOT_INTEGRITY_INFO_REPORTED\x10\x87\x06\x12/\n*ATOM_THREADNETWORK_TELEMETRY_DATA_REPORTED\x10\xe2\x05\x12+\n&ATOM_THREADNETWORK_TOPO_ENTRY_REPEATED\x10\xe3\x05\x12,\n\'ATOM_THREADNETWORK_DEVICE_INFO_REPORTED\x10\xe4\x05\x12,\n\'ATOM_CELLULAR_RADIO_POWER_STATE_CHANGED\x10\xc9\x05\x12 \n\x1b\x41TOM_EMERGENCY_NUMBERS_INFO\x10\xc4O\x12!\n\x1c\x41TOM_DATA_NETWORK_VALIDATION\x10\xdfO\x12 \n\x1b\x41TOM_DATA_RAT_STATE_CHANGED\x10\xd6\x06\x12#\n\x1e\x41TOM_CONNECTED_CHANNEL_CHANGED\x10\xf2\x06\x12\'\n\"ATOM_CELLULAR_IDENTIFIER_DISCLOSED\x10\xa0\x06\x12\x1e\n\x19\x41TOM_SATELLITE_CONTROLLER\x10\xc6O\x12\x1b\n\x16\x41TOM_SATELLITE_SESSION\x10\xc7O\x12%\n ATOM_SATELLITE_INCOMING_DATAGRAM\x10\xc8O\x12%\n ATOM_SATELLITE_OUTGOING_DATAGRAM\x10\xc9O\x12\x1d\n\x18\x41TOM_SATELLITE_PROVISION\x10\xcaO\x12+\n&ATOM_SATELLITE_SOS_MESSAGE_RECOMMENDER\x10\xcbO\x12+\n&ATOM_CARRIER_ROAMING_SATELLITE_SESSION\x10\xe3O\x12\x34\n/ATOM_CARRIER_ROAMING_SATELLITE_CONTROLLER_STATS\x10\xe4O\x12&\n!ATOM_CONTROLLER_STATS_PER_PACKAGE\x10\xe5O\x12\x1f\n\x1a\x41TOM_SATELLITE_ENTITLEMENT\x10\xe6O\x12\"\n\x1d\x41TOM_SATELLITE_CONFIG_UPDATER\x10\xe7O\x12%\n ATOM_SATELLITE_ACCESS_CONTROLLER\x10\xebO\x12$\n\x1f\x41TOM_QUALIFIED_RAT_LIST_CHANGED\x10\xfa\x04\x12!\n\x1c\x41TOM_QNS_IMS_CALL_DROP_STATS\x10\xfb\x04\x12*\n%ATOM_QNS_FALLBACK_RESTRICTION_CHANGED\x10\xfc\x04\x12*\n%ATOM_QNS_RAT_PREFERENCE_MISMATCH_INFO\x10\xc1O\x12\"\n\x1d\x41TOM_QNS_HANDOVER_TIME_MILLIS\x10\xc2O\x12\x1f\n\x1a\x41TOM_QNS_HANDOVER_PINGPONG\x10\xc3O\x12=\n8ATOM_IWLAN_UNDERLYING_NETWORK_VALIDATION_RESULT_REPORTED\x10\x9b\x07\x12!\n\x1c\x41TOM_EMERGENCY_NUMBER_DIALED\x10\xfd\x04\x12\x14\n\x0f\x41TOM_CALL_STATS\x10\xedO\x12 \n\x1b\x41TOM_CALL_AUDIO_ROUTE_STATS\x10\xeeO\x12\x1b\n\x16\x41TOM_TELECOM_API_STATS\x10\xefO\x12\x1d\n\x18\x41TOM_TELECOM_ERROR_STATS\x10\xf0O\x12&\n!ATOM_LOCKSCREEN_SHORTCUT_SELECTED\x10\xe3\x04\x12\'\n\"ATOM_LOCKSCREEN_SHORTCUT_TRIGGERED\x10\xe4\x04\x12&\n!ATOM_LAUNCHER_IMPRESSION_EVENT_V2\x10\xcc\x05\x12(\n#ATOM_DISPLAY_SWITCH_LATENCY_TRACKED\x10\xf1\x05\x12\'\n\"ATOM_NOTIFICATION_LISTENER_SERVICE\x10\xbd\x06\x12!\n\x1c\x41TOM_NAV_HANDLE_TOUCH_POINTS\x10\xe5\x06\x12,\n\'ATOM_COMMUNAL_HUB_WIDGET_EVENT_REPORTED\x10\x8c\x07\x12&\n!ATOM_PERIPHERAL_TUTORIAL_LAUNCHED\x10\xae\x07\x12(\n#ATOM_CONTEXTUAL_EDUCATION_TRIGGERED\x10\xcb\x07\x12\x1f\n\x1a\x41TOM_COMMUNAL_HUB_SNAPSHOT\x10\xf2O\x12&\n!ATOM_TEST_EXTENSION_ATOM_REPORTED\x10\x94\x05\x12\'\n\"ATOM_TEST_RESTRICTED_ATOM_REPORTED\x10\xa0\x05\x12$\n\x1f\x41TOM_STATS_SOCKET_LOSS_REPORTED\x10\xf0\x05\x12\x1f\n\x1a\x41TOM_SETTINGS_SPA_REPORTED\x10\xee\x04\x12\x1b\n\x16\x41TOM_SELINUX_AUDIT_LOG\x10\x9f\x06\x12\x1c\n\x17\x41TOM_SANDBOX_API_CALLED\x10\xe8\x03\x12)\n$ATOM_SANDBOX_ACTIVITY_EVENT_OCCURRED\x10\xdf\x05\x12\x32\n-ATOM_SDK_SANDBOX_RESTRICTED_ACCESS_IN_SESSION\x10\x9c\x06\x12\x1d\n\x18\x41TOM_SANDBOX_SDK_STORAGE\x10\xafO\x12\x19\n\x14\x41TOM_RKPD_POOL_STATS\x10\x98\x05\x12\x1f\n\x1a\x41TOM_RKPD_CLIENT_OPERATION\x10\x99\x05\x12$\n\x1f\x41TOM_RANGING_SESSION_CONFIGURED\x10\xe1\x07\x12!\n\x1c\x41TOM_RANGING_SESSION_STARTED\x10\xe2\x07\x12 \n\x1b\x41TOM_RANGING_SESSION_CLOSED\x10\xe3\x07\x12$\n\x1f\x41TOM_RANGING_TECHNOLOGY_STARTED\x10\xe4\x07\x12$\n\x1f\x41TOM_RANGING_TECHNOLOGY_STOPPED\x10\xe5\x07\x12\x33\n.ATOM_MEDIA_PROVIDER_DATABASE_ROLLBACK_REPORTED\x10\x90\x06\x12&\n!ATOM_BACKUP_SETUP_STATUS_REPORTED\x10\x91\x06\x12\x1d\n\x18\x41TOM_SCREEN_OFF_REPORTED\x10\x88\x06\x12*\n%ATOM_SCREEN_TIMEOUT_OVERRIDE_REPORTED\x10\xc4\x06\x12-\n(ATOM_SCREEN_INTERACTIVE_SESSION_REPORTED\x10\xc5\x06\x12\x1d\n\x18\x41TOM_SCREEN_DIM_REPORTED\x10\xe3\x06\x12\x13\n\x0e\x41TOM_ATOM_9999\x10\x8fN\x12\x15\n\x0f\x41TOM_ATOM_99999\x10\x9f\x8d\x06\x12+\n&ATOM_PHOTOPICKER_SESSION_INFO_REPORTED\x10\xf6\x06\x12\'\n\"ATOM_PHOTOPICKER_API_INFO_REPORTED\x10\xf7\x06\x12%\n ATOM_PHOTOPICKER_UI_EVENT_LOGGED\x10\xf8\x06\x12\x30\n+ATOM_PHOTOPICKER_MEDIA_ITEM_STATUS_REPORTED\x10\xf9\x06\x12)\n$ATOM_PHOTOPICKER_PREVIEW_INFO_LOGGED\x10\xfa\x06\x12-\n(ATOM_PHOTOPICKER_MENU_INTERACTION_LOGGED\x10\xfb\x06\x12/\n*ATOM_PHOTOPICKER_BANNER_INTERACTION_LOGGED\x10\xfc\x06\x12/\n*ATOM_PHOTOPICKER_MEDIA_LIBRARY_INFO_LOGGED\x10\xfd\x06\x12&\n!ATOM_PHOTOPICKER_PAGE_INFO_LOGGED\x10\xfe\x06\x12\x33\n.ATOM_PHOTOPICKER_MEDIA_GRID_SYNC_INFO_REPORTED\x10\xff\x06\x12.\n)ATOM_PHOTOPICKER_ALBUM_SYNC_INFO_REPORTED\x10\x80\x07\x12*\n%ATOM_PHOTOPICKER_SEARCH_INFO_REPORTED\x10\x81\x07\x12\x31\n,ATOM_SEARCH_DATA_EXTRACTION_DETAILS_REPORTED\x10\x82\x07\x12,\n\'ATOM_EMBEDDED_PHOTOPICKER_INFO_REPORTED\x10\x83\x07\x12,\n\'ATOM_PERMISSION_RATIONALE_DIALOG_VIEWED\x10\x85\x05\x12\x35\n0ATOM_PERMISSION_RATIONALE_DIALOG_ACTION_REPORTED\x10\x86\x05\x12;\n6ATOM_APP_DATA_SHARING_UPDATES_NOTIFICATION_INTERACTION\x10\x87\x05\x12\x32\n-ATOM_APP_DATA_SHARING_UPDATES_FRAGMENT_VIEWED\x10\x88\x05\x12;\n6ATOM_APP_DATA_SHARING_UPDATES_FRAGMENT_ACTION_REPORTED\x10\x89\x05\x12\x36\n1ATOM_ENHANCED_CONFIRMATION_DIALOG_RESULT_REPORTED\x10\xbb\x06\x12\x33\n.ATOM_ENHANCED_CONFIRMATION_RESTRICTION_CLEARED\x10\xbc\x06\x12$\n\x1f\x41TOM_PRESSURE_STALL_INFORMATION\x10\xf5O\x12\x1b\n\x16\x41TOM_PDF_LOAD_REPORTED\x10\xdb\x06\x12 \n\x1b\x41TOM_PDF_API_USAGE_REPORTED\x10\xdc\x06\x12\x1d\n\x18\x41TOM_PDF_SEARCH_REPORTED\x10\xdd\x06\x12*\n%ATOM_COMPONENT_STATE_CHANGED_REPORTED\x10\xdf\x06\x12,\n\'ATOM_ONDEVICEPERSONALIZATION_API_CALLED\x10\xc7\x05\x12-\n(ATOM_ONDEVICEPERSONALIZATION_TRACE_EVENT\x10\xb8\x07\x12(\n#ATOM_NFC_OBSERVE_MODE_STATE_CHANGED\x10\xd7\x06\x12\x1b\n\x16\x41TOM_NFC_FIELD_CHANGED\x10\xd8\x06\x12\x30\n+ATOM_NFC_POLLING_LOOP_NOTIFICATION_REPORTED\x10\xd9\x06\x12/\n*ATOM_NFC_PROPRIETARY_CAPABILITIES_REPORTED\x10\xda\x06\x12&\n!ATOM_NFC_EXIT_FRAME_TABLE_CHANGED\x10\x8c\x08\x12$\n\x1f\x41TOM_NFC_AUTO_TRANSACT_REPORTED\x10\x8e\x08\x12/\n*ATOM_MICROXR_DEVICE_BOOT_COMPLETE_REPORTED\x10\x85\x07\x12\x13\n\x0e\x41TOM_MTE_STATE\x10\xc5O\x12#\n\x1e\x41TOM_ZRAM_MAINTENANCE_EXECUTED\x10\xf7\x07\x12\x1d\n\x18\x41TOM_ZRAM_SETUP_EXECUTED\x10\x85\x08\x12\x1a\n\x15\x41TOM_ZRAM_MM_STAT_MMD\x10\xf8O\x12\x1a\n\x15\x41TOM_ZRAM_BD_STAT_MMD\x10\xf9O\x12&\n!ATOM_MEDIA_EDITING_ENDED_REPORTED\x10\x9e\x06\x12/\n*ATOM_MEDIA_CODEC_RECLAIM_REQUEST_COMPLETED\x10\xd8\x04\x12\x1d\n\x18\x41TOM_MEDIA_CODEC_STARTED\x10\x81\x05\x12\x1d\n\x18\x41TOM_MEDIA_CODEC_STOPPED\x10\x82\x05\x12\x1e\n\x19\x41TOM_MEDIA_CODEC_RENDERED\x10\xac\x05\x12!\n\x1c\x41TOM_EMERGENCY_STATE_CHANGED\x10\xf9\x04\x12/\n*ATOM_CHRE_SIGNIFICANT_MOTION_STATE_CHANGED\x10\xe4\x06\x12\x36\n1ATOM_POPULATION_DENSITY_PROVIDER_LOADING_REPORTED\x10\xea\x07\x12\x37\n2ATOM_DENSITY_BASED_COARSE_LOCATIONS_USAGE_REPORTED\x10\xeb\x07\x12@\n;ATOM_DENSITY_BASED_COARSE_LOCATIONS_PROVIDER_QUERY_REPORTED\x10\xec\x07\x12\"\n\x1d\x41TOM_KERNEL_OOM_KILL_OCCURRED\x10\xf2\x05\x12\x1d\n\x18\x41TOM_KEYBOARD_CONFIGURED\x10\xaa\x05\x12)\n$ATOM_KEYBOARD_SYSTEMS_EVENT_REPORTED\x10\xab\x05\x12$\n\x1f\x41TOM_INPUTDEVICE_USAGE_REPORTED\x10\xae\x05\x12&\n!ATOM_INPUT_EVENT_LATENCY_REPORTED\x10\xa4\x07\x12\x18\n\x13\x41TOM_TOUCHPAD_USAGE\x10\xcfO\x12 \n\x1b\x41TOM_IKE_SESSION_TERMINATED\x10\xa6\x05\x12.\n)ATOM_IKE_LIVENESS_CHECK_SESSION_VALIDATED\x10\xf8\x05\x12)\n$ATOM_NEGOTIATED_SECURITY_ASSOCIATION\x10\xb5\x06\x12+\n&ATOM_HOTWORD_EGRESS_SIZE_ATOM_REPORTED\x10\xf9\x05\x12&\n!ATOM_HEALTH_CONNECT_UI_IMPRESSION\x10\xef\x04\x12\'\n\"ATOM_HEALTH_CONNECT_UI_INTERACTION\x10\xf0\x04\x12,\n\'ATOM_HEALTH_CONNECT_APP_OPENED_REPORTED\x10\xf1\x04\x12#\n\x1e\x41TOM_HEALTH_CONNECT_API_CALLED\x10\xe8\x04\x12$\n\x1f\x41TOM_HEALTH_CONNECT_USAGE_STATS\x10\xe9\x04\x12&\n!ATOM_HEALTH_CONNECT_STORAGE_STATS\x10\xea\x04\x12$\n\x1f\x41TOM_HEALTH_CONNECT_API_INVOKED\x10\x83\x05\x12#\n\x1e\x41TOM_EXERCISE_ROUTE_API_CALLED\x10\x8e\x05\x12\'\n\"ATOM_HEALTH_CONNECT_EXPORT_INVOKED\x10\x8b\x07\x12\'\n\"ATOM_HEALTH_CONNECT_IMPORT_INVOKED\x10\x96\x07\x12\x35\n0ATOM_HEALTH_CONNECT_EXPORT_IMPORT_STATS_REPORTED\x10\x97\x07\x12)\n$ATOM_HEALTH_CONNECT_PERMISSION_STATS\x10\xc3\x07\x12(\n#ATOM_HEALTH_CONNECT_PHR_API_INVOKED\x10\xd4\x07\x12(\n#ATOM_HEALTH_CONNECT_PHR_USAGE_STATS\x10\xd5\x07\x12*\n%ATOM_HEALTH_CONNECT_PHR_STORAGE_STATS\x10\xd8\x07\x12\x33\n.ATOM_HEALTH_CONNECT_RESTRICTED_ECOSYSTEM_STATS\x10\xd9\x07\x12(\n#ATOM_HEALTH_CONNECT_ECOSYSTEM_STATS\x10\xda\x07\x12#\n\x1e\x41TOM_HDMI_EARC_STATUS_REPORTED\x10\xbd\x05\x12,\n\'ATOM_HDMI_SOUNDBAR_MODE_STATUS_REPORTED\x10\xd4\x05\x12?\n:ATOM_HDMI_POWER_STATE_CHANGE_ON_ACTIVE_SOURCE_LOST_TOGGLED\x10\xdf\x07\x12\x18\n\x13\x41TOM_BATTERY_HEALTH\x10\xecO\x12\x1e\n\x19\x41TOM_BIOMETRIC_UNENROLLED\x10\xb0\x07\x12\x1e\n\x19\x41TOM_BIOMETRIC_ENUMERATED\x10\xb1\x07\x12\x34\n/ATOM_APPLICATION_GRAMMATICAL_INFLECTION_CHANGED\x10\xc8\x04\x12/\n*ATOM_SYSTEM_GRAMMATICAL_INFLECTION_CHANGED\x10\xb0\x06\x12%\n ATOM_FULL_SCREEN_INTENT_LAUNCHED\x10\xf7\x04\x12\x15\n\x10\x41TOM_BAL_ALLOWED\x10\xf8\x04\x12\"\n\x1d\x41TOM_IN_TASK_ACTIVITY_STARTED\x10\xad\x05\x12$\n\x1f\x41TOM_DEVICE_ORIENTATION_CHANGED\x10\x8a\x07\x12$\n\x1f\x41TOM_CACHED_APPS_HIGH_WATERMARK\x10\xcdO\x12,\n\'ATOM_STYLUS_PREDICTION_METRICS_REPORTED\x10\xce\x05\x12\"\n\x1d\x41TOM_USER_RISK_EVENT_REPORTED\x10\xd5\x05\x12(\n#ATOM_MEDIA_PROJECTION_STATE_CHANGED\x10\xd9\x05\x12)\n$ATOM_MEDIA_PROJECTION_TARGET_CHANGED\x10\xda\x05\x12/\n*ATOM_EXCESSIVE_BINDER_PROXY_COUNT_REPORTED\x10\xd5\x06\x12\'\n\"ATOM_PROXY_BYTES_TRANSFER_BY_FG_BG\x10\xd8O\x12-\n(ATOM_MOBILE_BYTES_TRANSFER_BY_PROC_STATE\x10\xdcO\x12$\n\x1f\x41TOM_BIOMETRIC_FRR_NOTIFICATION\x10\xb1\x06\x12\x34\n/ATOM_SENSITIVE_CONTENT_MEDIA_PROJECTION_SESSION\x10\xbe\x06\x12\x37\n2ATOM_SENSITIVE_NOTIFICATION_APP_PROTECTION_SESSION\x10\xbf\x06\x12\x37\n2ATOM_SENSITIVE_NOTIFICATION_APP_PROTECTION_APPLIED\x10\xc0\x06\x12*\n%ATOM_SENSITIVE_NOTIFICATION_REDACTION\x10\xc1\x06\x12*\n%ATOM_SENSITIVE_CONTENT_APP_PROTECTION\x10\xc3\x06\x12\'\n\"ATOM_APP_RESTRICTION_STATE_CHANGED\x10\xe2\x06\x12%\n ATOM_BATTERY_USAGE_STATS_PER_UID\x10\xe1O\x12 \n\x1b\x41TOM_POSTGC_MEMORY_SNAPSHOT\x10\x9c\x07\x12+\n&ATOM_POWER_SAVE_TEMP_ALLOWLIST_CHANGED\x10\x9e\x07\x12\x1f\n\x1a\x41TOM_APP_OP_ACCESS_TRACKED\x10\xa3\x07\x12,\n\'ATOM_CONTENT_OR_FILE_URI_EVENT_REPORTED\x10\xa5\x07\x12,\n\'ATOM_DEVICE_IDLE_TEMP_ALLOWLIST_UPDATED\x10\xac\x07\x12\x36\n1ATOM_APP_OP_NOTE_OP_OR_CHECK_OP_BINDER_API_CALLED\x10\xaf\x07\x12!\n\x1c\x41TOM_FRAMEWORK_WAKELOCK_INFO\x10\xf6O\x12-\n(ATOM_JANK_FRAME_COUNT_BY_WIDGET_REPORTED\x10\xb6\x07\x12$\n\x1f\x41TOM_INTENT_CREATOR_TOKEN_ADDED\x10\xd2\x07\x12-\n(ATOM_NOTIFICATION_CHANNEL_CLASSIFICATION\x10\xd7\x07\x12\x31\n,ATOM_CAMERA_STATUS_FOR_COMPATIBILITY_CHANGED\x10\xe7\x07\x12&\n!ATOM_FEDERATED_COMPUTE_API_CALLED\x10\xc8\x05\x12\x33\n.ATOM_FEDERATED_COMPUTE_TRAINING_EVENT_REPORTED\x10\x83\x06\x12\x30\n+ATOM_EXAMPLE_ITERATOR_NEXT_LATENCY_REPORTED\x10\xc6\x06\x12\x30\n+ATOM_FEDERATED_COMPUTE_TRACE_EVENT_REPORTED\x10\xe0\x07\x12 \n\x1b\x41TOM_EXPRESS_EVENT_REPORTED\x10\x90\x04\x12+\n&ATOM_EXPRESS_HISTOGRAM_SAMPLE_REPORTED\x10\xd1\x04\x12$\n\x1f\x41TOM_EXPRESS_UID_EVENT_REPORTED\x10\x84\x05\x12/\n*ATOM_EXPRESS_UID_HISTOGRAM_SAMPLE_REPORTED\x10\x92\x05\x12\x1f\n\x1a\x41TOM_DREAM_SETTING_CHANGED\x10\xc1\x05\x12 \n\x1b\x41TOM_DREAM_SETTING_SNAPSHOT\x10\xd0O\x12\x1b\n\x16\x41TOM_DND_STATE_CHANGED\x10\x91\x05\x12(\n#ATOM_EXTERNAL_DISPLAY_STATE_CHANGED\x10\xa6\x06\x12,\n\'ATOM_DISPLAY_MODE_DIRECTOR_VOTE_CHANGED\x10\x98\x06\x12\'\n\"ATOM_DEVICE_POLICY_MANAGEMENT_MODE\x10\xe8O\x12\x1d\n\x18\x41TOM_DEVICE_POLICY_STATE\x10\xe9O\x12/\n*ATOM_DEVICE_LOCK_CHECK_IN_REQUEST_REPORTED\x10\xd6\x05\x12\x34\n/ATOM_DEVICE_LOCK_PROVISIONING_COMPLETE_REPORTED\x10\xd7\x05\x12\x30\n+ATOM_DEVICE_LOCK_KIOSK_APP_REQUEST_REPORTED\x10\xd8\x05\x12-\n(ATOM_DEVICE_LOCK_CHECK_IN_RETRY_REPORTED\x10\x95\x06\x12\x30\n+ATOM_DEVICE_LOCK_PROVISION_FAILURE_REPORTED\x10\x96\x06\x12\x39\n4ATOM_DEVICE_LOCK_LOCK_UNLOCK_DEVICE_FAILURE_REPORTED\x10\x97\x06\x12!\n\x1c\x41TOM_DESKTOP_MODE_UI_CHANGED\x10\xb2\x06\x12*\n%ATOM_DESKTOP_MODE_SESSION_TASK_UPDATE\x10\xb3\x06\x12(\n#ATOM_DESKTOP_MODE_TASK_SIZE_UPDATED\x10\xa7\x07\x12\x1f\n\x1a\x41TOM_CRONET_ENGINE_CREATED\x10\xbf\x05\x12!\n\x1c\x41TOM_CRONET_TRAFFIC_REPORTED\x10\xc0\x05\x12+\n&ATOM_CRONET_ENGINE_BUILDER_INITIALIZED\x10\xfa\x05\x12\'\n\"ATOM_CRONET_HTTP_FLAGS_INITIALIZED\x10\xfb\x05\x12\x1c\n\x17\x41TOM_CRONET_INITIALIZED\x10\xfc\x05\x12\'\n\"ATOM_CREDENTIAL_MANAGER_API_CALLED\x10\xc9\x04\x12\x30\n+ATOM_CREDENTIAL_MANAGER_INIT_PHASE_REPORTED\x10\x8b\x05\x12\x35\n0ATOM_CREDENTIAL_MANAGER_CANDIDATE_PHASE_REPORTED\x10\x8c\x05\x12\x31\n,ATOM_CREDENTIAL_MANAGER_FINAL_PHASE_REPORTED\x10\x8d\x05\x12+\n&ATOM_CREDENTIAL_MANAGER_TOTAL_REPORTED\x10\x9b\x05\x12\x30\n+ATOM_CREDENTIAL_MANAGER_FINALNOUID_REPORTED\x10\x9c\x05\x12)\n$ATOM_CREDENTIAL_MANAGER_GET_REPORTED\x10\x9d\x05\x12\x30\n+ATOM_CREDENTIAL_MANAGER_AUTH_CLICK_REPORTED\x10\x9e\x05\x12)\n$ATOM_CREDENTIAL_MANAGER_APIV2_CALLED\x10\x9f\x05\x12\x14\n\x0f\x41TOM_CPU_POLICY\x10\xd7O\x12&\n!ATOM_VPN_CONNECTION_STATE_CHANGED\x10\xd2\x06\x12!\n\x1c\x41TOM_VPN_CONNECTION_REPORTED\x10\xd3\x06\x12$\n\x1f\x41TOM_IP_CLIENT_RA_INFO_REPORTED\x10\x8a\x06\x12#\n\x1e\x41TOM_APF_SESSION_INFO_REPORTED\x10\x89\x06\x12\x31\n,ATOM_CORE_NETWORKING_TERRIBLE_ERROR_OCCURRED\x10\xd3\x07\x12.\n)ATOM_NETWORK_STATS_RECORDER_FILE_OPERATED\x10\x8f\x06\x12\'\n\"ATOM_DAILY_KEEPALIVE_INFO_REPORTED\x10\x8a\x05\x12\'\n\"ATOM_NETWORK_REQUEST_STATE_CHANGED\x10\x8b\x06\x12,\n\'ATOM_TETHERING_ACTIVE_SESSIONS_REPORTED\x10\x9d\x07\x12@\n;ATOM_CERTIFICATE_TRANSPARENCY_LOG_LIST_UPDATE_STATE_CHANGED\x10\xcc\x07\x12!\n\x1c\x41TOM_HARDWARE_RENDERER_EVENT\x10\xb2\x07\x12\x1c\n\x17\x41TOM_TEXTURE_VIEW_EVENT\x10\xb3\x07\x12\x1f\n\x1a\x41TOM_SURFACE_CONTROL_EVENT\x10\xb4\x07\x12\x17\n\x12\x41TOM_IMAGE_DECODED\x10\xd1\x07\x12\x39\n4ATOM_CERTIFICATE_TRANSPARENCY_LOG_LIST_STATE_CHANGED\x10\xa6\x07\x12 \n\x1b\x41TOM_CONSCRYPT_SERVICE_USED\x10\xc5\x07\x12\x38\n3ATOM_CERTIFICATE_TRANSPARENCY_VERIFICATION_REPORTED\x10\xdd\x07\x12\x30\n+ATOM_CAMERA_FEATURE_COMBINATION_QUERY_EVENT\x10\x84\x07\x12\x18\n\x13\x41TOM_BROADCAST_SENT\x10\x9a\x07\x12/\n*ATOM_BLUETOOTH_HASHED_DEVICE_NAME_REPORTED\x10\xe5\x04\x12/\n*ATOM_BLUETOOTH_L2CAP_COC_CLIENT_CONNECTION\x10\xe6\x04\x12/\n*ATOM_BLUETOOTH_L2CAP_COC_SERVER_CONNECTION\x10\xe7\x04\x12(\n#ATOM_BLUETOOTH_LE_SESSION_CONNECTED\x10\x90\x05\x12\x33\n.ATOM_RESTRICTED_BLUETOOTH_DEVICE_NAME_REPORTED\x10\x9a\x05\x12\x30\n+ATOM_BLUETOOTH_PROFILE_CONNECTION_ATTEMPTED\x10\xb8\x05\x12\x32\n-ATOM_BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED\x10\x8d\x06\x12/\n*ATOM_BLUETOOTH_RFCOMM_CONNECTION_ATTEMPTED\x10\x8e\x06\x12\x32\n-ATOM_REMOTE_DEVICE_INFORMATION_WITH_METRIC_ID\x10\xde\x06\x12#\n\x1e\x41TOM_LE_APP_SCAN_STATE_CHANGED\x10\xe6\x06\x12\x1f\n\x1a\x41TOM_LE_RADIO_SCAN_STOPPED\x10\xe7\x06\x12!\n\x1c\x41TOM_LE_SCAN_RESULT_RECEIVED\x10\xe8\x06\x12\x18\n\x13\x41TOM_LE_SCAN_ABUSED\x10\xe9\x06\x12\x1e\n\x19\x41TOM_LE_ADV_STATE_CHANGED\x10\xea\x06\x12\x1f\n\x1a\x41TOM_LE_ADV_ERROR_REPORTED\x10\xeb\x06\x12\x1f\n\x1a\x41TOM_A2DP_SESSION_REPORTED\x10\x88\x07\x12.\n)ATOM_BLUETOOTH_CROSS_LAYER_EVENT_REPORTED\x10\x94\x07\x12*\n%ATOM_BROADCAST_AUDIO_SESSION_REPORTED\x10\x9f\x07\x12\'\n\"ATOM_BROADCAST_AUDIO_SYNC_REPORTED\x10\xa0\x07\x12\x37\n2ATOM_BLUETOOTH_RFCOMM_CONNECTION_REPORTED_AT_CLOSE\x10\xd6\x07\x12!\n\x1c\x41TOM_BLUETOOTH_LE_CONNECTION\x10\xdc\x07\x12.\n)ATOM_HEARING_DEVICE_ACTIVE_EVENT_REPORTED\x10\xfd\x07\x12(\n#ATOM_BACKPORTED_FIX_STATUS_REPORTED\x10\xdb\x07\x12\x1c\n\x17\x41TOM_PLUGIN_INITIALIZED\x10\x8f\x05\x12\x38\n3ATOM_CAR_SYSTEM_UI_DATA_SUBSCRIPTION_EVENT_REPORTED\x10\xce\x07\x12\x37\n2ATOM_CAR_SETTINGS_DATA_SUBSCRIPTION_EVENT_REPORTED\x10\xcf\x07\x12#\n\x1e\x41TOM_CAR_QC_LIB_EVENT_REPORTED\x10\xd0\x07\x12*\n%ATOM_CAR_WAKEUP_FROM_SUSPEND_REPORTED\x10\xd4\x06\x12$\n\x1f\x41TOM_CAR_RECENTS_EVENT_REPORTED\x10\x82\x06\x12&\n!ATOM_CAR_CALM_MODE_EVENT_REPORTED\x10\x9d\x06\x12$\n\x1f\x41TOM_AUTOFILL_UI_EVENT_REPORTED\x10\xdb\x04\x12(\n#ATOM_AUTOFILL_FILL_REQUEST_REPORTED\x10\xdc\x04\x12)\n$ATOM_AUTOFILL_FILL_RESPONSE_REPORTED\x10\xdd\x04\x12&\n!ATOM_AUTOFILL_SAVE_EVENT_REPORTED\x10\xde\x04\x12$\n\x1f\x41TOM_AUTOFILL_SESSION_COMMITTED\x10\xdf\x04\x12\x36\n1ATOM_AUTOFILL_FIELD_CLASSIFICATION_EVENT_REPORTED\x10\x93\x05\x12\x1c\n\x17\x41TOM_ODREFRESH_REPORTED\x10\xee\x02\x12\x19\n\x14\x41TOM_ODSIGN_REPORTED\x10\xa4\x04\x12%\n ATOM_BACKGROUND_DEXOPT_JOB_ENDED\x10\xd3\x03\x12$\n\x1f\x41TOM_PREREBOOT_DEXOPT_JOB_ENDED\x10\xf3\x06\x12\x1c\n\x17\x41TOM_ART_DATUM_REPORTED\x10\xcc\x02\x12#\n\x1e\x41TOM_ART_DEVICE_DATUM_REPORTED\x10\xa6\x04\x12\"\n\x1d\x41TOM_ART_DATUM_DELTA_REPORTED\x10\xb5\x04\x12\x1e\n\x19\x41TOM_ART_DEX2OAT_REPORTED\x10\xa1\x07\x12\x1b\n\x16\x41TOM_ART_DEVICE_STATUS\x10\xddO\x12.\n)ATOM_APP_SEARCH_SET_SCHEMA_STATS_REPORTED\x10\x81\x03\x12\x34\n/ATOM_APP_SEARCH_SCHEMA_MIGRATION_STATS_REPORTED\x10\xc3\x04\x12\x37\n2ATOM_APP_SEARCH_USAGE_SEARCH_INTENT_STATS_REPORTED\x10\xb9\x06\x12\x41\n<ATOM_APP_SEARCH_USAGE_SEARCH_INTENT_RAW_QUERY_STATS_REPORTED\x10\xba\x06\x12\x30\n+ATOM_APP_SEARCH_APPS_INDEXER_STATS_REPORTED\x10\x8d\x07\x12(\n#ATOM_APP_FUNCTIONS_REQUEST_REPORTED\x10\xe6\x07\x12%\n ATOM_APEX_INSTALLATION_REQUESTED\x10\xdc\x05\x12\"\n\x1d\x41TOM_APEX_INSTALLATION_STAGED\x10\xdd\x05\x12!\n\x1c\x41TOM_APEX_INSTALLATION_ENDED\x10\xde\x05\x12&\n!ATOM_AI_WALLPAPERS_BUTTON_PRESSED\x10\xc2\x05\x12)\n$ATOM_AI_WALLPAPERS_TEMPLATE_SELECTED\x10\xc3\x05\x12%\n ATOM_AI_WALLPAPERS_TERM_SELECTED\x10\xc4\x05\x12%\n ATOM_AI_WALLPAPERS_WALLPAPER_SET\x10\xc5\x05\x12\'\n\"ATOM_AI_WALLPAPERS_SESSION_SUMMARY\x10\xc6\x05\x12)\n$ATOM_JSSCRIPTENGINE_LATENCY_REPORTED\x10\xe3\x03\x12 \n\x1b\x41TOM_AD_SERVICES_API_CALLED\x10\xb3\x03\x12\x31\n,ATOM_AD_SERVICES_MESUREMENT_REPORTS_UPLOADED\x10\xb4\x03\x12\x39\n4ATOM_MOBILE_DATA_DOWNLOAD_FILE_GROUP_STATUS_REPORTED\x10\xea\x03\x12\x37\n2ATOM_MOBILE_DATA_DOWNLOAD_DOWNLOAD_RESULT_REPORTED\x10\xf6\x03\x12-\n(ATOM_AD_SERVICES_SETTINGS_USAGE_REPORTED\x10\xed\x03\x12+\n&ATOM_BACKGROUND_FETCH_PROCESS_REPORTED\x10\xf0\x03\x12\x31\n,ATOM_UPDATE_CUSTOM_AUDIENCE_PROCESS_REPORTED\x10\xf1\x03\x12)\n$ATOM_RUN_AD_BIDDING_PROCESS_REPORTED\x10\xf2\x03\x12)\n$ATOM_RUN_AD_SCORING_PROCESS_REPORTED\x10\xf3\x03\x12+\n&ATOM_RUN_AD_SELECTION_PROCESS_REPORTED\x10\xf4\x03\x12\x30\n+ATOM_RUN_AD_BIDDING_PER_CA_PROCESS_REPORTED\x10\xf5\x03\x12@\n;ATOM_MOBILE_DATA_DOWNLOAD_FILE_GROUP_STORAGE_STATS_REPORTED\x10\xf7\x03\x12/\n*ATOM_AD_SERVICES_MEASUREMENT_REGISTRATIONS\x10\x80\x04\x12)\n$ATOM_AD_SERVICES_GET_TOPICS_REPORTED\x10\x97\x04\x12?\n:ATOM_AD_SERVICES_EPOCH_COMPUTATION_GET_TOP_TOPICS_REPORTED\x10\x98\x04\x12;\n6ATOM_AD_SERVICES_EPOCH_COMPUTATION_CLASSIFIER_REPORTED\x10\x99\x04\x12\x35\n0ATOM_AD_SERVICES_BACK_COMPAT_GET_TOPICS_REPORTED\x10\xd6\x04\x12G\nBATOM_AD_SERVICES_BACK_COMPAT_EPOCH_COMPUTATION_CLASSIFIER_REPORTED\x10\xd7\x04\x12,\n\'ATOM_AD_SERVICES_MEASUREMENT_DEBUG_KEYS\x10\x80\x05\x12$\n\x1f\x41TOM_AD_SERVICES_ERROR_REPORTED\x10\x96\x05\x12\x38\n3ATOM_AD_SERVICES_BACKGROUND_JOBS_EXECUTION_REPORTED\x10\x97\x05\x12=\n8ATOM_AD_SERVICES_MEASUREMENT_DELAYED_SOURCE_REGISTRATION\x10\xa1\x05\x12-\n(ATOM_AD_SERVICES_MEASUREMENT_ATTRIBUTION\x10\xa2\x05\x12&\n!ATOM_AD_SERVICES_MEASUREMENT_JOBS\x10\xa3\x05\x12)\n$ATOM_AD_SERVICES_MEASUREMENT_WIPEOUT\x10\xa4\x05\x12<\n7ATOM_AD_SERVICES_MEASUREMENT_AD_ID_MATCH_FOR_DEBUG_KEYS\x10\xb7\x05\x12,\n\'ATOM_AD_SERVICES_ENROLLMENT_DATA_STORED\x10\xb9\x05\x12\x30\n+ATOM_AD_SERVICES_ENROLLMENT_FILE_DOWNLOADED\x10\xba\x05\x12(\n#ATOM_AD_SERVICES_ENROLLMENT_MATCHED\x10\xbb\x05\x12&\n!ATOM_AD_SERVICES_CONSENT_MIGRATED\x10\xbe\x05\x12\'\n\"ATOM_AD_SERVICES_ENROLLMENT_FAILED\x10\xca\x05\x12\x34\n/ATOM_AD_SERVICES_MEASUREMENT_CLICK_VERIFICATION\x10\xf4\x05\x12,\n\'ATOM_AD_SERVICES_ENCRYPTION_KEY_FETCHED\x10\xfd\x05\x12\x39\n4ATOM_AD_SERVICES_ENCRYPTION_KEY_DB_TRANSACTION_ENDED\x10\xfe\x05\x12(\n#ATOM_DESTINATION_REGISTERED_BEACONS\x10\xff\x05\x12\'\n\"ATOM_REPORT_INTERACTION_API_CALLED\x10\x80\x06\x12-\n(ATOM_INTERACTION_REPORTING_TABLE_CLEARED\x10\x81\x06\x12+\n&ATOM_APP_MANIFEST_CONFIG_HELPER_CALLED\x10\x94\x06\x12/\n*ATOM_AD_FILTERING_PROCESS_JOIN_CA_REPORTED\x10\x99\x06\x12\x34\n/ATOM_AD_FILTERING_PROCESS_AD_SELECTION_REPORTED\x10\x9a\x06\x12/\n*ATOM_AD_COUNTER_HISTOGRAM_UPDATER_REPORTED\x10\x9b\x06\x12 \n\x1b\x41TOM_SIGNATURE_VERIFICATION\x10\xa7\x06\x12\x34\n/ATOM_K_ANON_IMMEDIATE_SIGN_JOIN_STATUS_REPORTED\x10\xa8\x06\x12/\n*ATOM_K_ANON_BACKGROUND_JOB_STATUS_REPORTED\x10\xa9\x06\x12+\n&ATOM_K_ANON_INITIALIZE_STATUS_REPORTED\x10\xaa\x06\x12%\n ATOM_K_ANON_SIGN_STATUS_REPORTED\x10\xab\x06\x12%\n ATOM_K_ANON_JOIN_STATUS_REPORTED\x10\xac\x06\x12\x30\n+ATOM_K_ANON_KEY_ATTESTATION_STATUS_REPORTED\x10\xad\x06\x12*\n%ATOM_GET_AD_SELECTION_DATA_API_CALLED\x10\xae\x06\x12\x35\n0ATOM_GET_AD_SELECTION_DATA_BUYER_INPUT_GENERATED\x10\xaf\x06\x12,\n\'ATOM_BACKGROUND_JOB_SCHEDULING_REPORTED\x10\xc2\x06\x12\x36\n1ATOM_TOPICS_ENCRYPTION_EPOCH_COMPUTATION_REPORTED\x10\xc8\x06\x12/\n*ATOM_TOPICS_ENCRYPTION_GET_TOPICS_REPORTED\x10\xc9\x06\x12)\n$ATOM_ADSERVICES_SHELL_COMMAND_CALLED\x10\xca\x06\x12#\n\x1e\x41TOM_UPDATE_SIGNALS_API_CALLED\x10\xcb\x06\x12\x1a\n\x15\x41TOM_ENCODING_JOB_RUN\x10\xcc\x06\x12\x1b\n\x16\x41TOM_ENCODING_JS_FETCH\x10\xcd\x06\x12\x1f\n\x1a\x41TOM_ENCODING_JS_EXECUTION\x10\xce\x06\x12,\n\'ATOM_PERSIST_AD_SELECTION_RESULT_CALLED\x10\xcf\x06\x12)\n$ATOM_SERVER_AUCTION_KEY_FETCH_CALLED\x10\xd0\x06\x12\x35\n0ATOM_SERVER_AUCTION_BACKGROUND_KEY_FETCH_ENABLED\x10\xd1\x06\x12:\n5ATOM_AD_SERVICES_MEASUREMENT_PROCESS_ODP_REGISTRATION\x10\xe0\x06\x12<\n7ATOM_AD_SERVICES_MEASUREMENT_NOTIFY_REGISTRATION_TO_ODP\x10\xe1\x06\x12-\n(ATOM_SELECT_ADS_FROM_OUTCOMES_API_CALLED\x10\xec\x06\x12&\n!ATOM_REPORT_IMPRESSION_API_CALLED\x10\xed\x06\x12\x32\n-ATOM_AD_SERVICES_ENROLLMENT_TRANSACTION_STATS\x10\xf5\x06\x12\x32\n-ATOM_AD_SERVICES_COBALT_LOGGER_EVENT_REPORTED\x10\x86\x07\x12\x38\n3ATOM_AD_SERVICES_COBALT_PERIODIC_JOB_EVENT_REPORTED\x10\x87\x07\x12)\n$ATOM_UPDATE_SIGNALS_PROCESS_REPORTED\x10\x89\x07\x12\x34\n/ATOM_TOPICS_SCHEDULE_EPOCH_JOB_SETTING_REPORTED\x10\xa2\x07\x12=\n8ATOM_SCHEDULED_CUSTOM_AUDIENCE_UPDATE_SCHEDULE_ATTEMPTED\x10\xc7\x07\x12\x34\n/ATOM_SCHEDULED_CUSTOM_AUDIENCE_UPDATE_PERFORMED\x10\xc8\x07\x12O\nJATOM_SCHEDULED_CUSTOM_AUDIENCE_UPDATE_PERFORMED_ATTEMPTED_FAILURE_REPORTED\x10\xc9\x07\x12=\n8ATOM_SCHEDULED_CUSTOM_AUDIENCE_UPDATE_BACKGROUND_JOB_RAN\x10\xca\x07\x12\x1f\n\x1a\x41TOM_THERMAL_STATUS_CALLED\x10\x84\x06\x12!\n\x1c\x41TOM_THERMAL_HEADROOM_CALLED\x10\x85\x06\x12,\n\'ATOM_THERMAL_HEADROOM_THRESHOLDS_CALLED\x10\x86\x06\x12\'\n\"ATOM_ADPF_HINT_SESSION_TID_CLEANUP\x10\xc7\x06\x12%\n ATOM_THERMAL_HEADROOM_THRESHOLDS\x10\xd9O\x12\x1f\n\x1a\x41TOM_ADPF_SESSION_SNAPSHOT\x10\xeaO\x12\x32\n-ATOM_ADAPTIVE_AUTH_UNLOCK_AFTER_LOCK_REPORTED\x10\xb4\x06\x12\x1f\n\x1a\x41TOM_ACCOUNT_MANAGER_EVENT\x10\xb7\x07\x12-\n(ATOM_ACCESSIBILITY_CHECK_RESULT_REPORTED\x10\x8e\x07*\xa5\x07\n\x0fMeminfoCounters\x12\x17\n\x13MEMINFO_UNSPECIFIED\x10\x00\x12\x15\n\x11MEMINFO_MEM_TOTAL\x10\x01\x12\x14\n\x10MEMINFO_MEM_FREE\x10\x02\x12\x19\n\x15MEMINFO_MEM_AVAILABLE\x10\x03\x12\x13\n\x0fMEMINFO_BUFFERS\x10\x04\x12\x12\n\x0eMEMINFO_CACHED\x10\x05\x12\x17\n\x13MEMINFO_SWAP_CACHED\x10\x06\x12\x12\n\x0eMEMINFO_ACTIVE\x10\x07\x12\x14\n\x10MEMINFO_INACTIVE\x10\x08\x12\x17\n\x13MEMINFO_ACTIVE_ANON\x10\t\x12\x19\n\x15MEMINFO_INACTIVE_ANON\x10\n\x12\x17\n\x13MEMINFO_ACTIVE_FILE\x10\x0b\x12\x19\n\x15MEMINFO_INACTIVE_FILE\x10\x0c\x12\x17\n\x13MEMINFO_UNEVICTABLE\x10\r\x12\x13\n\x0fMEMINFO_MLOCKED\x10\x0e\x12\x16\n\x12MEMINFO_SWAP_TOTAL\x10\x0f\x12\x15\n\x11MEMINFO_SWAP_FREE\x10\x10\x12\x11\n\rMEMINFO_DIRTY\x10\x11\x12\x15\n\x11MEMINFO_WRITEBACK\x10\x12\x12\x16\n\x12MEMINFO_ANON_PAGES\x10\x13\x12\x12\n\x0eMEMINFO_MAPPED\x10\x14\x12\x11\n\rMEMINFO_SHMEM\x10\x15\x12\x10\n\x0cMEMINFO_SLAB\x10\x16\x12\x1c\n\x18MEMINFO_SLAB_RECLAIMABLE\x10\x17\x12\x1e\n\x1aMEMINFO_SLAB_UNRECLAIMABLE\x10\x18\x12\x18\n\x14MEMINFO_KERNEL_STACK\x10\x19\x12\x17\n\x13MEMINFO_PAGE_TABLES\x10\x1a\x12\x18\n\x14MEMINFO_COMMIT_LIMIT\x10\x1b\x12\x17\n\x13MEMINFO_COMMITED_AS\x10\x1c\x12\x19\n\x15MEMINFO_VMALLOC_TOTAL\x10\x1d\x12\x18\n\x14MEMINFO_VMALLOC_USED\x10\x1e\x12\x19\n\x15MEMINFO_VMALLOC_CHUNK\x10\x1f\x12\x15\n\x11MEMINFO_CMA_TOTAL\x10 \x12\x14\n\x10MEMINFO_CMA_FREE\x10!\x12\x0f\n\x0bMEMINFO_GPU\x10\"\x12\x10\n\x0cMEMINFO_ZRAM\x10#\x12\x10\n\x0cMEMINFO_MISC\x10$\x12\x14\n\x10MEMINFO_ION_HEAP\x10%\x12\x19\n\x15MEMINFO_ION_HEAP_POOL\x10&*\x81,\n\x0eVmstatCounters\x12\x16\n\x12VMSTAT_UNSPECIFIED\x10\x00\x12\x18\n\x14VMSTAT_NR_FREE_PAGES\x10\x01\x12\x19\n\x15VMSTAT_NR_ALLOC_BATCH\x10\x02\x12\x1b\n\x17VMSTAT_NR_INACTIVE_ANON\x10\x03\x12\x19\n\x15VMSTAT_NR_ACTIVE_ANON\x10\x04\x12\x1b\n\x17VMSTAT_NR_INACTIVE_FILE\x10\x05\x12\x19\n\x15VMSTAT_NR_ACTIVE_FILE\x10\x06\x12\x19\n\x15VMSTAT_NR_UNEVICTABLE\x10\x07\x12\x13\n\x0fVMSTAT_NR_MLOCK\x10\x08\x12\x18\n\x14VMSTAT_NR_ANON_PAGES\x10\t\x12\x14\n\x10VMSTAT_NR_MAPPED\x10\n\x12\x18\n\x14VMSTAT_NR_FILE_PAGES\x10\x0b\x12\x13\n\x0fVMSTAT_NR_DIRTY\x10\x0c\x12\x17\n\x13VMSTAT_NR_WRITEBACK\x10\r\x12\x1e\n\x1aVMSTAT_NR_SLAB_RECLAIMABLE\x10\x0e\x12 \n\x1cVMSTAT_NR_SLAB_UNRECLAIMABLE\x10\x0f\x12\x1e\n\x1aVMSTAT_NR_PAGE_TABLE_PAGES\x10\x10\x12\x1a\n\x16VMSTAT_NR_KERNEL_STACK\x10\x11\x12\x16\n\x12VMSTAT_NR_OVERHEAD\x10\x12\x12\x16\n\x12VMSTAT_NR_UNSTABLE\x10\x13\x12\x14\n\x10VMSTAT_NR_BOUNCE\x10\x14\x12\x1a\n\x16VMSTAT_NR_VMSCAN_WRITE\x10\x15\x12&\n\"VMSTAT_NR_VMSCAN_IMMEDIATE_RECLAIM\x10\x16\x12\x1c\n\x18VMSTAT_NR_WRITEBACK_TEMP\x10\x17\x12\x1b\n\x17VMSTAT_NR_ISOLATED_ANON\x10\x18\x12\x1b\n\x17VMSTAT_NR_ISOLATED_FILE\x10\x19\x12\x13\n\x0fVMSTAT_NR_SHMEM\x10\x1a\x12\x15\n\x11VMSTAT_NR_DIRTIED\x10\x1b\x12\x15\n\x11VMSTAT_NR_WRITTEN\x10\x1c\x12\x1b\n\x17VMSTAT_NR_PAGES_SCANNED\x10\x1d\x12\x1d\n\x19VMSTAT_WORKINGSET_REFAULT\x10\x1e\x12\x1e\n\x1aVMSTAT_WORKINGSET_ACTIVATE\x10\x1f\x12!\n\x1dVMSTAT_WORKINGSET_NODERECLAIM\x10 \x12(\n$VMSTAT_NR_ANON_TRANSPARENT_HUGEPAGES\x10!\x12\x16\n\x12VMSTAT_NR_FREE_CMA\x10\"\x12\x17\n\x13VMSTAT_NR_SWAPCACHE\x10#\x12\x1d\n\x19VMSTAT_NR_DIRTY_THRESHOLD\x10$\x12(\n$VMSTAT_NR_DIRTY_BACKGROUND_THRESHOLD\x10%\x12\x11\n\rVMSTAT_PGPGIN\x10&\x12\x12\n\x0eVMSTAT_PGPGOUT\x10\'\x12\x17\n\x13VMSTAT_PGPGOUTCLEAN\x10(\x12\x11\n\rVMSTAT_PSWPIN\x10)\x12\x12\n\x0eVMSTAT_PSWPOUT\x10*\x12\x16\n\x12VMSTAT_PGALLOC_DMA\x10+\x12\x19\n\x15VMSTAT_PGALLOC_NORMAL\x10,\x12\x1a\n\x16VMSTAT_PGALLOC_MOVABLE\x10-\x12\x11\n\rVMSTAT_PGFREE\x10.\x12\x15\n\x11VMSTAT_PGACTIVATE\x10/\x12\x17\n\x13VMSTAT_PGDEACTIVATE\x10\x30\x12\x12\n\x0eVMSTAT_PGFAULT\x10\x31\x12\x15\n\x11VMSTAT_PGMAJFAULT\x10\x32\x12\x17\n\x13VMSTAT_PGREFILL_DMA\x10\x33\x12\x1a\n\x16VMSTAT_PGREFILL_NORMAL\x10\x34\x12\x1b\n\x17VMSTAT_PGREFILL_MOVABLE\x10\x35\x12\x1d\n\x19VMSTAT_PGSTEAL_KSWAPD_DMA\x10\x36\x12 \n\x1cVMSTAT_PGSTEAL_KSWAPD_NORMAL\x10\x37\x12!\n\x1dVMSTAT_PGSTEAL_KSWAPD_MOVABLE\x10\x38\x12\x1d\n\x19VMSTAT_PGSTEAL_DIRECT_DMA\x10\x39\x12 \n\x1cVMSTAT_PGSTEAL_DIRECT_NORMAL\x10:\x12!\n\x1dVMSTAT_PGSTEAL_DIRECT_MOVABLE\x10;\x12\x1c\n\x18VMSTAT_PGSCAN_KSWAPD_DMA\x10<\x12\x1f\n\x1bVMSTAT_PGSCAN_KSWAPD_NORMAL\x10=\x12 \n\x1cVMSTAT_PGSCAN_KSWAPD_MOVABLE\x10>\x12\x1c\n\x18VMSTAT_PGSCAN_DIRECT_DMA\x10?\x12\x1f\n\x1bVMSTAT_PGSCAN_DIRECT_NORMAL\x10@\x12 \n\x1cVMSTAT_PGSCAN_DIRECT_MOVABLE\x10\x41\x12!\n\x1dVMSTAT_PGSCAN_DIRECT_THROTTLE\x10\x42\x12\x17\n\x13VMSTAT_PGINODESTEAL\x10\x43\x12\x18\n\x14VMSTAT_SLABS_SCANNED\x10\x44\x12\x1c\n\x18VMSTAT_KSWAPD_INODESTEAL\x10\x45\x12\'\n#VMSTAT_KSWAPD_LOW_WMARK_HIT_QUICKLY\x10\x46\x12(\n$VMSTAT_KSWAPD_HIGH_WMARK_HIT_QUICKLY\x10G\x12\x15\n\x11VMSTAT_PAGEOUTRUN\x10H\x12\x15\n\x11VMSTAT_ALLOCSTALL\x10I\x12\x14\n\x10VMSTAT_PGROTATED\x10J\x12\x19\n\x15VMSTAT_DROP_PAGECACHE\x10K\x12\x14\n\x10VMSTAT_DROP_SLAB\x10L\x12\x1c\n\x18VMSTAT_PGMIGRATE_SUCCESS\x10M\x12\x19\n\x15VMSTAT_PGMIGRATE_FAIL\x10N\x12\"\n\x1eVMSTAT_COMPACT_MIGRATE_SCANNED\x10O\x12\x1f\n\x1bVMSTAT_COMPACT_FREE_SCANNED\x10P\x12\x1b\n\x17VMSTAT_COMPACT_ISOLATED\x10Q\x12\x18\n\x14VMSTAT_COMPACT_STALL\x10R\x12\x17\n\x13VMSTAT_COMPACT_FAIL\x10S\x12\x1a\n\x16VMSTAT_COMPACT_SUCCESS\x10T\x12\x1e\n\x1aVMSTAT_COMPACT_DAEMON_WAKE\x10U\x12!\n\x1dVMSTAT_UNEVICTABLE_PGS_CULLED\x10V\x12\"\n\x1eVMSTAT_UNEVICTABLE_PGS_SCANNED\x10W\x12\"\n\x1eVMSTAT_UNEVICTABLE_PGS_RESCUED\x10X\x12\"\n\x1eVMSTAT_UNEVICTABLE_PGS_MLOCKED\x10Y\x12$\n VMSTAT_UNEVICTABLE_PGS_MUNLOCKED\x10Z\x12\"\n\x1eVMSTAT_UNEVICTABLE_PGS_CLEARED\x10[\x12#\n\x1fVMSTAT_UNEVICTABLE_PGS_STRANDED\x10\\\x12\x15\n\x11VMSTAT_NR_ZSPAGES\x10]\x12\x16\n\x12VMSTAT_NR_ION_HEAP\x10^\x12\x16\n\x12VMSTAT_NR_GPU_HEAP\x10_\x12\x19\n\x15VMSTAT_ALLOCSTALL_DMA\x10`\x12\x1d\n\x19VMSTAT_ALLOCSTALL_MOVABLE\x10\x61\x12\x1c\n\x18VMSTAT_ALLOCSTALL_NORMAL\x10\x62\x12&\n\"VMSTAT_COMPACT_DAEMON_FREE_SCANNED\x10\x63\x12)\n%VMSTAT_COMPACT_DAEMON_MIGRATE_SCANNED\x10\x64\x12\x15\n\x11VMSTAT_NR_FASTRPC\x10\x65\x12$\n VMSTAT_NR_INDIRECTLY_RECLAIMABLE\x10\x66\x12\x1b\n\x17VMSTAT_NR_ION_HEAP_POOL\x10g\x12%\n!VMSTAT_NR_KERNEL_MISC_RECLAIMABLE\x10h\x12%\n!VMSTAT_NR_SHADOW_CALL_STACK_BYTES\x10i\x12\x1d\n\x19VMSTAT_NR_SHMEM_HUGEPAGES\x10j\x12\x1d\n\x19VMSTAT_NR_SHMEM_PMDMAPPED\x10k\x12!\n\x1dVMSTAT_NR_UNRECLAIMABLE_PAGES\x10l\x12\x1e\n\x1aVMSTAT_NR_ZONE_ACTIVE_ANON\x10m\x12\x1e\n\x1aVMSTAT_NR_ZONE_ACTIVE_FILE\x10n\x12 \n\x1cVMSTAT_NR_ZONE_INACTIVE_ANON\x10o\x12 \n\x1cVMSTAT_NR_ZONE_INACTIVE_FILE\x10p\x12\x1e\n\x1aVMSTAT_NR_ZONE_UNEVICTABLE\x10q\x12 \n\x1cVMSTAT_NR_ZONE_WRITE_PENDING\x10r\x12\x13\n\x0fVMSTAT_OOM_KILL\x10s\x12\x15\n\x11VMSTAT_PGLAZYFREE\x10t\x12\x16\n\x12VMSTAT_PGLAZYFREED\x10u\x12\x13\n\x0fVMSTAT_PGREFILL\x10v\x12\x18\n\x14VMSTAT_PGSCAN_DIRECT\x10w\x12\x18\n\x14VMSTAT_PGSCAN_KSWAPD\x10x\x12\x15\n\x11VMSTAT_PGSKIP_DMA\x10y\x12\x19\n\x15VMSTAT_PGSKIP_MOVABLE\x10z\x12\x18\n\x14VMSTAT_PGSKIP_NORMAL\x10{\x12\x19\n\x15VMSTAT_PGSTEAL_DIRECT\x10|\x12\x19\n\x15VMSTAT_PGSTEAL_KSWAPD\x10}\x12\x12\n\x0eVMSTAT_SWAP_RA\x10~\x12\x16\n\x12VMSTAT_SWAP_RA_HIT\x10\x7f\x12\x1e\n\x19VMSTAT_WORKINGSET_RESTORE\x10\x80\x01\x12\x1d\n\x18VMSTAT_ALLOCSTALL_DEVICE\x10\x81\x01\x12\x1c\n\x17VMSTAT_ALLOCSTALL_DMA32\x10\x82\x01\x12\x1b\n\x16VMSTAT_BALLOON_DEFLATE\x10\x83\x01\x12\x1b\n\x16VMSTAT_BALLOON_INFLATE\x10\x84\x01\x12\x1b\n\x16VMSTAT_BALLOON_MIGRATE\x10\x85\x01\x12\x1a\n\x15VMSTAT_CMA_ALLOC_FAIL\x10\x86\x01\x12\x1d\n\x18VMSTAT_CMA_ALLOC_SUCCESS\x10\x87\x01\x12\x1d\n\x18VMSTAT_NR_FILE_HUGEPAGES\x10\x88\x01\x12\x1d\n\x18VMSTAT_NR_FILE_PMDMAPPED\x10\x89\x01\x12 \n\x1bVMSTAT_NR_FOLL_PIN_ACQUIRED\x10\x8a\x01\x12 \n\x1bVMSTAT_NR_FOLL_PIN_RELEASED\x10\x8b\x01\x12#\n\x1eVMSTAT_NR_SEC_PAGE_TABLE_PAGES\x10\x8c\x01\x12 \n\x1bVMSTAT_NR_SHADOW_CALL_STACK\x10\x8d\x01\x12\x19\n\x14VMSTAT_NR_SWAPCACHED\x10\x8e\x01\x12 \n\x1bVMSTAT_NR_THROTTLED_WRITTEN\x10\x8f\x01\x12\x1a\n\x15VMSTAT_PGALLOC_DEVICE\x10\x90\x01\x12\x19\n\x14VMSTAT_PGALLOC_DMA32\x10\x91\x01\x12\x1b\n\x16VMSTAT_PGDEMOTE_DIRECT\x10\x92\x01\x12\x1b\n\x16VMSTAT_PGDEMOTE_KSWAPD\x10\x93\x01\x12\x13\n\x0eVMSTAT_PGREUSE\x10\x94\x01\x12\x17\n\x12VMSTAT_PGSCAN_ANON\x10\x95\x01\x12\x17\n\x12VMSTAT_PGSCAN_FILE\x10\x96\x01\x12\x19\n\x14VMSTAT_PGSKIP_DEVICE\x10\x97\x01\x12\x18\n\x13VMSTAT_PGSKIP_DMA32\x10\x98\x01\x12\x18\n\x13VMSTAT_PGSTEAL_ANON\x10\x99\x01\x12\x18\n\x13VMSTAT_PGSTEAL_FILE\x10\x9a\x01\x12\x1e\n\x19VMSTAT_THP_COLLAPSE_ALLOC\x10\x9b\x01\x12%\n VMSTAT_THP_COLLAPSE_ALLOC_FAILED\x10\x9c\x01\x12#\n\x1eVMSTAT_THP_DEFERRED_SPLIT_PAGE\x10\x9d\x01\x12\x1b\n\x16VMSTAT_THP_FAULT_ALLOC\x10\x9e\x01\x12\x1e\n\x19VMSTAT_THP_FAULT_FALLBACK\x10\x9f\x01\x12%\n VMSTAT_THP_FAULT_FALLBACK_CHARGE\x10\xa0\x01\x12\x1a\n\x15VMSTAT_THP_FILE_ALLOC\x10\xa1\x01\x12\x1d\n\x18VMSTAT_THP_FILE_FALLBACK\x10\xa2\x01\x12$\n\x1fVMSTAT_THP_FILE_FALLBACK_CHARGE\x10\xa3\x01\x12\x1b\n\x16VMSTAT_THP_FILE_MAPPED\x10\xa4\x01\x12\x1e\n\x19VMSTAT_THP_MIGRATION_FAIL\x10\xa5\x01\x12\x1f\n\x1aVMSTAT_THP_MIGRATION_SPLIT\x10\xa6\x01\x12!\n\x1cVMSTAT_THP_MIGRATION_SUCCESS\x10\xa7\x01\x12$\n\x1fVMSTAT_THP_SCAN_EXCEED_NONE_PTE\x10\xa8\x01\x12%\n VMSTAT_THP_SCAN_EXCEED_SHARE_PTE\x10\xa9\x01\x12$\n\x1fVMSTAT_THP_SCAN_EXCEED_SWAP_PTE\x10\xaa\x01\x12\x1a\n\x15VMSTAT_THP_SPLIT_PAGE\x10\xab\x01\x12!\n\x1cVMSTAT_THP_SPLIT_PAGE_FAILED\x10\xac\x01\x12\x19\n\x14VMSTAT_THP_SPLIT_PMD\x10\xad\x01\x12\x16\n\x11VMSTAT_THP_SWPOUT\x10\xae\x01\x12\x1f\n\x1aVMSTAT_THP_SWPOUT_FALLBACK\x10\xaf\x01\x12\x1f\n\x1aVMSTAT_THP_ZERO_PAGE_ALLOC\x10\xb0\x01\x12&\n!VMSTAT_THP_ZERO_PAGE_ALLOC_FAILED\x10\xb1\x01\x12\x1a\n\x15VMSTAT_VMA_LOCK_ABORT\x10\xb2\x01\x12\x19\n\x14VMSTAT_VMA_LOCK_MISS\x10\xb3\x01\x12\x1a\n\x15VMSTAT_VMA_LOCK_RETRY\x10\xb4\x01\x12\x1c\n\x17VMSTAT_VMA_LOCK_SUCCESS\x10\xb5\x01\x12$\n\x1fVMSTAT_WORKINGSET_ACTIVATE_ANON\x10\xb6\x01\x12$\n\x1fVMSTAT_WORKINGSET_ACTIVATE_FILE\x10\xb7\x01\x12\x1c\n\x17VMSTAT_WORKINGSET_NODES\x10\xb8\x01\x12#\n\x1eVMSTAT_WORKINGSET_REFAULT_ANON\x10\xb9\x01\x12#\n\x1eVMSTAT_WORKINGSET_REFAULT_FILE\x10\xba\x01\x12#\n\x1eVMSTAT_WORKINGSET_RESTORE_ANON\x10\xbb\x01\x12#\n\x1eVMSTAT_WORKINGSET_RESTORE_FILE\x10\xbc\x01*\xc8\x05\n\x11\x46traceParseStatus\x12\x1d\n\x19\x46TRACE_STATUS_UNSPECIFIED\x10\x00\x12\x14\n\x10\x46TRACE_STATUS_OK\x10\x01\x12\'\n#FTRACE_STATUS_UNEXPECTED_READ_ERROR\x10\x02\x12#\n\x1f\x46TRACE_STATUS_PARTIAL_PAGE_READ\x10\x03\x12)\n%FTRACE_STATUS_ABI_INVALID_PAGE_HEADER\x10\x04\x12(\n$FTRACE_STATUS_ABI_SHORT_EVENT_HEADER\x10\x05\x12\"\n\x1e\x46TRACE_STATUS_ABI_NULL_PADDING\x10\x06\x12*\n&FTRACE_STATUS_ABI_SHORT_PADDING_LENGTH\x10\x07\x12,\n(FTRACE_STATUS_ABI_INVALID_PADDING_LENGTH\x10\x08\x12\'\n#FTRACE_STATUS_ABI_SHORT_TIME_EXTEND\x10\t\x12&\n\"FTRACE_STATUS_ABI_SHORT_TIME_STAMP\x10\n\x12\'\n#FTRACE_STATUS_ABI_SHORT_DATA_LENGTH\x10\x0b\x12&\n\"FTRACE_STATUS_ABI_ZERO_DATA_LENGTH\x10\x0c\x12)\n%FTRACE_STATUS_ABI_INVALID_DATA_LENGTH\x10\r\x12$\n FTRACE_STATUS_ABI_SHORT_EVENT_ID\x10\x0e\x12\"\n\x1e\x46TRACE_STATUS_ABI_END_OVERFLOW\x10\x0f\x12%\n!FTRACE_STATUS_SHORT_COMPACT_EVENT\x10\x10\x12\x1f\n\x1b\x46TRACE_STATUS_INVALID_EVENT\x10\x11*\x91\x01\n\x0b\x46traceClock\x12\x1c\n\x18\x46TRACE_CLOCK_UNSPECIFIED\x10\x00\x12\x18\n\x14\x46TRACE_CLOCK_UNKNOWN\x10\x01\x12\x17\n\x13\x46TRACE_CLOCK_GLOBAL\x10\x02\x12\x16\n\x12\x46TRACE_CLOCK_LOCAL\x10\x03\x12\x19\n\x15\x46TRACE_CLOCK_MONO_RAW\x10\x04*\xb0\x05\n\x1f\x43hromeCompositorSchedulerAction\x12#\n\x1f\x43\x43_SCHEDULER_ACTION_UNSPECIFIED\x10\x00\x12\x1c\n\x18\x43\x43_SCHEDULER_ACTION_NONE\x10\x01\x12-\n)CC_SCHEDULER_ACTION_SEND_BEGIN_MAIN_FRAME\x10\x02\x12\x1e\n\x1a\x43\x43_SCHEDULER_ACTION_COMMIT\x10\x03\x12*\n&CC_SCHEDULER_ACTION_ACTIVATE_SYNC_TREE\x10\x04\x12(\n$CC_SCHEDULER_ACTION_DRAW_IF_POSSIBLE\x10\x05\x12#\n\x1f\x43\x43_SCHEDULER_ACTION_DRAW_FORCED\x10\x06\x12\"\n\x1e\x43\x43_SCHEDULER_ACTION_DRAW_ABORT\x10\x07\x12<\n8CC_SCHEDULER_ACTION_BEGIN_LAYER_TREE_FRAME_SINK_CREATION\x10\x08\x12%\n!CC_SCHEDULER_ACTION_PREPARE_TILES\x10\t\x12\x38\n4CC_SCHEDULER_ACTION_INVALIDATE_LAYER_TREE_FRAME_SINK\x10\n\x12\x36\n2CC_SCHEDULER_ACTION_PERFORM_IMPL_SIDE_INVALIDATION\x10\x0b\x12\x42\n>CC_SCHEDULER_ACTION_NOTIFY_BEGIN_MAIN_FRAME_NOT_EXPECTED_UNTIL\x10\x0c\x12\x41\n=CC_SCHEDULER_ACTION_NOTIFY_BEGIN_MAIN_FRAME_NOT_EXPECTED_SOON\x10\r*}\n\x0e\x43hromeRAILMode\x12\x12\n\x0eRAIL_MODE_NONE\x10\x00\x12\x16\n\x12RAIL_MODE_RESPONSE\x10\x01\x12\x17\n\x13RAIL_MODE_ANIMATION\x10\x02\x12\x12\n\x0eRAIL_MODE_IDLE\x10\x03\x12\x12\n\x0eRAIL_MODE_LOAD\x10\x04\x42+Z)github.com/google/perfetto/perfetto_proto')
+DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n*protos/perfetto/trace/perfetto_trace.proto\x12\x0fperfetto.protos\"\x94\x01\n\x10\x46traceDescriptor\x12K\n\x11\x61trace_categories\x18\x01 \x03(\x0b\x32\x30.perfetto.protos.FtraceDescriptor.AtraceCategory\x1a\x33\n\x0e\x41traceCategory\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x13\n\x0b\x64\x65scription\x18\x02 \x01(\t\"\x9f\x0f\n\x14GpuCounterDescriptor\x12\x43\n\x05specs\x18\x01 \x03(\x0b\x32\x34.perfetto.protos.GpuCounterDescriptor.GpuCounterSpec\x12\x45\n\x06\x62locks\x18\x02 \x03(\x0b\x32\x35.perfetto.protos.GpuCounterDescriptor.GpuCounterBlock\x12Q\n\x0e\x63ounter_groups\x18\x06 \x03(\x0b\x32\x39.perfetto.protos.GpuCounterDescriptor.GpuCounterGroupSpec\x12\x1e\n\x16min_sampling_period_ns\x18\x03 \x01(\x04\x12\x1e\n\x16max_sampling_period_ns\x18\x04 \x01(\x04\x12&\n\x1esupports_instrumented_sampling\x18\x05 \x01(\x08\x12\x1e\n\x16supports_counter_names\x18\x07 \x01(\x08\x12#\n\x1bsupports_counter_name_globs\x18\x08 \x01(\x08\x1a\xec\x04\n\x0eGpuCounterSpec\x12\x12\n\ncounter_id\x18\x01 \x01(\r\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x13\n\x0b\x64\x65scription\x18\x03 \x01(\t\x12\x18\n\x0eint_peak_value\x18\x05 \x01(\x03H\x00\x12\x1b\n\x11\x64ouble_peak_value\x18\x06 \x01(\x01H\x00\x12J\n\x0fnumerator_units\x18\x07 \x03(\x0e\x32\x31.perfetto.protos.GpuCounterDescriptor.MeasureUnit\x12L\n\x11\x64\x65nominator_units\x18\x08 \x03(\x0e\x32\x31.perfetto.protos.GpuCounterDescriptor.MeasureUnit\x12\x19\n\x11select_by_default\x18\t \x01(\x08\x12\x45\n\x06groups\x18\n \x03(\x0e\x32\x35.perfetto.protos.GpuCounterDescriptor.GpuCounterGroup\x12\\\n\x0fvalue_direction\x18\x0b \x01(\x0e\x32\x43.perfetto.protos.GpuCounterDescriptor.GpuCounterSpec.ValueDirection\"~\n\x0eValueDirection\x12\x1f\n\x1bVALUE_DIRECTION_UNSPECIFIED\x10\x00\x12%\n!VALUE_DIRECTION_BACKWARDS_LOOKING\x10\x01\x12$\n VALUE_DIRECTION_FORWARDS_LOOKING\x10\x02\x42\x0c\n\npeak_valueJ\x04\x08\x04\x10\x05\x1as\n\x0fGpuCounterBlock\x12\x10\n\x08\x62lock_id\x18\x01 \x01(\r\x12\x16\n\x0e\x62lock_capacity\x18\x02 \x01(\r\x12\x0c\n\x04name\x18\x03 \x01(\t\x12\x13\n\x0b\x64\x65scription\x18\x04 \x01(\t\x12\x13\n\x0b\x63ounter_ids\x18\x05 \x03(\r\x1a_\n\x13GpuCounterGroupSpec\x12\x10\n\x08group_id\x18\x01 \x01(\r\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x13\n\x0b\x64\x65scription\x18\x03 \x01(\t\x12\x13\n\x0b\x63ounter_ids\x18\x04 \x03(\r\"\x86\x01\n\x0fGpuCounterGroup\x12\x10\n\x0cUNCLASSIFIED\x10\x00\x12\n\n\x06SYSTEM\x10\x01\x12\x0c\n\x08VERTICES\x10\x02\x12\r\n\tFRAGMENTS\x10\x03\x12\x0e\n\nPRIMITIVES\x10\x04\x12\n\n\x06MEMORY\x10\x05\x12\x0b\n\x07\x43OMPUTE\x10\x06\x12\x0f\n\x0bRAY_TRACING\x10\x07\"\xac\x04\n\x0bMeasureUnit\x12\x08\n\x04NONE\x10\x00\x12\x07\n\x03\x42IT\x10\x01\x12\x0b\n\x07KILOBIT\x10\x02\x12\x0b\n\x07MEGABIT\x10\x03\x12\x0b\n\x07GIGABIT\x10\x04\x12\x0b\n\x07TERABIT\x10\x05\x12\x0b\n\x07PETABIT\x10\x06\x12\x08\n\x04\x42YTE\x10\x07\x12\x0c\n\x08KILOBYTE\x10\x08\x12\x0c\n\x08MEGABYTE\x10\t\x12\x0c\n\x08GIGABYTE\x10\n\x12\x0c\n\x08TERABYTE\x10\x0b\x12\x0c\n\x08PETABYTE\x10\x0c\x12\t\n\x05HERTZ\x10\r\x12\r\n\tKILOHERTZ\x10\x0e\x12\r\n\tMEGAHERTZ\x10\x0f\x12\r\n\tGIGAHERTZ\x10\x10\x12\r\n\tTERAHERTZ\x10\x11\x12\r\n\tPETAHERTZ\x10\x12\x12\x0e\n\nNANOSECOND\x10\x13\x12\x0f\n\x0bMICROSECOND\x10\x14\x12\x0f\n\x0bMILLISECOND\x10\x15\x12\n\n\x06SECOND\x10\x16\x12\n\n\x06MINUTE\x10\x17\x12\x08\n\x04HOUR\x10\x18\x12\n\n\x06VERTEX\x10\x19\x12\t\n\x05PIXEL\x10\x1a\x12\x0c\n\x08TRIANGLE\x10\x1b\x12\r\n\tPRIMITIVE\x10&\x12\x0c\n\x08\x46RAGMENT\x10\'\x12\r\n\tMILLIWATT\x10\x1c\x12\x08\n\x04WATT\x10\x1d\x12\x0c\n\x08KILOWATT\x10\x1e\x12\t\n\x05JOULE\x10\x1f\x12\x08\n\x04VOLT\x10 \x12\n\n\x06\x41MPERE\x10!\x12\x0b\n\x07\x43\x45LSIUS\x10\"\x12\x0e\n\nFAHRENHEIT\x10#\x12\n\n\x06KELVIN\x10$\x12\x0b\n\x07PERCENT\x10%\x12\x0f\n\x0bINSTRUCTION\x10(\"E\n\x12TrackEventCategory\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x13\n\x0b\x64\x65scription\x18\x02 \x01(\t\x12\x0c\n\x04tags\x18\x03 \x03(\t\"Y\n\x14TrackEventDescriptor\x12\x41\n\x14\x61vailable_categories\x18\x01 \x03(\x0b\x32#.perfetto.protos.TrackEventCategory\"R\n\tVmProgram\x12\x0f\n\x07version\x18\x01 \x01(\r\x12\x34\n\x0cinstructions\x18\x02 \x03(\x0b\x32\x1e.perfetto.protos.VmInstruction\"\xde\x03\n\rVmInstruction\x12-\n\x06select\x18\x01 \x01(\x0b\x32\x1b.perfetto.protos.VmOpSelectH\x00\x12\x30\n\x08reg_load\x18\x02 \x01(\x0b\x32\x1c.perfetto.protos.VmOpRegLoadH\x00\x12+\n\x05merge\x18\x03 \x01(\x0b\x32\x1a.perfetto.protos.VmOpMergeH\x00\x12\'\n\x03set\x18\x04 \x01(\x0b\x32\x18.perfetto.protos.VmOpSetH\x00\x12\'\n\x03\x64\x65l\x18\x05 \x01(\x0b\x32\x18.perfetto.protos.VmOpDelH\x00\x12>\n\x0b\x61\x62ort_level\x18\x06 \x01(\x0e\x32).perfetto.protos.VmInstruction.AbortLevel\x12;\n\x13nested_instructions\x18\x07 \x03(\x0b\x32\x1e.perfetto.protos.VmInstruction\"c\n\nAbortLevel\x12\x1c\n\x18SKIP_CURRENT_INSTRUCTION\x10\x01\x12,\n(SKIP_CURRENT_INSTRUCTION_AND_BREAK_OUTER\x10\x02\x12\t\n\x05\x41\x42ORT\x10\x03\x42\x0b\n\toperation\"\xd7\x02\n\nVmOpSelect\x12-\n\x06\x63ursor\x18\x01 \x01(\x0e\x32\x1d.perfetto.protos.VmCursorEnum\x12@\n\rrelative_path\x18\x02 \x03(\x0b\x32).perfetto.protos.VmOpSelect.PathComponent\x12\x1b\n\x13\x63reate_if_not_exist\x18\x03 \x01(\x08\x1a\xba\x01\n\rPathComponent\x12\x12\n\x08\x66ield_id\x18\x01 \x01(\rH\x00\x12\x15\n\x0b\x61rray_index\x18\x02 \x01(\rH\x00\x12\x1a\n\x10map_key_field_id\x18\x03 \x01(\rH\x00\x12\x13\n\x0bis_repeated\x18\x05 \x01(\x08\x12\x19\n\x11register_to_match\x18\x06 \x01(\r\x12)\n!store_foreach_index_into_register\x18\x07 \x01(\rB\x07\n\x05\x66ield\"R\n\x0bVmOpRegLoad\x12-\n\x06\x63ursor\x18\x01 \x01(\x0e\x32\x1d.perfetto.protos.VmCursorEnum\x12\x14\n\x0c\x64st_register\x18\x02 \x01(\r\"?\n\tVmOpMerge\x12\x18\n\x10skip_submessages\x18\x01 \x01(\x08\x12\x18\n\x10\x64\x65l_if_src_empty\x18\x02 \x01(\x08\"\t\n\x07VmOpSet\"\t\n\x07VmOpDel\"\xb7\x03\n\x14\x44\x61taSourceDescriptor\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\n\n\x02id\x18\x07 \x01(\x04\x12\x1b\n\x13will_notify_on_stop\x18\x02 \x01(\x08\x12\x1c\n\x14will_notify_on_start\x18\x03 \x01(\x08\x12\'\n\x1fhandles_incremental_state_clear\x18\x04 \x01(\x08\x12\x10\n\x08no_flush\x18\t \x01(\x08\x12\x37\n\x0fprotovm_program\x18\n \x01(\x0b\x32\x1a.perfetto.protos.VmProgramB\x02(\x01\x12I\n\x16gpu_counter_descriptor\x18\x05 \x01(\x0b\x32%.perfetto.protos.GpuCounterDescriptorB\x02(\x01\x12I\n\x16track_event_descriptor\x18\x06 \x01(\x0b\x32%.perfetto.protos.TrackEventDescriptorB\x02(\x01\x12@\n\x11\x66trace_descriptor\x18\x08 \x01(\x0b\x32!.perfetto.protos.FtraceDescriptorB\x02(\x01\"\xe2\x06\n\x13TracingServiceState\x12@\n\tproducers\x18\x01 \x03(\x0b\x32-.perfetto.protos.TracingServiceState.Producer\x12\x45\n\x0c\x64\x61ta_sources\x18\x02 \x03(\x0b\x32/.perfetto.protos.TracingServiceState.DataSource\x12M\n\x10tracing_sessions\x18\x06 \x03(\x0b\x32\x33.perfetto.protos.TracingServiceState.TracingSession\x12!\n\x19supports_tracing_sessions\x18\x07 \x01(\x08\x12\x14\n\x0cnum_sessions\x18\x03 \x01(\x05\x12\x1c\n\x14num_sessions_started\x18\x04 \x01(\x05\x12\x1f\n\x17tracing_service_version\x18\x05 \x01(\t\x1a\x8d\x01\n\x08Producer\x12\n\n\x02id\x18\x01 \x01(\x05\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x0b\n\x03pid\x18\x05 \x01(\x05\x12\x0b\n\x03uid\x18\x03 \x01(\x05\x12\x13\n\x0bsdk_version\x18\x04 \x01(\t\x12\x0e\n\x06\x66rozen\x18\x06 \x01(\x08\x12\x12\n\nmachine_id\x18\x07 \x01(\r\x12\x14\n\x0cmachine_name\x18\x08 \x01(\t\x1a_\n\nDataSource\x12<\n\rds_descriptor\x18\x01 \x01(\x0b\x32%.perfetto.protos.DataSourceDescriptor\x12\x13\n\x0bproducer_id\x18\x02 \x01(\x05\x1a\x89\x02\n\x0eTracingSession\x12\n\n\x02id\x18\x01 \x01(\x04\x12\x14\n\x0c\x63onsumer_uid\x18\x02 \x01(\x05\x12\r\n\x05state\x18\x03 \x01(\t\x12\x1b\n\x13unique_session_name\x18\x04 \x01(\t\x12\x16\n\x0e\x62uffer_size_kb\x18\x05 \x03(\r\x12\x13\n\x0b\x64uration_ms\x18\x06 \x01(\r\x12\x18\n\x10num_data_sources\x18\x07 \x01(\r\x12\x19\n\x11start_realtime_ns\x18\x08 \x01(\x03\x12\x17\n\x0f\x62ugreport_score\x18\t \x01(\x05\x12\x1a\n\x12\x62ugreport_filename\x18\n \x01(\t\x12\x12\n\nis_started\x18\x0b \x01(\x08\"\xa1\x01\n\x0fTraceAttributes\x12=\n\tattribute\x18\x01 \x03(\x0b\x32*.perfetto.protos.TraceAttributes.Attribute\x1aO\n\tAttribute\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\x14\n\nlong_value\x18\x02 \x01(\x03H\x00\x12\x16\n\x0cstring_value\x18\x03 \x01(\tH\x00\x42\x07\n\x05value\"&\n\x13\x41ndroidAflagsConfig\x12\x0f\n\x07poll_ms\x18\x01 \x01(\r\"@\n!AndroidGameInterventionListConfig\x12\x1b\n\x13package_name_filter\x18\x01 \x03(\t\"\xef\x04\n\x17\x41ndroidInputEventConfig\x12@\n\x04mode\x18\x01 \x01(\x0e\x32\x32.perfetto.protos.AndroidInputEventConfig.TraceMode\x12\x41\n\x05rules\x18\x02 \x03(\x0b\x32\x32.perfetto.protos.AndroidInputEventConfig.TraceRule\x12%\n\x1dtrace_dispatcher_input_events\x18\x03 \x01(\x08\x12(\n trace_dispatcher_window_dispatch\x18\x04 \x01(\x08\x12\x1a\n\x12trace_evdev_events\x18\x05 \x01(\x08\x1a\xc8\x01\n\tTraceRule\x12H\n\x0btrace_level\x18\x01 \x01(\x0e\x32\x33.perfetto.protos.AndroidInputEventConfig.TraceLevel\x12\x1a\n\x12match_all_packages\x18\x02 \x03(\t\x12\x1a\n\x12match_any_packages\x18\x03 \x03(\t\x12\x14\n\x0cmatch_secure\x18\x04 \x01(\x08\x12#\n\x1bmatch_ime_connection_active\x18\x05 \x01(\x08\"?\n\tTraceMode\x12\x18\n\x14TRACE_MODE_TRACE_ALL\x10\x00\x12\x18\n\x14TRACE_MODE_USE_RULES\x10\x01\"V\n\nTraceLevel\x12\x14\n\x10TRACE_LEVEL_NONE\x10\x00\x12\x18\n\x14TRACE_LEVEL_REDACTED\x10\x01\x12\x18\n\x14TRACE_LEVEL_COMPLETE\x10\x02\"\xb1\x01\n\x10\x41ndroidLogConfig\x12.\n\x07log_ids\x18\x01 \x03(\x0e\x32\x1d.perfetto.protos.AndroidLogId\x12\x35\n\x08min_prio\x18\x03 \x01(\x0e\x32#.perfetto.protos.AndroidLogPriority\x12\x13\n\x0b\x66ilter_tags\x18\x04 \x03(\t\x12\x1b\n\x13preserve_log_buffer\x18\x05 \x01(\x08J\x04\x08\x02\x10\x03\"+\n\x18\x41ndroidPolledStateConfig\x12\x0f\n\x07poll_ms\x18\x01 \x01(\r\":\n\x19\x41ndroidProcessStateConfig\x12\x1d\n\x15\x64ump_process_metadata\x18\x01 \x01(\x08\"\x8a\x01\n\x1c\x41ndroidSdkSyspropGuardConfig\x12(\n surfaceflinger_skia_track_events\x18\x01 \x01(\x08\x12\x1e\n\x16hwui_skia_track_events\x18\x02 \x01(\x08\x12 \n\x18hwui_package_name_filter\x18\x03 \x03(\t\"E\n\x1b\x41ndroidSystemPropertyConfig\x12\x0f\n\x07poll_ms\x18\x01 \x01(\r\x12\x15\n\rproperty_name\x18\x02 \x03(\t\"f\n\x12\x41ppWakelocksConfig\x12\x16\n\x0ewrite_delay_ms\x18\x01 \x01(\x05\x12 \n\x18\x66ilter_duration_below_ms\x18\x02 \x01(\x05\x12\x16\n\x0e\x64rop_owner_pid\x18\x03 \x01(\x08\"\"\n\x0f\x43puPerUidConfig\x12\x0f\n\x07poll_ms\x18\x01 \x01(\r\"\xf8\x01\n\x12\x44isplayVideoConfig\x12\r\n\x05scale\x18\x01 \x01(\x02\x12:\n\x06\x66ormat\x18\x02 \x01(\x0e\x32*.perfetto.protos.DisplayVideoConfig.Format\x12\x1f\n\x17key_frame_interval_secs\x18\x03 \x01(\r\x12\x1d\n\x15max_stream_size_bytes\x18\x04 \x01(\x04\x12\x13\n\x0b\x62itrate_bps\x18\x05 \x01(\r\"B\n\x06\x46ormat\x12\x16\n\x12\x46ORMAT_UNSPECIFIED\x10\x00\x12\x0f\n\x0b\x46ORMAT_H264\x10\x01\x12\x0f\n\x0b\x46ORMAT_HEVC\x10\x02\"M\n\x11InputMethodConfig\x12\x0e\n\x06\x63lient\x18\x01 \x01(\x08\x12\x0f\n\x07service\x18\x02 \x01(\x08\x12\x17\n\x0fmanager_service\x18\x03 \x01(\x08\"(\n\x15KernelWakelocksConfig\x12\x0f\n\x07poll_ms\x18\x01 \x01(\r\"\xab\x01\n\x18NetworkPacketTraceConfig\x12\x0f\n\x07poll_ms\x18\x01 \x01(\r\x12\x1d\n\x15\x61ggregation_threshold\x18\x02 \x01(\r\x12\x14\n\x0cintern_limit\x18\x03 \x01(\r\x12\x17\n\x0f\x64rop_local_port\x18\x04 \x01(\x08\x12\x18\n\x10\x64rop_remote_port\x18\x05 \x01(\x08\x12\x16\n\x0e\x64rop_tcp_flags\x18\x06 \x01(\x08\"|\n\x12PackagesListConfig\x12\x1b\n\x13package_name_filter\x18\x01 \x03(\t\x12!\n\x19package_name_regex_filter\x18\x03 \x03(\t\x12&\n\x1eonly_write_on_cpu_use_every_ms\x18\x02 \x01(\r\"\x84\x02\n\x10PixelModemConfig\x12\x41\n\x0b\x65vent_group\x18\x01 \x01(\x0e\x32,.perfetto.protos.PixelModemConfig.EventGroup\x12\x1f\n\x17pigweed_hash_allow_list\x18\x02 \x03(\x03\x12\x1e\n\x16pigweed_hash_deny_list\x18\x03 \x03(\x03\"l\n\nEventGroup\x12\x17\n\x13\x45VENT_GROUP_UNKNOWN\x10\x00\x12\x1d\n\x19\x45VENT_GROUP_LOW_BANDWIDTH\x10\x01\x12&\n\"EVENT_GROUP_HIGH_AND_LOW_BANDWIDTH\x10\x02\"\xf8\x01\n\x0eProtoLogConfig\x12\x37\n\x0fgroup_overrides\x18\x01 \x03(\x0b\x32\x1e.perfetto.protos.ProtoLogGroup\x12\x41\n\x0ctracing_mode\x18\x02 \x01(\x0e\x32+.perfetto.protos.ProtoLogConfig.TracingMode\x12>\n\x16\x64\x65\x66\x61ult_log_from_level\x18\x03 \x01(\x0e\x32\x1e.perfetto.protos.ProtoLogLevel\"*\n\x0bTracingMode\x12\x0b\n\x07\x44\x45\x46\x41ULT\x10\x00\x12\x0e\n\nENABLE_ALL\x10\x01\"q\n\rProtoLogGroup\x12\x12\n\ngroup_name\x18\x01 \x01(\t\x12\x30\n\x08log_from\x18\x02 \x01(\x0e\x32\x1e.perfetto.protos.ProtoLogLevel\x12\x1a\n\x12\x63ollect_stacktrace\x18\x03 \x01(\x08\"\x83\x04\n\x1aSurfaceFlingerLayersConfig\x12>\n\x04mode\x18\x01 \x01(\x0e\x32\x30.perfetto.protos.SurfaceFlingerLayersConfig.Mode\x12J\n\x0btrace_flags\x18\x02 \x03(\x0e\x32\x35.perfetto.protos.SurfaceFlingerLayersConfig.TraceFlag\"\x85\x01\n\x04Mode\x12\x14\n\x10MODE_UNSPECIFIED\x10\x00\x12\x0f\n\x0bMODE_ACTIVE\x10\x01\x12\x12\n\x0eMODE_GENERATED\x10\x02\x12\r\n\tMODE_DUMP\x10\x03\x12!\n\x1dMODE_GENERATED_BUGREPORT_ONLY\x10\x04\x12\x10\n\x0cMODE_PROTOVM\x10\x05\"\xd0\x01\n\tTraceFlag\x12\x1a\n\x16TRACE_FLAG_UNSPECIFIED\x10\x00\x12\x14\n\x10TRACE_FLAG_INPUT\x10\x02\x12\x1a\n\x16TRACE_FLAG_COMPOSITION\x10\x04\x12\x14\n\x10TRACE_FLAG_EXTRA\x10\x08\x12\x12\n\x0eTRACE_FLAG_HWC\x10\x10\x12\x16\n\x12TRACE_FLAG_BUFFERS\x10 \x12\x1f\n\x1bTRACE_FLAG_VIRTUAL_DISPLAYS\x10@\x12\x12\n\x0eTRACE_FLAG_ALL\x10\x0e\"\xac\x01\n SurfaceFlingerTransactionsConfig\x12\x44\n\x04mode\x18\x01 \x01(\x0e\x32\x36.perfetto.protos.SurfaceFlingerTransactionsConfig.Mode\"B\n\x04Mode\x12\x14\n\x10MODE_UNSPECIFIED\x10\x00\x12\x13\n\x0fMODE_CONTINUOUS\x10\x01\x12\x0f\n\x0bMODE_ACTIVE\x10\x02\"1\n\x15\x41ndroidUserListConfig\x12\x18\n\x10user_type_filter\x18\x01 \x03(\t\"\xab\x04\n\x13WindowManagerConfig\x12H\n\rlog_frequency\x18\x01 \x01(\x0e\x32\x31.perfetto.protos.WindowManagerConfig.LogFrequency\x12@\n\tlog_level\x18\x02 \x01(\x0e\x32-.perfetto.protos.WindowManagerConfig.LogLevel\x12>\n\x08log_mode\x18\x03 \x01(\x0e\x32,.perfetto.protos.WindowManagerConfig.LogMode\"\x84\x01\n\x0cLogFrequency\x12\x1d\n\x19LOG_FREQUENCY_UNSPECIFIED\x10\x00\x12\x17\n\x13LOG_FREQUENCY_FRAME\x10\x01\x12\x1d\n\x19LOG_FREQUENCY_TRANSACTION\x10\x02\x12\x1d\n\x19LOG_FREQUENCY_SINGLE_DUMP\x10\x03\"i\n\x08LogLevel\x12\x19\n\x15LOG_LEVEL_UNSPECIFIED\x10\x00\x12\x15\n\x11LOG_LEVEL_VERBOSE\x10\x01\x12\x13\n\x0fLOG_LEVEL_DEBUG\x10\x02\x12\x16\n\x12LOG_LEVEL_CRITICAL\x10\x03\"V\n\x07LogMode\x12\x18\n\x14LOG_MODE_UNSPECIFIED\x10\x00\x12\x17\n\x13LOG_MODE_FULL_STATE\x10\x01\x12\x18\n\x14LOG_MODE_INCREMENTAL\x10\x02\"\xbd\x02\n\x0c\x43hromeConfig\x12\x14\n\x0ctrace_config\x18\x01 \x01(\t\x12!\n\x19privacy_filtering_enabled\x18\x02 \x01(\x08\x12\x1e\n\x16\x63onvert_to_legacy_json\x18\x03 \x01(\x08\x12\x45\n\x0f\x63lient_priority\x18\x04 \x01(\x0e\x32,.perfetto.protos.ChromeConfig.ClientPriority\x12\x1f\n\x17json_agent_label_filter\x18\x05 \x01(\t\x12)\n!event_package_name_filter_enabled\x18\x06 \x01(\x08\"A\n\x0e\x43lientPriority\x12\x0b\n\x07UNKNOWN\x10\x00\x12\x0e\n\nBACKGROUND\x10\x01\x12\x12\n\x0eUSER_INITIATED\x10\x02\"\xe6\x01\n\x1e\x43hromiumHistogramSamplesConfig\x12S\n\nhistograms\x18\x01 \x03(\x0b\x32?.perfetto.protos.ChromiumHistogramSamplesConfig.HistogramSample\x12\x1e\n\x16\x66ilter_histogram_names\x18\x02 \x01(\x08\x1aO\n\x0fHistogramSample\x12\x16\n\x0ehistogram_name\x18\x01 \x01(\t\x12\x11\n\tmin_value\x18\x02 \x01(\x03\x12\x11\n\tmax_value\x18\x03 \x01(\x03\"c\n\"ChromiumSamplingHeapProfilerConfig\x12\x1f\n\x17sampling_interval_bytes\x18\x01 \x01(\x04\x12\x1c\n\x14sampling_interval_ms\x18\x02 \x01(\r\"C\n#ChromiumStackSamplingProfilerConfig\x12\x1c\n\x14sampling_interval_ms\x18\x01 \x01(\r\";\n\x1b\x43hromiumSystemMetricsConfig\x12\x1c\n\x14sampling_interval_ms\x18\x01 \x01(\r\"@\n\x08V8Config\x12\x1a\n\x12log_script_sources\x18\x01 \x01(\x08\x12\x18\n\x10log_instructions\x18\x02 \x01(\x08\"\xb1\x03\n\tEtwConfig\x12?\n\x0ckernel_flags\x18\x01 \x03(\x0e\x32%.perfetto.protos.EtwConfig.KernelFlagB\x02\x18\x01\x12!\n\x19scheduler_provider_events\x18\x02 \x03(\t\x12\x1e\n\x16memory_provider_events\x18\x03 \x03(\t\x12 \n\x14\x66ile_provider_events\x18\x04 \x03(\tB\x02\x18\x01\x12\x1d\n\x15stack_sampling_events\x18\x05 \x03(\t\x12 \n\x14\x64isk_provider_events\x18\x06 \x03(\tB\x02\x18\x01\x12!\n\x19system_io_provider_events\x18\x07 \x03(\t\x12\x44\n\x18stack_sampling_debug_ids\x18\x08 \x03(\x0b\x32\".perfetto.protos.EtwConfig.DebugId\x1a)\n\x07\x44\x65\x62ugId\x12\x0c\n\x04path\x18\x01 \x01(\t\x12\x10\n\x08\x64\x65\x62ug_id\x18\x02 \x01(\t\")\n\nKernelFlag\x12\x0b\n\x07\x43SWITCH\x10\x00\x12\x0e\n\nDISPATCHER\x10\x01\"+\n\x12\x46rozenFtraceConfig\x12\x15\n\rinstance_name\x18\x01 \x01(\t\"\xca\x0e\n\x0c\x46traceConfig\x12\x15\n\rftrace_events\x18\x01 \x03(\t\x12\x19\n\x11\x61trace_categories\x18\x02 \x03(\t\x12\x13\n\x0b\x61trace_apps\x18\x03 \x03(\t\x12$\n\x1c\x61trace_categories_prefer_sdk\x18\x1c \x03(\t\x12\x1d\n\x15\x61trace_userspace_only\x18\" \x01(\x08\x12\x16\n\x0e\x62uffer_size_kb\x18\n \x01(\r\x12\x1f\n\x17\x62uffer_size_lower_bound\x18\x1b \x01(\x08\x12\x17\n\x0f\x64rain_period_ms\x18\x0b \x01(\r\x12\x1c\n\x14\x64rain_buffer_percent\x18\x1d \x01(\r\x12G\n\rcompact_sched\x18\x0c \x01(\x0b\x32\x30.perfetto.protos.FtraceConfig.CompactSchedConfig\x12?\n\x0cprint_filter\x18\x16 \x01(\x0b\x32).perfetto.protos.FtraceConfig.PrintFilter\x12\x17\n\x0fsymbolize_ksyms\x18\r \x01(\x08\x12\x46\n\x10ksyms_mem_policy\x18\x11 \x01(\x0e\x32,.perfetto.protos.FtraceConfig.KsymsMemPolicy\x12\x19\n\x11throttle_rss_stat\x18\x0f \x01(\x08\x12%\n\x1d\x64\x65nser_generic_event_encoding\x18  \x01(\x08\x12\x1e\n\x16\x64isable_generic_events\x18\x10 \x01(\x08\x12\x16\n\x0esyscall_events\x18\x12 \x03(\t\x12\x1d\n\x15\x65nable_function_graph\x18\x13 \x01(\x08\x12\x18\n\x10\x66unction_filters\x18\x14 \x03(\t\x12\x1c\n\x14\x66unction_graph_roots\x18\x15 \x03(\t\x12 \n\x18\x66unction_graph_max_depth\x18! \x01(\r\x12@\n\rkprobe_events\x18\x1e \x03(\x0b\x32).perfetto.protos.FtraceConfig.KprobeEvent\x12\x1e\n\x16preserve_ftrace_buffer\x18\x17 \x01(\x08\x12\x1f\n\x17use_monotonic_raw_clock\x18\x18 \x01(\x08\x12\x15\n\rinstance_name\x18\x19 \x01(\t\x12\x18\n\x10\x64\x65\x62ug_ftrace_abi\x18\x1f \x01(\x08\x12\x15\n\rtids_to_trace\x18# \x03(\r\x12\x44\n\x0ftracefs_options\x18$ \x03(\x0b\x32+.perfetto.protos.FtraceConfig.TracefsOption\x12\x17\n\x0ftracing_cpumask\x18% \x01(\t\x12\x36\n*initialize_ksyms_synchronously_for_testing\x18\x0e \x01(\x08\x42\x02\x18\x01\x1a%\n\x12\x43ompactSchedConfig\x12\x0f\n\x07\x65nabled\x18\x01 \x01(\x08\x1a\x82\x02\n\x0bPrintFilter\x12=\n\x05rules\x18\x01 \x03(\x0b\x32..perfetto.protos.FtraceConfig.PrintFilter.Rule\x1a\xb3\x01\n\x04Rule\x12\x10\n\x06prefix\x18\x01 \x01(\tH\x00\x12R\n\natrace_msg\x18\x03 \x01(\x0b\x32<.perfetto.protos.FtraceConfig.PrintFilter.Rule.AtraceMessageH\x00\x12\r\n\x05\x61llow\x18\x02 \x01(\x08\x1a-\n\rAtraceMessage\x12\x0c\n\x04type\x18\x01 \x01(\t\x12\x0e\n\x06prefix\x18\x02 \x01(\tB\x07\n\x05match\x1a\xd0\x01\n\x0bKprobeEvent\x12\r\n\x05probe\x18\x01 \x01(\t\x12\x42\n\x04type\x18\x02 \x01(\x0e\x32\x34.perfetto.protos.FtraceConfig.KprobeEvent.KprobeType\"n\n\nKprobeType\x12\x17\n\x13KPROBE_TYPE_UNKNOWN\x10\x00\x12\x16\n\x12KPROBE_TYPE_KPROBE\x10\x01\x12\x19\n\x15KPROBE_TYPE_KRETPROBE\x10\x02\x12\x14\n\x10KPROBE_TYPE_BOTH\x10\x03\x1a\xa2\x01\n\rTracefsOption\x12\x0c\n\x04name\x18\x01 \x01(\t\x12@\n\x05state\x18\x02 \x01(\x0e\x32\x31.perfetto.protos.FtraceConfig.TracefsOption.State\"A\n\x05State\x12\x11\n\rSTATE_UNKNOWN\x10\x00\x12\x11\n\rSTATE_ENABLED\x10\x01\x12\x12\n\x0eSTATE_DISABLED\x10\x02\"T\n\x0eKsymsMemPolicy\x12\x15\n\x11KSYMS_UNSPECIFIED\x10\x00\x12\x19\n\x15KSYMS_CLEANUP_ON_STOP\x10\x01\x12\x10\n\x0cKSYMS_RETAIN\x10\x02J\x04\x08\x1a\x10\x1b\"\xe7\x06\n\x10GpuCounterConfig\x12\x19\n\x11\x63ounter_period_ns\x18\x01 \x01(\x04\x12\x13\n\x0b\x63ounter_ids\x18\x02 \x03(\r\x12\x15\n\rcounter_names\x18\x06 \x03(\t\x12\x1f\n\x15instrumented_sampling\x18\x03 \x01(\x08H\x00\x12\x64\n\x1cinstrumented_sampling_config\x18\x05 \x01(\x0b\x32<.perfetto.protos.GpuCounterConfig.InstrumentedSamplingConfigH\x00\x12\x15\n\rfix_gpu_clock\x18\x04 \x01(\x08\x1a\xcf\x04\n\x1aInstrumentedSamplingConfig\x12n\n\x15\x61\x63tivity_name_filters\x18\x03 \x03(\x0b\x32O.perfetto.protos.GpuCounterConfig.InstrumentedSamplingConfig.ActivityNameFilter\x12!\n\x19\x61\x63tivity_tx_include_globs\x18\x06 \x03(\t\x12!\n\x19\x61\x63tivity_tx_exclude_globs\x18\x07 \x03(\t\x12\x63\n\x0f\x61\x63tivity_ranges\x18\x05 \x03(\x0b\x32J.perfetto.protos.GpuCounterConfig.InstrumentedSamplingConfig.ActivityRange\x1a\xe7\x01\n\x12\x41\x63tivityNameFilter\x12\x11\n\tname_glob\x18\x01 \x01(\t\x12k\n\tname_base\x18\x02 \x01(\x0e\x32X.perfetto.protos.GpuCounterConfig.InstrumentedSamplingConfig.ActivityNameFilter.NameBase\"Q\n\x08NameBase\x12\x17\n\x13MANGLED_KERNEL_NAME\x10\x00\x12\x19\n\x15\x44\x45MANGLED_KERNEL_NAME\x10\x01\x12\x11\n\rFUNCTION_NAME\x10\x02\x1a,\n\rActivityRange\x12\x0c\n\x04skip\x18\x01 \x01(\r\x12\r\n\x05\x63ount\x18\x02 \x01(\rB\x1c\n\x1ainstrumented_sampling_mode\"u\n\x15GpuRenderStagesConfig\x12\x16\n\x0e\x66ull_loadstore\x18\x01 \x01(\x08\x12\x14\n\x0clow_overhead\x18\x02 \x01(\x08\x12\x15\n\rtrace_metrics\x18\x03 \x03(\t\x12\x17\n\x0f\x64rawcall_stages\x18\x04 \x01(\x08\"Z\n\x12VulkanMemoryConfig\x12!\n\x19track_driver_memory_usage\x18\x01 \x01(\x08\x12!\n\x19track_device_memory_usage\x18\x02 \x01(\x08\"\xa3\x02\n\x0fInodeFileConfig\x12\x18\n\x10scan_interval_ms\x18\x01 \x01(\r\x12\x15\n\rscan_delay_ms\x18\x02 \x01(\r\x12\x17\n\x0fscan_batch_size\x18\x03 \x01(\r\x12\x13\n\x0b\x64o_not_scan\x18\x04 \x01(\x08\x12\x19\n\x11scan_mount_points\x18\x05 \x03(\t\x12T\n\x13mount_point_mapping\x18\x06 \x03(\x0b\x32\x37.perfetto.protos.InodeFileConfig.MountPointMappingEntry\x1a@\n\x16MountPointMappingEntry\x12\x12\n\nmountpoint\x18\x01 \x01(\t\x12\x12\n\nscan_roots\x18\x02 \x03(\t\"\xa5\x01\n\rConsoleConfig\x12\x35\n\x06output\x18\x01 \x01(\x0e\x32%.perfetto.protos.ConsoleConfig.Output\x12\x15\n\renable_colors\x18\x02 \x01(\x08\"F\n\x06Output\x12\x16\n\x12OUTPUT_UNSPECIFIED\x10\x00\x12\x11\n\rOUTPUT_STDOUT\x10\x01\x12\x11\n\rOUTPUT_STDERR\x10\x02\"Y\n\x11InterceptorConfig\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x36\n\x0e\x63onsole_config\x18\x64 \x01(\x0b\x32\x1e.perfetto.protos.ConsoleConfig\"[\n\x15SystemdJournaldConfig\x12\x10\n\x08min_prio\x18\x01 \x01(\r\x12\x1a\n\x12\x66ilter_identifiers\x18\x02 \x03(\t\x12\x14\n\x0c\x66ilter_units\x18\x03 \x03(\t\"\xc0\x03\n\x12\x41ndroidPowerConfig\x12\x17\n\x0f\x62\x61ttery_poll_ms\x18\x01 \x01(\r\x12M\n\x10\x62\x61ttery_counters\x18\x02 \x03(\x0e\x32\x33.perfetto.protos.AndroidPowerConfig.BatteryCounters\x12\x1b\n\x13\x63ollect_power_rails\x18\x03 \x01(\x08\x12+\n#collect_energy_estimation_breakdown\x18\x04 \x01(\x08\x12&\n\x1e\x63ollect_entity_state_residency\x18\x05 \x01(\x08\"\xcf\x01\n\x0f\x42\x61tteryCounters\x12\x1f\n\x1b\x42\x41TTERY_COUNTER_UNSPECIFIED\x10\x00\x12\x1a\n\x16\x42\x41TTERY_COUNTER_CHARGE\x10\x01\x12$\n BATTERY_COUNTER_CAPACITY_PERCENT\x10\x02\x12\x1b\n\x17\x42\x41TTERY_COUNTER_CURRENT\x10\x03\x12\x1f\n\x1b\x42\x41TTERY_COUNTER_CURRENT_AVG\x10\x04\x12\x1b\n\x17\x42\x41TTERY_COUNTER_VOLTAGE\x10\x05\"\xbf\x01\n\x13PriorityBoostConfig\x12@\n\x06policy\x18\x01 \x01(\x0e\x32\x30.perfetto.protos.PriorityBoostConfig.BoostPolicy\x12\x10\n\x08priority\x18\x02 \x01(\r\"T\n\x0b\x42oostPolicy\x12\x16\n\x12POLICY_UNSPECIFIED\x10\x00\x12\x16\n\x12POLICY_SCHED_OTHER\x10\x01\x12\x15\n\x11POLICY_SCHED_FIFO\x10\x02\"\xeb\x03\n\x12ProcessStatsConfig\x12:\n\x06quirks\x18\x01 \x03(\x0e\x32*.perfetto.protos.ProcessStatsConfig.Quirks\x12#\n\x1bscan_all_processes_on_start\x18\x02 \x01(\x08\x12\x1b\n\x13record_thread_names\x18\x03 \x01(\x08\x12\x1a\n\x12proc_stats_poll_ms\x18\x04 \x01(\r\x12\x1f\n\x17proc_stats_cache_ttl_ms\x18\x06 \x01(\r\x12\x19\n\x11scan_smaps_rollup\x18\n \x01(\x08\x12\x1a\n\x12record_process_age\x18\x0b \x01(\x08\x12\x1e\n\x16record_process_runtime\x18\x0c \x01(\x08\x12!\n\x19record_process_dmabuf_rss\x18\r \x01(\x08\x12\x1b\n\x13resolve_process_fds\x18\t \x01(\x08\x12 \n\x18skip_main_thread_message\x18\x0e \x01(\x08\"U\n\x06Quirks\x12\x16\n\x12QUIRKS_UNSPECIFIED\x10\x00\x12\x1c\n\x14\x44ISABLE_INITIAL_DUMP\x10\x01\x1a\x02\x08\x01\x12\x15\n\x11\x44ISABLE_ON_DEMAND\x10\x02J\x04\x08\x07\x10\x08J\x04\x08\x08\x10\t\"\xcc\x06\n\x0fHeapprofdConfig\x12\x1f\n\x17sampling_interval_bytes\x18\x01 \x01(\x04\x12)\n!adaptive_sampling_shmem_threshold\x18\x18 \x01(\x04\x12\x35\n-adaptive_sampling_max_sampling_interval_bytes\x18\x19 \x01(\x04\x12\x17\n\x0fprocess_cmdline\x18\x02 \x03(\t\x12\x0b\n\x03pid\x18\x04 \x03(\x04\x12\x1b\n\x13target_installed_by\x18\x1a \x03(\t\x12\r\n\x05heaps\x18\x14 \x03(\t\x12\x15\n\rexclude_heaps\x18\x1b \x03(\t\x12\x1a\n\x12stream_allocations\x18\x17 \x01(\x08\x12\x1f\n\x17heap_sampling_intervals\x18\x16 \x03(\x04\x12\x11\n\tall_heaps\x18\x15 \x01(\x08\x12\x0b\n\x03\x61ll\x18\x05 \x01(\x08\x12\x1f\n\x17min_anonymous_memory_kb\x18\x0f \x01(\r\x12\x1f\n\x17max_heapprofd_memory_kb\x18\x10 \x01(\r\x12\x1e\n\x16max_heapprofd_cpu_secs\x18\x11 \x01(\x04\x12\x1a\n\x12skip_symbol_prefix\x18\x07 \x03(\t\x12U\n\x16\x63ontinuous_dump_config\x18\x06 \x01(\x0b\x32\x35.perfetto.protos.HeapprofdConfig.ContinuousDumpConfig\x12\x18\n\x10shmem_size_bytes\x18\x08 \x01(\x04\x12\x14\n\x0c\x62lock_client\x18\t \x01(\x08\x12\x1f\n\x17\x62lock_client_timeout_us\x18\x0e \x01(\r\x12\x12\n\nno_startup\x18\n \x01(\x08\x12\x12\n\nno_running\x18\x0b \x01(\x08\x12\x13\n\x0b\x64ump_at_max\x18\r \x01(\x08\x12\x1d\n\x15\x64isable_fork_teardown\x18\x12 \x01(\x08\x12\x1f\n\x17\x64isable_vfork_detection\x18\x13 \x01(\x08\x1aG\n\x14\x43ontinuousDumpConfig\x12\x15\n\rdump_phase_ms\x18\x05 \x01(\r\x12\x18\n\x10\x64ump_interval_ms\x18\x06 \x01(\rJ\x04\x08\x0c\x10\r\"\xfb\x02\n\x12ProcessSmapsConfig\x12\x32\n\x0csmaps_config\x18\x01 \x01(\x0b\x32\x1c.perfetto.protos.SmapsConfig\x12\x38\n\x05scope\x18\x02 \x01(\x0b\x32).perfetto.protos.ProcessSmapsConfig.Scope\x12\x16\n\x0eread_period_ms\x18\x03 \x01(\r\x12 \n\x18max_processes_per_period\x18\x04 \x01(\r\x1a\xbc\x01\n\x05Scope\x12\x16\n\x0etarget_cmdline\x18\x01 \x03(\t\x12\x46\n\ntarget_uid\x18\x02 \x03(\x0b\x32\x32.perfetto.protos.ProcessSmapsConfig.Scope.UidRange\x1aS\n\x08UidRange\x12\x0f\n\x07min_uid\x18\x01 \x01(\r\x12\x0f\n\x07max_uid\x18\x02 \x01(\r\x12%\n\x1d\x61ndroid_match_across_profiles\x18\x03 \x01(\x08\"\xe0\x03\n\x0bSmapsConfig\x12\x39\n\nvma_fields\x18\x01 \x03(\x0e\x32%.perfetto.protos.SmapsConfig.VmaField\x12\x14\n\x0cunaggregated\x18\x02 \x01(\x08\x12<\n\x14name_redaction_rules\x18\x03 \x03(\x0b\x32\x1e.perfetto.protos.RedactionRule\"\xc1\x02\n\x08VmaField\x12\x15\n\x11VMA_FIELD_UNKNOWN\x10\x00\x12\x12\n\x0eVMA_FIELD_SIZE\x10\x01\x12\x11\n\rVMA_FIELD_RSS\x10\x02\x12\x17\n\x13VMA_FIELD_ANONYMOUS\x10\x03\x12\x12\n\x0eVMA_FIELD_SWAP\x10\x04\x12\x1a\n\x16VMA_FIELD_SHARED_CLEAN\x10\x05\x12\x1a\n\x16VMA_FIELD_SHARED_DIRTY\x10\x06\x12\x1b\n\x17VMA_FIELD_PRIVATE_CLEAN\x10\x07\x12\x1b\n\x17VMA_FIELD_PRIVATE_DIRTY\x10\x08\x12\x14\n\x10VMA_FIELD_LOCKED\x10\t\x12\x11\n\rVMA_FIELD_PSS\x10\n\x12\x17\n\x13VMA_FIELD_PSS_DIRTY\x10\x0b\x12\x16\n\x12VMA_FIELD_SWAP_PSS\x10\x0c\"\xb6\x02\n\rRedactionRule\x12\x0f\n\x07pattern\x18\x01 \x01(\t\x12<\n\nmatch_mode\x18\x02 \x01(\x0e\x32(.perfetto.protos.RedactionRule.MatchMode\x12\x11\n\tkeep_full\x18\x03 \x01(\x08\x12\x18\n\x10replacement_name\x18\x04 \x01(\t\x12\x1b\n\x13keep_file_extension\x18\x05 \x01(\x08\x12\x1a\n\x12keep_path_elements\x18\x06 \x01(\r\"p\n\tMatchMode\x12\x16\n\x12MATCH_MODE_UNKNOWN\x10\x00\x12\x15\n\x11MATCH_MODE_PREFIX\x10\x01\x12\x18\n\x14MATCH_MODE_GLOB_PATH\x10\x02\x12\x1a\n\x16MATCH_MODE_GLOB_STRING\x10\x03\"\xd1\x03\n\x0fJavaHprofConfig\x12\x17\n\x0fprocess_cmdline\x18\x01 \x03(\t\x12\x0b\n\x03pid\x18\x02 \x03(\x04\x12\x1b\n\x13target_installed_by\x18\x07 \x03(\t\x12U\n\x16\x63ontinuous_dump_config\x18\x03 \x01(\x0b\x32\x35.perfetto.protos.JavaHprofConfig.ContinuousDumpConfig\x12\x1f\n\x17min_anonymous_memory_kb\x18\x04 \x01(\r\x12\x1d\n\x15min_java_heap_size_kb\x18\t \x01(\r\x12\x12\n\ndump_smaps\x18\x05 \x01(\x08\x12\x32\n\x0csmaps_config\x18\x08 \x01(\x0b\x32\x1c.perfetto.protos.SmapsConfig\x12\x15\n\rignored_types\x18\x06 \x03(\t\x12\x1b\n\x13\x64ump_oome_callstack\x18\n \x01(\x08\x1ah\n\x14\x43ontinuousDumpConfig\x12\x15\n\rdump_phase_ms\x18\x01 \x01(\r\x12\x18\n\x10\x64ump_interval_ms\x18\x02 \x01(\r\x12\x1f\n\x17scan_pids_only_on_start\x18\x03 \x01(\x08\"\xc9\n\n\nPerfEvents\x1a\x9d\x03\n\x08Timebase\x12\x13\n\tfrequency\x18\x02 \x01(\x04H\x00\x12\x10\n\x06period\x18\x01 \x01(\x04H\x00\x12\x18\n\x0epoll_period_ms\x18\x06 \x01(\rH\x00\x12\x36\n\x07\x63ounter\x18\x04 \x01(\x0e\x32#.perfetto.protos.PerfEvents.CounterH\x01\x12<\n\ntracepoint\x18\x03 \x01(\x0b\x32&.perfetto.protos.PerfEvents.TracepointH\x01\x12\x39\n\traw_event\x18\x05 \x01(\x0b\x32$.perfetto.protos.PerfEvents.RawEventH\x01\x12<\n\tmodifiers\x18\x0c \x03(\x0e\x32).perfetto.protos.PerfEvents.EventModifier\x12>\n\x0ftimestamp_clock\x18\x0b \x01(\x0e\x32%.perfetto.protos.PerfEvents.PerfClock\x12\x0c\n\x04name\x18\n \x01(\tB\n\n\x08intervalB\x07\n\x05\x65vent\x1a*\n\nTracepoint\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0e\n\x06\x66ilter\x18\x02 \x01(\t\x1a\\\n\x08RawEvent\x12\x0c\n\x04type\x18\x01 \x01(\r\x12\x0e\n\x06\x63onfig\x18\x02 \x01(\x04\x12\x0f\n\x07\x63onfig1\x18\x03 \x01(\x04\x12\x0f\n\x07\x63onfig2\x18\x04 \x01(\x04\x12\x10\n\x08pmu_name\x18\x05 \x01(\t\"\xe8\x03\n\x07\x43ounter\x12\x13\n\x0fUNKNOWN_COUNTER\x10\x00\x12\x10\n\x0cSW_CPU_CLOCK\x10\x01\x12\x12\n\x0eSW_PAGE_FAULTS\x10\x02\x12\x11\n\rSW_TASK_CLOCK\x10\x03\x12\x17\n\x13SW_CONTEXT_SWITCHES\x10\x04\x12\x15\n\x11SW_CPU_MIGRATIONS\x10\x05\x12\x16\n\x12SW_PAGE_FAULTS_MIN\x10\x06\x12\x16\n\x12SW_PAGE_FAULTS_MAJ\x10\x07\x12\x17\n\x13SW_ALIGNMENT_FAULTS\x10\x08\x12\x17\n\x13SW_EMULATION_FAULTS\x10\t\x12\x0c\n\x08SW_DUMMY\x10\x14\x12\x11\n\rHW_CPU_CYCLES\x10\n\x12\x13\n\x0fHW_INSTRUCTIONS\x10\x0b\x12\x17\n\x13HW_CACHE_REFERENCES\x10\x0c\x12\x13\n\x0fHW_CACHE_MISSES\x10\r\x12\x1a\n\x16HW_BRANCH_INSTRUCTIONS\x10\x0e\x12\x14\n\x10HW_BRANCH_MISSES\x10\x0f\x12\x11\n\rHW_BUS_CYCLES\x10\x10\x12\x1e\n\x1aHW_STALLED_CYCLES_FRONTEND\x10\x11\x12\x1d\n\x19HW_STALLED_CYCLES_BACKEND\x10\x12\x12\x15\n\x11HW_REF_CPU_CYCLES\x10\x13\"\x8d\x01\n\tPerfClock\x12\x16\n\x12UNKNOWN_PERF_CLOCK\x10\x00\x12\x17\n\x13PERF_CLOCK_REALTIME\x10\x01\x12\x18\n\x14PERF_CLOCK_MONOTONIC\x10\x02\x12\x1c\n\x18PERF_CLOCK_MONOTONIC_RAW\x10\x03\x12\x17\n\x13PERF_CLOCK_BOOTTIME\x10\x04\"\x95\x01\n\rEventModifier\x12\x1a\n\x16UNKNOWN_EVENT_MODIFIER\x10\x00\x12\"\n\x1e\x45VENT_MODIFIER_COUNT_USERSPACE\x10\x01\x12\x1f\n\x1b\x45VENT_MODIFIER_COUNT_KERNEL\x10\x02\x12#\n\x1f\x45VENT_MODIFIER_COUNT_HYPERVISOR\x10\x03\"\x95\x02\n\rFollowerEvent\x12\x36\n\x07\x63ounter\x18\x01 \x01(\x0e\x32#.perfetto.protos.PerfEvents.CounterH\x00\x12<\n\ntracepoint\x18\x02 \x01(\x0b\x32&.perfetto.protos.PerfEvents.TracepointH\x00\x12\x39\n\traw_event\x18\x03 \x01(\x0b\x32$.perfetto.protos.PerfEvents.RawEventH\x00\x12<\n\tmodifiers\x18\x05 \x03(\x0e\x32).perfetto.protos.PerfEvents.EventModifier\x12\x0c\n\x04name\x18\x04 \x01(\tB\x07\n\x05\x65vent\"\x85\t\n\x0fPerfEventConfig\x12\x36\n\x08timebase\x18\x0f \x01(\x0b\x32$.perfetto.protos.PerfEvents.Timebase\x12\x31\n\tfollowers\x18\x13 \x03(\x0b\x32\x1e.perfetto.protos.FollowerEvent\x12N\n\x12\x63\x61llstack_sampling\x18\x10 \x01(\x0b\x32\x32.perfetto.protos.PerfEventConfig.CallstackSampling\x12\x12\n\ntarget_cpu\x18\x14 \x03(\r\x12\x1b\n\x13ignore_open_failure\x18\x15 \x01(\x08\x12\r\n\x05\x63puid\x18\x16 \x03(\t\x12\"\n\x1aring_buffer_read_period_ms\x18\x08 \x01(\r\x12\x19\n\x11ring_buffer_pages\x18\x03 \x01(\r\x12!\n\x19max_enqueued_footprint_kb\x18\x11 \x01(\x04\x12\x1c\n\x14max_daemon_memory_kb\x18\r \x01(\r\x12$\n\x1cremote_descriptor_timeout_ms\x18\t \x01(\r\x12$\n\x1cunwind_state_clear_period_ms\x18\n \x01(\r\x12\x1b\n\x13target_installed_by\x18\x12 \x03(\t\x12\x10\n\x08\x61ll_cpus\x18\x01 \x01(\x08\x12\x1a\n\x12sampling_frequency\x18\x02 \x01(\r\x12\x15\n\rkernel_frames\x18\x0c \x01(\x08\x12\x12\n\ntarget_pid\x18\x04 \x03(\x05\x12\x16\n\x0etarget_cmdline\x18\x05 \x03(\t\x12\x13\n\x0b\x65xclude_pid\x18\x06 \x03(\x05\x12\x17\n\x0f\x65xclude_cmdline\x18\x07 \x03(\t\x12 \n\x18\x61\x64\x64itional_cmdline_count\x18\x0b \x01(\r\x1a\xa3\x01\n\x11\x43\x61llstackSampling\x12\x35\n\x05scope\x18\x01 \x01(\x0b\x32&.perfetto.protos.PerfEventConfig.Scope\x12\x15\n\rkernel_frames\x18\x02 \x01(\x08\x12@\n\x0buser_frames\x18\x03 \x01(\x0e\x32+.perfetto.protos.PerfEventConfig.UnwindMode\x1a\xa0\x01\n\x05Scope\x12\x12\n\ntarget_pid\x18\x01 \x03(\x05\x12\x16\n\x0etarget_cmdline\x18\x02 \x03(\t\x12\x13\n\x0b\x65xclude_pid\x18\x03 \x03(\x05\x12\x17\n\x0f\x65xclude_cmdline\x18\x04 \x03(\t\x12 \n\x18\x61\x64\x64itional_cmdline_count\x18\x05 \x01(\r\x12\x1b\n\x13process_shard_count\x18\x06 \x01(\r\"~\n\nUnwindMode\x12\x12\n\x0eUNWIND_UNKNOWN\x10\x00\x12\x0f\n\x0bUNWIND_SKIP\x10\x01\x12\x10\n\x0cUNWIND_DWARF\x10\x02\x12\x18\n\x14UNWIND_FRAME_POINTER\x10\x03\x12\x1f\n\x1bUNWIND_KERNEL_FRAME_POINTER\x10\x04J\x04\x08\x0e\x10\x0f\"(\n\rProtoVmConfig\x12\x17\n\x0fmemory_limit_kb\x18\x01 \x01(\r\"\xbf\x01\n\tQnxConfig\x12\x1a\n\x12qnx_kernel_buffers\x18\x01 \x01(\r\x12\x1b\n\x13qnx_kernel_kbuffers\x18\x02 \x01(\r\x12\x1e\n\x16qnx_kernel_wide_events\x18\x03 \x01(\x08\x12\x17\n\x0fqnx_cache_pages\x18\x04 \x01(\r\x12\x1b\n\x13qnx_cache_max_pages\x18\x05 \x01(\x05\x12#\n\x1bqnx_trace_buffer_init_bytes\x18\x06 \x01(\r\"\x9a\x01\n\x13StatsdTracingConfig\x12-\n\x0cpush_atom_id\x18\x01 \x03(\x0e\x32\x17.perfetto.protos.AtomId\x12\x18\n\x10raw_push_atom_id\x18\x02 \x03(\x05\x12:\n\x0bpull_config\x18\x03 \x03(\x0b\x32%.perfetto.protos.StatsdPullAtomConfig\"\x8c\x01\n\x14StatsdPullAtomConfig\x12-\n\x0cpull_atom_id\x18\x01 \x03(\x0e\x32\x17.perfetto.protos.AtomId\x12\x18\n\x10raw_pull_atom_id\x18\x02 \x03(\x05\x12\x19\n\x11pull_frequency_ms\x18\x03 \x01(\x05\x12\x10\n\x08packages\x18\x04 \x03(\t\"\x84\x05\n\x0eSysStatsConfig\x12\x19\n\x11meminfo_period_ms\x18\x01 \x01(\r\x12:\n\x10meminfo_counters\x18\x02 \x03(\x0e\x32 .perfetto.protos.MeminfoCounters\x12\x18\n\x10vmstat_period_ms\x18\x03 \x01(\r\x12\x38\n\x0fvmstat_counters\x18\x04 \x03(\x0e\x32\x1f.perfetto.protos.VmstatCounters\x12\x16\n\x0estat_period_ms\x18\x05 \x01(\r\x12\x43\n\rstat_counters\x18\x06 \x03(\x0e\x32,.perfetto.protos.SysStatsConfig.StatCounters\x12\x19\n\x11\x64\x65vfreq_period_ms\x18\x07 \x01(\r\x12\x19\n\x11\x63pufreq_period_ms\x18\x08 \x01(\r\x12\x1b\n\x13\x62uddyinfo_period_ms\x18\t \x01(\r\x12\x1a\n\x12\x64iskstat_period_ms\x18\n \x01(\r\x12\x15\n\rpsi_period_ms\x18\x0b \x01(\r\x12\x19\n\x11thermal_period_ms\x18\x0c \x01(\r\x12\x19\n\x11\x63puidle_period_ms\x18\r \x01(\r\x12\x19\n\x11gpufreq_period_ms\x18\x0e \x01(\r\x12\x16\n\x0eslab_period_ms\x18\x0f \x01(\r\"{\n\x0cStatCounters\x12\x14\n\x10STAT_UNSPECIFIED\x10\x00\x12\x12\n\x0eSTAT_CPU_TIMES\x10\x01\x12\x13\n\x0fSTAT_IRQ_COUNTS\x10\x02\x12\x17\n\x13STAT_SOFTIRQ_COUNTS\x10\x03\x12\x13\n\x0fSTAT_FORK_COUNT\x10\x04\"%\n\x10SystemInfoConfig\x12\x11\n\tirq_names\x18\x01 \x01(\x08\"\x8d\x04\n\nTestConfig\x12\x15\n\rmessage_count\x18\x01 \x01(\r\x12\x1f\n\x17max_messages_per_second\x18\x02 \x01(\r\x12\x0c\n\x04seed\x18\x03 \x01(\r\x12\x14\n\x0cmessage_size\x18\x04 \x01(\r\x12\x1e\n\x16send_batch_on_register\x18\x05 \x01(\x08\x12=\n\x0c\x64ummy_fields\x18\x06 \x01(\x0b\x32\'.perfetto.protos.TestConfig.DummyFields\x1a\xc3\x02\n\x0b\x44ummyFields\x12\x14\n\x0c\x66ield_uint32\x18\x01 \x01(\r\x12\x13\n\x0b\x66ield_int32\x18\x02 \x01(\x05\x12\x14\n\x0c\x66ield_uint64\x18\x03 \x01(\x04\x12\x13\n\x0b\x66ield_int64\x18\x04 \x01(\x03\x12\x15\n\rfield_fixed64\x18\x05 \x01(\x06\x12\x16\n\x0e\x66ield_sfixed64\x18\x06 \x01(\x10\x12\x15\n\rfield_fixed32\x18\x07 \x01(\x07\x12\x16\n\x0e\x66ield_sfixed32\x18\x08 \x01(\x0f\x12\x14\n\x0c\x66ield_double\x18\t \x01(\x01\x12\x13\n\x0b\x66ield_float\x18\n \x01(\x02\x12\x14\n\x0c\x66ield_sint64\x18\x0b \x01(\x12\x12\x14\n\x0c\x66ield_sint32\x18\x0c \x01(\x11\x12\x14\n\x0c\x66ield_string\x18\r \x01(\t\x12\x13\n\x0b\x66ield_bytes\x18\x0e \x01(\x0c\"\xd2\x02\n\x10TrackEventConfig\x12\x1b\n\x13\x64isabled_categories\x18\x01 \x03(\t\x12\x1a\n\x12\x65nabled_categories\x18\x02 \x03(\t\x12\x15\n\rdisabled_tags\x18\x03 \x03(\t\x12\x14\n\x0c\x65nabled_tags\x18\x04 \x03(\t\x12&\n\x1e\x64isable_incremental_timestamps\x18\x05 \x01(\x08\x12!\n\x19timestamp_unit_multiplier\x18\x06 \x01(\x04\x12 \n\x18\x66ilter_debug_annotations\x18\x07 \x01(\x08\x12#\n\x1b\x65nable_thread_time_sampling\x18\x08 \x01(\x08\x12\"\n\x1athread_time_subsampling_ns\x18\n \x01(\x04\x12\"\n\x1a\x66ilter_dynamic_event_names\x18\t \x01(\x08\"\xed$\n\x10\x44\x61taSourceConfig\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x15\n\rtarget_buffer\x18\x02 \x01(\r\x12\x1a\n\x12target_buffer_name\x18\x0b \x01(\t\x12\x19\n\x11trace_duration_ms\x18\x03 \x01(\r\x12)\n!prefer_suspend_clock_for_duration\x18z \x01(\x08\x12\x17\n\x0fstop_timeout_ms\x18\x07 \x01(\r\x12\x1f\n\x17\x65nable_extra_guardrails\x18\x06 \x01(\x08\x12M\n\x11session_initiator\x18\x08 \x01(\x0e\x32\x32.perfetto.protos.DataSourceConfig.SessionInitiator\x12\x1a\n\x12tracing_session_id\x18\x04 \x01(\x04\x12X\n\x17\x62uffer_exhausted_policy\x18\t \x01(\x0e\x32\x37.perfetto.protos.DataSourceConfig.BufferExhaustedPolicy\x12<\n\x0epriority_boost\x18\n \x01(\x0b\x32$.perfetto.protos.PriorityBoostConfig\x12\x36\n\x0eprotovm_config\x18\x0c \x01(\x0b\x32\x1e.perfetto.protos.ProtoVmConfig\x12\x1c\n\x13supports_tracing_v2\x18\x93\x01 \x01(\x08\x12_\n\x17\x65xperimental_tracing_v2\x18\x94\x01 \x01(\x0b\x32=.perfetto.protos.DataSourceConfig.ExperimentalTracingV2Config\x12\x38\n\rftrace_config\x18\x64 \x01(\x0b\x32\x1d.perfetto.protos.FtraceConfigB\x02(\x01\x12?\n\x11inode_file_config\x18\x66 \x01(\x0b\x32 .perfetto.protos.InodeFileConfigB\x02(\x01\x12\x45\n\x14process_stats_config\x18g \x01(\x0b\x32#.perfetto.protos.ProcessStatsConfigB\x02(\x01\x12=\n\x10sys_stats_config\x18h \x01(\x0b\x32\x1f.perfetto.protos.SysStatsConfigB\x02(\x01\x12>\n\x10heapprofd_config\x18i \x01(\x0b\x32 .perfetto.protos.HeapprofdConfigB\x02(\x01\x12?\n\x11java_hprof_config\x18n \x01(\x0b\x32 .perfetto.protos.JavaHprofConfigB\x02(\x01\x12\x45\n\x14\x61ndroid_power_config\x18j \x01(\x0b\x32#.perfetto.protos.AndroidPowerConfigB\x02(\x01\x12\x41\n\x12\x61ndroid_log_config\x18k \x01(\x0b\x32!.perfetto.protos.AndroidLogConfigB\x02(\x01\x12\x41\n\x12gpu_counter_config\x18l \x01(\x0b\x32!.perfetto.protos.GpuCounterConfigB\x02(\x01\x12\x65\n%android_game_intervention_list_config\x18t \x01(\x0b\x32\x32.perfetto.protos.AndroidGameInterventionListConfigB\x02(\x01\x12\x45\n\x14packages_list_config\x18m \x01(\x0b\x32#.perfetto.protos.PackagesListConfigB\x02(\x01\x12?\n\x11perf_event_config\x18o \x01(\x0b\x32 .perfetto.protos.PerfEventConfigB\x02(\x01\x12\x45\n\x14vulkan_memory_config\x18p \x01(\x0b\x32#.perfetto.protos.VulkanMemoryConfigB\x02(\x01\x12\x41\n\x12track_event_config\x18q \x01(\x0b\x32!.perfetto.protos.TrackEventConfigB\x02(\x01\x12R\n\x1b\x61ndroid_polled_state_config\x18r \x01(\x0b\x32).perfetto.protos.AndroidPolledStateConfigB\x02(\x01\x12X\n\x1e\x61ndroid_system_property_config\x18v \x01(\x0b\x32,.perfetto.protos.AndroidSystemPropertyConfigB\x02(\x01\x12G\n\x15statsd_tracing_config\x18u \x01(\x0b\x32$.perfetto.protos.StatsdTracingConfigB\x02(\x01\x12=\n\x12system_info_config\x18w \x01(\x0b\x32!.perfetto.protos.SystemInfoConfig\x12\x46\n\x14\x66rozen_ftrace_config\x18\x88\x01 \x01(\x0b\x32#.perfetto.protos.FrozenFtraceConfigB\x02(\x01\x12\x34\n\rchrome_config\x18\x65 \x01(\x0b\x32\x1d.perfetto.protos.ChromeConfig\x12\x30\n\tv8_config\x18\x7f \x01(\x0b\x32\x19.perfetto.protos.V8ConfigB\x02(\x01\x12>\n\x12interceptor_config\x18s \x01(\x0b\x32\".perfetto.protos.InterceptorConfig\x12R\n\x1bnetwork_packet_trace_config\x18x \x01(\x0b\x32).perfetto.protos.NetworkPacketTraceConfigB\x02(\x01\x12U\n\x1csurfaceflinger_layers_config\x18y \x01(\x0b\x32+.perfetto.protos.SurfaceFlingerLayersConfigB\x02(\x01\x12\x61\n\"surfaceflinger_transactions_config\x18{ \x01(\x0b\x32\x31.perfetto.protos.SurfaceFlingerTransactionsConfigB\x02(\x01\x12[\n android_sdk_sysprop_guard_config\x18| \x01(\x0b\x32-.perfetto.protos.AndroidSdkSyspropGuardConfigB\x02(\x01\x12\x32\n\netw_config\x18} \x01(\x0b\x32\x1a.perfetto.protos.EtwConfigB\x02(\x01\x12<\n\x0fprotolog_config\x18~ \x01(\x0b\x32\x1f.perfetto.protos.ProtoLogConfigB\x02(\x01\x12Q\n\x1a\x61ndroid_input_event_config\x18\x80\x01 \x01(\x0b\x32(.perfetto.protos.AndroidInputEventConfigB\x02(\x01\x12\x42\n\x12pixel_modem_config\x18\x81\x01 \x01(\x0b\x32!.perfetto.protos.PixelModemConfigB\x02(\x01\x12G\n\x14windowmanager_config\x18\x82\x01 \x01(\x0b\x32$.perfetto.protos.WindowManagerConfigB\x02(\x01\x12R\n\x17\x63hromium_system_metrics\x18\x83\x01 \x01(\x0b\x32,.perfetto.protos.ChromiumSystemMetricsConfigB\x02(\x01\x12L\n\x17kernel_wakelocks_config\x18\x84\x01 \x01(\x0b\x32&.perfetto.protos.KernelWakelocksConfigB\x02(\x01\x12L\n\x17gpu_renderstages_config\x18\x85\x01 \x01(\x0b\x32&.perfetto.protos.GpuRenderStagesConfigB\x02(\x01\x12X\n\x1a\x63hromium_histogram_samples\x18\x86\x01 \x01(\x0b\x32/.perfetto.protos.ChromiumHistogramSamplesConfigB\x02(\x01\x12\x46\n\x14\x61pp_wakelocks_config\x18\x87\x01 \x01(\x0b\x32#.perfetto.protos.AppWakelocksConfigB\x02(\x01\x12\x41\n\x12\x63pu_per_uid_config\x18\x89\x01 \x01(\x0b\x32 .perfetto.protos.CpuPerUidConfigB\x02(\x01\x12\x45\n\x10user_list_config\x18\x8a\x01 \x01(\x0b\x32&.perfetto.protos.AndroidUserListConfigB\x02(\x01\x12\x43\n\x12inputmethod_config\x18\x8b\x01 \x01(\x0b\x32\".perfetto.protos.InputMethodConfigB\x02(\x01\x12H\n\x15\x61ndroid_aflags_config\x18\x8c\x01 \x01(\x0b\x32$.perfetto.protos.AndroidAflagsConfigB\x02(\x01\x12\x44\n\x0fjournald_config\x18\x8d\x01 \x01(\x0b\x32&.perfetto.protos.SystemdJournaldConfigB\x02(\x01\x12\x46\n\x14\x64isplay_video_config\x18\x8e\x01 \x01(\x0b\x32#.perfetto.protos.DisplayVideoConfigB\x02(\x01\x12\x63\n chromium_stack_sampling_profiler\x18\x8f\x01 \x01(\x0b\x32\x34.perfetto.protos.ChromiumStackSamplingProfilerConfigB\x02(\x01\x12\x61\n\x1f\x63hromium_sampling_heap_profiler\x18\x90\x01 \x01(\x0b\x32\x33.perfetto.protos.ChromiumSamplingHeapProfilerConfigB\x02(\x01\x12U\n\x1c\x61ndroid_process_state_config\x18\x91\x01 \x01(\x0b\x32*.perfetto.protos.AndroidProcessStateConfigB\x02(\x01\x12\x46\n\x14process_smaps_config\x18\x92\x01 \x01(\x0b\x32#.perfetto.protos.ProcessSmapsConfigB\x02(\x01\x12\x33\n\nqnx_config\x18\x96\x01 \x01(\x0b\x32\x1a.perfetto.protos.QnxConfigB\x02(\x01\x12\x16\n\rlegacy_config\x18\xe8\x07 \x01(\t\x12\x31\n\x0b\x66or_testing\x18\xe9\x07 \x01(\x0b\x32\x1b.perfetto.protos.TestConfig\x1a\x84\x02\n\x1b\x45xperimentalTracingV2Config\x12\"\n\x1ause_v2_probability_percent\x18\x01 \x01(\r\x12i\n\x12\x63hunk_size_options\x18\x02 \x03(\x0b\x32M.perfetto.protos.DataSourceConfig.ExperimentalTracingV2Config.ChunkSizeOption\x12\x1f\n\x17\x64rain_occupancy_percent\x18\x03 \x01(\x05\x1a\x35\n\x0f\x43hunkSizeOption\x12\x12\n\nsize_bytes\x18\x01 \x01(\r\x12\x0e\n\x06weight\x18\x02 \x01(\r\"[\n\x10SessionInitiator\x12!\n\x1dSESSION_INITIATOR_UNSPECIFIED\x10\x00\x12$\n SESSION_INITIATOR_TRUSTED_SYSTEM\x10\x01\"\xa1\x01\n\x15\x42ufferExhaustedPolicy\x12 \n\x1c\x42UFFER_EXHAUSTED_UNSPECIFIED\x10\x00\x12\x19\n\x15\x42UFFER_EXHAUSTED_DROP\x10\x01\x12%\n!BUFFER_EXHAUSTED_STALL_THEN_ABORT\x10\x02\x12$\n BUFFER_EXHAUSTED_STALL_THEN_DROP\x10\x03J\x0b\x08\xff\xff\xff\x7f\x10\x80\x80\x80\x80\x01\"\xbb.\n\x0bTraceConfig\x12:\n\x07\x62uffers\x18\x01 \x03(\x0b\x32).perfetto.protos.TraceConfig.BufferConfig\x12/\n\'experimental_trace_buffer_v2_compaction\x18\x32 \x01(\x08\x12=\n\x0c\x64\x61ta_sources\x18\x02 \x03(\x0b\x32\'.perfetto.protos.TraceConfig.DataSource\x12L\n\x14\x62uiltin_data_sources\x18\x14 \x01(\x0b\x32..perfetto.protos.TraceConfig.BuiltinDataSource\x12\x13\n\x0b\x64uration_ms\x18\x03 \x01(\r\x12)\n!prefer_suspend_clock_for_duration\x18$ \x01(\x08\x12\x1f\n\x17\x65nable_extra_guardrails\x18\x04 \x01(\x08\x12I\n\rlockdown_mode\x18\x05 \x01(\x0e\x32\x32.perfetto.protos.TraceConfig.LockdownModeOperation\x12>\n\tproducers\x18\x06 \x03(\x0b\x32+.perfetto.protos.TraceConfig.ProducerConfig\x12\x44\n\x0fstatsd_metadata\x18\x07 \x01(\x0b\x32+.perfetto.protos.TraceConfig.StatsdMetadata\x12\x17\n\x0fwrite_into_file\x18\x08 \x01(\x08\x12\x13\n\x0boutput_path\x18\x1d \x01(\t\x12\x1c\n\x14\x66ile_write_period_ms\x18\t \x01(\r\x12\x1b\n\x13max_file_size_bytes\x18\n \x01(\x04\x12L\n\x13guardrail_overrides\x18\x0b \x01(\x0b\x32/.perfetto.protos.TraceConfig.GuardrailOverrides\x12\x16\n\x0e\x64\x65\x66\x65rred_start\x18\x0c \x01(\x08\x12\x17\n\x0f\x66lush_period_ms\x18\r \x01(\r\x12\x18\n\x10\x66lush_timeout_ms\x18\x0e \x01(\r\x12#\n\x1b\x64\x61ta_source_stop_timeout_ms\x18\x17 \x01(\r\x12\x16\n\x0enotify_traceur\x18\x10 \x01(\x08\x12\x17\n\x0f\x62ugreport_score\x18\x1e \x01(\x05\x12\x1a\n\x12\x62ugreport_filename\x18& \x01(\t\x12\x42\n\x0etrigger_config\x18\x11 \x01(\x0b\x32*.perfetto.protos.TraceConfig.TriggerConfig\x12\x19\n\x11\x61\x63tivate_triggers\x18\x12 \x03(\t\x12U\n\x18incremental_state_config\x18\x15 \x01(\x0b\x32\x33.perfetto.protos.TraceConfig.IncrementalStateConfig\x12$\n\x18\x61llow_user_build_tracing\x18\x13 \x01(\x08\x42\x02\x18\x01\x12\x1b\n\x13unique_session_name\x18\x16 \x01(\t\x12J\n\x10\x63ompression_type\x18\x18 \x01(\x0e\x32,.perfetto.protos.TraceConfig.CompressionTypeB\x02\x18\x01\x12\x43\n\x0b\x63ompression\x18/ \x01(\x0b\x32..perfetto.protos.TraceConfig.CompressionConfig\x12Q\n\x16incident_report_config\x18\x19 \x01(\x0b\x32\x31.perfetto.protos.TraceConfig.IncidentReportConfig\x12\x42\n\x0estatsd_logging\x18\x1f \x01(\x0e\x32*.perfetto.protos.TraceConfig.StatsdLogging\x12\x1a\n\x0etrace_uuid_msb\x18\x1b \x01(\x03\x42\x02\x18\x01\x12\x1a\n\x0etrace_uuid_lsb\x18\x1c \x01(\x03\x42\x02\x18\x01\x12>\n\x0ctrace_filter\x18! \x01(\x0b\x32(.perfetto.protos.TraceConfig.TraceFilter\x12O\n\x15\x61ndroid_report_config\x18\" \x01(\x0b\x32\x30.perfetto.protos.TraceConfig.AndroidReportConfig\x12N\n\x15\x63md_trace_start_delay\x18# \x01(\x0b\x32/.perfetto.protos.TraceConfig.CmdTraceStartDelay\x12I\n\x12session_semaphores\x18\' \x03(\x0b\x32-.perfetto.protos.TraceConfig.SessionSemaphore\x12<\n\x0epriority_boost\x18( \x01(\x0b\x32$.perfetto.protos.PriorityBoostConfig\x12\x16\n\x0e\x65xclusive_prio\x18) \x01(\r\x12\x45\n\x10write_flush_mode\x18, \x01(\x0e\x32+.perfetto.protos.TraceConfig.WriteFlushMode\x12\x42\n\x11\x66\x66lush_post_write\x18- \x01(\x0e\x32\'.perfetto.protos.TraceConfig.FFlushMode\x12\x1a\n\x12trace_all_machines\x18+ \x01(\x08\x12:\n\x10trace_attributes\x18\x30 \x01(\x0b\x32 .perfetto.protos.TraceAttributes\x12$\n\x1cpersist_trace_across_reboots\x18\x31 \x01(\x08\x1a\x94\x03\n\x0c\x42ufferConfig\x12\x0f\n\x07size_kb\x18\x01 \x01(\r\x12I\n\x0b\x66ill_policy\x18\x04 \x01(\x0e\x32\x34.perfetto.protos.TraceConfig.BufferConfig.FillPolicy\x12\x19\n\x11transfer_on_clone\x18\x05 \x01(\x08\x12\x1a\n\x12\x63lear_before_clone\x18\x06 \x01(\x08\x12\x0c\n\x04name\x18\x07 \x01(\t\x12U\n\x11\x65xperimental_mode\x18\x08 \x01(\x0e\x32:.perfetto.protos.TraceConfig.BufferConfig.ExperimentalMode\";\n\nFillPolicy\x12\x0f\n\x0bUNSPECIFIED\x10\x00\x12\x0f\n\x0bRING_BUFFER\x10\x01\x12\x0b\n\x07\x44ISCARD\x10\x02\"C\n\x10\x45xperimentalMode\x12\x14\n\x10MODE_UNSPECIFIED\x10\x00\x12\x13\n\x0fTRACE_BUFFER_V2\x10\x01\"\x04\x08\x02\x10\x02J\x04\x08\x02\x10\x03J\x04\x08\x03\x10\x04\x1a\x9e\x01\n\nDataSource\x12\x31\n\x06\x63onfig\x18\x01 \x01(\x0b\x32!.perfetto.protos.DataSourceConfig\x12\x1c\n\x14producer_name_filter\x18\x02 \x03(\t\x12\"\n\x1aproducer_name_regex_filter\x18\x03 \x03(\t\x12\x1b\n\x13machine_name_filter\x18\x04 \x03(\t\x1a\x90\x03\n\x11\x42uiltinDataSource\x12\"\n\x1a\x64isable_clock_snapshotting\x18\x01 \x01(\x08\x12\x1c\n\x14\x64isable_trace_config\x18\x02 \x01(\x08\x12\x1b\n\x13\x64isable_system_info\x18\x03 \x01(\x08\x12\x1e\n\x16\x64isable_service_events\x18\x04 \x01(\x08\x12:\n\x13primary_trace_clock\x18\x05 \x01(\x0e\x32\x1d.perfetto.protos.BuiltinClock\x12\x1c\n\x14snapshot_interval_ms\x18\x06 \x01(\r\x12)\n!prefer_suspend_clock_for_snapshot\x18\x07 \x01(\x08\x12&\n\x1e\x64isable_chunk_usage_histograms\x18\x08 \x01(\x08\x12%\n\x1d\x64isable_extension_descriptors\x18\t \x01(\x08\x12(\n enable_concurrent_session_events\x18\n \x01(\x08\x1aR\n\x0eProducerConfig\x12\x15\n\rproducer_name\x18\x01 \x01(\t\x12\x13\n\x0bshm_size_kb\x18\x02 \x01(\r\x12\x14\n\x0cpage_size_kb\x18\x03 \x01(\r\x1a\x8e\x01\n\x0eStatsdMetadata\x12\x1b\n\x13triggering_alert_id\x18\x01 \x01(\x03\x12\x1d\n\x15triggering_config_uid\x18\x02 \x01(\x05\x12\x1c\n\x14triggering_config_id\x18\x03 \x01(\x03\x12\"\n\x1atriggering_subscription_id\x18\x04 \x01(\x03\x1a^\n\x12GuardrailOverrides\x12$\n\x18max_upload_per_day_bytes\x18\x01 \x01(\x04\x42\x02\x18\x01\x12\"\n\x1amax_tracing_buffer_size_kb\x18\x02 \x01(\r\x1a\xca\x03\n\rTriggerConfig\x12L\n\x0ctrigger_mode\x18\x01 \x01(\x0e\x32\x36.perfetto.protos.TraceConfig.TriggerConfig.TriggerMode\x12\'\n\x1fuse_clone_snapshot_if_available\x18\x05 \x01(\x08\x12\x44\n\x08triggers\x18\x02 \x03(\x0b\x32\x32.perfetto.protos.TraceConfig.TriggerConfig.Trigger\x12\x1a\n\x12trigger_timeout_ms\x18\x03 \x01(\r\x1a{\n\x07Trigger\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x1b\n\x13producer_name_regex\x18\x02 \x01(\t\x12\x15\n\rstop_delay_ms\x18\x03 \x01(\r\x12\x14\n\x0cmax_per_24_h\x18\x04 \x01(\r\x12\x18\n\x10skip_probability\x18\x05 \x01(\x01\"]\n\x0bTriggerMode\x12\x0f\n\x0bUNSPECIFIED\x10\x00\x12\x11\n\rSTART_TRACING\x10\x01\x12\x10\n\x0cSTOP_TRACING\x10\x02\x12\x12\n\x0e\x43LONE_SNAPSHOT\x10\x04\"\x04\x08\x03\x10\x03J\x04\x08\x04\x10\x05\x1a\x31\n\x16IncrementalStateConfig\x12\x17\n\x0f\x63lear_period_ms\x18\x01 \x01(\r\x1a\xc1\x01\n\x11\x43ompressionConfig\x12G\n\x07\x64\x65\x66late\x18\x01 \x01(\x0b\x32\x36.perfetto.protos.TraceConfig.CompressionConfig.Deflate\x12\x41\n\x04zstd\x18\x02 \x01(\x0b\x32\x33.perfetto.protos.TraceConfig.CompressionConfig.Zstd\x1a\t\n\x07\x44\x65\x66late\x1a\x15\n\x04Zstd\x12\r\n\x05level\x18\x01 \x01(\x05\x1a\x97\x01\n\x14IncidentReportConfig\x12\x1b\n\x13\x64\x65stination_package\x18\x01 \x01(\t\x12\x19\n\x11\x64\x65stination_class\x18\x02 \x01(\t\x12\x15\n\rprivacy_level\x18\x03 \x01(\x05\x12\x16\n\x0eskip_incidentd\x18\x05 \x01(\x08\x12\x18\n\x0cskip_dropbox\x18\x04 \x01(\x08\x42\x02\x18\x01\x1a\x94\x06\n\x0bTraceFilter\x12\x10\n\x08\x62ytecode\x18\x01 \x01(\x0c\x12\x13\n\x0b\x62ytecode_v2\x18\x02 \x01(\x0c\x12W\n\x13string_filter_chain\x18\x03 \x01(\x0b\x32:.perfetto.protos.TraceConfig.TraceFilter.StringFilterChain\x12\x1c\n\x14\x62ytecode_overlay_v54\x18\x04 \x01(\x0c\x12[\n\x17string_filter_chain_v54\x18\x05 \x01(\x0b\x32:.perfetto.protos.TraceConfig.TraceFilter.StringFilterChain\x1a\xde\x01\n\x10StringFilterRule\x12K\n\x06policy\x18\x01 \x01(\x0e\x32;.perfetto.protos.TraceConfig.TraceFilter.StringFilterPolicy\x12\x15\n\rregex_pattern\x18\x02 \x01(\t\x12\"\n\x1a\x61trace_payload_starts_with\x18\x03 \x01(\t\x12\x0c\n\x04name\x18\x04 \x01(\t\x12\x34\n\rsemantic_type\x18\x05 \x03(\x0e\x32\x1d.perfetto.protos.SemanticType\x1a]\n\x11StringFilterChain\x12H\n\x05rules\x18\x01 \x03(\x0b\x32\x39.perfetto.protos.TraceConfig.TraceFilter.StringFilterRule\"\xc9\x01\n\x12StringFilterPolicy\x12\x13\n\x0fSFP_UNSPECIFIED\x10\x00\x12\x1b\n\x17SFP_MATCH_REDACT_GROUPS\x10\x01\x12\"\n\x1eSFP_ATRACE_MATCH_REDACT_GROUPS\x10\x02\x12\x13\n\x0fSFP_MATCH_BREAK\x10\x03\x12\x1a\n\x16SFP_ATRACE_MATCH_BREAK\x10\x04\x12,\n(SFP_ATRACE_REPEATED_SEARCH_REDACT_GROUPS\x10\x05\x1a\x97\x01\n\x13\x41ndroidReportConfig\x12 \n\x18reporter_service_package\x18\x01 \x01(\t\x12\x1e\n\x16reporter_service_class\x18\x02 \x01(\t\x12\x13\n\x0bskip_report\x18\x03 \x01(\x08\x12)\n!use_pipe_in_framework_for_testing\x18\x04 \x01(\x08\x1a@\n\x12\x43mdTraceStartDelay\x12\x14\n\x0cmin_delay_ms\x18\x01 \x01(\r\x12\x14\n\x0cmax_delay_ms\x18\x02 \x01(\r\x1a\x41\n\x10SessionSemaphore\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x1f\n\x17max_other_session_count\x18\x02 \x01(\x04\"U\n\x15LockdownModeOperation\x12\x16\n\x12LOCKDOWN_UNCHANGED\x10\x00\x12\x12\n\x0eLOCKDOWN_CLEAR\x10\x01\x12\x10\n\x0cLOCKDOWN_SET\x10\x02\"Q\n\x0f\x43ompressionType\x12 \n\x1c\x43OMPRESSION_TYPE_UNSPECIFIED\x10\x00\x12\x1c\n\x18\x43OMPRESSION_TYPE_DEFLATE\x10\x01\"h\n\rStatsdLogging\x12\x1e\n\x1aSTATSD_LOGGING_UNSPECIFIED\x10\x00\x12\x1a\n\x16STATSD_LOGGING_ENABLED\x10\x01\x12\x1b\n\x17STATSD_LOGGING_DISABLED\x10\x02\"v\n\x0eWriteFlushMode\x12\x1b\n\x17WRITE_FLUSH_UNSPECIFIED\x10\x00\x12\x14\n\x10WRITE_FLUSH_AUTO\x10\x01\x12\x18\n\x14WRITE_FLUSH_DISABLED\x10\x02\x12\x17\n\x13WRITE_FLUSH_ENABLED\x10\x03\"M\n\nFFlushMode\x12\x16\n\x12\x46\x46LUSH_UNSPECIFIED\x10\x00\x12\x13\n\x0f\x46\x46LUSH_DISABLED\x10\x01\x12\x12\n\x0e\x46\x46LUSH_ENABLED\x10\x02J\x04\x08\x0f\x10\x10J\x04\x08%\x10&J\x04\x08\x1a\x10\x1bJ\x04\x08 \x10!J\x04\x08*\x10+J\x04\x08.\x10/R\x05notes\"M\n\x07Utsname\x12\x0f\n\x07sysname\x18\x01 \x01(\t\x12\x0f\n\x07version\x18\x02 \x01(\t\x12\x0f\n\x07release\x18\x03 \x01(\t\x12\x0f\n\x07machine\x18\x04 \x01(\t\"\x93\x04\n\nSystemInfo\x12)\n\x07utsname\x18\x01 \x01(\x0b\x32\x18.perfetto.protos.Utsname\x12!\n\x19\x61ndroid_build_fingerprint\x18\x02 \x01(\t\x12#\n\x1b\x61ndroid_device_manufacturer\x18\x0e \x01(\t\x12\x19\n\x11\x61ndroid_soc_model\x18\t \x01(\t\x12\x1f\n\x17\x64\x65vice_tree_compatibles\x18\x12 \x03(\t\x12\x1f\n\x17\x61ndroid_guest_soc_model\x18\r \x01(\t\x12!\n\x19\x61ndroid_hardware_revision\x18\n \x01(\t\x12\x1d\n\x15\x61ndroid_storage_model\x18\x0b \x01(\t\x12\x19\n\x11\x61ndroid_ram_model\x18\x0c \x01(\t\x12\x1e\n\x16\x61ndroid_serial_console\x18\x0f \x01(\t\x12\x1f\n\x17tracing_service_version\x18\x04 \x01(\t\x12\x1b\n\x13\x61ndroid_sdk_version\x18\x05 \x01(\x04\x12\x11\n\tpage_size\x18\x06 \x01(\r\x12\x10\n\x08num_cpus\x18\x08 \x01(\r\x12\x19\n\x11timezone_off_mins\x18\x07 \x01(\x05\x12\n\n\x02hz\x18\x03 \x01(\x03\x12\x18\n\x10system_ram_bytes\x18\x10 \x01(\x04\x12\x14\n\x0cmachine_name\x18\x11 \x01(\t\"\xa5\r\n\nTraceStats\x12=\n\x0c\x62uffer_stats\x18\x01 \x03(\x0b\x32\'.perfetto.protos.TraceStats.BufferStats\x12#\n\x1b\x63hunk_payload_histogram_def\x18\x11 \x03(\x03\x12=\n\x0cwriter_stats\x18\x12 \x03(\x0b\x32\'.perfetto.protos.TraceStats.WriterStats\x12\x1b\n\x13producers_connected\x18\x02 \x01(\r\x12\x16\n\x0eproducers_seen\x18\x03 \x01(\x04\x12\x1f\n\x17\x64\x61ta_sources_registered\x18\x04 \x01(\r\x12\x19\n\x11\x64\x61ta_sources_seen\x18\x05 \x01(\x04\x12\x18\n\x10tracing_sessions\x18\x06 \x01(\r\x12\x15\n\rtotal_buffers\x18\x07 \x01(\r\x12\x18\n\x10\x63hunks_discarded\x18\x08 \x01(\x04\x12\x19\n\x11patches_discarded\x18\t \x01(\x04\x12\x17\n\x0finvalid_packets\x18\n \x01(\x04\x12=\n\x0c\x66ilter_stats\x18\x0b \x01(\x0b\x32\'.perfetto.protos.TraceStats.FilterStats\x12\x19\n\x11\x66lushes_requested\x18\x0c \x01(\x04\x12\x19\n\x11\x66lushes_succeeded\x18\r \x01(\x04\x12\x16\n\x0e\x66lushes_failed\x18\x0e \x01(\x04\x12J\n\x13\x66inal_flush_outcome\x18\x0f \x01(\x0e\x32-.perfetto.protos.TraceStats.FinalFlushOutcome\x1a\xff\x04\n\x0b\x42ufferStats\x12\x13\n\x0b\x62uffer_size\x18\x0c \x01(\x04\x12\x15\n\rbytes_written\x18\x01 \x01(\x04\x12\x19\n\x11\x62ytes_overwritten\x18\r \x01(\x04\x12\x12\n\nbytes_read\x18\x0e \x01(\x04\x12\x1d\n\x15padding_bytes_written\x18\x0f \x01(\x04\x12\x1d\n\x15padding_bytes_cleared\x18\x10 \x01(\x04\x12\x16\n\x0e\x63hunks_written\x18\x02 \x01(\x04\x12\x18\n\x10\x63hunks_rewritten\x18\n \x01(\x04\x12\x18\n\x10\x63hunks_relocated\x18\x14 \x01(\x04\x12\x1a\n\x12\x63hunks_overwritten\x18\x03 \x01(\x04\x12\x18\n\x10\x63hunks_discarded\x18\x12 \x01(\x04\x12\x13\n\x0b\x63hunks_read\x18\x11 \x01(\x04\x12%\n\x1d\x63hunks_committed_out_of_order\x18\x0b \x01(\x04\x12\x18\n\x10write_wrap_count\x18\x04 \x01(\x04\x12\x13\n\x0b\x63ompactions\x18\x17 \x01(\x04\x12\x1b\n\x13\x63ompactions_skipped\x18\x18 \x01(\x04\x12\x19\n\x11patches_succeeded\x18\x05 \x01(\x04\x12\x16\n\x0epatches_failed\x18\x06 \x01(\x04\x12\x1c\n\x14readaheads_succeeded\x18\x07 \x01(\x04\x12\x19\n\x11readaheads_failed\x18\x08 \x01(\x04\x12\x16\n\x0e\x61\x62i_violations\x18\t \x01(\x04\x12 \n\x18trace_writer_packet_loss\x18\x13 \x01(\x04\x12!\n\x19oversized_packets_dropped\x18\x16 \x01(\x04J\x04\x08\x15\x10\x16\x1a\xa6\x01\n\x0bWriterStats\x12\x13\n\x0bsequence_id\x18\x01 \x01(\x04\x12\x0e\n\x06\x62uffer\x18\x04 \x01(\r\x12\x1d\n\x15protocol_abi_versions\x18\x05 \x01(\r\x12*\n\x1e\x63hunk_payload_histogram_counts\x18\x02 \x03(\x04\x42\x02\x10\x01\x12\'\n\x1b\x63hunk_payload_histogram_sum\x18\x03 \x03(\x03\x42\x02\x10\x01\x1a\x9a\x01\n\x0b\x46ilterStats\x12\x15\n\rinput_packets\x18\x01 \x01(\x04\x12\x13\n\x0binput_bytes\x18\x02 \x01(\x04\x12\x14\n\x0coutput_bytes\x18\x03 \x01(\x04\x12\x0e\n\x06\x65rrors\x18\x04 \x01(\x04\x12\x15\n\rtime_taken_ns\x18\x05 \x01(\x04\x12\"\n\x1a\x62ytes_discarded_per_buffer\x18\x14 \x03(\x04\"c\n\x11\x46inalFlushOutcome\x12\x1b\n\x17\x46INAL_FLUSH_UNSPECIFIED\x10\x00\x12\x19\n\x15\x46INAL_FLUSH_SUCCEEDED\x10\x01\x12\x16\n\x12\x46INAL_FLUSH_FAILED\x10\x02\"\xd6\x07\n\rAndroidAflags\x12\x32\n\x05\x66lags\x18\x01 \x03(\x0b\x32#.perfetto.protos.AndroidAflags.Flag\x12\r\n\x05\x65rror\x18\x02 \x01(\t\x1a\x82\x03\n\x04\x46lag\x12\x16\n\x0e\x66lag_namespace\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x0b\n\x03pkg\x18\x03 \x01(\t\x12\x11\n\tcontainer\x18\x04 \x01(\t\x12\r\n\x05value\x18\x05 \x01(\t\x12\x14\n\x0cstaged_value\x18\x06 \x01(\t\x12\x41\n\npermission\x18\x07 \x01(\x0e\x32-.perfetto.protos.AndroidAflags.FlagPermission\x12I\n\x11value_picked_from\x18\x08 \x01(\x0e\x32..perfetto.protos.AndroidAflags.ValuePickedFrom\x12J\n\x0fstorage_backend\x18\t \x01(\x0e\x32\x31.perfetto.protos.AndroidAflags.FlagStorageBackend\x12\x35\n\x04type\x18\n \x01(\x0e\x32\'.perfetto.protos.AndroidAflags.FlagType\"p\n\x0e\x46lagPermission\x12\x1f\n\x1b\x46LAG_PERMISSION_UNSPECIFIED\x10\x00\x12\x1d\n\x19\x46LAG_PERMISSION_READ_ONLY\x10\x01\x12\x1e\n\x1a\x46LAG_PERMISSION_READ_WRITE\x10\x02\"\x8e\x01\n\x0fValuePickedFrom\x12!\n\x1dVALUE_PICKED_FROM_UNSPECIFIED\x10\x00\x12\x1d\n\x19VALUE_PICKED_FROM_DEFAULT\x10\x01\x12\x1c\n\x18VALUE_PICKED_FROM_SERVER\x10\x02\x12\x1b\n\x17VALUE_PICKED_FROM_LOCAL\x10\x03\"\xa4\x01\n\x12\x46lagStorageBackend\x12$\n FLAG_STORAGE_BACKEND_UNSPECIFIED\x10\x00\x12\x1d\n\x19\x46LAG_STORAGE_BACKEND_NONE\x10\x01\x12!\n\x1d\x46LAG_STORAGE_BACKEND_ACONFIGD\x10\x02\x12&\n\"FLAG_STORAGE_BACKEND_DEVICE_CONFIG\x10\x03\"S\n\x08\x46lagType\x12\x19\n\x15\x46LAG_TYPE_UNSPECIFIED\x10\x00\x12\x15\n\x11\x46LAG_TYPE_BOOLEAN\x10\x01\x12\x15\n\x11\x46LAG_TYPE_INTEGER\x10\x02\"\x8f\x03\n\x1b\x41ndroidGameInterventionList\x12S\n\rgame_packages\x18\x01 \x03(\x0b\x32<.perfetto.protos.AndroidGameInterventionList.GamePackageInfo\x12\x13\n\x0bparse_error\x18\x02 \x01(\x08\x12\x12\n\nread_error\x18\x03 \x01(\x08\x1aZ\n\x0cGameModeInfo\x12\x0c\n\x04mode\x18\x01 \x01(\r\x12\x11\n\tuse_angle\x18\x02 \x01(\x08\x12\x1c\n\x14resolution_downscale\x18\x03 \x01(\x02\x12\x0b\n\x03\x66ps\x18\x04 \x01(\x02\x1a\x95\x01\n\x0fGamePackageInfo\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0b\n\x03uid\x18\x02 \x01(\x04\x12\x14\n\x0c\x63urrent_mode\x18\x03 \x01(\r\x12Q\n\x0egame_mode_info\x18\x04 \x03(\x0b\x32\x39.perfetto.protos.AndroidGameInterventionList.GameModeInfo\"\xb2\x04\n\x10\x41ndroidLogPacket\x12:\n\x06\x65vents\x18\x01 \x03(\x0b\x32*.perfetto.protos.AndroidLogPacket.LogEvent\x12\x36\n\x05stats\x18\x02 \x01(\x0b\x32\'.perfetto.protos.AndroidLogPacket.Stats\x1a\xe4\x02\n\x08LogEvent\x12-\n\x06log_id\x18\x01 \x01(\x0e\x32\x1d.perfetto.protos.AndroidLogId\x12\x0b\n\x03pid\x18\x02 \x01(\x05\x12\x0b\n\x03tid\x18\x03 \x01(\x05\x12\x0b\n\x03uid\x18\x04 \x01(\x05\x12\x11\n\ttimestamp\x18\x05 \x01(\x04\x12\x0b\n\x03tag\x18\x06 \x01(\t\x12\x31\n\x04prio\x18\x07 \x01(\x0e\x32#.perfetto.protos.AndroidLogPriority\x12\x0f\n\x07message\x18\x08 \x01(\t\x12<\n\x04\x61rgs\x18\t \x03(\x0b\x32..perfetto.protos.AndroidLogPacket.LogEvent.Arg\x1a`\n\x03\x41rg\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x13\n\tint_value\x18\x02 \x01(\x03H\x00\x12\x15\n\x0b\x66loat_value\x18\x03 \x01(\x02H\x00\x12\x16\n\x0cstring_value\x18\x04 \x01(\tH\x00\x42\x07\n\x05value\x1a\x43\n\x05Stats\x12\x11\n\tnum_total\x18\x01 \x01(\x04\x12\x12\n\nnum_failed\x18\x02 \x01(\x04\x12\x13\n\x0bnum_skipped\x18\x03 \x01(\x04\"\x8b\x01\n\x15\x41ndroidSystemProperty\x12\x44\n\x06values\x18\x01 \x03(\x0b\x32\x34.perfetto.protos.AndroidSystemProperty.PropertyValue\x1a,\n\rPropertyValue\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t\"R\n\rCpuPerUidData\x12\x15\n\rcluster_count\x18\x01 \x01(\r\x12\x0f\n\x03uid\x18\x02 \x03(\rB\x02\x10\x01\x12\x19\n\rtotal_time_ms\x18\x03 \x03(\x04\x42\x02\x10\x01\"\xf1\x03\n\x12GraphicsFrameEvent\x12\x45\n\x0c\x62uffer_event\x18\x01 \x01(\x0b\x32/.perfetto.protos.GraphicsFrameEvent.BufferEvent\x1a\xa2\x01\n\x0b\x42ufferEvent\x12\x14\n\x0c\x66rame_number\x18\x01 \x01(\r\x12\x41\n\x04type\x18\x02 \x01(\x0e\x32\x33.perfetto.protos.GraphicsFrameEvent.BufferEventType\x12\x12\n\nlayer_name\x18\x03 \x01(\t\x12\x13\n\x0b\x64uration_ns\x18\x04 \x01(\x04\x12\x11\n\tbuffer_id\x18\x05 \x01(\r\"\xee\x01\n\x0f\x42ufferEventType\x12\x0f\n\x0bUNSPECIFIED\x10\x00\x12\x0b\n\x07\x44\x45QUEUE\x10\x01\x12\t\n\x05QUEUE\x10\x02\x12\x08\n\x04POST\x10\x03\x12\x11\n\rACQUIRE_FENCE\x10\x04\x12\t\n\x05LATCH\x10\x05\x12\x1a\n\x16HWC_COMPOSITION_QUEUED\x10\x06\x12\x18\n\x14\x46\x41LLBACK_COMPOSITION\x10\x07\x12\x11\n\rPRESENT_FENCE\x10\x08\x12\x11\n\rRELEASE_FENCE\x10\t\x12\n\n\x06MODIFY\x10\n\x12\n\n\x06\x44\x45TACH\x10\x0b\x12\n\n\x06\x41TTACH\x10\x0c\x12\n\n\x06\x43\x41NCEL\x10\r\"@\n\x13InitialDisplayState\x12\x15\n\rdisplay_state\x18\x01 \x01(\x05\x12\x12\n\nbrightness\x18\x02 \x01(\x01\"\xfa\x02\n\x12KernelWakelockData\x12>\n\x08wakelock\x18\x01 \x03(\x0b\x32,.perfetto.protos.KernelWakelockData.Wakelock\x12\x17\n\x0bwakelock_id\x18\x02 \x03(\rB\x02\x10\x01\x12\x1c\n\x10time_held_millis\x18\x03 \x03(\x04\x42\x02\x10\x01\x12\x13\n\x0b\x65rror_flags\x18\x04 \x01(\x04\x1a\xd7\x01\n\x08Wakelock\x12\x13\n\x0bwakelock_id\x18\x01 \x01(\r\x12\x15\n\rwakelock_name\x18\x02 \x01(\t\x12H\n\rwakelock_type\x18\x03 \x01(\x0e\x32\x31.perfetto.protos.KernelWakelockData.Wakelock.Type\"U\n\x04Type\x12\x19\n\x15WAKELOCK_TYPE_UNKNOWN\x10\x00\x12\x18\n\x14WAKELOCK_TYPE_KERNEL\x10\x01\x12\x18\n\x14WAKELOCK_TYPE_NATIVE\x10\x02\"\xfe\x01\n\x0cPackagesList\x12;\n\x08packages\x18\x01 \x03(\x0b\x32).perfetto.protos.PackagesList.PackageInfo\x12\x13\n\x0bparse_error\x18\x02 \x01(\x08\x12\x12\n\nread_error\x18\x03 \x01(\x08\x1a\x87\x01\n\x0bPackageInfo\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0b\n\x03uid\x18\x02 \x01(\x04\x12\x12\n\ndebuggable\x18\x03 \x01(\x08\x12\x1e\n\x16profileable_from_shell\x18\x04 \x01(\x08\x12\x14\n\x0cversion_code\x18\x05 \x01(\x03\x12\x13\n\x0bprofileable\x18\x06 \x01(\x08\"<\n\x10PixelModemEvents\x12\x0e\n\x06\x65vents\x18\x01 \x03(\x0c\x12\x18\n\x10\x65vent_time_nanos\x18\x02 \x03(\x04\"+\n\x17PixelModemTokenDatabase\x12\x10\n\x08\x64\x61tabase\x18\x01 \x01(\x0c\"\xcb\x01\n\x12RecoveredTraceInfo\x12:\n\x06reason\x18\x01 \x01(\x0e\x32*.perfetto.protos.RecoveredTraceInfo.Reason\x12 \n\x18original_file_size_bytes\x18\x02 \x01(\x04\x12\x17\n\x0f\x62ytes_truncated\x18\x03 \x01(\x04\">\n\x06Reason\x12\x16\n\x12REASON_UNSPECIFIED\x10\x00\x12\x1c\n\x18REASON_UNEXPECTED_REBOOT\x10\x01\"\x81\x01\n\x0f\x41ndroidUserList\x12\x38\n\x05users\x18\x01 \x03(\x0b\x32).perfetto.protos.AndroidUserList.UserInfo\x12\r\n\x05\x65rror\x18\x02 \x01(\x05\x1a%\n\x08UserInfo\x12\x0c\n\x04type\x18\x01 \x01(\t\x12\x0b\n\x03uid\x18\x02 \x01(\x05\"\xf2\x01\n\x17\x43hromeBenchmarkMetadata\x12\x1f\n\x17\x62\x65nchmark_start_time_us\x18\x01 \x01(\x03\x12\x19\n\x11story_run_time_us\x18\x02 \x01(\x03\x12\x16\n\x0e\x62\x65nchmark_name\x18\x03 \x01(\t\x12\x1d\n\x15\x62\x65nchmark_description\x18\x04 \x01(\t\x12\r\n\x05label\x18\x05 \x01(\t\x12\x12\n\nstory_name\x18\x06 \x01(\t\x12\x12\n\nstory_tags\x18\x07 \x03(\t\x12\x17\n\x0fstory_run_index\x18\x08 \x01(\x05\x12\x14\n\x0chad_failures\x18\t \x01(\x08\"\xe8\x02\n\x14\x43hromeMetadataPacket\x12O\n\x1b\x62\x61\x63kground_tracing_metadata\x18\x01 \x01(\x0b\x32*.perfetto.protos.BackgroundTracingMetadata\x12\x1b\n\x13\x63hrome_version_code\x18\x02 \x01(\x05\x12\x1a\n\x12\x65nabled_categories\x18\x03 \x01(\t\x12K\n\x12\x66ield_trial_hashes\x18\x04 \x03(\x0b\x32/.perfetto.protos.ChromeMetadataPacket.FinchHash\x12\x18\n\x10\x61pp_package_name\x18\x05 \x01(\t\x12\x13\n\x0b\x61pp_version\x18\x06 \x01(\t\x12\x0f\n\x07\x63hannel\x18\x07 \x01(\r\x12\x0f\n\x07os_name\x18\x08 \x01(\t\x1a(\n\tFinchHash\x12\x0c\n\x04name\x18\x01 \x01(\r\x12\r\n\x05group\x18\x02 \x01(\r\"\x95\x08\n\x19\x42\x61\x63kgroundTracingMetadata\x12N\n\x0etriggered_rule\x18\x01 \x01(\x0b\x32\x36.perfetto.protos.BackgroundTracingMetadata.TriggerRule\x12L\n\x0c\x61\x63tive_rules\x18\x02 \x03(\x0b\x32\x36.perfetto.protos.BackgroundTracingMetadata.TriggerRule\x12\x1a\n\x12scenario_name_hash\x18\x03 \x01(\x07\x1a\xbd\x06\n\x0bTriggerRule\x12X\n\x0ctrigger_type\x18\x01 \x01(\x0e\x32\x42.perfetto.protos.BackgroundTracingMetadata.TriggerRule.TriggerType\x12\\\n\x0ehistogram_rule\x18\x02 \x01(\x0b\x32\x44.perfetto.protos.BackgroundTracingMetadata.TriggerRule.HistogramRule\x12T\n\nnamed_rule\x18\x03 \x01(\x0b\x32@.perfetto.protos.BackgroundTracingMetadata.TriggerRule.NamedRule\x12\x11\n\tname_hash\x18\x04 \x01(\x07\x1aj\n\rHistogramRule\x12\x1b\n\x13histogram_name_hash\x18\x01 \x01(\x06\x12\x1d\n\x15histogram_min_trigger\x18\x02 \x01(\x03\x12\x1d\n\x15histogram_max_trigger\x18\x03 \x01(\x03\x1a\x96\x02\n\tNamedRule\x12^\n\nevent_type\x18\x01 \x01(\x0e\x32J.perfetto.protos.BackgroundTracingMetadata.TriggerRule.NamedRule.EventType\x12!\n\x19\x63ontent_trigger_name_hash\x18\x02 \x01(\x06\"\x85\x01\n\tEventType\x12\x0f\n\x0bUNSPECIFIED\x10\x00\x12\x13\n\x0fSESSION_RESTORE\x10\x01\x12\x0e\n\nNAVIGATION\x10\x02\x12\x0b\n\x07STARTUP\x10\x03\x12\x10\n\x0cREACHED_CODE\x10\x04\x12\x13\n\x0f\x43ONTENT_TRIGGER\x10\x05\x12\x0e\n\tTEST_RULE\x10\xe8\x07\"\x87\x01\n\x0bTriggerType\x12\x17\n\x13TRIGGER_UNSPECIFIED\x10\x00\x12\x36\n2MONITOR_AND_DUMP_WHEN_SPECIFIC_HISTOGRAM_AND_VALUE\x10\x01\x12\'\n#MONITOR_AND_DUMP_WHEN_TRIGGER_NAMED\x10\x02\"\xd3\x02\n\x11\x43hromeTracedValue\x12\x42\n\x0bnested_type\x18\x01 \x01(\x0e\x32-.perfetto.protos.ChromeTracedValue.NestedType\x12\x11\n\tdict_keys\x18\x02 \x03(\t\x12\x37\n\x0b\x64ict_values\x18\x03 \x03(\x0b\x32\".perfetto.protos.ChromeTracedValue\x12\x38\n\x0c\x61rray_values\x18\x04 \x03(\x0b\x32\".perfetto.protos.ChromeTracedValue\x12\x11\n\tint_value\x18\x05 \x01(\x05\x12\x14\n\x0c\x64ouble_value\x18\x06 \x01(\x01\x12\x12\n\nbool_value\x18\x07 \x01(\x08\x12\x14\n\x0cstring_value\x18\x08 \x01(\t\"!\n\nNestedType\x12\x08\n\x04\x44ICT\x10\x00\x12\t\n\x05\x41RRAY\x10\x01\"6\n\x16\x43hromeStringTableEntry\x12\r\n\x05value\x18\x01 \x01(\t\x12\r\n\x05index\x18\x02 \x01(\x05\"\x81\x05\n\x10\x43hromeTraceEvent\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x11\n\ttimestamp\x18\x02 \x01(\x03\x12\r\n\x05phase\x18\x03 \x01(\x05\x12\x11\n\tthread_id\x18\x04 \x01(\x05\x12\x10\n\x08\x64uration\x18\x05 \x01(\x03\x12\x17\n\x0fthread_duration\x18\x06 \x01(\x03\x12\r\n\x05scope\x18\x07 \x01(\t\x12\n\n\x02id\x18\x08 \x01(\x04\x12\r\n\x05\x66lags\x18\t \x01(\r\x12\x1b\n\x13\x63\x61tegory_group_name\x18\n \x01(\t\x12\x12\n\nprocess_id\x18\x0b \x01(\x05\x12\x18\n\x10thread_timestamp\x18\x0c \x01(\x03\x12\x0f\n\x07\x62ind_id\x18\r \x01(\x04\x12\x33\n\x04\x61rgs\x18\x0e \x03(\x0b\x32%.perfetto.protos.ChromeTraceEvent.Arg\x12\x12\n\nname_index\x18\x0f \x01(\r\x12!\n\x19\x63\x61tegory_group_name_index\x18\x10 \x01(\r\x1a\x8c\x02\n\x03\x41rg\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x14\n\nbool_value\x18\x02 \x01(\x08H\x00\x12\x14\n\nuint_value\x18\x03 \x01(\x04H\x00\x12\x13\n\tint_value\x18\x04 \x01(\x03H\x00\x12\x16\n\x0c\x64ouble_value\x18\x05 \x01(\x01H\x00\x12\x16\n\x0cstring_value\x18\x06 \x01(\tH\x00\x12\x17\n\rpointer_value\x18\x07 \x01(\x04H\x00\x12\x14\n\njson_value\x18\x08 \x01(\tH\x00\x12:\n\x0ctraced_value\x18\n \x01(\x0b\x32\".perfetto.protos.ChromeTracedValueH\x00\x12\x12\n\nname_index\x18\t \x01(\rB\x07\n\x05value\"\x80\x01\n\x0e\x43hromeMetadata\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x16\n\x0cstring_value\x18\x02 \x01(\tH\x00\x12\x14\n\nbool_value\x18\x03 \x01(\x08H\x00\x12\x13\n\tint_value\x18\x04 \x01(\x03H\x00\x12\x14\n\njson_value\x18\x05 \x01(\tH\x00\x42\x07\n\x05value\"\x94\x01\n\x15\x43hromeLegacyJsonTrace\x12>\n\x04type\x18\x01 \x01(\x0e\x32\x30.perfetto.protos.ChromeLegacyJsonTrace.TraceType\x12\x0c\n\x04\x64\x61ta\x18\x02 \x01(\t\"-\n\tTraceType\x12\x0e\n\nUSER_TRACE\x10\x00\x12\x10\n\x0cSYSTEM_TRACE\x10\x01\"\xa7\x02\n\x11\x43hromeEventBundle\x12;\n\x0ctrace_events\x18\x01 \x03(\x0b\x32!.perfetto.protos.ChromeTraceEventB\x02\x18\x01\x12\x31\n\x08metadata\x18\x02 \x03(\x0b\x32\x1f.perfetto.protos.ChromeMetadata\x12\x1c\n\x14legacy_ftrace_output\x18\x04 \x03(\t\x12\x41\n\x11legacy_json_trace\x18\x05 \x03(\x0b\x32&.perfetto.protos.ChromeLegacyJsonTrace\x12\x41\n\x0cstring_table\x18\x03 \x03(\x0b\x32\'.perfetto.protos.ChromeStringTableEntryB\x02\x18\x01\"Q\n\rChromeTrigger\x12\x14\n\x0ctrigger_name\x18\x01 \x01(\t\x12\x19\n\x11trigger_name_hash\x18\x02 \x01(\x07\x12\x0f\n\x07\x66low_id\x18\x03 \x01(\x06\"V\n\x08V8String\x12\x10\n\x06latin1\x18\x01 \x01(\x0cH\x00\x12\x12\n\x08utf16_le\x18\x02 \x01(\x0cH\x00\x12\x12\n\x08utf16_be\x18\x03 \x01(\x0cH\x00\x42\x10\n\x0e\x65ncoded_string\"k\n\x10InternedV8String\x12\x0b\n\x03iid\x18\x01 \x01(\x04\x12\x10\n\x06latin1\x18\x02 \x01(\x0cH\x00\x12\x12\n\x08utf16_le\x18\x03 \x01(\x0cH\x00\x12\x12\n\x08utf16_be\x18\x04 \x01(\x0cH\x00\x42\x10\n\x0e\x65ncoded_string\"\xc5\x02\n\x12InternedV8JsScript\x12\x0b\n\x03iid\x18\x01 \x01(\x04\x12\x11\n\tscript_id\x18\x02 \x01(\x05\x12\x36\n\x04type\x18\x03 \x01(\x0e\x32(.perfetto.protos.InternedV8JsScript.Type\x12\'\n\x04name\x18\x04 \x01(\x0b\x32\x19.perfetto.protos.V8String\x12)\n\x06source\x18\x05 \x01(\x0b\x32\x19.perfetto.protos.V8String\"\x82\x01\n\x04Type\x12\x10\n\x0cTYPE_UNKNOWN\x10\x00\x12\x0f\n\x0bTYPE_NORMAL\x10\x01\x12\r\n\tTYPE_EVAL\x10\x02\x12\x0f\n\x0bTYPE_MODULE\x10\x03\x12\x0f\n\x0bTYPE_NATIVE\x10\x04\x12\x12\n\x0eTYPE_EXTENSION\x10\x05\x12\x12\n\x0eTYPE_INSPECTOR\x10\x06\"W\n\x14InternedV8WasmScript\x12\x0b\n\x03iid\x18\x01 \x01(\x04\x12\x11\n\tscript_id\x18\x02 \x01(\x05\x12\x0b\n\x03url\x18\x03 \x01(\t\x12\x12\n\nwire_bytes\x18\x04 \x01(\x0c\"\xd5\x08\n\x14InternedV8JsFunction\x12\x0b\n\x03iid\x18\x01 \x01(\x04\x12\x1f\n\x17v8_js_function_name_iid\x18\x02 \x01(\x04\x12\x18\n\x10v8_js_script_iid\x18\x03 \x01(\x04\x12\x13\n\x0bis_toplevel\x18\x04 \x01(\x08\x12\x38\n\x04kind\x18\x05 \x01(\x0e\x32*.perfetto.protos.InternedV8JsFunction.Kind\x12\x13\n\x0b\x62yte_offset\x18\x06 \x01(\r\x12\x0c\n\x04line\x18\x07 \x01(\r\x12\x0e\n\x06\x63olumn\x18\x08 \x01(\r\"\xf2\x06\n\x04Kind\x12\x10\n\x0cKIND_UNKNOWN\x10\x00\x12\x18\n\x14KIND_NORMAL_FUNCTION\x10\x01\x12\x0f\n\x0bKIND_MODULE\x10\x02\x12\x15\n\x11KIND_ASYNC_MODULE\x10\x03\x12\x19\n\x15KIND_BASE_CONSTRUCTOR\x10\x04\x12!\n\x1dKIND_DEFAULT_BASE_CONSTRUCTOR\x10\x05\x12$\n KIND_DEFAULT_DERIVED_CONSTRUCTOR\x10\x06\x12\x1c\n\x18KIND_DERIVED_CONSTRUCTOR\x10\x07\x12\x18\n\x14KIND_GETTER_FUNCTION\x10\x08\x12\x1f\n\x1bKIND_STATIC_GETTER_FUNCTION\x10\t\x12\x18\n\x14KIND_SETTER_FUNCTION\x10\n\x12\x1f\n\x1bKIND_STATIC_SETTER_FUNCTION\x10\x0b\x12\x17\n\x13KIND_ARROW_FUNCTION\x10\x0c\x12\x1d\n\x19KIND_ASYNC_ARROW_FUNCTION\x10\r\x12\x17\n\x13KIND_ASYNC_FUNCTION\x10\x0e\x12\x1d\n\x19KIND_ASYNC_CONCISE_METHOD\x10\x0f\x12$\n KIND_STATIC_ASYNC_CONCISE_METHOD\x10\x10\x12\'\n#KIND_ASYNC_CONCISE_GENERATOR_METHOD\x10\x11\x12.\n*KIND_STATIC_ASYNC_CONCISE_GENERATOR_METHOD\x10\x12\x12!\n\x1dKIND_ASYNC_GENERATOR_FUNCTION\x10\x13\x12\x1b\n\x17KIND_GENERATOR_FUNCTION\x10\x14\x12!\n\x1dKIND_CONCISE_GENERATOR_METHOD\x10\x15\x12(\n$KIND_STATIC_CONCISE_GENERATOR_METHOD\x10\x16\x12\x17\n\x13KIND_CONCISE_METHOD\x10\x17\x12\x1e\n\x1aKIND_STATIC_CONCISE_METHOD\x10\x18\x12+\n\'KIND_CLASS_MEMBERS_INITIALIZER_FUNCTION\x10\x19\x12*\n&KIND_CLASS_STATIC_INITIALIZER_FUNCTION\x10\x1a\x12\x10\n\x0cKIND_INVALID\x10\x1b\"\xc7\x02\n\x11InternedV8Isolate\x12\x0b\n\x03iid\x18\x01 \x01(\x04\x12\x0b\n\x03pid\x18\x02 \x01(\r\x12\x12\n\nisolate_id\x18\x03 \x01(\x05\x12@\n\ncode_range\x18\x04 \x01(\x0b\x32,.perfetto.protos.InternedV8Isolate.CodeRange\x12(\n embedded_blob_code_start_address\x18\x05 \x01(\x04\x12\x1f\n\x17\x65mbedded_blob_code_size\x18\x06 \x01(\x04\x1aw\n\tCodeRange\x12\x14\n\x0c\x62\x61se_address\x18\x01 \x01(\x04\x12\x0c\n\x04size\x18\x02 \x01(\x04\x12-\n%embedded_blob_code_copy_start_address\x18\x03 \x01(\x04\x12\x17\n\x0fis_process_wide\x18\x04 \x01(\x08\"\xd8\x03\n\x08V8JsCode\x12\x16\n\x0ev8_isolate_iid\x18\x01 \x01(\x04\x12\x0b\n\x03tid\x18\x02 \x01(\r\x12\x1a\n\x12v8_js_function_iid\x18\x03 \x01(\x04\x12,\n\x04tier\x18\x04 \x01(\x0e\x32\x1e.perfetto.protos.V8JsCode.Tier\x12\x19\n\x11instruction_start\x18\x05 \x01(\x04\x12\x1e\n\x16instruction_size_bytes\x18\x06 \x01(\x04\x12\x16\n\x0cmachine_code\x18\x07 \x01(\x0cH\x00\x12\x12\n\x08\x62ytecode\x18\x08 \x01(\x0cH\x00\x12\x1a\n\x10source_positions\x18\t \x01(\x0cH\x01\x12\x1c\n\x12\x62ytecode_positions\x18\n \x01(\x0cH\x01\x12$\n\x1ainlined_bytecode_positions\x18\x0b \x01(\x0cH\x01\"x\n\x04Tier\x12\x10\n\x0cTIER_UNKNOWN\x10\x00\x12\x11\n\rTIER_IGNITION\x10\x01\x12\x12\n\x0eTIER_SPARKPLUG\x10\x02\x12\x0f\n\x0bTIER_MAGLEV\x10\x03\x12\x13\n\x0fTIER_TURBOSHAFT\x10\x04\x12\x11\n\rTIER_TURBOFAN\x10\x05\x42\x0e\n\x0cinstructionsB\x0c\n\nsource_map\"\xe1\x03\n\x0eV8InternalCode\x12\x16\n\x0ev8_isolate_iid\x18\x01 \x01(\x04\x12\x0b\n\x03tid\x18\x02 \x01(\r\x12\x0c\n\x04name\x18\x03 \x01(\t\x12\x32\n\x04type\x18\x04 \x01(\x0e\x32$.perfetto.protos.V8InternalCode.Type\x12\x12\n\nbuiltin_id\x18\x05 \x01(\x05\x12\x19\n\x11instruction_start\x18\x06 \x01(\x04\x12\x1e\n\x16instruction_size_bytes\x18\x07 \x01(\x04\x12\x14\n\x0cmachine_code\x18\x08 \x01(\x0c\"\x82\x02\n\x04Type\x12\x10\n\x0cTYPE_UNKNOWN\x10\x00\x12\x19\n\x15TYPE_BYTECODE_HANDLER\x10\x01\x12\x14\n\x10TYPE_FOR_TESTING\x10\x02\x12\x10\n\x0cTYPE_BUILTIN\x10\x03\x12\x16\n\x12TYPE_WASM_FUNCTION\x10\x04\x12\x1e\n\x1aTYPE_WASM_TO_CAPI_FUNCTION\x10\x05\x12\x1c\n\x18TYPE_WASM_TO_JS_FUNCTION\x10\x06\x12\x1c\n\x18TYPE_JS_TO_WASM_FUNCTION\x10\x07\x12\x1a\n\x16TYPE_JS_TO_JS_FUNCTION\x10\x08\x12\x15\n\x11TYPE_C_WASM_ENTRY\x10\t\"\xc3\x02\n\nV8WasmCode\x12\x16\n\x0ev8_isolate_iid\x18\x01 \x01(\x04\x12\x0b\n\x03tid\x18\x02 \x01(\r\x12\x1a\n\x12v8_wasm_script_iid\x18\x03 \x01(\x04\x12\x15\n\rfunction_name\x18\x04 \x01(\t\x12.\n\x04tier\x18\x05 \x01(\x0e\x32 .perfetto.protos.V8WasmCode.Tier\x12\x1d\n\x15\x63ode_offset_in_module\x18\x06 \x01(\x05\x12\x19\n\x11instruction_start\x18\x07 \x01(\x04\x12\x1e\n\x16instruction_size_bytes\x18\x08 \x01(\x04\x12\x14\n\x0cmachine_code\x18\t \x01(\x0c\"=\n\x04Tier\x12\x10\n\x0cTIER_UNKNOWN\x10\x00\x12\x10\n\x0cTIER_LIFTOFF\x10\x01\x12\x11\n\rTIER_TURBOFAN\x10\x02\"\xb0\x01\n\x0cV8RegExpCode\x12\x16\n\x0ev8_isolate_iid\x18\x01 \x01(\x04\x12\x0b\n\x03tid\x18\x02 \x01(\r\x12*\n\x07pattern\x18\x03 \x01(\x0b\x32\x19.perfetto.protos.V8String\x12\x19\n\x11instruction_start\x18\x04 \x01(\x04\x12\x1e\n\x16instruction_size_bytes\x18\x05 \x01(\x04\x12\x14\n\x0cmachine_code\x18\x06 \x01(\x0c\"\xe1\x01\n\nV8CodeMove\x12\x13\n\x0bisolate_iid\x18\x01 \x01(\x04\x12\x0b\n\x03tid\x18\x02 \x01(\r\x12&\n\x1e\x66rom_instruction_start_address\x18\x03 \x01(\x04\x12$\n\x1cto_instruction_start_address\x18\x04 \x01(\x04\x12\x1e\n\x16instruction_size_bytes\x18\x05 \x01(\x04\x12\x19\n\x0fto_machine_code\x18\x06 \x01(\x0cH\x00\x12\x15\n\x0bto_bytecode\x18\x07 \x01(\x0cH\x00\x42\x11\n\x0fto_instructions\"\x1d\n\x0eV8CodeDefaults\x12\x0b\n\x03tid\x18\x01 \x01(\r\"\x92\x03\n\rClockSnapshot\x12\x34\n\x06\x63locks\x18\x01 \x03(\x0b\x32$.perfetto.protos.ClockSnapshot.Clock\x12:\n\x13primary_trace_clock\x18\x02 \x01(\x0e\x32\x1d.perfetto.protos.BuiltinClock\x1a\x8e\x02\n\x05\x43lock\x12\x10\n\x08\x63lock_id\x18\x01 \x01(\r\x12\x11\n\ttimestamp\x18\x02 \x01(\x04\x12\x16\n\x0eis_incremental\x18\x03 \x01(\x08\x12\x1a\n\x12unit_multiplier_ns\x18\x04 \x01(\x04\"\xab\x01\n\rBuiltinClocks\x12\x0b\n\x07UNKNOWN\x10\x00\x12\x0c\n\x08REALTIME\x10\x01\x12\x13\n\x0fREALTIME_COARSE\x10\x02\x12\r\n\tMONOTONIC\x10\x03\x12\x14\n\x10MONOTONIC_COARSE\x10\x04\x12\x11\n\rMONOTONIC_RAW\x10\x05\x12\x0c\n\x08\x42OOTTIME\x10\x06\x12\x18\n\x14\x42UILTIN_CLOCK_MAX_ID\x10?\"\x04\x08\x07\x10\x07\"\x04\x08\x08\x10\x08\"\xd2\x0c\n\x0f\x43SwitchEtwEvent\x12\x15\n\rnew_thread_id\x18\x01 \x01(\r\x12\x15\n\rold_thread_id\x18\x02 \x01(\r\x12\x1b\n\x13new_thread_priority\x18\x03 \x01(\x11\x12\x1b\n\x13old_thread_priority\x18\x04 \x01(\x11\x12\x18\n\x10previous_c_state\x18\x05 \x01(\r\x12V\n\x16old_thread_wait_reason\x18\x06 \x01(\x0e\x32\x34.perfetto.protos.CSwitchEtwEvent.OldThreadWaitReasonH\x00\x12$\n\x1aold_thread_wait_reason_int\x18\x0b \x01(\x05H\x00\x12R\n\x14old_thread_wait_mode\x18\x07 \x01(\x0e\x32\x32.perfetto.protos.CSwitchEtwEvent.OldThreadWaitModeH\x01\x12\"\n\x18old_thread_wait_mode_int\x18\x0c \x01(\x05H\x01\x12K\n\x10old_thread_state\x18\x08 \x01(\x0e\x32/.perfetto.protos.CSwitchEtwEvent.OldThreadStateH\x02\x12\x1e\n\x14old_thread_state_int\x18\r \x01(\x11H\x02\x12\'\n\x1fold_thread_wait_ideal_processor\x18\t \x01(\x11\x12\x1c\n\x14new_thread_wait_time\x18\n \x01(\r\"\xe9\x05\n\x13OldThreadWaitReason\x12\r\n\tEXECUTIVE\x10\x00\x12\r\n\tFREE_PAGE\x10\x01\x12\x0b\n\x07PAGE_IN\x10\x02\x12\x13\n\x0fPOOL_ALLOCATION\x10\x03\x12\x13\n\x0f\x44\x45LAY_EXECUTION\x10\x04\x12\x0b\n\x07SUSPEND\x10\x05\x12\x10\n\x0cUSER_REQUEST\x10\x06\x12\x10\n\x0cWR_EXECUTIVE\x10\x07\x12\x10\n\x0cWR_FREE_PAGE\x10\x08\x12\x0e\n\nWR_PAGE_IN\x10\t\x12\x16\n\x12WR_POOL_ALLOCATION\x10\n\x12\x16\n\x12WR_DELAY_EXECUTION\x10\x0b\x12\x10\n\x0cWR_SUSPENDED\x10\x0c\x12\x13\n\x0fWR_USER_REQUEST\x10\r\x12\x11\n\rWR_EVENT_PAIR\x10\x0e\x12\x0c\n\x08WR_QUEUE\x10\x0f\x12\x13\n\x0fWR_LPC_RECEIVER\x10\x10\x12\x10\n\x0cWR_LPC_REPLY\x10\x11\x12\x15\n\x11WR_VIRTUAL_MEMORY\x10\x12\x12\x0f\n\x0bWR_PAGE_OUT\x10\x13\x12\x12\n\x0eWR_RENDEZ_VOUS\x10\x14\x12\x12\n\x0eWR_KEYED_EVENT\x10\x15\x12\x11\n\rWR_TERMINATED\x10\x16\x12\x16\n\x12WR_PROCESS_IN_SWAP\x10\x17\x12\x17\n\x13WR_CPU_RATE_CONTROL\x10\x18\x12\x14\n\x10WR_CALLOUT_STACK\x10\x19\x12\r\n\tWR_KERNEL\x10\x1a\x12\x0f\n\x0bWR_RESOURCE\x10\x1b\x12\x10\n\x0cWR_PUSH_LOCK\x10\x1c\x12\x0c\n\x08WR_MUTEX\x10\x1d\x12\x12\n\x0eWR_QUANTUM_END\x10\x1e\x12\x13\n\x0fWR_DISPATCH_INT\x10\x1f\x12\x10\n\x0cWR_PREEMPTED\x10 \x12\x16\n\x12WR_YIELD_EXECUTION\x10!\x12\x11\n\rWR_FAST_MUTEX\x10\"\x12\x12\n\x0eWR_GUARD_MUTEX\x10#\x12\x0e\n\nWR_RUNDOWN\x10$\x12\x17\n\x13MAXIMUM_WAIT_REASON\x10%\"3\n\x11OldThreadWaitMode\x12\x0f\n\x0bKERNEL_MODE\x10\x00\x12\r\n\tUSER_MODE\x10\x01\"\x87\x01\n\x0eOldThreadState\x12\x0f\n\x0bINITIALIZED\x10\x00\x12\t\n\x05READY\x10\x01\x12\x0b\n\x07RUNNING\x10\x02\x12\x0b\n\x07STANDBY\x10\x03\x12\x0e\n\nTERMINATED\x10\x04\x12\x0b\n\x07WAITING\x10\x05\x12\x0e\n\nTRANSITION\x10\x06\x12\x12\n\x0e\x44\x45\x46\x45RRED_READY\x10\x07\x42$\n\"old_thread_wait_reason_enum_or_intB\"\n old_thread_wait_mode_enum_or_intB\x1e\n\x1cold_thread_state_enum_or_int\"\x88\x04\n\x13ReadyThreadEtwEvent\x12\x13\n\x0bt_thread_id\x18\x01 \x01(\r\x12J\n\radjust_reason\x18\x02 \x01(\x0e\x32\x31.perfetto.protos.ReadyThreadEtwEvent.AdjustReasonH\x00\x12\x1b\n\x11\x61\x64just_reason_int\x18\x05 \x01(\x05H\x00\x12\x18\n\x10\x61\x64just_increment\x18\x03 \x01(\x11\x12>\n\x04\x66lag\x18\x04 \x01(\x0e\x32..perfetto.protos.ReadyThreadEtwEvent.TraceFlagH\x01\x12\x12\n\x08\x66lag_int\x18\x06 \x01(\x05H\x01\"X\n\x0c\x41\x64justReason\x12\x18\n\x14IGNORE_THE_INCREMENT\x10\x00\x12\x13\n\x0f\x41PPLY_INCREMENT\x10\x01\x12\x19\n\x15\x41PPLY_INCREMENT_BOOST\x10\x02\"z\n\tTraceFlag\x12\x1a\n\x16TRACE_FLAG_UNSPECIFIED\x10\x00\x12\x12\n\x0eTHREAD_READIED\x10\x01\x12\x1c\n\x18KERNEL_STACK_SWAPPED_OUT\x10\x02\x12\x1f\n\x1bPROCESS_ADDRESS_SWAPPED_OUT\x10\x04\x42\x1b\n\x19\x61\x64just_reason_enum_or_intB\x12\n\x10\x66lag_enum_or_int\"\x90\x03\n\x0fMemInfoEtwEvent\x12\x17\n\x0fpriority_levels\x18\x01 \x01(\r\x12\x17\n\x0fzero_page_count\x18\x02 \x01(\x04\x12\x17\n\x0f\x66ree_page_count\x18\x03 \x01(\x04\x12\x1b\n\x13modified_page_count\x18\x04 \x01(\x04\x12$\n\x1cmodified_no_write_page_count\x18\x05 \x01(\x04\x12\x16\n\x0e\x62\x61\x64_page_count\x18\x06 \x01(\x04\x12\x1b\n\x13standby_page_counts\x18\x07 \x03(\x04\x12\x1e\n\x16repurposed_page_counts\x18\x08 \x03(\x04\x12%\n\x1dmodified_page_count_page_file\x18\t \x01(\x04\x12\x1d\n\x15paged_pool_page_count\x18\n \x01(\x04\x12!\n\x19non_paged_pool_page_count\x18\x0b \x01(\x04\x12\x16\n\x0emdl_page_count\x18\x0c \x01(\x04\x12\x19\n\x11\x63ommit_page_count\x18\r \x01(\x04\"\xa4\x01\n\x14\x46ileIoCreateEtwEvent\x12\x0f\n\x07irp_ptr\x18\x01 \x01(\x04\x12\x13\n\x0b\x66ile_object\x18\x02 \x01(\x04\x12\x0c\n\x04ttid\x18\x03 \x01(\r\x12\x16\n\x0e\x63reate_options\x18\x04 \x01(\r\x12\x17\n\x0f\x66ile_attributes\x18\x05 \x01(\r\x12\x14\n\x0cshare_access\x18\x06 \x01(\r\x12\x11\n\topen_path\x18\x07 \x01(\t\"\xb8\x01\n\x15\x46ileIoDirEnumEtwEvent\x12\x0f\n\x07irp_ptr\x18\x01 \x01(\x04\x12\x13\n\x0b\x66ile_object\x18\x02 \x01(\x04\x12\x10\n\x08\x66ile_key\x18\x03 \x01(\x04\x12\x0c\n\x04ttid\x18\x04 \x01(\r\x12\x0e\n\x06length\x18\x05 \x01(\r\x12\x12\n\ninfo_class\x18\x06 \x01(\r\x12\x12\n\nfile_index\x18\x07 \x01(\r\x12\x11\n\tfile_name\x18\x08 \x01(\t\x12\x0e\n\x06opcode\x18\t \x01(\r\"\x92\x01\n\x12\x46ileIoInfoEtwEvent\x12\x0f\n\x07irp_ptr\x18\x01 \x01(\x04\x12\x13\n\x0b\x66ile_object\x18\x02 \x01(\x04\x12\x10\n\x08\x66ile_key\x18\x03 \x01(\x04\x12\x12\n\nextra_info\x18\x04 \x01(\x04\x12\x0c\n\x04ttid\x18\x05 \x01(\r\x12\x12\n\ninfo_class\x18\x06 \x01(\r\x12\x0e\n\x06opcode\x18\x07 \x01(\r\"\xa2\x01\n\x17\x46ileIoReadWriteEtwEvent\x12\x0e\n\x06offset\x18\x01 \x01(\x04\x12\x0f\n\x07irp_ptr\x18\x02 \x01(\x04\x12\x13\n\x0b\x66ile_object\x18\x03 \x01(\x04\x12\x10\n\x08\x66ile_key\x18\x04 \x01(\x04\x12\x0c\n\x04ttid\x18\x05 \x01(\r\x12\x0f\n\x07io_size\x18\x06 \x01(\r\x12\x10\n\x08io_flags\x18\x07 \x01(\r\x12\x0e\n\x06opcode\x18\x08 \x01(\r\"n\n\x16\x46ileIoSimpleOpEtwEvent\x12\x0f\n\x07irp_ptr\x18\x01 \x01(\x04\x12\x13\n\x0b\x66ile_object\x18\x02 \x01(\x04\x12\x10\n\x08\x66ile_key\x18\x03 \x01(\x04\x12\x0c\n\x04ttid\x18\x04 \x01(\r\x12\x0e\n\x06opcode\x18\x05 \x01(\r\"M\n\x13\x46ileIoOpEndEtwEvent\x12\x0f\n\x07irp_ptr\x18\x01 \x01(\x04\x12\x12\n\nextra_info\x18\x02 \x01(\x04\x12\x11\n\tnt_status\x18\x03 \x01(\r\"\xae\x01\n\x1b\x46ileIoPathOperationEtwEvent\x12\x0f\n\x07irp_ptr\x18\x01 \x01(\x04\x12\x13\n\x0b\x66ile_object\x18\x02 \x01(\x04\x12\x10\n\x08\x66ile_key\x18\x03 \x01(\x04\x12\x12\n\nextra_info\x18\x04 \x01(\x04\x12\x0c\n\x04ttid\x18\x05 \x01(\r\x12\x12\n\ninfo_class\x18\x06 \x01(\r\x12\x11\n\tfile_name\x18\x07 \x01(\t\x12\x0e\n\x06opcode\x18\x08 \x01(\r\";\n\x11StackWalkEtwEvent\x12\x0f\n\x07trigger\x18\x01 \x01(\t\x12\x15\n\rcallstack_iid\x18\x02 \x01(\x04\"\xcc\x01\n\x0e\x44iskIoEtwEvent\x12\x13\n\x0b\x64isk_number\x18\x01 \x01(\r\x12\x11\n\tirp_flags\x18\x02 \x01(\r\x12\x15\n\rtransfer_size\x18\x03 \x01(\r\x12\x13\n\x0b\x62yte_offset\x18\x04 \x01(\x03\x12\x13\n\x0b\x66ile_object\x18\x05 \x01(\x04\x12\x0f\n\x07irp_ptr\x18\x06 \x01(\x04\x12\x15\n\rresponse_time\x18\x07 \x01(\x03\x12\x19\n\x11issuing_thread_id\x18\x08 \x01(\r\x12\x0e\n\x06opcode\x18\t \x01(\r\"\xc3\x06\n\rEtwTraceEvent\x12\x11\n\ttimestamp\x18\x01 \x01(\x04\x12\x0b\n\x03\x63pu\x18\x04 \x01(\r\x12\x11\n\tthread_id\x18\x05 \x01(\r\x12\x34\n\x08\x63_switch\x18\x02 \x01(\x0b\x32 .perfetto.protos.CSwitchEtwEventH\x00\x12<\n\x0cready_thread\x18\x03 \x01(\x0b\x32$.perfetto.protos.ReadyThreadEtwEventH\x00\x12\x34\n\x08mem_info\x18\x06 \x01(\x0b\x32 .perfetto.protos.MemInfoEtwEventH\x00\x12?\n\x0e\x66ile_io_create\x18\x07 \x01(\x0b\x32%.perfetto.protos.FileIoCreateEtwEventH\x00\x12\x42\n\x10\x66ile_io_dir_enum\x18\x08 \x01(\x0b\x32&.perfetto.protos.FileIoDirEnumEtwEventH\x00\x12;\n\x0c\x66ile_io_info\x18\t \x01(\x0b\x32#.perfetto.protos.FileIoInfoEtwEventH\x00\x12\x46\n\x12\x66ile_io_read_write\x18\n \x01(\x0b\x32(.perfetto.protos.FileIoReadWriteEtwEventH\x00\x12\x44\n\x11\x66ile_io_simple_op\x18\x0b \x01(\x0b\x32\'.perfetto.protos.FileIoSimpleOpEtwEventH\x00\x12>\n\x0e\x66ile_io_op_end\x18\x0c \x01(\x0b\x32$.perfetto.protos.FileIoOpEndEtwEventH\x00\x12\x38\n\nstack_walk\x18\r \x01(\x0b\x32\".perfetto.protos.StackWalkEtwEventH\x00\x12N\n\x16\x66ile_io_path_operation\x18\x0e \x01(\x0b\x32,.perfetto.protos.FileIoPathOperationEtwEventH\x00\x12\x32\n\x07\x64isk_io\x18\x0f \x01(\x0b\x32\x1f.perfetto.protos.DiskIoEtwEventH\x00\x42\x07\n\x05\x65vent\"Q\n\x13\x45twTraceEventBundle\x12\x0b\n\x03\x63pu\x18\x01 \x01(\r\x12-\n\x05\x65vent\x18\x02 \x03(\x0b\x32\x1e.perfetto.protos.EtwTraceEvent\"G\n\x11\x46ileDescriptorSet\x12\x32\n\x04\x66ile\x18\x01 \x03(\x0b\x32$.perfetto.protos.FileDescriptorProto\"\xbf\x02\n\x13\x46ileDescriptorProto\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0f\n\x07package\x18\x02 \x01(\t\x12\x12\n\ndependency\x18\x03 \x03(\t\x12\x19\n\x11public_dependency\x18\n \x03(\x05\x12\x17\n\x0fweak_dependency\x18\x0b \x03(\x05\x12\x36\n\x0cmessage_type\x18\x04 \x03(\x0b\x32 .perfetto.protos.DescriptorProto\x12\x37\n\tenum_type\x18\x05 \x03(\x0b\x32$.perfetto.protos.EnumDescriptorProto\x12\x38\n\textension\x18\x07 \x03(\x0b\x32%.perfetto.protos.FieldDescriptorProtoJ\x04\x08\x06\x10\x07J\x04\x08\x08\x10\tJ\x04\x08\t\x10\nJ\x04\x08\x0c\x10\r\"\xd2\x03\n\x0f\x44\x65scriptorProto\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x34\n\x05\x66ield\x18\x02 \x03(\x0b\x32%.perfetto.protos.FieldDescriptorProto\x12\x38\n\textension\x18\x06 \x03(\x0b\x32%.perfetto.protos.FieldDescriptorProto\x12\x35\n\x0bnested_type\x18\x03 \x03(\x0b\x32 .perfetto.protos.DescriptorProto\x12\x37\n\tenum_type\x18\x04 \x03(\x0b\x32$.perfetto.protos.EnumDescriptorProto\x12\x39\n\noneof_decl\x18\x08 \x03(\x0b\x32%.perfetto.protos.OneofDescriptorProto\x12\x46\n\x0ereserved_range\x18\t \x03(\x0b\x32..perfetto.protos.DescriptorProto.ReservedRange\x12\x15\n\rreserved_name\x18\n \x03(\t\x1a+\n\rReservedRange\x12\r\n\x05start\x18\x01 \x01(\x05\x12\x0b\n\x03\x65nd\x18\x02 \x01(\x05J\x04\x08\x05\x10\x06J\x04\x08\x07\x10\x08\"\x9e\x02\n\x13UninterpretedOption\x12;\n\x04name\x18\x02 \x03(\x0b\x32-.perfetto.protos.UninterpretedOption.NamePart\x12\x18\n\x10identifier_value\x18\x03 \x01(\t\x12\x1a\n\x12positive_int_value\x18\x04 \x01(\x04\x12\x1a\n\x12negative_int_value\x18\x05 \x01(\x03\x12\x14\n\x0c\x64ouble_value\x18\x06 \x01(\x01\x12\x14\n\x0cstring_value\x18\x07 \x01(\x0c\x12\x17\n\x0f\x61ggregate_value\x18\x08 \x01(\t\x1a\x33\n\x08NamePart\x12\x11\n\tname_part\x18\x01 \x01(\t\x12\x14\n\x0cis_extension\x18\x02 \x01(\x08\"c\n\x0c\x46ieldOptions\x12\x0e\n\x06packed\x18\x02 \x01(\x08\x12\x43\n\x14uninterpreted_option\x18\xe7\x07 \x03(\x0b\x32$.perfetto.protos.UninterpretedOption\"\xaf\x05\n\x14\x46ieldDescriptorProto\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0e\n\x06number\x18\x03 \x01(\x05\x12:\n\x05label\x18\x04 \x01(\x0e\x32+.perfetto.protos.FieldDescriptorProto.Label\x12\x38\n\x04type\x18\x05 \x01(\x0e\x32*.perfetto.protos.FieldDescriptorProto.Type\x12\x11\n\ttype_name\x18\x06 \x01(\t\x12\x10\n\x08\x65xtendee\x18\x02 \x01(\t\x12\x15\n\rdefault_value\x18\x07 \x01(\t\x12.\n\x07options\x18\x08 \x01(\x0b\x32\x1d.perfetto.protos.FieldOptions\x12\x13\n\x0boneof_index\x18\t \x01(\x05\"\xb6\x02\n\x04Type\x12\x0f\n\x0bTYPE_DOUBLE\x10\x01\x12\x0e\n\nTYPE_FLOAT\x10\x02\x12\x0e\n\nTYPE_INT64\x10\x03\x12\x0f\n\x0bTYPE_UINT64\x10\x04\x12\x0e\n\nTYPE_INT32\x10\x05\x12\x10\n\x0cTYPE_FIXED64\x10\x06\x12\x10\n\x0cTYPE_FIXED32\x10\x07\x12\r\n\tTYPE_BOOL\x10\x08\x12\x0f\n\x0bTYPE_STRING\x10\t\x12\x0e\n\nTYPE_GROUP\x10\n\x12\x10\n\x0cTYPE_MESSAGE\x10\x0b\x12\x0e\n\nTYPE_BYTES\x10\x0c\x12\x0f\n\x0bTYPE_UINT32\x10\r\x12\r\n\tTYPE_ENUM\x10\x0e\x12\x11\n\rTYPE_SFIXED32\x10\x0f\x12\x11\n\rTYPE_SFIXED64\x10\x10\x12\x0f\n\x0bTYPE_SINT32\x10\x11\x12\x0f\n\x0bTYPE_SINT64\x10\x12\"C\n\x05Label\x12\x12\n\x0eLABEL_OPTIONAL\x10\x01\x12\x12\n\x0eLABEL_REQUIRED\x10\x02\x12\x12\n\x0eLABEL_REPEATED\x10\x03J\x04\x08\n\x10\x0b\"T\n\x14OneofDescriptorProto\x12\x0c\n\x04name\x18\x01 \x01(\t\x12.\n\x07options\x18\x02 \x01(\x0b\x32\x1d.perfetto.protos.OneofOptions\"\x80\x01\n\x13\x45numDescriptorProto\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x38\n\x05value\x18\x02 \x03(\x0b\x32).perfetto.protos.EnumValueDescriptorProto\x12\x15\n\rreserved_name\x18\x05 \x03(\tJ\x04\x08\x03\x10\x04J\x04\x08\x04\x10\x05\">\n\x18\x45numValueDescriptorProto\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0e\n\x06number\x18\x02 \x01(\x05J\x04\x08\x03\x10\x04\"!\n\x0cOneofOptions*\t\x08\xe8\x07\x10\x80\x80\x80\x80\x02J\x06\x08\xe7\x07\x10\xe8\x07\"\x91\x01\n\x13\x45xtensionDescriptor\x12;\n\rextension_set\x18\x01 \x01(\x0b\x32\".perfetto.protos.FileDescriptorSetH\x00\x12\x1c\n\x12\x65xtension_set_gzip\x18\x02 \x01(\x0cH\x00\x12\x11\n\tfile_name\x18\x03 \x01(\tB\x0c\n\ndescriptor\"\x88\x02\n\x0cInodeFileMap\x12\x17\n\x0f\x62lock_device_id\x18\x01 \x01(\x04\x12\x14\n\x0cmount_points\x18\x02 \x03(\t\x12\x34\n\x07\x65ntries\x18\x03 \x03(\x0b\x32#.perfetto.protos.InodeFileMap.Entry\x1a\x92\x01\n\x05\x45ntry\x12\x14\n\x0cinode_number\x18\x01 \x01(\x04\x12\r\n\x05paths\x18\x02 \x03(\t\x12\x36\n\x04type\x18\x03 \x01(\x0e\x32(.perfetto.protos.InodeFileMap.Entry.Type\",\n\x04Type\x12\x0b\n\x07UNKNOWN\x10\x00\x12\x08\n\x04\x46ILE\x10\x01\x12\r\n\tDIRECTORY\x10\x02\"M\n\x1f\x41ndroidFsDatareadEndFtraceEvent\x12\r\n\x05\x62ytes\x18\x01 \x01(\x05\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x0e\n\x06offset\x18\x03 \x01(\x03\"\x8e\x01\n!AndroidFsDatareadStartFtraceEvent\x12\r\n\x05\x62ytes\x18\x01 \x01(\x05\x12\x0f\n\x07\x63mdline\x18\x02 \x01(\t\x12\x0e\n\x06i_size\x18\x03 \x01(\x03\x12\x0b\n\x03ino\x18\x04 \x01(\x04\x12\x0e\n\x06offset\x18\x05 \x01(\x03\x12\x0f\n\x07pathbuf\x18\x06 \x01(\t\x12\x0b\n\x03pid\x18\x07 \x01(\x05\"N\n AndroidFsDatawriteEndFtraceEvent\x12\r\n\x05\x62ytes\x18\x01 \x01(\x05\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x0e\n\x06offset\x18\x03 \x01(\x03\"\x8f\x01\n\"AndroidFsDatawriteStartFtraceEvent\x12\r\n\x05\x62ytes\x18\x01 \x01(\x05\x12\x0f\n\x07\x63mdline\x18\x02 \x01(\t\x12\x0e\n\x06i_size\x18\x03 \x01(\x03\x12\x0b\n\x03ino\x18\x04 \x01(\x04\x12\x0e\n\x06offset\x18\x05 \x01(\x03\x12\x0f\n\x07pathbuf\x18\x06 \x01(\t\x12\x0b\n\x03pid\x18\x07 \x01(\x05\"J\n\x1c\x41ndroidFsFsyncEndFtraceEvent\x12\r\n\x05\x62ytes\x18\x01 \x01(\x05\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x0e\n\x06offset\x18\x03 \x01(\x03\"l\n\x1e\x41ndroidFsFsyncStartFtraceEvent\x12\x0f\n\x07\x63mdline\x18\x01 \x01(\t\x12\x0e\n\x06i_size\x18\x02 \x01(\x03\x12\x0b\n\x03ino\x18\x03 \x01(\x04\x12\x0f\n\x07pathbuf\x18\x04 \x01(\t\x12\x0b\n\x03pid\x18\x05 \x01(\x05\"\xbd\x01\n\x18\x42\x63lIrqTriggerFtraceEvent\x12\n\n\x02id\x18\x01 \x01(\x05\x12\x10\n\x08throttle\x18\x02 \x01(\x05\x12\x12\n\ncpu0_limit\x18\x03 \x01(\x05\x12\x12\n\ncpu1_limit\x18\x04 \x01(\x05\x12\x12\n\ncpu2_limit\x18\x05 \x01(\x05\x12\x11\n\ttpu_limit\x18\x06 \x01(\x05\x12\x11\n\tgpu_limit\x18\x07 \x01(\x05\x12\x0f\n\x07voltage\x18\x08 \x01(\x05\x12\x10\n\x08\x63\x61pacity\x18\t \x01(\x05\"\x95\x01\n\x1c\x42inderTransactionFtraceEvent\x12\x10\n\x08\x64\x65\x62ug_id\x18\x01 \x01(\x05\x12\x13\n\x0btarget_node\x18\x02 \x01(\x05\x12\x0f\n\x07to_proc\x18\x03 \x01(\x05\x12\x11\n\tto_thread\x18\x04 \x01(\x05\x12\r\n\x05reply\x18\x05 \x01(\x05\x12\x0c\n\x04\x63ode\x18\x06 \x01(\r\x12\r\n\x05\x66lags\x18\x07 \x01(\r\"8\n$BinderTransactionReceivedFtraceEvent\x12\x10\n\x08\x64\x65\x62ug_id\x18\x01 \x01(\x05\"v\n\x1c\x42inderSetPriorityFtraceEvent\x12\x0c\n\x04proc\x18\x01 \x01(\x05\x12\x0e\n\x06thread\x18\x02 \x01(\x05\x12\x10\n\x08old_prio\x18\x03 \x01(\r\x12\x10\n\x08new_prio\x18\x04 \x01(\r\x12\x14\n\x0c\x64\x65sired_prio\x18\x05 \x01(\r\"$\n\x15\x42inderLockFtraceEvent\x12\x0b\n\x03tag\x18\x01 \x01(\t\"&\n\x17\x42inderLockedFtraceEvent\x12\x0b\n\x03tag\x18\x01 \x01(\t\"&\n\x17\x42inderUnlockFtraceEvent\x12\x0b\n\x03tag\x18\x01 \x01(\t\"}\n$BinderTransactionAllocBufFtraceEvent\x12\x11\n\tdata_size\x18\x01 \x01(\x04\x12\x10\n\x08\x64\x65\x62ug_id\x18\x02 \x01(\x05\x12\x14\n\x0coffsets_size\x18\x03 \x01(\x04\x12\x1a\n\x12\x65xtra_buffers_size\x18\x04 \x01(\x04\"\'\n\x18\x42inderCommandFtraceEvent\x12\x0b\n\x03\x63md\x18\x01 \x01(\r\"&\n\x17\x42inderReturnFtraceEvent\x12\x0b\n\x03\x63md\x18\x01 \x01(\r\"\x81\x01\n\x17\x42lockRqIssueFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0e\n\x06sector\x18\x02 \x01(\x04\x12\x11\n\tnr_sector\x18\x03 \x01(\r\x12\r\n\x05\x62ytes\x18\x04 \x01(\r\x12\x0c\n\x04rwbs\x18\x05 \x01(\t\x12\x0c\n\x04\x63omm\x18\x06 \x01(\t\x12\x0b\n\x03\x63md\x18\x07 \x01(\t\"j\n\x1c\x42lockBioBackmergeFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0e\n\x06sector\x18\x02 \x01(\x04\x12\x11\n\tnr_sector\x18\x03 \x01(\r\x12\x0c\n\x04rwbs\x18\x04 \x01(\t\x12\x0c\n\x04\x63omm\x18\x05 \x01(\t\"g\n\x19\x42lockBioBounceFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0e\n\x06sector\x18\x02 \x01(\x04\x12\x11\n\tnr_sector\x18\x03 \x01(\r\x12\x0c\n\x04rwbs\x18\x04 \x01(\t\x12\x0c\n\x04\x63omm\x18\x05 \x01(\t\"j\n\x1b\x42lockBioCompleteFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0e\n\x06sector\x18\x02 \x01(\x04\x12\x11\n\tnr_sector\x18\x03 \x01(\r\x12\r\n\x05\x65rror\x18\x04 \x01(\x05\x12\x0c\n\x04rwbs\x18\x05 \x01(\t\"k\n\x1d\x42lockBioFrontmergeFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0e\n\x06sector\x18\x02 \x01(\x04\x12\x11\n\tnr_sector\x18\x03 \x01(\r\x12\x0c\n\x04rwbs\x18\x04 \x01(\t\x12\x0c\n\x04\x63omm\x18\x05 \x01(\t\"f\n\x18\x42lockBioQueueFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0e\n\x06sector\x18\x02 \x01(\x04\x12\x11\n\tnr_sector\x18\x03 \x01(\r\x12\x0c\n\x04rwbs\x18\x04 \x01(\t\x12\x0c\n\x04\x63omm\x18\x05 \x01(\t\"}\n\x18\x42lockBioRemapFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0e\n\x06sector\x18\x02 \x01(\x04\x12\x11\n\tnr_sector\x18\x03 \x01(\r\x12\x0f\n\x07old_dev\x18\x04 \x01(\x04\x12\x12\n\nold_sector\x18\x05 \x01(\x04\x12\x0c\n\x04rwbs\x18\x06 \x01(\t\"H\n\x1b\x42lockDirtyBufferFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0e\n\x06sector\x18\x02 \x01(\x04\x12\x0c\n\x04size\x18\x03 \x01(\x04\"c\n\x15\x42lockGetrqFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0e\n\x06sector\x18\x02 \x01(\x04\x12\x11\n\tnr_sector\x18\x03 \x01(\r\x12\x0c\n\x04rwbs\x18\x04 \x01(\t\x12\x0c\n\x04\x63omm\x18\x05 \x01(\t\"$\n\x14\x42lockPlugFtraceEvent\x12\x0c\n\x04\x63omm\x18\x01 \x01(\t\"t\n\x17\x42lockRqAbortFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0e\n\x06sector\x18\x02 \x01(\x04\x12\x11\n\tnr_sector\x18\x03 \x01(\r\x12\x0e\n\x06\x65rrors\x18\x04 \x01(\x05\x12\x0c\n\x04rwbs\x18\x05 \x01(\t\x12\x0b\n\x03\x63md\x18\x06 \x01(\t\"\x86\x01\n\x1a\x42lockRqCompleteFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0e\n\x06sector\x18\x02 \x01(\x04\x12\x11\n\tnr_sector\x18\x03 \x01(\r\x12\x0e\n\x06\x65rrors\x18\x04 \x01(\x05\x12\x0c\n\x04rwbs\x18\x05 \x01(\t\x12\x0b\n\x03\x63md\x18\x06 \x01(\t\x12\r\n\x05\x65rror\x18\x07 \x01(\x05\"\x82\x01\n\x18\x42lockRqInsertFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0e\n\x06sector\x18\x02 \x01(\x04\x12\x11\n\tnr_sector\x18\x03 \x01(\r\x12\r\n\x05\x62ytes\x18\x04 \x01(\r\x12\x0c\n\x04rwbs\x18\x05 \x01(\t\x12\x0c\n\x04\x63omm\x18\x06 \x01(\t\x12\x0b\n\x03\x63md\x18\x07 \x01(\t\"\x8d\x01\n\x17\x42lockRqRemapFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0e\n\x06sector\x18\x02 \x01(\x04\x12\x11\n\tnr_sector\x18\x03 \x01(\r\x12\x0f\n\x07old_dev\x18\x04 \x01(\x04\x12\x12\n\nold_sector\x18\x05 \x01(\x04\x12\x0f\n\x07nr_bios\x18\x06 \x01(\r\x12\x0c\n\x04rwbs\x18\x07 \x01(\t\"v\n\x19\x42lockRqRequeueFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0e\n\x06sector\x18\x02 \x01(\x04\x12\x11\n\tnr_sector\x18\x03 \x01(\r\x12\x0e\n\x06\x65rrors\x18\x04 \x01(\x05\x12\x0c\n\x04rwbs\x18\x05 \x01(\t\x12\x0b\n\x03\x63md\x18\x06 \x01(\t\"e\n\x17\x42lockSleeprqFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0e\n\x06sector\x18\x02 \x01(\x04\x12\x11\n\tnr_sector\x18\x03 \x01(\r\x12\x0c\n\x04rwbs\x18\x04 \x01(\t\x12\x0c\n\x04\x63omm\x18\x05 \x01(\t\"d\n\x15\x42lockSplitFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0e\n\x06sector\x18\x02 \x01(\x04\x12\x12\n\nnew_sector\x18\x03 \x01(\x04\x12\x0c\n\x04rwbs\x18\x04 \x01(\t\x12\x0c\n\x04\x63omm\x18\x05 \x01(\t\"H\n\x1b\x42lockTouchBufferFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0e\n\x06sector\x18\x02 \x01(\x04\x12\x0c\n\x04size\x18\x03 \x01(\x04\"5\n\x16\x42lockUnplugFtraceEvent\x12\r\n\x05nr_rq\x18\x01 \x01(\x05\x12\x0c\n\x04\x63omm\x18\x02 \x01(\t\"\x91\x01\n\x17\x42lockIoStartFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0e\n\x06sector\x18\x02 \x01(\x04\x12\x11\n\tnr_sector\x18\x03 \x01(\r\x12\r\n\x05\x62ytes\x18\x04 \x01(\r\x12\x0e\n\x06ioprio\x18\x05 \x01(\r\x12\x0c\n\x04rwbs\x18\x06 \x01(\t\x12\x0c\n\x04\x63omm\x18\x07 \x01(\t\x12\x0b\n\x03\x63md\x18\x08 \x01(\t\"\x90\x01\n\x16\x42lockIoDoneFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0e\n\x06sector\x18\x02 \x01(\x04\x12\x11\n\tnr_sector\x18\x03 \x01(\r\x12\r\n\x05\x62ytes\x18\x04 \x01(\r\x12\x0e\n\x06ioprio\x18\x05 \x01(\r\x12\x0c\n\x04rwbs\x18\x06 \x01(\t\x12\x0c\n\x04\x63omm\x18\x07 \x01(\t\x12\x0b\n\x03\x63md\x18\x08 \x01(\t\"\x8e\x01\n\x1b\x43groupAttachTaskFtraceEvent\x12\x10\n\x08\x64st_root\x18\x01 \x01(\x05\x12\x0e\n\x06\x64st_id\x18\x02 \x01(\x05\x12\x0b\n\x03pid\x18\x03 \x01(\x05\x12\x0c\n\x04\x63omm\x18\x04 \x01(\t\x12\r\n\x05\x63name\x18\x05 \x01(\t\x12\x11\n\tdst_level\x18\x06 \x01(\x05\x12\x10\n\x08\x64st_path\x18\x07 \x01(\t\"^\n\x16\x43groupMkdirFtraceEvent\x12\x0c\n\x04root\x18\x01 \x01(\x05\x12\n\n\x02id\x18\x02 \x01(\x05\x12\r\n\x05\x63name\x18\x03 \x01(\t\x12\r\n\x05level\x18\x04 \x01(\x05\x12\x0c\n\x04path\x18\x05 \x01(\t\"G\n\x18\x43groupRemountFtraceEvent\x12\x0c\n\x04root\x18\x01 \x01(\x05\x12\x0f\n\x07ss_mask\x18\x02 \x01(\r\x12\x0c\n\x04name\x18\x03 \x01(\t\"^\n\x16\x43groupRmdirFtraceEvent\x12\x0c\n\x04root\x18\x01 \x01(\x05\x12\n\n\x02id\x18\x02 \x01(\x05\x12\r\n\x05\x63name\x18\x03 \x01(\t\x12\r\n\x05level\x18\x04 \x01(\x05\x12\x0c\n\x04path\x18\x05 \x01(\t\"\x91\x01\n\x1e\x43groupTransferTasksFtraceEvent\x12\x10\n\x08\x64st_root\x18\x01 \x01(\x05\x12\x0e\n\x06\x64st_id\x18\x02 \x01(\x05\x12\x0b\n\x03pid\x18\x03 \x01(\x05\x12\x0c\n\x04\x63omm\x18\x04 \x01(\t\x12\r\n\x05\x63name\x18\x05 \x01(\t\x12\x11\n\tdst_level\x18\x06 \x01(\x05\x12\x10\n\x08\x64st_path\x18\x07 \x01(\t\"K\n\x1c\x43groupDestroyRootFtraceEvent\x12\x0c\n\x04root\x18\x01 \x01(\x05\x12\x0f\n\x07ss_mask\x18\x02 \x01(\r\x12\x0c\n\x04name\x18\x03 \x01(\t\"`\n\x18\x43groupReleaseFtraceEvent\x12\x0c\n\x04root\x18\x01 \x01(\x05\x12\n\n\x02id\x18\x02 \x01(\x05\x12\r\n\x05\x63name\x18\x03 \x01(\t\x12\r\n\x05level\x18\x04 \x01(\x05\x12\x0c\n\x04path\x18\x05 \x01(\t\"_\n\x17\x43groupRenameFtraceEvent\x12\x0c\n\x04root\x18\x01 \x01(\x05\x12\n\n\x02id\x18\x02 \x01(\x05\x12\r\n\x05\x63name\x18\x03 \x01(\t\x12\r\n\x05level\x18\x04 \x01(\x05\x12\x0c\n\x04path\x18\x05 \x01(\t\"I\n\x1a\x43groupSetupRootFtraceEvent\x12\x0c\n\x04root\x18\x01 \x01(\x05\x12\x0f\n\x07ss_mask\x18\x02 \x01(\r\x12\x0c\n\x04name\x18\x03 \x01(\t\"$\n\x14\x43lkEnableFtraceEvent\x12\x0c\n\x04name\x18\x01 \x01(\t\"%\n\x15\x43lkDisableFtraceEvent\x12\x0c\n\x04name\x18\x01 \x01(\t\"3\n\x15\x43lkSetRateFtraceEvent\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0c\n\x04rate\x18\x02 \x01(\x04\"F\n\x18\x43maAllocStartFtraceEvent\x12\r\n\x05\x61lign\x18\x01 \x01(\r\x12\r\n\x05\x63ount\x18\x02 \x01(\r\x12\x0c\n\x04name\x18\x03 \x01(\t\"\xc4\x01\n\x17\x43maAllocInfoFtraceEvent\x12\r\n\x05\x61lign\x18\x01 \x01(\r\x12\r\n\x05\x63ount\x18\x02 \x01(\r\x12\x0f\n\x07\x65rr_iso\x18\x03 \x01(\r\x12\x0f\n\x07\x65rr_mig\x18\x04 \x01(\r\x12\x10\n\x08\x65rr_test\x18\x05 \x01(\r\x12\x0c\n\x04name\x18\x06 \x01(\t\x12\x11\n\tnr_mapped\x18\x07 \x01(\x04\x12\x13\n\x0bnr_migrated\x18\x08 \x01(\x04\x12\x14\n\x0cnr_reclaimed\x18\t \x01(\x04\x12\x0b\n\x03pfn\x18\n \x01(\x04\"s\n\x19\x43maAllocFinishFtraceEvent\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0b\n\x03pfn\x18\x02 \x01(\x04\x12\x0c\n\x04page\x18\x03 \x01(\x04\x12\r\n\x05\x63ount\x18\x04 \x01(\x04\x12\r\n\x05\x61lign\x18\x05 \x01(\r\x12\x0f\n\x07\x65rrorno\x18\x06 \x01(\x05\"y\n\x1cMmCompactionBeginFtraceEvent\x12\x12\n\nzone_start\x18\x01 \x01(\x04\x12\x13\n\x0bmigrate_pfn\x18\x02 \x01(\x04\x12\x10\n\x08\x66ree_pfn\x18\x03 \x01(\x04\x12\x10\n\x08zone_end\x18\x04 \x01(\x04\x12\x0c\n\x04sync\x18\x05 \x01(\r\"\x90\x01\n&MmCompactionDeferCompactionFtraceEvent\x12\x0b\n\x03nid\x18\x01 \x01(\x05\x12\x0b\n\x03idx\x18\x02 \x01(\r\x12\r\n\x05order\x18\x03 \x01(\x05\x12\x12\n\nconsidered\x18\x04 \x01(\r\x12\x13\n\x0b\x64\x65\x66\x65r_shift\x18\x05 \x01(\r\x12\x14\n\x0corder_failed\x18\x06 \x01(\x05\"\x89\x01\n\x1fMmCompactionDeferredFtraceEvent\x12\x0b\n\x03nid\x18\x01 \x01(\x05\x12\x0b\n\x03idx\x18\x02 \x01(\r\x12\r\n\x05order\x18\x03 \x01(\x05\x12\x12\n\nconsidered\x18\x04 \x01(\r\x12\x13\n\x0b\x64\x65\x66\x65r_shift\x18\x05 \x01(\r\x12\x14\n\x0corder_failed\x18\x06 \x01(\x05\"\x8b\x01\n!MmCompactionDeferResetFtraceEvent\x12\x0b\n\x03nid\x18\x01 \x01(\x05\x12\x0b\n\x03idx\x18\x02 \x01(\r\x12\r\n\x05order\x18\x03 \x01(\x05\x12\x12\n\nconsidered\x18\x04 \x01(\r\x12\x13\n\x0b\x64\x65\x66\x65r_shift\x18\x05 \x01(\r\x12\x14\n\x0corder_failed\x18\x06 \x01(\x05\"\x87\x01\n\x1aMmCompactionEndFtraceEvent\x12\x12\n\nzone_start\x18\x01 \x01(\x04\x12\x13\n\x0bmigrate_pfn\x18\x02 \x01(\x04\x12\x10\n\x08\x66ree_pfn\x18\x03 \x01(\x04\x12\x10\n\x08zone_end\x18\x04 \x01(\x04\x12\x0c\n\x04sync\x18\x05 \x01(\r\x12\x0e\n\x06status\x18\x06 \x01(\x05\"W\n\x1fMmCompactionFinishedFtraceEvent\x12\x0b\n\x03nid\x18\x01 \x01(\x05\x12\x0b\n\x03idx\x18\x02 \x01(\r\x12\r\n\x05order\x18\x03 \x01(\x05\x12\x0b\n\x03ret\x18\x04 \x01(\x05\"s\n\'MmCompactionIsolateFreepagesFtraceEvent\x12\x11\n\tstart_pfn\x18\x01 \x01(\x04\x12\x0f\n\x07\x65nd_pfn\x18\x02 \x01(\x04\x12\x12\n\nnr_scanned\x18\x03 \x01(\x04\x12\x10\n\x08nr_taken\x18\x04 \x01(\x04\"v\n*MmCompactionIsolateMigratepagesFtraceEvent\x12\x11\n\tstart_pfn\x18\x01 \x01(\x04\x12\x0f\n\x07\x65nd_pfn\x18\x02 \x01(\x04\x12\x12\n\nnr_scanned\x18\x03 \x01(\x04\x12\x10\n\x08nr_taken\x18\x04 \x01(\x04\"4\n%MmCompactionKcompactdSleepFtraceEvent\x12\x0b\n\x03nid\x18\x01 \x01(\x05\"r\n$MmCompactionKcompactdWakeFtraceEvent\x12\x0b\n\x03nid\x18\x01 \x01(\x05\x12\r\n\x05order\x18\x02 \x01(\x05\x12\x15\n\rclasszone_idx\x18\x03 \x01(\r\x12\x17\n\x0fhighest_zoneidx\x18\x04 \x01(\r\"M\n#MmCompactionMigratepagesFtraceEvent\x12\x13\n\x0bnr_migrated\x18\x01 \x01(\x04\x12\x11\n\tnr_failed\x18\x02 \x01(\x04\"W\n\x1fMmCompactionSuitableFtraceEvent\x12\x0b\n\x03nid\x18\x01 \x01(\x05\x12\x0b\n\x03idx\x18\x02 \x01(\r\x12\r\n\x05order\x18\x03 \x01(\x05\x12\x0b\n\x03ret\x18\x04 \x01(\x05\"g\n(MmCompactionTryToCompactPagesFtraceEvent\x12\r\n\x05order\x18\x01 \x01(\x05\x12\x10\n\x08gfp_mask\x18\x02 \x01(\r\x12\x0c\n\x04mode\x18\x03 \x01(\r\x12\x0c\n\x04prio\x18\x04 \x01(\x05\"t\n&MmCompactionWakeupKcompactdFtraceEvent\x12\x0b\n\x03nid\x18\x01 \x01(\x05\x12\r\n\x05order\x18\x02 \x01(\x05\x12\x15\n\rclasszone_idx\x18\x03 \x01(\r\x12\x17\n\x0fhighest_zoneidx\x18\x04 \x01(\r\"M\n\x1bParamSetValueCpmFtraceEvent\x12\x0c\n\x04\x62ody\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\r\x12\x11\n\ttimestamp\x18\x03 \x01(\x03\"L\n\x14\x43puhpExitFtraceEvent\x12\x0b\n\x03\x63pu\x18\x01 \x01(\r\x12\x0b\n\x03idx\x18\x02 \x01(\x05\x12\x0b\n\x03ret\x18\x03 \x01(\x05\x12\r\n\x05state\x18\x04 \x01(\x05\"S\n\x1a\x43puhpMultiEnterFtraceEvent\x12\x0b\n\x03\x63pu\x18\x01 \x01(\r\x12\x0b\n\x03\x66un\x18\x02 \x01(\x04\x12\x0b\n\x03idx\x18\x03 \x01(\x05\x12\x0e\n\x06target\x18\x04 \x01(\x05\"N\n\x15\x43puhpEnterFtraceEvent\x12\x0b\n\x03\x63pu\x18\x01 \x01(\r\x12\x0b\n\x03\x66un\x18\x02 \x01(\x04\x12\x0b\n\x03idx\x18\x03 \x01(\x05\x12\x0e\n\x06target\x18\x04 \x01(\x05\"P\n\x17\x43puhpLatencyFtraceEvent\x12\x0b\n\x03\x63pu\x18\x01 \x01(\r\x12\x0b\n\x03ret\x18\x02 \x01(\x05\x12\r\n\x05state\x18\x03 \x01(\r\x12\x0c\n\x04time\x18\x04 \x01(\x04\"W\n\x15\x43puhpPauseFtraceEvent\x12\x13\n\x0b\x61\x63tive_cpus\x18\x01 \x01(\r\x12\x0c\n\x04\x63pus\x18\x02 \x01(\r\x12\r\n\x05pause\x18\x03 \x01(\r\x12\x0c\n\x04time\x18\x04 \x01(\r\"\xaa\x01\n\x1e\x43rosEcSensorhubDataFtraceEvent\x12\x14\n\x0c\x63urrent_time\x18\x01 \x01(\x03\x12\x19\n\x11\x63urrent_timestamp\x18\x02 \x01(\x03\x12\r\n\x05\x64\x65lta\x18\x03 \x01(\x03\x12\x19\n\x11\x65\x63_fifo_timestamp\x18\x04 \x01(\r\x12\x15\n\rec_sensor_num\x18\x05 \x01(\r\x12\x16\n\x0e\x66ifo_timestamp\x18\x06 \x01(\x03\"1\n\x14\x44\x63vshFreqFtraceEvent\x12\x0b\n\x03\x63pu\x18\x01 \x01(\x04\x12\x0c\n\x04\x66req\x18\x02 \x01(\x04\"w\n\x1b\x44\x65vfreqFrequencyFtraceEvent\x12\x10\n\x08\x64\x65v_name\x18\x01 \x01(\t\x12\x0c\n\x04\x66req\x18\x02 \x01(\x04\x12\x11\n\tprev_freq\x18\x03 \x01(\x04\x12\x11\n\tbusy_time\x18\x04 \x01(\x04\x12\x12\n\ntotal_time\x18\x05 \x01(\x04\"[\n\x17\x44maFenceInitFtraceEvent\x12\x0f\n\x07\x63ontext\x18\x01 \x01(\r\x12\x0e\n\x06\x64river\x18\x02 \x01(\t\x12\r\n\x05seqno\x18\x03 \x01(\r\x12\x10\n\x08timeline\x18\x04 \x01(\t\"[\n\x17\x44maFenceEmitFtraceEvent\x12\x0f\n\x07\x63ontext\x18\x01 \x01(\r\x12\x0e\n\x06\x64river\x18\x02 \x01(\t\x12\r\n\x05seqno\x18\x03 \x01(\r\x12\x10\n\x08timeline\x18\x04 \x01(\t\"_\n\x1b\x44maFenceSignaledFtraceEvent\x12\x0f\n\x07\x63ontext\x18\x01 \x01(\r\x12\x0e\n\x06\x64river\x18\x02 \x01(\t\x12\r\n\x05seqno\x18\x03 \x01(\r\x12\x10\n\x08timeline\x18\x04 \x01(\t\"`\n\x1c\x44maFenceWaitStartFtraceEvent\x12\x0f\n\x07\x63ontext\x18\x01 \x01(\r\x12\x0e\n\x06\x64river\x18\x02 \x01(\t\x12\r\n\x05seqno\x18\x03 \x01(\r\x12\x10\n\x08timeline\x18\x04 \x01(\t\"^\n\x1a\x44maFenceWaitEndFtraceEvent\x12\x0f\n\x07\x63ontext\x18\x01 \x01(\r\x12\x0e\n\x06\x64river\x18\x02 \x01(\t\x12\r\n\x05seqno\x18\x03 \x01(\r\x12\x10\n\x08timeline\x18\x04 \x01(\t\"M\n\x16\x44maHeapStatFtraceEvent\x12\r\n\x05inode\x18\x01 \x01(\x04\x12\x0b\n\x03len\x18\x02 \x01(\x03\x12\x17\n\x0ftotal_allocated\x18\x03 \x01(\x04\"\x81\x01\n\x1e\x44puTracingMarkWriteFtraceEvent\x12\x0b\n\x03pid\x18\x01 \x01(\x05\x12\x12\n\ntrace_name\x18\x02 \x01(\t\x12\x13\n\x0btrace_begin\x18\x03 \x01(\r\x12\x0c\n\x04name\x18\x04 \x01(\t\x12\x0c\n\x04type\x18\x05 \x01(\r\x12\r\n\x05value\x18\x06 \x01(\x05\"A\n\x1e\x44puDsiCmdFifoStatusFtraceEvent\x12\x0e\n\x06header\x18\x01 \x01(\r\x12\x0f\n\x07payload\x18\x02 \x01(\r\"2\n\x13\x44puDsiRxFtraceEvent\x12\x0b\n\x03\x63md\x18\x01 \x01(\r\x12\x0e\n\x06rx_buf\x18\x03 \x01(\x0c\"S\n\x13\x44puDsiTxFtraceEvent\x12\x0c\n\x04type\x18\x01 \x01(\r\x12\x0c\n\x04last\x18\x03 \x01(\r\x12\x10\n\x08\x64\x65lay_ms\x18\x04 \x01(\r\x12\x0e\n\x06tx_buf\x18\x05 \x01(\x0c\"X\n\x1d\x44puDispDpuUnderrunFtraceEvent\x12\n\n\x02id\x18\x01 \x01(\x05\x12\x16\n\x0e\x66rames_pending\x18\x02 \x01(\x05\x12\x13\n\x0bvsync_count\x18\x03 \x01(\x05\"R\n!DpuDispVblankIrqEnableFtraceEvent\x12\n\n\x02id\x18\x01 \x01(\x05\x12\x11\n\toutput_id\x18\x02 \x01(\x05\x12\x0e\n\x06\x65nable\x18\x03 \x01(\x05\"\x8d\x01\n\"DpuDispFrameDoneTimeoutFtraceEvent\x12\x12\n\ndisplay_id\x18\x01 \x01(\x05\x12\x11\n\toutput_id\x18\x02 \x01(\r\x12\x16\n\x0e\x66rames_pending\x18\x03 \x01(\x05\x12\x10\n\x08te_count\x18\x04 \x01(\x05\x12\x16\n\x0e\x64uring_disable\x18\x05 \x01(\r\"v\n#DpuDispFrameStartTimeoutFtraceEvent\x12\x12\n\ndisplay_id\x18\x01 \x01(\x05\x12\x11\n\toutput_id\x18\x02 \x01(\r\x12\x16\n\x0e\x66rames_pending\x18\x03 \x01(\x05\x12\x10\n\x08te_count\x18\x04 \x01(\x05\"u\n\"DpuDispFrameDoneMissingFtraceEvent\x12\x12\n\ndisplay_id\x18\x01 \x01(\x05\x12\x11\n\toutput_id\x18\x02 \x01(\r\x12\x16\n\x0e\x66rames_pending\x18\x03 \x01(\x05\x12\x10\n\x08te_count\x18\x04 \x01(\x05\"v\n#DpuDispFrameStartMissingFtraceEvent\x12\x12\n\ndisplay_id\x18\x01 \x01(\x05\x12\x11\n\toutput_id\x18\x02 \x01(\r\x12\x16\n\x0e\x66rames_pending\x18\x03 \x01(\x05\x12\x10\n\x08te_count\x18\x04 \x01(\x05\"\\\n!DpuDispDpuLineUnderrunFtraceEvent\x12\n\n\x02id\x18\x01 \x01(\x05\x12\x16\n\x0e\x66rames_pending\x18\x02 \x01(\x05\x12\x13\n\x0bvsync_count\x18\x03 \x01(\x05\"W\n\x19\x44rmVblankEventFtraceEvent\x12\x0c\n\x04\x63rtc\x18\x01 \x01(\x05\x12\x11\n\thigh_prec\x18\x02 \x01(\r\x12\x0b\n\x03seq\x18\x03 \x01(\r\x12\x0c\n\x04time\x18\x04 \x01(\x03\"M\n\"DrmVblankEventDeliveredFtraceEvent\x12\x0c\n\x04\x63rtc\x18\x01 \x01(\x05\x12\x0c\n\x04\x66ile\x18\x02 \x01(\x04\x12\x0b\n\x03seq\x18\x03 \x01(\r\"\xa2\x01\n\x1b\x44wc3AllocRequestFtraceEvent\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0b\n\x03req\x18\x02 \x01(\x04\x12\x0e\n\x06\x61\x63tual\x18\x03 \x01(\r\x12\x0e\n\x06length\x18\x04 \x01(\r\x12\x0e\n\x06status\x18\x05 \x01(\x05\x12\x0c\n\x04zero\x18\x06 \x01(\x05\x12\x14\n\x0cshort_not_ok\x18\x07 \x01(\x05\x12\x14\n\x0cno_interrupt\x18\x08 \x01(\x05\"\xc0\x01\n\x1a\x44wc3CompleteTrbFtraceEvent\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0b\n\x03trb\x18\x02 \x01(\x04\x12\x11\n\tallocated\x18\x03 \x01(\r\x12\x0e\n\x06queued\x18\x04 \x01(\r\x12\x0b\n\x03\x62pl\x18\x05 \x01(\r\x12\x0b\n\x03\x62ph\x18\x06 \x01(\r\x12\x0c\n\x04size\x18\x07 \x01(\r\x12\x0c\n\x04\x63trl\x18\x08 \x01(\r\x12\x0c\n\x04type\x18\t \x01(\r\x12\x0f\n\x07\x65nqueue\x18\n \x01(\r\x12\x0f\n\x07\x64\x65queue\x18\x0b \x01(\r\"~\n\x16\x44wc3CtrlReqFtraceEvent\x12\x14\n\x0c\x62RequestType\x18\x01 \x01(\r\x12\x10\n\x08\x62Request\x18\x02 \x01(\r\x12\x0e\n\x06wValue\x18\x03 \x01(\r\x12\x0e\n\x06wIndex\x18\x04 \x01(\r\x12\x0f\n\x07wLength\x18\x05 \x01(\r\x12\x0b\n\x03str\x18\x06 \x01(\t\"\x9f\x01\n\x18\x44wc3EpDequeueFtraceEvent\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0b\n\x03req\x18\x02 \x01(\x04\x12\x0e\n\x06\x61\x63tual\x18\x03 \x01(\r\x12\x0e\n\x06length\x18\x04 \x01(\r\x12\x0e\n\x06status\x18\x05 \x01(\x05\x12\x0c\n\x04zero\x18\x06 \x01(\x05\x12\x14\n\x0cshort_not_ok\x18\x07 \x01(\x05\x12\x14\n\x0cno_interrupt\x18\x08 \x01(\x05\"\x9d\x01\n\x16\x44wc3EpQueueFtraceEvent\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0b\n\x03req\x18\x02 \x01(\x04\x12\x0e\n\x06\x61\x63tual\x18\x03 \x01(\r\x12\x0e\n\x06length\x18\x04 \x01(\r\x12\x0e\n\x06status\x18\x05 \x01(\x05\x12\x0c\n\x04zero\x18\x06 \x01(\x05\x12\x14\n\x0cshort_not_ok\x18\x07 \x01(\x05\x12\x14\n\x0cno_interrupt\x18\x08 \x01(\x05\"D\n\x14\x44wc3EventFtraceEvent\x12\r\n\x05\x65vent\x18\x01 \x01(\r\x12\x10\n\x08\x65p0state\x18\x02 \x01(\r\x12\x0b\n\x03str\x18\x03 \x01(\t\"\xa1\x01\n\x1a\x44wc3FreeRequestFtraceEvent\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0b\n\x03req\x18\x02 \x01(\x04\x12\x0e\n\x06\x61\x63tual\x18\x03 \x01(\r\x12\x0e\n\x06length\x18\x04 \x01(\r\x12\x0e\n\x06status\x18\x05 \x01(\x05\x12\x0c\n\x04zero\x18\x06 \x01(\x05\x12\x14\n\x0cshort_not_ok\x18\x07 \x01(\x05\x12\x14\n\x0cno_interrupt\x18\x08 \x01(\x05\"{\n\x1a\x44wc3GadgetEpCmdFtraceEvent\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0b\n\x03\x63md\x18\x02 \x01(\r\x12\x0e\n\x06param0\x18\x03 \x01(\r\x12\x0e\n\x06param1\x18\x04 \x01(\r\x12\x0e\n\x06param2\x18\x05 \x01(\r\x12\x12\n\ncmd_status\x18\x06 \x01(\x05\"\xcd\x01\n\x1e\x44wc3GadgetEpDisableFtraceEvent\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x11\n\tmaxpacket\x18\x02 \x01(\r\x12\x17\n\x0fmaxpacket_limit\x18\x03 \x01(\r\x12\x13\n\x0bmax_streams\x18\x04 \x01(\r\x12\x10\n\x08maxburst\x18\x05 \x01(\r\x12\r\n\x05\x66lags\x18\x06 \x01(\r\x12\x11\n\tdirection\x18\x07 \x01(\r\x12\x13\n\x0btrb_enqueue\x18\x08 \x01(\r\x12\x13\n\x0btrb_dequeue\x18\t \x01(\r\"\xcc\x01\n\x1d\x44wc3GadgetEpEnableFtraceEvent\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x11\n\tmaxpacket\x18\x02 \x01(\r\x12\x17\n\x0fmaxpacket_limit\x18\x03 \x01(\r\x12\x13\n\x0bmax_streams\x18\x04 \x01(\r\x12\x10\n\x08maxburst\x18\x05 \x01(\r\x12\r\n\x05\x66lags\x18\x06 \x01(\r\x12\x11\n\tdirection\x18\x07 \x01(\r\x12\x13\n\x0btrb_enqueue\x18\x08 \x01(\r\x12\x13\n\x0btrb_dequeue\x18\t \x01(\r\"M\n\x1f\x44wc3GadgetGenericCmdFtraceEvent\x12\x0b\n\x03\x63md\x18\x01 \x01(\r\x12\r\n\x05param\x18\x02 \x01(\r\x12\x0e\n\x06status\x18\x03 \x01(\x05\"\xa4\x01\n\x1d\x44wc3GadgetGivebackFtraceEvent\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0b\n\x03req\x18\x02 \x01(\x04\x12\x0e\n\x06\x61\x63tual\x18\x03 \x01(\r\x12\x0e\n\x06length\x18\x04 \x01(\r\x12\x0e\n\x06status\x18\x05 \x01(\x05\x12\x0c\n\x04zero\x18\x06 \x01(\x05\x12\x14\n\x0cshort_not_ok\x18\x07 \x01(\x05\x12\x14\n\x0cno_interrupt\x18\x08 \x01(\x05\"\xbf\x01\n\x19\x44wc3PrepareTrbFtraceEvent\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0b\n\x03trb\x18\x02 \x01(\x04\x12\x11\n\tallocated\x18\x03 \x01(\r\x12\x0e\n\x06queued\x18\x04 \x01(\r\x12\x0b\n\x03\x62pl\x18\x05 \x01(\r\x12\x0b\n\x03\x62ph\x18\x06 \x01(\r\x12\x0c\n\x04size\x18\x07 \x01(\r\x12\x0c\n\x04\x63trl\x18\x08 \x01(\r\x12\x0c\n\x04type\x18\t \x01(\r\x12\x0f\n\x07\x65nqueue\x18\n \x01(\r\x12\x0f\n\x07\x64\x65queue\x18\x0b \x01(\r\"P\n\x14\x44wc3ReadlFtraceEvent\x12\x0c\n\x04\x62\x61se\x18\x01 \x01(\x04\x12\x0e\n\x06offset\x18\x02 \x01(\r\x12\r\n\x05value\x18\x03 \x01(\r\x12\x0b\n\x03msg\x18\x04 \x01(\t\"Q\n\x15\x44wc3WritelFtraceEvent\x12\x0c\n\x04\x62\x61se\x18\x01 \x01(\x04\x12\x0e\n\x06offset\x18\x02 \x01(\r\x12\r\n\x05value\x18\x03 \x01(\r\x12\x0b\n\x03msg\x18\x04 \x01(\t\"`\n\x1b\x45xt4DaWriteBeginFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x0b\n\x03pos\x18\x03 \x01(\x03\x12\x0b\n\x03len\x18\x04 \x01(\r\x12\r\n\x05\x66lags\x18\x05 \x01(\r\"_\n\x19\x45xt4DaWriteEndFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x0b\n\x03pos\x18\x03 \x01(\x03\x12\x0b\n\x03len\x18\x04 \x01(\r\x12\x0e\n\x06\x63opied\x18\x05 \x01(\r\"Z\n\x1c\x45xt4SyncFileEnterFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x0e\n\x06parent\x18\x03 \x01(\x04\x12\x10\n\x08\x64\x61tasync\x18\x04 \x01(\x05\"D\n\x1b\x45xt4SyncFileExitFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x0b\n\x03ret\x18\x03 \x01(\x05\"b\n\x1c\x45xt4AllocDaBlocksFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x13\n\x0b\x64\x61ta_blocks\x18\x03 \x01(\r\x12\x13\n\x0bmeta_blocks\x18\x04 \x01(\r\"\xc1\x01\n\x1d\x45xt4AllocateBlocksFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\r\n\x05\x62lock\x18\x03 \x01(\x04\x12\x0b\n\x03len\x18\x04 \x01(\r\x12\x0f\n\x07logical\x18\x05 \x01(\r\x12\r\n\x05lleft\x18\x06 \x01(\r\x12\x0e\n\x06lright\x18\x07 \x01(\r\x12\x0c\n\x04goal\x18\x08 \x01(\x04\x12\r\n\x05pleft\x18\t \x01(\x04\x12\x0e\n\x06pright\x18\n \x01(\x04\x12\r\n\x05\x66lags\x18\x0b \x01(\r\"S\n\x1c\x45xt4AllocateInodeFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x0b\n\x03\x64ir\x18\x03 \x01(\x04\x12\x0c\n\x04mode\x18\x04 \x01(\r\"Q\n#Ext4BeginOrderedTruncateFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x10\n\x08new_size\x18\x03 \x01(\x03\"U\n\x1c\x45xt4CollapseRangeFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x0e\n\x06offset\x18\x03 \x01(\x03\x12\x0b\n\x03len\x18\x04 \x01(\x03\"\xca\x01\n\x1d\x45xt4DaReleaseSpaceFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x10\n\x08i_blocks\x18\x03 \x01(\x04\x12\x14\n\x0c\x66reed_blocks\x18\x04 \x01(\x05\x12\x1c\n\x14reserved_data_blocks\x18\x05 \x01(\x05\x12\x1c\n\x14reserved_meta_blocks\x18\x06 \x01(\x05\x12\x1d\n\x15\x61llocated_meta_blocks\x18\x07 \x01(\x05\x12\x0c\n\x04mode\x18\x08 \x01(\r\"\xa8\x01\n\x1d\x45xt4DaReserveSpaceFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x10\n\x08i_blocks\x18\x03 \x01(\x04\x12\x1c\n\x14reserved_data_blocks\x18\x04 \x01(\x05\x12\x1c\n\x14reserved_meta_blocks\x18\x05 \x01(\x05\x12\x0c\n\x04mode\x18\x06 \x01(\r\x12\x11\n\tmd_needed\x18\x07 \x01(\x05\"\xe4\x01\n#Ext4DaUpdateReserveSpaceFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x10\n\x08i_blocks\x18\x03 \x01(\x04\x12\x13\n\x0bused_blocks\x18\x04 \x01(\x05\x12\x1c\n\x14reserved_data_blocks\x18\x05 \x01(\x05\x12\x1c\n\x14reserved_meta_blocks\x18\x06 \x01(\x05\x12\x1d\n\x15\x61llocated_meta_blocks\x18\x07 \x01(\x05\x12\x13\n\x0bquota_claim\x18\x08 \x01(\x05\x12\x0c\n\x04mode\x18\t \x01(\r\"\xcf\x01\n\x1b\x45xt4DaWritePagesFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x12\n\nfirst_page\x18\x03 \x01(\x04\x12\x13\n\x0bnr_to_write\x18\x04 \x01(\x03\x12\x11\n\tsync_mode\x18\x05 \x01(\x05\x12\x11\n\tb_blocknr\x18\x06 \x01(\x04\x12\x0e\n\x06\x62_size\x18\x07 \x01(\r\x12\x0f\n\x07\x62_state\x18\x08 \x01(\r\x12\x0f\n\x07io_done\x18\t \x01(\x05\x12\x15\n\rpages_written\x18\n \x01(\x05\"g\n!Ext4DaWritePagesExtentFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x0c\n\x04lblk\x18\x03 \x01(\x04\x12\x0b\n\x03len\x18\x04 \x01(\r\x12\r\n\x05\x66lags\x18\x05 \x01(\r\"^\n\x1c\x45xt4DirectIOEnterFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x0b\n\x03pos\x18\x03 \x01(\x03\x12\x0b\n\x03len\x18\x04 \x01(\x04\x12\n\n\x02rw\x18\x05 \x01(\x05\"j\n\x1b\x45xt4DirectIOExitFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x0b\n\x03pos\x18\x03 \x01(\x03\x12\x0b\n\x03len\x18\x04 \x01(\x04\x12\n\n\x02rw\x18\x05 \x01(\x05\x12\x0b\n\x03ret\x18\x06 \x01(\x05\"G\n\x1c\x45xt4DiscardBlocksFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03\x62lk\x18\x02 \x01(\x04\x12\r\n\x05\x63ount\x18\x03 \x01(\x04\"]\n$Ext4DiscardPreallocationsFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x0b\n\x03len\x18\x03 \x01(\r\x12\x0e\n\x06needed\x18\x04 \x01(\r\"B\n\x18\x45xt4DropInodeFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x0c\n\x04\x64rop\x18\x03 \x01(\x05\"q\n\x1c\x45xt4EsCacheExtentFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x0c\n\x04lblk\x18\x03 \x01(\r\x12\x0b\n\x03len\x18\x04 \x01(\r\x12\x0c\n\x04pblk\x18\x05 \x01(\x04\x12\x0e\n\x06status\x18\x06 \x01(\r\"V\n,Ext4EsFindDelayedExtentRangeEnterFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x0c\n\x04lblk\x18\x03 \x01(\r\"\x80\x01\n+Ext4EsFindDelayedExtentRangeExitFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x0c\n\x04lblk\x18\x03 \x01(\r\x12\x0b\n\x03len\x18\x04 \x01(\r\x12\x0c\n\x04pblk\x18\x05 \x01(\x04\x12\x0e\n\x06status\x18\x06 \x01(\x04\"r\n\x1d\x45xt4EsInsertExtentFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x0c\n\x04lblk\x18\x03 \x01(\r\x12\x0b\n\x03len\x18\x04 \x01(\r\x12\x0c\n\x04pblk\x18\x05 \x01(\x04\x12\x0e\n\x06status\x18\x06 \x01(\x04\"L\n\"Ext4EsLookupExtentEnterFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x0c\n\x04lblk\x18\x03 \x01(\r\"\x85\x01\n!Ext4EsLookupExtentExitFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x0c\n\x04lblk\x18\x03 \x01(\r\x12\x0b\n\x03len\x18\x04 \x01(\r\x12\x0c\n\x04pblk\x18\x05 \x01(\x04\x12\x0e\n\x06status\x18\x06 \x01(\x04\x12\r\n\x05\x66ound\x18\x07 \x01(\x05\"T\n\x1d\x45xt4EsRemoveExtentFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x0c\n\x04lblk\x18\x03 \x01(\x03\x12\x0b\n\x03len\x18\x04 \x01(\x03\"q\n\x17\x45xt4EsShrinkFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x11\n\tnr_shrunk\x18\x02 \x01(\x05\x12\x11\n\tscan_time\x18\x03 \x01(\x04\x12\x12\n\nnr_skipped\x18\x04 \x01(\x05\x12\x0f\n\x07retried\x18\x05 \x01(\x05\"R\n\x1c\x45xt4EsShrinkCountFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x12\n\nnr_to_scan\x18\x02 \x01(\x05\x12\x11\n\tcache_cnt\x18\x03 \x01(\x05\"V\n Ext4EsShrinkScanEnterFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x12\n\nnr_to_scan\x18\x02 \x01(\x05\x12\x11\n\tcache_cnt\x18\x03 \x01(\x05\"T\n\x1f\x45xt4EsShrinkScanExitFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x11\n\tnr_shrunk\x18\x02 \x01(\x05\x12\x11\n\tcache_cnt\x18\x03 \x01(\x05\"D\n\x19\x45xt4EvictInodeFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\r\n\x05nlink\x18\x03 \x01(\x05\"\x95\x01\n+Ext4ExtConvertToInitializedEnterFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x0e\n\x06m_lblk\x18\x03 \x01(\r\x12\r\n\x05m_len\x18\x04 \x01(\r\x12\x0e\n\x06u_lblk\x18\x05 \x01(\r\x12\r\n\x05u_len\x18\x06 \x01(\r\x12\x0e\n\x06u_pblk\x18\x07 \x01(\x04\"\xc7\x01\n.Ext4ExtConvertToInitializedFastpathFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x0e\n\x06m_lblk\x18\x03 \x01(\r\x12\r\n\x05m_len\x18\x04 \x01(\r\x12\x0e\n\x06u_lblk\x18\x05 \x01(\r\x12\r\n\x05u_len\x18\x06 \x01(\r\x12\x0e\n\x06u_pblk\x18\x07 \x01(\x04\x12\x0e\n\x06i_lblk\x18\x08 \x01(\r\x12\r\n\x05i_len\x18\t \x01(\r\x12\x0e\n\x06i_pblk\x18\n \x01(\x04\"\x9f\x01\n(Ext4ExtHandleUnwrittenExtentsFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\r\n\x05\x66lags\x18\x03 \x01(\x05\x12\x0c\n\x04lblk\x18\x04 \x01(\r\x12\x0c\n\x04pblk\x18\x05 \x01(\x04\x12\x0b\n\x03len\x18\x06 \x01(\r\x12\x11\n\tallocated\x18\x07 \x01(\r\x12\x0e\n\x06newblk\x18\x08 \x01(\x04\"P\n\x19\x45xt4ExtInCacheFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x0c\n\x04lblk\x18\x03 \x01(\r\x12\x0b\n\x03ret\x18\x04 \x01(\x05\"T\n\x1c\x45xt4ExtLoadExtentFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x0c\n\x04pblk\x18\x03 \x01(\x04\x12\x0c\n\x04lblk\x18\x04 \x01(\r\"f\n Ext4ExtMapBlocksEnterFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x0c\n\x04lblk\x18\x03 \x01(\r\x12\x0b\n\x03len\x18\x04 \x01(\r\x12\r\n\x05\x66lags\x18\x05 \x01(\r\"\x90\x01\n\x1f\x45xt4ExtMapBlocksExitFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\r\n\x05\x66lags\x18\x03 \x01(\r\x12\x0c\n\x04pblk\x18\x04 \x01(\x04\x12\x0c\n\x04lblk\x18\x05 \x01(\r\x12\x0b\n\x03len\x18\x06 \x01(\r\x12\x0e\n\x06mflags\x18\x07 \x01(\r\x12\x0b\n\x03ret\x18\x08 \x01(\x05\"b\n\x1c\x45xt4ExtPutInCacheFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x0c\n\x04lblk\x18\x03 \x01(\r\x12\x0b\n\x03len\x18\x04 \x01(\r\x12\r\n\x05start\x18\x05 \x01(\x04\"d\n\x1d\x45xt4ExtRemoveSpaceFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\r\n\x05start\x18\x03 \x01(\r\x12\x0b\n\x03\x65nd\x18\x04 \x01(\r\x12\r\n\x05\x64\x65pth\x18\x05 \x01(\x05\"\xc1\x01\n!Ext4ExtRemoveSpaceDoneFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\r\n\x05start\x18\x03 \x01(\r\x12\x0b\n\x03\x65nd\x18\x04 \x01(\r\x12\r\n\x05\x64\x65pth\x18\x05 \x01(\x05\x12\x0f\n\x07partial\x18\x06 \x01(\x03\x12\x12\n\neh_entries\x18\x07 \x01(\r\x12\x0f\n\x07pc_lblk\x18\x08 \x01(\r\x12\x0f\n\x07pc_pclu\x18\t \x01(\x04\x12\x10\n\x08pc_state\x18\n \x01(\x05\"A\n\x17\x45xt4ExtRmIdxFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x0c\n\x04pblk\x18\x03 \x01(\x04\"\xba\x01\n\x18\x45xt4ExtRmLeafFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x0f\n\x07partial\x18\x03 \x01(\x03\x12\r\n\x05start\x18\x04 \x01(\r\x12\x0f\n\x07\x65\x65_lblk\x18\x05 \x01(\r\x12\x0f\n\x07\x65\x65_pblk\x18\x06 \x01(\x04\x12\x0e\n\x06\x65\x65_len\x18\x07 \x01(\x05\x12\x0f\n\x07pc_lblk\x18\x08 \x01(\r\x12\x0f\n\x07pc_pclu\x18\t \x01(\x04\x12\x10\n\x08pc_state\x18\n \x01(\x05\"a\n\x1c\x45xt4ExtShowExtentFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x0c\n\x04pblk\x18\x03 \x01(\x04\x12\x0c\n\x04lblk\x18\x04 \x01(\r\x12\x0b\n\x03len\x18\x05 \x01(\r\"q\n\x1d\x45xt4FallocateEnterFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x0e\n\x06offset\x18\x03 \x01(\x03\x12\x0b\n\x03len\x18\x04 \x01(\x03\x12\x0c\n\x04mode\x18\x05 \x01(\x05\x12\x0b\n\x03pos\x18\x06 \x01(\x03\"b\n\x1c\x45xt4FallocateExitFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x0b\n\x03pos\x18\x03 \x01(\x03\x12\x0e\n\x06\x62locks\x18\x04 \x01(\r\x12\x0b\n\x03ret\x18\x05 \x01(\x05\"\x89\x01\n Ext4FindDelallocRangeFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x0c\n\x04\x66rom\x18\x03 \x01(\r\x12\n\n\x02to\x18\x04 \x01(\r\x12\x0f\n\x07reverse\x18\x05 \x01(\x05\x12\r\n\x05\x66ound\x18\x06 \x01(\x05\x12\x11\n\tfound_blk\x18\x07 \x01(\r\"c\n\x15\x45xt4ForgetFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\r\n\x05\x62lock\x18\x03 \x01(\x04\x12\x13\n\x0bis_metadata\x18\x04 \x01(\x05\x12\x0c\n\x04mode\x18\x05 \x01(\r\"p\n\x19\x45xt4FreeBlocksFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\r\n\x05\x62lock\x18\x03 \x01(\x04\x12\r\n\x05\x63ount\x18\x04 \x01(\x04\x12\r\n\x05\x66lags\x18\x05 \x01(\x05\x12\x0c\n\x04mode\x18\x06 \x01(\r\"l\n\x18\x45xt4FreeInodeFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x0b\n\x03uid\x18\x03 \x01(\r\x12\x0b\n\x03gid\x18\x04 \x01(\r\x12\x0e\n\x06\x62locks\x18\x05 \x01(\x04\x12\x0c\n\x04mode\x18\x06 \x01(\r\"}\n)Ext4GetImpliedClusterAllocExitFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\r\n\x05\x66lags\x18\x02 \x01(\r\x12\x0c\n\x04lblk\x18\x03 \x01(\r\x12\x0c\n\x04pblk\x18\x04 \x01(\x04\x12\x0b\n\x03len\x18\x05 \x01(\r\x12\x0b\n\x03ret\x18\x06 \x01(\x05\"]\n&Ext4GetReservedClusterAllocFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x0c\n\x04lblk\x18\x03 \x01(\r\x12\x0b\n\x03len\x18\x04 \x01(\r\"f\n Ext4IndMapBlocksEnterFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x0c\n\x04lblk\x18\x03 \x01(\r\x12\x0b\n\x03len\x18\x04 \x01(\r\x12\r\n\x05\x66lags\x18\x05 \x01(\r\"\x90\x01\n\x1f\x45xt4IndMapBlocksExitFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\r\n\x05\x66lags\x18\x03 \x01(\r\x12\x0c\n\x04pblk\x18\x04 \x01(\x04\x12\x0c\n\x04lblk\x18\x05 \x01(\r\x12\x0b\n\x03len\x18\x06 \x01(\r\x12\x0e\n\x06mflags\x18\x07 \x01(\r\x12\x0b\n\x03ret\x18\x08 \x01(\x05\"S\n\x1a\x45xt4InsertRangeFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x0e\n\x06offset\x18\x03 \x01(\x03\x12\x0b\n\x03len\x18\x04 \x01(\x03\"h\n\x1d\x45xt4InvalidatepageFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\r\n\x05index\x18\x03 \x01(\x04\x12\x0e\n\x06offset\x18\x04 \x01(\x04\x12\x0e\n\x06length\x18\x05 \x01(\r\"\x81\x01\n\x1b\x45xt4JournalStartFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\n\n\x02ip\x18\x02 \x01(\x04\x12\x0e\n\x06\x62locks\x18\x03 \x01(\x05\x12\x12\n\nrsv_blocks\x18\x04 \x01(\x05\x12\x0f\n\x07nblocks\x18\x05 \x01(\x05\x12\x14\n\x0crevoke_creds\x18\x06 \x01(\x05\"N\n#Ext4JournalStartReservedFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\n\n\x02ip\x18\x02 \x01(\x04\x12\x0e\n\x06\x62locks\x18\x03 \x01(\x05\"r\n\'Ext4JournalledInvalidatepageFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\r\n\x05index\x18\x03 \x01(\x04\x12\x0e\n\x06offset\x18\x04 \x01(\x04\x12\x0e\n\x06length\x18\x05 \x01(\r\"g\n!Ext4JournalledWriteEndFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x0b\n\x03pos\x18\x03 \x01(\x03\x12\x0b\n\x03len\x18\x04 \x01(\r\x12\x0e\n\x06\x63opied\x18\x05 \x01(\r\"4\n\x18\x45xt4LoadInodeFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\"<\n\x1e\x45xt4LoadInodeBitmapFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\r\n\x05group\x18\x02 \x01(\r\"E\n\x1d\x45xt4MarkInodeDirtyFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\n\n\x02ip\x18\x03 \x01(\x04\"9\n\x1b\x45xt4MbBitmapLoadFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\r\n\x05group\x18\x02 \x01(\r\">\n Ext4MbBuddyBitmapLoadFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\r\n\x05group\x18\x02 \x01(\r\"E\n&Ext4MbDiscardPreallocationsFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0e\n\x06needed\x18\x02 \x01(\x05\"m\n\x1b\x45xt4MbNewGroupPaFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x11\n\tpa_pstart\x18\x03 \x01(\x04\x12\x11\n\tpa_lstart\x18\x04 \x01(\x04\x12\x0e\n\x06pa_len\x18\x05 \x01(\r\"m\n\x1b\x45xt4MbNewInodePaFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x11\n\tpa_pstart\x18\x03 \x01(\x04\x12\x11\n\tpa_lstart\x18\x04 \x01(\x04\x12\x0e\n\x06pa_len\x18\x05 \x01(\r\"Q\n\x1f\x45xt4MbReleaseGroupPaFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x11\n\tpa_pstart\x18\x02 \x01(\x04\x12\x0e\n\x06pa_len\x18\x03 \x01(\r\"Y\n\x1f\x45xt4MbReleaseInodePaFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\r\n\x05\x62lock\x18\x03 \x01(\x04\x12\r\n\x05\x63ount\x18\x04 \x01(\r\"\x86\x03\n\x1b\x45xt4MballocAllocFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x14\n\x0corig_logical\x18\x03 \x01(\r\x12\x12\n\norig_start\x18\x04 \x01(\x05\x12\x12\n\norig_group\x18\x05 \x01(\r\x12\x10\n\x08orig_len\x18\x06 \x01(\x05\x12\x14\n\x0cgoal_logical\x18\x07 \x01(\r\x12\x12\n\ngoal_start\x18\x08 \x01(\x05\x12\x12\n\ngoal_group\x18\t \x01(\r\x12\x10\n\x08goal_len\x18\n \x01(\x05\x12\x16\n\x0eresult_logical\x18\x0b \x01(\r\x12\x14\n\x0cresult_start\x18\x0c \x01(\x05\x12\x14\n\x0cresult_group\x18\r \x01(\r\x12\x12\n\nresult_len\x18\x0e \x01(\x05\x12\r\n\x05\x66ound\x18\x0f \x01(\r\x12\x0e\n\x06groups\x18\x10 \x01(\r\x12\r\n\x05\x62uddy\x18\x11 \x01(\r\x12\r\n\x05\x66lags\x18\x12 \x01(\r\x12\x0c\n\x04tail\x18\x13 \x01(\r\x12\n\n\x02\x63r\x18\x14 \x01(\r\"y\n\x1d\x45xt4MballocDiscardFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x14\n\x0cresult_start\x18\x03 \x01(\x05\x12\x14\n\x0cresult_group\x18\x04 \x01(\r\x12\x12\n\nresult_len\x18\x05 \x01(\x05\"v\n\x1a\x45xt4MballocFreeFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x14\n\x0cresult_start\x18\x03 \x01(\x05\x12\x14\n\x0cresult_group\x18\x04 \x01(\r\x12\x12\n\nresult_len\x18\x05 \x01(\x05\"\xe2\x01\n\x1e\x45xt4MballocPreallocFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x14\n\x0corig_logical\x18\x03 \x01(\r\x12\x12\n\norig_start\x18\x04 \x01(\x05\x12\x12\n\norig_group\x18\x05 \x01(\r\x12\x10\n\x08orig_len\x18\x06 \x01(\x05\x12\x16\n\x0eresult_logical\x18\x07 \x01(\r\x12\x14\n\x0cresult_start\x18\x08 \x01(\x05\x12\x14\n\x0cresult_group\x18\t \x01(\r\x12\x12\n\nresult_len\x18\n \x01(\x05\"y\n#Ext4OtherInodeUpdateTimeFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x10\n\x08orig_ino\x18\x03 \x01(\x04\x12\x0b\n\x03uid\x18\x04 \x01(\r\x12\x0b\n\x03gid\x18\x05 \x01(\r\x12\x0c\n\x04mode\x18\x06 \x01(\r\"_\n\x18\x45xt4PunchHoleFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x0e\n\x06offset\x18\x03 \x01(\x03\x12\x0b\n\x03len\x18\x04 \x01(\x03\x12\x0c\n\x04mode\x18\x05 \x01(\x05\"R\n\"Ext4ReadBlockBitmapLoadFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\r\n\x05group\x18\x02 \x01(\r\x12\x10\n\x08prefetch\x18\x03 \x01(\r\"B\n\x17\x45xt4ReadpageFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\r\n\x05index\x18\x03 \x01(\x04\"E\n\x1a\x45xt4ReleasepageFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\r\n\x05index\x18\x03 \x01(\x04\"\xc8\x01\n\x1b\x45xt4RemoveBlocksFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x0c\n\x04\x66rom\x18\x03 \x01(\r\x12\n\n\x02to\x18\x04 \x01(\r\x12\x0f\n\x07partial\x18\x05 \x01(\x03\x12\x0f\n\x07\x65\x65_pblk\x18\x06 \x01(\x04\x12\x0f\n\x07\x65\x65_lblk\x18\x07 \x01(\r\x12\x0e\n\x06\x65\x65_len\x18\x08 \x01(\r\x12\x0f\n\x07pc_lblk\x18\t \x01(\r\x12\x0f\n\x07pc_pclu\x18\n \x01(\x04\x12\x10\n\x08pc_state\x18\x0b \x01(\x05\"\xb1\x01\n\x1c\x45xt4RequestBlocksFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x0b\n\x03len\x18\x03 \x01(\r\x12\x0f\n\x07logical\x18\x04 \x01(\r\x12\r\n\x05lleft\x18\x05 \x01(\r\x12\x0e\n\x06lright\x18\x06 \x01(\r\x12\x0c\n\x04goal\x18\x07 \x01(\x04\x12\r\n\x05pleft\x18\x08 \x01(\x04\x12\x0e\n\x06pright\x18\t \x01(\x04\x12\r\n\x05\x66lags\x18\n \x01(\r\"E\n\x1b\x45xt4RequestInodeFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03\x64ir\x18\x02 \x01(\x04\x12\x0c\n\x04mode\x18\x03 \x01(\r\"2\n\x15\x45xt4SyncFsFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0c\n\x04wait\x18\x02 \x01(\x05\"m\n\x1a\x45xt4TrimAllFreeFtraceEvent\x12\x11\n\tdev_major\x18\x01 \x01(\x05\x12\x11\n\tdev_minor\x18\x02 \x01(\x05\x12\r\n\x05group\x18\x03 \x01(\r\x12\r\n\x05start\x18\x04 \x01(\x05\x12\x0b\n\x03len\x18\x05 \x01(\x05\"l\n\x19\x45xt4TrimExtentFtraceEvent\x12\x11\n\tdev_major\x18\x01 \x01(\x05\x12\x11\n\tdev_minor\x18\x02 \x01(\x05\x12\r\n\x05group\x18\x03 \x01(\r\x12\r\n\x05start\x18\x04 \x01(\x05\x12\x0b\n\x03len\x18\x05 \x01(\x05\"H\n\x1c\x45xt4TruncateEnterFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x0e\n\x06\x62locks\x18\x03 \x01(\x04\"G\n\x1b\x45xt4TruncateExitFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x0e\n\x06\x62locks\x18\x03 \x01(\x04\"T\n\x1a\x45xt4UnlinkEnterFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x0e\n\x06parent\x18\x03 \x01(\x04\x12\x0c\n\x04size\x18\x04 \x01(\x03\"B\n\x19\x45xt4UnlinkExitFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x0b\n\x03ret\x18\x03 \x01(\x05\"^\n\x19\x45xt4WriteBeginFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x0b\n\x03pos\x18\x03 \x01(\x03\x12\x0b\n\x03len\x18\x04 \x01(\r\x12\r\n\x05\x66lags\x18\x05 \x01(\r\"]\n\x17\x45xt4WriteEndFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x0b\n\x03pos\x18\x03 \x01(\x03\x12\x0b\n\x03len\x18\x04 \x01(\r\x12\x0e\n\x06\x63opied\x18\x05 \x01(\r\"C\n\x18\x45xt4WritepageFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\r\n\x05index\x18\x03 \x01(\x04\"\xe0\x01\n\x19\x45xt4WritepagesFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x13\n\x0bnr_to_write\x18\x03 \x01(\x03\x12\x15\n\rpages_skipped\x18\x04 \x01(\x03\x12\x13\n\x0brange_start\x18\x05 \x01(\x03\x12\x11\n\trange_end\x18\x06 \x01(\x03\x12\x17\n\x0fwriteback_index\x18\x07 \x01(\x04\x12\x11\n\tsync_mode\x18\x08 \x01(\x05\x12\x13\n\x0b\x66or_kupdate\x18\t \x01(\r\x12\x14\n\x0crange_cyclic\x18\n \x01(\r\"\xa2\x01\n\x1f\x45xt4WritepagesResultFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x0b\n\x03ret\x18\x03 \x01(\x05\x12\x15\n\rpages_written\x18\x04 \x01(\x05\x12\x15\n\rpages_skipped\x18\x05 \x01(\x03\x12\x17\n\x0fwriteback_index\x18\x06 \x01(\x04\x12\x11\n\tsync_mode\x18\x07 \x01(\x05\"_\n\x18\x45xt4ZeroRangeFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x0e\n\x06offset\x18\x03 \x01(\x03\x12\x0b\n\x03len\x18\x04 \x01(\x03\x12\x0c\n\x04mode\x18\x05 \x01(\x05\"d\n\x1a\x46\x32\x66sDoSubmitBioFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\r\n\x05\x62type\x18\x02 \x01(\x05\x12\x0c\n\x04sync\x18\x03 \x01(\r\x12\x0e\n\x06sector\x18\x04 \x01(\x04\x12\x0c\n\x04size\x18\x05 \x01(\r\"\x8e\x01\n\x19\x46\x32\x66sEvictInodeFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x0c\n\x04pino\x18\x03 \x01(\x04\x12\x0c\n\x04mode\x18\x04 \x01(\r\x12\x0c\n\x04size\x18\x05 \x01(\x03\x12\r\n\x05nlink\x18\x06 \x01(\r\x12\x0e\n\x06\x62locks\x18\x07 \x01(\x04\x12\x0e\n\x06\x61\x64vise\x18\x08 \x01(\r\"\x8a\x01\n\x18\x46\x32\x66sFallocateFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x0c\n\x04mode\x18\x03 \x01(\x05\x12\x0e\n\x06offset\x18\x04 \x01(\x03\x12\x0b\n\x03len\x18\x05 \x01(\x03\x12\x0c\n\x04size\x18\x06 \x01(\x03\x12\x0e\n\x06\x62locks\x18\x07 \x01(\x04\x12\x0b\n\x03ret\x18\x08 \x01(\x05\"w\n\x1b\x46\x32\x66sGetDataBlockFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x0e\n\x06iblock\x18\x03 \x01(\x04\x12\x10\n\x08\x62h_start\x18\x04 \x01(\x04\x12\x0f\n\x07\x62h_size\x18\x05 \x01(\x04\x12\x0b\n\x03ret\x18\x06 \x01(\x05\"\xce\x01\n\x18\x46\x32\x66sGetVictimFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0c\n\x04type\x18\x02 \x01(\x05\x12\x0f\n\x07gc_type\x18\x03 \x01(\x05\x12\x12\n\nalloc_mode\x18\x04 \x01(\x05\x12\x0f\n\x07gc_mode\x18\x05 \x01(\x05\x12\x0e\n\x06victim\x18\x06 \x01(\r\x12\x10\n\x08ofs_unit\x18\x07 \x01(\r\x12\x12\n\npre_victim\x18\x08 \x01(\r\x12\x0f\n\x07prefree\x18\t \x01(\r\x12\x0c\n\x04\x66ree\x18\n \x01(\r\x12\x0c\n\x04\x63ost\x18\x0b \x01(\r\"\x88\x01\n\x13\x46\x32\x66sIgetFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x0c\n\x04pino\x18\x03 \x01(\x04\x12\x0c\n\x04mode\x18\x04 \x01(\r\x12\x0c\n\x04size\x18\x05 \x01(\x03\x12\r\n\x05nlink\x18\x06 \x01(\r\x12\x0e\n\x06\x62locks\x18\x07 \x01(\x04\x12\x0e\n\x06\x61\x64vise\x18\x08 \x01(\r\"@\n\x17\x46\x32\x66sIgetExitFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x0b\n\x03ret\x18\x03 \x01(\x05\"@\n\x17\x46\x32\x66sNewInodeFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x0b\n\x03ret\x18\x03 \x01(\x05\"\x8f\x01\n\x17\x46\x32\x66sReadpageFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\r\n\x05index\x18\x03 \x01(\x04\x12\x0f\n\x07\x62lkaddr\x18\x04 \x01(\x04\x12\x0c\n\x04type\x18\x05 \x01(\x05\x12\x0b\n\x03\x64ir\x18\x06 \x01(\x05\x12\r\n\x05\x64irty\x18\x07 \x01(\x05\x12\x10\n\x08uptodate\x18\x08 \x01(\x05\"O\n\x1e\x46\x32\x66sReserveNewBlockFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03nid\x18\x02 \x01(\r\x12\x13\n\x0bofs_in_node\x18\x03 \x01(\r\"\x82\x01\n\x1b\x46\x32\x66sSetPageDirtyFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x0c\n\x04type\x18\x03 \x01(\x05\x12\x0b\n\x03\x64ir\x18\x04 \x01(\x05\x12\r\n\x05index\x18\x05 \x01(\x04\x12\r\n\x05\x64irty\x18\x06 \x01(\x05\x12\x10\n\x08uptodate\x18\x07 \x01(\x05\"f\n\x1e\x46\x32\x66sSubmitWritePageFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x0c\n\x04type\x18\x03 \x01(\x05\x12\r\n\x05index\x18\x04 \x01(\x04\x12\r\n\x05\x62lock\x18\x05 \x01(\r\"\x91\x01\n\x1c\x46\x32\x66sSyncFileEnterFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x0c\n\x04pino\x18\x03 \x01(\x04\x12\x0c\n\x04mode\x18\x04 \x01(\r\x12\x0c\n\x04size\x18\x05 \x01(\x03\x12\r\n\x05nlink\x18\x06 \x01(\r\x12\x0e\n\x06\x62locks\x18\x07 \x01(\x04\x12\x0e\n\x06\x61\x64vise\x18\x08 \x01(\r\"z\n\x1b\x46\x32\x66sSyncFileExitFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x0f\n\x07need_cp\x18\x03 \x01(\r\x12\x10\n\x08\x64\x61tasync\x18\x04 \x01(\x05\x12\x0b\n\x03ret\x18\x05 \x01(\x05\x12\x11\n\tcp_reason\x18\x06 \x01(\x05\"A\n\x15\x46\x32\x66sSyncFsFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\r\n\x05\x64irty\x18\x02 \x01(\x05\x12\x0c\n\x04wait\x18\x03 \x01(\x05\"\x8c\x01\n\x17\x46\x32\x66sTruncateFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x0c\n\x04pino\x18\x03 \x01(\x04\x12\x0c\n\x04mode\x18\x04 \x01(\r\x12\x0c\n\x04size\x18\x05 \x01(\x03\x12\r\n\x05nlink\x18\x06 \x01(\r\x12\x0e\n\x06\x62locks\x18\x07 \x01(\x04\x12\x0e\n\x06\x61\x64vise\x18\x08 \x01(\r\"j\n\"F2fsTruncateBlocksEnterFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x0c\n\x04size\x18\x03 \x01(\x03\x12\x0e\n\x06\x62locks\x18\x04 \x01(\x04\x12\x0c\n\x04\x66rom\x18\x05 \x01(\x04\"J\n!F2fsTruncateBlocksExitFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x0b\n\x03ret\x18\x03 \x01(\x05\"j\n&F2fsTruncateDataBlocksRangeFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x0b\n\x03nid\x18\x03 \x01(\r\x12\x0b\n\x03ofs\x18\x04 \x01(\r\x12\x0c\n\x04\x66ree\x18\x05 \x01(\x05\"o\n\'F2fsTruncateInodeBlocksEnterFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x0c\n\x04size\x18\x03 \x01(\x03\x12\x0e\n\x06\x62locks\x18\x04 \x01(\x04\x12\x0c\n\x04\x66rom\x18\x05 \x01(\x04\"O\n&F2fsTruncateInodeBlocksExitFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x0b\n\x03ret\x18\x03 \x01(\x05\"V\n\x1b\x46\x32\x66sTruncateNodeFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x0b\n\x03nid\x18\x03 \x01(\r\x12\x10\n\x08\x62lk_addr\x18\x04 \x01(\r\"\\\n!F2fsTruncateNodesEnterFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x0b\n\x03nid\x18\x03 \x01(\r\x12\x10\n\x08\x62lk_addr\x18\x04 \x01(\r\"I\n F2fsTruncateNodesExitFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x0b\n\x03ret\x18\x03 \x01(\x05\"h\n#F2fsTruncatePartialNodesFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x0b\n\x03nid\x18\x03 \x01(\r\x12\r\n\x05\x64\x65pth\x18\x04 \x01(\x05\x12\x0b\n\x03\x65rr\x18\x05 \x01(\x05\"b\n\x1a\x46\x32\x66sUnlinkEnterFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x0c\n\x04size\x18\x03 \x01(\x03\x12\x0e\n\x06\x62locks\x18\x04 \x01(\x04\x12\x0c\n\x04name\x18\x05 \x01(\t\"B\n\x19\x46\x32\x66sUnlinkExitFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x0b\n\x03ret\x18\x03 \x01(\x05\"\x83\x01\n\x1c\x46\x32\x66sVmPageMkwriteFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x0c\n\x04type\x18\x03 \x01(\x05\x12\x0b\n\x03\x64ir\x18\x04 \x01(\x05\x12\r\n\x05index\x18\x05 \x01(\x04\x12\r\n\x05\x64irty\x18\x06 \x01(\x05\x12\x10\n\x08uptodate\x18\x07 \x01(\x05\"^\n\x19\x46\x32\x66sWriteBeginFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x0b\n\x03pos\x18\x03 \x01(\x03\x12\x0b\n\x03len\x18\x04 \x01(\r\x12\r\n\x05\x66lags\x18\x05 \x01(\r\"l\n\x1e\x46\x32\x66sWriteCheckpointFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x11\n\tis_umount\x18\x02 \x01(\r\x12\x0b\n\x03msg\x18\x03 \x01(\t\x12\x0e\n\x06reason\x18\x04 \x01(\x05\x12\r\n\x05phase\x18\x05 \x01(\r\"]\n\x17\x46\x32\x66sWriteEndFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ino\x18\x02 \x01(\x04\x12\x0b\n\x03pos\x18\x03 \x01(\x03\x12\x0b\n\x03len\x18\x04 \x01(\r\x12\x0e\n\x06\x63opied\x18\x05 \x01(\r\"\xa9\x03\n\x15\x46\x32\x66sIostatFtraceEvent\x12\x0f\n\x07\x61pp_bio\x18\x01 \x01(\x04\x12\x10\n\x08\x61pp_brio\x18\x02 \x01(\x04\x12\x0f\n\x07\x61pp_dio\x18\x03 \x01(\x04\x12\x10\n\x08\x61pp_drio\x18\x04 \x01(\x04\x12\x0f\n\x07\x61pp_mio\x18\x05 \x01(\x04\x12\x10\n\x08\x61pp_mrio\x18\x06 \x01(\x04\x12\x0f\n\x07\x61pp_rio\x18\x07 \x01(\x04\x12\x0f\n\x07\x61pp_wio\x18\x08 \x01(\x04\x12\x0b\n\x03\x64\x65v\x18\t \x01(\x04\x12\x10\n\x08\x66s_cdrio\x18\n \x01(\x04\x12\x11\n\tfs_cp_dio\x18\x0b \x01(\x04\x12\x11\n\tfs_cp_mio\x18\x0c \x01(\x04\x12\x11\n\tfs_cp_nio\x18\r \x01(\x04\x12\x0e\n\x06\x66s_dio\x18\x0e \x01(\x04\x12\x12\n\nfs_discard\x18\x0f \x01(\x04\x12\x0f\n\x07\x66s_drio\x18\x10 \x01(\x04\x12\x11\n\tfs_gc_dio\x18\x11 \x01(\x04\x12\x11\n\tfs_gc_nio\x18\x12 \x01(\x04\x12\x10\n\x08\x66s_gdrio\x18\x13 \x01(\x04\x12\x0e\n\x06\x66s_mio\x18\x14 \x01(\x04\x12\x0f\n\x07\x66s_mrio\x18\x15 \x01(\x04\x12\x0e\n\x06\x66s_nio\x18\x16 \x01(\x04\x12\x0f\n\x07\x66s_nrio\x18\x17 \x01(\x04\"\xc7\x04\n\x1c\x46\x32\x66sIostatLatencyFtraceEvent\x12\x10\n\x08\x64_rd_avg\x18\x01 \x01(\r\x12\x10\n\x08\x64_rd_cnt\x18\x02 \x01(\r\x12\x11\n\td_rd_peak\x18\x03 \x01(\r\x12\x13\n\x0b\x64_wr_as_avg\x18\x04 \x01(\r\x12\x13\n\x0b\x64_wr_as_cnt\x18\x05 \x01(\r\x12\x14\n\x0c\x64_wr_as_peak\x18\x06 \x01(\r\x12\x12\n\nd_wr_s_avg\x18\x07 \x01(\r\x12\x12\n\nd_wr_s_cnt\x18\x08 \x01(\r\x12\x13\n\x0b\x64_wr_s_peak\x18\t \x01(\r\x12\x0b\n\x03\x64\x65v\x18\n \x01(\x04\x12\x10\n\x08m_rd_avg\x18\x0b \x01(\r\x12\x10\n\x08m_rd_cnt\x18\x0c \x01(\r\x12\x11\n\tm_rd_peak\x18\r \x01(\r\x12\x13\n\x0bm_wr_as_avg\x18\x0e \x01(\r\x12\x13\n\x0bm_wr_as_cnt\x18\x0f \x01(\r\x12\x14\n\x0cm_wr_as_peak\x18\x10 \x01(\r\x12\x12\n\nm_wr_s_avg\x18\x11 \x01(\r\x12\x12\n\nm_wr_s_cnt\x18\x12 \x01(\r\x12\x13\n\x0bm_wr_s_peak\x18\x13 \x01(\r\x12\x10\n\x08n_rd_avg\x18\x14 \x01(\r\x12\x10\n\x08n_rd_cnt\x18\x15 \x01(\r\x12\x11\n\tn_rd_peak\x18\x16 \x01(\r\x12\x13\n\x0bn_wr_as_avg\x18\x17 \x01(\r\x12\x13\n\x0bn_wr_as_cnt\x18\x18 \x01(\r\x12\x14\n\x0cn_wr_as_peak\x18\x19 \x01(\r\x12\x12\n\nn_wr_s_avg\x18\x1a \x01(\r\x12\x12\n\nn_wr_s_cnt\x18\x1b \x01(\r\x12\x13\n\x0bn_wr_s_peak\x18\x1c \x01(\r\"Z\n\x1b\x46\x32\x66sBackgroundGcFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0f\n\x07wait_ms\x18\x02 \x01(\r\x12\x0f\n\x07prefree\x18\x03 \x01(\r\x12\x0c\n\x04\x66ree\x18\x04 \x01(\r\"\x8e\x02\n\x16\x46\x32\x66sGcBeginFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0c\n\x04sync\x18\x02 \x01(\r\x12\x12\n\nbackground\x18\x03 \x01(\r\x12\x13\n\x0b\x64irty_nodes\x18\x04 \x01(\x03\x12\x13\n\x0b\x64irty_dents\x18\x05 \x01(\x03\x12\x13\n\x0b\x64irty_imeta\x18\x06 \x01(\x03\x12\x10\n\x08\x66ree_sec\x18\x07 \x01(\r\x12\x10\n\x08\x66ree_seg\x18\x08 \x01(\r\x12\x14\n\x0creserved_seg\x18\t \x01(\x05\x12\x13\n\x0bprefree_seg\x18\n \x01(\r\x12\x0f\n\x07gc_type\x18\x0b \x01(\x05\x12\x10\n\x08no_bg_gc\x18\x0c \x01(\r\x12\x14\n\x0cnr_free_secs\x18\r \x01(\r\"\xe4\x01\n\x14\x46\x32\x66sGcEndFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0b\n\x03ret\x18\x02 \x01(\x05\x12\x11\n\tseg_freed\x18\x03 \x01(\x05\x12\x11\n\tsec_freed\x18\x04 \x01(\x05\x12\x13\n\x0b\x64irty_nodes\x18\x05 \x01(\x03\x12\x13\n\x0b\x64irty_dents\x18\x06 \x01(\x03\x12\x13\n\x0b\x64irty_imeta\x18\x07 \x01(\x03\x12\x10\n\x08\x66ree_sec\x18\x08 \x01(\r\x12\x10\n\x08\x66ree_seg\x18\t \x01(\r\x12\x14\n\x0creserved_seg\x18\n \x01(\x05\x12\x13\n\x0bprefree_seg\x18\x0b \x01(\r\"\x92\x02\n\x1e\x46\x32\x66sLockElapsedTimeFtraceEvent\x12\x0b\n\x03\x64\x65v\x18\x01 \x01(\x04\x12\x0c\n\x04\x63omm\x18\x02 \x01(\t\x12\x0b\n\x03pid\x18\x03 \x01(\x05\x12\x0c\n\x04prio\x18\x04 \x01(\x05\x12\x14\n\x0cioprio_class\x18\x05 \x01(\x05\x12\x13\n\x0bioprio_data\x18\x06 \x01(\x05\x12\x11\n\tlock_name\x18\x07 \x01(\r\x12\x10\n\x08is_write\x18\x08 \x01(\r\x12\x12\n\ntotal_time\x18\t \x01(\x04\x12\x14\n\x0crunning_time\x18\n \x01(\x04\x12\x15\n\rrunnable_time\x18\x0b \x01(\x04\x12\x15\n\rio_sleep_time\x18\x0c \x01(\x04\x12\x12\n\nother_time\x18\r \x01(\x04\"N\n\x19\x46\x61strpcDmaStatFtraceEvent\x12\x0b\n\x03\x63id\x18\x01 \x01(\x05\x12\x0b\n\x03len\x18\x02 \x01(\x03\x12\x17\n\x0ftotal_allocated\x18\x03 \x01(\x04\"D\n\x19\x46\x61strpcDmaFreeFtraceEvent\x12\x0b\n\x03\x63id\x18\x01 \x01(\x05\x12\x0c\n\x04phys\x18\x02 \x01(\x04\x12\x0c\n\x04size\x18\x03 \x01(\x04\"c\n\x1a\x46\x61strpcDmaAllocFtraceEvent\x12\x0b\n\x03\x63id\x18\x01 \x01(\x05\x12\x0c\n\x04phys\x18\x02 \x01(\x04\x12\x0c\n\x04size\x18\x03 \x01(\x04\x12\x0c\n\x04\x61ttr\x18\x04 \x01(\x04\x12\x0e\n\x06mflags\x18\x05 \x01(\x05\"E\n\x1a\x46\x61strpcDmaUnmapFtraceEvent\x12\x0b\n\x03\x63id\x18\x01 \x01(\x05\x12\x0c\n\x04phys\x18\x02 \x01(\x04\x12\x0c\n\x04size\x18\x03 \x01(\x04\"z\n\x18\x46\x61strpcDmaMapFtraceEvent\x12\x0b\n\x03\x63id\x18\x01 \x01(\x05\x12\n\n\x02\x66\x64\x18\x02 \x01(\x05\x12\x0c\n\x04phys\x18\x03 \x01(\x04\x12\x0c\n\x04size\x18\x04 \x01(\x04\x12\x0b\n\x03len\x18\x05 \x01(\x04\x12\x0c\n\x04\x61ttr\x18\x06 \x01(\r\x12\x0e\n\x06mflags\x18\x07 \x01(\x05\"X\n\x14\x46\x65nceInitFtraceEvent\x12\x0f\n\x07\x63ontext\x18\x01 \x01(\r\x12\x0e\n\x06\x64river\x18\x02 \x01(\t\x12\r\n\x05seqno\x18\x03 \x01(\r\x12\x10\n\x08timeline\x18\x04 \x01(\t\"[\n\x17\x46\x65nceDestroyFtraceEvent\x12\x0f\n\x07\x63ontext\x18\x01 \x01(\r\x12\x0e\n\x06\x64river\x18\x02 \x01(\t\x12\r\n\x05seqno\x18\x03 \x01(\r\x12\x10\n\x08timeline\x18\x04 \x01(\t\"`\n\x1c\x46\x65nceEnableSignalFtraceEvent\x12\x0f\n\x07\x63ontext\x18\x01 \x01(\r\x12\x0e\n\x06\x64river\x18\x02 \x01(\t\x12\r\n\x05seqno\x18\x03 \x01(\r\x12\x10\n\x08timeline\x18\x04 \x01(\t\"\\\n\x18\x46\x65nceSignaledFtraceEvent\x12\x0f\n\x07\x63ontext\x18\x01 \x01(\r\x12\x0e\n\x06\x64river\x18\x02 \x01(\t\x12\r\n\x05seqno\x18\x03 \x01(\r\x12\x10\n\x08timeline\x18\x04 \x01(\t\"l\n\"MmFilemapAddToPageCacheFtraceEvent\x12\x0b\n\x03pfn\x18\x01 \x01(\x04\x12\r\n\x05i_ino\x18\x02 \x01(\x04\x12\r\n\x05index\x18\x03 \x01(\x04\x12\r\n\x05s_dev\x18\x04 \x01(\x04\x12\x0c\n\x04page\x18\x05 \x01(\x04\"q\n\'MmFilemapDeleteFromPageCacheFtraceEvent\x12\x0b\n\x03pfn\x18\x01 \x01(\x04\x12\r\n\x05i_ino\x18\x02 \x01(\x04\x12\r\n\x05index\x18\x03 \x01(\x04\x12\r\n\x05s_dev\x18\x04 \x01(\x04\x12\x0c\n\x04page\x18\x05 \x01(\x04\"E\n\x14\x44oSysOpenFtraceEvent\x12\x10\n\x08\x66ilename\x18\x01 \x01(\t\x12\r\n\x05\x66lags\x18\x02 \x01(\x05\x12\x0c\n\x04mode\x18\x03 \x01(\x05\"\'\n\x13OpenExecFtraceEvent\x12\x10\n\x08\x66ilename\x18\x01 \x01(\t\"+\n\x10PrintFtraceEvent\x12\n\n\x02ip\x18\x01 \x01(\x04\x12\x0b\n\x03\x62uf\x18\x02 \x01(\t\"8\n\x19\x46uncgraphEntryFtraceEvent\x12\r\n\x05\x64\x65pth\x18\x01 \x01(\x05\x12\x0c\n\x04\x66unc\x18\x02 \x01(\x04\"k\n\x18\x46uncgraphExitFtraceEvent\x12\x10\n\x08\x63\x61lltime\x18\x01 \x01(\x04\x12\r\n\x05\x64\x65pth\x18\x02 \x01(\x05\x12\x0c\n\x04\x66unc\x18\x03 \x01(\x04\x12\x0f\n\x07overrun\x18\x04 \x01(\x04\x12\x0f\n\x07rettime\x18\x05 \x01(\x04\"t\n\x1e\x46wtpPerfettoCounterFtraceEvent\x12\x11\n\ttimestamp\x18\x01 \x01(\x04\x12\x10\n\x08track_id\x18\x02 \x01(\r\x12\x10\n\x08\x63\x61tegory\x18\x03 \x01(\t\x12\x0c\n\x04name\x18\x04 \x01(\t\x12\r\n\x05value\x18\x05 \x01(\r\"r\n\x1c\x46wtpPerfettoSliceFtraceEvent\x12\x11\n\ttimestamp\x18\x01 \x01(\x04\x12\x10\n\x08track_id\x18\x02 \x01(\r\x12\x10\n\x08\x63\x61tegory\x18\x03 \x01(\t\x12\x0c\n\x04name\x18\x04 \x01(\t\x12\r\n\x05\x62\x65gin\x18\x05 \x01(\r\"X\n\x1eG2dTracingMarkWriteFtraceEvent\x12\x0b\n\x03pid\x18\x01 \x01(\x05\x12\x0c\n\x04name\x18\x04 \x01(\t\x12\x0c\n\x04type\x18\x05 \x01(\r\x12\r\n\x05value\x18\x06 \x01(\x05\"\xc2\x01\n\x12GenericFtraceEvent\x12\x12\n\nevent_name\x18\x01 \x01(\t\x12\x38\n\x05\x66ield\x18\x02 \x03(\x0b\x32).perfetto.protos.GenericFtraceEvent.Field\x1a^\n\x05\x46ield\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x13\n\tstr_value\x18\x03 \x01(\tH\x00\x12\x13\n\tint_value\x18\x04 \x01(\x03H\x00\x12\x14\n\nuint_value\x18\x05 \x01(\x04H\x00\x42\x07\n\x05value\"\xbe\x01\n\x0bKprobeEvent\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x35\n\x04type\x18\x02 \x01(\x0e\x32\'.perfetto.protos.KprobeEvent.KprobeType\"j\n\nKprobeType\x12\x17\n\x13KPROBE_TYPE_UNKNOWN\x10\x00\x12\x15\n\x11KPROBE_TYPE_BEGIN\x10\x01\x12\x13\n\x0fKPROBE_TYPE_END\x10\x02\x12\x17\n\x13KPROBE_TYPE_INSTANT\x10\x03\"=\n\x19GoogleIccEventFtraceEvent\x12\r\n\x05\x65vent\x18\x01 \x01(\t\x12\x11\n\ttimestamp\x18\x02 \x01(\x04\"=\n\x19GoogleIrmEventFtraceEvent\x12\r\n\x05\x65vent\x18\x01 \x01(\t\x12\x11\n\ttimestamp\x18\x02 \x01(\x04\"C\n\x16GpuMemTotalFtraceEvent\x12\x0e\n\x06gpu_id\x18\x01 \x01(\r\x12\x0b\n\x03pid\x18\x02 \x01(\r\x12\x0c\n\x04size\x18\x03 \x01(\x04\"z\n\x16\x44rmSchedJobFtraceEvent\x12\x0e\n\x06\x65ntity\x18\x01 \x01(\x04\x12\r\n\x05\x66\x65nce\x18\x02 \x01(\x04\x12\x14\n\x0chw_job_count\x18\x03 \x01(\x05\x12\n\n\x02id\x18\x04 \x01(\x04\x12\x11\n\tjob_count\x18\x05 \x01(\r\x12\x0c\n\x04name\x18\x06 \x01(\t\"x\n\x14\x44rmRunJobFtraceEvent\x12\x0e\n\x06\x65ntity\x18\x01 \x01(\x04\x12\r\n\x05\x66\x65nce\x18\x02 \x01(\x04\x12\x14\n\x0chw_job_count\x18\x03 \x01(\x05\x12\n\n\x02id\x18\x04 \x01(\x04\x12\x11\n\tjob_count\x18\x05 \x01(\r\x12\x0c\n\x04name\x18\x06 \x01(\t\".\n\x1d\x44rmSchedProcessJobFtraceEvent\x12\r\n\x05\x66\x65nce\x18\x01 \x01(\x04\"f\n\x1c\x44rmSchedJobAddDepFtraceEvent\x12\x15\n\rfence_context\x18\x01 \x01(\x04\x12\x13\n\x0b\x66\x65nce_seqno\x18\x02 \x01(\x04\x12\x0b\n\x03\x63tx\x18\x03 \x01(\x04\x12\r\n\x05seqno\x18\x04 \x01(\x04\"H\n\x1a\x44rmSchedJobDoneFtraceEvent\x12\x15\n\rfence_context\x18\x01 \x01(\x04\x12\x13\n\x0b\x66\x65nce_seqno\x18\x02 \x01(\x04\"\xa0\x01\n\x1b\x44rmSchedJobQueueFtraceEvent\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x11\n\tjob_count\x18\x02 \x01(\r\x12\x14\n\x0chw_job_count\x18\x03 \x01(\x05\x12\x0b\n\x03\x64\x65v\x18\x04 \x01(\t\x12\x15\n\rfence_context\x18\x05 \x01(\x04\x12\x13\n\x0b\x66\x65nce_seqno\x18\x06 \x01(\x04\x12\x11\n\tclient_id\x18\x07 \x01(\x04\"\x9e\x01\n\x19\x44rmSchedJobRunFtraceEvent\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x11\n\tjob_count\x18\x02 \x01(\r\x12\x14\n\x0chw_job_count\x18\x03 \x01(\x05\x12\x0b\n\x03\x64\x65v\x18\x04 \x01(\t\x12\x15\n\rfence_context\x18\x05 \x01(\x04\x12\x13\n\x0b\x66\x65nce_seqno\x18\x06 \x01(\x04\x12\x11\n\tclient_id\x18\x07 \x01(\x04\"m\n#DrmSchedJobUnschedulableFtraceEvent\x12\x15\n\rfence_context\x18\x01 \x01(\x04\x12\x13\n\x0b\x66\x65nce_seqno\x18\x02 \x01(\x04\x12\x0b\n\x03\x63tx\x18\x03 \x01(\x04\x12\r\n\x05seqno\x18\x04 \x01(\x04\"\x15\n\x13HypEnterFtraceEvent\"\x14\n\x12HypExitFtraceEvent\"3\n\x14HostHcallFtraceEvent\x12\n\n\x02id\x18\x01 \x01(\r\x12\x0f\n\x07invalid\x18\x02 \x01(\r\"3\n\x12HostSmcFtraceEvent\x12\n\n\x02id\x18\x01 \x01(\x04\x12\x11\n\tforwarded\x18\x02 \x01(\r\"4\n\x17HostMemAbortFtraceEvent\x12\x0b\n\x03\x65sr\x18\x01 \x01(\x04\x12\x0c\n\x04\x61\x64\x64r\x18\x02 \x01(\x04\"\x87\x01\n\x16HostFfaCallFtraceEvent\x12\x0f\n\x07\x66unc_id\x18\x01 \x01(\x04\x12\x0e\n\x06res_a1\x18\x02 \x01(\x04\x12\x0e\n\x06res_a2\x18\x03 \x01(\x04\x12\x0e\n\x06res_a3\x18\x04 \x01(\x04\x12\x0e\n\x06res_a4\x18\x05 \x01(\x04\x12\x0f\n\x07handled\x18\x06 \x01(\x05\x12\x0b\n\x03\x65rr\x18\x07 \x01(\x05\"?\n\x15IommuIdmapFtraceEvent\x12\x0c\n\x04\x66rom\x18\x01 \x01(\x04\x12\n\n\x02to\x18\x02 \x01(\x04\x12\x0c\n\x04prot\x18\x03 \x01(\x05\"7\n\x19PsciMemProtectFtraceEvent\x12\r\n\x05\x63ount\x18\x01 \x01(\x04\x12\x0b\n\x03was\x18\x02 \x01(\x04\"=\n\x1eHypervisorHostHcallFtraceEvent\x12\n\n\x02id\x18\x01 \x01(\r\x12\x0f\n\x07invalid\x18\x02 \x01(\r\"=\n\x1cHypervisorHostSmcFtraceEvent\x12\n\n\x02id\x18\x01 \x01(\x04\x12\x11\n\tforwarded\x18\x02 \x01(\r\"\x1e\n\x1cHypervisorHypExitFtraceEvent\"I\n\x1fHypervisorIommuIdmapFtraceEvent\x12\x0c\n\x04\x66rom\x18\x01 \x01(\x04\x12\n\n\x02to\x18\x02 \x01(\x04\x12\x0c\n\x04prot\x18\x03 \x01(\x05\"A\n#HypervisorPsciMemProtectFtraceEvent\x12\r\n\x05\x63ount\x18\x01 \x01(\x04\x12\x0b\n\x03was\x18\x02 \x01(\x04\">\n!HypervisorHostMemAbortFtraceEvent\x12\x0b\n\x03\x65sr\x18\x01 \x01(\x04\x12\x0c\n\x04\x61\x64\x64r\x18\x02 \x01(\x04\"\x1f\n\x1dHypervisorHypEnterFtraceEvent\"6\n\'HypervisorIommuIdmapCompleteFtraceEvent\x12\x0b\n\x03map\x18\x01 \x01(\r\"3\n$HypervisorVcpuIllegalTrapFtraceEvent\x12\x0b\n\x03\x65sr\x18\x01 \x01(\x04\"b\n\x12I2cReadFtraceEvent\x12\x12\n\nadapter_nr\x18\x01 \x01(\x05\x12\x0e\n\x06msg_nr\x18\x02 \x01(\r\x12\x0c\n\x04\x61\x64\x64r\x18\x03 \x01(\r\x12\r\n\x05\x66lags\x18\x04 \x01(\r\x12\x0b\n\x03len\x18\x05 \x01(\r\"p\n\x13I2cWriteFtraceEvent\x12\x12\n\nadapter_nr\x18\x01 \x01(\x05\x12\x0e\n\x06msg_nr\x18\x02 \x01(\r\x12\x0c\n\x04\x61\x64\x64r\x18\x03 \x01(\r\x12\r\n\x05\x66lags\x18\x04 \x01(\r\x12\x0b\n\x03len\x18\x05 \x01(\r\x12\x0b\n\x03\x62uf\x18\x07 \x01(\x0c\"H\n\x14I2cResultFtraceEvent\x12\x12\n\nadapter_nr\x18\x01 \x01(\x05\x12\x0f\n\x07nr_msgs\x18\x02 \x01(\r\x12\x0b\n\x03ret\x18\x03 \x01(\x05\"p\n\x13I2cReplyFtraceEvent\x12\x12\n\nadapter_nr\x18\x01 \x01(\x05\x12\x0e\n\x06msg_nr\x18\x02 \x01(\r\x12\x0c\n\x04\x61\x64\x64r\x18\x03 \x01(\r\x12\r\n\x05\x66lags\x18\x04 \x01(\r\x12\x0b\n\x03len\x18\x05 \x01(\r\x12\x0b\n\x03\x62uf\x18\x07 \x01(\x0c\"j\n\x14SmbusReadFtraceEvent\x12\x12\n\nadapter_nr\x18\x01 \x01(\x05\x12\r\n\x05\x66lags\x18\x02 \x01(\r\x12\x0c\n\x04\x61\x64\x64r\x18\x03 \x01(\r\x12\x0f\n\x07\x63ommand\x18\x04 \x01(\r\x12\x10\n\x08protocol\x18\x05 \x01(\r\"x\n\x15SmbusWriteFtraceEvent\x12\x12\n\nadapter_nr\x18\x01 \x01(\x05\x12\x0c\n\x04\x61\x64\x64r\x18\x02 \x01(\r\x12\r\n\x05\x66lags\x18\x03 \x01(\r\x12\x0f\n\x07\x63ommand\x18\x04 \x01(\r\x12\x0b\n\x03len\x18\x05 \x01(\r\x12\x10\n\x08protocol\x18\x06 \x01(\r\"\x8d\x01\n\x16SmbusResultFtraceEvent\x12\x12\n\nadapter_nr\x18\x01 \x01(\x05\x12\x0c\n\x04\x61\x64\x64r\x18\x02 \x01(\r\x12\r\n\x05\x66lags\x18\x03 \x01(\r\x12\x12\n\nread_write\x18\x04 \x01(\r\x12\x0f\n\x07\x63ommand\x18\x05 \x01(\r\x12\x0b\n\x03res\x18\x06 \x01(\x05\x12\x10\n\x08protocol\x18\x07 \x01(\r\"x\n\x15SmbusReplyFtraceEvent\x12\x12\n\nadapter_nr\x18\x01 \x01(\x05\x12\x0c\n\x04\x61\x64\x64r\x18\x02 \x01(\r\x12\r\n\x05\x66lags\x18\x03 \x01(\r\x12\x0f\n\x07\x63ommand\x18\x04 \x01(\r\x12\x0b\n\x03len\x18\x05 \x01(\r\x12\x10\n\x08protocol\x18\x06 \x01(\r\"M\n\x12IonStatFtraceEvent\x12\x11\n\tbuffer_id\x18\x01 \x01(\r\x12\x0b\n\x03len\x18\x02 \x01(\x03\x12\x17\n\x0ftotal_allocated\x18\x03 \x01(\x04\"%\n\x13IpiEntryFtraceEvent\x12\x0e\n\x06reason\x18\x01 \x01(\t\"$\n\x12IpiExitFtraceEvent\x12\x0e\n\x06reason\x18\x01 \x01(\t\":\n\x13IpiRaiseFtraceEvent\x12\x13\n\x0btarget_cpus\x18\x01 \x01(\r\x12\x0e\n\x06reason\x18\x02 \x01(\t\"&\n\x17SoftirqEntryFtraceEvent\x12\x0b\n\x03vec\x18\x01 \x01(\r\"%\n\x16SoftirqExitFtraceEvent\x12\x0b\n\x03vec\x18\x01 \x01(\r\"&\n\x17SoftirqRaiseFtraceEvent\x12\x0b\n\x03vec\x18\x01 \x01(\r\"H\n\x1aIrqHandlerEntryFtraceEvent\x12\x0b\n\x03irq\x18\x01 \x01(\x05\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x0f\n\x07handler\x18\x03 \x01(\r\"5\n\x19IrqHandlerExitFtraceEvent\x12\x0b\n\x03irq\x18\x01 \x01(\x05\x12\x0b\n\x03ret\x18\x02 \x01(\x05\",\n\x1aLocalTimerEntryFtraceEvent\x12\x0e\n\x06vector\x18\x01 \x01(\x05\"+\n\x19LocalTimerExitFtraceEvent\x12\x0e\n\x06vector\x18\x01 \x01(\x05\"?\n\x1bKgslGpuFrequencyFtraceEvent\x12\x10\n\x08gpu_freq\x18\x01 \x01(\r\x12\x0e\n\x06gpu_id\x18\x02 \x01(\r\"q\n#KgslAdrenoCmdbatchQueuedFtraceEvent\x12\n\n\x02id\x18\x01 \x01(\r\x12\x11\n\ttimestamp\x18\x02 \x01(\r\x12\x0e\n\x06queued\x18\x03 \x01(\r\x12\r\n\x05\x66lags\x18\x04 \x01(\r\x12\x0c\n\x04prio\x18\x05 \x01(\r\"\xf9\x01\n&KgslAdrenoCmdbatchSubmittedFtraceEvent\x12\n\n\x02id\x18\x01 \x01(\r\x12\x11\n\ttimestamp\x18\x02 \x01(\r\x12\x10\n\x08inflight\x18\x03 \x01(\x03\x12\r\n\x05\x66lags\x18\x04 \x01(\r\x12\r\n\x05ticks\x18\x05 \x01(\x04\x12\x0c\n\x04secs\x18\x06 \x01(\x04\x12\r\n\x05usecs\x18\x07 \x01(\x04\x12\x0c\n\x04prio\x18\x08 \x01(\x05\x12\r\n\x05rb_id\x18\t \x01(\x05\x12\x0c\n\x04rptr\x18\n \x01(\r\x12\x0c\n\x04wptr\x18\x0b \x01(\r\x12\x12\n\nq_inflight\x18\x0c \x01(\x05\x12\x16\n\x0e\x64ispatch_queue\x18\r \x01(\x05\"_\n!KgslAdrenoCmdbatchSyncFtraceEvent\x12\n\n\x02id\x18\x01 \x01(\r\x12\x11\n\ttimestamp\x18\x02 \x01(\r\x12\r\n\x05ticks\x18\x03 \x01(\x04\x12\x0c\n\x04prio\x18\x04 \x01(\x05\"\xd5\x02\n$KgslAdrenoCmdbatchRetiredFtraceEvent\x12\n\n\x02id\x18\x01 \x01(\r\x12\x11\n\ttimestamp\x18\x02 \x01(\r\x12\x10\n\x08inflight\x18\x03 \x01(\x03\x12\x10\n\x08recovery\x18\x04 \x01(\r\x12\r\n\x05\x66lags\x18\x05 \x01(\r\x12\r\n\x05start\x18\x06 \x01(\x04\x12\x0e\n\x06retire\x18\x07 \x01(\x04\x12\x0c\n\x04prio\x18\x08 \x01(\x05\x12\r\n\x05rb_id\x18\t \x01(\x05\x12\x0c\n\x04rptr\x18\n \x01(\r\x12\x0c\n\x04wptr\x18\x0b \x01(\r\x12\x12\n\nq_inflight\x18\x0c \x01(\x05\x12\x16\n\x0e\x66\x61ult_recovery\x18\r \x01(\x04\x12\x16\n\x0e\x64ispatch_queue\x18\x0e \x01(\r\x12\x17\n\x0fsubmitted_to_rb\x18\x0f \x01(\x04\x12\x16\n\x0eretired_on_gmu\x18\x10 \x01(\x04\x12\x0e\n\x06\x61\x63tive\x18\x11 \x01(\x04\"A\n\x1d\x41llocPagesIommuEndFtraceEvent\x12\x11\n\tgfp_flags\x18\x01 \x01(\r\x12\r\n\x05order\x18\x02 \x01(\r\"B\n\x1e\x41llocPagesIommuFailFtraceEvent\x12\x11\n\tgfp_flags\x18\x01 \x01(\r\x12\r\n\x05order\x18\x02 \x01(\r\"C\n\x1f\x41llocPagesIommuStartFtraceEvent\x12\x11\n\tgfp_flags\x18\x01 \x01(\r\x12\r\n\x05order\x18\x02 \x01(\r\"?\n\x1b\x41llocPagesSysEndFtraceEvent\x12\x11\n\tgfp_flags\x18\x01 \x01(\r\x12\r\n\x05order\x18\x02 \x01(\r\"@\n\x1c\x41llocPagesSysFailFtraceEvent\x12\x11\n\tgfp_flags\x18\x01 \x01(\r\x12\r\n\x05order\x18\x02 \x01(\r\"A\n\x1d\x41llocPagesSysStartFtraceEvent\x12\x11\n\tgfp_flags\x18\x01 \x01(\r\x12\r\n\x05order\x18\x02 \x01(\r\"3\n\"DmaAllocContiguousRetryFtraceEvent\x12\r\n\x05tries\x18\x01 \x01(\x05\"S\n\x18IommuMapRangeFtraceEvent\x12\x12\n\nchunk_size\x18\x01 \x01(\x04\x12\x0b\n\x03len\x18\x02 \x01(\x04\x12\n\n\x02pa\x18\x03 \x01(\x04\x12\n\n\x02va\x18\x04 \x01(\x04\"f\n\"IommuSecPtblMapRangeEndFtraceEvent\x12\x0b\n\x03len\x18\x01 \x01(\x04\x12\x0b\n\x03num\x18\x02 \x01(\x05\x12\n\n\x02pa\x18\x03 \x01(\r\x12\x0e\n\x06sec_id\x18\x04 \x01(\x05\x12\n\n\x02va\x18\x05 \x01(\x04\"h\n$IommuSecPtblMapRangeStartFtraceEvent\x12\x0b\n\x03len\x18\x01 \x01(\x04\x12\x0b\n\x03num\x18\x02 \x01(\x05\x12\n\n\x02pa\x18\x03 \x01(\r\x12\x0e\n\x06sec_id\x18\x04 \x01(\x05\x12\n\n\x02va\x18\x05 \x01(\x04\"p\n\x1cIonAllocBufferEndFtraceEvent\x12\x13\n\x0b\x63lient_name\x18\x01 \x01(\t\x12\r\n\x05\x66lags\x18\x02 \x01(\r\x12\x11\n\theap_name\x18\x03 \x01(\t\x12\x0b\n\x03len\x18\x04 \x01(\x04\x12\x0c\n\x04mask\x18\x05 \x01(\r\"\x80\x01\n\x1dIonAllocBufferFailFtraceEvent\x12\x13\n\x0b\x63lient_name\x18\x01 \x01(\t\x12\r\n\x05\x65rror\x18\x02 \x01(\x03\x12\r\n\x05\x66lags\x18\x03 \x01(\r\x12\x11\n\theap_name\x18\x04 \x01(\t\x12\x0b\n\x03len\x18\x05 \x01(\x04\x12\x0c\n\x04mask\x18\x06 \x01(\r\"\x84\x01\n!IonAllocBufferFallbackFtraceEvent\x12\x13\n\x0b\x63lient_name\x18\x01 \x01(\t\x12\r\n\x05\x65rror\x18\x02 \x01(\x03\x12\r\n\x05\x66lags\x18\x03 \x01(\r\x12\x11\n\theap_name\x18\x04 \x01(\t\x12\x0b\n\x03len\x18\x05 \x01(\x04\x12\x0c\n\x04mask\x18\x06 \x01(\r\"r\n\x1eIonAllocBufferStartFtraceEvent\x12\x13\n\x0b\x63lient_name\x18\x01 \x01(\t\x12\r\n\x05\x66lags\x18\x02 \x01(\r\x12\x11\n\theap_name\x18\x03 \x01(\t\x12\x0b\n\x03len\x18\x04 \x01(\x04\x12\x0c\n\x04mask\x18\x05 \x01(\r\"+\n\x1aIonCpAllocRetryFtraceEvent\x12\r\n\x05tries\x18\x01 \x01(\x05\"_\n\x1fIonCpSecureBufferEndFtraceEvent\x12\r\n\x05\x61lign\x18\x01 \x01(\x04\x12\r\n\x05\x66lags\x18\x02 \x01(\x04\x12\x11\n\theap_name\x18\x03 \x01(\t\x12\x0b\n\x03len\x18\x04 \x01(\x04\"a\n!IonCpSecureBufferStartFtraceEvent\x12\r\n\x05\x61lign\x18\x01 \x01(\x04\x12\r\n\x05\x66lags\x18\x02 \x01(\x04\x12\x11\n\theap_name\x18\x03 \x01(\t\x12\x0b\n\x03len\x18\x04 \x01(\x04\"(\n\x19IonPrefetchingFtraceEvent\x12\x0b\n\x03len\x18\x01 \x01(\x04\"[\n#IonSecureCmaAddToPoolEndFtraceEvent\x12\x13\n\x0bis_prefetch\x18\x01 \x01(\r\x12\x0b\n\x03len\x18\x02 \x01(\x04\x12\x12\n\npool_total\x18\x03 \x01(\x05\"]\n%IonSecureCmaAddToPoolStartFtraceEvent\x12\x13\n\x0bis_prefetch\x18\x01 \x01(\r\x12\x0b\n\x03len\x18\x02 \x01(\x04\x12\x12\n\npool_total\x18\x03 \x01(\x05\"b\n\"IonSecureCmaAllocateEndFtraceEvent\x12\r\n\x05\x61lign\x18\x01 \x01(\x04\x12\r\n\x05\x66lags\x18\x02 \x01(\x04\x12\x11\n\theap_name\x18\x03 \x01(\t\x12\x0b\n\x03len\x18\x04 \x01(\x04\"d\n$IonSecureCmaAllocateStartFtraceEvent\x12\r\n\x05\x61lign\x18\x01 \x01(\x04\x12\r\n\x05\x66lags\x18\x02 \x01(\x04\x12\x11\n\theap_name\x18\x03 \x01(\t\x12\x0b\n\x03len\x18\x04 \x01(\x04\"R\n$IonSecureCmaShrinkPoolEndFtraceEvent\x12\x14\n\x0c\x64rained_size\x18\x01 \x01(\x04\x12\x14\n\x0cskipped_size\x18\x02 \x01(\x04\"T\n&IonSecureCmaShrinkPoolStartFtraceEvent\x12\x14\n\x0c\x64rained_size\x18\x01 \x01(\x04\x12\x14\n\x0cskipped_size\x18\x02 \x01(\x04\"2\n\x10KfreeFtraceEvent\x12\x11\n\tcall_site\x18\x01 \x01(\x04\x12\x0b\n\x03ptr\x18\x02 \x01(\x04\"o\n\x12KmallocFtraceEvent\x12\x13\n\x0b\x62ytes_alloc\x18\x01 \x01(\x04\x12\x11\n\tbytes_req\x18\x02 \x01(\x04\x12\x11\n\tcall_site\x18\x03 \x01(\x04\x12\x11\n\tgfp_flags\x18\x04 \x01(\r\x12\x0b\n\x03ptr\x18\x05 \x01(\x04\"\x81\x01\n\x16KmallocNodeFtraceEvent\x12\x13\n\x0b\x62ytes_alloc\x18\x01 \x01(\x04\x12\x11\n\tbytes_req\x18\x02 \x01(\x04\x12\x11\n\tcall_site\x18\x03 \x01(\x04\x12\x11\n\tgfp_flags\x18\x04 \x01(\r\x12\x0c\n\x04node\x18\x05 \x01(\x05\x12\x0b\n\x03ptr\x18\x06 \x01(\x04\"v\n\x19KmemCacheAllocFtraceEvent\x12\x13\n\x0b\x62ytes_alloc\x18\x01 \x01(\x04\x12\x11\n\tbytes_req\x18\x02 \x01(\x04\x12\x11\n\tcall_site\x18\x03 \x01(\x04\x12\x11\n\tgfp_flags\x18\x04 \x01(\r\x12\x0b\n\x03ptr\x18\x05 \x01(\x04\"\x88\x01\n\x1dKmemCacheAllocNodeFtraceEvent\x12\x13\n\x0b\x62ytes_alloc\x18\x01 \x01(\x04\x12\x11\n\tbytes_req\x18\x02 \x01(\x04\x12\x11\n\tcall_site\x18\x03 \x01(\x04\x12\x11\n\tgfp_flags\x18\x04 \x01(\r\x12\x0c\n\x04node\x18\x05 \x01(\x05\x12\x0b\n\x03ptr\x18\x06 \x01(\x04\":\n\x18KmemCacheFreeFtraceEvent\x12\x11\n\tcall_site\x18\x01 \x01(\x04\x12\x0b\n\x03ptr\x18\x02 \x01(\x04\"*\n\x1aMigratePagesEndFtraceEvent\x12\x0c\n\x04mode\x18\x01 \x01(\x05\",\n\x1cMigratePagesStartFtraceEvent\x12\x0c\n\x04mode\x18\x01 \x01(\x05\"(\n\x17MigrateRetryFtraceEvent\x12\r\n\x05tries\x18\x01 \x01(\x05\"j\n\x16MmPageAllocFtraceEvent\x12\x11\n\tgfp_flags\x18\x01 \x01(\r\x12\x13\n\x0bmigratetype\x18\x02 \x01(\x05\x12\r\n\x05order\x18\x03 \x01(\r\x12\x0c\n\x04page\x18\x04 \x01(\x04\x12\x0b\n\x03pfn\x18\x05 \x01(\x04\"\xba\x01\n\x1dMmPageAllocExtfragFtraceEvent\x12\x19\n\x11\x61lloc_migratetype\x18\x01 \x01(\x05\x12\x13\n\x0b\x61lloc_order\x18\x02 \x01(\x05\x12\x1c\n\x14\x66\x61llback_migratetype\x18\x03 \x01(\x05\x12\x16\n\x0e\x66\x61llback_order\x18\x04 \x01(\x05\x12\x0c\n\x04page\x18\x05 \x01(\x04\x12\x18\n\x10\x63hange_ownership\x18\x06 \x01(\x05\x12\x0b\n\x03pfn\x18\x07 \x01(\x04\"a\n MmPageAllocZoneLockedFtraceEvent\x12\x13\n\x0bmigratetype\x18\x01 \x01(\x05\x12\r\n\x05order\x18\x02 \x01(\r\x12\x0c\n\x04page\x18\x03 \x01(\x04\x12\x0b\n\x03pfn\x18\x04 \x01(\x04\"A\n\x15MmPageFreeFtraceEvent\x12\r\n\x05order\x18\x01 \x01(\r\x12\x0c\n\x04page\x18\x02 \x01(\x04\x12\x0b\n\x03pfn\x18\x03 \x01(\x04\"G\n\x1cMmPageFreeBatchedFtraceEvent\x12\x0c\n\x04\x63old\x18\x01 \x01(\x05\x12\x0c\n\x04page\x18\x02 \x01(\x04\x12\x0b\n\x03pfn\x18\x03 \x01(\x04\"[\n\x1aMmPagePcpuDrainFtraceEvent\x12\x13\n\x0bmigratetype\x18\x01 \x01(\x05\x12\r\n\x05order\x18\x02 \x01(\r\x12\x0c\n\x04page\x18\x03 \x01(\x04\x12\x0b\n\x03pfn\x18\x04 \x01(\x04\"O\n\x12RssStatFtraceEvent\x12\x0e\n\x06member\x18\x01 \x01(\x05\x12\x0c\n\x04size\x18\x02 \x01(\x03\x12\x0c\n\x04\x63urr\x18\x03 \x01(\r\x12\r\n\x05mm_id\x18\x04 \x01(\r\"S\n\x18IonHeapShrinkFtraceEvent\x12\x11\n\theap_name\x18\x01 \x01(\t\x12\x0b\n\x03len\x18\x02 \x01(\x04\x12\x17\n\x0ftotal_allocated\x18\x03 \x01(\x03\"Q\n\x16IonHeapGrowFtraceEvent\x12\x11\n\theap_name\x18\x01 \x01(\t\x12\x0b\n\x03len\x18\x02 \x01(\x04\x12\x17\n\x0ftotal_allocated\x18\x03 \x01(\x03\"7\n\x1aIonBufferCreateFtraceEvent\x12\x0c\n\x04\x61\x64\x64r\x18\x01 \x01(\x04\x12\x0b\n\x03len\x18\x02 \x01(\x04\"8\n\x1bIonBufferDestroyFtraceEvent\x12\x0c\n\x04\x61\x64\x64r\x18\x01 \x01(\x04\x12\x0b\n\x03len\x18\x02 \x01(\x04\"\x99\x01\n(MmAllocContigMigrateRangeInfoFtraceEvent\x12\r\n\x05start\x18\x01 \x01(\x04\x12\x0b\n\x03\x65nd\x18\x02 \x01(\x04\x12\x13\n\x0bnr_migrated\x18\x03 \x01(\x04\x12\x14\n\x0cnr_reclaimed\x18\x04 \x01(\x04\x12\x11\n\tnr_mapped\x18\x05 \x01(\x04\x12\x13\n\x0bmigratetype\x18\x06 \x01(\x05\"I\n\x18\x44mabufRssStatFtraceEvent\x12\x0b\n\x03rss\x18\x01 \x01(\x04\x12\x11\n\trss_delta\x18\x02 \x01(\x03\x12\r\n\x05i_ino\x18\x03 \x01(\x04\"(\n\x19KvmAccessFaultFtraceEvent\x12\x0b\n\x03ipa\x18\x01 \x01(\x04\"4\n\x14KvmAckIrqFtraceEvent\x12\x0f\n\x07irqchip\x18\x01 \x01(\r\x12\x0b\n\x03pin\x18\x02 \x01(\r\"2\n\x14KvmAgeHvaFtraceEvent\x12\x0b\n\x03\x65nd\x18\x01 \x01(\x04\x12\r\n\x05start\x18\x02 \x01(\x04\"T\n\x15KvmAgePageFtraceEvent\x12\x0b\n\x03gfn\x18\x01 \x01(\x04\x12\x0b\n\x03hva\x18\x02 \x01(\x04\x12\r\n\x05level\x18\x03 \x01(\r\x12\x12\n\nreferenced\x18\x04 \x01(\r\"2\n\x1bKvmArmClearDebugFtraceEvent\x12\x13\n\x0bguest_debug\x18\x01 \x01(\r\"9\n\x1aKvmArmSetDreg32FtraceEvent\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\r\"7\n\x1aKvmArmSetRegsetFtraceEvent\x12\x0b\n\x03len\x18\x01 \x01(\x05\x12\x0c\n\x04name\x18\x02 \x01(\t\"@\n\x1bKvmArmSetupDebugFtraceEvent\x12\x13\n\x0bguest_debug\x18\x01 \x01(\r\x12\x0c\n\x04vcpu\x18\x02 \x01(\x04\"&\n\x13KvmEntryFtraceEvent\x12\x0f\n\x07vcpu_pc\x18\x01 \x01(\x04\"B\n\x12KvmExitFtraceEvent\x12\x0e\n\x06\x65sr_ec\x18\x01 \x01(\r\x12\x0b\n\x03ret\x18\x02 \x01(\x05\x12\x0f\n\x07vcpu_pc\x18\x03 \x01(\x04\"!\n\x11KvmFpuFtraceEvent\x12\x0c\n\x04load\x18\x01 \x01(\r\"o\n\x19KvmGetTimerMapFtraceEvent\x12\x15\n\rdirect_ptimer\x18\x01 \x01(\x05\x12\x15\n\rdirect_vtimer\x18\x02 \x01(\x05\x12\x13\n\x0b\x65mul_ptimer\x18\x03 \x01(\x05\x12\x0f\n\x07vcpu_id\x18\x04 \x01(\x04\"T\n\x18KvmGuestFaultFtraceEvent\x12\x0b\n\x03hsr\x18\x01 \x01(\x04\x12\r\n\x05hxfar\x18\x02 \x01(\x04\x12\x0b\n\x03ipa\x18\x03 \x01(\x04\x12\x0f\n\x07vcpu_pc\x18\x04 \x01(\x04\")\n\x1aKvmHandleSysRegFtraceEvent\x12\x0b\n\x03hsr\x18\x01 \x01(\x04\"B\n\x16KvmHvcArm64FtraceEvent\x12\x0b\n\x03imm\x18\x01 \x01(\x04\x12\n\n\x02r0\x18\x02 \x01(\x04\x12\x0f\n\x07vcpu_pc\x18\x03 \x01(\x04\"W\n\x15KvmIrqLineFtraceEvent\x12\x0f\n\x07irq_num\x18\x01 \x01(\x05\x12\r\n\x05level\x18\x02 \x01(\x05\x12\x0c\n\x04type\x18\x03 \x01(\r\x12\x10\n\x08vcpu_idx\x18\x04 \x01(\x05\"I\n\x12KvmMmioFtraceEvent\x12\x0b\n\x03gpa\x18\x01 \x01(\x04\x12\x0b\n\x03len\x18\x02 \x01(\r\x12\x0c\n\x04type\x18\x03 \x01(\r\x12\x0b\n\x03val\x18\x04 \x01(\x04\"I\n\x19KvmMmioEmulateFtraceEvent\x12\x0c\n\x04\x63psr\x18\x01 \x01(\x04\x12\r\n\x05instr\x18\x02 \x01(\x04\x12\x0f\n\x07vcpu_pc\x18\x03 \x01(\x04\"@\n\x1bKvmSetGuestDebugFtraceEvent\x12\x13\n\x0bguest_debug\x18\x01 \x01(\r\x12\x0c\n\x04vcpu\x18\x02 \x01(\x04\"I\n\x14KvmSetIrqFtraceEvent\x12\x0b\n\x03gsi\x18\x01 \x01(\r\x12\x15\n\rirq_source_id\x18\x02 \x01(\x05\x12\r\n\x05level\x18\x03 \x01(\x05\"\'\n\x18KvmSetSpteHvaFtraceEvent\x12\x0b\n\x03hva\x18\x01 \x01(\x04\";\n\x19KvmSetWayFlushFtraceEvent\x12\r\n\x05\x63\x61\x63he\x18\x01 \x01(\r\x12\x0f\n\x07vcpu_pc\x18\x02 \x01(\x04\"\x8b\x01\n\x17KvmSysAccessFtraceEvent\x12\x0b\n\x03\x43Rm\x18\x01 \x01(\r\x12\x0b\n\x03\x43Rn\x18\x02 \x01(\r\x12\x0b\n\x03Op0\x18\x03 \x01(\r\x12\x0b\n\x03Op1\x18\x04 \x01(\r\x12\x0b\n\x03Op2\x18\x05 \x01(\r\x12\x10\n\x08is_write\x18\x06 \x01(\r\x12\x0c\n\x04name\x18\x07 \x01(\t\x12\x0f\n\x07vcpu_pc\x18\x08 \x01(\x04\"\'\n\x18KvmTestAgeHvaFtraceEvent\x12\x0b\n\x03hva\x18\x01 \x01(\x04\"D\n\x1aKvmTimerEmulateFtraceEvent\x12\x13\n\x0bshould_fire\x18\x01 \x01(\r\x12\x11\n\ttimer_idx\x18\x02 \x01(\x05\"5\n KvmTimerHrtimerExpireFtraceEvent\x12\x11\n\ttimer_idx\x18\x01 \x01(\x05\"O\n\x1fKvmTimerRestoreStateFtraceEvent\x12\x0b\n\x03\x63tl\x18\x01 \x01(\x04\x12\x0c\n\x04\x63val\x18\x02 \x01(\x04\x12\x11\n\ttimer_idx\x18\x03 \x01(\x05\"L\n\x1cKvmTimerSaveStateFtraceEvent\x12\x0b\n\x03\x63tl\x18\x01 \x01(\x04\x12\x0c\n\x04\x63val\x18\x02 \x01(\x04\x12\x11\n\ttimer_idx\x18\x03 \x01(\x05\"K\n\x1cKvmTimerUpdateIrqFtraceEvent\x12\x0b\n\x03irq\x18\x01 \x01(\r\x12\r\n\x05level\x18\x02 \x01(\x05\x12\x0f\n\x07vcpu_id\x18\x03 \x01(\x04\"F\n\x19KvmToggleCacheFtraceEvent\x12\x0b\n\x03now\x18\x01 \x01(\r\x12\x0f\n\x07vcpu_pc\x18\x02 \x01(\x04\x12\x0b\n\x03was\x18\x03 \x01(\r\"9\n\x1bKvmUnmapHvaRangeFtraceEvent\x12\x0b\n\x03\x65nd\x18\x01 \x01(\x04\x12\r\n\x05start\x18\x02 \x01(\x04\"-\n\x1bKvmUserspaceExitFtraceEvent\x12\x0e\n\x06reason\x18\x01 \x01(\r\"E\n\x18KvmVcpuWakeupFtraceEvent\x12\n\n\x02ns\x18\x01 \x01(\x04\x12\r\n\x05valid\x18\x02 \x01(\r\x12\x0e\n\x06waited\x18\x03 \x01(\r\"9\n\x16KvmWfxArm64FtraceEvent\x12\x0e\n\x06is_wfe\x18\x01 \x01(\r\x12\x0f\n\x07vcpu_pc\x18\x02 \x01(\x04\"T\n\x12TrapRegFtraceEvent\x12\n\n\x02\x66n\x18\x01 \x01(\t\x12\x10\n\x08is_write\x18\x02 \x01(\r\x12\x0b\n\x03reg\x18\x03 \x01(\x05\x12\x13\n\x0bwrite_value\x18\x04 \x01(\x04\"N\n\x1fVgicUpdateIrqPendingFtraceEvent\x12\x0b\n\x03irq\x18\x01 \x01(\r\x12\r\n\x05level\x18\x02 \x01(\r\x12\x0f\n\x07vcpu_id\x18\x03 \x01(\x04\"t\n\x18LowmemoryKillFtraceEvent\x12\x0c\n\x04\x63omm\x18\x01 \x01(\t\x12\x0b\n\x03pid\x18\x02 \x01(\x05\x12\x16\n\x0epagecache_size\x18\x03 \x01(\x03\x12\x17\n\x0fpagecache_limit\x18\x04 \x01(\x03\x12\x0c\n\x04\x66ree\x18\x05 \x01(\x03\"q\n\x1fLwisTracingMarkWriteFtraceEvent\x12\x11\n\tlwis_name\x18\x01 \x01(\t\x12\x0c\n\x04type\x18\x02 \x01(\r\x12\x0b\n\x03pid\x18\x03 \x01(\x05\x12\x11\n\tfunc_name\x18\x04 \x01(\t\x12\r\n\x05value\x18\x05 \x01(\x03\"Y\n\x1fMaliTracingMarkWriteFtraceEvent\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0b\n\x03pid\x18\x02 \x01(\x05\x12\x0c\n\x04type\x18\x03 \x01(\r\x12\r\n\x05value\x18\x04 \x01(\x05\"u\n\x1dMaliMaliKCPUCQSSETFtraceEvent\x12\n\n\x02id\x18\x01 \x01(\r\x12\x11\n\tinfo_val1\x18\x02 \x01(\x04\x12\x11\n\tinfo_val2\x18\x03 \x01(\x04\x12\x0f\n\x07kctx_id\x18\x04 \x01(\r\x12\x11\n\tkctx_tgid\x18\x05 \x01(\x05\"{\n#MaliMaliKCPUCQSWAITSTARTFtraceEvent\x12\n\n\x02id\x18\x01 \x01(\r\x12\x11\n\tinfo_val1\x18\x02 \x01(\x04\x12\x11\n\tinfo_val2\x18\x03 \x01(\x04\x12\x0f\n\x07kctx_id\x18\x04 \x01(\r\x12\x11\n\tkctx_tgid\x18\x05 \x01(\x05\"y\n!MaliMaliKCPUCQSWAITENDFtraceEvent\x12\n\n\x02id\x18\x01 \x01(\r\x12\x11\n\tinfo_val1\x18\x02 \x01(\x04\x12\x11\n\tinfo_val2\x18\x03 \x01(\x04\x12\x0f\n\x07kctx_id\x18\x04 \x01(\r\x12\x11\n\tkctx_tgid\x18\x05 \x01(\x05\"z\n\"MaliMaliKCPUFENCESIGNALFtraceEvent\x12\x11\n\tinfo_val1\x18\x01 \x01(\x04\x12\x11\n\tinfo_val2\x18\x02 \x01(\x04\x12\x11\n\tkctx_tgid\x18\x03 \x01(\x05\x12\x0f\n\x07kctx_id\x18\x04 \x01(\r\x12\n\n\x02id\x18\x05 \x01(\r\"}\n%MaliMaliKCPUFENCEWAITSTARTFtraceEvent\x12\x11\n\tinfo_val1\x18\x01 \x01(\x04\x12\x11\n\tinfo_val2\x18\x02 \x01(\x04\x12\x11\n\tkctx_tgid\x18\x03 \x01(\x05\x12\x0f\n\x07kctx_id\x18\x04 \x01(\r\x12\n\n\x02id\x18\x05 \x01(\r\"{\n#MaliMaliKCPUFENCEWAITENDFtraceEvent\x12\x11\n\tinfo_val1\x18\x01 \x01(\x04\x12\x11\n\tinfo_val2\x18\x02 \x01(\x04\x12\x11\n\tkctx_tgid\x18\x03 \x01(\x05\x12\x0f\n\x07kctx_id\x18\x04 \x01(\r\x12\n\n\x02id\x18\x05 \x01(\r\"\\\n$MaliMaliCSFINTERRUPTSTARTFtraceEvent\x12\x11\n\tkctx_tgid\x18\x01 \x01(\x05\x12\x0f\n\x07kctx_id\x18\x02 \x01(\r\x12\x10\n\x08info_val\x18\x03 \x01(\x04\"Z\n\"MaliMaliCSFINTERRUPTENDFtraceEvent\x12\x11\n\tkctx_tgid\x18\x01 \x01(\x05\x12\x0f\n\x07kctx_id\x18\x02 \x01(\r\x12\x10\n\x08info_val\x18\x03 \x01(\x04\"l\n4MaliMaliPMMCUHCTLCORESDOWNSCALENOTIFYPENDFtraceEvent\x12\x11\n\tkctx_tgid\x18\x01 \x01(\x05\x12\x0f\n\x07kctx_id\x18\x02 \x01(\r\x12\x10\n\x08info_val\x18\x03 \x01(\x04\"c\n+MaliMaliPMMCUHCTLCORESNOTIFYPENDFtraceEvent\x12\x11\n\tkctx_tgid\x18\x01 \x01(\x05\x12\x0f\n\x07kctx_id\x18\x02 \x01(\r\x12\x10\n\x08info_val\x18\x03 \x01(\x04\"d\n,MaliMaliPMMCUHCTLCOREINACTIVEPENDFtraceEvent\x12\x11\n\tkctx_tgid\x18\x01 \x01(\x05\x12\x0f\n\x07kctx_id\x18\x02 \x01(\r\x12\x10\n\x08info_val\x18\x03 \x01(\x04\"`\n(MaliMaliPMMCUHCTLMCUONRECHECKFtraceEvent\x12\x11\n\tkctx_tgid\x18\x01 \x01(\x05\x12\x0f\n\x07kctx_id\x18\x02 \x01(\r\x12\x10\n\x08info_val\x18\x03 \x01(\x04\"f\n.MaliMaliPMMCUHCTLSHADERSCOREOFFPENDFtraceEvent\x12\x11\n\tkctx_tgid\x18\x01 \x01(\x05\x12\x0f\n\x07kctx_id\x18\x02 \x01(\r\x12\x10\n\x08info_val\x18\x03 \x01(\x04\"b\n*MaliMaliPMMCUHCTLSHADERSPENDOFFFtraceEvent\x12\x11\n\tkctx_tgid\x18\x01 \x01(\x05\x12\x0f\n\x07kctx_id\x18\x02 \x01(\r\x12\x10\n\x08info_val\x18\x03 \x01(\x04\"a\n)MaliMaliPMMCUHCTLSHADERSPENDONFtraceEvent\x12\x11\n\tkctx_tgid\x18\x01 \x01(\x05\x12\x0f\n\x07kctx_id\x18\x02 \x01(\r\x12\x10\n\x08info_val\x18\x03 \x01(\x04\"c\n+MaliMaliPMMCUHCTLSHADERSREADYOFFFtraceEvent\x12\x11\n\tkctx_tgid\x18\x01 \x01(\x05\x12\x0f\n\x07kctx_id\x18\x02 \x01(\r\x12\x10\n\x08info_val\x18\x03 \x01(\x04\"W\n\x1fMaliMaliPMMCUINSLEEPFtraceEvent\x12\x11\n\tkctx_tgid\x18\x01 \x01(\x05\x12\x0f\n\x07kctx_id\x18\x02 \x01(\r\x12\x10\n\x08info_val\x18\x03 \x01(\x04\"S\n\x1bMaliMaliPMMCUOFFFtraceEvent\x12\x11\n\tkctx_tgid\x18\x01 \x01(\x05\x12\x0f\n\x07kctx_id\x18\x02 \x01(\r\x12\x10\n\x08info_val\x18\x03 \x01(\x04\"R\n\x1aMaliMaliPMMCUONFtraceEvent\x12\x11\n\tkctx_tgid\x18\x01 \x01(\x05\x12\x0f\n\x07kctx_id\x18\x02 \x01(\r\x12\x10\n\x08info_val\x18\x03 \x01(\x04\"d\n,MaliMaliPMMCUONCOREATTRUPDATEPENDFtraceEvent\x12\x11\n\tkctx_tgid\x18\x01 \x01(\x05\x12\x0f\n\x07kctx_id\x18\x02 \x01(\r\x12\x10\n\x08info_val\x18\x03 \x01(\x04\"_\n\'MaliMaliPMMCUONGLBREINITPENDFtraceEvent\x12\x11\n\tkctx_tgid\x18\x01 \x01(\x05\x12\x0f\n\x07kctx_id\x18\x02 \x01(\r\x12\x10\n\x08info_val\x18\x03 \x01(\x04\"V\n\x1eMaliMaliPMMCUONHALTFtraceEvent\x12\x11\n\tkctx_tgid\x18\x01 \x01(\x05\x12\x0f\n\x07kctx_id\x18\x02 \x01(\r\x12\x10\n\x08info_val\x18\x03 \x01(\x04\"^\n&MaliMaliPMMCUONHWCNTDISABLEFtraceEvent\x12\x11\n\tkctx_tgid\x18\x01 \x01(\x05\x12\x0f\n\x07kctx_id\x18\x02 \x01(\r\x12\x10\n\x08info_val\x18\x03 \x01(\x04\"]\n%MaliMaliPMMCUONHWCNTENABLEFtraceEvent\x12\x11\n\tkctx_tgid\x18\x01 \x01(\x05\x12\x0f\n\x07kctx_id\x18\x02 \x01(\r\x12\x10\n\x08info_val\x18\x03 \x01(\x04\"Z\n\"MaliMaliPMMCUONPENDHALTFtraceEvent\x12\x11\n\tkctx_tgid\x18\x01 \x01(\x05\x12\x0f\n\x07kctx_id\x18\x02 \x01(\r\x12\x10\n\x08info_val\x18\x03 \x01(\x04\"[\n#MaliMaliPMMCUONPENDSLEEPFtraceEvent\x12\x11\n\tkctx_tgid\x18\x01 \x01(\x05\x12\x0f\n\x07kctx_id\x18\x02 \x01(\r\x12\x10\n\x08info_val\x18\x03 \x01(\x04\"_\n\'MaliMaliPMMCUONSLEEPINITIATEFtraceEvent\x12\x11\n\tkctx_tgid\x18\x01 \x01(\x05\x12\x0f\n\x07kctx_id\x18\x02 \x01(\r\x12\x10\n\x08info_val\x18\x03 \x01(\x04\"W\n\x1fMaliMaliPMMCUPENDOFFFtraceEvent\x12\x11\n\tkctx_tgid\x18\x01 \x01(\x05\x12\x0f\n\x07kctx_id\x18\x02 \x01(\r\x12\x10\n\x08info_val\x18\x03 \x01(\x04\"\\\n$MaliMaliPMMCUPENDONRELOADFtraceEvent\x12\x11\n\tkctx_tgid\x18\x01 \x01(\x05\x12\x0f\n\x07kctx_id\x18\x02 \x01(\r\x12\x10\n\x08info_val\x18\x03 \x01(\x04\"Y\n!MaliMaliPMMCUPOWERDOWNFtraceEvent\x12\x11\n\tkctx_tgid\x18\x01 \x01(\x05\x12\x0f\n\x07kctx_id\x18\x02 \x01(\r\x12\x10\n\x08info_val\x18\x03 \x01(\x04\"Y\n!MaliMaliPMMCURESETWAITFtraceEvent\x12\x11\n\tkctx_tgid\x18\x01 \x01(\x05\x12\x0f\n\x07kctx_id\x18\x02 \x01(\r\x12\x10\n\x08info_val\x18\x03 \x01(\x04\"W\n\x1cMaliGpuPowerStateFtraceEvent\x12\x11\n\tchange_ns\x18\x01 \x01(\x04\x12\x12\n\nfrom_state\x18\x02 \x01(\x05\x12\x10\n\x08to_state\x18\x03 \x01(\x05\"@\n\x18MdpCmdKickoffFtraceEvent\x12\x0f\n\x07\x63tl_num\x18\x01 \x01(\r\x12\x13\n\x0bkickoff_cnt\x18\x02 \x01(\x05\"Z\n\x14MdpCommitFtraceEvent\x12\x0b\n\x03num\x18\x01 \x01(\r\x12\x10\n\x08play_cnt\x18\x02 \x01(\r\x12\x10\n\x08\x63lk_rate\x18\x03 \x01(\r\x12\x11\n\tbandwidth\x18\x04 \x01(\x04\"[\n\x17MdpPerfSetOtFtraceEvent\x12\x0c\n\x04pnum\x18\x01 \x01(\r\x12\x0e\n\x06xin_id\x18\x02 \x01(\r\x12\x0e\n\x06rd_lim\x18\x03 \x01(\r\x12\x12\n\nis_vbif_rt\x18\x04 \x01(\r\"\x8c\x02\n\x18MdpSsppChangeFtraceEvent\x12\x0b\n\x03num\x18\x01 \x01(\r\x12\x10\n\x08play_cnt\x18\x02 \x01(\r\x12\r\n\x05mixer\x18\x03 \x01(\r\x12\r\n\x05stage\x18\x04 \x01(\r\x12\r\n\x05\x66lags\x18\x05 \x01(\r\x12\x0e\n\x06\x66ormat\x18\x06 \x01(\r\x12\r\n\x05img_w\x18\x07 \x01(\r\x12\r\n\x05img_h\x18\x08 \x01(\r\x12\r\n\x05src_x\x18\t \x01(\r\x12\r\n\x05src_y\x18\n \x01(\r\x12\r\n\x05src_w\x18\x0b \x01(\r\x12\r\n\x05src_h\x18\x0c \x01(\r\x12\r\n\x05\x64st_x\x18\r \x01(\r\x12\r\n\x05\x64st_y\x18\x0e \x01(\r\x12\r\n\x05\x64st_w\x18\x0f \x01(\r\x12\r\n\x05\x64st_h\x18\x10 \x01(\r\"S\n\x1bTracingMarkWriteFtraceEvent\x12\x0b\n\x03pid\x18\x01 \x01(\x05\x12\x12\n\ntrace_name\x18\x02 \x01(\t\x12\x13\n\x0btrace_begin\x18\x03 \x01(\r\"d\n\x1dMdpCmdPingpongDoneFtraceEvent\x12\x0f\n\x07\x63tl_num\x18\x01 \x01(\r\x12\x10\n\x08intf_num\x18\x02 \x01(\r\x12\x0e\n\x06pp_num\x18\x03 \x01(\r\x12\x10\n\x08koff_cnt\x18\x04 \x01(\x05\"\xa4\x01\n\x17MdpCompareBwFtraceEvent\x12\x0e\n\x06new_ab\x18\x01 \x01(\x04\x12\x0e\n\x06new_ib\x18\x02 \x01(\x04\x12\x0e\n\x06new_wb\x18\x03 \x01(\x04\x12\x0e\n\x06old_ab\x18\x04 \x01(\x04\x12\x0e\n\x06old_ib\x18\x05 \x01(\x04\x12\x0e\n\x06old_wb\x18\x06 \x01(\x04\x12\x16\n\x0eparams_changed\x18\x07 \x01(\r\x12\x11\n\tupdate_bw\x18\x08 \x01(\r\"p\n\x1eMdpPerfSetPanicLutsFtraceEvent\x12\x0c\n\x04pnum\x18\x01 \x01(\r\x12\x0b\n\x03\x66mt\x18\x02 \x01(\r\x12\x0c\n\x04mode\x18\x03 \x01(\r\x12\x11\n\tpanic_lut\x18\x04 \x01(\r\x12\x12\n\nrobust_lut\x18\x05 \x01(\r\"\x89\x02\n\x15MdpSsppSetFtraceEvent\x12\x0b\n\x03num\x18\x01 \x01(\r\x12\x10\n\x08play_cnt\x18\x02 \x01(\r\x12\r\n\x05mixer\x18\x03 \x01(\r\x12\r\n\x05stage\x18\x04 \x01(\r\x12\r\n\x05\x66lags\x18\x05 \x01(\r\x12\x0e\n\x06\x66ormat\x18\x06 \x01(\r\x12\r\n\x05img_w\x18\x07 \x01(\r\x12\r\n\x05img_h\x18\x08 \x01(\r\x12\r\n\x05src_x\x18\t \x01(\r\x12\r\n\x05src_y\x18\n \x01(\r\x12\r\n\x05src_w\x18\x0b \x01(\r\x12\r\n\x05src_h\x18\x0c \x01(\r\x12\r\n\x05\x64st_x\x18\r \x01(\r\x12\r\n\x05\x64st_y\x18\x0e \x01(\r\x12\r\n\x05\x64st_w\x18\x0f \x01(\r\x12\r\n\x05\x64st_h\x18\x10 \x01(\r\"A\n\x1cMdpCmdReadptrDoneFtraceEvent\x12\x0f\n\x07\x63tl_num\x18\x01 \x01(\r\x12\x10\n\x08koff_cnt\x18\x02 \x01(\x05\"I\n\x15MdpMisrCrcFtraceEvent\x12\x10\n\x08\x62lock_id\x18\x01 \x01(\r\x12\x11\n\tvsync_cnt\x18\x02 \x01(\r\x12\x0b\n\x03\x63rc\x18\x03 \x01(\r\"}\n\x1cMdpPerfSetQosLutsFtraceEvent\x12\x0c\n\x04pnum\x18\x01 \x01(\r\x12\x0b\n\x03\x66mt\x18\x02 \x01(\r\x12\x0c\n\x04intf\x18\x03 \x01(\r\x12\x0b\n\x03rot\x18\x04 \x01(\r\x12\n\n\x02\x66l\x18\x05 \x01(\r\x12\x0b\n\x03lut\x18\x06 \x01(\r\x12\x0e\n\x06linear\x18\x07 \x01(\r\"N\n\x1aMdpTraceCounterFtraceEvent\x12\x0b\n\x03pid\x18\x01 \x01(\x05\x12\x14\n\x0c\x63ounter_name\x18\x02 \x01(\t\x12\r\n\x05value\x18\x03 \x01(\x05\"-\n\x1aMdpCmdReleaseBwFtraceEvent\x12\x0f\n\x07\x63tl_num\x18\x01 \x01(\r\".\n\x19MdpMixerUpdateFtraceEvent\x12\x11\n\tmixer_num\x18\x01 \x01(\r\"\xa0\x01\n\x1dMdpPerfSetWmLevelsFtraceEvent\x12\x0c\n\x04pnum\x18\x01 \x01(\r\x12\x11\n\tuse_space\x18\x02 \x01(\r\x12\x16\n\x0epriority_bytes\x18\x03 \x01(\r\x12\x0b\n\x03wm0\x18\x04 \x01(\r\x12\x0b\n\x03wm1\x18\x05 \x01(\r\x12\x0b\n\x03wm2\x18\x06 \x01(\r\x12\x0e\n\x06mb_cnt\x18\x07 \x01(\r\x12\x0f\n\x07mb_size\x18\x08 \x01(\r\"H\n\x1fMdpVideoUnderrunDoneFtraceEvent\x12\x0f\n\x07\x63tl_num\x18\x01 \x01(\r\x12\x14\n\x0cunderrun_cnt\x18\x02 \x01(\r\"E\n\x1dMdpCmdWaitPingpongFtraceEvent\x12\x0f\n\x07\x63tl_num\x18\x01 \x01(\r\x12\x13\n\x0bkickoff_cnt\x18\x02 \x01(\x05\"\xce\x01\n\x1dMdpPerfPrefillCalcFtraceEvent\x12\x0c\n\x04pnum\x18\x01 \x01(\r\x12\x13\n\x0blatency_buf\x18\x02 \x01(\r\x12\n\n\x02ot\x18\x03 \x01(\r\x12\r\n\x05y_buf\x18\x04 \x01(\r\x12\x10\n\x08y_scaler\x18\x05 \x01(\r\x12\x10\n\x08pp_lines\x18\x06 \x01(\r\x12\x10\n\x08pp_bytes\x18\x07 \x01(\r\x12\x0f\n\x07post_sc\x18\x08 \x01(\r\x12\x11\n\tfbc_bytes\x18\t \x01(\r\x12\x15\n\rprefill_bytes\x18\n \x01(\r\"Q\n\x1bMdpPerfUpdateBusFtraceEvent\x12\x0e\n\x06\x63lient\x18\x01 \x01(\x05\x12\x10\n\x08\x61\x62_quota\x18\x02 \x01(\x04\x12\x10\n\x08ib_quota\x18\x03 \x01(\x04\"0\n\x1fRotatorBwAoAsContextFtraceEvent\x12\r\n\x05state\x18\x01 \x01(\r\"Y\n\x18MmEventRecordFtraceEvent\x12\x0f\n\x07\x61vg_lat\x18\x01 \x01(\r\x12\r\n\x05\x63ount\x18\x02 \x01(\r\x12\x0f\n\x07max_lat\x18\x03 \x01(\r\x12\x0c\n\x04type\x18\x04 \x01(\r\"H\n\x1aNetifReceiveSkbFtraceEvent\x12\x0b\n\x03len\x18\x01 \x01(\r\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x0f\n\x07skbaddr\x18\x03 \x01(\x04\"O\n\x15NetDevXmitFtraceEvent\x12\x0b\n\x03len\x18\x01 \x01(\r\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\n\n\x02rc\x18\x03 \x01(\x05\x12\x0f\n\x07skbaddr\x18\x04 \x01(\x04\"\xfb\x02\n\x1eNapiGroReceiveEntryFtraceEvent\x12\x10\n\x08\x64\x61ta_len\x18\x01 \x01(\r\x12\x10\n\x08gso_size\x18\x02 \x01(\r\x12\x10\n\x08gso_type\x18\x03 \x01(\r\x12\x0c\n\x04hash\x18\x04 \x01(\r\x12\x11\n\tip_summed\x18\x05 \x01(\r\x12\x0f\n\x07l4_hash\x18\x06 \x01(\r\x12\x0b\n\x03len\x18\x07 \x01(\r\x12\x12\n\nmac_header\x18\x08 \x01(\x05\x12\x18\n\x10mac_header_valid\x18\t \x01(\r\x12\x0c\n\x04name\x18\n \x01(\t\x12\x0f\n\x07napi_id\x18\x0b \x01(\r\x12\x10\n\x08nr_frags\x18\x0c \x01(\r\x12\x10\n\x08protocol\x18\r \x01(\r\x12\x15\n\rqueue_mapping\x18\x0e \x01(\r\x12\x0f\n\x07skbaddr\x18\x0f \x01(\x04\x12\x10\n\x08truesize\x18\x10 \x01(\r\x12\x12\n\nvlan_proto\x18\x11 \x01(\r\x12\x13\n\x0bvlan_tagged\x18\x12 \x01(\r\x12\x10\n\x08vlan_tci\x18\x13 \x01(\r\",\n\x1dNapiGroReceiveExitFtraceEvent\x12\x0b\n\x03ret\x18\x01 \x01(\x05\"P\n\x1cOomScoreAdjUpdateFtraceEvent\x12\x0c\n\x04\x63omm\x18\x01 \x01(\t\x12\x15\n\room_score_adj\x18\x02 \x01(\x05\x12\x0b\n\x03pid\x18\x03 \x01(\x05\"$\n\x15MarkVictimFtraceEvent\x12\x0b\n\x03pid\x18\x01 \x01(\x05\">\n\x1b\x44siCmdFifoStatusFtraceEvent\x12\x0e\n\x06header\x18\x01 \x01(\r\x12\x0f\n\x07payload\x18\x02 \x01(\r\"/\n\x10\x44siRxFtraceEvent\x12\x0b\n\x03\x63md\x18\x01 \x01(\r\x12\x0e\n\x06rx_buf\x18\x03 \x01(\x0c\">\n\x10\x44siTxFtraceEvent\x12\x0c\n\x04last\x18\x01 \x01(\r\x12\x0c\n\x04type\x18\x03 \x01(\r\x12\x0e\n\x06tx_buf\x18\x04 \x01(\x0c\"\x7f\n\x1cPanelWriteGenericFtraceEvent\x12\x0b\n\x03pid\x18\x01 \x01(\x05\x12\x12\n\ntrace_name\x18\x02 \x01(\t\x12\x13\n\x0btrace_begin\x18\x03 \x01(\r\x12\x0c\n\x04name\x18\x04 \x01(\t\x12\x0c\n\x04type\x18\x05 \x01(\r\x12\r\n\x05value\x18\x06 \x01(\x05\"F\n\x18GramCollisionFtraceEvent\x12\x13\n\x0bpanel_index\x18\x01 \x01(\x05\x12\x15\n\rcollision_cnt\x18\x02 \x01(\r\"\xc5\x01\n\x1cPanelSettingsFullFtraceEvent\x12\x13\n\x0bpanel_index\x18\x01 \x01(\x05\x12\x0b\n\x03hbm\x18\x02 \x01(\r\x12\x0b\n\x03irc\x18\x03 \x01(\r\x12\r\n\x05h_pwm\x18\x04 \x01(\r\x12\x0f\n\x07\x66i_auto\x18\x05 \x01(\r\x12\x11\n\tfi_manual\x18\x06 \x01(\r\x12\x12\n\nearly_exit\x18\x07 \x01(\r\x12\x0e\n\x06min_rr\x18\x08 \x01(\r\x12\x0e\n\x06max_rr\x18\t \x01(\r\x12\x0f\n\x07te_freq\x18\n \x01(\r\"q\n\x1cPanelSettingsLiteFtraceEvent\x12\x13\n\x0bpanel_index\x18\x01 \x01(\x05\x12\x0b\n\x03vrr\x18\x02 \x01(\r\x12\x0e\n\x06min_rr\x18\x03 \x01(\r\x12\x0e\n\x06max_rr\x18\x04 \x01(\r\x12\x0f\n\x07te_freq\x18\x05 \x01(\r\"\x84\x03\n\x1eSchedSwitchWithCtrsFtraceEvent\x12\x0f\n\x07old_pid\x18\x01 \x01(\x05\x12\x0f\n\x07new_pid\x18\x02 \x01(\x05\x12\x0c\n\x04\x63\x63tr\x18\x03 \x01(\x04\x12\x0c\n\x04\x63tr0\x18\x04 \x01(\x04\x12\x0c\n\x04\x63tr1\x18\x05 \x01(\x04\x12\x0c\n\x04\x63tr2\x18\x06 \x01(\x04\x12\x0c\n\x04\x63tr3\x18\x07 \x01(\x04\x12\r\n\x05lctr0\x18\x08 \x01(\r\x12\r\n\x05lctr1\x18\t \x01(\r\x12\x0c\n\x04\x63tr4\x18\n \x01(\x04\x12\x0c\n\x04\x63tr5\x18\x0b \x01(\x04\x12\x11\n\tprev_comm\x18\x0c \x01(\t\x12\x10\n\x08prev_pid\x18\r \x01(\x05\x12\x0b\n\x03\x63yc\x18\x0e \x01(\r\x12\x0c\n\x04inst\x18\x0f \x01(\r\x12\x0f\n\x07stallbm\x18\x10 \x01(\r\x12\x0c\n\x04l3dm\x18\x11 \x01(\r\x12\x10\n\x08next_pid\x18\x12 \x01(\x05\x12\x11\n\tnext_comm\x18\x13 \x01(\t\x12\x12\n\nprev_state\x18\x14 \x01(\x03\x12\x0c\n\x04\x61mu0\x18\x15 \x01(\x04\x12\x0c\n\x04\x61mu1\x18\x16 \x01(\x04\x12\x0c\n\x04\x61mu2\x18\x17 \x01(\x04\"A\n\x12LongIrqFtraceEvent\x12\x0b\n\x03irq\x18\x01 \x01(\x05\x12\x0f\n\x07latency\x18\x02 \x01(\r\x12\r\n\x05\x63ount\x18\x03 \x01(\r\"H\n\x16LongSoftirqFtraceEvent\x12\x0e\n\x06vec_nr\x18\x01 \x01(\x05\x12\x0f\n\x07latency\x18\x02 \x01(\r\x12\r\n\x05\x63ount\x18\x03 \x01(\r\"0\n\x1cPixelMmKswapdWakeFtraceEvent\x12\x10\n\x08whatever\x18\x01 \x01(\x05\"\x85\x01\n\x1cPixelMmKswapdDoneFtraceEvent\x12\x18\n\x10\x64\x65lta_nr_scanned\x18\x01 \x01(\x04\x12\x1a\n\x12\x64\x65lta_nr_reclaimed\x18\x02 \x01(\x04\x12\x1a\n\x12\x64\x65lta_nr_allocated\x18\x03 \x01(\x04\x12\x13\n\x0b\x64uration_ns\x18\x04 \x01(\x04\"8\n\x17\x43puFrequencyFtraceEvent\x12\r\n\x05state\x18\x01 \x01(\r\x12\x0e\n\x06\x63pu_id\x18\x02 \x01(\r\"S\n\x1d\x43puFrequencyLimitsFtraceEvent\x12\x10\n\x08min_freq\x18\x01 \x01(\r\x12\x10\n\x08max_freq\x18\x02 \x01(\r\x12\x0e\n\x06\x63pu_id\x18\x03 \x01(\r\"3\n\x12\x43puIdleFtraceEvent\x12\r\n\x05state\x18\x01 \x01(\r\x12\x0e\n\x06\x63pu_id\x18\x02 \x01(\r\"E\n\x16\x43lockEnableFtraceEvent\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\r\n\x05state\x18\x02 \x01(\x04\x12\x0e\n\x06\x63pu_id\x18\x03 \x01(\x04\"F\n\x17\x43lockDisableFtraceEvent\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\r\n\x05state\x18\x02 \x01(\x04\x12\x0e\n\x06\x63pu_id\x18\x03 \x01(\x04\"F\n\x17\x43lockSetRateFtraceEvent\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\r\n\x05state\x18\x02 \x01(\x04\x12\x0e\n\x06\x63pu_id\x18\x03 \x01(\x04\"F\n\x18SuspendResumeFtraceEvent\x12\x0e\n\x06\x61\x63tion\x18\x01 \x01(\t\x12\x0b\n\x03val\x18\x02 \x01(\x05\x12\r\n\x05start\x18\x03 \x01(\r\"8\n\x17GpuFrequencyFtraceEvent\x12\x0e\n\x06gpu_id\x18\x01 \x01(\r\x12\r\n\x05state\x18\x02 \x01(\r\">\n\x1fWakeupSourceActivateFtraceEvent\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\r\n\x05state\x18\x02 \x01(\x04\"@\n!WakeupSourceDeactivateFtraceEvent\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\r\n\x05state\x18\x02 \x01(\x04\"\x85\x01\n\x18GpuWorkPeriodFtraceEvent\x12\x0e\n\x06gpu_id\x18\x01 \x01(\r\x12\x0b\n\x03uid\x18\x02 \x01(\r\x12\x15\n\rstart_time_ns\x18\x03 \x01(\x04\x12\x13\n\x0b\x65nd_time_ns\x18\x04 \x01(\x04\x12 \n\x18total_active_duration_ns\x18\x05 \x01(\x04\"q\n DevicePmCallbackStartFtraceEvent\x12\x0e\n\x06\x64\x65vice\x18\x01 \x01(\t\x12\x0e\n\x06\x64river\x18\x02 \x01(\t\x12\x0e\n\x06parent\x18\x03 \x01(\t\x12\x0e\n\x06pm_ops\x18\x04 \x01(\t\x12\r\n\x05\x65vent\x18\x05 \x01(\x05\"O\n\x1e\x44\x65vicePmCallbackEndFtraceEvent\x12\x0e\n\x06\x64\x65vice\x18\x01 \x01(\t\x12\x0e\n\x06\x64river\x18\x02 \x01(\t\x12\r\n\x05\x65rror\x18\x03 \x01(\x05\"@\n\x18GpuPowerStateFtraceEvent\x12\x11\n\told_state\x18\x01 \x01(\x05\x12\x11\n\tnew_state\x18\x02 \x01(\x05\"N\n\x1dPsciDomainIdleExitFtraceEvent\x12\x0e\n\x06\x63pu_id\x18\x01 \x01(\r\x12\r\n\x05state\x18\x02 \x01(\r\x12\x0e\n\x06s2idle\x18\x03 \x01(\r\"O\n\x1ePsciDomainIdleEnterFtraceEvent\x12\x0e\n\x06\x63pu_id\x18\x01 \x01(\r\x12\r\n\x05state\x18\x02 \x01(\r\x12\x0e\n\x06s2idle\x18\x03 \x01(\r\"!\n\x12\x43onsoleFtraceEvent\x12\x0b\n\x03msg\x18\x01 \x01(\t\"/\n\x13SysEnterFtraceEvent\x12\n\n\x02id\x18\x01 \x01(\x03\x12\x0c\n\x04\x61rgs\x18\x02 \x03(\x04\"-\n\x12SysExitFtraceEvent\x12\n\n\x02id\x18\x01 \x01(\x03\x12\x0b\n\x03ret\x18\x02 \x01(\x03\"+\n\x1bRegulatorDisableFtraceEvent\x12\x0c\n\x04name\x18\x01 \x01(\t\"3\n#RegulatorDisableCompleteFtraceEvent\x12\x0c\n\x04name\x18\x01 \x01(\t\"*\n\x1aRegulatorEnableFtraceEvent\x12\x0c\n\x04name\x18\x01 \x01(\t\"2\n\"RegulatorEnableCompleteFtraceEvent\x12\x0c\n\x04name\x18\x01 \x01(\t\"/\n\x1fRegulatorEnableDelayFtraceEvent\x12\x0c\n\x04name\x18\x01 \x01(\t\"H\n\x1eRegulatorSetVoltageFtraceEvent\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0b\n\x03min\x18\x02 \x01(\x05\x12\x0b\n\x03max\x18\x03 \x01(\x05\"C\n&RegulatorSetVoltageCompleteFtraceEvent\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0b\n\x03val\x18\x02 \x01(\r\"4\n\x14RpmStatusFtraceEvent\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0e\n\x06status\x18\x02 \x01(\x05\"}\n\"SamsungTracingMarkWriteFtraceEvent\x12\x0b\n\x03pid\x18\x01 \x01(\x05\x12\x12\n\ntrace_name\x18\x02 \x01(\t\x12\x13\n\x0btrace_begin\x18\x03 \x01(\r\x12\x12\n\ntrace_type\x18\x04 \x01(\r\x12\r\n\x05value\x18\x05 \x01(\x05\"\x9c\x01\n\x16SchedSwitchFtraceEvent\x12\x11\n\tprev_comm\x18\x01 \x01(\t\x12\x10\n\x08prev_pid\x18\x02 \x01(\x05\x12\x11\n\tprev_prio\x18\x03 \x01(\x05\x12\x12\n\nprev_state\x18\x04 \x01(\x03\x12\x11\n\tnext_comm\x18\x05 \x01(\t\x12\x10\n\x08next_pid\x18\x06 \x01(\x05\x12\x11\n\tnext_prio\x18\x07 \x01(\x05\"f\n\x16SchedWakeupFtraceEvent\x12\x0c\n\x04\x63omm\x18\x01 \x01(\t\x12\x0b\n\x03pid\x18\x02 \x01(\x05\x12\x0c\n\x04prio\x18\x03 \x01(\x05\x12\x0f\n\x07success\x18\x04 \x01(\x05\x12\x12\n\ntarget_cpu\x18\x05 \x01(\x05\"M\n\x1dSchedBlockedReasonFtraceEvent\x12\x0b\n\x03pid\x18\x01 \x01(\x05\x12\x0e\n\x06\x63\x61ller\x18\x02 \x01(\x04\x12\x0f\n\x07io_wait\x18\x03 \x01(\r\"Q\n\x1aSchedCpuHotplugFtraceEvent\x12\x14\n\x0c\x61\x66\x66\x65\x63ted_cpu\x18\x01 \x01(\x05\x12\r\n\x05\x65rror\x18\x02 \x01(\x05\x12\x0e\n\x06status\x18\x03 \x01(\x05\"f\n\x16SchedWakingFtraceEvent\x12\x0c\n\x04\x63omm\x18\x01 \x01(\t\x12\x0b\n\x03pid\x18\x02 \x01(\x05\x12\x0c\n\x04prio\x18\x03 \x01(\x05\x12\x0f\n\x07success\x18\x04 \x01(\x05\x12\x12\n\ntarget_cpu\x18\x05 \x01(\x05\"i\n\x19SchedWakeupNewFtraceEvent\x12\x0c\n\x04\x63omm\x18\x01 \x01(\t\x12\x0b\n\x03pid\x18\x02 \x01(\x05\x12\x0c\n\x04prio\x18\x03 \x01(\x05\x12\x0f\n\x07success\x18\x04 \x01(\x05\x12\x12\n\ntarget_cpu\x18\x05 \x01(\x05\"M\n\x1bSchedProcessExecFtraceEvent\x12\x10\n\x08\x66ilename\x18\x01 \x01(\t\x12\x0b\n\x03pid\x18\x02 \x01(\x05\x12\x0f\n\x07old_pid\x18\x03 \x01(\x05\"T\n\x1bSchedProcessExitFtraceEvent\x12\x0c\n\x04\x63omm\x18\x01 \x01(\t\x12\x0b\n\x03pid\x18\x02 \x01(\x05\x12\x0c\n\x04tgid\x18\x03 \x01(\x05\x12\x0c\n\x04prio\x18\x04 \x01(\x05\"m\n\x1bSchedProcessForkFtraceEvent\x12\x13\n\x0bparent_comm\x18\x01 \x01(\t\x12\x12\n\nparent_pid\x18\x02 \x01(\x05\x12\x12\n\nchild_comm\x18\x03 \x01(\t\x12\x11\n\tchild_pid\x18\x04 \x01(\x05\"F\n\x1bSchedProcessFreeFtraceEvent\x12\x0c\n\x04\x63omm\x18\x01 \x01(\t\x12\x0b\n\x03pid\x18\x02 \x01(\x05\x12\x0c\n\x04prio\x18\x03 \x01(\x05\"8\n\x1bSchedProcessHangFtraceEvent\x12\x0c\n\x04\x63omm\x18\x01 \x01(\t\x12\x0b\n\x03pid\x18\x02 \x01(\x05\"F\n\x1bSchedProcessWaitFtraceEvent\x12\x0c\n\x04\x63omm\x18\x01 \x01(\t\x12\x0b\n\x03pid\x18\x02 \x01(\x05\x12\x0c\n\x04prio\x18\x03 \x01(\x05\"X\n\x19SchedPiSetprioFtraceEvent\x12\x0c\n\x04\x63omm\x18\x01 \x01(\t\x12\x0f\n\x07newprio\x18\x02 \x01(\x05\x12\x0f\n\x07oldprio\x18\x03 \x01(\x05\x12\x0b\n\x03pid\x18\x04 \x01(\x05\"\xc8\x02\n\x1aSchedCpuUtilCfsFtraceEvent\x12\x0e\n\x06\x61\x63tive\x18\x01 \x01(\x05\x12\x10\n\x08\x63\x61pacity\x18\x02 \x01(\x04\x12\x15\n\rcapacity_orig\x18\x03 \x01(\x04\x12\x0b\n\x03\x63pu\x18\x04 \x01(\r\x12\x16\n\x0e\x63pu_importance\x18\x05 \x01(\x04\x12\x10\n\x08\x63pu_util\x18\x06 \x01(\x04\x12\x10\n\x08\x65xit_lat\x18\x07 \x01(\r\x12\x16\n\x0egroup_capacity\x18\x08 \x01(\x04\x12\x18\n\x10grp_overutilized\x18\t \x01(\r\x12\x10\n\x08idle_cpu\x18\n \x01(\r\x12\x12\n\nnr_running\x18\x0b \x01(\r\x12\x11\n\tspare_cap\x18\x0c \x01(\x03\x12\x11\n\ttask_fits\x18\r \x01(\r\x12\x17\n\x0fwake_group_util\x18\x0e \x01(\x04\x12\x11\n\twake_util\x18\x0f \x01(\x04\"\x89\x01\n\x1bSchedMigrateTaskFtraceEvent\x12\x0c\n\x04\x63omm\x18\x01 \x01(\t\x12\x0b\n\x03pid\x18\x02 \x01(\x05\x12\x0c\n\x04prio\x18\x03 \x01(\x05\x12\x10\n\x08orig_cpu\x18\x04 \x01(\x05\x12\x10\n\x08\x64\x65st_cpu\x18\x05 \x01(\x05\x12\x0f\n\x07running\x18\x06 \x01(\x05\x12\x0c\n\x04load\x18\x07 \x01(\r\"\xf0\x01\n\x1eSchedWakeupTaskAttrFtraceEvent\x12\x0b\n\x03pid\x18\x01 \x01(\x05\x12\x14\n\x0c\x63pu_affinity\x18\x02 \x01(\x04\x12\x11\n\ttask_util\x18\x03 \x01(\x04\x12\x12\n\nuclamp_min\x18\x04 \x01(\x04\x12\x10\n\x08vruntime\x18\x05 \x01(\x04\x12#\n\x1bsched_qos_user_defined_flag\x18\x06 \x01(\x04\x12\x19\n\x11rampup_multiplier\x18\x07 \x01(\r\x12 \n\x18\x65\x66\x66\x65\x63t_rampup_multiplier\x18\x08 \x01(\r\x12\x10\n\x08tag_nice\x18\t \x01(\x05\"[\n\x1cSchedGroupTrackerFtraceEvent\x12\x0c\n\x04\x63omm\x18\x01 \x01(\t\x12\x0b\n\x03pid\x18\x02 \x01(\x05\x12\r\n\x05group\x18\x03 \x01(\t\x12\x11\n\tgroup_num\x18\x04 \x01(\x05\"B\n\x17ScmCallStartFtraceEvent\x12\x0f\n\x07\x61rginfo\x18\x01 \x01(\r\x12\n\n\x02x0\x18\x02 \x01(\x04\x12\n\n\x02x5\x18\x03 \x01(\x04\"\x17\n\x15ScmCallEndFtraceEvent\"\xfc\x01\n\x1fScsiDispatchCmdErrorFtraceEvent\x12\x0f\n\x07host_no\x18\x01 \x01(\r\x12\x0f\n\x07\x63hannel\x18\x02 \x01(\r\x12\n\n\x02id\x18\x03 \x01(\r\x12\x0b\n\x03lun\x18\x04 \x01(\r\x12\x0b\n\x03rtn\x18\x05 \x01(\x05\x12\x0e\n\x06opcode\x18\x06 \x01(\r\x12\x0f\n\x07\x63md_len\x18\x07 \x01(\r\x12\x12\n\ndata_sglen\x18\x08 \x01(\r\x12\x12\n\nprot_sglen\x18\t \x01(\r\x12\x0f\n\x07prot_op\x18\n \x01(\r\x12\x12\n\ndriver_tag\x18\x0c \x01(\x05\x12\x15\n\rscheduler_tag\x18\r \x01(\x05\x12\x0c\n\x04\x63mnd\x18\x0e \x01(\x0c\"\xaf\x02\n!ScsiDispatchCmdTimeoutFtraceEvent\x12\x0f\n\x07host_no\x18\x01 \x01(\r\x12\x0f\n\x07\x63hannel\x18\x02 \x01(\r\x12\n\n\x02id\x18\x03 \x01(\r\x12\x0b\n\x03lun\x18\x04 \x01(\r\x12\x0e\n\x06result\x18\x05 \x01(\x05\x12\x0e\n\x06opcode\x18\x06 \x01(\r\x12\x0f\n\x07\x63md_len\x18\x07 \x01(\r\x12\x12\n\ndata_sglen\x18\x08 \x01(\r\x12\x12\n\nprot_sglen\x18\t \x01(\r\x12\x0f\n\x07prot_op\x18\n \x01(\r\x12\x12\n\ndriver_tag\x18\x0c \x01(\x05\x12\x15\n\rscheduler_tag\x18\r \x01(\x05\x12\x11\n\tsense_key\x18\x0e \x01(\r\x12\x0b\n\x03\x61sc\x18\x0f \x01(\r\x12\x0c\n\x04\x61scq\x18\x10 \x01(\r\x12\x0c\n\x04\x63mnd\x18\x11 \x01(\x0c\"*\n\x17ScsiEhWakeupFtraceEvent\x12\x0f\n\x07host_no\x18\x01 \x01(\r\"y\n\x1eSdeTracingMarkWriteFtraceEvent\x12\x0b\n\x03pid\x18\x01 \x01(\x05\x12\x12\n\ntrace_name\x18\x02 \x01(\t\x12\x12\n\ntrace_type\x18\x03 \x01(\r\x12\r\n\x05value\x18\x04 \x01(\x05\x12\x13\n\x0btrace_begin\x18\x05 \x01(\r\"\x8d\x02\n\x17SdeSdeEvtlogFtraceEvent\x12\x12\n\nevtlog_tag\x18\x01 \x01(\t\x12\x0b\n\x03pid\x18\x02 \x01(\x05\x12\x0e\n\x06tag_id\x18\x03 \x01(\r\x12\x0b\n\x03\x64\x30\x30\x18\x04 \x01(\r\x12\x0b\n\x03\x64\x30\x31\x18\x05 \x01(\r\x12\x0b\n\x03\x64\x30\x32\x18\x06 \x01(\r\x12\x0b\n\x03\x64\x30\x33\x18\x07 \x01(\r\x12\x0b\n\x03\x64\x30\x34\x18\x08 \x01(\r\x12\x0b\n\x03\x64\x30\x35\x18\t \x01(\r\x12\x0b\n\x03\x64\x30\x36\x18\n \x01(\r\x12\x0b\n\x03\x64\x30\x37\x18\x0b \x01(\r\x12\x0b\n\x03\x64\x30\x38\x18\x0c \x01(\r\x12\x0b\n\x03\x64\x30\x39\x18\r \x01(\r\x12\x0b\n\x03\x64\x31\x30\x18\x0e \x01(\r\x12\x0b\n\x03\x64\x31\x31\x18\x0f \x01(\r\x12\x0b\n\x03\x64\x31\x32\x18\x10 \x01(\r\x12\x0b\n\x03\x64\x31\x33\x18\x11 \x01(\r\x12\x0b\n\x03\x64\x31\x34\x18\x12 \x01(\r\"\xb4\x01\n\x1dSdeSdePerfCalcCrtcFtraceEvent\x12\x12\n\nbw_ctl_ebi\x18\x01 \x01(\x04\x12\x13\n\x0b\x62w_ctl_llcc\x18\x02 \x01(\x04\x12\x13\n\x0b\x62w_ctl_mnoc\x18\x03 \x01(\x04\x12\x15\n\rcore_clk_rate\x18\x04 \x01(\r\x12\x0c\n\x04\x63rtc\x18\x05 \x01(\r\x12\x0e\n\x06ib_ebi\x18\x06 \x01(\x04\x12\x0f\n\x07ib_llcc\x18\x07 \x01(\x04\x12\x0f\n\x07ib_mnoc\x18\x08 \x01(\x04\"\x9b\x02\n\x1fSdeSdePerfCrtcUpdateFtraceEvent\x12\x12\n\nbw_ctl_ebi\x18\x01 \x01(\x04\x12\x13\n\x0b\x62w_ctl_llcc\x18\x02 \x01(\x04\x12\x13\n\x0b\x62w_ctl_mnoc\x18\x03 \x01(\x04\x12\x15\n\rcore_clk_rate\x18\x04 \x01(\r\x12\x0c\n\x04\x63rtc\x18\x05 \x01(\r\x12\x0e\n\x06params\x18\x06 \x01(\x05\x12\x17\n\x0fper_pipe_ib_ebi\x18\x07 \x01(\x04\x12\x18\n\x10per_pipe_ib_llcc\x18\x08 \x01(\x04\x12\x18\n\x10per_pipe_ib_mnoc\x18\t \x01(\x04\x12\x10\n\x08stop_req\x18\n \x01(\r\x12\x12\n\nupdate_bus\x18\x0b \x01(\r\x12\x12\n\nupdate_clk\x18\x0c \x01(\r\"t\n\x1fSdeSdePerfSetQosLutsFtraceEvent\x12\n\n\x02\x66l\x18\x01 \x01(\r\x12\x0b\n\x03\x66mt\x18\x02 \x01(\r\x12\x0b\n\x03lut\x18\x03 \x01(\x04\x12\x11\n\tlut_usage\x18\x04 \x01(\r\x12\x0c\n\x04pnum\x18\x05 \x01(\r\x12\n\n\x02rt\x18\x06 \x01(\r\"d\n\x1eSdeSdePerfUpdateBusFtraceEvent\x12\x10\n\x08\x61\x62_quota\x18\x01 \x01(\x04\x12\x0e\n\x06\x62us_id\x18\x02 \x01(\r\x12\x0e\n\x06\x63lient\x18\x03 \x01(\x05\x12\x10\n\x08ib_quota\x18\x04 \x01(\x04\"G\n\x18SignalDeliverFtraceEvent\x12\x0c\n\x04\x63ode\x18\x01 \x01(\x05\x12\x10\n\x08sa_flags\x18\x02 \x01(\x04\x12\x0b\n\x03sig\x18\x03 \x01(\x05\"p\n\x19SignalGenerateFtraceEvent\x12\x0c\n\x04\x63ode\x18\x01 \x01(\x05\x12\x0c\n\x04\x63omm\x18\x02 \x01(\t\x12\r\n\x05group\x18\x03 \x01(\x05\x12\x0b\n\x03pid\x18\x04 \x01(\x05\x12\x0e\n\x06result\x18\x05 \x01(\x05\x12\x0b\n\x03sig\x18\x06 \x01(\x05\"J\n\x13KfreeSkbFtraceEvent\x12\x10\n\x08location\x18\x01 \x01(\x04\x12\x10\n\x08protocol\x18\x02 \x01(\r\x12\x0f\n\x07skbaddr\x18\x03 \x01(\x04\"\xaf\x01\n\x1bInetSockSetStateFtraceEvent\x12\r\n\x05\x64\x61\x64\x64r\x18\x01 \x01(\r\x12\r\n\x05\x64port\x18\x02 \x01(\r\x12\x0e\n\x06\x66\x61mily\x18\x03 \x01(\r\x12\x10\n\x08newstate\x18\x04 \x01(\x05\x12\x10\n\x08oldstate\x18\x05 \x01(\x05\x12\x10\n\x08protocol\x18\x06 \x01(\r\x12\r\n\x05saddr\x18\x07 \x01(\r\x12\x0e\n\x06skaddr\x18\x08 \x01(\x04\x12\r\n\x05sport\x18\t \x01(\r\"4\n\x11SyncPtFtraceEvent\x12\x10\n\x08timeline\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t\"6\n\x17SyncTimelineFtraceEvent\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t\"B\n\x13SyncWaitFtraceEvent\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0e\n\x06status\x18\x02 \x01(\x05\x12\r\n\x05\x62\x65gin\x18\x03 \x01(\r\"X\n\x1bRssStatThrottledFtraceEvent\x12\x0c\n\x04\x63urr\x18\x01 \x01(\r\x12\x0e\n\x06member\x18\x02 \x01(\x05\x12\r\n\x05mm_id\x18\x03 \x01(\r\x12\x0c\n\x04size\x18\x04 \x01(\x03\"0\n\x1fSuspendResumeMinimalFtraceEvent\x12\r\n\x05start\x18\x01 \x01(\r\"I\n\x0fZeroFtraceEvent\x12\x0c\n\x04\x66lag\x18\x01 \x01(\x05\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x0b\n\x03pid\x18\x03 \x01(\x05\x12\r\n\x05value\x18\x04 \x01(\x03\"_\n\x16TaskNewtaskFtraceEvent\x12\x0b\n\x03pid\x18\x01 \x01(\x05\x12\x0c\n\x04\x63omm\x18\x02 \x01(\t\x12\x13\n\x0b\x63lone_flags\x18\x03 \x01(\x04\x12\x15\n\room_score_adj\x18\x04 \x01(\x05\"]\n\x15TaskRenameFtraceEvent\x12\x0b\n\x03pid\x18\x01 \x01(\x05\x12\x0f\n\x07oldcomm\x18\x02 \x01(\t\x12\x0f\n\x07newcomm\x18\x03 \x01(\t\x12\x15\n\room_score_adj\x18\x04 \x01(\x05\"\x89\x01\n\x1bTcpRetransmitSkbFtraceEvent\x12\r\n\x05\x64\x61\x64\x64r\x18\x01 \x01(\r\x12\r\n\x05\x64port\x18\x02 \x01(\r\x12\r\n\x05saddr\x18\x03 \x01(\r\x12\x0e\n\x06skaddr\x18\x04 \x01(\x04\x12\x0f\n\x07skbaddr\x18\x05 \x01(\x04\x12\r\n\x05sport\x18\x06 \x01(\r\x12\r\n\x05state\x18\x07 \x01(\x05\"b\n\x1dThermalTemperatureFtraceEvent\x12\n\n\x02id\x18\x01 \x01(\x05\x12\x0c\n\x04temp\x18\x02 \x01(\x05\x12\x11\n\ttemp_prev\x18\x03 \x01(\x05\x12\x14\n\x0cthermal_zone\x18\x04 \x01(\t\"5\n\x15\x43\x64\x65vUpdateFtraceEvent\x12\x0e\n\x06target\x18\x01 \x01(\x04\x12\x0c\n\x04type\x18\x02 \x01(\t\"\xe4\x01\n ThermalExynosAcpmBulkFtraceEvent\x12\r\n\x05tz_id\x18\x01 \x01(\r\x12\x14\n\x0c\x63urrent_temp\x18\x02 \x01(\r\x12\x11\n\tctrl_temp\x18\x03 \x01(\r\x12\x12\n\ncdev_state\x18\x04 \x01(\r\x12\x10\n\x08pid_et_p\x18\x05 \x01(\x05\x12\x17\n\x0fpid_power_range\x18\x06 \x01(\x05\x12\r\n\x05pid_p\x18\x07 \x01(\x05\x12\r\n\x05pid_i\x18\x08 \x01(\x05\x12\x0b\n\x03k_p\x18\t \x01(\x05\x12\x0b\n\x03k_i\x18\n \x01(\x05\x12\x11\n\ttimestamp\x18\x0b \x01(\x04\"\xa2\x01\n(ThermalExynosAcpmHighOverheadFtraceEvent\x12\r\n\x05tz_id\x18\x01 \x01(\x05\x12\x14\n\x0c\x63urrent_temp\x18\x02 \x01(\r\x12\x11\n\tctrl_temp\x18\x03 \x01(\r\x12\x12\n\ncdev_state\x18\x04 \x01(\r\x12\x10\n\x08pid_et_p\x18\x05 \x01(\x05\x12\x0b\n\x03k_p\x18\x06 \x01(\x05\x12\x0b\n\x03k_i\x18\x07 \x01(\x05\"p\n\x17HrtimerStartFtraceEvent\x12\x0f\n\x07hrtimer\x18\x01 \x01(\x04\x12\x10\n\x08\x66unction\x18\x02 \x01(\x04\x12\x0f\n\x07\x65xpires\x18\x03 \x01(\x03\x12\x13\n\x0bsoftexpires\x18\x04 \x01(\x03\x12\x0c\n\x04mode\x18\x05 \x01(\r\"+\n\x18HrtimerCancelFtraceEvent\x12\x0f\n\x07hrtimer\x18\x01 \x01(\x04\"O\n\x1dHrtimerExpireEntryFtraceEvent\x12\x0f\n\x07hrtimer\x18\x01 \x01(\x04\x12\x0b\n\x03now\x18\x02 \x01(\x03\x12\x10\n\x08\x66unction\x18\x03 \x01(\x04\"/\n\x1cHrtimerExpireExitFtraceEvent\x12\x0f\n\x07hrtimer\x18\x01 \x01(\x04\"\x90\x01\n\x15TimerStartFtraceEvent\x12\r\n\x05timer\x18\x01 \x01(\x04\x12\x10\n\x08\x66unction\x18\x02 \x01(\x04\x12\x0f\n\x07\x65xpires\x18\x03 \x01(\x04\x12\x0b\n\x03now\x18\x04 \x01(\x04\x12\x12\n\ndeferrable\x18\x05 \x01(\r\x12\r\n\x05\x66lags\x18\x06 \x01(\r\x12\x15\n\rbucket_expiry\x18\x07 \x01(\x04\"\'\n\x16TimerCancelFtraceEvent\x12\r\n\x05timer\x18\x01 \x01(\x04\"\\\n\x1bTimerExpireEntryFtraceEvent\x12\r\n\x05timer\x18\x01 \x01(\x04\x12\x0b\n\x03now\x18\x02 \x01(\x04\x12\x10\n\x08\x66unction\x18\x03 \x01(\x04\x12\x0f\n\x07\x62\x61seclk\x18\x04 \x01(\x04\"+\n\x1aTimerExpireExitFtraceEvent\x12\r\n\x05timer\x18\x01 \x01(\x04\"F\n\x14TrustySmcFtraceEvent\x12\n\n\x02r0\x18\x01 \x01(\x04\x12\n\n\x02r1\x18\x02 \x01(\x04\x12\n\n\x02r2\x18\x03 \x01(\x04\x12\n\n\x02r3\x18\x04 \x01(\x04\"\'\n\x18TrustySmcDoneFtraceEvent\x12\x0b\n\x03ret\x18\x01 \x01(\x04\"L\n\x1aTrustyStdCall32FtraceEvent\x12\n\n\x02r0\x18\x01 \x01(\x04\x12\n\n\x02r1\x18\x02 \x01(\x04\x12\n\n\x02r2\x18\x03 \x01(\x04\x12\n\n\x02r3\x18\x04 \x01(\x04\"-\n\x1eTrustyStdCall32DoneFtraceEvent\x12\x0b\n\x03ret\x18\x01 \x01(\x03\"H\n\x1cTrustyShareMemoryFtraceEvent\x12\x0b\n\x03len\x18\x01 \x01(\x04\x12\x0c\n\x04lend\x18\x02 \x01(\r\x12\r\n\x05nents\x18\x03 \x01(\r\"i\n TrustyShareMemoryDoneFtraceEvent\x12\x0e\n\x06handle\x18\x01 \x01(\x04\x12\x0b\n\x03len\x18\x02 \x01(\x04\x12\x0c\n\x04lend\x18\x03 \x01(\r\x12\r\n\x05nents\x18\x04 \x01(\r\x12\x0b\n\x03ret\x18\x05 \x01(\x05\",\n\x1eTrustyReclaimMemoryFtraceEvent\x12\n\n\x02id\x18\x01 \x01(\x04\"=\n\"TrustyReclaimMemoryDoneFtraceEvent\x12\n\n\x02id\x18\x01 \x01(\x04\x12\x0b\n\x03ret\x18\x02 \x01(\x05\"#\n\x14TrustyIrqFtraceEvent\x12\x0b\n\x03irq\x18\x01 \x01(\x05\"S\n\x1fTrustyIpcHandleEventFtraceEvent\x12\x0c\n\x04\x63han\x18\x01 \x01(\r\x12\x10\n\x08\x65vent_id\x18\x02 \x01(\r\x12\x10\n\x08srv_name\x18\x03 \x01(\t\"H\n\x1bTrustyIpcConnectFtraceEvent\x12\x0c\n\x04\x63han\x18\x01 \x01(\r\x12\x0c\n\x04port\x18\x02 \x01(\t\x12\r\n\x05state\x18\x03 \x01(\x05\"J\n\x1eTrustyIpcConnectEndFtraceEvent\x12\x0c\n\x04\x63han\x18\x01 \x01(\r\x12\x0b\n\x03\x65rr\x18\x02 \x01(\x05\x12\r\n\x05state\x18\x03 \x01(\x05\"\x82\x01\n\x19TrustyIpcWriteFtraceEvent\x12\x0e\n\x06\x62uf_id\x18\x01 \x01(\x04\x12\x0c\n\x04\x63han\x18\x02 \x01(\r\x12\x10\n\x08kind_shm\x18\x03 \x01(\x05\x12\x12\n\nlen_or_err\x18\x04 \x01(\x05\x12\x0f\n\x07shm_cnt\x18\x05 \x01(\x04\x12\x10\n\x08srv_name\x18\x06 \x01(\t\"M\n\x18TrustyIpcPollFtraceEvent\x12\x0c\n\x04\x63han\x18\x01 \x01(\r\x12\x11\n\tpoll_mask\x18\x02 \x01(\r\x12\x10\n\x08srv_name\x18\x03 \x01(\t\":\n\x18TrustyIpcReadFtraceEvent\x12\x0c\n\x04\x63han\x18\x01 \x01(\r\x12\x10\n\x08srv_name\x18\x02 \x01(\t\"r\n\x1bTrustyIpcReadEndFtraceEvent\x12\x0e\n\x06\x62uf_id\x18\x01 \x01(\x04\x12\x0c\n\x04\x63han\x18\x02 \x01(\r\x12\x12\n\nlen_or_err\x18\x03 \x01(\x05\x12\x0f\n\x07shm_cnt\x18\x04 \x01(\x04\x12\x10\n\x08srv_name\x18\x05 \x01(\t\"H\n\x16TrustyIpcRxFtraceEvent\x12\x0e\n\x06\x62uf_id\x18\x01 \x01(\x04\x12\x0c\n\x04\x63han\x18\x02 \x01(\r\x12\x10\n\x08srv_name\x18\x03 \x01(\t\"G\n\x1bTrustyEnqueueNopFtraceEvent\x12\x0c\n\x04\x61rg1\x18\x01 \x01(\r\x12\x0c\n\x04\x61rg2\x18\x02 \x01(\r\x12\x0c\n\x04\x61rg3\x18\x03 \x01(\r\"\xba\x01\n\x18UfshcdCommandFtraceEvent\x12\x10\n\x08\x64\x65v_name\x18\x01 \x01(\t\x12\x10\n\x08\x64oorbell\x18\x02 \x01(\r\x12\x0c\n\x04intr\x18\x03 \x01(\r\x12\x0b\n\x03lba\x18\x04 \x01(\x04\x12\x0e\n\x06opcode\x18\x05 \x01(\r\x12\x0b\n\x03str\x18\x06 \x01(\t\x12\x0b\n\x03tag\x18\x07 \x01(\r\x12\x14\n\x0ctransfer_len\x18\x08 \x01(\x05\x12\x10\n\x08group_id\x18\t \x01(\r\x12\r\n\x05str_t\x18\n \x01(\r\"=\n\x1aUfshcdClkGatingFtraceEvent\x12\x10\n\x08\x64\x65v_name\x18\x01 \x01(\t\x12\r\n\x05state\x18\x02 \x01(\x05\"\x9b\x03\n\x13V4l2QbufFtraceEvent\x12\x11\n\tbytesused\x18\x01 \x01(\r\x12\r\n\x05\x66ield\x18\x02 \x01(\r\x12\r\n\x05\x66lags\x18\x03 \x01(\r\x12\r\n\x05index\x18\x04 \x01(\r\x12\r\n\x05minor\x18\x05 \x01(\x05\x12\x10\n\x08sequence\x18\x06 \x01(\r\x12\x16\n\x0etimecode_flags\x18\x07 \x01(\r\x12\x17\n\x0ftimecode_frames\x18\x08 \x01(\r\x12\x16\n\x0etimecode_hours\x18\t \x01(\r\x12\x18\n\x10timecode_minutes\x18\n \x01(\r\x12\x18\n\x10timecode_seconds\x18\x0b \x01(\r\x12\x15\n\rtimecode_type\x18\x0c \x01(\r\x12\x1a\n\x12timecode_userbits0\x18\r \x01(\r\x12\x1a\n\x12timecode_userbits1\x18\x0e \x01(\r\x12\x1a\n\x12timecode_userbits2\x18\x0f \x01(\r\x12\x1a\n\x12timecode_userbits3\x18\x10 \x01(\r\x12\x11\n\ttimestamp\x18\x11 \x01(\x03\x12\x0c\n\x04type\x18\x12 \x01(\r\"\x9c\x03\n\x14V4l2DqbufFtraceEvent\x12\x11\n\tbytesused\x18\x01 \x01(\r\x12\r\n\x05\x66ield\x18\x02 \x01(\r\x12\r\n\x05\x66lags\x18\x03 \x01(\r\x12\r\n\x05index\x18\x04 \x01(\r\x12\r\n\x05minor\x18\x05 \x01(\x05\x12\x10\n\x08sequence\x18\x06 \x01(\r\x12\x16\n\x0etimecode_flags\x18\x07 \x01(\r\x12\x17\n\x0ftimecode_frames\x18\x08 \x01(\r\x12\x16\n\x0etimecode_hours\x18\t \x01(\r\x12\x18\n\x10timecode_minutes\x18\n \x01(\r\x12\x18\n\x10timecode_seconds\x18\x0b \x01(\r\x12\x15\n\rtimecode_type\x18\x0c \x01(\r\x12\x1a\n\x12timecode_userbits0\x18\r \x01(\r\x12\x1a\n\x12timecode_userbits1\x18\x0e \x01(\r\x12\x1a\n\x12timecode_userbits2\x18\x0f \x01(\r\x12\x1a\n\x12timecode_userbits3\x18\x10 \x01(\r\x12\x11\n\ttimestamp\x18\x11 \x01(\x03\x12\x0c\n\x04type\x18\x12 \x01(\r\"\xf2\x02\n\x1aVb2V4l2BufQueueFtraceEvent\x12\r\n\x05\x66ield\x18\x01 \x01(\r\x12\r\n\x05\x66lags\x18\x02 \x01(\r\x12\r\n\x05minor\x18\x03 \x01(\x05\x12\x10\n\x08sequence\x18\x04 \x01(\r\x12\x16\n\x0etimecode_flags\x18\x05 \x01(\r\x12\x17\n\x0ftimecode_frames\x18\x06 \x01(\r\x12\x16\n\x0etimecode_hours\x18\x07 \x01(\r\x12\x18\n\x10timecode_minutes\x18\x08 \x01(\r\x12\x18\n\x10timecode_seconds\x18\t \x01(\r\x12\x15\n\rtimecode_type\x18\n \x01(\r\x12\x1a\n\x12timecode_userbits0\x18\x0b \x01(\r\x12\x1a\n\x12timecode_userbits1\x18\x0c \x01(\r\x12\x1a\n\x12timecode_userbits2\x18\r \x01(\r\x12\x1a\n\x12timecode_userbits3\x18\x0e \x01(\r\x12\x11\n\ttimestamp\x18\x0f \x01(\x03\"\xf1\x02\n\x19Vb2V4l2BufDoneFtraceEvent\x12\r\n\x05\x66ield\x18\x01 \x01(\r\x12\r\n\x05\x66lags\x18\x02 \x01(\r\x12\r\n\x05minor\x18\x03 \x01(\x05\x12\x10\n\x08sequence\x18\x04 \x01(\r\x12\x16\n\x0etimecode_flags\x18\x05 \x01(\r\x12\x17\n\x0ftimecode_frames\x18\x06 \x01(\r\x12\x16\n\x0etimecode_hours\x18\x07 \x01(\r\x12\x18\n\x10timecode_minutes\x18\x08 \x01(\r\x12\x18\n\x10timecode_seconds\x18\t \x01(\r\x12\x15\n\rtimecode_type\x18\n \x01(\r\x12\x1a\n\x12timecode_userbits0\x18\x0b \x01(\r\x12\x1a\n\x12timecode_userbits1\x18\x0c \x01(\r\x12\x1a\n\x12timecode_userbits2\x18\r \x01(\r\x12\x1a\n\x12timecode_userbits3\x18\x0e \x01(\r\x12\x11\n\ttimestamp\x18\x0f \x01(\x03\"\xee\x02\n\x16Vb2V4l2QbufFtraceEvent\x12\r\n\x05\x66ield\x18\x01 \x01(\r\x12\r\n\x05\x66lags\x18\x02 \x01(\r\x12\r\n\x05minor\x18\x03 \x01(\x05\x12\x10\n\x08sequence\x18\x04 \x01(\r\x12\x16\n\x0etimecode_flags\x18\x05 \x01(\r\x12\x17\n\x0ftimecode_frames\x18\x06 \x01(\r\x12\x16\n\x0etimecode_hours\x18\x07 \x01(\r\x12\x18\n\x10timecode_minutes\x18\x08 \x01(\r\x12\x18\n\x10timecode_seconds\x18\t \x01(\r\x12\x15\n\rtimecode_type\x18\n \x01(\r\x12\x1a\n\x12timecode_userbits0\x18\x0b \x01(\r\x12\x1a\n\x12timecode_userbits1\x18\x0c \x01(\r\x12\x1a\n\x12timecode_userbits2\x18\r \x01(\r\x12\x1a\n\x12timecode_userbits3\x18\x0e \x01(\r\x12\x11\n\ttimestamp\x18\x0f \x01(\x03\"\xef\x02\n\x17Vb2V4l2DqbufFtraceEvent\x12\r\n\x05\x66ield\x18\x01 \x01(\r\x12\r\n\x05\x66lags\x18\x02 \x01(\r\x12\r\n\x05minor\x18\x03 \x01(\x05\x12\x10\n\x08sequence\x18\x04 \x01(\r\x12\x16\n\x0etimecode_flags\x18\x05 \x01(\r\x12\x17\n\x0ftimecode_frames\x18\x06 \x01(\r\x12\x16\n\x0etimecode_hours\x18\x07 \x01(\r\x12\x18\n\x10timecode_minutes\x18\x08 \x01(\r\x12\x18\n\x10timecode_seconds\x18\t \x01(\r\x12\x15\n\rtimecode_type\x18\n \x01(\r\x12\x1a\n\x12timecode_userbits0\x18\x0b \x01(\r\x12\x1a\n\x12timecode_userbits1\x18\x0c \x01(\r\x12\x1a\n\x12timecode_userbits2\x18\r \x01(\r\x12\x1a\n\x12timecode_userbits3\x18\x0e \x01(\r\x12\x11\n\ttimestamp\x18\x0f \x01(\x03\"\xa5\x01\n\x1cVirtioGpuCmdQueueFtraceEvent\x12\x0e\n\x06\x63tx_id\x18\x01 \x01(\r\x12\x0b\n\x03\x64\x65v\x18\x02 \x01(\x05\x12\x10\n\x08\x66\x65nce_id\x18\x03 \x01(\x04\x12\r\n\x05\x66lags\x18\x04 \x01(\r\x12\x0c\n\x04name\x18\x05 \x01(\t\x12\x10\n\x08num_free\x18\x06 \x01(\r\x12\r\n\x05seqno\x18\x07 \x01(\r\x12\x0c\n\x04type\x18\x08 \x01(\r\x12\n\n\x02vq\x18\t \x01(\r\"\xa8\x01\n\x1fVirtioGpuCmdResponseFtraceEvent\x12\x0e\n\x06\x63tx_id\x18\x01 \x01(\r\x12\x0b\n\x03\x64\x65v\x18\x02 \x01(\x05\x12\x10\n\x08\x66\x65nce_id\x18\x03 \x01(\x04\x12\r\n\x05\x66lags\x18\x04 \x01(\r\x12\x0c\n\x04name\x18\x05 \x01(\t\x12\x10\n\x08num_free\x18\x06 \x01(\r\x12\r\n\x05seqno\x18\x07 \x01(\r\x12\x0c\n\x04type\x18\x08 \x01(\r\x12\n\n\x02vq\x18\t \x01(\r\"<\n\x19VirtioVideoCmdFtraceEvent\x12\x11\n\tstream_id\x18\x01 \x01(\r\x12\x0c\n\x04type\x18\x02 \x01(\r\"@\n\x1dVirtioVideoCmdDoneFtraceEvent\x12\x11\n\tstream_id\x18\x01 \x01(\r\x12\x0c\n\x04type\x18\x02 \x01(\r\"\xc4\x01\n#VirtioVideoResourceQueueFtraceEvent\x12\x12\n\ndata_size0\x18\x01 \x01(\r\x12\x12\n\ndata_size1\x18\x02 \x01(\r\x12\x12\n\ndata_size2\x18\x03 \x01(\r\x12\x12\n\ndata_size3\x18\x04 \x01(\r\x12\x12\n\nqueue_type\x18\x05 \x01(\r\x12\x13\n\x0bresource_id\x18\x06 \x01(\x05\x12\x11\n\tstream_id\x18\x07 \x01(\x05\x12\x11\n\ttimestamp\x18\x08 \x01(\x04\"\xc8\x01\n\'VirtioVideoResourceQueueDoneFtraceEvent\x12\x12\n\ndata_size0\x18\x01 \x01(\r\x12\x12\n\ndata_size1\x18\x02 \x01(\r\x12\x12\n\ndata_size2\x18\x03 \x01(\r\x12\x12\n\ndata_size3\x18\x04 \x01(\r\x12\x12\n\nqueue_type\x18\x05 \x01(\r\x12\x13\n\x0bresource_id\x18\x06 \x01(\x05\x12\x11\n\tstream_id\x18\x07 \x01(\x05\x12\x11\n\ttimestamp\x18\x08 \x01(\x04\"`\n%MmVmscanDirectReclaimBeginFtraceEvent\x12\r\n\x05order\x18\x01 \x01(\x05\x12\x15\n\rmay_writepage\x18\x02 \x01(\x05\x12\x11\n\tgfp_flags\x18\x03 \x01(\r\";\n#MmVmscanDirectReclaimEndFtraceEvent\x12\x14\n\x0cnr_reclaimed\x18\x01 \x01(\x04\"H\n\x1dMmVmscanKswapdWakeFtraceEvent\x12\x0b\n\x03nid\x18\x01 \x01(\x05\x12\r\n\x05order\x18\x02 \x01(\x05\x12\x0b\n\x03zid\x18\x03 \x01(\x05\"-\n\x1eMmVmscanKswapdSleepFtraceEvent\x12\x0b\n\x03nid\x18\x01 \x01(\x05\"\xe9\x01\n\x1cMmShrinkSlabStartFtraceEvent\x12\x13\n\x0b\x63\x61\x63he_items\x18\x01 \x01(\x04\x12\r\n\x05\x64\x65lta\x18\x02 \x01(\x04\x12\x11\n\tgfp_flags\x18\x03 \x01(\r\x12\x0f\n\x07lru_pgs\x18\x04 \x01(\x04\x12\x1c\n\x14nr_objects_to_shrink\x18\x05 \x01(\x03\x12\x13\n\x0bpgs_scanned\x18\x06 \x01(\x04\x12\x0b\n\x03shr\x18\x07 \x01(\x04\x12\x0e\n\x06shrink\x18\x08 \x01(\x04\x12\x12\n\ntotal_scan\x18\t \x01(\x04\x12\x0b\n\x03nid\x18\n \x01(\x05\x12\x10\n\x08priority\x18\x0b \x01(\x05\"\x91\x01\n\x1aMmShrinkSlabEndFtraceEvent\x12\x10\n\x08new_scan\x18\x01 \x01(\x03\x12\x0e\n\x06retval\x18\x02 \x01(\x05\x12\x0b\n\x03shr\x18\x03 \x01(\x04\x12\x0e\n\x06shrink\x18\x04 \x01(\x04\x12\x12\n\ntotal_scan\x18\x05 \x01(\x03\x12\x13\n\x0bunused_scan\x18\x06 \x01(\x03\x12\x0b\n\x03nid\x18\x07 \x01(\x05\"_\n$MmVmscanMemcgReclaimBeginFtraceEvent\x12\r\n\x05order\x18\x01 \x01(\x05\x12\x15\n\rmay_writepage\x18\x02 \x01(\x05\x12\x11\n\tgfp_flags\x18\x03 \x01(\x04\":\n\"MmVmscanMemcgReclaimEndFtraceEvent\x12\x14\n\x0cnr_reclaimed\x18\x01 \x01(\x04\"B\n WorkqueueActivateWorkFtraceEvent\x12\x0c\n\x04work\x18\x01 \x01(\x04\x12\x10\n\x08\x66unction\x18\x02 \x01(\x04\"@\n\x1eWorkqueueExecuteEndFtraceEvent\x12\x0c\n\x04work\x18\x01 \x01(\x04\x12\x10\n\x08\x66unction\x18\x02 \x01(\x04\"B\n WorkqueueExecuteStartFtraceEvent\x12\x0c\n\x04work\x18\x01 \x01(\x04\x12\x10\n\x08\x66unction\x18\x02 \x01(\x04\"p\n\x1dWorkqueueQueueWorkFtraceEvent\x12\x0c\n\x04work\x18\x01 \x01(\x04\x12\x10\n\x08\x66unction\x18\x02 \x01(\x04\x12\x0f\n\x07req_cpu\x18\x04 \x01(\x05\x12\x0b\n\x03\x63pu\x18\x05 \x01(\x05\x12\x11\n\tworkqueue\x18\x06 \x01(\t\"\xff\xec\x02\n\x0b\x46traceEvent\x12\x11\n\ttimestamp\x18\x01 \x01(\x04\x12\x0b\n\x03pid\x18\x02 \x01(\r\x12\x14\n\x0c\x63ommon_flags\x18\x05 \x01(\r\x12\x32\n\x05print\x18\x03 \x01(\x0b\x32!.perfetto.protos.PrintFtraceEventH\x00\x12?\n\x0csched_switch\x18\x04 \x01(\x0b\x32\'.perfetto.protos.SchedSwitchFtraceEventH\x00\x12\x41\n\rcpu_frequency\x18\x0b \x01(\x0b\x32(.perfetto.protos.CpuFrequencyFtraceEventH\x00\x12N\n\x14\x63pu_frequency_limits\x18\x0c \x01(\x0b\x32..perfetto.protos.CpuFrequencyLimitsFtraceEventH\x00\x12\x37\n\x08\x63pu_idle\x18\r \x01(\x0b\x32#.perfetto.protos.CpuIdleFtraceEventH\x00\x12?\n\x0c\x63lock_enable\x18\x0e \x01(\x0b\x32\'.perfetto.protos.ClockEnableFtraceEventH\x00\x12\x41\n\rclock_disable\x18\x0f \x01(\x0b\x32(.perfetto.protos.ClockDisableFtraceEventH\x00\x12\x42\n\x0e\x63lock_set_rate\x18\x10 \x01(\x0b\x32(.perfetto.protos.ClockSetRateFtraceEventH\x00\x12?\n\x0csched_wakeup\x18\x11 \x01(\x0b\x32\'.perfetto.protos.SchedWakeupFtraceEventH\x00\x12N\n\x14sched_blocked_reason\x18\x12 \x01(\x0b\x32..perfetto.protos.SchedBlockedReasonFtraceEventH\x00\x12H\n\x11sched_cpu_hotplug\x18\x13 \x01(\x0b\x32+.perfetto.protos.SchedCpuHotplugFtraceEventH\x00\x12?\n\x0csched_waking\x18\x14 \x01(\x0b\x32\'.perfetto.protos.SchedWakingFtraceEventH\x00\x12\x39\n\tipi_entry\x18\x15 \x01(\x0b\x32$.perfetto.protos.IpiEntryFtraceEventH\x00\x12\x37\n\x08ipi_exit\x18\x16 \x01(\x0b\x32#.perfetto.protos.IpiExitFtraceEventH\x00\x12\x39\n\tipi_raise\x18\x17 \x01(\x0b\x32$.perfetto.protos.IpiRaiseFtraceEventH\x00\x12\x41\n\rsoftirq_entry\x18\x18 \x01(\x0b\x32(.perfetto.protos.SoftirqEntryFtraceEventH\x00\x12?\n\x0csoftirq_exit\x18\x19 \x01(\x0b\x32\'.perfetto.protos.SoftirqExitFtraceEventH\x00\x12\x41\n\rsoftirq_raise\x18\x1a \x01(\x0b\x32(.perfetto.protos.SoftirqRaiseFtraceEventH\x00\x12\x37\n\x08i2c_read\x18\x1b \x01(\x0b\x32#.perfetto.protos.I2cReadFtraceEventH\x00\x12\x39\n\ti2c_write\x18\x1c \x01(\x0b\x32$.perfetto.protos.I2cWriteFtraceEventH\x00\x12;\n\ni2c_result\x18\x1d \x01(\x0b\x32%.perfetto.protos.I2cResultFtraceEventH\x00\x12\x39\n\ti2c_reply\x18\x1e \x01(\x0b\x32$.perfetto.protos.I2cReplyFtraceEventH\x00\x12;\n\nsmbus_read\x18\x1f \x01(\x0b\x32%.perfetto.protos.SmbusReadFtraceEventH\x00\x12=\n\x0bsmbus_write\x18  \x01(\x0b\x32&.perfetto.protos.SmbusWriteFtraceEventH\x00\x12?\n\x0csmbus_result\x18! \x01(\x0b\x32\'.perfetto.protos.SmbusResultFtraceEventH\x00\x12=\n\x0bsmbus_reply\x18\" \x01(\x0b\x32&.perfetto.protos.SmbusReplyFtraceEventH\x00\x12\x43\n\x0elowmemory_kill\x18# \x01(\x0b\x32).perfetto.protos.LowmemoryKillFtraceEventH\x00\x12H\n\x11irq_handler_entry\x18$ \x01(\x0b\x32+.perfetto.protos.IrqHandlerEntryFtraceEventH\x00\x12\x46\n\x10irq_handler_exit\x18% \x01(\x0b\x32*.perfetto.protos.IrqHandlerExitFtraceEventH\x00\x12\x35\n\x07sync_pt\x18& \x01(\x0b\x32\".perfetto.protos.SyncPtFtraceEventH\x00\x12\x41\n\rsync_timeline\x18\' \x01(\x0b\x32(.perfetto.protos.SyncTimelineFtraceEventH\x00\x12\x39\n\tsync_wait\x18( \x01(\x0b\x32$.perfetto.protos.SyncWaitFtraceEventH\x00\x12K\n\x13\x65xt4_da_write_begin\x18) \x01(\x0b\x32,.perfetto.protos.Ext4DaWriteBeginFtraceEventH\x00\x12G\n\x11\x65xt4_da_write_end\x18* \x01(\x0b\x32*.perfetto.protos.Ext4DaWriteEndFtraceEventH\x00\x12M\n\x14\x65xt4_sync_file_enter\x18+ \x01(\x0b\x32-.perfetto.protos.Ext4SyncFileEnterFtraceEventH\x00\x12K\n\x13\x65xt4_sync_file_exit\x18, \x01(\x0b\x32,.perfetto.protos.Ext4SyncFileExitFtraceEventH\x00\x12\x42\n\x0e\x62lock_rq_issue\x18- \x01(\x0b\x32(.perfetto.protos.BlockRqIssueFtraceEventH\x00\x12`\n\x1emm_vmscan_direct_reclaim_begin\x18. \x01(\x0b\x32\x36.perfetto.protos.MmVmscanDirectReclaimBeginFtraceEventH\x00\x12\\\n\x1cmm_vmscan_direct_reclaim_end\x18/ \x01(\x0b\x32\x34.perfetto.protos.MmVmscanDirectReclaimEndFtraceEventH\x00\x12O\n\x15mm_vmscan_kswapd_wake\x18\x30 \x01(\x0b\x32..perfetto.protos.MmVmscanKswapdWakeFtraceEventH\x00\x12Q\n\x16mm_vmscan_kswapd_sleep\x18\x31 \x01(\x0b\x32/.perfetto.protos.MmVmscanKswapdSleepFtraceEventH\x00\x12K\n\x12\x62inder_transaction\x18\x32 \x01(\x0b\x32-.perfetto.protos.BinderTransactionFtraceEventH\x00\x12\\\n\x1b\x62inder_transaction_received\x18\x33 \x01(\x0b\x32\x35.perfetto.protos.BinderTransactionReceivedFtraceEventH\x00\x12L\n\x13\x62inder_set_priority\x18\x34 \x01(\x0b\x32-.perfetto.protos.BinderSetPriorityFtraceEventH\x00\x12=\n\x0b\x62inder_lock\x18\x35 \x01(\x0b\x32&.perfetto.protos.BinderLockFtraceEventH\x00\x12\x41\n\rbinder_locked\x18\x36 \x01(\x0b\x32(.perfetto.protos.BinderLockedFtraceEventH\x00\x12\x41\n\rbinder_unlock\x18\x37 \x01(\x0b\x32(.perfetto.protos.BinderUnlockFtraceEventH\x00\x12T\n\x17workqueue_activate_work\x18\x38 \x01(\x0b\x32\x31.perfetto.protos.WorkqueueActivateWorkFtraceEventH\x00\x12P\n\x15workqueue_execute_end\x18\x39 \x01(\x0b\x32/.perfetto.protos.WorkqueueExecuteEndFtraceEventH\x00\x12T\n\x17workqueue_execute_start\x18: \x01(\x0b\x32\x31.perfetto.protos.WorkqueueExecuteStartFtraceEventH\x00\x12N\n\x14workqueue_queue_work\x18; \x01(\x0b\x32..perfetto.protos.WorkqueueQueueWorkFtraceEventH\x00\x12I\n\x11regulator_disable\x18< \x01(\x0b\x32,.perfetto.protos.RegulatorDisableFtraceEventH\x00\x12Z\n\x1aregulator_disable_complete\x18= \x01(\x0b\x32\x34.perfetto.protos.RegulatorDisableCompleteFtraceEventH\x00\x12G\n\x10regulator_enable\x18> \x01(\x0b\x32+.perfetto.protos.RegulatorEnableFtraceEventH\x00\x12X\n\x19regulator_enable_complete\x18? \x01(\x0b\x32\x33.perfetto.protos.RegulatorEnableCompleteFtraceEventH\x00\x12R\n\x16regulator_enable_delay\x18@ \x01(\x0b\x32\x30.perfetto.protos.RegulatorEnableDelayFtraceEventH\x00\x12P\n\x15regulator_set_voltage\x18\x41 \x01(\x0b\x32/.perfetto.protos.RegulatorSetVoltageFtraceEventH\x00\x12\x61\n\x1eregulator_set_voltage_complete\x18\x42 \x01(\x0b\x32\x37.perfetto.protos.RegulatorSetVoltageCompleteFtraceEventH\x00\x12J\n\x12\x63group_attach_task\x18\x43 \x01(\x0b\x32,.perfetto.protos.CgroupAttachTaskFtraceEventH\x00\x12?\n\x0c\x63group_mkdir\x18\x44 \x01(\x0b\x32\'.perfetto.protos.CgroupMkdirFtraceEventH\x00\x12\x43\n\x0e\x63group_remount\x18\x45 \x01(\x0b\x32).perfetto.protos.CgroupRemountFtraceEventH\x00\x12?\n\x0c\x63group_rmdir\x18\x46 \x01(\x0b\x32\'.perfetto.protos.CgroupRmdirFtraceEventH\x00\x12P\n\x15\x63group_transfer_tasks\x18G \x01(\x0b\x32/.perfetto.protos.CgroupTransferTasksFtraceEventH\x00\x12L\n\x13\x63group_destroy_root\x18H \x01(\x0b\x32-.perfetto.protos.CgroupDestroyRootFtraceEventH\x00\x12\x43\n\x0e\x63group_release\x18I \x01(\x0b\x32).perfetto.protos.CgroupReleaseFtraceEventH\x00\x12\x41\n\rcgroup_rename\x18J \x01(\x0b\x32(.perfetto.protos.CgroupRenameFtraceEventH\x00\x12H\n\x11\x63group_setup_root\x18K \x01(\x0b\x32+.perfetto.protos.CgroupSetupRootFtraceEventH\x00\x12\x44\n\x0fmdp_cmd_kickoff\x18L \x01(\x0b\x32).perfetto.protos.MdpCmdKickoffFtraceEventH\x00\x12;\n\nmdp_commit\x18M \x01(\x0b\x32%.perfetto.protos.MdpCommitFtraceEventH\x00\x12\x43\n\x0fmdp_perf_set_ot\x18N \x01(\x0b\x32(.perfetto.protos.MdpPerfSetOtFtraceEventH\x00\x12\x44\n\x0fmdp_sspp_change\x18O \x01(\x0b\x32).perfetto.protos.MdpSsppChangeFtraceEventH\x00\x12J\n\x12tracing_mark_write\x18P \x01(\x0b\x32,.perfetto.protos.TracingMarkWriteFtraceEventH\x00\x12O\n\x15mdp_cmd_pingpong_done\x18Q \x01(\x0b\x32..perfetto.protos.MdpCmdPingpongDoneFtraceEventH\x00\x12\x42\n\x0emdp_compare_bw\x18R \x01(\x0b\x32(.perfetto.protos.MdpCompareBwFtraceEventH\x00\x12R\n\x17mdp_perf_set_panic_luts\x18S \x01(\x0b\x32/.perfetto.protos.MdpPerfSetPanicLutsFtraceEventH\x00\x12>\n\x0cmdp_sspp_set\x18T \x01(\x0b\x32&.perfetto.protos.MdpSsppSetFtraceEventH\x00\x12M\n\x14mdp_cmd_readptr_done\x18U \x01(\x0b\x32-.perfetto.protos.MdpCmdReadptrDoneFtraceEventH\x00\x12>\n\x0cmdp_misr_crc\x18V \x01(\x0b\x32&.perfetto.protos.MdpMisrCrcFtraceEventH\x00\x12N\n\x15mdp_perf_set_qos_luts\x18W \x01(\x0b\x32-.perfetto.protos.MdpPerfSetQosLutsFtraceEventH\x00\x12H\n\x11mdp_trace_counter\x18X \x01(\x0b\x32+.perfetto.protos.MdpTraceCounterFtraceEventH\x00\x12I\n\x12mdp_cmd_release_bw\x18Y \x01(\x0b\x32+.perfetto.protos.MdpCmdReleaseBwFtraceEventH\x00\x12\x46\n\x10mdp_mixer_update\x18Z \x01(\x0b\x32*.perfetto.protos.MdpMixerUpdateFtraceEventH\x00\x12P\n\x16mdp_perf_set_wm_levels\x18[ \x01(\x0b\x32..perfetto.protos.MdpPerfSetWmLevelsFtraceEventH\x00\x12S\n\x17mdp_video_underrun_done\x18\\ \x01(\x0b\x32\x30.perfetto.protos.MdpVideoUnderrunDoneFtraceEventH\x00\x12O\n\x15mdp_cmd_wait_pingpong\x18] \x01(\x0b\x32..perfetto.protos.MdpCmdWaitPingpongFtraceEventH\x00\x12O\n\x15mdp_perf_prefill_calc\x18^ \x01(\x0b\x32..perfetto.protos.MdpPerfPrefillCalcFtraceEventH\x00\x12K\n\x13mdp_perf_update_bus\x18_ \x01(\x0b\x32,.perfetto.protos.MdpPerfUpdateBusFtraceEventH\x00\x12T\n\x18rotator_bw_ao_as_context\x18` \x01(\x0b\x32\x30.perfetto.protos.RotatorBwAoAsContextFtraceEventH\x00\x12[\n\x1cmm_filemap_add_to_page_cache\x18\x61 \x01(\x0b\x32\x33.perfetto.protos.MmFilemapAddToPageCacheFtraceEventH\x00\x12\x65\n!mm_filemap_delete_from_page_cache\x18\x62 \x01(\x0b\x32\x38.perfetto.protos.MmFilemapDeleteFromPageCacheFtraceEventH\x00\x12L\n\x13mm_compaction_begin\x18\x63 \x01(\x0b\x32-.perfetto.protos.MmCompactionBeginFtraceEventH\x00\x12\x61\n\x1emm_compaction_defer_compaction\x18\x64 \x01(\x0b\x32\x37.perfetto.protos.MmCompactionDeferCompactionFtraceEventH\x00\x12R\n\x16mm_compaction_deferred\x18\x65 \x01(\x0b\x32\x30.perfetto.protos.MmCompactionDeferredFtraceEventH\x00\x12W\n\x19mm_compaction_defer_reset\x18\x66 \x01(\x0b\x32\x32.perfetto.protos.MmCompactionDeferResetFtraceEventH\x00\x12H\n\x11mm_compaction_end\x18g \x01(\x0b\x32+.perfetto.protos.MmCompactionEndFtraceEventH\x00\x12R\n\x16mm_compaction_finished\x18h \x01(\x0b\x32\x30.perfetto.protos.MmCompactionFinishedFtraceEventH\x00\x12\x63\n\x1fmm_compaction_isolate_freepages\x18i \x01(\x0b\x32\x38.perfetto.protos.MmCompactionIsolateFreepagesFtraceEventH\x00\x12i\n\"mm_compaction_isolate_migratepages\x18j \x01(\x0b\x32;.perfetto.protos.MmCompactionIsolateMigratepagesFtraceEventH\x00\x12_\n\x1dmm_compaction_kcompactd_sleep\x18k \x01(\x0b\x32\x36.perfetto.protos.MmCompactionKcompactdSleepFtraceEventH\x00\x12]\n\x1cmm_compaction_kcompactd_wake\x18l \x01(\x0b\x32\x35.perfetto.protos.MmCompactionKcompactdWakeFtraceEventH\x00\x12Z\n\x1amm_compaction_migratepages\x18m \x01(\x0b\x32\x34.perfetto.protos.MmCompactionMigratepagesFtraceEventH\x00\x12R\n\x16mm_compaction_suitable\x18n \x01(\x0b\x32\x30.perfetto.protos.MmCompactionSuitableFtraceEventH\x00\x12g\n\"mm_compaction_try_to_compact_pages\x18o \x01(\x0b\x32\x39.perfetto.protos.MmCompactionTryToCompactPagesFtraceEventH\x00\x12\x61\n\x1emm_compaction_wakeup_kcompactd\x18p \x01(\x0b\x32\x37.perfetto.protos.MmCompactionWakeupKcompactdFtraceEventH\x00\x12\x43\n\x0esuspend_resume\x18q \x01(\x0b\x32).perfetto.protos.SuspendResumeFtraceEventH\x00\x12\x46\n\x10sched_wakeup_new\x18r \x01(\x0b\x32*.perfetto.protos.SchedWakeupNewFtraceEventH\x00\x12L\n\x13\x62lock_bio_backmerge\x18s \x01(\x0b\x32-.perfetto.protos.BlockBioBackmergeFtraceEventH\x00\x12\x46\n\x10\x62lock_bio_bounce\x18t \x01(\x0b\x32*.perfetto.protos.BlockBioBounceFtraceEventH\x00\x12J\n\x12\x62lock_bio_complete\x18u \x01(\x0b\x32,.perfetto.protos.BlockBioCompleteFtraceEventH\x00\x12N\n\x14\x62lock_bio_frontmerge\x18v \x01(\x0b\x32..perfetto.protos.BlockBioFrontmergeFtraceEventH\x00\x12\x44\n\x0f\x62lock_bio_queue\x18w \x01(\x0b\x32).perfetto.protos.BlockBioQueueFtraceEventH\x00\x12\x44\n\x0f\x62lock_bio_remap\x18x \x01(\x0b\x32).perfetto.protos.BlockBioRemapFtraceEventH\x00\x12J\n\x12\x62lock_dirty_buffer\x18y \x01(\x0b\x32,.perfetto.protos.BlockDirtyBufferFtraceEventH\x00\x12=\n\x0b\x62lock_getrq\x18z \x01(\x0b\x32&.perfetto.protos.BlockGetrqFtraceEventH\x00\x12;\n\nblock_plug\x18{ \x01(\x0b\x32%.perfetto.protos.BlockPlugFtraceEventH\x00\x12\x42\n\x0e\x62lock_rq_abort\x18| \x01(\x0b\x32(.perfetto.protos.BlockRqAbortFtraceEventH\x00\x12H\n\x11\x62lock_rq_complete\x18} \x01(\x0b\x32+.perfetto.protos.BlockRqCompleteFtraceEventH\x00\x12\x44\n\x0f\x62lock_rq_insert\x18~ \x01(\x0b\x32).perfetto.protos.BlockRqInsertFtraceEventH\x00\x12\x43\n\x0e\x62lock_rq_remap\x18\x80\x01 \x01(\x0b\x32(.perfetto.protos.BlockRqRemapFtraceEventH\x00\x12G\n\x10\x62lock_rq_requeue\x18\x81\x01 \x01(\x0b\x32*.perfetto.protos.BlockRqRequeueFtraceEventH\x00\x12\x42\n\rblock_sleeprq\x18\x82\x01 \x01(\x0b\x32(.perfetto.protos.BlockSleeprqFtraceEventH\x00\x12>\n\x0b\x62lock_split\x18\x83\x01 \x01(\x0b\x32&.perfetto.protos.BlockSplitFtraceEventH\x00\x12K\n\x12\x62lock_touch_buffer\x18\x84\x01 \x01(\x0b\x32,.perfetto.protos.BlockTouchBufferFtraceEventH\x00\x12@\n\x0c\x62lock_unplug\x18\x85\x01 \x01(\x0b\x32\'.perfetto.protos.BlockUnplugFtraceEventH\x00\x12N\n\x14\x65xt4_alloc_da_blocks\x18\x86\x01 \x01(\x0b\x32-.perfetto.protos.Ext4AllocDaBlocksFtraceEventH\x00\x12O\n\x14\x65xt4_allocate_blocks\x18\x87\x01 \x01(\x0b\x32..perfetto.protos.Ext4AllocateBlocksFtraceEventH\x00\x12M\n\x13\x65xt4_allocate_inode\x18\x88\x01 \x01(\x0b\x32-.perfetto.protos.Ext4AllocateInodeFtraceEventH\x00\x12\\\n\x1b\x65xt4_begin_ordered_truncate\x18\x89\x01 \x01(\x0b\x32\x34.perfetto.protos.Ext4BeginOrderedTruncateFtraceEventH\x00\x12M\n\x13\x65xt4_collapse_range\x18\x8a\x01 \x01(\x0b\x32-.perfetto.protos.Ext4CollapseRangeFtraceEventH\x00\x12P\n\x15\x65xt4_da_release_space\x18\x8b\x01 \x01(\x0b\x32..perfetto.protos.Ext4DaReleaseSpaceFtraceEventH\x00\x12P\n\x15\x65xt4_da_reserve_space\x18\x8c\x01 \x01(\x0b\x32..perfetto.protos.Ext4DaReserveSpaceFtraceEventH\x00\x12]\n\x1c\x65xt4_da_update_reserve_space\x18\x8d\x01 \x01(\x0b\x32\x34.perfetto.protos.Ext4DaUpdateReserveSpaceFtraceEventH\x00\x12L\n\x13\x65xt4_da_write_pages\x18\x8e\x01 \x01(\x0b\x32,.perfetto.protos.Ext4DaWritePagesFtraceEventH\x00\x12Y\n\x1a\x65xt4_da_write_pages_extent\x18\x8f\x01 \x01(\x0b\x32\x32.perfetto.protos.Ext4DaWritePagesExtentFtraceEventH\x00\x12N\n\x14\x65xt4_direct_IO_enter\x18\x90\x01 \x01(\x0b\x32-.perfetto.protos.Ext4DirectIOEnterFtraceEventH\x00\x12L\n\x13\x65xt4_direct_IO_exit\x18\x91\x01 \x01(\x0b\x32,.perfetto.protos.Ext4DirectIOExitFtraceEventH\x00\x12M\n\x13\x65xt4_discard_blocks\x18\x92\x01 \x01(\x0b\x32-.perfetto.protos.Ext4DiscardBlocksFtraceEventH\x00\x12]\n\x1b\x65xt4_discard_preallocations\x18\x93\x01 \x01(\x0b\x32\x35.perfetto.protos.Ext4DiscardPreallocationsFtraceEventH\x00\x12\x45\n\x0f\x65xt4_drop_inode\x18\x94\x01 \x01(\x0b\x32).perfetto.protos.Ext4DropInodeFtraceEventH\x00\x12N\n\x14\x65xt4_es_cache_extent\x18\x95\x01 \x01(\x0b\x32-.perfetto.protos.Ext4EsCacheExtentFtraceEventH\x00\x12q\n\'ext4_es_find_delayed_extent_range_enter\x18\x96\x01 \x01(\x0b\x32=.perfetto.protos.Ext4EsFindDelayedExtentRangeEnterFtraceEventH\x00\x12o\n&ext4_es_find_delayed_extent_range_exit\x18\x97\x01 \x01(\x0b\x32<.perfetto.protos.Ext4EsFindDelayedExtentRangeExitFtraceEventH\x00\x12P\n\x15\x65xt4_es_insert_extent\x18\x98\x01 \x01(\x0b\x32..perfetto.protos.Ext4EsInsertExtentFtraceEventH\x00\x12[\n\x1b\x65xt4_es_lookup_extent_enter\x18\x99\x01 \x01(\x0b\x32\x33.perfetto.protos.Ext4EsLookupExtentEnterFtraceEventH\x00\x12Y\n\x1a\x65xt4_es_lookup_extent_exit\x18\x9a\x01 \x01(\x0b\x32\x32.perfetto.protos.Ext4EsLookupExtentExitFtraceEventH\x00\x12P\n\x15\x65xt4_es_remove_extent\x18\x9b\x01 \x01(\x0b\x32..perfetto.protos.Ext4EsRemoveExtentFtraceEventH\x00\x12\x43\n\x0e\x65xt4_es_shrink\x18\x9c\x01 \x01(\x0b\x32(.perfetto.protos.Ext4EsShrinkFtraceEventH\x00\x12N\n\x14\x65xt4_es_shrink_count\x18\x9d\x01 \x01(\x0b\x32-.perfetto.protos.Ext4EsShrinkCountFtraceEventH\x00\x12W\n\x19\x65xt4_es_shrink_scan_enter\x18\x9e\x01 \x01(\x0b\x32\x31.perfetto.protos.Ext4EsShrinkScanEnterFtraceEventH\x00\x12U\n\x18\x65xt4_es_shrink_scan_exit\x18\x9f\x01 \x01(\x0b\x32\x30.perfetto.protos.Ext4EsShrinkScanExitFtraceEventH\x00\x12G\n\x10\x65xt4_evict_inode\x18\xa0\x01 \x01(\x0b\x32*.perfetto.protos.Ext4EvictInodeFtraceEventH\x00\x12n\n%ext4_ext_convert_to_initialized_enter\x18\xa1\x01 \x01(\x0b\x32<.perfetto.protos.Ext4ExtConvertToInitializedEnterFtraceEventH\x00\x12t\n(ext4_ext_convert_to_initialized_fastpath\x18\xa2\x01 \x01(\x0b\x32?.perfetto.protos.Ext4ExtConvertToInitializedFastpathFtraceEventH\x00\x12g\n!ext4_ext_handle_unwritten_extents\x18\xa3\x01 \x01(\x0b\x32\x39.perfetto.protos.Ext4ExtHandleUnwrittenExtentsFtraceEventH\x00\x12H\n\x11\x65xt4_ext_in_cache\x18\xa4\x01 \x01(\x0b\x32*.perfetto.protos.Ext4ExtInCacheFtraceEventH\x00\x12N\n\x14\x65xt4_ext_load_extent\x18\xa5\x01 \x01(\x0b\x32-.perfetto.protos.Ext4ExtLoadExtentFtraceEventH\x00\x12W\n\x19\x65xt4_ext_map_blocks_enter\x18\xa6\x01 \x01(\x0b\x32\x31.perfetto.protos.Ext4ExtMapBlocksEnterFtraceEventH\x00\x12U\n\x18\x65xt4_ext_map_blocks_exit\x18\xa7\x01 \x01(\x0b\x32\x30.perfetto.protos.Ext4ExtMapBlocksExitFtraceEventH\x00\x12O\n\x15\x65xt4_ext_put_in_cache\x18\xa8\x01 \x01(\x0b\x32-.perfetto.protos.Ext4ExtPutInCacheFtraceEventH\x00\x12P\n\x15\x65xt4_ext_remove_space\x18\xa9\x01 \x01(\x0b\x32..perfetto.protos.Ext4ExtRemoveSpaceFtraceEventH\x00\x12Y\n\x1a\x65xt4_ext_remove_space_done\x18\xaa\x01 \x01(\x0b\x32\x32.perfetto.protos.Ext4ExtRemoveSpaceDoneFtraceEventH\x00\x12\x44\n\x0f\x65xt4_ext_rm_idx\x18\xab\x01 \x01(\x0b\x32(.perfetto.protos.Ext4ExtRmIdxFtraceEventH\x00\x12\x46\n\x10\x65xt4_ext_rm_leaf\x18\xac\x01 \x01(\x0b\x32).perfetto.protos.Ext4ExtRmLeafFtraceEventH\x00\x12N\n\x14\x65xt4_ext_show_extent\x18\xad\x01 \x01(\x0b\x32-.perfetto.protos.Ext4ExtShowExtentFtraceEventH\x00\x12O\n\x14\x65xt4_fallocate_enter\x18\xae\x01 \x01(\x0b\x32..perfetto.protos.Ext4FallocateEnterFtraceEventH\x00\x12M\n\x13\x65xt4_fallocate_exit\x18\xaf\x01 \x01(\x0b\x32-.perfetto.protos.Ext4FallocateExitFtraceEventH\x00\x12V\n\x18\x65xt4_find_delalloc_range\x18\xb0\x01 \x01(\x0b\x32\x31.perfetto.protos.Ext4FindDelallocRangeFtraceEventH\x00\x12>\n\x0b\x65xt4_forget\x18\xb1\x01 \x01(\x0b\x32&.perfetto.protos.Ext4ForgetFtraceEventH\x00\x12G\n\x10\x65xt4_free_blocks\x18\xb2\x01 \x01(\x0b\x32*.perfetto.protos.Ext4FreeBlocksFtraceEventH\x00\x12\x45\n\x0f\x65xt4_free_inode\x18\xb3\x01 \x01(\x0b\x32).perfetto.protos.Ext4FreeInodeFtraceEventH\x00\x12j\n#ext4_get_implied_cluster_alloc_exit\x18\xb4\x01 \x01(\x0b\x32:.perfetto.protos.Ext4GetImpliedClusterAllocExitFtraceEventH\x00\x12\x63\n\x1f\x65xt4_get_reserved_cluster_alloc\x18\xb5\x01 \x01(\x0b\x32\x37.perfetto.protos.Ext4GetReservedClusterAllocFtraceEventH\x00\x12W\n\x19\x65xt4_ind_map_blocks_enter\x18\xb6\x01 \x01(\x0b\x32\x31.perfetto.protos.Ext4IndMapBlocksEnterFtraceEventH\x00\x12U\n\x18\x65xt4_ind_map_blocks_exit\x18\xb7\x01 \x01(\x0b\x32\x30.perfetto.protos.Ext4IndMapBlocksExitFtraceEventH\x00\x12I\n\x11\x65xt4_insert_range\x18\xb8\x01 \x01(\x0b\x32+.perfetto.protos.Ext4InsertRangeFtraceEventH\x00\x12N\n\x13\x65xt4_invalidatepage\x18\xb9\x01 \x01(\x0b\x32..perfetto.protos.Ext4InvalidatepageFtraceEventH\x00\x12K\n\x12\x65xt4_journal_start\x18\xba\x01 \x01(\x0b\x32,.perfetto.protos.Ext4JournalStartFtraceEventH\x00\x12\\\n\x1b\x65xt4_journal_start_reserved\x18\xbb\x01 \x01(\x0b\x32\x34.perfetto.protos.Ext4JournalStartReservedFtraceEventH\x00\x12\x63\n\x1e\x65xt4_journalled_invalidatepage\x18\xbc\x01 \x01(\x0b\x32\x38.perfetto.protos.Ext4JournalledInvalidatepageFtraceEventH\x00\x12X\n\x19\x65xt4_journalled_write_end\x18\xbd\x01 \x01(\x0b\x32\x32.perfetto.protos.Ext4JournalledWriteEndFtraceEventH\x00\x12\x45\n\x0f\x65xt4_load_inode\x18\xbe\x01 \x01(\x0b\x32).perfetto.protos.Ext4LoadInodeFtraceEventH\x00\x12R\n\x16\x65xt4_load_inode_bitmap\x18\xbf\x01 \x01(\x0b\x32/.perfetto.protos.Ext4LoadInodeBitmapFtraceEventH\x00\x12P\n\x15\x65xt4_mark_inode_dirty\x18\xc0\x01 \x01(\x0b\x32..perfetto.protos.Ext4MarkInodeDirtyFtraceEventH\x00\x12L\n\x13\x65xt4_mb_bitmap_load\x18\xc1\x01 \x01(\x0b\x32,.perfetto.protos.Ext4MbBitmapLoadFtraceEventH\x00\x12W\n\x19\x65xt4_mb_buddy_bitmap_load\x18\xc2\x01 \x01(\x0b\x32\x31.perfetto.protos.Ext4MbBuddyBitmapLoadFtraceEventH\x00\x12\x62\n\x1e\x65xt4_mb_discard_preallocations\x18\xc3\x01 \x01(\x0b\x32\x37.perfetto.protos.Ext4MbDiscardPreallocationsFtraceEventH\x00\x12M\n\x14\x65xt4_mb_new_group_pa\x18\xc4\x01 \x01(\x0b\x32,.perfetto.protos.Ext4MbNewGroupPaFtraceEventH\x00\x12M\n\x14\x65xt4_mb_new_inode_pa\x18\xc5\x01 \x01(\x0b\x32,.perfetto.protos.Ext4MbNewInodePaFtraceEventH\x00\x12U\n\x18\x65xt4_mb_release_group_pa\x18\xc6\x01 \x01(\x0b\x32\x30.perfetto.protos.Ext4MbReleaseGroupPaFtraceEventH\x00\x12U\n\x18\x65xt4_mb_release_inode_pa\x18\xc7\x01 \x01(\x0b\x32\x30.perfetto.protos.Ext4MbReleaseInodePaFtraceEventH\x00\x12K\n\x12\x65xt4_mballoc_alloc\x18\xc8\x01 \x01(\x0b\x32,.perfetto.protos.Ext4MballocAllocFtraceEventH\x00\x12O\n\x14\x65xt4_mballoc_discard\x18\xc9\x01 \x01(\x0b\x32..perfetto.protos.Ext4MballocDiscardFtraceEventH\x00\x12I\n\x11\x65xt4_mballoc_free\x18\xca\x01 \x01(\x0b\x32+.perfetto.protos.Ext4MballocFreeFtraceEventH\x00\x12Q\n\x15\x65xt4_mballoc_prealloc\x18\xcb\x01 \x01(\x0b\x32/.perfetto.protos.Ext4MballocPreallocFtraceEventH\x00\x12]\n\x1c\x65xt4_other_inode_update_time\x18\xcc\x01 \x01(\x0b\x32\x34.perfetto.protos.Ext4OtherInodeUpdateTimeFtraceEventH\x00\x12\x45\n\x0f\x65xt4_punch_hole\x18\xcd\x01 \x01(\x0b\x32).perfetto.protos.Ext4PunchHoleFtraceEventH\x00\x12[\n\x1b\x65xt4_read_block_bitmap_load\x18\xce\x01 \x01(\x0b\x32\x33.perfetto.protos.Ext4ReadBlockBitmapLoadFtraceEventH\x00\x12\x42\n\rext4_readpage\x18\xcf\x01 \x01(\x0b\x32(.perfetto.protos.Ext4ReadpageFtraceEventH\x00\x12H\n\x10\x65xt4_releasepage\x18\xd0\x01 \x01(\x0b\x32+.perfetto.protos.Ext4ReleasepageFtraceEventH\x00\x12K\n\x12\x65xt4_remove_blocks\x18\xd1\x01 \x01(\x0b\x32,.perfetto.protos.Ext4RemoveBlocksFtraceEventH\x00\x12M\n\x13\x65xt4_request_blocks\x18\xd2\x01 \x01(\x0b\x32-.perfetto.protos.Ext4RequestBlocksFtraceEventH\x00\x12K\n\x12\x65xt4_request_inode\x18\xd3\x01 \x01(\x0b\x32,.perfetto.protos.Ext4RequestInodeFtraceEventH\x00\x12?\n\x0c\x65xt4_sync_fs\x18\xd4\x01 \x01(\x0b\x32&.perfetto.protos.Ext4SyncFsFtraceEventH\x00\x12J\n\x12\x65xt4_trim_all_free\x18\xd5\x01 \x01(\x0b\x32+.perfetto.protos.Ext4TrimAllFreeFtraceEventH\x00\x12G\n\x10\x65xt4_trim_extent\x18\xd6\x01 \x01(\x0b\x32*.perfetto.protos.Ext4TrimExtentFtraceEventH\x00\x12M\n\x13\x65xt4_truncate_enter\x18\xd7\x01 \x01(\x0b\x32-.perfetto.protos.Ext4TruncateEnterFtraceEventH\x00\x12K\n\x12\x65xt4_truncate_exit\x18\xd8\x01 \x01(\x0b\x32,.perfetto.protos.Ext4TruncateExitFtraceEventH\x00\x12I\n\x11\x65xt4_unlink_enter\x18\xd9\x01 \x01(\x0b\x32+.perfetto.protos.Ext4UnlinkEnterFtraceEventH\x00\x12G\n\x10\x65xt4_unlink_exit\x18\xda\x01 \x01(\x0b\x32*.perfetto.protos.Ext4UnlinkExitFtraceEventH\x00\x12G\n\x10\x65xt4_write_begin\x18\xdb\x01 \x01(\x0b\x32*.perfetto.protos.Ext4WriteBeginFtraceEventH\x00\x12\x43\n\x0e\x65xt4_write_end\x18\xe6\x01 \x01(\x0b\x32(.perfetto.protos.Ext4WriteEndFtraceEventH\x00\x12\x44\n\x0e\x65xt4_writepage\x18\xe7\x01 \x01(\x0b\x32).perfetto.protos.Ext4WritepageFtraceEventH\x00\x12\x46\n\x0f\x65xt4_writepages\x18\xe8\x01 \x01(\x0b\x32*.perfetto.protos.Ext4WritepagesFtraceEventH\x00\x12S\n\x16\x65xt4_writepages_result\x18\xe9\x01 \x01(\x0b\x32\x30.perfetto.protos.Ext4WritepagesResultFtraceEventH\x00\x12\x45\n\x0f\x65xt4_zero_range\x18\xea\x01 \x01(\x0b\x32).perfetto.protos.Ext4ZeroRangeFtraceEventH\x00\x12@\n\x0ctask_newtask\x18\xeb\x01 \x01(\x0b\x32\'.perfetto.protos.TaskNewtaskFtraceEventH\x00\x12>\n\x0btask_rename\x18\xec\x01 \x01(\x0b\x32&.perfetto.protos.TaskRenameFtraceEventH\x00\x12K\n\x12sched_process_exec\x18\xed\x01 \x01(\x0b\x32,.perfetto.protos.SchedProcessExecFtraceEventH\x00\x12K\n\x12sched_process_exit\x18\xee\x01 \x01(\x0b\x32,.perfetto.protos.SchedProcessExitFtraceEventH\x00\x12K\n\x12sched_process_fork\x18\xef\x01 \x01(\x0b\x32,.perfetto.protos.SchedProcessForkFtraceEventH\x00\x12K\n\x12sched_process_free\x18\xf0\x01 \x01(\x0b\x32,.perfetto.protos.SchedProcessFreeFtraceEventH\x00\x12K\n\x12sched_process_hang\x18\xf1\x01 \x01(\x0b\x32,.perfetto.protos.SchedProcessHangFtraceEventH\x00\x12K\n\x12sched_process_wait\x18\xf2\x01 \x01(\x0b\x32,.perfetto.protos.SchedProcessWaitFtraceEventH\x00\x12J\n\x12\x66\x32\x66s_do_submit_bio\x18\xf3\x01 \x01(\x0b\x32+.perfetto.protos.F2fsDoSubmitBioFtraceEventH\x00\x12G\n\x10\x66\x32\x66s_evict_inode\x18\xf4\x01 \x01(\x0b\x32*.perfetto.protos.F2fsEvictInodeFtraceEventH\x00\x12\x44\n\x0e\x66\x32\x66s_fallocate\x18\xf5\x01 \x01(\x0b\x32).perfetto.protos.F2fsFallocateFtraceEventH\x00\x12L\n\x13\x66\x32\x66s_get_data_block\x18\xf6\x01 \x01(\x0b\x32,.perfetto.protos.F2fsGetDataBlockFtraceEventH\x00\x12\x45\n\x0f\x66\x32\x66s_get_victim\x18\xf7\x01 \x01(\x0b\x32).perfetto.protos.F2fsGetVictimFtraceEventH\x00\x12:\n\tf2fs_iget\x18\xf8\x01 \x01(\x0b\x32$.perfetto.protos.F2fsIgetFtraceEventH\x00\x12\x43\n\x0e\x66\x32\x66s_iget_exit\x18\xf9\x01 \x01(\x0b\x32(.perfetto.protos.F2fsIgetExitFtraceEventH\x00\x12\x43\n\x0e\x66\x32\x66s_new_inode\x18\xfa\x01 \x01(\x0b\x32(.perfetto.protos.F2fsNewInodeFtraceEventH\x00\x12\x42\n\rf2fs_readpage\x18\xfb\x01 \x01(\x0b\x32(.perfetto.protos.F2fsReadpageFtraceEventH\x00\x12R\n\x16\x66\x32\x66s_reserve_new_block\x18\xfc\x01 \x01(\x0b\x32/.perfetto.protos.F2fsReserveNewBlockFtraceEventH\x00\x12L\n\x13\x66\x32\x66s_set_page_dirty\x18\xfd\x01 \x01(\x0b\x32,.perfetto.protos.F2fsSetPageDirtyFtraceEventH\x00\x12R\n\x16\x66\x32\x66s_submit_write_page\x18\xfe\x01 \x01(\x0b\x32/.perfetto.protos.F2fsSubmitWritePageFtraceEventH\x00\x12N\n\x14\x66\x32\x66s_sync_file_enter\x18\xff\x01 \x01(\x0b\x32-.perfetto.protos.F2fsSyncFileEnterFtraceEventH\x00\x12L\n\x13\x66\x32\x66s_sync_file_exit\x18\x80\x02 \x01(\x0b\x32,.perfetto.protos.F2fsSyncFileExitFtraceEventH\x00\x12?\n\x0c\x66\x32\x66s_sync_fs\x18\x81\x02 \x01(\x0b\x32&.perfetto.protos.F2fsSyncFsFtraceEventH\x00\x12\x42\n\rf2fs_truncate\x18\x82\x02 \x01(\x0b\x32(.perfetto.protos.F2fsTruncateFtraceEventH\x00\x12Z\n\x1a\x66\x32\x66s_truncate_blocks_enter\x18\x83\x02 \x01(\x0b\x32\x33.perfetto.protos.F2fsTruncateBlocksEnterFtraceEventH\x00\x12X\n\x19\x66\x32\x66s_truncate_blocks_exit\x18\x84\x02 \x01(\x0b\x32\x32.perfetto.protos.F2fsTruncateBlocksExitFtraceEventH\x00\x12\x63\n\x1f\x66\x32\x66s_truncate_data_blocks_range\x18\x85\x02 \x01(\x0b\x32\x37.perfetto.protos.F2fsTruncateDataBlocksRangeFtraceEventH\x00\x12\x65\n f2fs_truncate_inode_blocks_enter\x18\x86\x02 \x01(\x0b\x32\x38.perfetto.protos.F2fsTruncateInodeBlocksEnterFtraceEventH\x00\x12\x63\n\x1f\x66\x32\x66s_truncate_inode_blocks_exit\x18\x87\x02 \x01(\x0b\x32\x37.perfetto.protos.F2fsTruncateInodeBlocksExitFtraceEventH\x00\x12K\n\x12\x66\x32\x66s_truncate_node\x18\x88\x02 \x01(\x0b\x32,.perfetto.protos.F2fsTruncateNodeFtraceEventH\x00\x12X\n\x19\x66\x32\x66s_truncate_nodes_enter\x18\x89\x02 \x01(\x0b\x32\x32.perfetto.protos.F2fsTruncateNodesEnterFtraceEventH\x00\x12V\n\x18\x66\x32\x66s_truncate_nodes_exit\x18\x8a\x02 \x01(\x0b\x32\x31.perfetto.protos.F2fsTruncateNodesExitFtraceEventH\x00\x12\\\n\x1b\x66\x32\x66s_truncate_partial_nodes\x18\x8b\x02 \x01(\x0b\x32\x34.perfetto.protos.F2fsTruncatePartialNodesFtraceEventH\x00\x12I\n\x11\x66\x32\x66s_unlink_enter\x18\x8c\x02 \x01(\x0b\x32+.perfetto.protos.F2fsUnlinkEnterFtraceEventH\x00\x12G\n\x10\x66\x32\x66s_unlink_exit\x18\x8d\x02 \x01(\x0b\x32*.perfetto.protos.F2fsUnlinkExitFtraceEventH\x00\x12N\n\x14\x66\x32\x66s_vm_page_mkwrite\x18\x8e\x02 \x01(\x0b\x32-.perfetto.protos.F2fsVmPageMkwriteFtraceEventH\x00\x12G\n\x10\x66\x32\x66s_write_begin\x18\x8f\x02 \x01(\x0b\x32*.perfetto.protos.F2fsWriteBeginFtraceEventH\x00\x12Q\n\x15\x66\x32\x66s_write_checkpoint\x18\x90\x02 \x01(\x0b\x32/.perfetto.protos.F2fsWriteCheckpointFtraceEventH\x00\x12\x43\n\x0e\x66\x32\x66s_write_end\x18\x91\x02 \x01(\x0b\x32(.perfetto.protos.F2fsWriteEndFtraceEventH\x00\x12P\n\x15\x61lloc_pages_iommu_end\x18\x92\x02 \x01(\x0b\x32..perfetto.protos.AllocPagesIommuEndFtraceEventH\x00\x12R\n\x16\x61lloc_pages_iommu_fail\x18\x93\x02 \x01(\x0b\x32/.perfetto.protos.AllocPagesIommuFailFtraceEventH\x00\x12T\n\x17\x61lloc_pages_iommu_start\x18\x94\x02 \x01(\x0b\x32\x30.perfetto.protos.AllocPagesIommuStartFtraceEventH\x00\x12L\n\x13\x61lloc_pages_sys_end\x18\x95\x02 \x01(\x0b\x32,.perfetto.protos.AllocPagesSysEndFtraceEventH\x00\x12N\n\x14\x61lloc_pages_sys_fail\x18\x96\x02 \x01(\x0b\x32-.perfetto.protos.AllocPagesSysFailFtraceEventH\x00\x12P\n\x15\x61lloc_pages_sys_start\x18\x97\x02 \x01(\x0b\x32..perfetto.protos.AllocPagesSysStartFtraceEventH\x00\x12Z\n\x1a\x64ma_alloc_contiguous_retry\x18\x98\x02 \x01(\x0b\x32\x33.perfetto.protos.DmaAllocContiguousRetryFtraceEventH\x00\x12\x45\n\x0fiommu_map_range\x18\x99\x02 \x01(\x0b\x32).perfetto.protos.IommuMapRangeFtraceEventH\x00\x12\\\n\x1ciommu_sec_ptbl_map_range_end\x18\x9a\x02 \x01(\x0b\x32\x33.perfetto.protos.IommuSecPtblMapRangeEndFtraceEventH\x00\x12`\n\x1eiommu_sec_ptbl_map_range_start\x18\x9b\x02 \x01(\x0b\x32\x35.perfetto.protos.IommuSecPtblMapRangeStartFtraceEventH\x00\x12N\n\x14ion_alloc_buffer_end\x18\x9c\x02 \x01(\x0b\x32-.perfetto.protos.IonAllocBufferEndFtraceEventH\x00\x12P\n\x15ion_alloc_buffer_fail\x18\x9d\x02 \x01(\x0b\x32..perfetto.protos.IonAllocBufferFailFtraceEventH\x00\x12X\n\x19ion_alloc_buffer_fallback\x18\x9e\x02 \x01(\x0b\x32\x32.perfetto.protos.IonAllocBufferFallbackFtraceEventH\x00\x12R\n\x16ion_alloc_buffer_start\x18\x9f\x02 \x01(\x0b\x32/.perfetto.protos.IonAllocBufferStartFtraceEventH\x00\x12J\n\x12ion_cp_alloc_retry\x18\xa0\x02 \x01(\x0b\x32+.perfetto.protos.IonCpAllocRetryFtraceEventH\x00\x12U\n\x18ion_cp_secure_buffer_end\x18\xa1\x02 \x01(\x0b\x32\x30.perfetto.protos.IonCpSecureBufferEndFtraceEventH\x00\x12Y\n\x1aion_cp_secure_buffer_start\x18\xa2\x02 \x01(\x0b\x32\x32.perfetto.protos.IonCpSecureBufferStartFtraceEventH\x00\x12\x46\n\x0fion_prefetching\x18\xa3\x02 \x01(\x0b\x32*.perfetto.protos.IonPrefetchingFtraceEventH\x00\x12_\n\x1eion_secure_cma_add_to_pool_end\x18\xa4\x02 \x01(\x0b\x32\x34.perfetto.protos.IonSecureCmaAddToPoolEndFtraceEventH\x00\x12\x63\n ion_secure_cma_add_to_pool_start\x18\xa5\x02 \x01(\x0b\x32\x36.perfetto.protos.IonSecureCmaAddToPoolStartFtraceEventH\x00\x12[\n\x1bion_secure_cma_allocate_end\x18\xa6\x02 \x01(\x0b\x32\x33.perfetto.protos.IonSecureCmaAllocateEndFtraceEventH\x00\x12_\n\x1dion_secure_cma_allocate_start\x18\xa7\x02 \x01(\x0b\x32\x35.perfetto.protos.IonSecureCmaAllocateStartFtraceEventH\x00\x12`\n\x1eion_secure_cma_shrink_pool_end\x18\xa8\x02 \x01(\x0b\x32\x35.perfetto.protos.IonSecureCmaShrinkPoolEndFtraceEventH\x00\x12\x64\n ion_secure_cma_shrink_pool_start\x18\xa9\x02 \x01(\x0b\x32\x37.perfetto.protos.IonSecureCmaShrinkPoolStartFtraceEventH\x00\x12\x33\n\x05kfree\x18\xaa\x02 \x01(\x0b\x32!.perfetto.protos.KfreeFtraceEventH\x00\x12\x37\n\x07kmalloc\x18\xab\x02 \x01(\x0b\x32#.perfetto.protos.KmallocFtraceEventH\x00\x12@\n\x0ckmalloc_node\x18\xac\x02 \x01(\x0b\x32\'.perfetto.protos.KmallocNodeFtraceEventH\x00\x12G\n\x10kmem_cache_alloc\x18\xad\x02 \x01(\x0b\x32*.perfetto.protos.KmemCacheAllocFtraceEventH\x00\x12P\n\x15kmem_cache_alloc_node\x18\xae\x02 \x01(\x0b\x32..perfetto.protos.KmemCacheAllocNodeFtraceEventH\x00\x12\x45\n\x0fkmem_cache_free\x18\xaf\x02 \x01(\x0b\x32).perfetto.protos.KmemCacheFreeFtraceEventH\x00\x12I\n\x11migrate_pages_end\x18\xb0\x02 \x01(\x0b\x32+.perfetto.protos.MigratePagesEndFtraceEventH\x00\x12M\n\x13migrate_pages_start\x18\xb1\x02 \x01(\x0b\x32-.perfetto.protos.MigratePagesStartFtraceEventH\x00\x12\x42\n\rmigrate_retry\x18\xb2\x02 \x01(\x0b\x32(.perfetto.protos.MigrateRetryFtraceEventH\x00\x12\x41\n\rmm_page_alloc\x18\xb3\x02 \x01(\x0b\x32\'.perfetto.protos.MmPageAllocFtraceEventH\x00\x12P\n\x15mm_page_alloc_extfrag\x18\xb4\x02 \x01(\x0b\x32..perfetto.protos.MmPageAllocExtfragFtraceEventH\x00\x12W\n\x19mm_page_alloc_zone_locked\x18\xb5\x02 \x01(\x0b\x32\x31.perfetto.protos.MmPageAllocZoneLockedFtraceEventH\x00\x12?\n\x0cmm_page_free\x18\xb6\x02 \x01(\x0b\x32&.perfetto.protos.MmPageFreeFtraceEventH\x00\x12N\n\x14mm_page_free_batched\x18\xb7\x02 \x01(\x0b\x32-.perfetto.protos.MmPageFreeBatchedFtraceEventH\x00\x12J\n\x12mm_page_pcpu_drain\x18\xb8\x02 \x01(\x0b\x32+.perfetto.protos.MmPagePcpuDrainFtraceEventH\x00\x12\x38\n\x08rss_stat\x18\xb9\x02 \x01(\x0b\x32#.perfetto.protos.RssStatFtraceEventH\x00\x12\x45\n\x0fion_heap_shrink\x18\xba\x02 \x01(\x0b\x32).perfetto.protos.IonHeapShrinkFtraceEventH\x00\x12\x41\n\rion_heap_grow\x18\xbb\x02 \x01(\x0b\x32\'.perfetto.protos.IonHeapGrowFtraceEventH\x00\x12<\n\nfence_init\x18\xbc\x02 \x01(\x0b\x32%.perfetto.protos.FenceInitFtraceEventH\x00\x12\x42\n\rfence_destroy\x18\xbd\x02 \x01(\x0b\x32(.perfetto.protos.FenceDestroyFtraceEventH\x00\x12M\n\x13\x66\x65nce_enable_signal\x18\xbe\x02 \x01(\x0b\x32-.perfetto.protos.FenceEnableSignalFtraceEventH\x00\x12\x44\n\x0e\x66\x65nce_signaled\x18\xbf\x02 \x01(\x0b\x32).perfetto.protos.FenceSignaledFtraceEventH\x00\x12<\n\nclk_enable\x18\xc0\x02 \x01(\x0b\x32%.perfetto.protos.ClkEnableFtraceEventH\x00\x12>\n\x0b\x63lk_disable\x18\xc1\x02 \x01(\x0b\x32&.perfetto.protos.ClkDisableFtraceEventH\x00\x12?\n\x0c\x63lk_set_rate\x18\xc2\x02 \x01(\x0b\x32&.perfetto.protos.ClkSetRateFtraceEventH\x00\x12^\n\x1c\x62inder_transaction_alloc_buf\x18\xc3\x02 \x01(\x0b\x32\x35.perfetto.protos.BinderTransactionAllocBufFtraceEventH\x00\x12\x44\n\x0esignal_deliver\x18\xc4\x02 \x01(\x0b\x32).perfetto.protos.SignalDeliverFtraceEventH\x00\x12\x46\n\x0fsignal_generate\x18\xc5\x02 \x01(\x0b\x32*.perfetto.protos.SignalGenerateFtraceEventH\x00\x12N\n\x14oom_score_adj_update\x18\xc6\x02 \x01(\x0b\x32-.perfetto.protos.OomScoreAdjUpdateFtraceEventH\x00\x12\x37\n\x07generic\x18\xc7\x02 \x01(\x0b\x32#.perfetto.protos.GenericFtraceEventH\x00\x12\x45\n\x0fmm_event_record\x18\xc8\x02 \x01(\x0b\x32).perfetto.protos.MmEventRecordFtraceEventH\x00\x12:\n\tsys_enter\x18\xc9\x02 \x01(\x0b\x32$.perfetto.protos.SysEnterFtraceEventH\x00\x12\x38\n\x08sys_exit\x18\xca\x02 \x01(\x0b\x32#.perfetto.protos.SysExitFtraceEventH\x00\x12\x31\n\x04zero\x18\xcb\x02 \x01(\x0b\x32 .perfetto.protos.ZeroFtraceEventH\x00\x12\x42\n\rgpu_frequency\x18\xcc\x02 \x01(\x0b\x32(.perfetto.protos.GpuFrequencyFtraceEventH\x00\x12R\n\x16sde_tracing_mark_write\x18\xcd\x02 \x01(\x0b\x32/.perfetto.protos.SdeTracingMarkWriteFtraceEventH\x00\x12>\n\x0bmark_victim\x18\xce\x02 \x01(\x0b\x32&.perfetto.protos.MarkVictimFtraceEventH\x00\x12\x38\n\x08ion_stat\x18\xcf\x02 \x01(\x0b\x32#.perfetto.protos.IonStatFtraceEventH\x00\x12I\n\x11ion_buffer_create\x18\xd0\x02 \x01(\x0b\x32+.perfetto.protos.IonBufferCreateFtraceEventH\x00\x12K\n\x12ion_buffer_destroy\x18\xd1\x02 \x01(\x0b\x32,.perfetto.protos.IonBufferDestroyFtraceEventH\x00\x12\x43\n\x0escm_call_start\x18\xd2\x02 \x01(\x0b\x32(.perfetto.protos.ScmCallStartFtraceEventH\x00\x12?\n\x0cscm_call_end\x18\xd3\x02 \x01(\x0b\x32&.perfetto.protos.ScmCallEndFtraceEventH\x00\x12\x41\n\rgpu_mem_total\x18\xd4\x02 \x01(\x0b\x32\'.perfetto.protos.GpuMemTotalFtraceEventH\x00\x12N\n\x13thermal_temperature\x18\xd5\x02 \x01(\x0b\x32..perfetto.protos.ThermalTemperatureFtraceEventH\x00\x12>\n\x0b\x63\x64\x65v_update\x18\xd6\x02 \x01(\x0b\x32&.perfetto.protos.CdevUpdateFtraceEventH\x00\x12<\n\ncpuhp_exit\x18\xd7\x02 \x01(\x0b\x32%.perfetto.protos.CpuhpExitFtraceEventH\x00\x12I\n\x11\x63puhp_multi_enter\x18\xd8\x02 \x01(\x0b\x32+.perfetto.protos.CpuhpMultiEnterFtraceEventH\x00\x12>\n\x0b\x63puhp_enter\x18\xd9\x02 \x01(\x0b\x32&.perfetto.protos.CpuhpEnterFtraceEventH\x00\x12\x42\n\rcpuhp_latency\x18\xda\x02 \x01(\x0b\x32(.perfetto.protos.CpuhpLatencyFtraceEventH\x00\x12G\n\x10\x66\x61strpc_dma_stat\x18\xdb\x02 \x01(\x0b\x32*.perfetto.protos.FastrpcDmaStatFtraceEventH\x00\x12R\n\x16\x64pu_tracing_mark_write\x18\xdc\x02 \x01(\x0b\x32/.perfetto.protos.DpuTracingMarkWriteFtraceEventH\x00\x12R\n\x16g2d_tracing_mark_write\x18\xdd\x02 \x01(\x0b\x32/.perfetto.protos.G2dTracingMarkWriteFtraceEventH\x00\x12T\n\x17mali_tracing_mark_write\x18\xde\x02 \x01(\x0b\x32\x30.perfetto.protos.MaliTracingMarkWriteFtraceEventH\x00\x12\x41\n\rdma_heap_stat\x18\xdf\x02 \x01(\x0b\x32\'.perfetto.protos.DmaHeapStatFtraceEventH\x00\x12>\n\x0b\x63puhp_pause\x18\xe0\x02 \x01(\x0b\x32&.perfetto.protos.CpuhpPauseFtraceEventH\x00\x12G\n\x10sched_pi_setprio\x18\xe1\x02 \x01(\x0b\x32*.perfetto.protos.SchedPiSetprioFtraceEventH\x00\x12\x43\n\x0esde_sde_evtlog\x18\xe2\x02 \x01(\x0b\x32(.perfetto.protos.SdeSdeEvtlogFtraceEventH\x00\x12Q\n\x16sde_sde_perf_calc_crtc\x18\xe3\x02 \x01(\x0b\x32..perfetto.protos.SdeSdePerfCalcCrtcFtraceEventH\x00\x12U\n\x18sde_sde_perf_crtc_update\x18\xe4\x02 \x01(\x0b\x32\x30.perfetto.protos.SdeSdePerfCrtcUpdateFtraceEventH\x00\x12V\n\x19sde_sde_perf_set_qos_luts\x18\xe5\x02 \x01(\x0b\x32\x30.perfetto.protos.SdeSdePerfSetQosLutsFtraceEventH\x00\x12S\n\x17sde_sde_perf_update_bus\x18\xe6\x02 \x01(\x0b\x32/.perfetto.protos.SdeSdePerfUpdateBusFtraceEventH\x00\x12K\n\x12rss_stat_throttled\x18\xe7\x02 \x01(\x0b\x32,.perfetto.protos.RssStatThrottledFtraceEventH\x00\x12I\n\x11netif_receive_skb\x18\xe8\x02 \x01(\x0b\x32+.perfetto.protos.NetifReceiveSkbFtraceEventH\x00\x12?\n\x0cnet_dev_xmit\x18\xe9\x02 \x01(\x0b\x32&.perfetto.protos.NetDevXmitFtraceEventH\x00\x12L\n\x13inet_sock_set_state\x18\xea\x02 \x01(\x0b\x32,.perfetto.protos.InetSockSetStateFtraceEventH\x00\x12K\n\x12tcp_retransmit_skb\x18\xeb\x02 \x01(\x0b\x32,.perfetto.protos.TcpRetransmitSkbFtraceEventH\x00\x12R\n\x16\x63ros_ec_sensorhub_data\x18\xec\x02 \x01(\x0b\x32/.perfetto.protos.CrosEcSensorhubDataFtraceEventH\x00\x12R\n\x16napi_gro_receive_entry\x18\xed\x02 \x01(\x0b\x32/.perfetto.protos.NapiGroReceiveEntryFtraceEventH\x00\x12P\n\x15napi_gro_receive_exit\x18\xee\x02 \x01(\x0b\x32..perfetto.protos.NapiGroReceiveExitFtraceEventH\x00\x12:\n\tkfree_skb\x18\xef\x02 \x01(\x0b\x32$.perfetto.protos.KfreeSkbFtraceEventH\x00\x12G\n\x10kvm_access_fault\x18\xf0\x02 \x01(\x0b\x32*.perfetto.protos.KvmAccessFaultFtraceEventH\x00\x12=\n\x0bkvm_ack_irq\x18\xf1\x02 \x01(\x0b\x32%.perfetto.protos.KvmAckIrqFtraceEventH\x00\x12=\n\x0bkvm_age_hva\x18\xf2\x02 \x01(\x0b\x32%.perfetto.protos.KvmAgeHvaFtraceEventH\x00\x12?\n\x0ckvm_age_page\x18\xf3\x02 \x01(\x0b\x32&.perfetto.protos.KvmAgePageFtraceEventH\x00\x12L\n\x13kvm_arm_clear_debug\x18\xf4\x02 \x01(\x0b\x32,.perfetto.protos.KvmArmClearDebugFtraceEventH\x00\x12J\n\x12kvm_arm_set_dreg32\x18\xf5\x02 \x01(\x0b\x32+.perfetto.protos.KvmArmSetDreg32FtraceEventH\x00\x12J\n\x12kvm_arm_set_regset\x18\xf6\x02 \x01(\x0b\x32+.perfetto.protos.KvmArmSetRegsetFtraceEventH\x00\x12L\n\x13kvm_arm_setup_debug\x18\xf7\x02 \x01(\x0b\x32,.perfetto.protos.KvmArmSetupDebugFtraceEventH\x00\x12:\n\tkvm_entry\x18\xf8\x02 \x01(\x0b\x32$.perfetto.protos.KvmEntryFtraceEventH\x00\x12\x38\n\x08kvm_exit\x18\xf9\x02 \x01(\x0b\x32#.perfetto.protos.KvmExitFtraceEventH\x00\x12\x36\n\x07kvm_fpu\x18\xfa\x02 \x01(\x0b\x32\".perfetto.protos.KvmFpuFtraceEventH\x00\x12H\n\x11kvm_get_timer_map\x18\xfb\x02 \x01(\x0b\x32*.perfetto.protos.KvmGetTimerMapFtraceEventH\x00\x12\x45\n\x0fkvm_guest_fault\x18\xfc\x02 \x01(\x0b\x32).perfetto.protos.KvmGuestFaultFtraceEventH\x00\x12J\n\x12kvm_handle_sys_reg\x18\xfd\x02 \x01(\x0b\x32+.perfetto.protos.KvmHandleSysRegFtraceEventH\x00\x12\x41\n\rkvm_hvc_arm64\x18\xfe\x02 \x01(\x0b\x32\'.perfetto.protos.KvmHvcArm64FtraceEventH\x00\x12?\n\x0ckvm_irq_line\x18\xff\x02 \x01(\x0b\x32&.perfetto.protos.KvmIrqLineFtraceEventH\x00\x12\x38\n\x08kvm_mmio\x18\x80\x03 \x01(\x0b\x32#.perfetto.protos.KvmMmioFtraceEventH\x00\x12G\n\x10kvm_mmio_emulate\x18\x81\x03 \x01(\x0b\x32*.perfetto.protos.KvmMmioEmulateFtraceEventH\x00\x12L\n\x13kvm_set_guest_debug\x18\x82\x03 \x01(\x0b\x32,.perfetto.protos.KvmSetGuestDebugFtraceEventH\x00\x12=\n\x0bkvm_set_irq\x18\x83\x03 \x01(\x0b\x32%.perfetto.protos.KvmSetIrqFtraceEventH\x00\x12\x46\n\x10kvm_set_spte_hva\x18\x84\x03 \x01(\x0b\x32).perfetto.protos.KvmSetSpteHvaFtraceEventH\x00\x12H\n\x11kvm_set_way_flush\x18\x85\x03 \x01(\x0b\x32*.perfetto.protos.KvmSetWayFlushFtraceEventH\x00\x12\x43\n\x0ekvm_sys_access\x18\x86\x03 \x01(\x0b\x32(.perfetto.protos.KvmSysAccessFtraceEventH\x00\x12\x46\n\x10kvm_test_age_hva\x18\x87\x03 \x01(\x0b\x32).perfetto.protos.KvmTestAgeHvaFtraceEventH\x00\x12I\n\x11kvm_timer_emulate\x18\x88\x03 \x01(\x0b\x32+.perfetto.protos.KvmTimerEmulateFtraceEventH\x00\x12V\n\x18kvm_timer_hrtimer_expire\x18\x89\x03 \x01(\x0b\x32\x31.perfetto.protos.KvmTimerHrtimerExpireFtraceEventH\x00\x12T\n\x17kvm_timer_restore_state\x18\x8a\x03 \x01(\x0b\x32\x30.perfetto.protos.KvmTimerRestoreStateFtraceEventH\x00\x12N\n\x14kvm_timer_save_state\x18\x8b\x03 \x01(\x0b\x32-.perfetto.protos.KvmTimerSaveStateFtraceEventH\x00\x12N\n\x14kvm_timer_update_irq\x18\x8c\x03 \x01(\x0b\x32-.perfetto.protos.KvmTimerUpdateIrqFtraceEventH\x00\x12G\n\x10kvm_toggle_cache\x18\x8d\x03 \x01(\x0b\x32*.perfetto.protos.KvmToggleCacheFtraceEventH\x00\x12L\n\x13kvm_unmap_hva_range\x18\x8e\x03 \x01(\x0b\x32,.perfetto.protos.KvmUnmapHvaRangeFtraceEventH\x00\x12K\n\x12kvm_userspace_exit\x18\x8f\x03 \x01(\x0b\x32,.perfetto.protos.KvmUserspaceExitFtraceEventH\x00\x12\x45\n\x0fkvm_vcpu_wakeup\x18\x90\x03 \x01(\x0b\x32).perfetto.protos.KvmVcpuWakeupFtraceEventH\x00\x12\x41\n\rkvm_wfx_arm64\x18\x91\x03 \x01(\x0b\x32\'.perfetto.protos.KvmWfxArm64FtraceEventH\x00\x12\x38\n\x08trap_reg\x18\x92\x03 \x01(\x0b\x32#.perfetto.protos.TrapRegFtraceEventH\x00\x12T\n\x17vgic_update_irq_pending\x18\x93\x03 \x01(\x0b\x32\x30.perfetto.protos.VgicUpdateIrqPendingFtraceEventH\x00\x12S\n\x16wakeup_source_activate\x18\x94\x03 \x01(\x0b\x32\x30.perfetto.protos.WakeupSourceActivateFtraceEventH\x00\x12W\n\x18wakeup_source_deactivate\x18\x95\x03 \x01(\x0b\x32\x32.perfetto.protos.WakeupSourceDeactivateFtraceEventH\x00\x12\x44\n\x0eufshcd_command\x18\x96\x03 \x01(\x0b\x32).perfetto.protos.UfshcdCommandFtraceEventH\x00\x12I\n\x11ufshcd_clk_gating\x18\x97\x03 \x01(\x0b\x32+.perfetto.protos.UfshcdClkGatingFtraceEventH\x00\x12\x37\n\x07\x63onsole\x18\x98\x03 \x01(\x0b\x32#.perfetto.protos.ConsoleFtraceEventH\x00\x12G\n\x10\x64rm_vblank_event\x18\x99\x03 \x01(\x0b\x32*.perfetto.protos.DrmVblankEventFtraceEventH\x00\x12Z\n\x1a\x64rm_vblank_event_delivered\x18\x9a\x03 \x01(\x0b\x32\x33.perfetto.protos.DrmVblankEventDeliveredFtraceEventH\x00\x12\x41\n\rdrm_sched_job\x18\x9b\x03 \x01(\x0b\x32\'.perfetto.protos.DrmSchedJobFtraceEventH\x00\x12=\n\x0b\x64rm_run_job\x18\x9c\x03 \x01(\x0b\x32%.perfetto.protos.DrmRunJobFtraceEventH\x00\x12P\n\x15\x64rm_sched_process_job\x18\x9d\x03 \x01(\x0b\x32..perfetto.protos.DrmSchedProcessJobFtraceEventH\x00\x12\x43\n\x0e\x64ma_fence_init\x18\x9e\x03 \x01(\x0b\x32(.perfetto.protos.DmaFenceInitFtraceEventH\x00\x12\x43\n\x0e\x64ma_fence_emit\x18\x9f\x03 \x01(\x0b\x32(.perfetto.protos.DmaFenceEmitFtraceEventH\x00\x12K\n\x12\x64ma_fence_signaled\x18\xa0\x03 \x01(\x0b\x32,.perfetto.protos.DmaFenceSignaledFtraceEventH\x00\x12N\n\x14\x64ma_fence_wait_start\x18\xa1\x03 \x01(\x0b\x32-.perfetto.protos.DmaFenceWaitStartFtraceEventH\x00\x12J\n\x12\x64ma_fence_wait_end\x18\xa2\x03 \x01(\x0b\x32+.perfetto.protos.DmaFenceWaitEndFtraceEventH\x00\x12>\n\x0b\x66\x32\x66s_iostat\x18\xa3\x03 \x01(\x0b\x32&.perfetto.protos.F2fsIostatFtraceEventH\x00\x12M\n\x13\x66\x32\x66s_iostat_latency\x18\xa4\x03 \x01(\x0b\x32-.perfetto.protos.F2fsIostatLatencyFtraceEventH\x00\x12J\n\x12sched_cpu_util_cfs\x18\xa5\x03 \x01(\x0b\x32+.perfetto.protos.SchedCpuUtilCfsFtraceEventH\x00\x12:\n\tv4l2_qbuf\x18\xa6\x03 \x01(\x0b\x32$.perfetto.protos.V4l2QbufFtraceEventH\x00\x12<\n\nv4l2_dqbuf\x18\xa7\x03 \x01(\x0b\x32%.perfetto.protos.V4l2DqbufFtraceEventH\x00\x12J\n\x12vb2_v4l2_buf_queue\x18\xa8\x03 \x01(\x0b\x32+.perfetto.protos.Vb2V4l2BufQueueFtraceEventH\x00\x12H\n\x11vb2_v4l2_buf_done\x18\xa9\x03 \x01(\x0b\x32*.perfetto.protos.Vb2V4l2BufDoneFtraceEventH\x00\x12\x41\n\rvb2_v4l2_qbuf\x18\xaa\x03 \x01(\x0b\x32\'.perfetto.protos.Vb2V4l2QbufFtraceEventH\x00\x12\x43\n\x0evb2_v4l2_dqbuf\x18\xab\x03 \x01(\x0b\x32(.perfetto.protos.Vb2V4l2DqbufFtraceEventH\x00\x12L\n\x13\x64si_cmd_fifo_status\x18\xac\x03 \x01(\x0b\x32,.perfetto.protos.DsiCmdFifoStatusFtraceEventH\x00\x12\x34\n\x06\x64si_rx\x18\xad\x03 \x01(\x0b\x32!.perfetto.protos.DsiRxFtraceEventH\x00\x12\x34\n\x06\x64si_tx\x18\xae\x03 \x01(\x0b\x32!.perfetto.protos.DsiTxFtraceEventH\x00\x12T\n\x17\x61ndroid_fs_dataread_end\x18\xaf\x03 \x01(\x0b\x32\x30.perfetto.protos.AndroidFsDatareadEndFtraceEventH\x00\x12X\n\x19\x61ndroid_fs_dataread_start\x18\xb0\x03 \x01(\x0b\x32\x32.perfetto.protos.AndroidFsDatareadStartFtraceEventH\x00\x12V\n\x18\x61ndroid_fs_datawrite_end\x18\xb1\x03 \x01(\x0b\x32\x31.perfetto.protos.AndroidFsDatawriteEndFtraceEventH\x00\x12Z\n\x1a\x61ndroid_fs_datawrite_start\x18\xb2\x03 \x01(\x0b\x32\x33.perfetto.protos.AndroidFsDatawriteStartFtraceEventH\x00\x12N\n\x14\x61ndroid_fs_fsync_end\x18\xb3\x03 \x01(\x0b\x32-.perfetto.protos.AndroidFsFsyncEndFtraceEventH\x00\x12R\n\x16\x61ndroid_fs_fsync_start\x18\xb4\x03 \x01(\x0b\x32/.perfetto.protos.AndroidFsFsyncStartFtraceEventH\x00\x12\x46\n\x0f\x66uncgraph_entry\x18\xb5\x03 \x01(\x0b\x32*.perfetto.protos.FuncgraphEntryFtraceEventH\x00\x12\x44\n\x0e\x66uncgraph_exit\x18\xb6\x03 \x01(\x0b\x32).perfetto.protos.FuncgraphExitFtraceEventH\x00\x12G\n\x10virtio_video_cmd\x18\xb7\x03 \x01(\x0b\x32*.perfetto.protos.VirtioVideoCmdFtraceEventH\x00\x12P\n\x15virtio_video_cmd_done\x18\xb8\x03 \x01(\x0b\x32..perfetto.protos.VirtioVideoCmdDoneFtraceEventH\x00\x12\\\n\x1bvirtio_video_resource_queue\x18\xb9\x03 \x01(\x0b\x32\x34.perfetto.protos.VirtioVideoResourceQueueFtraceEventH\x00\x12\x65\n virtio_video_resource_queue_done\x18\xba\x03 \x01(\x0b\x32\x38.perfetto.protos.VirtioVideoResourceQueueDoneFtraceEventH\x00\x12N\n\x14mm_shrink_slab_start\x18\xbb\x03 \x01(\x0b\x32-.perfetto.protos.MmShrinkSlabStartFtraceEventH\x00\x12J\n\x12mm_shrink_slab_end\x18\xbc\x03 \x01(\x0b\x32+.perfetto.protos.MmShrinkSlabEndFtraceEventH\x00\x12<\n\ntrusty_smc\x18\xbd\x03 \x01(\x0b\x32%.perfetto.protos.TrustySmcFtraceEventH\x00\x12\x45\n\x0ftrusty_smc_done\x18\xbe\x03 \x01(\x0b\x32).perfetto.protos.TrustySmcDoneFtraceEventH\x00\x12I\n\x11trusty_std_call32\x18\xbf\x03 \x01(\x0b\x32+.perfetto.protos.TrustyStdCall32FtraceEventH\x00\x12R\n\x16trusty_std_call32_done\x18\xc0\x03 \x01(\x0b\x32/.perfetto.protos.TrustyStdCall32DoneFtraceEventH\x00\x12M\n\x13trusty_share_memory\x18\xc1\x03 \x01(\x0b\x32-.perfetto.protos.TrustyShareMemoryFtraceEventH\x00\x12V\n\x18trusty_share_memory_done\x18\xc2\x03 \x01(\x0b\x32\x31.perfetto.protos.TrustyShareMemoryDoneFtraceEventH\x00\x12Q\n\x15trusty_reclaim_memory\x18\xc3\x03 \x01(\x0b\x32/.perfetto.protos.TrustyReclaimMemoryFtraceEventH\x00\x12Z\n\x1atrusty_reclaim_memory_done\x18\xc4\x03 \x01(\x0b\x32\x33.perfetto.protos.TrustyReclaimMemoryDoneFtraceEventH\x00\x12<\n\ntrusty_irq\x18\xc5\x03 \x01(\x0b\x32%.perfetto.protos.TrustyIrqFtraceEventH\x00\x12T\n\x17trusty_ipc_handle_event\x18\xc6\x03 \x01(\x0b\x32\x30.perfetto.protos.TrustyIpcHandleEventFtraceEventH\x00\x12K\n\x12trusty_ipc_connect\x18\xc7\x03 \x01(\x0b\x32,.perfetto.protos.TrustyIpcConnectFtraceEventH\x00\x12R\n\x16trusty_ipc_connect_end\x18\xc8\x03 \x01(\x0b\x32/.perfetto.protos.TrustyIpcConnectEndFtraceEventH\x00\x12G\n\x10trusty_ipc_write\x18\xc9\x03 \x01(\x0b\x32*.perfetto.protos.TrustyIpcWriteFtraceEventH\x00\x12\x45\n\x0ftrusty_ipc_poll\x18\xca\x03 \x01(\x0b\x32).perfetto.protos.TrustyIpcPollFtraceEventH\x00\x12\x45\n\x0ftrusty_ipc_read\x18\xcc\x03 \x01(\x0b\x32).perfetto.protos.TrustyIpcReadFtraceEventH\x00\x12L\n\x13trusty_ipc_read_end\x18\xcd\x03 \x01(\x0b\x32,.perfetto.protos.TrustyIpcReadEndFtraceEventH\x00\x12\x41\n\rtrusty_ipc_rx\x18\xce\x03 \x01(\x0b\x32\'.perfetto.protos.TrustyIpcRxFtraceEventH\x00\x12K\n\x12trusty_enqueue_nop\x18\xd0\x03 \x01(\x0b\x32,.perfetto.protos.TrustyEnqueueNopFtraceEventH\x00\x12\x45\n\x0f\x63ma_alloc_start\x18\xd1\x03 \x01(\x0b\x32).perfetto.protos.CmaAllocStartFtraceEventH\x00\x12\x43\n\x0e\x63ma_alloc_info\x18\xd2\x03 \x01(\x0b\x32(.perfetto.protos.CmaAllocInfoFtraceEventH\x00\x12T\n\x17lwis_tracing_mark_write\x18\xd3\x03 \x01(\x0b\x32\x30.perfetto.protos.LwisTracingMarkWriteFtraceEventH\x00\x12N\n\x14virtio_gpu_cmd_queue\x18\xd4\x03 \x01(\x0b\x32-.perfetto.protos.VirtioGpuCmdQueueFtraceEventH\x00\x12T\n\x17virtio_gpu_cmd_response\x18\xd5\x03 \x01(\x0b\x32\x30.perfetto.protos.VirtioGpuCmdResponseFtraceEventH\x00\x12Q\n\x16mali_mali_KCPU_CQS_SET\x18\xd6\x03 \x01(\x0b\x32..perfetto.protos.MaliMaliKCPUCQSSETFtraceEventH\x00\x12^\n\x1dmali_mali_KCPU_CQS_WAIT_START\x18\xd7\x03 \x01(\x0b\x32\x34.perfetto.protos.MaliMaliKCPUCQSWAITSTARTFtraceEventH\x00\x12Z\n\x1bmali_mali_KCPU_CQS_WAIT_END\x18\xd8\x03 \x01(\x0b\x32\x32.perfetto.protos.MaliMaliKCPUCQSWAITENDFtraceEventH\x00\x12[\n\x1bmali_mali_KCPU_FENCE_SIGNAL\x18\xd9\x03 \x01(\x0b\x32\x33.perfetto.protos.MaliMaliKCPUFENCESIGNALFtraceEventH\x00\x12\x62\n\x1fmali_mali_KCPU_FENCE_WAIT_START\x18\xda\x03 \x01(\x0b\x32\x36.perfetto.protos.MaliMaliKCPUFENCEWAITSTARTFtraceEventH\x00\x12^\n\x1dmali_mali_KCPU_FENCE_WAIT_END\x18\xdb\x03 \x01(\x0b\x32\x34.perfetto.protos.MaliMaliKCPUFENCEWAITENDFtraceEventH\x00\x12:\n\thyp_enter\x18\xdc\x03 \x01(\x0b\x32$.perfetto.protos.HypEnterFtraceEventH\x00\x12\x38\n\x08hyp_exit\x18\xdd\x03 \x01(\x0b\x32#.perfetto.protos.HypExitFtraceEventH\x00\x12<\n\nhost_hcall\x18\xde\x03 \x01(\x0b\x32%.perfetto.protos.HostHcallFtraceEventH\x00\x12\x38\n\x08host_smc\x18\xdf\x03 \x01(\x0b\x32#.perfetto.protos.HostSmcFtraceEventH\x00\x12\x43\n\x0ehost_mem_abort\x18\xe0\x03 \x01(\x0b\x32(.perfetto.protos.HostMemAbortFtraceEventH\x00\x12S\n\x16suspend_resume_minimal\x18\xe1\x03 \x01(\x0b\x32\x30.perfetto.protos.SuspendResumeMinimalFtraceEventH\x00\x12_\n\x1dmali_mali_CSF_INTERRUPT_START\x18\xe2\x03 \x01(\x0b\x32\x35.perfetto.protos.MaliMaliCSFINTERRUPTSTARTFtraceEventH\x00\x12[\n\x1bmali_mali_CSF_INTERRUPT_END\x18\xe3\x03 \x01(\x0b\x32\x33.perfetto.protos.MaliMaliCSFINTERRUPTENDFtraceEventH\x00\x12Z\n\x1asamsung_tracing_mark_write\x18\xe4\x03 \x01(\x0b\x32\x33.perfetto.protos.SamsungTracingMarkWriteFtraceEventH\x00\x12\x44\n\x0e\x62inder_command\x18\xe5\x03 \x01(\x0b\x32).perfetto.protos.BinderCommandFtraceEventH\x00\x12\x42\n\rbinder_return\x18\xe6\x03 \x01(\x0b\x32(.perfetto.protos.BinderReturnFtraceEventH\x00\x12R\n\x16sched_switch_with_ctrs\x18\xe7\x03 \x01(\x0b\x32/.perfetto.protos.SchedSwitchWithCtrsFtraceEventH\x00\x12\x45\n\x0fgpu_work_period\x18\xe8\x03 \x01(\x0b\x32).perfetto.protos.GpuWorkPeriodFtraceEventH\x00\x12<\n\nrpm_status\x18\xe9\x03 \x01(\x0b\x32%.perfetto.protos.RpmStatusFtraceEventH\x00\x12M\n\x13panel_write_generic\x18\xea\x03 \x01(\x0b\x32-.perfetto.protos.PanelWriteGenericFtraceEventH\x00\x12K\n\x12sched_migrate_task\x18\xeb\x03 \x01(\x0b\x32,.perfetto.protos.SchedMigrateTaskFtraceEventH\x00\x12S\n\x17\x64pu_dsi_cmd_fifo_status\x18\xec\x03 \x01(\x0b\x32/.perfetto.protos.DpuDsiCmdFifoStatusFtraceEventH\x00\x12;\n\ndpu_dsi_rx\x18\xed\x03 \x01(\x0b\x32$.perfetto.protos.DpuDsiRxFtraceEventH\x00\x12;\n\ndpu_dsi_tx\x18\xee\x03 \x01(\x0b\x32$.perfetto.protos.DpuDsiTxFtraceEventH\x00\x12K\n\x12\x66\x32\x66s_background_gc\x18\xef\x03 \x01(\x0b\x32,.perfetto.protos.F2fsBackgroundGcFtraceEventH\x00\x12\x41\n\rf2fs_gc_begin\x18\xf0\x03 \x01(\x0b\x32\'.perfetto.protos.F2fsGcBeginFtraceEventH\x00\x12=\n\x0b\x66\x32\x66s_gc_end\x18\xf1\x03 \x01(\x0b\x32%.perfetto.protos.F2fsGcEndFtraceEventH\x00\x12G\n\x10\x66\x61strpc_dma_free\x18\xf2\x03 \x01(\x0b\x32*.perfetto.protos.FastrpcDmaFreeFtraceEventH\x00\x12I\n\x11\x66\x61strpc_dma_alloc\x18\xf3\x03 \x01(\x0b\x32+.perfetto.protos.FastrpcDmaAllocFtraceEventH\x00\x12I\n\x11\x66\x61strpc_dma_unmap\x18\xf4\x03 \x01(\x0b\x32+.perfetto.protos.FastrpcDmaUnmapFtraceEventH\x00\x12\x45\n\x0f\x66\x61strpc_dma_map\x18\xf5\x03 \x01(\x0b\x32).perfetto.protos.FastrpcDmaMapFtraceEventH\x00\x12G\n\x10google_icc_event\x18\xf6\x03 \x01(\x0b\x32*.perfetto.protos.GoogleIccEventFtraceEventH\x00\x12G\n\x10google_irm_event\x18\xf7\x03 \x01(\x0b\x32*.perfetto.protos.GoogleIrmEventFtraceEventH\x00\x12V\n\x18\x64\x65vice_pm_callback_start\x18\xf8\x03 \x01(\x0b\x32\x31.perfetto.protos.DevicePmCallbackStartFtraceEventH\x00\x12R\n\x16\x64\x65vice_pm_callback_end\x18\xf9\x03 \x01(\x0b\x32/.perfetto.protos.DevicePmCallbackEndFtraceEventH\x00\x12V\n\x18thermal_exynos_acpm_bulk\x18\xfa\x03 \x01(\x0b\x32\x31.perfetto.protos.ThermalExynosAcpmBulkFtraceEventH\x00\x12g\n!thermal_exynos_acpm_high_overhead\x18\xfb\x03 \x01(\x0b\x32\x39.perfetto.protos.ThermalExynosAcpmHighOverheadFtraceEventH\x00\x12<\n\ndcvsh_freq\x18\xfc\x03 \x01(\x0b\x32%.perfetto.protos.DcvshFreqFtraceEventH\x00\x12K\n\x12kgsl_gpu_frequency\x18\xfd\x03 \x01(\x0b\x32,.perfetto.protos.KgslGpuFrequencyFtraceEventH\x00\x12\x84\x01\n2mali_mali_PM_MCU_HCTL_CORES_DOWN_SCALE_NOTIFY_PEND\x18\xfe\x03 \x01(\x0b\x32\x45.perfetto.protos.MaliMaliPMMCUHCTLCORESDOWNSCALENOTIFYPENDFtraceEventH\x00\x12p\n\'mali_mali_PM_MCU_HCTL_CORES_NOTIFY_PEND\x18\xff\x03 \x01(\x0b\x32<.perfetto.protos.MaliMaliPMMCUHCTLCORESNOTIFYPENDFtraceEventH\x00\x12r\n(mali_mali_PM_MCU_HCTL_CORE_INACTIVE_PEND\x18\x80\x04 \x01(\x0b\x32=.perfetto.protos.MaliMaliPMMCUHCTLCOREINACTIVEPENDFtraceEventH\x00\x12j\n$mali_mali_PM_MCU_HCTL_MCU_ON_RECHECK\x18\x81\x04 \x01(\x0b\x32\x39.perfetto.protos.MaliMaliPMMCUHCTLMCUONRECHECKFtraceEventH\x00\x12w\n+mali_mali_PM_MCU_HCTL_SHADERS_CORE_OFF_PEND\x18\x82\x04 \x01(\x0b\x32?.perfetto.protos.MaliMaliPMMCUHCTLSHADERSCOREOFFPENDFtraceEventH\x00\x12n\n&mali_mali_PM_MCU_HCTL_SHADERS_PEND_OFF\x18\x83\x04 \x01(\x0b\x32;.perfetto.protos.MaliMaliPMMCUHCTLSHADERSPENDOFFFtraceEventH\x00\x12l\n%mali_mali_PM_MCU_HCTL_SHADERS_PEND_ON\x18\x84\x04 \x01(\x0b\x32:.perfetto.protos.MaliMaliPMMCUHCTLSHADERSPENDONFtraceEventH\x00\x12p\n\'mali_mali_PM_MCU_HCTL_SHADERS_READY_OFF\x18\x85\x04 \x01(\x0b\x32<.perfetto.protos.MaliMaliPMMCUHCTLSHADERSREADYOFFFtraceEventH\x00\x12V\n\x19mali_mali_PM_MCU_IN_SLEEP\x18\x86\x04 \x01(\x0b\x32\x30.perfetto.protos.MaliMaliPMMCUINSLEEPFtraceEventH\x00\x12M\n\x14mali_mali_PM_MCU_OFF\x18\x87\x04 \x01(\x0b\x32,.perfetto.protos.MaliMaliPMMCUOFFFtraceEventH\x00\x12K\n\x13mali_mali_PM_MCU_ON\x18\x88\x04 \x01(\x0b\x32+.perfetto.protos.MaliMaliPMMCUONFtraceEventH\x00\x12s\n)mali_mali_PM_MCU_ON_CORE_ATTR_UPDATE_PEND\x18\x89\x04 \x01(\x0b\x32=.perfetto.protos.MaliMaliPMMCUONCOREATTRUPDATEPENDFtraceEventH\x00\x12h\n#mali_mali_PM_MCU_ON_GLB_REINIT_PEND\x18\x8a\x04 \x01(\x0b\x32\x38.perfetto.protos.MaliMaliPMMCUONGLBREINITPENDFtraceEventH\x00\x12T\n\x18mali_mali_PM_MCU_ON_HALT\x18\x8b\x04 \x01(\x0b\x32/.perfetto.protos.MaliMaliPMMCUONHALTFtraceEventH\x00\x12\x65\n!mali_mali_PM_MCU_ON_HWCNT_DISABLE\x18\x8c\x04 \x01(\x0b\x32\x37.perfetto.protos.MaliMaliPMMCUONHWCNTDISABLEFtraceEventH\x00\x12\x63\n mali_mali_PM_MCU_ON_HWCNT_ENABLE\x18\x8d\x04 \x01(\x0b\x32\x36.perfetto.protos.MaliMaliPMMCUONHWCNTENABLEFtraceEventH\x00\x12]\n\x1dmali_mali_PM_MCU_ON_PEND_HALT\x18\x8e\x04 \x01(\x0b\x32\x33.perfetto.protos.MaliMaliPMMCUONPENDHALTFtraceEventH\x00\x12_\n\x1emali_mali_PM_MCU_ON_PEND_SLEEP\x18\x8f\x04 \x01(\x0b\x32\x34.perfetto.protos.MaliMaliPMMCUONPENDSLEEPFtraceEventH\x00\x12g\n\"mali_mali_PM_MCU_ON_SLEEP_INITIATE\x18\x90\x04 \x01(\x0b\x32\x38.perfetto.protos.MaliMaliPMMCUONSLEEPINITIATEFtraceEventH\x00\x12V\n\x19mali_mali_PM_MCU_PEND_OFF\x18\x91\x04 \x01(\x0b\x32\x30.perfetto.protos.MaliMaliPMMCUPENDOFFFtraceEventH\x00\x12\x61\n\x1fmali_mali_PM_MCU_PEND_ON_RELOAD\x18\x92\x04 \x01(\x0b\x32\x35.perfetto.protos.MaliMaliPMMCUPENDONRELOADFtraceEventH\x00\x12Z\n\x1bmali_mali_PM_MCU_POWER_DOWN\x18\x93\x04 \x01(\x0b\x32\x32.perfetto.protos.MaliMaliPMMCUPOWERDOWNFtraceEventH\x00\x12Z\n\x1bmali_mali_PM_MCU_RESET_WAIT\x18\x94\x04 \x01(\x0b\x32\x32.perfetto.protos.MaliMaliPMMCURESETWAITFtraceEventH\x00\x12\x45\n\x0f\x62\x63l_irq_trigger\x18\x95\x04 \x01(\x0b\x32).perfetto.protos.BclIrqTriggerFtraceEventH\x00\x12\\\n\x1bkgsl_adreno_cmdbatch_queued\x18\x96\x04 \x01(\x0b\x32\x34.perfetto.protos.KgslAdrenoCmdbatchQueuedFtraceEventH\x00\x12\x62\n\x1ekgsl_adreno_cmdbatch_submitted\x18\x97\x04 \x01(\x0b\x32\x37.perfetto.protos.KgslAdrenoCmdbatchSubmittedFtraceEventH\x00\x12X\n\x19kgsl_adreno_cmdbatch_sync\x18\x98\x04 \x01(\x0b\x32\x32.perfetto.protos.KgslAdrenoCmdbatchSyncFtraceEventH\x00\x12^\n\x1ckgsl_adreno_cmdbatch_retired\x18\x99\x04 \x01(\x0b\x32\x35.perfetto.protos.KgslAdrenoCmdbatchRetiredFtraceEventH\x00\x12N\n\x14pixel_mm_kswapd_wake\x18\x9a\x04 \x01(\x0b\x32-.perfetto.protos.PixelMmKswapdWakeFtraceEventH\x00\x12N\n\x14pixel_mm_kswapd_done\x18\x9b\x04 \x01(\x0b\x32-.perfetto.protos.PixelMmKswapdDoneFtraceEventH\x00\x12R\n\x16sched_wakeup_task_attr\x18\x9c\x04 \x01(\x0b\x32/.perfetto.protos.SchedWakeupTaskAttrFtraceEventH\x00\x12J\n\x11\x64\x65vfreq_frequency\x18\x9d\x04 \x01(\x0b\x32,.perfetto.protos.DevfreqFrequencyFtraceEventH\x00\x12\x35\n\x0ckprobe_event\x18\x9e\x04 \x01(\x0b\x32\x1c.perfetto.protos.KprobeEventH\x00\x12L\n\x13param_set_value_cpm\x18\x9f\x04 \x01(\x0b\x32,.perfetto.protos.ParamSetValueCpmFtraceEventH\x00\x12=\n\x0b\x64o_sys_open\x18\xa0\x04 \x01(\x0b\x32%.perfetto.protos.DoSysOpenFtraceEventH\x00\x12:\n\topen_exec\x18\xa1\x04 \x01(\x0b\x32$.perfetto.protos.OpenExecFtraceEventH\x00\x12\x43\n\x0e\x62lock_io_start\x18\xa2\x04 \x01(\x0b\x32(.perfetto.protos.BlockIoStartFtraceEventH\x00\x12\x41\n\rblock_io_done\x18\xa3\x04 \x01(\x0b\x32\'.perfetto.protos.BlockIoDoneFtraceEventH\x00\x12N\n\x14mali_gpu_power_state\x18\xa4\x04 \x01(\x0b\x32-.perfetto.protos.MaliGpuPowerStateFtraceEventH\x00\x12P\n\x15\x64pu_disp_dpu_underrun\x18\xa5\x04 \x01(\x0b\x32..perfetto.protos.DpuDispDpuUnderrunFtraceEventH\x00\x12Y\n\x1a\x64pu_disp_vblank_irq_enable\x18\xa6\x04 \x01(\x0b\x32\x32.perfetto.protos.DpuDispVblankIrqEnableFtraceEventH\x00\x12\x42\n\rhrtimer_start\x18\xa7\x04 \x01(\x0b\x32(.perfetto.protos.HrtimerStartFtraceEventH\x00\x12\x44\n\x0ehrtimer_cancel\x18\xa8\x04 \x01(\x0b\x32).perfetto.protos.HrtimerCancelFtraceEventH\x00\x12O\n\x14hrtimer_expire_entry\x18\xa9\x04 \x01(\x0b\x32..perfetto.protos.HrtimerExpireEntryFtraceEventH\x00\x12M\n\x13hrtimer_expire_exit\x18\xaa\x04 \x01(\x0b\x32-.perfetto.protos.HrtimerExpireExitFtraceEventH\x00\x12>\n\x0btimer_start\x18\xab\x04 \x01(\x0b\x32&.perfetto.protos.TimerStartFtraceEventH\x00\x12@\n\x0ctimer_cancel\x18\xac\x04 \x01(\x0b\x32\'.perfetto.protos.TimerCancelFtraceEventH\x00\x12K\n\x12timer_expire_entry\x18\xad\x04 \x01(\x0b\x32,.perfetto.protos.TimerExpireEntryFtraceEventH\x00\x12I\n\x11timer_expire_exit\x18\xae\x04 \x01(\x0b\x32+.perfetto.protos.TimerExpireExitFtraceEventH\x00\x12I\n\x11local_timer_entry\x18\xaf\x04 \x01(\x0b\x32+.perfetto.protos.LocalTimerEntryFtraceEventH\x00\x12G\n\x10local_timer_exit\x18\xb0\x04 \x01(\x0b\x32*.perfetto.protos.LocalTimerExitFtraceEventH\x00\x12K\n\x12\x64wc3_alloc_request\x18\xb1\x04 \x01(\x0b\x32,.perfetto.protos.Dwc3AllocRequestFtraceEventH\x00\x12I\n\x11\x64wc3_complete_trb\x18\xb2\x04 \x01(\x0b\x32+.perfetto.protos.Dwc3CompleteTrbFtraceEventH\x00\x12\x41\n\rdwc3_ctrl_req\x18\xb3\x04 \x01(\x0b\x32\'.perfetto.protos.Dwc3CtrlReqFtraceEventH\x00\x12\x45\n\x0f\x64wc3_ep_dequeue\x18\xb4\x04 \x01(\x0b\x32).perfetto.protos.Dwc3EpDequeueFtraceEventH\x00\x12\x41\n\rdwc3_ep_queue\x18\xb5\x04 \x01(\x0b\x32\'.perfetto.protos.Dwc3EpQueueFtraceEventH\x00\x12<\n\ndwc3_event\x18\xb6\x04 \x01(\x0b\x32%.perfetto.protos.Dwc3EventFtraceEventH\x00\x12I\n\x11\x64wc3_free_request\x18\xb7\x04 \x01(\x0b\x32+.perfetto.protos.Dwc3FreeRequestFtraceEventH\x00\x12J\n\x12\x64wc3_gadget_ep_cmd\x18\xb8\x04 \x01(\x0b\x32+.perfetto.protos.Dwc3GadgetEpCmdFtraceEventH\x00\x12R\n\x16\x64wc3_gadget_ep_disable\x18\xb9\x04 \x01(\x0b\x32/.perfetto.protos.Dwc3GadgetEpDisableFtraceEventH\x00\x12P\n\x15\x64wc3_gadget_ep_enable\x18\xba\x04 \x01(\x0b\x32..perfetto.protos.Dwc3GadgetEpEnableFtraceEventH\x00\x12T\n\x17\x64wc3_gadget_generic_cmd\x18\xbb\x04 \x01(\x0b\x32\x30.perfetto.protos.Dwc3GadgetGenericCmdFtraceEventH\x00\x12O\n\x14\x64wc3_gadget_giveback\x18\xbc\x04 \x01(\x0b\x32..perfetto.protos.Dwc3GadgetGivebackFtraceEventH\x00\x12G\n\x10\x64wc3_prepare_trb\x18\xbd\x04 \x01(\x0b\x32*.perfetto.protos.Dwc3PrepareTrbFtraceEventH\x00\x12<\n\ndwc3_readl\x18\xbe\x04 \x01(\x0b\x32%.perfetto.protos.Dwc3ReadlFtraceEventH\x00\x12>\n\x0b\x64wc3_writel\x18\xbf\x04 \x01(\x0b\x32&.perfetto.protos.Dwc3WritelFtraceEventH\x00\x12G\n\x10\x63ma_alloc_finish\x18\xc0\x04 \x01(\x0b\x32*.perfetto.protos.CmaAllocFinishFtraceEventH\x00\x12h\n\"mm_alloc_contig_migrate_range_info\x18\xc1\x04 \x01(\x0b\x32\x39.perfetto.protos.MmAllocContigMigrateRangeInfoFtraceEventH\x00\x12\x41\n\rhost_ffa_call\x18\xc2\x04 \x01(\x0b\x32\'.perfetto.protos.HostFfaCallFtraceEventH\x00\x12\x45\n\x0f\x64mabuf_rss_stat\x18\xc3\x04 \x01(\x0b\x32).perfetto.protos.DmabufRssStatFtraceEventH\x00\x12>\n\x0biommu_idmap\x18\xc4\x04 \x01(\x0b\x32&.perfetto.protos.IommuIdmapFtraceEventH\x00\x12G\n\x10psci_mem_protect\x18\xc5\x04 \x01(\x0b\x32*.perfetto.protos.PsciMemProtectFtraceEventH\x00\x12Q\n\x15hypervisor_host_hcall\x18\xc6\x04 \x01(\x0b\x32/.perfetto.protos.HypervisorHostHcallFtraceEventH\x00\x12M\n\x13hypervisor_host_smc\x18\xc7\x04 \x01(\x0b\x32-.perfetto.protos.HypervisorHostSmcFtraceEventH\x00\x12M\n\x13hypervisor_hyp_exit\x18\xc8\x04 \x01(\x0b\x32-.perfetto.protos.HypervisorHypExitFtraceEventH\x00\x12S\n\x16hypervisor_iommu_idmap\x18\xc9\x04 \x01(\x0b\x32\x30.perfetto.protos.HypervisorIommuIdmapFtraceEventH\x00\x12\\\n\x1bhypervisor_psci_mem_protect\x18\xca\x04 \x01(\x0b\x32\x34.perfetto.protos.HypervisorPsciMemProtectFtraceEventH\x00\x12X\n\x19hypervisor_host_mem_abort\x18\xcb\x04 \x01(\x0b\x32\x32.perfetto.protos.HypervisorHostMemAbortFtraceEventH\x00\x12O\n\x14hypervisor_hyp_enter\x18\xcc\x04 \x01(\x0b\x32..perfetto.protos.HypervisorHypEnterFtraceEventH\x00\x12\x64\n\x1fhypervisor_iommu_idmap_complete\x18\xcd\x04 \x01(\x0b\x32\x38.perfetto.protos.HypervisorIommuIdmapCompleteFtraceEventH\x00\x12^\n\x1chypervisor_vcpu_illegal_trap\x18\xce\x04 \x01(\x0b\x32\x35.perfetto.protos.HypervisorVcpuIllegalTrapFtraceEventH\x00\x12O\n\x15\x64rm_sched_job_add_dep\x18\xcf\x04 \x01(\x0b\x32-.perfetto.protos.DrmSchedJobAddDepFtraceEventH\x00\x12J\n\x12\x64rm_sched_job_done\x18\xd0\x04 \x01(\x0b\x32+.perfetto.protos.DrmSchedJobDoneFtraceEventH\x00\x12L\n\x13\x64rm_sched_job_queue\x18\xd1\x04 \x01(\x0b\x32,.perfetto.protos.DrmSchedJobQueueFtraceEventH\x00\x12H\n\x11\x64rm_sched_job_run\x18\xd2\x04 \x01(\x0b\x32*.perfetto.protos.DrmSchedJobRunFtraceEventH\x00\x12\\\n\x1b\x64rm_sched_job_unschedulable\x18\xd3\x04 \x01(\x0b\x32\x34.perfetto.protos.DrmSchedJobUnschedulableFtraceEventH\x00\x12Q\n\x15\x66wtp_perfetto_counter\x18\xd4\x04 \x01(\x0b\x32/.perfetto.protos.FwtpPerfettoCounterFtraceEventH\x00\x12T\n\x17scsi_dispatch_cmd_error\x18\xd5\x04 \x01(\x0b\x32\x30.perfetto.protos.ScsiDispatchCmdErrorFtraceEventH\x00\x12X\n\x19scsi_dispatch_cmd_timeout\x18\xd6\x04 \x01(\x0b\x32\x32.perfetto.protos.ScsiDispatchCmdTimeoutFtraceEventH\x00\x12\x43\n\x0escsi_eh_wakeup\x18\xd7\x04 \x01(\x0b\x32(.perfetto.protos.ScsiEhWakeupFtraceEventH\x00\x12M\n\x13\x66wtp_perfetto_slice\x18\xd8\x04 \x01(\x0b\x32-.perfetto.protos.FwtpPerfettoSliceFtraceEventH\x00\x12\x45\n\x0fgpu_power_state\x18\xd9\x04 \x01(\x0b\x32).perfetto.protos.GpuPowerStateFtraceEventH\x00\x12\x44\n\x0egram_collision\x18\xda\x04 \x01(\x0b\x32).perfetto.protos.GramCollisionFtraceEventH\x00\x12R\n\x16\x66\x32\x66s_lock_elapsed_time\x18\xdb\x04 \x01(\x0b\x32/.perfetto.protos.F2fsLockElapsedTimeFtraceEventH\x00\x12M\n\x13sched_group_tracker\x18\xdc\x04 \x01(\x0b\x32-.perfetto.protos.SchedGroupTrackerFtraceEventH\x00\x12[\n\x1b\x64pu_disp_frame_done_timeout\x18\xdd\x04 \x01(\x0b\x32\x33.perfetto.protos.DpuDispFrameDoneTimeoutFtraceEventH\x00\x12]\n\x1c\x64pu_disp_frame_start_timeout\x18\xde\x04 \x01(\x0b\x32\x34.perfetto.protos.DpuDispFrameStartTimeoutFtraceEventH\x00\x12_\n\x1dmm_vmscan_memcg_reclaim_begin\x18\xdf\x04 \x01(\x0b\x32\x35.perfetto.protos.MmVmscanMemcgReclaimBeginFtraceEventH\x00\x12[\n\x1bmm_vmscan_memcg_reclaim_end\x18\xe0\x04 \x01(\x0b\x32\x33.perfetto.protos.MmVmscanMemcgReclaimEndFtraceEventH\x00\x12[\n\x1b\x64pu_disp_frame_done_missing\x18\xe1\x04 \x01(\x0b\x32\x33.perfetto.protos.DpuDispFrameDoneMissingFtraceEventH\x00\x12]\n\x1c\x64pu_disp_frame_start_missing\x18\xe2\x04 \x01(\x0b\x32\x34.perfetto.protos.DpuDispFrameStartMissingFtraceEventH\x00\x12M\n\x13panel_settings_full\x18\xe3\x04 \x01(\x0b\x32-.perfetto.protos.PanelSettingsFullFtraceEventH\x00\x12M\n\x13panel_settings_lite\x18\xe4\x04 \x01(\x0b\x32-.perfetto.protos.PanelSettingsLiteFtraceEventH\x00\x12Y\n\x1a\x64pu_disp_dpu_line_underrun\x18\xe5\x04 \x01(\x0b\x32\x32.perfetto.protos.DpuDispDpuLineUnderrunFtraceEventH\x00\x12P\n\x15psci_domain_idle_exit\x18\xe6\x04 \x01(\x0b\x32..perfetto.protos.PsciDomainIdleExitFtraceEventH\x00\x12R\n\x16psci_domain_idle_enter\x18\xe7\x04 \x01(\x0b\x32/.perfetto.protos.PsciDomainIdleEnterFtraceEventH\x00\x12\x38\n\x08long_irq\x18\xe8\x04 \x01(\x0b\x32#.perfetto.protos.LongIrqFtraceEventH\x00\x12@\n\x0clong_softirq\x18\xe9\x04 \x01(\x0b\x32\'.perfetto.protos.LongSoftirqFtraceEventH\x00\x42\x07\n\x05\x65ventJ\x08\x08\x80\x80\x04\x10\x81\x80\x08\"\xc1\x01\n\x0e\x46traceCpuStats\x12\x0b\n\x03\x63pu\x18\x01 \x01(\x04\x12\x0f\n\x07\x65ntries\x18\x02 \x01(\x04\x12\x0f\n\x07overrun\x18\x03 \x01(\x04\x12\x16\n\x0e\x63ommit_overrun\x18\x04 \x01(\x04\x12\x12\n\nbytes_read\x18\x05 \x01(\x04\x12\x17\n\x0foldest_event_ts\x18\x06 \x01(\x01\x12\x0e\n\x06now_ts\x18\x07 \x01(\x01\x12\x16\n\x0e\x64ropped_events\x18\x08 \x01(\x04\x12\x13\n\x0bread_events\x18\t \x01(\x04\"1\n\x11\x46traceKprobeStats\x12\x0c\n\x04hits\x18\x01 \x01(\x03\x12\x0e\n\x06misses\x18\x02 \x01(\x03\"\xc7\x04\n\x0b\x46traceStats\x12\x31\n\x05phase\x18\x01 \x01(\x0e\x32\".perfetto.protos.FtraceStats.Phase\x12\x32\n\tcpu_stats\x18\x02 \x03(\x0b\x32\x1f.perfetto.protos.FtraceCpuStats\x12\x1d\n\x15kernel_symbols_parsed\x18\x03 \x01(\r\x12\x1d\n\x15kernel_symbols_mem_kb\x18\x04 \x01(\r\x12\x15\n\ratrace_errors\x18\x05 \x01(\t\x12\x1f\n\x17\x65xclusive_feature_error\x18\r \x01(\t\x12\x1d\n\x15unknown_ftrace_events\x18\x06 \x03(\t\x12\x1c\n\x14\x66\x61iled_ftrace_events\x18\x07 \x03(\t\x12\x1e\n\x16preserve_ftrace_buffer\x18\x08 \x01(\x08\x12?\n\x13\x66trace_parse_errors\x18\t \x03(\x0e\x32\".perfetto.protos.FtraceParseStatus\x12\x38\n\x0ckprobe_stats\x18\n \x01(\x0b\x32\".perfetto.protos.FtraceKprobeStats\x12\x1d\n\x15\x63pu_buffer_size_pages\x18\x0b \x01(\r\x12$\n\x1c\x63\x61\x63hed_cpu_buffer_size_pages\x18\x0c \x01(\r\">\n\x05Phase\x12\x0f\n\x0bUNSPECIFIED\x10\x00\x12\x12\n\x0eSTART_OF_TRACE\x10\x01\x12\x10\n\x0c\x45ND_OF_TRACE\x10\x02\"\xb8\x08\n\x11\x46traceEventBundle\x12\x0b\n\x03\x63pu\x18\x01 \x01(\r\x12+\n\x05\x65vent\x18\x02 \x03(\x0b\x32\x1c.perfetto.protos.FtraceEvent\x12\x13\n\x0blost_events\x18\x03 \x01(\x08\x12\x46\n\rcompact_sched\x18\x04 \x01(\x0b\x32/.perfetto.protos.FtraceEventBundle.CompactSched\x12\x32\n\x0c\x66trace_clock\x18\x05 \x01(\x0e\x32\x1c.perfetto.protos.FtraceClock\x12\x18\n\x10\x66trace_timestamp\x18\x06 \x01(\x03\x12\x16\n\x0e\x62oot_timestamp\x18\x07 \x01(\x03\x12=\n\x05\x65rror\x18\x08 \x03(\x0b\x32..perfetto.protos.FtraceEventBundle.FtraceError\x12!\n\x19last_read_event_timestamp\x18\t \x01(\x04\x12%\n\x1dprevious_bundle_end_timestamp\x18\n \x01(\x04\x12\\\n\x19generic_event_descriptors\x18\x0b \x03(\x0b\x32\x39.perfetto.protos.FtraceEventBundle.GenericEventDescriptor\x12\x1e\n\x15\x62roken_abi_trace_page\x18\x80\x04 \x01(\x0c\x1a\xee\x02\n\x0c\x43ompactSched\x12\x14\n\x0cintern_table\x18\x05 \x03(\t\x12\x1c\n\x10switch_timestamp\x18\x01 \x03(\x04\x42\x02\x10\x01\x12\x1d\n\x11switch_prev_state\x18\x02 \x03(\x03\x42\x02\x10\x01\x12\x1b\n\x0fswitch_next_pid\x18\x03 \x03(\x05\x42\x02\x10\x01\x12\x1c\n\x10switch_next_prio\x18\x04 \x03(\x05\x42\x02\x10\x01\x12\"\n\x16switch_next_comm_index\x18\x06 \x03(\rB\x02\x10\x01\x12\x1c\n\x10waking_timestamp\x18\x07 \x03(\x04\x42\x02\x10\x01\x12\x16\n\nwaking_pid\x18\x08 \x03(\x05\x42\x02\x10\x01\x12\x1d\n\x11waking_target_cpu\x18\t \x03(\x05\x42\x02\x10\x01\x12\x17\n\x0bwaking_prio\x18\n \x03(\x05\x42\x02\x10\x01\x12\x1d\n\x11waking_comm_index\x18\x0b \x03(\rB\x02\x10\x01\x12\x1f\n\x13waking_common_flags\x18\x0c \x03(\rB\x02\x10\x01\x1aT\n\x0b\x46traceError\x12\x11\n\ttimestamp\x18\x01 \x01(\x04\x12\x32\n\x06status\x18\x02 \x01(\x0e\x32\".perfetto.protos.FtraceParseStatus\x1aX\n\x16GenericEventDescriptor\x12\x10\n\x08\x66ield_id\x18\x01 \x01(\x05\x12\x12\n\ngroup_name\x18\x03 \x01(\t\x12\x18\n\x10\x65vent_descriptor\x18\x02 \x01(\x0c\"A\n\x18GenericGpuFrequencyEvent\x12\x0e\n\x06gpu_id\x18\x01 \x01(\r\x12\x15\n\rfrequency_khz\x18\x02 \x01(\r\">\n\x1eGenericKernelCpuFrequencyEvent\x12\x0b\n\x03\x63pu\x18\x01 \x01(\x05\x12\x0f\n\x07\x66req_hz\x18\x02 \x01(\x03\"\xa2\x03\n\x1bGenericKernelTaskStateEvent\x12\x0b\n\x03\x63pu\x18\x01 \x01(\x05\x12\x0c\n\x04\x63omm\x18\x02 \x01(\t\x12\x0b\n\x03tid\x18\x03 \x01(\x03\x12I\n\x05state\x18\x04 \x01(\x0e\x32:.perfetto.protos.GenericKernelTaskStateEvent.TaskStateEnum\x12\x0c\n\x04prio\x18\x05 \x01(\x05\"\x81\x02\n\rTaskStateEnum\x12\x16\n\x12TASK_STATE_UNKNOWN\x10\x00\x12\x16\n\x12TASK_STATE_CREATED\x10\x01\x12\x17\n\x13TASK_STATE_RUNNABLE\x10\x02\x12\x16\n\x12TASK_STATE_RUNNING\x10\x03\x12\"\n\x1eTASK_STATE_INTERRUPTIBLE_SLEEP\x10\x04\x12$\n TASK_STATE_UNINTERRUPTIBLE_SLEEP\x10\x05\x12\x16\n\x12TASK_STATE_STOPPED\x10\x06\x12\x13\n\x0fTASK_STATE_DEAD\x10\x07\x12\x18\n\x14TASK_STATE_DESTROYED\x10\x08\"9\n\x1cGenericKernelTaskRenameEvent\x12\x0b\n\x03tid\x18\x01 \x01(\x03\x12\x0c\n\x04\x63omm\x18\x02 \x01(\t\"\xb5\x02\n\x18GenericKernelProcessTree\x12\x44\n\tprocesses\x18\x01 \x03(\x0b\x32\x31.perfetto.protos.GenericKernelProcessTree.Process\x12\x41\n\x07threads\x18\x02 \x03(\x0b\x32\x30.perfetto.protos.GenericKernelProcessTree.Thread\x1aY\n\x06Thread\x12\x0b\n\x03tid\x18\x01 \x01(\x03\x12\x0b\n\x03pid\x18\x02 \x01(\x03\x12\x0c\n\x04\x63omm\x18\x03 \x01(\t\x12\x16\n\x0eis_main_thread\x18\x04 \x01(\x08\x12\x0f\n\x07is_idle\x18\x05 \x01(\x08\x1a\x35\n\x07Process\x12\x0b\n\x03pid\x18\x01 \x01(\x03\x12\x0c\n\x04ppid\x18\x02 \x01(\x03\x12\x0f\n\x07\x63mdline\x18\x03 \x01(\t\"\xa7\x02\n\x0fGpuCounterEvent\x12\x43\n\x12\x63ounter_descriptor\x18\x01 \x01(\x0b\x32%.perfetto.protos.GpuCounterDescriptorH\x00\x12 \n\x16\x63ounter_descriptor_iid\x18\x04 \x01(\x04H\x00\x12=\n\x08\x63ounters\x18\x02 \x03(\x0b\x32+.perfetto.protos.GpuCounterEvent.GpuCounter\x12\x0e\n\x06gpu_id\x18\x03 \x01(\x05\x1aV\n\nGpuCounter\x12\x12\n\ncounter_id\x18\x01 \x01(\r\x12\x13\n\tint_value\x18\x02 \x01(\x03H\x00\x12\x16\n\x0c\x64ouble_value\x18\x03 \x01(\x01H\x00\x42\x07\n\x05valueB\x06\n\x04\x64\x65sc\"~\n\x1cInternedGpuCounterDescriptor\x12\x0b\n\x03iid\x18\x01 \x01(\x04\x12\x41\n\x12\x63ounter_descriptor\x18\x02 \x01(\x0b\x32%.perfetto.protos.GpuCounterDescriptor\x12\x0e\n\x06gpu_id\x18\x03 \x01(\x05\"\x84\x02\n\x06GpuLog\x12\x32\n\x08severity\x18\x01 \x01(\x0e\x32 .perfetto.protos.GpuLog.Severity\x12\x0b\n\x03tag\x18\x02 \x01(\t\x12\x13\n\x0blog_message\x18\x03 \x01(\t\"\xa3\x01\n\x08Severity\x12\x1c\n\x18LOG_SEVERITY_UNSPECIFIED\x10\x00\x12\x18\n\x14LOG_SEVERITY_VERBOSE\x10\x01\x12\x16\n\x12LOG_SEVERITY_DEBUG\x10\x02\x12\x15\n\x11LOG_SEVERITY_INFO\x10\x03\x12\x18\n\x14LOG_SEVERITY_WARNING\x10\x04\x12\x16\n\x12LOG_SEVERITY_ERROR\x10\x05\"=\n\x10GpuMemTotalEvent\x12\x0e\n\x06gpu_id\x18\x01 \x01(\r\x12\x0b\n\x03pid\x18\x02 \x01(\r\x12\x0c\n\x04size\x18\x03 \x01(\x04\"\x8b\x0c\n\x13GpuRenderStageEvent\x12\x10\n\x08\x65vent_id\x18\x01 \x01(\x04\x12\x10\n\x08\x64uration\x18\x02 \x01(\x04\x12\x14\n\x0chw_queue_iid\x18\r \x01(\x04\x12\x11\n\tstage_iid\x18\x0e \x01(\x04\x12\x0e\n\x06gpu_id\x18\x0b \x01(\x05\x12\x0f\n\x07\x63ontext\x18\x05 \x01(\x04\x12\x1c\n\x14render_target_handle\x18\x08 \x01(\x04\x12\x15\n\rsubmission_id\x18\n \x01(\r\x12\x42\n\nextra_data\x18\x06 \x03(\x0b\x32..perfetto.protos.GpuRenderStageEvent.ExtraData\x12\x1a\n\x12render_pass_handle\x18\t \x01(\x04\x12\x1f\n\x17render_pass_instance_id\x18\x10 \x01(\x04\x12!\n\x19render_subpass_index_mask\x18\x0f \x03(\x04\x12\x1d\n\x15\x63ommand_buffer_handle\x18\x0c \x01(\x04\x12\x0e\n\x04name\x18\x11 \x01(\tH\x00\x12\x12\n\x08name_iid\x18\x14 \x01(\x04H\x00\x12\x16\n\x0e\x65vent_wait_ids\x18\x12 \x03(\x04\x12\x12\n\nkernel_iid\x18\x13 \x01(\x04\x12H\n\x06launch\x18\x15 \x01(\x0b\x32\x38.perfetto.protos.GpuRenderStageEvent.ComputeKernelLaunch\x12O\n\x0especifications\x18\x07 \x01(\x0b\x32\x33.perfetto.protos.GpuRenderStageEvent.SpecificationsB\x02\x18\x01\x12\x17\n\x0bhw_queue_id\x18\x03 \x01(\x05\x42\x02\x18\x01\x12\x14\n\x08stage_id\x18\x04 \x01(\x05\x42\x02\x18\x01\x1a(\n\tExtraData\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t\x1a\'\n\x04\x44im3\x12\t\n\x01x\x18\x01 \x01(\r\x12\t\n\x01y\x18\x02 \x01(\r\x12\t\n\x01z\x18\x03 \x01(\r\x1a\xc3\x01\n\x0f\x45xtraComputeArg\x12\x12\n\x08name_iid\x18\x01 \x01(\x04H\x00\x12\x0e\n\x04name\x18\x02 \x01(\tH\x00\x12\x13\n\tint_value\x18\x03 \x01(\x03H\x01\x12\x14\n\nuint_value\x18\x04 \x01(\x04H\x01\x12\x16\n\x0c\x64ouble_value\x18\x05 \x01(\x01H\x01\x12\x16\n\x0cstring_value\x18\x06 \x01(\tH\x01\x12\x1a\n\x10string_value_iid\x18\x07 \x01(\x04H\x01\x42\x0c\n\nname_fieldB\x07\n\x05value\x1a\xda\x01\n\x13\x43omputeKernelLaunch\x12<\n\tgrid_size\x18\x01 \x01(\x0b\x32).perfetto.protos.GpuRenderStageEvent.Dim3\x12\x41\n\x0eworkgroup_size\x18\x02 \x01(\x0b\x32).perfetto.protos.GpuRenderStageEvent.Dim3\x12\x42\n\x04\x61rgs\x18\x03 \x03(\x0b\x32\x34.perfetto.protos.GpuRenderStageEvent.ExtraComputeArg\x1a\xe9\x02\n\x0eSpecifications\x12U\n\x0c\x63ontext_spec\x18\x01 \x01(\x0b\x32?.perfetto.protos.GpuRenderStageEvent.Specifications.ContextSpec\x12Q\n\x08hw_queue\x18\x02 \x03(\x0b\x32?.perfetto.protos.GpuRenderStageEvent.Specifications.Description\x12N\n\x05stage\x18\x03 \x03(\x0b\x32?.perfetto.protos.GpuRenderStageEvent.Specifications.Description\x1a+\n\x0b\x43ontextSpec\x12\x0f\n\x07\x63ontext\x18\x01 \x01(\x04\x12\x0b\n\x03pid\x18\x02 \x01(\x05\x1a\x30\n\x0b\x44\x65scription\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x13\n\x0b\x64\x65scription\x18\x02 \x01(\t*\x04\x08\x64\x10\x65\x42\x0c\n\nname_field\"\xbd\x01\n\x17InternedGraphicsContext\x12\x0b\n\x03iid\x18\x01 \x01(\x04\x12\x0b\n\x03pid\x18\x02 \x01(\x05\x12\x39\n\x03\x61pi\x18\x03 \x01(\x0e\x32,.perfetto.protos.InternedGraphicsContext.Api\"M\n\x03\x41pi\x12\r\n\tUNDEFINED\x10\x00\x12\x0b\n\x07OPEN_GL\x10\x01\x12\n\n\x06VULKAN\x10\x02\x12\x0b\n\x07OPEN_CL\x10\x03\x12\x08\n\x04\x43UDA\x10\x04\x12\x07\n\x03HIP\x10\x05\"\xee\x01\n#InternedGpuRenderStageSpecification\x12\x0b\n\x03iid\x18\x01 \x01(\x04\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x13\n\x0b\x64\x65scription\x18\x03 \x01(\t\x12Z\n\x08\x63\x61tegory\x18\x04 \x01(\x0e\x32H.perfetto.protos.InternedGpuRenderStageSpecification.RenderStageCategory\";\n\x13RenderStageCategory\x12\t\n\x05OTHER\x10\x00\x12\x0c\n\x08GRAPHICS\x10\x01\x12\x0b\n\x07\x43OMPUTE\x10\x02\"\x9c\x01\n\x15InternedComputeKernel\x12\x0b\n\x03iid\x18\x01 \x01(\x04\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x16\n\x0e\x64\x65mangled_name\x18\x03 \x01(\t\x12\x0c\n\x04\x61rch\x18\x04 \x01(\t\x12\x42\n\x04\x61rgs\x18\x05 \x03(\x0b\x32\x34.perfetto.protos.GpuRenderStageEvent.ExtraComputeArg\"3\n\x16InternedComputeArgName\x12\x0b\n\x03iid\x18\x01 \x01(\x04\x12\x0c\n\x04name\x18\x02 \x01(\t\"\xbb\x03\n\x0eVulkanApiEvent\x12\\\n\x1avk_debug_utils_object_name\x18\x01 \x01(\x0b\x32\x36.perfetto.protos.VulkanApiEvent.VkDebugUtilsObjectNameH\x00\x12H\n\x0fvk_queue_submit\x18\x02 \x01(\x0b\x32-.perfetto.protos.VulkanApiEvent.VkQueueSubmitH\x00\x1ar\n\x16VkDebugUtilsObjectName\x12\x0b\n\x03pid\x18\x01 \x01(\r\x12\x11\n\tvk_device\x18\x02 \x01(\x04\x12\x13\n\x0bobject_type\x18\x03 \x01(\x05\x12\x0e\n\x06object\x18\x04 \x01(\x04\x12\x13\n\x0bobject_name\x18\x05 \x01(\t\x1a\x83\x01\n\rVkQueueSubmit\x12\x13\n\x0b\x64uration_ns\x18\x01 \x01(\x04\x12\x0b\n\x03pid\x18\x02 \x01(\r\x12\x0b\n\x03tid\x18\x03 \x01(\r\x12\x10\n\x08vk_queue\x18\x04 \x01(\x04\x12\x1a\n\x12vk_command_buffers\x18\x05 \x03(\x04\x12\x15\n\rsubmission_id\x18\x06 \x01(\rB\x07\n\x05\x65vent\"z\n\x1bVulkanMemoryEventAnnotation\x12\x0f\n\x07key_iid\x18\x01 \x01(\x04\x12\x13\n\tint_value\x18\x02 \x01(\x03H\x00\x12\x16\n\x0c\x64ouble_value\x18\x03 \x01(\x01H\x00\x12\x14\n\nstring_iid\x18\x04 \x01(\x04H\x00\x42\x07\n\x05value\"\xe8\x06\n\x11VulkanMemoryEvent\x12\x39\n\x06source\x18\x01 \x01(\x0e\x32).perfetto.protos.VulkanMemoryEvent.Source\x12?\n\toperation\x18\x02 \x01(\x0e\x32,.perfetto.protos.VulkanMemoryEvent.Operation\x12\x11\n\ttimestamp\x18\x03 \x01(\x03\x12\x0b\n\x03pid\x18\x04 \x01(\r\x12\x16\n\x0ememory_address\x18\x05 \x01(\x06\x12\x13\n\x0bmemory_size\x18\x06 \x01(\x04\x12\x12\n\ncaller_iid\x18\x07 \x01(\x04\x12L\n\x10\x61llocation_scope\x18\x08 \x01(\x0e\x32\x32.perfetto.protos.VulkanMemoryEvent.AllocationScope\x12\x41\n\x0b\x61nnotations\x18\t \x03(\x0b\x32,.perfetto.protos.VulkanMemoryEventAnnotation\x12\x0e\n\x06\x64\x65vice\x18\x10 \x01(\x06\x12\x15\n\rdevice_memory\x18\x11 \x01(\x06\x12\x13\n\x0bmemory_type\x18\x12 \x01(\r\x12\x0c\n\x04heap\x18\x13 \x01(\r\x12\x15\n\robject_handle\x18\x14 \x01(\x06\"\x85\x01\n\x06Source\x12\x16\n\x12SOURCE_UNSPECIFIED\x10\x00\x12\x11\n\rSOURCE_DRIVER\x10\x01\x12\x11\n\rSOURCE_DEVICE\x10\x02\x12\x18\n\x14SOURCE_DEVICE_MEMORY\x10\x03\x12\x11\n\rSOURCE_BUFFER\x10\x04\x12\x10\n\x0cSOURCE_IMAGE\x10\x05\"u\n\tOperation\x12\x12\n\x0eOP_UNSPECIFIED\x10\x00\x12\r\n\tOP_CREATE\x10\x01\x12\x0e\n\nOP_DESTROY\x10\x02\x12\x0b\n\x07OP_BIND\x10\x03\x12\x14\n\x10OP_DESTROY_BOUND\x10\x04\x12\x12\n\x0eOP_ANNOTATIONS\x10\x05\"\x84\x01\n\x0f\x41llocationScope\x12\x15\n\x11SCOPE_UNSPECIFIED\x10\x00\x12\x11\n\rSCOPE_COMMAND\x10\x01\x12\x10\n\x0cSCOPE_OBJECT\x10\x02\x12\x0f\n\x0bSCOPE_CACHE\x10\x03\x12\x10\n\x0cSCOPE_DEVICE\x10\x04\x12\x12\n\x0eSCOPE_INSTANCE\x10\x05\"*\n\x0eInternedString\x12\x0b\n\x03iid\x18\x01 \x01(\x04\x12\x0b\n\x03str\x18\x02 \x01(\x0c\"L\n\x04Line\x12\x15\n\rfunction_name\x18\x01 \x01(\t\x12\x18\n\x10source_file_name\x18\x02 \x01(\t\x12\x13\n\x0bline_number\x18\x03 \x01(\r\"G\n\x0e\x41\x64\x64ressSymbols\x12\x0f\n\x07\x61\x64\x64ress\x18\x01 \x01(\x04\x12$\n\x05lines\x18\x02 \x03(\x0b\x32\x15.perfetto.protos.Line\"i\n\rModuleSymbols\x12\x0c\n\x04path\x18\x01 \x01(\t\x12\x10\n\x08\x62uild_id\x18\x02 \x01(\t\x12\x38\n\x0f\x61\x64\x64ress_symbols\x18\x03 \x03(\x0b\x32\x1f.perfetto.protos.AddressSymbols\"\x9c\x01\n\x07Mapping\x12\x0b\n\x03iid\x18\x01 \x01(\x04\x12\x10\n\x08\x62uild_id\x18\x02 \x01(\x04\x12\x14\n\x0c\x65xact_offset\x18\x08 \x01(\x04\x12\x14\n\x0cstart_offset\x18\x03 \x01(\x04\x12\r\n\x05start\x18\x04 \x01(\x04\x12\x0b\n\x03\x65nd\x18\x05 \x01(\x04\x12\x11\n\tload_bias\x18\x06 \x01(\x04\x12\x17\n\x0fpath_string_ids\x18\x07 \x03(\x04\"\xce\x02\n\x05\x46rame\x12\x0b\n\x03iid\x18\x01 \x01(\x04\x12\x18\n\x10\x66unction_name_id\x18\x02 \x01(\x04\x12\x12\n\nmapping_id\x18\x03 \x01(\x04\x12\x0e\n\x06rel_pc\x18\x04 \x01(\x04\x12\x17\n\x0fsource_path_iid\x18\x05 \x01(\x04\x12\x13\n\x0bline_number\x18\x06 \x01(\r\x12+\n\x04kind\x18\x07 \x01(\x0e\x32\x1b.perfetto.protos.Frame.KindH\x00\x12\x12\n\x08kind_str\x18\x08 \x01(\tH\x00\"}\n\x04Kind\x12\x10\n\x0cKIND_UNKNOWN\x10\x00\x12\x0f\n\x0bKIND_NATIVE\x10\x01\x12\x0f\n\x0bKIND_KERNEL\x10\x02\x12\x14\n\x10KIND_INTERPRETED\x10\x03\x12\x0c\n\x08KIND_JIT\x10\x04\x12\x0b\n\x07KIND_GC\x10\x05\x12\x10\n\x0cKIND_RUNTIME\x10\x06\x42\x0c\n\nkind_field\"+\n\tCallstack\x12\x0b\n\x03iid\x18\x01 \x01(\x04\x12\x11\n\tframe_ids\x18\x02 \x03(\x04\"\x93\x01\n\x0fInlineCallstack\x12\x36\n\x06\x66rames\x18\x01 \x03(\x0b\x32&.perfetto.protos.InlineCallstack.Frame\x1aH\n\x05\x46rame\x12\x15\n\rfunction_name\x18\x01 \x01(\t\x12\x13\n\x0bsource_file\x18\x02 \x01(\t\x12\x13\n\x0bline_number\x18\x03 \x01(\r\"\x80\r\n\x0bStackSample\x12@\n\x0ctask_context\x18\x01 \x01(\x0b\x32(.perfetto.protos.StackSample.TaskContextH\x00\x12\x1a\n\x10task_context_iid\x18\x02 \x01(\x04H\x00\x12J\n\x11\x65xecution_context\x18\x03 \x01(\x0b\x32-.perfetto.protos.StackSample.ExecutionContextH\x01\x12\x1f\n\x15\x65xecution_context_iid\x18\x04 \x01(\x04H\x01\x12\x35\n\tcallstack\x18\x05 \x01(\x0b\x32 .perfetto.protos.InlineCallstackH\x02\x12\x17\n\rcallstack_iid\x18\x06 \x01(\x04H\x02\x12\x16\n\x0cunwind_error\x18\x07 \x01(\tH\x03\x12\x1a\n\x10unwind_error_iid\x18\x08 \x01(\x04H\x03\x12L\n\x12primary_descriptor\x18\t \x01(\x0b\x32..perfetto.protos.StackSample.CounterDescriptorH\x04\x12 \n\x16primary_descriptor_iid\x18\n \x01(\x04H\x04\x12\x16\n\x0eprimary_weight\x18\x0b \x01(\x04\x12L\n\x14\x66ollower_descriptors\x18\x0c \x03(\x0b\x32..perfetto.protos.StackSample.CounterDescriptor\x12$\n\x18\x66ollower_descriptor_iids\x18\r \x03(\x04\x42\x02\x10\x01\x12\x1c\n\x10\x66ollower_weights\x18\x0e \x03(\x04\x42\x02\x10\x01\x1a\x46\n\x0bTaskContext\x12\x0b\n\x03iid\x18\x01 \x01(\x04\x12\x0b\n\x03pid\x18\x02 \x01(\r\x12\x0b\n\x03tid\x18\x03 \x01(\r\x12\x10\n\x08\x61sync_id\x18\x04 \x01(\x04\x1aU\n\x16\x41syncContextDescriptor\x12\x0b\n\x03iid\x18\x01 \x01(\x04\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x0c\n\x04kind\x18\x03 \x01(\t\x12\x12\n\nparent_iid\x18\x04 \x01(\x04\x1a]\n\x10\x45xecutionContext\x12\x0b\n\x03iid\x18\x01 \x01(\x04\x12\x0b\n\x03\x63pu\x18\x02 \x01(\r\x12/\n\x04mode\x18\x03 \x01(\x0e\x32!.perfetto.protos.StackSample.Mode\x1a\xb7\x02\n\x11\x43ounterDescriptor\x12\x0b\n\x03iid\x18\x01 \x01(\x04\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x31\n\x04unit\x18\x03 \x01(\x0e\x32!.perfetto.protos.StackSample.UnitH\x00\x12\x12\n\x08unit_str\x18\x04 \x01(\tH\x00\x12\x17\n\x0funit_multiplier\x18\x05 \x01(\x04\x12\x13\n\x0b\x64\x65scription\x18\x06 \x01(\t\x12\x43\n\x05scope\x18\x07 \x01(\x0e\x32\x34.perfetto.protos.StackSample.CounterDescriptor.Scope\"?\n\x05Scope\x12\x15\n\x11SCOPE_UNSPECIFIED\x10\x00\x12\x10\n\x0cSCOPE_GLOBAL\x10\x01\x12\r\n\tSCOPE_CPU\x10\x02\x42\x0c\n\nunit_field\"y\n\x04Mode\x12\x10\n\x0cMODE_UNKNOWN\x10\x00\x12\r\n\tMODE_USER\x10\x01\x12\x0f\n\x0bMODE_KERNEL\x10\x02\x12\x13\n\x0fMODE_HYPERVISOR\x10\x03\x12\x13\n\x0fMODE_GUEST_USER\x10\x04\x12\x15\n\x11MODE_GUEST_KERNEL\x10\x05\"\xde\x01\n\x04Unit\x12\x14\n\x10UNIT_UNSPECIFIED\x10\x00\x12\x14\n\x10UNIT_NANOSECONDS\x10\x01\x12\x13\n\x0fUNIT_CPU_CYCLES\x10\x02\x12\x15\n\x11UNIT_INSTRUCTIONS\x10\x03\x12\x0e\n\nUNIT_BYTES\x10\x04\x12\x14\n\x10UNIT_PAGE_FAULTS\x10\x05\x12\x15\n\x11UNIT_CACHE_MISSES\x10\x06\x12\x19\n\x15UNIT_CACHE_REFERENCES\x10\x07\x12\x16\n\x12UNIT_BRANCH_MISSES\x10\x08\x12\x0e\n\nUNIT_COUNT\x10\tB\x14\n\x12task_context_fieldB\x19\n\x17\x65xecution_context_fieldB\x11\n\x0f\x63\x61llstack_fieldB\x14\n\x12unwind_error_fieldB\x1a\n\x18primary_descriptor_field\"\xbf\x01\n\x13StackSampleDefaults\x12\x0e\n\x06source\x18\x01 \x01(\t\x12J\n\x12primary_descriptor\x18\x02 \x01(\x0b\x32..perfetto.protos.StackSample.CounterDescriptor\x12L\n\x14\x66ollower_descriptors\x18\x03 \x03(\x0b\x32..perfetto.protos.StackSample.CounterDescriptor\"*\n\rHistogramName\x12\x0b\n\x03iid\x18\x01 \x01(\x04\x12\x0c\n\x04name\x18\x02 \x01(\t\"Z\n\x15\x43hromeHistogramSample\x12\x11\n\tname_hash\x18\x01 \x01(\x04\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x0e\n\x06sample\x18\x03 \x01(\x03\x12\x10\n\x08name_iid\x18\x04 \x01(\x04\"\xac\x07\n\x0f\x44\x65\x62ugAnnotation\x12\x12\n\x08name_iid\x18\x01 \x01(\x04H\x00\x12\x0e\n\x04name\x18\n \x01(\tH\x00\x12\x14\n\nbool_value\x18\x02 \x01(\x08H\x01\x12\x14\n\nuint_value\x18\x03 \x01(\x04H\x01\x12\x13\n\tint_value\x18\x04 \x01(\x03H\x01\x12\x16\n\x0c\x64ouble_value\x18\x05 \x01(\x01H\x01\x12\x17\n\rpointer_value\x18\x07 \x01(\x04H\x01\x12\x44\n\x0cnested_value\x18\x08 \x01(\x0b\x32,.perfetto.protos.DebugAnnotation.NestedValueH\x01\x12\x1b\n\x11legacy_json_value\x18\t \x01(\tH\x01\x12\x16\n\x0cstring_value\x18\x06 \x01(\tH\x01\x12\x1a\n\x10string_value_iid\x18\x11 \x01(\x04H\x01\x12\x19\n\x0fproto_type_name\x18\x10 \x01(\tH\x02\x12\x1d\n\x13proto_type_name_iid\x18\r \x01(\x04H\x02\x12\x13\n\x0bproto_value\x18\x0e \x01(\x0c\x12\x36\n\x0c\x64ict_entries\x18\x0b \x03(\x0b\x32 .perfetto.protos.DebugAnnotation\x12\x36\n\x0c\x61rray_values\x18\x0c \x03(\x0b\x32 .perfetto.protos.DebugAnnotation\x1a\xfc\x02\n\x0bNestedValue\x12L\n\x0bnested_type\x18\x01 \x01(\x0e\x32\x37.perfetto.protos.DebugAnnotation.NestedValue.NestedType\x12\x11\n\tdict_keys\x18\x02 \x03(\t\x12\x41\n\x0b\x64ict_values\x18\x03 \x03(\x0b\x32,.perfetto.protos.DebugAnnotation.NestedValue\x12\x42\n\x0c\x61rray_values\x18\x04 \x03(\x0b\x32,.perfetto.protos.DebugAnnotation.NestedValue\x12\x11\n\tint_value\x18\x05 \x01(\x03\x12\x14\n\x0c\x64ouble_value\x18\x06 \x01(\x01\x12\x12\n\nbool_value\x18\x07 \x01(\x08\x12\x14\n\x0cstring_value\x18\x08 \x01(\t\"2\n\nNestedType\x12\x0f\n\x0bUNSPECIFIED\x10\x00\x12\x08\n\x04\x44ICT\x10\x01\x12\t\n\x05\x41RRAY\x10\x02\x42\x0c\n\nname_fieldB\x07\n\x05valueB\x17\n\x15proto_type_descriptor\"0\n\x13\x44\x65\x62ugAnnotationName\x12\x0b\n\x03iid\x18\x01 \x01(\x04\x12\x0c\n\x04name\x18\x02 \x01(\t\"9\n\x1c\x44\x65\x62ugAnnotationValueTypeName\x12\x0b\n\x03iid\x18\x01 \x01(\x04\x12\x0c\n\x04name\x18\x02 \x01(\t\"\x83\x02\n\nLogMessage\x12\x1b\n\x13source_location_iid\x18\x01 \x01(\x04\x12\x10\n\x08\x62ody_iid\x18\x02 \x01(\x04\x12\x32\n\x04prio\x18\x03 \x01(\x0e\x32$.perfetto.protos.LogMessage.Priority\"\x91\x01\n\x08Priority\x12\x14\n\x10PRIO_UNSPECIFIED\x10\x00\x12\x0f\n\x0bPRIO_UNUSED\x10\x01\x12\x10\n\x0cPRIO_VERBOSE\x10\x02\x12\x0e\n\nPRIO_DEBUG\x10\x03\x12\r\n\tPRIO_INFO\x10\x04\x12\r\n\tPRIO_WARN\x10\x05\x12\x0e\n\nPRIO_ERROR\x10\x06\x12\x0e\n\nPRIO_FATAL\x10\x07\"+\n\x0eLogMessageBody\x12\x0b\n\x03iid\x18\x01 \x01(\x04\x12\x0c\n\x04\x62ody\x18\x02 \x01(\t\"M\n\x1aUnsymbolizedSourceLocation\x12\x0b\n\x03iid\x18\x01 \x01(\x04\x12\x12\n\nmapping_id\x18\x02 \x01(\x04\x12\x0e\n\x06rel_pc\x18\x03 \x01(\x04\"\\\n\x0eSourceLocation\x12\x0b\n\x03iid\x18\x01 \x01(\x04\x12\x11\n\tfile_name\x18\x02 \x01(\t\x12\x15\n\rfunction_name\x18\x03 \x01(\t\x12\x13\n\x0bline_number\x18\x04 \x01(\r\"$\n\x15\x43hromeActiveProcesses\x12\x0b\n\x03pid\x18\x01 \x03(\x05\"\xee\x02\n\x1a\x43hromeApplicationStateInfo\x12]\n\x11\x61pplication_state\x18\x01 \x01(\x0e\x32\x42.perfetto.protos.ChromeApplicationStateInfo.ChromeApplicationState\"\xf0\x01\n\x16\x43hromeApplicationState\x12\x1d\n\x19\x41PPLICATION_STATE_UNKNOWN\x10\x00\x12,\n(APPLICATION_STATE_HAS_RUNNING_ACTIVITIES\x10\x01\x12+\n\'APPLICATION_STATE_HAS_PAUSED_ACTIVITIES\x10\x02\x12,\n(APPLICATION_STATE_HAS_STOPPED_ACTIVITIES\x10\x03\x12.\n*APPLICATION_STATE_HAS_DESTROYED_ACTIVITIES\x10\x04\"\xbf\x08\n\x1e\x43hromeCompositorSchedulerState\x12\x44\n\rstate_machine\x18\x01 \x01(\x0b\x32-.perfetto.protos.ChromeCompositorStateMachine\x12$\n\x1cobserving_begin_frame_source\x18\x02 \x01(\x08\x12&\n\x1e\x62\x65gin_impl_frame_deadline_task\x18\x03 \x01(\x08\x12 \n\x18pending_begin_frame_task\x18\x04 \x01(\x08\x12\x33\n+skipped_last_frame_missed_exceeded_deadline\x18\x05 \x01(\x08\x12G\n\rinside_action\x18\x07 \x01(\x0e\x32\x30.perfetto.protos.ChromeCompositorSchedulerAction\x12\x61\n\rdeadline_mode\x18\x08 \x01(\x0e\x32J.perfetto.protos.ChromeCompositorSchedulerState.BeginImplFrameDeadlineMode\x12\x13\n\x0b\x64\x65\x61\x64line_us\x18\t \x01(\x03\x12 \n\x18\x64\x65\x61\x64line_scheduled_at_us\x18\n \x01(\x03\x12\x0e\n\x06now_us\x18\x0b \x01(\x03\x12 \n\x18now_to_deadline_delta_us\x18\x0c \x01(\x03\x12-\n%now_to_deadline_scheduled_at_delta_us\x18\r \x01(\x03\x12\x42\n\x15\x62\x65gin_impl_frame_args\x18\x0e \x01(\x0b\x32#.perfetto.protos.BeginImplFrameArgs\x12L\n\x1a\x62\x65gin_frame_observer_state\x18\x0f \x01(\x0b\x32(.perfetto.protos.BeginFrameObserverState\x12H\n\x18\x62\x65gin_frame_source_state\x18\x10 \x01(\x0b\x32&.perfetto.protos.BeginFrameSourceState\x12K\n\x19\x63ompositor_timing_history\x18\x11 \x01(\x0b\x32(.perfetto.protos.CompositorTimingHistory\"\xbe\x01\n\x1a\x42\x65ginImplFrameDeadlineMode\x12\x1d\n\x19\x44\x45\x41\x44LINE_MODE_UNSPECIFIED\x10\x00\x12\x16\n\x12\x44\x45\x41\x44LINE_MODE_NONE\x10\x01\x12\x1b\n\x17\x44\x45\x41\x44LINE_MODE_IMMEDIATE\x10\x02\x12\x19\n\x15\x44\x45\x41\x44LINE_MODE_REGULAR\x10\x03\x12\x16\n\x12\x44\x45\x41\x44LINE_MODE_LATE\x10\x04\x12\x19\n\x15\x44\x45\x41\x44LINE_MODE_BLOCKED\x10\x05J\x04\x08\x06\x10\x07\"\xfe\x1c\n\x1c\x43hromeCompositorStateMachine\x12M\n\x0bmajor_state\x18\x01 \x01(\x0b\x32\x38.perfetto.protos.ChromeCompositorStateMachine.MajorState\x12M\n\x0bminor_state\x18\x02 \x01(\x0b\x32\x38.perfetto.protos.ChromeCompositorStateMachine.MinorState\x1a\x93\n\n\nMajorState\x12\x45\n\x0bnext_action\x18\x01 \x01(\x0e\x32\x30.perfetto.protos.ChromeCompositorSchedulerAction\x12l\n\x16\x62\x65gin_impl_frame_state\x18\x02 \x01(\x0e\x32L.perfetto.protos.ChromeCompositorStateMachine.MajorState.BeginImplFrameState\x12l\n\x16\x62\x65gin_main_frame_state\x18\x03 \x01(\x0e\x32L.perfetto.protos.ChromeCompositorStateMachine.MajorState.BeginMainFrameState\x12u\n\x1blayer_tree_frame_sink_state\x18\x04 \x01(\x0e\x32P.perfetto.protos.ChromeCompositorStateMachine.MajorState.LayerTreeFrameSinkState\x12p\n\x13\x66orced_redraw_state\x18\x05 \x01(\x0e\x32S.perfetto.protos.ChromeCompositorStateMachine.MajorState.ForcedRedrawOnTimeoutState\"\xa1\x01\n\x13\x42\x65ginImplFrameState\x12 \n\x1c\x42\x45GIN_IMPL_FRAME_UNSPECIFIED\x10\x00\x12\x19\n\x15\x42\x45GIN_IMPL_FRAME_IDLE\x10\x01\x12\'\n#BEGIN_IMPL_FRAME_INSIDE_BEGIN_FRAME\x10\x02\x12$\n BEGIN_IMPL_FRAME_INSIDE_DEADLINE\x10\x03\"\x93\x01\n\x13\x42\x65ginMainFrameState\x12 \n\x1c\x42\x45GIN_MAIN_FRAME_UNSPECIFIED\x10\x00\x12\x19\n\x15\x42\x45GIN_MAIN_FRAME_IDLE\x10\x01\x12\x19\n\x15\x42\x45GIN_MAIN_FRAME_SENT\x10\x02\x12$\n BEGIN_MAIN_FRAME_READY_TO_COMMIT\x10\x03\"\xf4\x01\n\x17LayerTreeFrameSinkState\x12 \n\x1cLAYER_TREE_FRAME_UNSPECIFIED\x10\x00\x12\x19\n\x15LAYER_TREE_FRAME_NONE\x10\x01\x12\x1b\n\x17LAYER_TREE_FRAME_ACTIVE\x10\x02\x12\x1d\n\x19LAYER_TREE_FRAME_CREATING\x10\x03\x12-\n)LAYER_TREE_FRAME_WAITING_FOR_FIRST_COMMIT\x10\x04\x12\x31\n-LAYER_TREE_FRAME_WAITING_FOR_FIRST_ACTIVATION\x10\x05\"\xc7\x01\n\x1a\x46orcedRedrawOnTimeoutState\x12\x1d\n\x19\x46ORCED_REDRAW_UNSPECIFIED\x10\x00\x12\x16\n\x12\x46ORCED_REDRAW_IDLE\x10\x01\x12$\n FORCED_REDRAW_WAITING_FOR_COMMIT\x10\x02\x12(\n$FORCED_REDRAW_WAITING_FOR_ACTIVATION\x10\x03\x12\"\n\x1e\x46ORCED_REDRAW_WAITING_FOR_DRAW\x10\x04\x1a\xa9\x11\n\nMinorState\x12\x14\n\x0c\x63ommit_count\x18\x01 \x01(\x05\x12\x1c\n\x14\x63urrent_frame_number\x18\x02 \x01(\x05\x12*\n\"last_frame_number_submit_performed\x18\x03 \x01(\x05\x12(\n last_frame_number_draw_performed\x18\x04 \x01(\x05\x12/\n\'last_frame_number_begin_main_frame_sent\x18\x05 \x01(\x05\x12\x10\n\x08\x64id_draw\x18\x06 \x01(\x08\x12\x33\n+did_send_begin_main_frame_for_current_frame\x18\x07 \x01(\x08\x12\x36\n.did_notify_begin_main_frame_not_expected_until\x18\x08 \x01(\x08\x12\x35\n-did_notify_begin_main_frame_not_expected_soon\x18\t \x01(\x08\x12+\n#wants_begin_main_frame_not_expected\x18\n \x01(\x08\x12\x1f\n\x17\x64id_commit_during_frame\x18\x0b \x01(\x08\x12,\n$did_invalidate_layer_tree_frame_sink\x18\x0c \x01(\x08\x12)\n!did_perform_impl_side_invalidaion\x18\r \x01(\x08\x12\x19\n\x11\x64id_prepare_tiles\x18\x0e \x01(\x08\x12+\n#consecutive_checkerboard_animations\x18\x0f \x01(\x05\x12\x1d\n\x15pending_submit_frames\x18\x10 \x01(\x05\x12\x38\n0submit_frames_with_current_layer_tree_frame_sink\x18\x11 \x01(\x05\x12\x14\n\x0cneeds_redraw\x18\x12 \x01(\x08\x12\x1b\n\x13needs_prepare_tiles\x18\x13 \x01(\x08\x12\x1e\n\x16needs_begin_main_frame\x18\x14 \x01(\x08\x12\"\n\x1aneeds_one_begin_impl_frame\x18\x15 \x01(\x08\x12\x0f\n\x07visible\x18\x16 \x01(\x08\x12!\n\x19\x62\x65gin_frame_source_paused\x18\x17 \x01(\x08\x12\x10\n\x08\x63\x61n_draw\x18\x18 \x01(\x08\x12\x19\n\x11resourceless_draw\x18\x19 \x01(\x08\x12\x18\n\x10has_pending_tree\x18\x1a \x01(\x08\x12,\n$pending_tree_is_ready_for_activation\x18\x1b \x01(\x08\x12$\n\x1c\x61\x63tive_tree_needs_first_draw\x18\x1c \x01(\x08\x12$\n\x1c\x61\x63tive_tree_is_ready_to_draw\x18\x1d \x01(\x08\x12=\n5did_create_and_initialize_first_layer_tree_frame_sink\x18\x1e \x01(\x08\x12\\\n\rtree_priority\x18\x1f \x01(\x0e\x32\x45.perfetto.protos.ChromeCompositorStateMachine.MinorState.TreePriority\x12i\n\x14scroll_handler_state\x18  \x01(\x0e\x32K.perfetto.protos.ChromeCompositorStateMachine.MinorState.ScrollHandlerState\x12\x35\n-critical_begin_main_frame_to_activate_is_fast\x18! \x01(\x08\x12(\n main_thread_missed_last_deadline\x18\" \x01(\x08\x12 \n\x18video_needs_begin_frames\x18$ \x01(\x08\x12\x1e\n\x16\x64\x65\x66\x65r_begin_main_frame\x18% \x01(\x08\x12\"\n\x1alast_commit_had_no_updates\x18& \x01(\x08\x12\x1e\n\x16\x64id_draw_in_last_frame\x18\' \x01(\x08\x12 \n\x18\x64id_submit_in_last_frame\x18( \x01(\x08\x12$\n\x1cneeds_impl_side_invalidation\x18) \x01(\x08\x12)\n!current_pending_tree_is_impl_side\x18* \x01(\x08\x12+\n#previous_pending_tree_was_impl_side\x18+ \x01(\x08\x12\x35\n-processing_animation_worklets_for_active_tree\x18, \x01(\x08\x12\x36\n.processing_animation_worklets_for_pending_tree\x18- \x01(\x08\x12\x32\n*processing_paint_worklets_for_pending_tree\x18. \x01(\x08\"\xb8\x01\n\x0cTreePriority\x12\x1d\n\x19TREE_PRIORITY_UNSPECIFIED\x10\x00\x12.\n*TREE_PRIORITY_SAME_PRIORITY_FOR_BOTH_TREES\x10\x01\x12+\n\'TREE_PRIORITY_SMOOTHNESS_TAKES_PRIORITY\x10\x02\x12,\n(TREE_PRIORITY_NEW_CONTENT_TAKES_PRIORITY\x10\x03\"\x82\x01\n\x12ScrollHandlerState\x12\x1e\n\x1aSCROLL_HANDLER_UNSPECIFIED\x10\x00\x12!\n\x1dSCROLL_AFFECTS_SCROLL_HANDLER\x10\x01\x12)\n%SCROLL_DOES_NOT_AFFECT_SCROLL_HANDLER\x10\x02J\x04\x08#\x10$\"\xaa\x04\n\x0e\x42\x65ginFrameArgs\x12@\n\x04type\x18\x01 \x01(\x0e\x32\x32.perfetto.protos.BeginFrameArgs.BeginFrameArgsType\x12\x11\n\tsource_id\x18\x02 \x01(\x04\x12\x17\n\x0fsequence_number\x18\x03 \x01(\x04\x12\x15\n\rframe_time_us\x18\x04 \x01(\x03\x12\x13\n\x0b\x64\x65\x61\x64line_us\x18\x05 \x01(\x03\x12\x19\n\x11interval_delta_us\x18\x06 \x01(\x03\x12\x18\n\x10on_critical_path\x18\x07 \x01(\x08\x12\x14\n\x0c\x61nimate_only\x18\x08 \x01(\x08\x12\x1d\n\x13source_location_iid\x18\t \x01(\x04H\x00\x12:\n\x0fsource_location\x18\n \x01(\x0b\x32\x1f.perfetto.protos.SourceLocationH\x00\x12#\n\x1b\x66rames_throttled_since_last\x18\x0c \x01(\x03\"\xa2\x01\n\x12\x42\x65ginFrameArgsType\x12%\n!BEGIN_FRAME_ARGS_TYPE_UNSPECIFIED\x10\x00\x12!\n\x1d\x42\x45GIN_FRAME_ARGS_TYPE_INVALID\x10\x01\x12 \n\x1c\x42\x45GIN_FRAME_ARGS_TYPE_NORMAL\x10\x02\x12 \n\x1c\x42\x45GIN_FRAME_ARGS_TYPE_MISSED\x10\x03\x42\x0e\n\x0c\x63reated_from\"\xc0\x04\n\x12\x42\x65ginImplFrameArgs\x12\x15\n\rupdated_at_us\x18\x01 \x01(\x03\x12\x16\n\x0e\x66inished_at_us\x18\x02 \x01(\x03\x12\x38\n\x05state\x18\x03 \x01(\x0e\x32).perfetto.protos.BeginImplFrameArgs.State\x12\x37\n\x0c\x63urrent_args\x18\x04 \x01(\x0b\x32\x1f.perfetto.protos.BeginFrameArgsH\x00\x12\x34\n\tlast_args\x18\x05 \x01(\x0b\x32\x1f.perfetto.protos.BeginFrameArgsH\x00\x12L\n\x10timestamps_in_us\x18\x06 \x01(\x0b\x32\x32.perfetto.protos.BeginImplFrameArgs.TimestampsInUs\x1a\xc1\x01\n\x0eTimestampsInUs\x12\x16\n\x0einterval_delta\x18\x01 \x01(\x03\x12\x1d\n\x15now_to_deadline_delta\x18\x02 \x01(\x03\x12\x1f\n\x17\x66rame_time_to_now_delta\x18\x03 \x01(\x03\x12$\n\x1c\x66rame_time_to_deadline_delta\x18\x04 \x01(\x03\x12\x0b\n\x03now\x18\x05 \x01(\x03\x12\x12\n\nframe_time\x18\x06 \x01(\x03\x12\x10\n\x08\x64\x65\x61\x64line\x18\x07 \x01(\x03\"8\n\x05State\x12\x18\n\x14\x42\x45GIN_FRAME_FINISHED\x10\x00\x12\x15\n\x11\x42\x45GIN_FRAME_USING\x10\x01\x42\x06\n\x04\x61rgs\"{\n\x17\x42\x65ginFrameObserverState\x12 \n\x18\x64ropped_begin_frame_args\x18\x01 \x01(\x03\x12>\n\x15last_begin_frame_args\x18\x02 \x01(\x0b\x32\x1f.perfetto.protos.BeginFrameArgs\"\x91\x01\n\x15\x42\x65ginFrameSourceState\x12\x11\n\tsource_id\x18\x01 \x01(\r\x12\x0e\n\x06paused\x18\x02 \x01(\x08\x12\x15\n\rnum_observers\x18\x03 \x01(\r\x12>\n\x15last_begin_frame_args\x18\x04 \x01(\x0b\x32\x1f.perfetto.protos.BeginFrameArgs\"\xfc\x02\n\x17\x43ompositorTimingHistory\x12\x39\n1begin_main_frame_queue_critical_estimate_delta_us\x18\x01 \x01(\x03\x12=\n5begin_main_frame_queue_not_critical_estimate_delta_us\x18\x02 \x01(\x03\x12\x43\n;begin_main_frame_start_to_ready_to_commit_estimate_delta_us\x18\x03 \x01(\x03\x12\x35\n-commit_to_ready_to_activate_estimate_delta_us\x18\x04 \x01(\x03\x12\'\n\x1fprepare_tiles_estimate_delta_us\x18\x05 \x01(\x03\x12\"\n\x1a\x61\x63tivate_estimate_delta_us\x18\x06 \x01(\x03\x12\x1e\n\x16\x64raw_estimate_delta_us\x18\x07 \x01(\x03\">\n\x1e\x43hromeContentSettingsEventInfo\x12\x1c\n\x14number_of_exceptions\x18\x01 \x01(\r\"\xe0\x08\n\x13\x43hromeFrameReporter\x12\x39\n\x05state\x18\x01 \x01(\x0e\x32*.perfetto.protos.ChromeFrameReporter.State\x12\x44\n\x06reason\x18\x02 \x01(\x0e\x32\x34.perfetto.protos.ChromeFrameReporter.FrameDropReason\x12\x14\n\x0c\x66rame_source\x18\x03 \x01(\x04\x12\x16\n\x0e\x66rame_sequence\x18\x04 \x01(\x04\x12\x1a\n\x12\x61\x66\x66\x65\x63ts_smoothness\x18\x05 \x01(\x08\x12\x46\n\x0cscroll_state\x18\x06 \x01(\x0e\x32\x30.perfetto.protos.ChromeFrameReporter.ScrollState\x12\x1a\n\x12has_main_animation\x18\x07 \x01(\x08\x12 \n\x18has_compositor_animation\x18\x08 \x01(\x08\x12\x1d\n\x15has_smooth_input_main\x18\t \x01(\x08\x12\x1b\n\x13has_missing_content\x18\n \x01(\x08\x12\x1a\n\x12layer_tree_host_id\x18\x0b \x01(\x04\x12\x18\n\x10has_high_latency\x18\x0c \x01(\x08\x12\x42\n\nframe_type\x18\r \x01(\x0e\x32..perfetto.protos.ChromeFrameReporter.FrameType\x12\'\n\x1fhigh_latency_contribution_stage\x18\x0e \x03(\t\x12#\n\x1b\x63heckerboarded_needs_raster\x18\x0f \x01(\x08\x12#\n\x1b\x63heckerboarded_needs_record\x18\x10 \x01(\x08\x12\x1e\n\x16surface_frame_trace_id\x18\x11 \x01(\x03\x12\x18\n\x10\x64isplay_trace_id\x18\x12 \x01(\x03\"m\n\x05State\x12\x1b\n\x17STATE_NO_UPDATE_DESIRED\x10\x00\x12\x17\n\x13STATE_PRESENTED_ALL\x10\x01\x12\x1b\n\x17STATE_PRESENTED_PARTIAL\x10\x02\x12\x11\n\rSTATE_DROPPED\x10\x03\"~\n\x0f\x46rameDropReason\x12\x16\n\x12REASON_UNSPECIFIED\x10\x00\x12\x1d\n\x19REASON_DISPLAY_COMPOSITOR\x10\x01\x12\x16\n\x12REASON_MAIN_THREAD\x10\x02\x12\x1c\n\x18REASON_CLIENT_COMPOSITOR\x10\x03\"{\n\x0bScrollState\x12\x0f\n\x0bSCROLL_NONE\x10\x00\x12\x16\n\x12SCROLL_MAIN_THREAD\x10\x01\x12\x1c\n\x18SCROLL_COMPOSITOR_THREAD\x10\x02\x12\x11\n\rSCROLL_RASTER\x10\x03\x12\x12\n\x0eSCROLL_UNKNOWN\x10\x04\"%\n\tFrameType\x12\n\n\x06\x46ORKED\x10\x00\x12\x0c\n\x08\x42\x41\x43KFILL\x10\x01:\x02\x18\x01\"\"\n\x12\x43hromeKeyedService\x12\x0c\n\x04name\x18\x01 \x01(\t\"\xf6\r\n\x11\x43hromeLatencyInfo\x12\x10\n\x08trace_id\x18\x01 \x01(\x03\x12\x35\n\x04step\x18\x02 \x01(\x0e\x32\'.perfetto.protos.ChromeLatencyInfo.Step\x12\x1a\n\x12\x66rame_tree_node_id\x18\x03 \x01(\x05\x12H\n\x0e\x63omponent_info\x18\x04 \x03(\x0b\x32\x30.perfetto.protos.ChromeLatencyInfo.ComponentInfo\x12\x14\n\x0cis_coalesced\x18\x05 \x01(\x08\x12\x19\n\x11gesture_scroll_id\x18\x06 \x01(\x03\x12\x10\n\x08touch_id\x18\x07 \x01(\x03\x12@\n\ninput_type\x18\x08 \x01(\x0e\x32,.perfetto.protos.ChromeLatencyInfo.InputType\x1aq\n\rComponentInfo\x12O\n\x0e\x63omponent_type\x18\x01 \x01(\x0e\x32\x37.perfetto.protos.ChromeLatencyInfo.LatencyComponentType\x12\x0f\n\x07time_us\x18\x02 \x01(\x04\"\x92\x03\n\x04Step\x12\x14\n\x10STEP_UNSPECIFIED\x10\x00\x12\x1c\n\x18STEP_SEND_INPUT_EVENT_UI\x10\x03\x12 \n\x1cSTEP_HANDLE_INPUT_EVENT_IMPL\x10\x05\x12(\n$STEP_DID_HANDLE_INPUT_AND_OVERSCROLL\x10\x08\x12 \n\x1cSTEP_HANDLE_INPUT_EVENT_MAIN\x10\x04\x12\"\n\x1eSTEP_MAIN_THREAD_SCROLL_UPDATE\x10\x02\x12\'\n#STEP_HANDLE_INPUT_EVENT_MAIN_COMMIT\x10\x01\x12)\n%STEP_HANDLED_INPUT_EVENT_MAIN_OR_IMPL\x10\t\x12!\n\x1dSTEP_HANDLED_INPUT_EVENT_IMPL\x10\n\x12\x15\n\x11STEP_SWAP_BUFFERS\x10\x06\x12\x16\n\x12STEP_DRAW_AND_SWAP\x10\x07\x12\x1e\n\x1aSTEP_FINISHED_SWAP_BUFFERS\x10\x0b\"\xf5\x05\n\x14LatencyComponentType\x12\x19\n\x15\x43OMPONENT_UNSPECIFIED\x10\x00\x12+\n\'COMPONENT_INPUT_EVENT_LATENCY_BEGIN_RWH\x10\x01\x12\x38\n4COMPONENT_INPUT_EVENT_LATENCY_SCROLL_UPDATE_ORIGINAL\x10\x02\x12>\n:COMPONENT_INPUT_EVENT_LATENCY_FIRST_SCROLL_UPDATE_ORIGINAL\x10\x03\x12*\n&COMPONENT_INPUT_EVENT_LATENCY_ORIGINAL\x10\x04\x12$\n COMPONENT_INPUT_EVENT_LATENCY_UI\x10\x05\x12/\n+COMPONENT_INPUT_EVENT_LATENCY_RENDERER_MAIN\x10\x06\x12:\n6COMPONENT_INPUT_EVENT_LATENCY_RENDERING_SCHEDULED_MAIN\x10\x07\x12:\n6COMPONENT_INPUT_EVENT_LATENCY_RENDERING_SCHEDULED_IMPL\x10\x08\x12:\n6COMPONENT_INPUT_EVENT_LATENCY_SCROLL_UPDATE_LAST_EVENT\x10\t\x12)\n%COMPONENT_INPUT_EVENT_LATENCY_ACK_RWH\x10\n\x12/\n+COMPONENT_INPUT_EVENT_LATENCY_RENDERER_SWAP\x10\x0b\x12/\n+COMPONENT_DISPLAY_COMPOSITOR_RECEIVED_FRAME\x10\x0c\x12)\n%COMPONENT_INPUT_EVENT_GPU_SWAP_BUFFER\x10\r\x12,\n(COMPONENT_INPUT_EVENT_LATENCY_FRAME_SWAP\x10\x0e\"\xac\x01\n\tInputType\x12\x18\n\x14UNSPECIFIED_OR_OTHER\x10\x00\x12\x0f\n\x0bTOUCH_MOVED\x10\x01\x12\x18\n\x14GESTURE_SCROLL_BEGIN\x10\x02\x12\x19\n\x15GESTURE_SCROLL_UPDATE\x10\x03\x12\x16\n\x12GESTURE_SCROLL_END\x10\x04\x12\x0f\n\x0bGESTURE_TAP\x10\x05\x12\x16\n\x12GESTURE_TAP_CANCEL\x10\x06\"\xce\x07\n\x0f\x43hromeLegacyIpc\x12\x44\n\rmessage_class\x18\x01 \x01(\x0e\x32-.perfetto.protos.ChromeLegacyIpc.MessageClass\x12\x14\n\x0cmessage_line\x18\x02 \x01(\r\"\xde\x06\n\x0cMessageClass\x12\x15\n\x11\x43LASS_UNSPECIFIED\x10\x00\x12\x14\n\x10\x43LASS_AUTOMATION\x10\x01\x12\x0f\n\x0b\x43LASS_FRAME\x10\x02\x12\x0e\n\nCLASS_PAGE\x10\x03\x12\x0e\n\nCLASS_VIEW\x10\x04\x12\x10\n\x0c\x43LASS_WIDGET\x10\x05\x12\x0f\n\x0b\x43LASS_INPUT\x10\x06\x12\x0e\n\nCLASS_TEST\x10\x07\x12\x10\n\x0c\x43LASS_WORKER\x10\x08\x12\x0e\n\nCLASS_NACL\x10\t\x12\x15\n\x11\x43LASS_GPU_CHANNEL\x10\n\x12\x0f\n\x0b\x43LASS_MEDIA\x10\x0b\x12\x0f\n\x0b\x43LASS_PPAPI\x10\x0c\x12\x10\n\x0c\x43LASS_CHROME\x10\r\x12\x0e\n\nCLASS_DRAG\x10\x0e\x12\x0f\n\x0b\x43LASS_PRINT\x10\x0f\x12\x13\n\x0f\x43LASS_EXTENSION\x10\x10\x12\x1b\n\x17\x43LASS_TEXT_INPUT_CLIENT\x10\x11\x12\x14\n\x10\x43LASS_BLINK_TEST\x10\x12\x12\x17\n\x13\x43LASS_ACCESSIBILITY\x10\x13\x12\x13\n\x0f\x43LASS_PRERENDER\x10\x14\x12\x14\n\x10\x43LASS_CHROMOTING\x10\x15\x12\x18\n\x14\x43LASS_BROWSER_PLUGIN\x10\x16\x12\x1a\n\x16\x43LASS_ANDROID_WEB_VIEW\x10\x17\x12\x13\n\x0f\x43LASS_NACL_HOST\x10\x18\x12\x19\n\x15\x43LASS_ENCRYPTED_MEDIA\x10\x19\x12\x0e\n\nCLASS_CAST\x10\x1a\x12\x19\n\x15\x43LASS_GIN_JAVA_BRIDGE\x10\x1b\x12!\n\x1d\x43LASS_CHROME_UTILITY_PRINTING\x10\x1c\x12\x13\n\x0f\x43LASS_OZONE_GPU\x10\x1d\x12\x12\n\x0e\x43LASS_WEB_TEST\x10\x1e\x12\x17\n\x13\x43LASS_NETWORK_HINTS\x10\x1f\x12\x1f\n\x1b\x43LASS_EXTENSIONS_GUEST_VIEW\x10 \x12\x14\n\x10\x43LASS_GUEST_VIEW\x10!\x12\x1f\n\x1b\x43LASS_MEDIA_PLAYER_DELEGATE\x10\"\x12\x1a\n\x16\x43LASS_EXTENSION_WORKER\x10#\x12\x1c\n\x18\x43LASS_SUBRESOURCE_FILTER\x10$\x12\x1b\n\x17\x43LASS_UNFREEZABLE_FRAME\x10%\"T\n\x11\x43hromeMessagePump\x12\x1e\n\x16sent_messages_in_queue\x18\x01 \x01(\x08\x12\x1f\n\x17io_handler_location_iid\x18\x02 \x01(\x04\"\xcc\x01\n\x13\x43hromeMojoEventInfo\x12$\n\x1cwatcher_notify_interface_tag\x18\x01 \x01(\t\x12\x10\n\x08ipc_hash\x18\x02 \x01(\r\x12\x1a\n\x12mojo_interface_tag\x18\x03 \x01(\t\x12!\n\x19mojo_interface_method_iid\x18\x04 \x01(\x04\x12\x10\n\x08is_reply\x18\x05 \x01(\x08\x12\x14\n\x0cpayload_size\x18\x06 \x01(\x04\x12\x16\n\x0e\x64\x61ta_num_bytes\x18\x07 \x01(\x04\"~\n\x1c\x43hromeRendererSchedulerState\x12\x32\n\trail_mode\x18\x01 \x01(\x0e\x32\x1f.perfetto.protos.ChromeRAILMode\x12\x17\n\x0fis_backgrounded\x18\x02 \x01(\x08\x12\x11\n\tis_hidden\x18\x03 \x01(\x08\"6\n\x0f\x43hromeUserEvent\x12\x0e\n\x06\x61\x63tion\x18\x01 \x01(\t\x12\x13\n\x0b\x61\x63tion_hash\x18\x02 \x01(\x04\"P\n\x1b\x43hromeWindowHandleEventInfo\x12\x0b\n\x03\x64pi\x18\x01 \x01(\r\x12\x12\n\nmessage_id\x18\x02 \x01(\r\x12\x10\n\x08hwnd_ptr\x18\x03 \x01(\x06\"E\n\nScreenshot\x12\x11\n\tjpg_image\x18\x01 \x01(\x0c\x12\x11\n\tpam_image\x18\x02 \x01(\x0c\x12\x11\n\tppm_image\x18\x03 \x01(\x0c\"(\n\rTaskExecution\x12\x17\n\x0fposted_from_iid\x18\x01 \x01(\x04\"\xf8\x1a\n\nTrackEvent\x12\x15\n\rcategory_iids\x18\x03 \x03(\x04\x12\x12\n\ncategories\x18\x16 \x03(\t\x12\x12\n\x08name_iid\x18\n \x01(\x04H\x00\x12\x0e\n\x04name\x18\x17 \x01(\tH\x00\x12.\n\x04type\x18\t \x01(\x0e\x32 .perfetto.protos.TrackEvent.Type\x12\x12\n\ntrack_uuid\x18\x0b \x01(\x04\x12\x17\n\rcounter_value\x18\x1e \x01(\x03H\x01\x12\x1e\n\x14\x64ouble_counter_value\x18, \x01(\x01H\x01\x12!\n\x19\x65xtra_counter_track_uuids\x18\x1f \x03(\x04\x12\x1c\n\x14\x65xtra_counter_values\x18\x0c \x03(\x03\x12(\n extra_double_counter_track_uuids\x18- \x03(\x04\x12#\n\x1b\x65xtra_double_counter_values\x18. \x03(\x01\x12\x18\n\x0c\x66low_ids_old\x18$ \x03(\x04\x42\x02\x18\x01\x12\x10\n\x08\x66low_ids\x18/ \x03(\x06\x12$\n\x18terminating_flow_ids_old\x18* \x03(\x04\x42\x02\x18\x01\x12\x1c\n\x14terminating_flow_ids\x18\x30 \x03(\x06\x12\x18\n\x0e\x63orrelation_id\x18\x34 \x01(\x04H\x02\x12\x1c\n\x12\x63orrelation_id_str\x18\x35 \x01(\tH\x02\x12 \n\x16\x63orrelation_id_str_iid\x18\x36 \x01(\x04H\x02\x12@\n\tcallstack\x18\x37 \x01(\x0b\x32+.perfetto.protos.TrackEvent.InlineCallstackH\x03\x12\x17\n\rcallstack_iid\x18\x38 \x01(\x04H\x03\x12\x18\n\x10\x63\x61llstack_weight\x18\x39 \x01(\x01\x12;\n\x11\x64\x65\x62ug_annotations\x18\x04 \x03(\x0b\x32 .perfetto.protos.DebugAnnotation\x12\x36\n\x0etask_execution\x18\x05 \x01(\x0b\x32\x1e.perfetto.protos.TaskExecution\x12\x30\n\x0blog_message\x18\x15 \x01(\x0b\x32\x1b.perfetto.protos.LogMessage\x12K\n\x12\x63\x63_scheduler_state\x18\x18 \x01(\x0b\x32/.perfetto.protos.ChromeCompositorSchedulerState\x12;\n\x11\x63hrome_user_event\x18\x19 \x01(\x0b\x32 .perfetto.protos.ChromeUserEvent\x12\x41\n\x14\x63hrome_keyed_service\x18\x1a \x01(\x0b\x32#.perfetto.protos.ChromeKeyedService\x12;\n\x11\x63hrome_legacy_ipc\x18\x1b \x01(\x0b\x32 .perfetto.protos.ChromeLegacyIpc\x12G\n\x17\x63hrome_histogram_sample\x18\x1c \x01(\x0b\x32&.perfetto.protos.ChromeHistogramSample\x12?\n\x13\x63hrome_latency_info\x18\x1d \x01(\x0b\x32\".perfetto.protos.ChromeLatencyInfo\x12G\n\x15\x63hrome_frame_reporter\x18  \x01(\x0b\x32$.perfetto.protos.ChromeFrameReporterB\x02\x18\x01\x12R\n\x1d\x63hrome_application_state_info\x18\' \x01(\x0b\x32+.perfetto.protos.ChromeApplicationStateInfo\x12V\n\x1f\x63hrome_renderer_scheduler_state\x18( \x01(\x0b\x32-.perfetto.protos.ChromeRendererSchedulerState\x12U\n\x1f\x63hrome_window_handle_event_info\x18) \x01(\x0b\x32,.perfetto.protos.ChromeWindowHandleEventInfo\x12[\n\"chrome_content_settings_event_info\x18+ \x01(\x0b\x32/.perfetto.protos.ChromeContentSettingsEventInfo\x12G\n\x17\x63hrome_active_processes\x18\x31 \x01(\x0b\x32&.perfetto.protos.ChromeActiveProcesses\x12/\n\nscreenshot\x18\x32 \x01(\x0b\x32\x1b.perfetto.protos.Screenshot\x12:\n\x0fsource_location\x18! \x01(\x0b\x32\x1f.perfetto.protos.SourceLocationH\x04\x12\x1d\n\x13source_location_iid\x18\" \x01(\x04H\x04\x12?\n\x13\x63hrome_message_pump\x18# \x01(\x0b\x32\".perfetto.protos.ChromeMessagePump\x12\x44\n\x16\x63hrome_mojo_event_info\x18& \x01(\x0b\x32$.perfetto.protos.ChromeMojoEventInfo\x12\x1c\n\x12timestamp_delta_us\x18\x01 \x01(\x03H\x05\x12\x1f\n\x15timestamp_absolute_us\x18\x10 \x01(\x03H\x05\x12\x1e\n\x14thread_time_delta_us\x18\x02 \x01(\x03H\x06\x12!\n\x17thread_time_absolute_us\x18\x11 \x01(\x03H\x06\x12(\n\x1ethread_instruction_count_delta\x18\x08 \x01(\x03H\x07\x12+\n!thread_instruction_count_absolute\x18\x14 \x01(\x03H\x07\x12=\n\x0clegacy_event\x18\x06 \x01(\x0b\x32\'.perfetto.protos.TrackEvent.LegacyEvent\x1a\x9e\x01\n\x0fInlineCallstack\x12\x41\n\x06\x66rames\x18\x01 \x03(\x0b\x32\x31.perfetto.protos.TrackEvent.InlineCallstack.Frame\x1aH\n\x05\x46rame\x12\x15\n\rfunction_name\x18\x01 \x01(\t\x12\x13\n\x0bsource_file\x18\x02 \x01(\t\x12\x13\n\x0bline_number\x18\x03 \x01(\r\x1a\xaa\x05\n\x0bLegacyEvent\x12\x10\n\x08name_iid\x18\x01 \x01(\x04\x12\r\n\x05phase\x18\x02 \x01(\x05\x12\x13\n\x0b\x64uration_us\x18\x03 \x01(\x03\x12\x1a\n\x12thread_duration_us\x18\x04 \x01(\x03\x12 \n\x18thread_instruction_delta\x18\x0f \x01(\x03\x12\x15\n\x0bunscoped_id\x18\x06 \x01(\x04H\x00\x12\x12\n\x08local_id\x18\n \x01(\x04H\x00\x12\x13\n\tglobal_id\x18\x0b \x01(\x04H\x00\x12\x10\n\x08id_scope\x18\x07 \x01(\t\x12\x15\n\ruse_async_tts\x18\t \x01(\x08\x12\x0f\n\x07\x62ind_id\x18\x08 \x01(\x04\x12\x19\n\x11\x62ind_to_enclosing\x18\x0c \x01(\x08\x12M\n\x0e\x66low_direction\x18\r \x01(\x0e\x32\x35.perfetto.protos.TrackEvent.LegacyEvent.FlowDirection\x12V\n\x13instant_event_scope\x18\x0e \x01(\x0e\x32\x39.perfetto.protos.TrackEvent.LegacyEvent.InstantEventScope\x12\x14\n\x0cpid_override\x18\x12 \x01(\x05\x12\x14\n\x0ctid_override\x18\x13 \x01(\x05\"P\n\rFlowDirection\x12\x14\n\x10\x46LOW_UNSPECIFIED\x10\x00\x12\x0b\n\x07\x46LOW_IN\x10\x01\x12\x0c\n\x08\x46LOW_OUT\x10\x02\x12\x0e\n\nFLOW_INOUT\x10\x03\"a\n\x11InstantEventScope\x12\x15\n\x11SCOPE_UNSPECIFIED\x10\x00\x12\x10\n\x0cSCOPE_GLOBAL\x10\x01\x12\x11\n\rSCOPE_PROCESS\x10\x02\x12\x10\n\x0cSCOPE_THREAD\x10\x03\x42\x04\n\x02idJ\x04\x08\x05\x10\x06\"z\n\x04Type\x12\x14\n\x10TYPE_UNSPECIFIED\x10\x00\x12\x14\n\x10TYPE_SLICE_BEGIN\x10\x01\x12\x12\n\x0eTYPE_SLICE_END\x10\x02\x12\x10\n\x0cTYPE_INSTANT\x10\x03\x12\x10\n\x0cTYPE_COUNTER\x10\x04\x12\x0e\n\nTYPE_STATE\x10\x05*\x06\x08\xe8\x07\x10\x90NB\x0c\n\nname_fieldB\x15\n\x13\x63ounter_value_fieldB\x16\n\x14\x63orrelation_id_fieldB\x11\n\x0f\x63\x61llstack_fieldB\x17\n\x15source_location_fieldB\x0b\n\ttimestampB\r\n\x0bthread_timeB\x1a\n\x18thread_instruction_countJ\x04\x08\x33\x10\x34\"u\n\x12TrackEventDefaults\x12\x12\n\ntrack_uuid\x18\x0b \x01(\x04\x12!\n\x19\x65xtra_counter_track_uuids\x18\x1f \x03(\x04\x12(\n extra_double_counter_track_uuids\x18- \x03(\x04\"*\n\rEventCategory\x12\x0b\n\x03iid\x18\x01 \x01(\x04\x12\x0c\n\x04name\x18\x02 \x01(\t\"&\n\tEventName\x12\x0b\n\x03iid\x18\x01 \x01(\x04\x12\x0c\n\x04name\x18\x02 \x01(\t\"\x87\x11\n\x0cInternedData\x12\x38\n\x10\x65vent_categories\x18\x01 \x03(\x0b\x32\x1e.perfetto.protos.EventCategory\x12/\n\x0b\x65vent_names\x18\x02 \x03(\x0b\x32\x1a.perfetto.protos.EventName\x12\x44\n\x16\x64\x65\x62ug_annotation_names\x18\x03 \x03(\x0b\x32$.perfetto.protos.DebugAnnotationName\x12X\n!debug_annotation_value_type_names\x18\x1b \x03(\x0b\x32-.perfetto.protos.DebugAnnotationValueTypeName\x12G\n\x1e\x64\x65\x62ug_annotation_string_values\x18\x1d \x03(\x0b\x32\x1f.perfetto.protos.InternedString\x12;\n\x12\x63orrelation_id_str\x18+ \x03(\x0b\x32\x1f.perfetto.protos.InternedString\x12@\n\x17track_dimension_strings\x18\x34 \x03(\x0b\x32\x1f.perfetto.protos.InternedString\x12\x32\n\tbuild_ids\x18\x10 \x03(\x0b\x32\x1f.perfetto.protos.InternedString\x12\x36\n\rmapping_paths\x18\x11 \x03(\x0b\x32\x1f.perfetto.protos.InternedString\x12\x35\n\x0csource_paths\x18\x12 \x03(\x0b\x32\x1f.perfetto.protos.InternedString\x12\x37\n\x0e\x66unction_names\x18\x05 \x03(\x0b\x32\x1f.perfetto.protos.InternedString\x12*\n\x08mappings\x18\x13 \x03(\x0b\x32\x18.perfetto.protos.Mapping\x12&\n\x06\x66rames\x18\x06 \x03(\x0b\x32\x16.perfetto.protos.Frame\x12.\n\ncallstacks\x18\x07 \x03(\x0b\x32\x1a.perfetto.protos.Callstack\x12L\n\x1astack_sample_task_contexts\x18\x30 \x03(\x0b\x32(.perfetto.protos.StackSample.TaskContext\x12V\n\x1fstack_sample_execution_contexts\x18\x31 \x03(\x0b\x32-.perfetto.protos.StackSample.ExecutionContext\x12X\n stack_sample_counter_descriptors\x18\x32 \x03(\x0b\x32..perfetto.protos.StackSample.CounterDescriptor\x12\x63\n&stack_sample_async_context_descriptors\x18\x33 \x03(\x0b\x32\x33.perfetto.protos.StackSample.AsyncContextDescriptor\x12\x39\n\x10source_locations\x18\x04 \x03(\x0b\x32\x1f.perfetto.protos.SourceLocation\x12R\n\x1dunsymbolized_source_locations\x18\x1c \x03(\x0b\x32+.perfetto.protos.UnsymbolizedSourceLocation\x12\x39\n\x10log_message_body\x18\x14 \x03(\x0b\x32\x1f.perfetto.protos.LogMessageBody\x12\x37\n\x0fhistogram_names\x18\x19 \x03(\x0b\x32\x1e.perfetto.protos.HistogramName\x12;\n\x12vulkan_memory_keys\x18\x16 \x03(\x0b\x32\x1f.perfetto.protos.InternedString\x12\x43\n\x11graphics_contexts\x18\x17 \x03(\x0b\x32(.perfetto.protos.InternedGraphicsContext\x12P\n\x12gpu_specifications\x18\x18 \x03(\x0b\x32\x34.perfetto.protos.InternedGpuRenderStageSpecification\x12N\n\x17gpu_counter_descriptors\x18/ \x03(\x0b\x32-.perfetto.protos.InternedGpuCounterDescriptor\x12\x37\n\x0ekernel_symbols\x18\x1a \x03(\x0b\x32\x1f.perfetto.protos.InternedString\x12>\n\x13v8_js_function_name\x18\x1f \x03(\x0b\x32!.perfetto.protos.InternedV8String\x12=\n\x0ev8_js_function\x18  \x03(\x0b\x32%.perfetto.protos.InternedV8JsFunction\x12\x39\n\x0cv8_js_script\x18! \x03(\x0b\x32#.perfetto.protos.InternedV8JsScript\x12=\n\x0ev8_wasm_script\x18\" \x03(\x0b\x32%.perfetto.protos.InternedV8WasmScript\x12\x36\n\nv8_isolate\x18# \x03(\x0b\x32\".perfetto.protos.InternedV8Isolate*\x04\x08\x1e\x10\x1f*\x04\x08$\x10%*\x04\x08%\x10&*\x04\x08&\x10\'*\x04\x08\'\x10(*\x04\x08(\x10)*\x04\x08)\x10**\x04\x08*\x10+*\x04\x08,\x10-*\x04\x08-\x10.*\x04\x08.\x10/*\x06\x08\xe8\x07\x10\x90NJ\x04\x08\x15\x10\x16\"\xf3\x01\n\x14SystemdJournaldEvent\x12\x0b\n\x03pid\x18\x01 \x01(\r\x12\x0b\n\x03tid\x18\x02 \x01(\r\x12\x0b\n\x03uid\x18\x03 \x01(\r\x12\x0b\n\x03gid\x18\x04 \x01(\r\x12\x0c\n\x04prio\x18\x05 \x01(\r\x12\x0b\n\x03tag\x18\x06 \x01(\t\x12\x0f\n\x07message\x18\x07 \x01(\t\x12\x0c\n\x04\x63omm\x18\x08 \x01(\t\x12\x0b\n\x03\x65xe\x18\t \x01(\t\x12\x14\n\x0csystemd_unit\x18\n \x01(\t\x12\x10\n\x08hostname\x18\x0b \x01(\t\x12\x11\n\ttransport\x18\x0c \x01(\t\x12\x11\n\tnum_total\x18\x14 \x01(\x04\x12\x12\n\nnum_failed\x18\x15 \x01(\x04\"\xf0\x07\n\x15MemoryTrackerSnapshot\x12\x16\n\x0eglobal_dump_id\x18\x01 \x01(\x04\x12M\n\x0flevel_of_detail\x18\x02 \x01(\x0e\x32\x34.perfetto.protos.MemoryTrackerSnapshot.LevelOfDetail\x12T\n\x14process_memory_dumps\x18\x03 \x03(\x0b\x32\x36.perfetto.protos.MemoryTrackerSnapshot.ProcessSnapshot\x1a\xce\x05\n\x0fProcessSnapshot\x12\x0b\n\x03pid\x18\x01 \x01(\x05\x12Z\n\x0f\x61llocator_dumps\x18\x02 \x03(\x0b\x32\x41.perfetto.protos.MemoryTrackerSnapshot.ProcessSnapshot.MemoryNode\x12W\n\x0cmemory_edges\x18\x03 \x03(\x0b\x32\x41.perfetto.protos.MemoryTrackerSnapshot.ProcessSnapshot.MemoryEdge\x1a\x9b\x03\n\nMemoryNode\x12\n\n\x02id\x18\x01 \x01(\x04\x12\x15\n\rabsolute_name\x18\x02 \x01(\t\x12\x0c\n\x04weak\x18\x03 \x01(\x08\x12\x12\n\nsize_bytes\x18\x04 \x01(\x04\x12\x62\n\x07\x65ntries\x18\x05 \x03(\x0b\x32Q.perfetto.protos.MemoryTrackerSnapshot.ProcessSnapshot.MemoryNode.MemoryNodeEntry\x1a\xe3\x01\n\x0fMemoryNodeEntry\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x66\n\x05units\x18\x02 \x01(\x0e\x32W.perfetto.protos.MemoryTrackerSnapshot.ProcessSnapshot.MemoryNode.MemoryNodeEntry.Units\x12\x14\n\x0cvalue_uint64\x18\x03 \x01(\x04\x12\x14\n\x0cvalue_string\x18\x04 \x01(\t\".\n\x05Units\x12\x0f\n\x0bUNSPECIFIED\x10\x00\x12\t\n\x05\x42YTES\x10\x01\x12\t\n\x05\x43OUNT\x10\x02\x1a[\n\nMemoryEdge\x12\x11\n\tsource_id\x18\x01 \x01(\x04\x12\x11\n\ttarget_id\x18\x02 \x01(\x04\x12\x12\n\nimportance\x18\x03 \x01(\r\x12\x13\n\x0boverridable\x18\x04 \x01(\x08\"I\n\rLevelOfDetail\x12\x0f\n\x0b\x44\x45TAIL_FULL\x10\x00\x12\x10\n\x0c\x44\x45TAIL_LIGHT\x10\x01\x12\x15\n\x11\x44\x45TAIL_BACKGROUND\x10\x02\"\xd1\x02\n\x16\x43oncurrentSessionEvent\x12<\n\x05state\x18\x01 \x01(\x0e\x32-.perfetto.protos.ConcurrentSessionEvent.State\x12\x14\n\x0csession_name\x18\x02 \x01(\t\x12\x12\n\nsession_id\x18\x03 \x01(\x04\x12\x14\n\x0c\x63onsumer_uid\x18\x04 \x01(\x05\x12\x18\n\x10num_data_sources\x18\x05 \x01(\r\"\x9e\x01\n\x05State\x12\x15\n\x11STATE_UNSPECIFIED\x10\x00\x12\x12\n\x0eSTATE_DISABLED\x10\x01\x12\x14\n\x10STATE_CONFIGURED\x10\x02\x12\x11\n\rSTATE_STARTED\x10\x03\x12%\n!STATE_DISABLING_WAITING_STOP_ACKS\x10\x04\x12\x1a\n\x16STATE_CLONED_READ_ONLY\x10\x05\"\xa1\x04\n\x11PerfettoMetatrace\x12\x12\n\x08\x65vent_id\x18\x01 \x01(\rH\x00\x12\x14\n\ncounter_id\x18\x02 \x01(\rH\x00\x12\x14\n\nevent_name\x18\x08 \x01(\tH\x00\x12\x18\n\x0e\x65vent_name_iid\x18\x0b \x01(\x04H\x00\x12\x16\n\x0c\x63ounter_name\x18\t \x01(\tH\x00\x12\x19\n\x11\x65vent_duration_ns\x18\x03 \x01(\x04\x12\x15\n\rcounter_value\x18\x04 \x01(\x05\x12\x11\n\tthread_id\x18\x05 \x01(\r\x12\x14\n\x0chas_overruns\x18\x06 \x01(\x08\x12\x34\n\x04\x61rgs\x18\x07 \x03(\x0b\x32&.perfetto.protos.PerfettoMetatrace.Arg\x12K\n\x10interned_strings\x18\n \x03(\x0b\x32\x31.perfetto.protos.PerfettoMetatrace.InternedString\x1a\x7f\n\x03\x41rg\x12\r\n\x03key\x18\x01 \x01(\tH\x00\x12\x11\n\x07key_iid\x18\x03 \x01(\x04H\x00\x12\x0f\n\x05value\x18\x02 \x01(\tH\x01\x12\x13\n\tvalue_iid\x18\x04 \x01(\x04H\x01\x42\x15\n\x13key_or_interned_keyB\x19\n\x17value_or_interned_value\x1a,\n\x0eInternedString\x12\x0b\n\x03iid\x18\x01 \x01(\x04\x12\r\n\x05value\x18\x02 \x01(\tB\r\n\x0brecord_type\"\xc0\x01\n\x0fTraceProvenance\x12\x38\n\x07\x62uffers\x18\x02 \x03(\x0b\x32\'.perfetto.protos.TraceProvenance.Buffer\x1a+\n\x08Sequence\x12\n\n\x02id\x18\x01 \x01(\r\x12\x13\n\x0bproducer_id\x18\x02 \x01(\x05\x1a\x46\n\x06\x42uffer\x12<\n\tsequences\x18\x01 \x03(\x0b\x32).perfetto.protos.TraceProvenance.Sequence\"\x8a\x05\n\x13TracingServiceEvent\x12\x19\n\x0ftracing_started\x18\x02 \x01(\x08H\x00\x12\"\n\x18\x61ll_data_sources_started\x18\x01 \x01(\x08H\x00\x12\x17\n\rflush_started\x18\t \x01(\x08H\x00\x12\"\n\x18\x61ll_data_sources_flushed\x18\x03 \x01(\x08H\x00\x12(\n\x1eread_tracing_buffers_completed\x18\x04 \x01(\x08H\x00\x12\x1a\n\x10tracing_disabled\x18\x05 \x01(\x08H\x00\x12\x1e\n\x14seized_for_bugreport\x18\x06 \x01(\x08H\x00\x12V\n\x1aslow_starting_data_sources\x18\x07 \x01(\x0b\x32\x30.perfetto.protos.TracingServiceEvent.DataSourcesH\x00\x12X\n\x1clast_flush_slow_data_sources\x18\x08 \x01(\x0b\x32\x30.perfetto.protos.TracingServiceEvent.DataSourcesH\x00\x12\x17\n\rclone_started\x18\n \x01(\x08H\x00\x12\x17\n\rbuffer_cloned\x18\x0b \x01(\rH\x00\x1a\x9e\x01\n\x0b\x44\x61taSources\x12P\n\x0b\x64\x61ta_source\x18\x01 \x03(\x0b\x32;.perfetto.protos.TracingServiceEvent.DataSources.DataSource\x1a=\n\nDataSource\x12\x15\n\rproducer_name\x18\x01 \x01(\t\x12\x18\n\x10\x64\x61ta_source_name\x18\x02 \x01(\tB\x0c\n\nevent_type\"\xc6\x04\n\"ExperimentalTracingV2ProducerStats\x12\x13\n\x0bproducer_id\x18\x01 \x01(\r\x12\x0b\n\x03pid\x18\x02 \x01(\x05\x12\x15\n\rproducer_name\x18\x03 \x01(\t\x12\x18\n\x10\x63hunk_size_bytes\x18\x04 \x01(\r\x12\x12\n\nnum_chunks\x18\x05 \x01(\r\x12\x13\n\x0b\x63hunks_read\x18\x06 \x01(\x04\x12\x12\n\nbytes_read\x18\x07 \x01(\x04\x12\x18\n\x10\x64\x61ta_loss_chunks\x18\x08 \x01(\x04\x12\x18\n\x10malformed_chunks\x18\t \x01(\x04\x12!\n\x19unsupported_format_chunks\x18\n \x01(\x04\x12\x1d\n\x15invalid_writer_chunks\x18\x0b \x01(\x04\x12\"\n\x1ainvalid_destination_chunks\x18\x0c \x01(\x04\x12$\n\x1ctrace_buffer_rejected_chunks\x18\r \x01(\x04\x12\x18\n\x10rewrite_requests\x18\x0e \x01(\x04\x12\x19\n\x11positions_skipped\x18\x0f \x01(\x04\x12\x14\n\x0c\x64rain_passes\x18\x10 \x01(\x04\x12\x15\n\rdrain_time_ns\x18\x11 \x01(\x04\x12\x19\n\x11\x64rain_max_time_ns\x18\x12 \x01(\x04\x12\x1e\n\x16writer_dropped_packets\x18\x13 \x01(\x04\x12\x15\n\rwriter_stalls\x18\x14 \x01(\x04\x12\x1c\n\x14writer_stall_time_ms\x18\x15 \x01(\x04\"`\n\x15\x41ndroidEnergyConsumer\x12\x1a\n\x12\x65nergy_consumer_id\x18\x01 \x01(\x05\x12\x0f\n\x07ordinal\x18\x02 \x01(\x05\x12\x0c\n\x04type\x18\x03 \x01(\t\x12\x0c\n\x04name\x18\x04 \x01(\t\"c\n\x1f\x41ndroidEnergyConsumerDescriptor\x12@\n\x10\x65nergy_consumers\x18\x01 \x03(\x0b\x32&.perfetto.protos.AndroidEnergyConsumer\"\xc0\x02\n AndroidEnergyEstimationBreakdown\x12T\n\x1a\x65nergy_consumer_descriptor\x18\x01 \x01(\x0b\x32\x30.perfetto.protos.AndroidEnergyConsumerDescriptor\x12\x1a\n\x12\x65nergy_consumer_id\x18\x02 \x01(\x05\x12\x12\n\nenergy_uws\x18\x03 \x01(\x03\x12_\n\x11per_uid_breakdown\x18\x04 \x03(\x0b\x32\x44.perfetto.protos.AndroidEnergyEstimationBreakdown.EnergyUidBreakdown\x1a\x35\n\x12\x45nergyUidBreakdown\x12\x0b\n\x03uid\x18\x01 \x01(\x05\x12\x12\n\nenergy_uws\x18\x02 \x01(\x03\"\xbb\x03\n\x14\x45ntityStateResidency\x12R\n\x12power_entity_state\x18\x01 \x03(\x0b\x32\x36.perfetto.protos.EntityStateResidency.PowerEntityState\x12G\n\tresidency\x18\x02 \x03(\x0b\x32\x34.perfetto.protos.EntityStateResidency.StateResidency\x1a\x66\n\x10PowerEntityState\x12\x14\n\x0c\x65ntity_index\x18\x01 \x01(\x05\x12\x13\n\x0bstate_index\x18\x02 \x01(\x05\x12\x13\n\x0b\x65ntity_name\x18\x03 \x01(\t\x12\x12\n\nstate_name\x18\x04 \x01(\t\x1a\x9d\x01\n\x0eStateResidency\x12\x14\n\x0c\x65ntity_index\x18\x01 \x01(\x05\x12\x13\n\x0bstate_index\x18\x02 \x01(\x05\x12\x1e\n\x16total_time_in_state_ms\x18\x03 \x01(\x04\x12\x1f\n\x17total_state_entry_count\x18\x04 \x01(\x04\x12\x1f\n\x17last_entry_timestamp_ms\x18\x05 \x01(\x04\"\xb1\x01\n\x0f\x42\x61tteryCounters\x12\x1a\n\x12\x63harge_counter_uah\x18\x01 \x01(\x03\x12\x18\n\x10\x63\x61pacity_percent\x18\x02 \x01(\x02\x12\x12\n\ncurrent_ua\x18\x03 \x01(\x03\x12\x16\n\x0e\x63urrent_avg_ua\x18\x04 \x01(\x03\x12\x0c\n\x04name\x18\x05 \x01(\t\x12\x1a\n\x12\x65nergy_counter_uwh\x18\x06 \x01(\x03\x12\x12\n\nvoltage_uv\x18\x07 \x01(\x03\"\xc7\x02\n\nPowerRails\x12\x43\n\x0frail_descriptor\x18\x01 \x03(\x0b\x32*.perfetto.protos.PowerRails.RailDescriptor\x12;\n\x0b\x65nergy_data\x18\x02 \x03(\x0b\x32&.perfetto.protos.PowerRails.EnergyData\x12\x14\n\x0csession_uuid\x18\x03 \x01(\x04\x1a^\n\x0eRailDescriptor\x12\r\n\x05index\x18\x01 \x01(\r\x12\x11\n\trail_name\x18\x02 \x01(\t\x12\x13\n\x0bsubsys_name\x18\x03 \x01(\t\x12\x15\n\rsampling_rate\x18\x04 \x01(\r\x1a\x41\n\nEnergyData\x12\r\n\x05index\x18\x01 \x01(\r\x12\x14\n\x0ctimestamp_ms\x18\x02 \x01(\x04\x12\x0e\n\x06\x65nergy\x18\x03 \x01(\x04\"J\n\tJavaFrame\x12\x13\n\x0bmethod_name\x18\x01 \x01(\t\x12\x13\n\x0bsource_file\x18\x02 \x01(\t\x12\x13\n\x0bline_number\x18\x03 \x01(\x05\"7\n\tJavaStack\x12*\n\x06\x66rames\x18\x01 \x03(\x0b\x32\x1a.perfetto.protos.JavaFrame\"\x89\x02\n\x12\x41rtProcessMetadata\x12\x0b\n\x03pid\x18\x01 \x01(\x05\x12\x0b\n\x03uid\x18\x02 \x01(\x05\x12\x14\n\x0cprocess_name\x18\x03 \x01(\t\x12\x14\n\x0cpackage_name\x18\x04 \x01(\t\x12\x1b\n\x13oom_allocation_size\x18\x05 \x01(\x04\x12\x1c\n\x14oom_total_bytes_free\x18\x06 \x01(\x04\x12 \n\x18oom_free_bytes_until_oom\x18\x07 \x01(\x04\x12\x39\n\x15oom_thread_java_stack\x18\x08 \x01(\x0b\x32\x1a.perfetto.protos.JavaStack\x12\x15\n\room_error_msg\x18\t \x01(\t\"\xb6\x01\n\x10ObfuscatedMember\x12\x17\n\x0fobfuscated_name\x18\x01 \x01(\t\x12\x19\n\x11\x64\x65obfuscated_name\x18\x02 \x01(\t\x12\x1d\n\x15obfuscated_line_start\x18\x03 \x01(\r\x12\x1b\n\x13obfuscated_line_end\x18\x04 \x01(\r\x12\x19\n\x11source_line_start\x18\x05 \x01(\r\x12\x17\n\x0fsource_line_end\x18\x06 \x01(\r\"\x97\x04\n\x0fObfuscatedClass\x12\x17\n\x0fobfuscated_name\x18\x01 \x01(\t\x12\x19\n\x11\x64\x65obfuscated_name\x18\x02 \x01(\t\x12=\n\x12obfuscated_members\x18\x03 \x03(\x0b\x32!.perfetto.protos.ObfuscatedMember\x12=\n\x12obfuscated_methods\x18\x04 \x03(\x0b\x32!.perfetto.protos.ObfuscatedMember\x12\x46\n\x0emerged_classes\x18\x05 \x01(\x0b\x32..perfetto.protos.ObfuscatedClass.MergedClasses\x1au\n\x0bMergedClass\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x10\n\x08\x63lass_id\x18\x02 \x01(\x05\x12\x46\n\x0emerged_classes\x18\x03 \x01(\x0b\x32..perfetto.protos.ObfuscatedClass.MergedClasses\x1a\x92\x01\n\rMergedClasses\x12\x1b\n\x13\x63lass_id_field_name\x18\x01 \x01(\t\x12\x44\n\x0emerged_classes\x18\x02 \x03(\x0b\x32,.perfetto.protos.ObfuscatedClass.MergedClass\x12\x1e\n\x16unknown_merged_classes\x18\x03 \x01(\x08\"\x80\x01\n\x14\x44\x65obfuscationMapping\x12\x14\n\x0cpackage_name\x18\x01 \x01(\t\x12\x14\n\x0cversion_code\x18\x02 \x01(\x03\x12<\n\x12obfuscated_classes\x18\x03 \x03(\x0b\x32 .perfetto.protos.ObfuscatedClass\"\xd5\x0b\n\rProfilePacket\x12\x30\n\x07strings\x18\x01 \x03(\x0b\x32\x1f.perfetto.protos.InternedString\x12*\n\x08mappings\x18\x04 \x03(\x0b\x32\x18.perfetto.protos.Mapping\x12&\n\x06\x66rames\x18\x02 \x03(\x0b\x32\x16.perfetto.protos.Frame\x12.\n\ncallstacks\x18\x03 \x03(\x0b\x32\x1a.perfetto.protos.Callstack\x12H\n\rprocess_dumps\x18\x05 \x03(\x0b\x32\x31.perfetto.protos.ProfilePacket.ProcessHeapSamples\x12\x11\n\tcontinued\x18\x06 \x01(\x08\x12\r\n\x05index\x18\x07 \x01(\x04\x1a\xba\x01\n\nHeapSample\x12\x14\n\x0c\x63\x61llstack_id\x18\x01 \x01(\x04\x12\x16\n\x0eself_allocated\x18\x02 \x01(\x04\x12\x12\n\nself_freed\x18\x03 \x01(\x04\x12\x10\n\x08self_max\x18\x08 \x01(\x04\x12\x16\n\x0eself_max_count\x18\t \x01(\x04\x12\x11\n\ttimestamp\x18\x04 \x01(\x04\x12\x13\n\x0b\x61lloc_count\x18\x05 \x01(\x04\x12\x12\n\nfree_count\x18\x06 \x01(\x04J\x04\x08\x07\x10\x08\x1a\x8f\x01\n\tHistogram\x12@\n\x07\x62uckets\x18\x01 \x03(\x0b\x32/.perfetto.protos.ProfilePacket.Histogram.Bucket\x1a@\n\x06\x42ucket\x12\x13\n\x0bupper_limit\x18\x01 \x01(\x04\x12\x12\n\nmax_bucket\x18\x02 \x01(\x08\x12\r\n\x05\x63ount\x18\x03 \x01(\x04\x1a\xde\x01\n\x0cProcessStats\x12\x18\n\x10unwinding_errors\x18\x01 \x01(\x04\x12\x14\n\x0cheap_samples\x18\x02 \x01(\x04\x12\x14\n\x0cmap_reparses\x18\x03 \x01(\x04\x12\x43\n\x11unwinding_time_us\x18\x04 \x01(\x0b\x32(.perfetto.protos.ProfilePacket.Histogram\x12\x1f\n\x17total_unwinding_time_us\x18\x05 \x01(\x04\x12\"\n\x1a\x63lient_spinlock_blocked_us\x18\x06 \x01(\x04\x1a\xf1\x04\n\x12ProcessHeapSamples\x12\x0b\n\x03pid\x18\x01 \x01(\x04\x12\x14\n\x0c\x66rom_startup\x18\x03 \x01(\x08\x12\x1b\n\x13rejected_concurrent\x18\x04 \x01(\x08\x12\x14\n\x0c\x64isconnected\x18\x06 \x01(\x08\x12\x16\n\x0e\x62uffer_overran\x18\x07 \x01(\x08\x12S\n\x0c\x63lient_error\x18\x0e \x01(\x0e\x32=.perfetto.protos.ProfilePacket.ProcessHeapSamples.ClientError\x12\x18\n\x10\x62uffer_corrupted\x18\x08 \x01(\x08\x12\x15\n\rhit_guardrail\x18\n \x01(\x08\x12\x11\n\theap_name\x18\x0b \x01(\t\x12\x1f\n\x17sampling_interval_bytes\x18\x0c \x01(\x04\x12$\n\x1corig_sampling_interval_bytes\x18\r \x01(\x04\x12\x11\n\ttimestamp\x18\t \x01(\x04\x12\x17\n\x0fstart_timestamp\x18\x0f \x01(\x04\x12:\n\x05stats\x18\x05 \x01(\x0b\x32+.perfetto.protos.ProfilePacket.ProcessStats\x12:\n\x07samples\x18\x02 \x03(\x0b\x32).perfetto.protos.ProfilePacket.HeapSample\"i\n\x0b\x43lientError\x12\x15\n\x11\x43LIENT_ERROR_NONE\x10\x00\x12\x1c\n\x18\x43LIENT_ERROR_HIT_TIMEOUT\x10\x01\x12%\n!CLIENT_ERROR_INVALID_STACK_BOUNDS\x10\x02\"\x9d\x01\n\x13StreamingAllocation\x12\x0f\n\x07\x61\x64\x64ress\x18\x01 \x03(\x04\x12\x0c\n\x04size\x18\x02 \x03(\x04\x12\x13\n\x0bsample_size\x18\x03 \x03(\x04\x12(\n clock_monotonic_coarse_timestamp\x18\x04 \x03(\x04\x12\x0f\n\x07heap_id\x18\x05 \x03(\r\x12\x17\n\x0fsequence_number\x18\x06 \x03(\x04\"J\n\rStreamingFree\x12\x0f\n\x07\x61\x64\x64ress\x18\x01 \x03(\x04\x12\x0f\n\x07heap_id\x18\x02 \x03(\r\x12\x17\n\x0fsequence_number\x18\x03 \x03(\x04\"e\n\x16StreamingProfilePacket\x12\x15\n\rcallstack_iid\x18\x01 \x03(\x04\x12\x1a\n\x12timestamp_delta_us\x18\x02 \x03(\x03\x12\x18\n\x10process_priority\x18\x03 \x01(\x05\"\x90\x05\n\tProfiling\"|\n\x07\x43puMode\x12\x10\n\x0cMODE_UNKNOWN\x10\x00\x12\x0f\n\x0bMODE_KERNEL\x10\x01\x12\r\n\tMODE_USER\x10\x02\x12\x13\n\x0fMODE_HYPERVISOR\x10\x03\x12\x15\n\x11MODE_GUEST_KERNEL\x10\x04\x12\x13\n\x0fMODE_GUEST_USER\x10\x05\"\x84\x04\n\x10StackUnwindError\x12\x18\n\x14UNWIND_ERROR_UNKNOWN\x10\x00\x12\x15\n\x11UNWIND_ERROR_NONE\x10\x01\x12\x1f\n\x1bUNWIND_ERROR_MEMORY_INVALID\x10\x02\x12\x1c\n\x18UNWIND_ERROR_UNWIND_INFO\x10\x03\x12\x1c\n\x18UNWIND_ERROR_UNSUPPORTED\x10\x04\x12\x1c\n\x18UNWIND_ERROR_INVALID_MAP\x10\x05\x12$\n UNWIND_ERROR_MAX_FRAMES_EXCEEDED\x10\x06\x12\x1f\n\x1bUNWIND_ERROR_REPEATED_FRAME\x10\x07\x12\x1c\n\x18UNWIND_ERROR_INVALID_ELF\x10\x08\x12\x1c\n\x18UNWIND_ERROR_SYSTEM_CALL\x10\t\x12\x1f\n\x1bUNWIND_ERROR_THREAD_TIMEOUT\x10\n\x12&\n\"UNWIND_ERROR_THREAD_DOES_NOT_EXIST\x10\x0b\x12\x19\n\x15UNWIND_ERROR_BAD_ARCH\x10\x0c\x12\x1b\n\x17UNWIND_ERROR_MAPS_PARSE\x10\r\x12\"\n\x1eUNWIND_ERROR_INVALID_PARAMETER\x10\x0e\x12\x1c\n\x18UNWIND_ERROR_PTRACE_CALL\x10\x0f\"\xef\x06\n\nPerfSample\x12\x0b\n\x03\x63pu\x18\x01 \x01(\r\x12\x0b\n\x03pid\x18\x02 \x01(\r\x12\x0b\n\x03tid\x18\x03 \x01(\r\x12\x34\n\x08\x63pu_mode\x18\x05 \x01(\x0e\x32\".perfetto.protos.Profiling.CpuMode\x12\x16\n\x0etimebase_count\x18\x06 \x01(\x04\x12\x17\n\x0f\x66ollower_counts\x18\x07 \x03(\x04\x12\x15\n\rcallstack_iid\x18\x04 \x01(\x04\x12\x43\n\x0cunwind_error\x18\x10 \x01(\x0e\x32+.perfetto.protos.Profiling.StackUnwindErrorH\x00\x12\x1b\n\x13kernel_records_lost\x18\x11 \x01(\x04\x12M\n\x15sample_skipped_reason\x18\x12 \x01(\x0e\x32,.perfetto.protos.PerfSample.SampleSkipReasonH\x01\x12\x41\n\x0eproducer_event\x18\x13 \x01(\x0b\x32).perfetto.protos.PerfSample.ProducerEvent\x1a\xdc\x01\n\rProducerEvent\x12\\\n\x12source_stop_reason\x18\x01 \x01(\x0e\x32>.perfetto.protos.PerfSample.ProducerEvent.DataSourceStopReasonH\x00\"N\n\x14\x44\x61taSourceStopReason\x12\x19\n\x15PROFILER_STOP_UNKNOWN\x10\x00\x12\x1b\n\x17PROFILER_STOP_GUARDRAIL\x10\x01\x42\x1d\n\x1boptional_source_stop_reason\"\xad\x01\n\x10SampleSkipReason\x12\x19\n\x15PROFILER_SKIP_UNKNOWN\x10\x00\x12\x1c\n\x18PROFILER_SKIP_READ_STAGE\x10\x01\x12\x1e\n\x1aPROFILER_SKIP_UNWIND_STAGE\x10\x02\x12 \n\x1cPROFILER_SKIP_UNWIND_ENQUEUE\x10\x03\x12\x1e\n\x1aPROFILER_SKIP_NOT_IN_SCOPE\x10\x04\x42\x17\n\x15optional_unwind_errorB \n\x1eoptional_sample_skipped_reason\"\xba\x01\n\x12PerfSampleDefaults\x12\x36\n\x08timebase\x18\x01 \x01(\x0b\x32$.perfetto.protos.PerfEvents.Timebase\x12\x31\n\tfollowers\x18\x04 \x03(\x0b\x32\x1e.perfetto.protos.FollowerEvent\x12\x1b\n\x13process_shard_count\x18\x02 \x01(\r\x12\x1c\n\x14\x63hosen_process_shard\x18\x03 \x01(\r\"\x83\x03\n\nSmapsEntry\x12\x0c\n\x04path\x18\x01 \x01(\t\x12\x0f\n\x07size_kb\x18\x02 \x01(\x04\x12\x18\n\x10private_dirty_kb\x18\x03 \x01(\x04\x12\x0f\n\x07swap_kb\x18\x04 \x01(\x04\x12\x11\n\tfile_name\x18\x05 \x01(\t\x12\x15\n\rstart_address\x18\x06 \x01(\x04\x12\x18\n\x10module_timestamp\x18\x07 \x01(\x04\x12\x16\n\x0emodule_debugid\x18\x08 \x01(\t\x12\x19\n\x11module_debug_path\x18\t \x01(\t\x12\x18\n\x10protection_flags\x18\n \x01(\r\x12!\n\x19private_clean_resident_kb\x18\x0b \x01(\x04\x12 \n\x18shared_dirty_resident_kb\x18\x0c \x01(\x04\x12 \n\x18shared_clean_resident_kb\x18\r \x01(\x04\x12\x11\n\tlocked_kb\x18\x0e \x01(\x04\x12 \n\x18proportional_resident_kb\x18\x0f \x01(\x04\"\x81\x03\n\x0bPackedSmaps\x12\x14\n\x0cstring_table\x18\x01 \x03(\t\x12\x13\n\x07name_id\x18\x02 \x03(\rB\x02\x10\x01\x12\x1b\n\x0f\x61ggregate_count\x18\x03 \x03(\rB\x02\x10\x01\x12\x13\n\x07size_kb\x18\x04 \x03(\x04\x42\x02\x10\x01\x12\x12\n\x06rss_kb\x18\x05 \x03(\x04\x42\x02\x10\x01\x12\x18\n\x0c\x61nonymous_kb\x18\x06 \x03(\x04\x42\x02\x10\x01\x12\x13\n\x07swap_kb\x18\x07 \x03(\x04\x42\x02\x10\x01\x12\x1b\n\x0fshared_clean_kb\x18\x08 \x03(\x04\x42\x02\x10\x01\x12\x1b\n\x0fshared_dirty_kb\x18\t \x03(\x04\x42\x02\x10\x01\x12\x1c\n\x10private_clean_kb\x18\n \x03(\x04\x42\x02\x10\x01\x12\x1c\n\x10private_dirty_kb\x18\x0b \x03(\x04\x42\x02\x10\x01\x12\x15\n\tlocked_kb\x18\x0c \x03(\x04\x42\x02\x10\x01\x12\x12\n\x06pss_kb\x18\r \x03(\x04\x42\x02\x10\x01\x12\x18\n\x0cpss_dirty_kb\x18\x0e \x03(\x04\x42\x02\x10\x01\x12\x17\n\x0bswap_pss_kb\x18\x0f \x03(\x04\x42\x02\x10\x01\"\xdc\x02\n\x0bSmapsPacket\x12\x0b\n\x03pid\x18\x01 \x01(\r\x12,\n\x07\x65ntries\x18\x02 \x03(\x0b\x32\x1b.perfetto.protos.SmapsEntry\x12\x34\n\x0epacked_entries\x18\x03 \x01(\x0b\x32\x1c.perfetto.protos.PackedSmaps\x12\x42\n\x0erecording_type\x18\x04 \x01(\x0e\x32*.perfetto.protos.SmapsPacket.RecordingType\"\x97\x01\n\rRecordingType\x12\x1a\n\x16RECORDING_TYPE_UNKNOWN\x10\x00\x12\x1d\n\x19RECORDING_TYPE_STANDALONE\x10\x01\x12%\n!RECORDING_TYPE_ART_HPROF_POSTFORK\x10\x02\x12$\n RECORDING_TYPE_ART_HPROF_PREFORK\x10\x03\"\xbb\x06\n\x0cProcessStats\x12\x38\n\tprocesses\x18\x01 \x03(\x0b\x32%.perfetto.protos.ProcessStats.Process\x12 \n\x18\x63ollection_end_timestamp\x18\x02 \x01(\x04\x1a\'\n\x06Thread\x12\x0b\n\x03tid\x18\x01 \x01(\x05J\x04\x08\x02\x10\x03J\x04\x08\x03\x10\x04J\x04\x08\x04\x10\x05\x1a\"\n\x06\x46\x44Info\x12\n\n\x02\x66\x64\x18\x01 \x01(\x04\x12\x0c\n\x04path\x18\x02 \x01(\t\x1a\x81\x05\n\x07Process\x12\x0b\n\x03pid\x18\x01 \x01(\x05\x12\x35\n\x07threads\x18\x0b \x03(\x0b\x32$.perfetto.protos.ProcessStats.Thread\x12\x12\n\nvm_size_kb\x18\x02 \x01(\x04\x12\x11\n\tvm_rss_kb\x18\x03 \x01(\x04\x12\x13\n\x0brss_anon_kb\x18\x04 \x01(\x04\x12\x13\n\x0brss_file_kb\x18\x05 \x01(\x04\x12\x14\n\x0crss_shmem_kb\x18\x06 \x01(\x04\x12\x12\n\nvm_swap_kb\x18\x07 \x01(\x04\x12\x14\n\x0cvm_locked_kb\x18\x08 \x01(\x04\x12\x11\n\tvm_hwm_kb\x18\t \x01(\x04\x12\x15\n\room_score_adj\x18\n \x01(\x03\x12\x1e\n\x16is_peak_rss_resettable\x18\x0c \x01(\x08\x12#\n\x1b\x63hrome_private_footprint_kb\x18\r \x01(\r\x12#\n\x1b\x63hrome_peak_resident_set_kb\x18\x0e \x01(\r\x12\x31\n\x03\x66\x64s\x18\x0f \x03(\x0b\x32$.perfetto.protos.ProcessStats.FDInfo\x12\x12\n\nsmr_rss_kb\x18\x10 \x01(\x04\x12\x12\n\nsmr_pss_kb\x18\x11 \x01(\x04\x12\x17\n\x0fsmr_pss_anon_kb\x18\x12 \x01(\x04\x12\x17\n\x0fsmr_pss_file_kb\x18\x13 \x01(\x04\x12\x18\n\x10smr_pss_shmem_kb\x18\x14 \x01(\x04\x12\x17\n\x0fsmr_swap_pss_kb\x18\x17 \x01(\x04\x12\x19\n\x11runtime_user_mode\x18\x15 \x01(\x04\x12\x1b\n\x13runtime_kernel_mode\x18\x16 \x01(\x04\x12\x15\n\rdmabuf_rss_kb\x18\x18 \x01(\x04\"\x88\x03\n\x0bProcessTree\x12\x37\n\tprocesses\x18\x01 \x03(\x0b\x32$.perfetto.protos.ProcessTree.Process\x12\x34\n\x07threads\x18\x02 \x03(\x0b\x32#.perfetto.protos.ProcessTree.Thread\x12 \n\x18\x63ollection_end_timestamp\x18\x03 \x01(\x04\x1a@\n\x06Thread\x12\x0b\n\x03tid\x18\x01 \x01(\x05\x12\x0c\n\x04tgid\x18\x03 \x01(\x05\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\r\n\x05nstid\x18\x04 \x03(\x05\x1a\xa5\x01\n\x07Process\x12\x0b\n\x03pid\x18\x01 \x01(\x05\x12\x0c\n\x04ppid\x18\x02 \x01(\x05\x12\x0f\n\x07\x63mdline\x18\x03 \x03(\t\x12\x17\n\x0f\x63mdline_is_comm\x18\t \x01(\x08\x12\x0b\n\x03uid\x18\x05 \x01(\x05\x12\r\n\x05nspid\x18\x06 \x03(\x05\x12\x1f\n\x17process_start_from_boot\x18\x07 \x01(\x04\x12\x12\n\nis_kthread\x18\x08 \x01(\x08J\x04\x08\x04\x10\x05\"\xd3\x01\n\x0fRemoteClockSync\x12\x44\n\rsynced_clocks\x18\x01 \x03(\x0b\x32-.perfetto.protos.RemoteClockSync.SyncedClocks\x1az\n\x0cSyncedClocks\x12\x35\n\rclient_clocks\x18\x02 \x01(\x0b\x32\x1e.perfetto.protos.ClockSnapshot\x12\x33\n\x0bhost_clocks\x18\x03 \x01(\x0b\x32\x1e.perfetto.protos.ClockSnapshot\"\x06\n\x04\x41tom\"J\n\nStatsdAtom\x12#\n\x04\x61tom\x18\x01 \x03(\x0b\x32\x15.perfetto.protos.Atom\x12\x17\n\x0ftimestamp_nanos\x18\x02 \x03(\x03\"\xe4\x10\n\x08SysStats\x12\x37\n\x07meminfo\x18\x01 \x03(\x0b\x32&.perfetto.protos.SysStats.MeminfoValue\x12\x35\n\x06vmstat\x18\x02 \x03(\x0b\x32%.perfetto.protos.SysStats.VmstatValue\x12\x34\n\x08\x63pu_stat\x18\x03 \x03(\x0b\x32\".perfetto.protos.SysStats.CpuTimes\x12\x11\n\tnum_forks\x18\x04 \x01(\x04\x12\x15\n\rnum_irq_total\x18\x05 \x01(\x04\x12\x39\n\x07num_irq\x18\x06 \x03(\x0b\x32(.perfetto.protos.SysStats.InterruptCount\x12\x19\n\x11num_softirq_total\x18\x07 \x01(\x04\x12=\n\x0bnum_softirq\x18\x08 \x03(\x0b\x32(.perfetto.protos.SysStats.InterruptCount\x12 \n\x18\x63ollection_end_timestamp\x18\t \x01(\x04\x12\x37\n\x07\x64\x65vfreq\x18\n \x03(\x0b\x32&.perfetto.protos.SysStats.DevfreqValue\x12\x13\n\x0b\x63pufreq_khz\x18\x0b \x03(\r\x12\x37\n\nbuddy_info\x18\x0c \x03(\x0b\x32#.perfetto.protos.SysStats.BuddyInfo\x12\x35\n\tdisk_stat\x18\r \x03(\x0b\x32\".perfetto.protos.SysStats.DiskStat\x12\x30\n\x03psi\x18\x0e \x03(\x0b\x32#.perfetto.protos.SysStats.PsiSample\x12;\n\x0cthermal_zone\x18\x0f \x03(\x0b\x32%.perfetto.protos.SysStats.ThermalZone\x12=\n\rcpuidle_state\x18\x10 \x03(\x0b\x32&.perfetto.protos.SysStats.CpuIdleState\x12\x13\n\x0bgpufreq_mhz\x18\x11 \x03(\x04\x12\x35\n\tslab_info\x18\x12 \x03(\x0b\x32\".perfetto.protos.SysStats.SlabInfo\x1aL\n\x0cMeminfoValue\x12-\n\x03key\x18\x01 \x01(\x0e\x32 .perfetto.protos.MeminfoCounters\x12\r\n\x05value\x18\x02 \x01(\x04\x1aJ\n\x0bVmstatValue\x12,\n\x03key\x18\x01 \x01(\x0e\x32\x1f.perfetto.protos.VmstatCounters\x12\r\n\x05value\x18\x02 \x01(\x04\x1a\xb4\x01\n\x08\x43puTimes\x12\x0e\n\x06\x63pu_id\x18\x01 \x01(\r\x12\x0f\n\x07user_ns\x18\x02 \x01(\x04\x12\x14\n\x0cuser_nice_ns\x18\x03 \x01(\x04\x12\x16\n\x0esystem_mode_ns\x18\x04 \x01(\x04\x12\x0f\n\x07idle_ns\x18\x05 \x01(\x04\x12\x12\n\nio_wait_ns\x18\x06 \x01(\x04\x12\x0e\n\x06irq_ns\x18\x07 \x01(\x04\x12\x12\n\nsoftirq_ns\x18\x08 \x01(\x04\x12\x10\n\x08steal_ns\x18\t \x01(\x04\x1a,\n\x0eInterruptCount\x12\x0b\n\x03irq\x18\x01 \x01(\x05\x12\r\n\x05\x63ount\x18\x02 \x01(\x04\x1a*\n\x0c\x44\x65vfreqValue\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\x04\x1a<\n\tBuddyInfo\x12\x0c\n\x04node\x18\x01 \x01(\t\x12\x0c\n\x04zone\x18\x02 \x01(\t\x12\x13\n\x0border_pages\x18\x03 \x03(\r\x1a\xd7\x01\n\x08\x44iskStat\x12\x13\n\x0b\x64\x65vice_name\x18\x01 \x01(\t\x12\x14\n\x0cread_sectors\x18\x02 \x01(\x04\x12\x14\n\x0cread_time_ms\x18\x03 \x01(\x04\x12\x15\n\rwrite_sectors\x18\x04 \x01(\x04\x12\x15\n\rwrite_time_ms\x18\x05 \x01(\x04\x12\x17\n\x0f\x64iscard_sectors\x18\x06 \x01(\x04\x12\x17\n\x0f\x64iscard_time_ms\x18\x07 \x01(\x04\x12\x13\n\x0b\x66lush_count\x18\x08 \x01(\x04\x12\x15\n\rflush_time_ms\x18\t \x01(\x04\x1a\xb4\x02\n\tPsiSample\x12\x41\n\x08resource\x18\x01 \x01(\x0e\x32/.perfetto.protos.SysStats.PsiSample.PsiResource\x12\x10\n\x08total_ns\x18\x02 \x01(\x04\"\xd1\x01\n\x0bPsiResource\x12\x1c\n\x18PSI_RESOURCE_UNSPECIFIED\x10\x00\x12\x19\n\x15PSI_RESOURCE_CPU_SOME\x10\x01\x12\x19\n\x15PSI_RESOURCE_CPU_FULL\x10\x02\x12\x18\n\x14PSI_RESOURCE_IO_SOME\x10\x03\x12\x18\n\x14PSI_RESOURCE_IO_FULL\x10\x04\x12\x1c\n\x18PSI_RESOURCE_MEMORY_SOME\x10\x05\x12\x1c\n\x18PSI_RESOURCE_MEMORY_FULL\x10\x06\x1a\x37\n\x0bThermalZone\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0c\n\x04temp\x18\x02 \x01(\x04\x12\x0c\n\x04type\x18\x03 \x01(\t\x1a\x37\n\x11\x43puIdleStateEntry\x12\r\n\x05state\x18\x01 \x01(\t\x12\x13\n\x0b\x64uration_us\x18\x02 \x01(\x04\x1ah\n\x0c\x43puIdleState\x12\x0e\n\x06\x63pu_id\x18\x01 \x01(\r\x12H\n\x13\x63puidle_state_entry\x18\x02 \x03(\x0b\x32+.perfetto.protos.SysStats.CpuIdleStateEntry\x1a\x43\n\x08SlabInfo\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x16\n\x0epages_per_slab\x18\x02 \x01(\r\x12\x11\n\tnum_slabs\x18\x03 \x01(\r\"\xcc\x02\n\x07\x43puInfo\x12*\n\x04\x63pus\x18\x01 \x03(\x0b\x32\x1c.perfetto.protos.CpuInfo.Cpu\x1an\n\x10\x41rmCpuIdentifier\x12\x13\n\x0bimplementer\x18\x01 \x01(\r\x12\x14\n\x0c\x61rchitecture\x18\x02 \x01(\r\x12\x0f\n\x07variant\x18\x03 \x01(\r\x12\x0c\n\x04part\x18\x04 \x01(\r\x12\x10\n\x08revision\x18\x05 \x01(\r\x1a\xa4\x01\n\x03\x43pu\x12\x11\n\tprocessor\x18\x01 \x01(\t\x12\x13\n\x0b\x66requencies\x18\x02 \x03(\r\x12\x10\n\x08\x63\x61pacity\x18\x03 \x01(\r\x12\x43\n\x0e\x61rm_identifier\x18\x04 \x01(\x0b\x32).perfetto.protos.CpuInfo.ArmCpuIdentifierH\x00\x12\x10\n\x08\x66\x65\x61tures\x18\x05 \x01(\x04\x42\x0c\n\nidentifier\"\x82\x02\n\x07GpuInfo\x12*\n\x04gpus\x18\x01 \x03(\x0b\x32\x1c.perfetto.protos.GpuInfo.Gpu\x1a\xca\x01\n\x03Gpu\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0e\n\x06vendor\x18\x02 \x01(\t\x12\r\n\x05model\x18\x03 \x01(\t\x12\x14\n\x0c\x61rchitecture\x18\x04 \x01(\t\x12\x0c\n\x04uuid\x18\x05 \x01(\x0c\x12\x0f\n\x07pci_bdf\x18\x07 \x01(\t\x12\x39\n\nextra_info\x18\x06 \x03(\x0b\x32%.perfetto.protos.GpuInfo.Gpu.KeyValue\x1a&\n\x08KeyValue\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t\"\x87\x01\n\rInterruptInfo\x12\x44\n\x0birq_mapping\x18\x01 \x03(\x0b\x32/.perfetto.protos.InterruptInfo.InterruptMapping\x1a\x30\n\x10InterruptMapping\x12\x0e\n\x06irq_id\x18\x01 \x01(\r\x12\x0c\n\x04name\x18\x02 \x01(\t\"\xce\x08\n\tTestEvent\x12\x0b\n\x03str\x18\x01 \x01(\t\x12\x11\n\tseq_value\x18\x02 \x01(\r\x12\x0f\n\x07\x63ounter\x18\x03 \x01(\x04\x12\x0f\n\x07is_last\x18\x04 \x01(\x08\x12\x37\n\x07payload\x18\x05 \x01(\x0b\x32&.perfetto.protos.TestEvent.TestPayload\x12>\n\rprotovm_patch\x18\x06 \x01(\x0b\x32\'.perfetto.protos.TestEvent.ProtoVmPatch\x12U\n\x19protovm_incremental_state\x18\x07 \x01(\x0b\x32\x32.perfetto.protos.TestEvent.ProtoVmIncrementalState\x1a\xf2\x01\n\x0bTestPayload\x12\x0b\n\x03str\x18\x01 \x03(\t\x12\x36\n\x06nested\x18\x02 \x03(\x0b\x32&.perfetto.protos.TestEvent.TestPayload\x12\x15\n\rsingle_string\x18\x04 \x01(\t\x12\x12\n\nsingle_int\x18\x05 \x01(\x05\x12\x15\n\rrepeated_ints\x18\x06 \x03(\x05\x12\x1f\n\x17remaining_nesting_depth\x18\x03 \x01(\r\x12;\n\x11\x64\x65\x62ug_annotations\x18\x07 \x03(\x0b\x32 .perfetto.protos.DebugAnnotation\x1a\x96\x01\n\x0eProtoVmMessage\x12\n\n\x02id\x18\x01 \x01(\r\x12O\n\nsubmessage\x18\x02 \x01(\x0b\x32;.perfetto.protos.TestEvent.ProtoVmMessage.ProtoVmSubmessage\x1a\'\n\x11ProtoVmSubmessage\x12\x12\n\nsingle_int\x18\x01 \x01(\r\x1a\xd9\x01\n\x0cProtoVmPatch\x12\x17\n\x0fstring_to_merge\x18\x01 \x01(\t\x12\x14\n\x0cint_to_merge\x18\x02 \x01(\x05\x12\x41\n\x0esingle_message\x18\x03 \x01(\x0b\x32).perfetto.protos.TestEvent.ProtoVmMessage\x12;\n\x08messages\x18\x04 \x03(\x0b\x32).perfetto.protos.TestEvent.ProtoVmMessage\x12\x1a\n\x12\x64\x65lete_message_ids\x18\x05 \x03(\r\x1a\xc4\x01\n\x17ProtoVmIncrementalState\x12\x15\n\rstring_merged\x18\x01 \x01(\t\x12\x12\n\nint_merged\x18\x02 \x01(\x05\x12\x41\n\x0esingle_message\x18\x03 \x01(\x0b\x32).perfetto.protos.TestEvent.ProtoVmMessage\x12;\n\x08messages\x18\x04 \x03(\x0b\x32).perfetto.protos.TestEvent.ProtoVmMessage\"\xb7\x02\n\x13TracePacketDefaults\x12\x1a\n\x12timestamp_clock_id\x18: \x01(\r\x12\x41\n\x14track_event_defaults\x18\x0b \x01(\x0b\x32#.perfetto.protos.TrackEventDefaults\x12\x41\n\x14perf_sample_defaults\x18\x0c \x01(\x0b\x32#.perfetto.protos.PerfSampleDefaults\x12\x43\n\x15stack_sample_defaults\x18\x64 \x01(\x0b\x32$.perfetto.protos.StackSampleDefaults\x12\x39\n\x10v8_code_defaults\x18\x63 \x01(\x0b\x32\x1f.perfetto.protos.V8CodeDefaults\"%\n\tTraceUuid\x12\x0b\n\x03msb\x18\x01 \x01(\x03\x12\x0b\n\x03lsb\x18\x02 \x01(\x03\"\xe7\x03\n\x11ProcessDescriptor\x12\x0b\n\x03pid\x18\x01 \x01(\x05\x12\x0f\n\x07\x63mdline\x18\x02 \x03(\t\x12\x14\n\x0cprocess_name\x18\x06 \x01(\t\x12\x18\n\x10process_priority\x18\x05 \x01(\x05\x12\x1a\n\x12start_timestamp_ns\x18\x07 \x01(\x03\x12Q\n\x13\x63hrome_process_type\x18\x04 \x01(\x0e\x32\x34.perfetto.protos.ProcessDescriptor.ChromeProcessType\x12\x19\n\x11legacy_sort_index\x18\x03 \x01(\x05\x12\x16\n\x0eprocess_labels\x18\x08 \x03(\t\"\xe1\x01\n\x11\x43hromeProcessType\x12\x17\n\x13PROCESS_UNSPECIFIED\x10\x00\x12\x13\n\x0fPROCESS_BROWSER\x10\x01\x12\x14\n\x10PROCESS_RENDERER\x10\x02\x12\x13\n\x0fPROCESS_UTILITY\x10\x03\x12\x12\n\x0ePROCESS_ZYGOTE\x10\x04\x12\x1a\n\x16PROCESS_SANDBOX_HELPER\x10\x05\x12\x0f\n\x0bPROCESS_GPU\x10\x06\x12\x18\n\x14PROCESS_PPAPI_PLUGIN\x10\x07\x12\x18\n\x14PROCESS_PPAPI_BROKER\x10\x08\"-\n\x19TrackEventRangeOfInterest\x12\x10\n\x08start_us\x18\x01 \x01(\x03\"\xf4\x05\n\x10ThreadDescriptor\x12\x0b\n\x03pid\x18\x01 \x01(\x05\x12\x0b\n\x03tid\x18\x02 \x01(\x03\x12\x13\n\x0bthread_name\x18\x05 \x01(\t\x12N\n\x12\x63hrome_thread_type\x18\x04 \x01(\x0e\x32\x32.perfetto.protos.ThreadDescriptor.ChromeThreadType\x12\x1e\n\x16reference_timestamp_us\x18\x06 \x01(\x03\x12 \n\x18reference_thread_time_us\x18\x07 \x01(\x03\x12*\n\"reference_thread_instruction_count\x18\x08 \x01(\x03\x12\x19\n\x11legacy_sort_index\x18\x03 \x01(\x05\"\xd7\x03\n\x10\x43hromeThreadType\x12\x1d\n\x19\x43HROME_THREAD_UNSPECIFIED\x10\x00\x12\x16\n\x12\x43HROME_THREAD_MAIN\x10\x01\x12\x14\n\x10\x43HROME_THREAD_IO\x10\x02\x12 \n\x1c\x43HROME_THREAD_POOL_BG_WORKER\x10\x03\x12 \n\x1c\x43HROME_THREAD_POOL_FG_WORKER\x10\x04\x12\"\n\x1e\x43HROME_THREAD_POOL_FB_BLOCKING\x10\x05\x12\"\n\x1e\x43HROME_THREAD_POOL_BG_BLOCKING\x10\x06\x12\x1e\n\x1a\x43HROME_THREAD_POOL_SERVICE\x10\x07\x12\x1c\n\x18\x43HROME_THREAD_COMPOSITOR\x10\x08\x12 \n\x1c\x43HROME_THREAD_VIZ_COMPOSITOR\x10\t\x12#\n\x1f\x43HROME_THREAD_COMPOSITOR_WORKER\x10\n\x12 \n\x1c\x43HROME_THREAD_SERVICE_WORKER\x10\x0b\x12\x1e\n\x1a\x43HROME_THREAD_MEMORY_INFRA\x10\x32\x12#\n\x1f\x43HROME_THREAD_SAMPLING_PROFILER\x10\x33\"\x9b\x01\n\x17\x43hromeProcessDescriptor\x12\x14\n\x0cprocess_type\x18\x01 \x01(\x05\x12\x18\n\x10process_priority\x18\x02 \x01(\x05\x12\x19\n\x11legacy_sort_index\x18\x03 \x01(\x05\x12\x1d\n\x15host_app_package_name\x18\x04 \x01(\t\x12\x16\n\x0e\x63rash_trace_id\x18\x05 \x01(\x04\"b\n\x16\x43hromeThreadDescriptor\x12\x13\n\x0bthread_type\x18\x01 \x01(\x05\x12\x19\n\x11legacy_sort_index\x18\x02 \x01(\x05\x12\x18\n\x10is_sandboxed_tid\x18\x03 \x01(\x08\"\xc7\x03\n\x11\x43ounterDescriptor\x12\x43\n\x04type\x18\x01 \x01(\x0e\x32\x35.perfetto.protos.CounterDescriptor.BuiltinCounterType\x12\x12\n\ncategories\x18\x02 \x03(\t\x12\x35\n\x04unit\x18\x03 \x01(\x0e\x32\'.perfetto.protos.CounterDescriptor.Unit\x12\x11\n\tunit_name\x18\x06 \x01(\t\x12\x17\n\x0funit_multiplier\x18\x04 \x01(\x03\x12\x16\n\x0eis_incremental\x18\x05 \x01(\x08\x12\x18\n\x10y_axis_share_key\x18\x07 \x01(\t\"o\n\x12\x42uiltinCounterType\x12\x17\n\x13\x43OUNTER_UNSPECIFIED\x10\x00\x12\x1a\n\x16\x43OUNTER_THREAD_TIME_NS\x10\x01\x12$\n COUNTER_THREAD_INSTRUCTION_COUNT\x10\x02\"S\n\x04Unit\x12\x14\n\x10UNIT_UNSPECIFIED\x10\x00\x12\x10\n\x0cUNIT_TIME_NS\x10\x01\x12\x0e\n\nUNIT_COUNT\x10\x02\x12\x13\n\x0fUNIT_SIZE_BYTES\x10\x03\"\x11\n\x0fStateDescriptor\"\xd3\x01\n\x0eTrackDimension\x12\x0e\n\x04name\x18\x01 \x01(\tH\x00\x12\x12\n\x08name_iid\x18\x07 \x01(\x04H\x00\x12\x13\n\tint_value\x18\x02 \x01(\x03H\x01\x12\x16\n\x0cstring_value\x18\x03 \x01(\tH\x01\x12\x1a\n\x10string_value_iid\x18\x05 \x01(\x04H\x01\x12\x16\n\x0c\x64isplay_name\x18\x04 \x01(\tH\x02\x12\x1a\n\x10\x64isplay_name_iid\x18\x06 \x01(\x04H\x02\x42\x0c\n\nname_fieldB\x07\n\x05valueB\t\n\x07\x64isplay\"\xbd\x0b\n\x0fTrackDescriptor\x12\x0c\n\x04uuid\x18\x01 \x01(\x04\x12\x13\n\x0bparent_uuid\x18\x05 \x01(\x04\x12\x0e\n\x04name\x18\x02 \x01(\tH\x00\x12\x15\n\x0bstatic_name\x18\n \x01(\tH\x00\x12\x15\n\x0b\x61trace_name\x18\r \x01(\tH\x00\x12\x13\n\x0b\x64\x65scription\x18\x0e \x01(\t\x12\x33\n\x07process\x18\x03 \x01(\x0b\x32\".perfetto.protos.ProcessDescriptor\x12@\n\x0e\x63hrome_process\x18\x06 \x01(\x0b\x32(.perfetto.protos.ChromeProcessDescriptor\x12\x31\n\x06thread\x18\x04 \x01(\x0b\x32!.perfetto.protos.ThreadDescriptor\x12>\n\rchrome_thread\x18\x07 \x01(\x0b\x32\'.perfetto.protos.ChromeThreadDescriptor\x12\x33\n\x07\x63ounter\x18\x08 \x01(\x0b\x32\".perfetto.protos.CounterDescriptor\x12/\n\x05state\x18\x12 \x01(\x0b\x32 .perfetto.protos.StateDescriptor\x12+\n#disallow_merging_with_system_tracks\x18\t \x01(\x08\x12L\n\x0e\x63hild_ordering\x18\x0b \x01(\x0e\x32\x34.perfetto.protos.TrackDescriptor.ChildTracksOrdering\x12\x1a\n\x12sibling_order_rank\x18\x0c \x01(\x05\x12U\n\x16sibling_merge_behavior\x18\x0f \x01(\x0e\x32\x35.perfetto.protos.TrackDescriptor.SiblingMergeBehavior\x12\x1b\n\x11sibling_merge_key\x18\x10 \x01(\tH\x01\x12\x1f\n\x15sibling_merge_key_int\x18\x11 \x01(\x04H\x01\x12J\n\x10process_ordering\x18\x13 \x01(\x0e\x32\x30.perfetto.protos.TrackDescriptor.ProcessOrdering\x12H\n\x0fthread_ordering\x18\x14 \x01(\x0e\x32/.perfetto.protos.TrackDescriptor.ThreadOrdering\x12\x33\n\ndimensions\x18\x15 \x03(\x0b\x32\x1f.perfetto.protos.TrackDimension\"V\n\x13\x43hildTracksOrdering\x12\x0b\n\x07UNKNOWN\x10\x00\x12\x11\n\rLEXICOGRAPHIC\x10\x01\x12\x11\n\rCHRONOLOGICAL\x10\x02\x12\x0c\n\x08\x45XPLICIT\x10\x03\"\xba\x01\n\x14SiblingMergeBehavior\x12&\n\"SIBLING_MERGE_BEHAVIOR_UNSPECIFIED\x10\x00\x12(\n$SIBLING_MERGE_BEHAVIOR_BY_TRACK_NAME\x10\x01\x12\x1f\n\x1bSIBLING_MERGE_BEHAVIOR_NONE\x10\x02\x12/\n+SIBLING_MERGE_BEHAVIOR_BY_SIBLING_MERGE_KEY\x10\x03\"R\n\x0fProcessOrdering\x12 \n\x1cPROCESS_ORDERING_UNSPECIFIED\x10\x00\x12\x1d\n\x19PROCESS_ORDERING_EXPLICIT\x10\x01\"O\n\x0eThreadOrdering\x12\x1f\n\x1bTHREAD_ORDERING_UNSPECIFIED\x10\x00\x12\x1c\n\x18THREAD_ORDERING_EXPLICIT\x10\x01\x42\x18\n\x16static_or_dynamic_nameB\x19\n\x17sibling_merge_key_field\"\xed\x03\n\x10TranslationTable\x12M\n\x10\x63hrome_histogram\x18\x01 \x01(\x0b\x32\x31.perfetto.protos.ChromeHistorgramTranslationTableH\x00\x12M\n\x11\x63hrome_user_event\x18\x02 \x01(\x0b\x32\x30.perfetto.protos.ChromeUserEventTranslationTableH\x00\x12Y\n\x17\x63hrome_performance_mark\x18\x03 \x01(\x0b\x32\x36.perfetto.protos.ChromePerformanceMarkTranslationTableH\x00\x12@\n\nslice_name\x18\x04 \x01(\x0b\x32*.perfetto.protos.SliceNameTranslationTableH\x00\x12O\n\x12process_track_name\x18\x05 \x01(\x0b\x32\x31.perfetto.protos.ProcessTrackNameTranslationTableH\x00\x12\x44\n\x0c\x63hrome_study\x18\x06 \x01(\x0b\x32,.perfetto.protos.ChromeStudyTranslationTableH\x00\x42\x07\n\x05table\"\xae\x01\n ChromeHistorgramTranslationTable\x12W\n\x0chash_to_name\x18\x01 \x03(\x0b\x32\x41.perfetto.protos.ChromeHistorgramTranslationTable.HashToNameEntry\x1a\x31\n\x0fHashToNameEntry\x12\x0b\n\x03key\x18\x01 \x01(\x04\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"\xbf\x01\n\x1f\x43hromeUserEventTranslationTable\x12\x63\n\x13\x61\x63tion_hash_to_name\x18\x01 \x03(\x0b\x32\x46.perfetto.protos.ChromeUserEventTranslationTable.ActionHashToNameEntry\x1a\x37\n\x15\x41\x63tionHashToNameEntry\x12\x0b\n\x03key\x18\x01 \x01(\x04\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"\xe3\x02\n%ChromePerformanceMarkTranslationTable\x12\x65\n\x11site_hash_to_name\x18\x01 \x03(\x0b\x32J.perfetto.protos.ChromePerformanceMarkTranslationTable.SiteHashToNameEntry\x12\x65\n\x11mark_hash_to_name\x18\x02 \x03(\x0b\x32J.perfetto.protos.ChromePerformanceMarkTranslationTable.MarkHashToNameEntry\x1a\x35\n\x13SiteHashToNameEntry\x12\x0b\n\x03key\x18\x01 \x01(\r\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\x1a\x35\n\x13MarkHashToNameEntry\x12\x0b\n\x03key\x18\x01 \x01(\r\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"\xc2\x01\n\x19SliceNameTranslationTable\x12g\n\x18raw_to_deobfuscated_name\x18\x01 \x03(\x0b\x32\x45.perfetto.protos.SliceNameTranslationTable.RawToDeobfuscatedNameEntry\x1a<\n\x1aRawToDeobfuscatedNameEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"\xd0\x01\n ProcessTrackNameTranslationTable\x12n\n\x18raw_to_deobfuscated_name\x18\x01 \x03(\x0b\x32L.perfetto.protos.ProcessTrackNameTranslationTable.RawToDeobfuscatedNameEntry\x1a<\n\x1aRawToDeobfuscatedNameEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"\xa4\x01\n\x1b\x43hromeStudyTranslationTable\x12R\n\x0chash_to_name\x18\x01 \x03(\x0b\x32<.perfetto.protos.ChromeStudyTranslationTable.HashToNameEntry\x1a\x31\n\x0fHashToNameEntry\x12\x0b\n\x03key\x18\x01 \x01(\x04\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"k\n\x07Trigger\x12\x14\n\x0ctrigger_name\x18\x01 \x01(\t\x12\x15\n\rproducer_name\x18\x02 \x01(\t\x12\x1c\n\x14trusted_producer_uid\x18\x03 \x01(\x05\x12\x15\n\rstop_delay_ms\x18\x04 \x01(\x04\"\xc5\x01\n\x07UiState\x12\x19\n\x11timeline_start_ts\x18\x01 \x01(\x03\x12\x17\n\x0ftimeline_end_ts\x18\x02 \x01(\x03\x12\x44\n\x11highlight_process\x18\x03 \x01(\x0b\x32).perfetto.protos.UiState.HighlightProcess\x1a@\n\x10HighlightProcess\x12\r\n\x03pid\x18\x01 \x01(\rH\x00\x12\x11\n\x07\x63mdline\x18\x02 \x01(\tH\x00\x42\n\n\x08selector\"\x9b\x34\n\x0bTracePacket\x12\x11\n\ttimestamp\x18\x08 \x01(\x04\x12\x1a\n\x12timestamp_clock_id\x18: \x01(\r\x12\x32\n\x0btrack_event\x18\x0b \x01(\x0b\x32\x1b.perfetto.protos.TrackEventH\x00\x12<\n\x10track_descriptor\x18< \x01(\x0b\x32 .perfetto.protos.TrackDescriptorH\x00\x12W\n\x1fgeneric_kernel_task_state_event\x18u \x01(\x0b\x32,.perfetto.protos.GenericKernelTaskStateEventH\x00\x12X\n\x1dgeneric_kernel_cpu_freq_event\x18v \x01(\x0b\x32/.perfetto.protos.GenericKernelCpuFrequencyEventH\x00\x12Y\n generic_kernel_task_rename_event\x18x \x01(\x0b\x32-.perfetto.protos.GenericKernelTaskRenameEventH\x00\x12P\n\x1bgeneric_kernel_process_tree\x18z \x01(\x0b\x32).perfetto.protos.GenericKernelProcessTreeH\x00\x12Q\n\x1bgeneric_gpu_frequency_event\x18\x81\x01 \x01(\x0b\x32).perfetto.protos.GenericGpuFrequencyEventH\x00\x12\x34\n\x0cprocess_tree\x18\x02 \x01(\x0b\x32\x1c.perfetto.protos.ProcessTreeH\x00\x12S\n\x1dtrack_event_range_of_interest\x18Z \x01(\x0b\x32*.perfetto.protos.TrackEventRangeOfInterestH\x00\x12\x36\n\rprocess_stats\x18\t \x01(\x0b\x32\x1d.perfetto.protos.ProcessStatsH\x00\x12\x37\n\x0einode_file_map\x18\x04 \x01(\x0b\x32\x1d.perfetto.protos.InodeFileMapH\x00\x12;\n\rchrome_events\x18\x05 \x01(\x0b\x32\".perfetto.protos.ChromeEventBundleH\x00\x12\x38\n\x0e\x63lock_snapshot\x18\x06 \x01(\x0b\x32\x1e.perfetto.protos.ClockSnapshotH\x00\x12.\n\tsys_stats\x18\x07 \x01(\x0b\x32\x19.perfetto.protos.SysStatsH\x00\x12\x30\n\ntrace_uuid\x18Y \x01(\x0b\x32\x1a.perfetto.protos.TraceUuidH\x00\x12\x34\n\x0ctrace_config\x18! \x01(\x0b\x32\x1c.perfetto.protos.TraceConfigH\x00\x12\x34\n\x0c\x66trace_stats\x18\" \x01(\x0b\x32\x1c.perfetto.protos.FtraceStatsH\x00\x12\x32\n\x0btrace_stats\x18# \x01(\x0b\x32\x1b.perfetto.protos.TraceStatsH\x00\x12\x66\n&experimental_tracing_v2_producer_stats\x18\x8b\x01 \x01(\x0b\x32\x33.perfetto.protos.ExperimentalTracingV2ProducerStatsH\x00\x12\x38\n\x0eprofile_packet\x18% \x01(\x0b\x32\x1e.perfetto.protos.ProfilePacketH\x00\x12\x44\n\x14streaming_allocation\x18J \x01(\x0b\x32$.perfetto.protos.StreamingAllocationH\x00\x12\x38\n\x0estreaming_free\x18K \x01(\x0b\x32\x1e.perfetto.protos.StreamingFreeH\x00\x12\x33\n\x07\x62\x61ttery\x18& \x01(\x0b\x32 .perfetto.protos.BatteryCountersH\x00\x12\x32\n\x0bpower_rails\x18( \x01(\x0b\x32\x1b.perfetto.protos.PowerRailsH\x00\x12\x38\n\x0b\x61ndroid_log\x18\' \x01(\x0b\x32!.perfetto.protos.AndroidLogPacketH\x00\x12\x32\n\x0bsystem_info\x18- \x01(\x0b\x32\x1b.perfetto.protos.SystemInfoH\x00\x12+\n\x07trigger\x18. \x01(\x0b\x32\x18.perfetto.protos.TriggerH\x00\x12\x38\n\x0e\x63hrome_trigger\x18m \x01(\x0b\x32\x1e.perfetto.protos.ChromeTriggerH\x00\x12\x36\n\rpackages_list\x18/ \x01(\x0b\x32\x1d.perfetto.protos.PackagesListH\x00\x12M\n\x19\x63hrome_benchmark_metadata\x18\x30 \x01(\x0b\x32(.perfetto.protos.ChromeBenchmarkMetadataH\x00\x12@\n\x12perfetto_metatrace\x18\x31 \x01(\x0b\x32\".perfetto.protos.PerfettoMetatraceH\x00\x12@\n\x0f\x63hrome_metadata\x18\x33 \x01(\x0b\x32%.perfetto.protos.ChromeMetadataPacketH\x00\x12=\n\x11gpu_counter_event\x18\x34 \x01(\x0b\x32 .perfetto.protos.GpuCounterEventH\x00\x12\x46\n\x16gpu_render_stage_event\x18\x35 \x01(\x0b\x32$.perfetto.protos.GpuRenderStageEventH\x00\x12K\n\x18streaming_profile_packet\x18\x36 \x01(\x0b\x32\'.perfetto.protos.StreamingProfilePacketH\x00\x12\x44\n\x14\x61rt_process_metadata\x18\x83\x01 \x01(\x0b\x32#.perfetto.protos.ArtProcessMetadataH\x00\x12\x43\n\x14graphics_frame_event\x18\x39 \x01(\x0b\x32#.perfetto.protos.GraphicsFrameEventH\x00\x12\x41\n\x13vulkan_memory_event\x18> \x01(\x0b\x32\".perfetto.protos.VulkanMemoryEventH\x00\x12*\n\x07gpu_log\x18? \x01(\x0b\x32\x17.perfetto.protos.GpuLogH\x00\x12;\n\x10vulkan_api_event\x18\x41 \x01(\x0b\x32\x1f.perfetto.protos.VulkanApiEventH\x00\x12\x32\n\x0bperf_sample\x18\x42 \x01(\x0b\x32\x1b.perfetto.protos.PerfSampleH\x00\x12,\n\x08\x63pu_info\x18\x43 \x01(\x0b\x32\x18.perfetto.protos.CpuInfoH\x00\x12\x34\n\x0csmaps_packet\x18\x44 \x01(\x0b\x32\x1c.perfetto.protos.SmapsPacketH\x00\x12=\n\rservice_event\x18\x45 \x01(\x0b\x32$.perfetto.protos.TracingServiceEventH\x00\x12L\n\x18\x63oncurrent_session_event\x18\x86\x01 \x01(\x0b\x32\'.perfetto.protos.ConcurrentSessionEventH\x00\x12\x35\n\x0cstack_sample\x18\x87\x01 \x01(\x0b\x32\x1c.perfetto.protos.StackSampleH\x00\x12\x45\n\x15initial_display_state\x18\x46 \x01(\x0b\x32$.perfetto.protos.InitialDisplayStateH\x00\x12@\n\x13gpu_mem_total_event\x18G \x01(\x0b\x32!.perfetto.protos.GpuMemTotalEventH\x00\x12I\n\x17memory_tracker_snapshot\x18I \x01(\x0b\x32&.perfetto.protos.MemoryTrackerSnapshotH\x00\x12`\n#android_energy_estimation_breakdown\x18M \x01(\x0b\x32\x31.perfetto.protos.AndroidEnergyEstimationBreakdownH\x00\x12,\n\x08ui_state\x18N \x01(\x0b\x32\x18.perfetto.protos.UiStateH\x00\x12>\n\x11translation_table\x18R \x01(\x0b\x32!.perfetto.protos.TranslationTableH\x00\x12V\n\x1e\x61ndroid_game_intervention_list\x18S \x01(\x0b\x32,.perfetto.protos.AndroidGameInterventionListH\x00\x12\x32\n\x0bstatsd_atom\x18T \x01(\x0b\x32\x1b.perfetto.protos.StatsdAtomH\x00\x12I\n\x17\x61ndroid_system_property\x18V \x01(\x0b\x32&.perfetto.protos.AndroidSystemPropertyH\x00\x12G\n\x16\x65ntity_state_residency\x18[ \x01(\x0b\x32%.perfetto.protos.EntityStateResidencyH\x00\x12<\n\x10trace_provenance\x18| \x01(\x0b\x32 .perfetto.protos.TraceProvenanceH\x00\x12\x39\n\x08protovms\x18} \x01(\x0b\x32%.perfetto.protos.TracePacket.ProtoVmsH\x00\x12<\n\x10trace_attributes\x18~ \x01(\x0b\x32 .perfetto.protos.TraceAttributesH\x00\x12\x38\n\x0e\x61ndroid_aflags\x18\x7f \x01(\x0b\x32\x1e.perfetto.protos.AndroidAflagsH\x00\x12-\n\x08gpu_info\x18\x80\x01 \x01(\x0b\x32\x18.perfetto.protos.GpuInfoH\x00\x12\x39\n\x0einterrupt_info\x18\x82\x01 \x01(\x0b\x32\x1e.perfetto.protos.InterruptInfoH\x00\x12\x38\n\x0emodule_symbols\x18= \x01(\x0b\x32\x1e.perfetto.protos.ModuleSymbolsH\x00\x12\x46\n\x15\x64\x65obfuscation_mapping\x18@ \x01(\x0b\x32%.perfetto.protos.DeobfuscationMappingH\x00\x12@\n\x12process_descriptor\x18+ \x01(\x0b\x32\".perfetto.protos.ProcessDescriptorH\x00\x12>\n\x11thread_descriptor\x18, \x01(\x0b\x32!.perfetto.protos.ThreadDescriptorH\x00\x12;\n\rftrace_events\x18\x01 \x01(\x0b\x32\".perfetto.protos.FtraceEventBundleH\x00\x12 \n\x16synchronization_marker\x18$ \x01(\x0cH\x00\x12\x1c\n\x12\x63ompressed_packets\x18\x32 \x01(\x0cH\x00\x12\"\n\x17zstd_compressed_packets\x18\x85\x01 \x01(\x0cH\x00\x12\x44\n\x14\x65xtension_descriptor\x18H \x01(\x0b\x32$.perfetto.protos.ExtensionDescriptorH\x00\x12:\n\netw_events\x18_ \x01(\x0b\x32$.perfetto.protos.EtwTraceEventBundleH\x00\x12/\n\nv8_js_code\x18\x63 \x01(\x0b\x32\x19.perfetto.protos.V8JsCodeH\x00\x12;\n\x10v8_internal_code\x18\x64 \x01(\x0b\x32\x1f.perfetto.protos.V8InternalCodeH\x00\x12\x33\n\x0cv8_wasm_code\x18\x65 \x01(\x0b\x32\x1b.perfetto.protos.V8WasmCodeH\x00\x12\x38\n\x0fv8_reg_exp_code\x18\x66 \x01(\x0b\x32\x1d.perfetto.protos.V8RegExpCodeH\x00\x12\x33\n\x0cv8_code_move\x18g \x01(\x0b\x32\x1b.perfetto.protos.V8CodeMoveH\x00\x12=\n\x11remote_clock_sync\x18k \x01(\x0b\x32 .perfetto.protos.RemoteClockSyncH\x00\x12?\n\x12pixel_modem_events\x18n \x01(\x0b\x32!.perfetto.protos.PixelModemEventsH\x00\x12N\n\x1apixel_modem_token_database\x18o \x01(\x0b\x32(.perfetto.protos.PixelModemTokenDatabaseH\x00\x12:\n\x16\x63lone_snapshot_trigger\x18q \x01(\x0b\x32\x18.perfetto.protos.TriggerH\x00\x12\x43\n\x14kernel_wakelock_data\x18s \x01(\x0b\x32#.perfetto.protos.KernelWakelockDataH\x00\x12:\n\x10\x63pu_per_uid_data\x18w \x01(\x0b\x32\x1e.perfetto.protos.CpuPerUidDataH\x00\x12\x35\n\tuser_list\x18{ \x01(\x0b\x32 .perfetto.protos.AndroidUserListH\x00\x12@\n\x0ejournald_event\x18\x84\x01 \x01(\x0b\x32%.perfetto.protos.SystemdJournaldEventH\x00\x12\x44\n\x14recovered_trace_info\x18\x8a\x01 \x01(\x0b\x32#.perfetto.protos.RecoveredTraceInfoH\x00\x12\x32\n\x0b\x66or_testing\x18\x84\x07 \x01(\x0b\x32\x1a.perfetto.protos.TestEventH\x00\x12\x15\n\x0btrusted_uid\x18\x03 \x01(\x05H\x01\x12$\n\x1atrusted_packet_sequence_id\x18\n \x01(\rH\x02\x12\x13\n\x0btrusted_pid\x18O \x01(\x05\x12\x34\n\rinterned_data\x18\x0c \x01(\x0b\x32\x1d.perfetto.protos.InternedData\x12\x16\n\x0esequence_flags\x18\r \x01(\r\x12!\n\x19incremental_state_cleared\x18) \x01(\x08\x12\x43\n\x15trace_packet_defaults\x18; \x01(\x0b\x32$.perfetto.protos.TracePacketDefaults\x12\x1f\n\x17previous_packet_dropped\x18* \x01(\r\x12 \n\x18\x66irst_packet_on_sequence\x18W \x01(\x08\x12\x12\n\nmachine_id\x18\x62 \x01(\r\x1a\xe1\x01\n\x08ProtoVms\x12@\n\x08instance\x18\x01 \x03(\x0b\x32..perfetto.protos.TracePacket.ProtoVms.Instance\x1a\x92\x01\n\x08Instance\x12+\n\x07program\x18\x01 \x01(\x0b\x32\x1a.perfetto.protos.VmProgram\x12+\n\x05state\x18\x02 \x01(\x0b\x32\x1c.perfetto.protos.TracePacket\x12\x17\n\x0fmemory_limit_kb\x18\x03 \x01(\r\x12\x13\n\x0bproducer_id\x18\x04 \x03(\x05\"h\n\rSequenceFlags\x12\x13\n\x0fSEQ_UNSPECIFIED\x10\x00\x12!\n\x1dSEQ_INCREMENTAL_STATE_CLEARED\x10\x01\x12\x1f\n\x1bSEQ_NEEDS_INCREMENTAL_STATE\x10\x02\"\xb0\x02\n\x0e\x44\x61taLossReason\x12\x19\n\x15\x44\x41TA_LOSS_UNSPECIFIED\x10\x00\x12\x15\n\x11\x44\x41TA_LOSS_PRESENT\x10\x01\x12\x16\n\x12\x44\x41TA_LOSS_READ_GAP\x10\x02\x12\x1d\n\x19\x44\x41TA_LOSS_CHUNK_CORRUPTED\x10\x04\x12!\n\x1d\x44\x41TA_LOSS_ORPHAN_CONTINUATION\x10\x08\x12\x1c\n\x18\x44\x41TA_LOSS_REASSEMBLY_GAP\x10\x10\x12%\n!DATA_LOSS_REASSEMBLY_BROKEN_CHAIN\x10 \x12\x17\n\x13\x44\x41TA_LOSS_OVERWRITE\x10@\x12\x1b\n\x16\x44\x41TA_LOSS_WRITER_ABORT\x10\x80\x01\x12\x17\n\x12\x44\x41TA_LOSS_SMB_FULL\x10\x80\x02*\x04\x08\x38\x10\x39*\x04\x08L\x10M*\x04\x08X\x10Y*\x04\x08\\\x10]*\x04\x08]\x10^*\x04\x08^\x10_*\x04\x08`\x10\x61*\x04\x08\x61\x10\x62*\x04\x08h\x10i*\x04\x08i\x10j*\x04\x08p\x10q*\x04\x08r\x10s*\x04\x08t\x10u*\x04\x08y\x10z*\x06\x08\xe8\x07\x10\xd0\x0f\x42\x06\n\x04\x64\x61taB\x16\n\x14optional_trusted_uidB%\n#optional_trusted_packet_sequence_idJ\x04\x08j\x10kJ\x04\x08\x37\x10\x38J\x04\x08P\x10QJ\x04\x08Q\x10R\"5\n\x05Trace\x12,\n\x06packet\x18\x01 \x03(\x0b\x32\x1c.perfetto.protos.TracePacket*c\n\x0cVmCursorEnum\x12\x19\n\x15VM_CURSOR_UNSPECIFIED\x10\x00\x12\x11\n\rVM_CURSOR_SRC\x10\x01\x12\x11\n\rVM_CURSOR_DST\x10\x02\x12\x12\n\x0eVM_CURSOR_BOTH\x10\x03*\xd9\x02\n\x0c\x42uiltinClock\x12\x19\n\x15\x42UILTIN_CLOCK_UNKNOWN\x10\x00\x12\x1a\n\x16\x42UILTIN_CLOCK_REALTIME\x10\x01\x12!\n\x1d\x42UILTIN_CLOCK_REALTIME_COARSE\x10\x02\x12\x1b\n\x17\x42UILTIN_CLOCK_MONOTONIC\x10\x03\x12\"\n\x1e\x42UILTIN_CLOCK_MONOTONIC_COARSE\x10\x04\x12\x1f\n\x1b\x42UILTIN_CLOCK_MONOTONIC_RAW\x10\x05\x12\x1a\n\x16\x42UILTIN_CLOCK_BOOTTIME\x10\x06\x12\x15\n\x11\x42UILTIN_CLOCK_TSC\x10\t\x12\x16\n\x12\x42UILTIN_CLOCK_PERF\x10\n\x12\x1c\n\x18\x42UILTIN_CLOCK_TRACE_FILE\x10\x0b\x12\x18\n\x14\x42UILTIN_CLOCK_MAX_ID\x10?\"\x04\x08\x07\x10\x07\"\x04\x08\x08\x10\x08*z\n\x0cSemanticType\x12\x1d\n\x19SEMANTIC_TYPE_UNSPECIFIED\x10\x00\x12\x18\n\x14SEMANTIC_TYPE_ATRACE\x10\x01\x12\x15\n\x11SEMANTIC_TYPE_JOB\x10\x02\x12\x1a\n\x16SEMANTIC_TYPE_WAKELOCK\x10\x03*\x8e\x01\n\x0c\x41ndroidLogId\x12\x0f\n\x0bLID_DEFAULT\x10\x00\x12\r\n\tLID_RADIO\x10\x01\x12\x0e\n\nLID_EVENTS\x10\x02\x12\x0e\n\nLID_SYSTEM\x10\x03\x12\r\n\tLID_CRASH\x10\x04\x12\r\n\tLID_STATS\x10\x05\x12\x10\n\x0cLID_SECURITY\x10\x06\x12\x0e\n\nLID_KERNEL\x10\x07*\x9b\x01\n\x12\x41ndroidLogPriority\x12\x14\n\x10PRIO_UNSPECIFIED\x10\x00\x12\x0f\n\x0bPRIO_UNUSED\x10\x01\x12\x10\n\x0cPRIO_VERBOSE\x10\x02\x12\x0e\n\nPRIO_DEBUG\x10\x03\x12\r\n\tPRIO_INFO\x10\x04\x12\r\n\tPRIO_WARN\x10\x05\x12\x0e\n\nPRIO_ERROR\x10\x06\x12\x0e\n\nPRIO_FATAL\x10\x07*\xc7\x01\n\rProtoLogLevel\x12\x1c\n\x18PROTOLOG_LEVEL_UNDEFINED\x10\x00\x12\x18\n\x14PROTOLOG_LEVEL_DEBUG\x10\x01\x12\x1a\n\x16PROTOLOG_LEVEL_VERBOSE\x10\x02\x12\x17\n\x13PROTOLOG_LEVEL_INFO\x10\x03\x12\x17\n\x13PROTOLOG_LEVEL_WARN\x10\x04\x12\x18\n\x14PROTOLOG_LEVEL_ERROR\x10\x05\x12\x16\n\x12PROTOLOG_LEVEL_WTF\x10\x06*\xf3\xfb\x02\n\x06\x41tomId\x12\x14\n\x10\x41TOM_UNSPECIFIED\x10\x00\x12\x1f\n\x1b\x41TOM_BLE_SCAN_STATE_CHANGED\x10\x02\x12\x1e\n\x1a\x41TOM_PROCESS_STATE_CHANGED\x10\x03\x12!\n\x1d\x41TOM_BLE_SCAN_RESULT_RECEIVED\x10\x04\x12\x1d\n\x19\x41TOM_SENSOR_STATE_CHANGED\x10\x05\x12\x1f\n\x1b\x41TOM_GPS_SCAN_STATE_CHANGED\x10\x06\x12\x1b\n\x17\x41TOM_SYNC_STATE_CHANGED\x10\x07\x12$\n ATOM_SCHEDULED_JOB_STATE_CHANGED\x10\x08\x12\"\n\x1e\x41TOM_SCREEN_BRIGHTNESS_CHANGED\x10\t\x12\x1f\n\x1b\x41TOM_WAKELOCK_STATE_CHANGED\x10\n\x12,\n(ATOM_LONG_PARTIAL_WAKELOCK_STATE_CHANGED\x10\x0b\x12)\n%ATOM_MOBILE_RADIO_POWER_STATE_CHANGED\x10\x0c\x12\'\n#ATOM_WIFI_RADIO_POWER_STATE_CHANGED\x10\r\x12-\n)ATOM_ACTIVITY_MANAGER_SLEEP_STATE_CHANGED\x10\x0e\x12$\n ATOM_MEMORY_FACTOR_STATE_CHANGED\x10\x0f\x12%\n!ATOM_EXCESSIVE_CPU_USAGE_REPORTED\x10\x10\x12\x1d\n\x19\x41TOM_CACHED_KILL_REPORTED\x10\x11\x12%\n!ATOM_PROCESS_MEMORY_STAT_REPORTED\x10\x12\x12\x17\n\x13\x41TOM_LAUNCHER_EVENT\x10\x13\x12)\n%ATOM_BATTERY_SAVER_MODE_STATE_CHANGED\x10\x14\x12\'\n#ATOM_DEVICE_IDLE_MODE_STATE_CHANGED\x10\x15\x12)\n%ATOM_DEVICE_IDLING_MODE_STATE_CHANGED\x10\x16\x12\x1c\n\x18\x41TOM_AUDIO_STATE_CHANGED\x10\x17\x12\"\n\x1e\x41TOM_MEDIA_CODEC_STATE_CHANGED\x10\x18\x12\x1d\n\x19\x41TOM_CAMERA_STATE_CHANGED\x10\x19\x12!\n\x1d\x41TOM_FLASHLIGHT_STATE_CHANGED\x10\x1a\x12\"\n\x1e\x41TOM_UID_PROCESS_STATE_CHANGED\x10\x1b\x12)\n%ATOM_PROCESS_LIFE_CYCLE_STATE_CHANGED\x10\x1c\x12\x1d\n\x19\x41TOM_SCREEN_STATE_CHANGED\x10\x1d\x12\x1e\n\x1a\x41TOM_BATTERY_LEVEL_CHANGED\x10\x1e\x12\x1f\n\x1b\x41TOM_CHARGING_STATE_CHANGED\x10\x1f\x12\x1e\n\x1a\x41TOM_PLUGGED_STATE_CHANGED\x10 \x12\"\n\x1e\x41TOM_INTERACTIVE_STATE_CHANGED\x10!\x12\x1d\n\x19\x41TOM_TOUCH_EVENT_REPORTED\x10\"\x12\x1e\n\x1a\x41TOM_WAKEUP_ALARM_OCCURRED\x10#\x12\x1f\n\x1b\x41TOM_KERNEL_WAKEUP_REPORTED\x10$\x12 \n\x1c\x41TOM_WIFI_LOCK_STATE_CHANGED\x10%\x12%\n!ATOM_WIFI_SIGNAL_STRENGTH_CHANGED\x10&\x12 \n\x1c\x41TOM_WIFI_SCAN_STATE_CHANGED\x10\'\x12&\n\"ATOM_PHONE_SIGNAL_STRENGTH_CHANGED\x10(\x12\x18\n\x14\x41TOM_SETTING_CHANGED\x10)\x12*\n&ATOM_ACTIVITY_FOREGROUND_STATE_CHANGED\x10*\x12\x1d\n\x19\x41TOM_ISOLATED_UID_CHANGED\x10+\x12\x1f\n\x1b\x41TOM_PACKET_WAKEUP_OCCURRED\x10,\x12 \n\x1c\x41TOM_WALL_CLOCK_TIME_SHIFTED\x10-\x12\x19\n\x15\x41TOM_ANOMALY_DETECTED\x10.\x12 \n\x1c\x41TOM_APP_BREADCRUMB_REPORTED\x10/\x12\x1b\n\x17\x41TOM_APP_START_OCCURRED\x10\x30\x12\x1b\n\x17\x41TOM_APP_START_CANCELED\x10\x31\x12\x1e\n\x1a\x41TOM_APP_START_FULLY_DRAWN\x10\x32\x12\x1a\n\x16\x41TOM_LMK_KILL_OCCURRED\x10\x33\x12)\n%ATOM_PICTURE_IN_PICTURE_STATE_CHANGED\x10\x34\x12*\n&ATOM_WIFI_MULTICAST_LOCK_STATE_CHANGED\x10\x35\x12(\n$ATOM_APP_START_MEMORY_STATE_CAPTURED\x10\x37\x12#\n\x1f\x41TOM_SHUTDOWN_SEQUENCE_REPORTED\x10\x38\x12\x1f\n\x1b\x41TOM_BOOT_SEQUENCE_REPORTED\x10\x39\x12\x1e\n\x1a\x41TOM_OVERLAY_STATE_CHANGED\x10;\x12)\n%ATOM_FOREGROUND_SERVICE_STATE_CHANGED\x10<\x12\x1b\n\x17\x41TOM_CALL_STATE_CHANGED\x10=\x12\x1f\n\x1b\x41TOM_KEYGUARD_STATE_CHANGED\x10>\x12\'\n#ATOM_KEYGUARD_BOUNCER_STATE_CHANGED\x10?\x12*\n&ATOM_KEYGUARD_BOUNCER_PASSWORD_ENTERED\x10@\x12\x11\n\rATOM_APP_DIED\x10\x41\x12\'\n#ATOM_RESOURCE_CONFIGURATION_CHANGED\x10\x42\x12(\n$ATOM_BLUETOOTH_ENABLED_STATE_CHANGED\x10\x43\x12+\n\'ATOM_BLUETOOTH_CONNECTION_STATE_CHANGED\x10\x44\x12#\n\x1f\x41TOM_GPS_SIGNAL_QUALITY_CHANGED\x10\x45\x12$\n ATOM_USB_CONNECTOR_STATE_CHANGED\x10\x46\x12#\n\x1f\x41TOM_SPEAKER_IMPEDANCE_REPORTED\x10G\x12\x18\n\x14\x41TOM_HARDWARE_FAILED\x10H\x12\x1f\n\x1b\x41TOM_PHYSICAL_DROP_DETECTED\x10I\x12\x1f\n\x1b\x41TOM_CHARGE_CYCLES_REPORTED\x10J\x12(\n$ATOM_MOBILE_CONNECTION_STATE_CHANGED\x10K\x12(\n$ATOM_MOBILE_RADIO_TECHNOLOGY_CHANGED\x10L\x12\x1c\n\x18\x41TOM_USB_DEVICE_ATTACHED\x10M\x12\x1b\n\x17\x41TOM_APP_CRASH_OCCURRED\x10N\x12\x15\n\x11\x41TOM_ANR_OCCURRED\x10O\x12\x15\n\x11\x41TOM_WTF_OCCURRED\x10P\x12\x19\n\x15\x41TOM_LOW_MEM_REPORTED\x10Q\x12\x15\n\x11\x41TOM_GENERIC_ATOM\x10R\x12\x1f\n\x1b\x41TOM_VIBRATOR_STATE_CHANGED\x10T\x12$\n ATOM_DEFERRED_JOB_STATS_REPORTED\x10U\x12\x1b\n\x17\x41TOM_THERMAL_THROTTLING\x10V\x12\x1b\n\x17\x41TOM_BIOMETRIC_ACQUIRED\x10W\x12 \n\x1c\x41TOM_BIOMETRIC_AUTHENTICATED\x10X\x12!\n\x1d\x41TOM_BIOMETRIC_ERROR_OCCURRED\x10Y\x12\x1a\n\x16\x41TOM_UI_EVENT_REPORTED\x10Z\x12 \n\x1c\x41TOM_BATTERY_HEALTH_SNAPSHOT\x10[\x12\x10\n\x0c\x41TOM_SLOW_IO\x10\\\x12 \n\x1c\x41TOM_BATTERY_CAUSED_SHUTDOWN\x10]\x12$\n ATOM_PHONE_SERVICE_STATE_CHANGED\x10^\x12\x1c\n\x18\x41TOM_PHONE_STATE_CHANGED\x10_\x12!\n\x1d\x41TOM_USER_RESTRICTION_CHANGED\x10`\x12\x1c\n\x18\x41TOM_SETTINGS_UI_CHANGED\x10\x61\x12#\n\x1f\x41TOM_CONNECTIVITY_STATE_CHANGED\x10\x62\x12\x1e\n\x1a\x41TOM_SERVICE_STATE_CHANGED\x10\x63\x12 \n\x1c\x41TOM_SERVICE_LAUNCH_REPORTED\x10\x64\x12\"\n\x1e\x41TOM_FLAG_FLIP_UPDATE_OCCURRED\x10\x65\x12\"\n\x1e\x41TOM_BINARY_PUSH_STATE_CHANGED\x10\x66\x12\x1c\n\x18\x41TOM_DEVICE_POLICY_EVENT\x10g\x12!\n\x1d\x41TOM_DOCS_UI_FILE_OP_CANCELED\x10h\x12\x30\n,ATOM_DOCS_UI_FILE_OP_COPY_MOVE_MODE_REPORTED\x10i\x12 \n\x1c\x41TOM_DOCS_UI_FILE_OP_FAILURE\x10j\x12!\n\x1d\x41TOM_DOCS_UI_PROVIDER_FILE_OP\x10k\x12.\n*ATOM_DOCS_UI_INVALID_SCOPED_ACCESS_REQUEST\x10l\x12 \n\x1c\x41TOM_DOCS_UI_LAUNCH_REPORTED\x10m\x12\x1d\n\x19\x41TOM_DOCS_UI_ROOT_VISITED\x10n\x12\x1b\n\x17\x41TOM_DOCS_UI_STARTUP_MS\x10o\x12%\n!ATOM_DOCS_UI_USER_ACTION_REPORTED\x10p\x12#\n\x1f\x41TOM_WIFI_ENABLED_STATE_CHANGED\x10q\x12#\n\x1f\x41TOM_WIFI_RUNNING_STATE_CHANGED\x10r\x12\x16\n\x12\x41TOM_APP_COMPACTED\x10s\x12#\n\x1f\x41TOM_NETWORK_DNS_EVENT_REPORTED\x10t\x12.\n*ATOM_DOCS_UI_PICKER_LAUNCHED_FROM_REPORTED\x10u\x12%\n!ATOM_DOCS_UI_PICK_RESULT_REPORTED\x10v\x12%\n!ATOM_DOCS_UI_SEARCH_MODE_REPORTED\x10w\x12%\n!ATOM_DOCS_UI_SEARCH_TYPE_REPORTED\x10x\x12\x19\n\x15\x41TOM_DATA_STALL_EVENT\x10y\x12$\n ATOM_RESCUE_PARTY_RESET_REPORTED\x10z\x12\x1f\n\x1b\x41TOM_SIGNED_CONFIG_REPORTED\x10{\x12\x1f\n\x1b\x41TOM_GNSS_NI_EVENT_REPORTED\x10|\x12.\n*ATOM_BLUETOOTH_LINK_LAYER_CONNECTION_EVENT\x10}\x12/\n+ATOM_BLUETOOTH_ACL_CONNECTION_STATE_CHANGED\x10~\x12/\n+ATOM_BLUETOOTH_SCO_CONNECTION_STATE_CHANGED\x10\x7f\x12\x18\n\x13\x41TOM_APP_DOWNGRADED\x10\x80\x01\x12(\n#ATOM_APP_OPTIMIZED_AFTER_DOWNGRADED\x10\x81\x01\x12#\n\x1e\x41TOM_LOW_STORAGE_STATE_CHANGED\x10\x82\x01\x12(\n#ATOM_GNSS_NFW_NOTIFICATION_REPORTED\x10\x83\x01\x12%\n ATOM_GNSS_CONFIGURATION_REPORTED\x10\x84\x01\x12*\n%ATOM_USB_PORT_OVERHEAT_EVENT_REPORTED\x10\x85\x01\x12\x1c\n\x17\x41TOM_NFC_ERROR_OCCURRED\x10\x86\x01\x12\x1b\n\x16\x41TOM_NFC_STATE_CHANGED\x10\x87\x01\x12\x1b\n\x16\x41TOM_NFC_BEAM_OCCURRED\x10\x88\x01\x12$\n\x1f\x41TOM_NFC_CARDEMULATION_OCCURRED\x10\x89\x01\x12\x1a\n\x15\x41TOM_NFC_TAG_OCCURRED\x10\x8a\x01\x12&\n!ATOM_NFC_HCE_TRANSACTION_OCCURRED\x10\x8b\x01\x12\x1a\n\x15\x41TOM_SE_STATE_CHANGED\x10\x8c\x01\x12\x1b\n\x16\x41TOM_SE_OMAPI_REPORTED\x10\x8d\x01\x12-\n(ATOM_BROADCAST_DISPATCH_LATENCY_REPORTED\x10\x8e\x01\x12\x33\n.ATOM_ATTENTION_MANAGER_SERVICE_RESULT_REPORTED\x10\x8f\x01\x12 \n\x1b\x41TOM_ADB_CONNECTION_CHANGED\x10\x90\x01\x12\"\n\x1d\x41TOM_SPEECH_DSP_STAT_REPORTED\x10\x91\x01\x12\"\n\x1d\x41TOM_USB_CONTAMINANT_REPORTED\x10\x92\x01\x12$\n\x1f\x41TOM_WATCHDOG_ROLLBACK_OCCURRED\x10\x93\x01\x12\x30\n+ATOM_BIOMETRIC_SYSTEM_HEALTH_ISSUE_DETECTED\x10\x94\x01\x12\x1b\n\x16\x41TOM_BUBBLE_UI_CHANGED\x10\x95\x01\x12*\n%ATOM_SCHEDULED_JOB_CONSTRAINT_CHANGED\x10\x96\x01\x12)\n$ATOM_BLUETOOTH_ACTIVE_DEVICE_CHANGED\x10\x97\x01\x12/\n*ATOM_BLUETOOTH_A2DP_PLAYBACK_STATE_CHANGED\x10\x98\x01\x12-\n(ATOM_BLUETOOTH_A2DP_CODEC_CONFIG_CHANGED\x10\x99\x01\x12\x31\n,ATOM_BLUETOOTH_A2DP_CODEC_CAPABILITY_CHANGED\x10\x9a\x01\x12\x30\n+ATOM_BLUETOOTH_A2DP_AUDIO_UNDERRUN_REPORTED\x10\x9b\x01\x12/\n*ATOM_BLUETOOTH_A2DP_AUDIO_OVERRUN_REPORTED\x10\x9c\x01\x12(\n#ATOM_BLUETOOTH_DEVICE_RSSI_REPORTED\x10\x9d\x01\x12:\n5ATOM_BLUETOOTH_DEVICE_FAILED_CONTACT_COUNTER_REPORTED\x10\x9e\x01\x12\x32\n-ATOM_BLUETOOTH_DEVICE_TX_POWER_LEVEL_REPORTED\x10\x9f\x01\x12(\n#ATOM_BLUETOOTH_HCI_TIMEOUT_REPORTED\x10\xa0\x01\x12+\n&ATOM_BLUETOOTH_QUALITY_REPORT_REPORTED\x10\xa1\x01\x12(\n#ATOM_BLUETOOTH_DEVICE_INFO_REPORTED\x10\xa2\x01\x12\x30\n+ATOM_BLUETOOTH_REMOTE_VERSION_INFO_REPORTED\x10\xa3\x01\x12*\n%ATOM_BLUETOOTH_SDP_ATTRIBUTE_REPORTED\x10\xa4\x01\x12&\n!ATOM_BLUETOOTH_BOND_STATE_CHANGED\x10\xa5\x01\x12\x32\n-ATOM_BLUETOOTH_CLASSIC_PAIRING_EVENT_REPORTED\x10\xa6\x01\x12.\n)ATOM_BLUETOOTH_SMP_PAIRING_EVENT_REPORTED\x10\xa7\x01\x12+\n&ATOM_SCREEN_TIMEOUT_EXTENSION_REPORTED\x10\xa8\x01\x12\x1c\n\x17\x41TOM_PROCESS_START_TIME\x10\xa9\x01\x12\x32\n-ATOM_PERMISSION_GRANT_REQUEST_RESULT_REPORTED\x10\xaa\x01\x12\x33\n.ATOM_BLUETOOTH_SOCKET_CONNECTION_STATE_CHANGED\x10\xab\x01\x12)\n$ATOM_DEVICE_IDENTIFIER_ACCESS_DENIED\x10\xac\x01\x12)\n$ATOM_BUBBLE_DEVELOPER_ERROR_REPORTED\x10\xad\x01\x12\'\n\"ATOM_ASSIST_GESTURE_STAGE_REPORTED\x10\xae\x01\x12*\n%ATOM_ASSIST_GESTURE_FEEDBACK_REPORTED\x10\xaf\x01\x12*\n%ATOM_ASSIST_GESTURE_PROGRESS_REPORTED\x10\xb0\x01\x12\"\n\x1d\x41TOM_TOUCH_GESTURE_CLASSIFIED\x10\xb1\x01\x12\x19\n\x14\x41TOM_HIDDEN_API_USED\x10\xb2\x01\x12\x1a\n\x15\x41TOM_STYLE_UI_CHANGED\x10\xb3\x01\x12\'\n\"ATOM_PRIVACY_INDICATORS_INTERACTED\x10\xb4\x01\x12\x32\n-ATOM_APP_INSTALL_ON_EXTERNAL_STORAGE_REPORTED\x10\xb5\x01\x12 \n\x1b\x41TOM_NETWORK_STACK_REPORTED\x10\xb6\x01\x12$\n\x1f\x41TOM_APP_MOVED_STORAGE_REPORTED\x10\xb7\x01\x12\x1c\n\x17\x41TOM_BIOMETRIC_ENROLLED\x10\xb8\x01\x12)\n$ATOM_SYSTEM_SERVER_WATCHDOG_OCCURRED\x10\xb9\x01\x12\x1d\n\x18\x41TOM_TOMB_STONE_OCCURRED\x10\xba\x01\x12,\n\'ATOM_BLUETOOTH_CLASS_OF_DEVICE_REPORTED\x10\xbb\x01\x12%\n ATOM_INTELLIGENCE_EVENT_REPORTED\x10\xbc\x01\x12\x33\n.ATOM_THERMAL_THROTTLING_SEVERITY_STATE_CHANGED\x10\xbd\x01\x12&\n!ATOM_ROLE_REQUEST_RESULT_REPORTED\x10\xbe\x01\x12+\n&ATOM_MEDIAMETRICS_AUDIOPOLICY_REPORTED\x10\xbf\x01\x12+\n&ATOM_MEDIAMETRICS_AUDIORECORD_REPORTED\x10\xc0\x01\x12+\n&ATOM_MEDIAMETRICS_AUDIOTHREAD_REPORTED\x10\xc1\x01\x12*\n%ATOM_MEDIAMETRICS_AUDIOTRACK_REPORTED\x10\xc2\x01\x12%\n ATOM_MEDIAMETRICS_CODEC_REPORTED\x10\xc3\x01\x12,\n\'ATOM_MEDIAMETRICS_DRM_WIDEVINE_REPORTED\x10\xc4\x01\x12)\n$ATOM_MEDIAMETRICS_EXTRACTOR_REPORTED\x10\xc5\x01\x12(\n#ATOM_MEDIAMETRICS_MEDIADRM_REPORTED\x10\xc6\x01\x12(\n#ATOM_MEDIAMETRICS_NUPLAYER_REPORTED\x10\xc7\x01\x12(\n#ATOM_MEDIAMETRICS_RECORDER_REPORTED\x10\xc8\x01\x12*\n%ATOM_MEDIAMETRICS_DRMMANAGER_REPORTED\x10\xc9\x01\x12!\n\x1c\x41TOM_CAR_POWER_STATE_CHANGED\x10\xcb\x01\x12\x1a\n\x15\x41TOM_GARAGE_MODE_INFO\x10\xcc\x01\x12\x1c\n\x17\x41TOM_TEST_ATOM_REPORTED\x10\xcd\x01\x12\x32\n-ATOM_CONTENT_CAPTURE_CALLER_MISMATCH_REPORTED\x10\xce\x01\x12(\n#ATOM_CONTENT_CAPTURE_SERVICE_EVENTS\x10\xcf\x01\x12(\n#ATOM_CONTENT_CAPTURE_SESSION_EVENTS\x10\xd0\x01\x12!\n\x1c\x41TOM_CONTENT_CAPTURE_FLUSHED\x10\xd1\x01\x12-\n(ATOM_LOCATION_MANAGER_API_USAGE_REPORTED\x10\xd2\x01\x12\x35\n0ATOM_REVIEW_PERMISSIONS_FRAGMENT_RESULT_REPORTED\x10\xd3\x01\x12,\n\'ATOM_RUNTIME_PERMISSIONS_UPGRADE_RESULT\x10\xd4\x01\x12\x33\n.ATOM_GRANT_PERMISSIONS_ACTIVITY_BUTTON_ACTIONS\x10\xd5\x01\x12\x33\n.ATOM_LOCATION_ACCESS_CHECK_NOTIFICATION_ACTION\x10\xd6\x01\x12\x31\n,ATOM_APP_PERMISSION_FRAGMENT_ACTION_REPORTED\x10\xd7\x01\x12(\n#ATOM_APP_PERMISSION_FRAGMENT_VIEWED\x10\xd8\x01\x12)\n$ATOM_APP_PERMISSIONS_FRAGMENT_VIEWED\x10\xd9\x01\x12)\n$ATOM_PERMISSION_APPS_FRAGMENT_VIEWED\x10\xda\x01\x12\x1e\n\x19\x41TOM_TEXT_SELECTION_EVENT\x10\xdb\x01\x12\x1c\n\x17\x41TOM_TEXT_LINKIFY_EVENT\x10\xdc\x01\x12$\n\x1f\x41TOM_CONVERSATION_ACTIONS_EVENT\x10\xdd\x01\x12\"\n\x1d\x41TOM_LANGUAGE_DETECTION_EVENT\x10\xde\x01\x12&\n!ATOM_EXCLUSION_RECT_STATE_CHANGED\x10\xdf\x01\x12(\n#ATOM_BACK_GESTURE_REPORTED_REPORTED\x10\xe0\x01\x12/\n*ATOM_UPDATE_ENGINE_UPDATE_ATTEMPT_REPORTED\x10\xe1\x01\x12\x32\n-ATOM_UPDATE_ENGINE_SUCCESSFUL_UPDATE_REPORTED\x10\xe2\x01\x12\x1d\n\x18\x41TOM_CAMERA_ACTION_EVENT\x10\xe3\x01\x12+\n&ATOM_APP_COMPATIBILITY_CHANGE_REPORTED\x10\xe4\x01\x12\x1b\n\x16\x41TOM_PERFETTO_UPLOADED\x10\xe5\x01\x12-\n(ATOM_VMS_CLIENT_CONNECTION_STATE_CHANGED\x10\xe6\x01\x12&\n!ATOM_MEDIA_PROVIDER_SCAN_OCCURRED\x10\xe9\x01\x12\x1f\n\x1a\x41TOM_MEDIA_CONTENT_DELETED\x10\xea\x01\x12-\n(ATOM_MEDIA_PROVIDER_PERMISSION_REQUESTED\x10\xeb\x01\x12\'\n\"ATOM_MEDIA_PROVIDER_SCHEMA_CHANGED\x10\xec\x01\x12\x32\n-ATOM_MEDIA_PROVIDER_IDLE_MAINTENANCE_FINISHED\x10\xed\x01\x12)\n$ATOM_REBOOT_ESCROW_RECOVERY_REPORTED\x10\xee\x01\x12+\n&ATOM_BOOT_TIME_EVENT_DURATION_REPORTED\x10\xef\x01\x12/\n*ATOM_BOOT_TIME_EVENT_ELAPSED_TIME_REPORTED\x10\xf0\x01\x12+\n&ATOM_BOOT_TIME_EVENT_UTC_TIME_REPORTED\x10\xf1\x01\x12-\n(ATOM_BOOT_TIME_EVENT_ERROR_CODE_REPORTED\x10\xf2\x01\x12#\n\x1e\x41TOM_USERSPACE_REBOOT_REPORTED\x10\xf3\x01\x12\x1f\n\x1a\x41TOM_NOTIFICATION_REPORTED\x10\xf4\x01\x12%\n ATOM_NOTIFICATION_PANEL_REPORTED\x10\xf5\x01\x12\'\n\"ATOM_NOTIFICATION_CHANNEL_MODIFIED\x10\xf6\x01\x12)\n$ATOM_INTEGRITY_CHECK_RESULT_REPORTED\x10\xf7\x01\x12 \n\x1b\x41TOM_INTEGRITY_RULES_PUSHED\x10\xf8\x01\x12\x1d\n\x18\x41TOM_CB_MESSAGE_REPORTED\x10\xf9\x01\x12\x1a\n\x15\x41TOM_CB_MESSAGE_ERROR\x10\xfa\x01\x12#\n\x1e\x41TOM_WIFI_HEALTH_STAT_REPORTED\x10\xfb\x01\x12$\n\x1f\x41TOM_WIFI_FAILURE_STAT_REPORTED\x10\xfc\x01\x12)\n$ATOM_WIFI_CONNECTION_RESULT_REPORTED\x10\xfd\x01\x12\x1c\n\x17\x41TOM_APP_FREEZE_CHANGED\x10\xfe\x01\x12!\n\x1c\x41TOM_SNAPSHOT_MERGE_REPORTED\x10\xff\x01\x12\x31\n,ATOM_FOREGROUND_SERVICE_APP_OP_SESSION_ENDED\x10\x80\x02\x12\x1f\n\x1a\x41TOM_DISPLAY_JANK_REPORTED\x10\x81\x02\x12$\n\x1f\x41TOM_APP_STANDBY_BUCKET_CHANGED\x10\x82\x02\x12\x1c\n\x17\x41TOM_SHARESHEET_STARTED\x10\x83\x02\x12\x1a\n\x15\x41TOM_RANKING_SELECTED\x10\x84\x02\x12\"\n\x1d\x41TOM_TVSETTINGS_UI_INTERACTED\x10\x85\x02\x12\x1b\n\x16\x41TOM_LAUNCHER_SNAPSHOT\x10\x86\x02\x12\'\n\"ATOM_PACKAGE_INSTALLER_V2_REPORTED\x10\x87\x02\x12)\n$ATOM_USER_LIFECYCLE_JOURNEY_REPORTED\x10\x88\x02\x12\'\n\"ATOM_USER_LIFECYCLE_EVENT_OCCURRED\x10\x89\x02\x12)\n$ATOM_ACCESSIBILITY_SHORTCUT_REPORTED\x10\x8a\x02\x12(\n#ATOM_ACCESSIBILITY_SERVICE_REPORTED\x10\x8b\x02\x12(\n#ATOM_DOCS_UI_DRAG_AND_DROP_REPORTED\x10\x8c\x02\x12\"\n\x1d\x41TOM_APP_USAGE_EVENT_OCCURRED\x10\x8d\x02\x12*\n%ATOM_AUTO_REVOKE_NOTIFICATION_CLICKED\x10\x8e\x02\x12)\n$ATOM_AUTO_REVOKE_FRAGMENT_APP_VIEWED\x10\x8f\x02\x12&\n!ATOM_AUTO_REVOKED_APP_INTERACTION\x10\x90\x02\x12;\n6ATOM_APP_PERMISSION_GROUPS_FRAGMENT_AUTO_REVOKE_ACTION\x10\x91\x02\x12\"\n\x1d\x41TOM_EVS_USAGE_STATS_REPORTED\x10\x92\x02\x12)\n$ATOM_AUDIO_POWER_USAGE_DATA_REPORTED\x10\x93\x02\x12 \n\x1b\x41TOM_TV_TUNER_STATE_CHANGED\x10\x94\x02\x12(\n#ATOM_MEDIAOUTPUT_OP_SWITCH_REPORTED\x10\x95\x02\x12\x1d\n\x18\x41TOM_CB_MESSAGE_FILTERED\x10\x96\x02\x12\x1d\n\x18\x41TOM_TV_TUNER_DVR_STATUS\x10\x97\x02\x12$\n\x1f\x41TOM_TV_CAS_SESSION_OPEN_STATUS\x10\x98\x02\x12\'\n\"ATOM_ASSISTANT_INVOCATION_REPORTED\x10\x99\x02\x12\x1f\n\x1a\x41TOM_DISPLAY_WAKE_REPORTED\x10\x9a\x02\x12\x33\n.ATOM_CAR_USER_HAL_MODIFY_USER_REQUEST_REPORTED\x10\x9b\x02\x12\x34\n/ATOM_CAR_USER_HAL_MODIFY_USER_RESPONSE_REPORTED\x10\x9c\x02\x12\x34\n/ATOM_CAR_USER_HAL_POST_SWITCH_RESPONSE_REPORTED\x10\x9d\x02\x12\x39\n4ATOM_CAR_USER_HAL_INITIAL_USER_INFO_REQUEST_REPORTED\x10\x9e\x02\x12:\n5ATOM_CAR_USER_HAL_INITIAL_USER_INFO_RESPONSE_REPORTED\x10\x9f\x02\x12\x38\n3ATOM_CAR_USER_HAL_USER_ASSOCIATION_REQUEST_REPORTED\x10\xa0\x02\x12=\n8ATOM_CAR_USER_HAL_SET_USER_ASSOCIATION_RESPONSE_REPORTED\x10\xa1\x02\x12*\n%ATOM_NETWORK_IP_PROVISIONING_REPORTED\x10\xa2\x02\x12%\n ATOM_NETWORK_DHCP_RENEW_REPORTED\x10\xa3\x02\x12%\n ATOM_NETWORK_VALIDATION_REPORTED\x10\xa4\x02\x12&\n!ATOM_NETWORK_STACK_QUIRK_REPORTED\x10\xa5\x02\x12\x36\n1ATOM_MEDIAMETRICS_AUDIORECORDDEVICEUSAGE_REPORTED\x10\xa6\x02\x12\x36\n1ATOM_MEDIAMETRICS_AUDIOTHREADDEVICEUSAGE_REPORTED\x10\xa7\x02\x12\x35\n0ATOM_MEDIAMETRICS_AUDIOTRACKDEVICEUSAGE_REPORTED\x10\xa8\x02\x12\x35\n0ATOM_MEDIAMETRICS_AUDIODEVICECONNECTION_REPORTED\x10\xa9\x02\x12\x18\n\x13\x41TOM_BLOB_COMMITTED\x10\xaa\x02\x12\x15\n\x10\x41TOM_BLOB_LEASED\x10\xab\x02\x12\x15\n\x10\x41TOM_BLOB_OPENED\x10\xac\x02\x12+\n&ATOM_CONTACTS_PROVIDER_STATUS_REPORTED\x10\xad\x02\x12%\n ATOM_KEYSTORE_KEY_EVENT_REPORTED\x10\xae\x02\x12$\n\x1f\x41TOM_NETWORK_TETHERING_REPORTED\x10\xaf\x02\x12\x1c\n\x17\x41TOM_IME_TOUCH_REPORTED\x10\xb0\x02\x12,\n\'ATOM_UI_INTERACTION_FRAME_INFO_REPORTED\x10\xb1\x02\x12$\n\x1f\x41TOM_UI_ACTION_LATENCY_REPORTED\x10\xb2\x02\x12\"\n\x1d\x41TOM_WIFI_DISCONNECT_REPORTED\x10\xb3\x02\x12\'\n\"ATOM_WIFI_CONNECTION_STATE_CHANGED\x10\xb4\x02\x12(\n#ATOM_HDMI_CEC_ACTIVE_SOURCE_CHANGED\x10\xb5\x02\x12#\n\x1e\x41TOM_HDMI_CEC_MESSAGE_REPORTED\x10\xb6\x02\x12\x17\n\x12\x41TOM_AIRPLANE_MODE\x10\xb7\x02\x12\x17\n\x12\x41TOM_MODEM_RESTART\x10\xb8\x02\x12&\n!ATOM_CARRIER_ID_MISMATCH_REPORTED\x10\xb9\x02\x12\"\n\x1d\x41TOM_CARRIER_ID_TABLE_UPDATED\x10\xba\x02\x12&\n!ATOM_DATA_STALL_RECOVERY_REPORTED\x10\xbb\x02\x12+\n&ATOM_MEDIAMETRICS_MEDIAPARSER_REPORTED\x10\xbc\x02\x12 \n\x1b\x41TOM_TLS_HANDSHAKE_REPORTED\x10\xbd\x02\x12,\n\'ATOM_TEXT_CLASSIFIER_API_USAGE_REPORTED\x10\xbe\x02\x12*\n%ATOM_CAR_WATCHDOG_KILL_STATS_REPORTED\x10\xbf\x02\x12(\n#ATOM_MEDIAMETRICS_PLAYBACK_REPORTED\x10\xc0\x02\x12$\n\x1f\x41TOM_MEDIA_NETWORK_INFO_CHANGED\x10\xc1\x02\x12&\n!ATOM_MEDIA_PLAYBACK_STATE_CHANGED\x10\xc2\x02\x12\'\n\"ATOM_MEDIA_PLAYBACK_ERROR_REPORTED\x10\xc3\x02\x12&\n!ATOM_MEDIA_PLAYBACK_TRACK_CHANGED\x10\xc4\x02\x12\x1c\n\x17\x41TOM_WIFI_SCAN_REPORTED\x10\xc5\x02\x12 \n\x1b\x41TOM_WIFI_PNO_SCAN_REPORTED\x10\xc6\x02\x12\x1a\n\x15\x41TOM_TIF_TUNE_CHANGED\x10\xc7\x02\x12\x1e\n\x19\x41TOM_AUTO_ROTATE_REPORTED\x10\xc8\x02\x12\x1a\n\x15\x41TOM_PERFETTO_TRIGGER\x10\xc9\x02\x12\x1a\n\x15\x41TOM_TRANSCODING_DATA\x10\xca\x02\x12)\n$ATOM_IMS_SERVICE_ENTITLEMENT_UPDATED\x10\xcb\x02\x12\x18\n\x13\x41TOM_DEVICE_ROTATED\x10\xcd\x02\x12(\n#ATOM_SIM_SPECIFIC_SETTINGS_RESTORED\x10\xce\x02\x12+\n&ATOM_TEXT_CLASSIFIER_DOWNLOAD_REPORTED\x10\xcf\x02\x12\x1b\n\x16\x41TOM_PIN_STORAGE_EVENT\x10\xd0\x02\x12\x1c\n\x17\x41TOM_FACE_DOWN_REPORTED\x10\xd1\x02\x12-\n(ATOM_BLUETOOTH_HAL_CRASH_REASON_REPORTED\x10\xd2\x02\x12,\n\'ATOM_REBOOT_ESCROW_PREPARATION_REPORTED\x10\xd3\x02\x12-\n(ATOM_REBOOT_ESCROW_LSKF_CAPTURE_REPORTED\x10\xd4\x02\x12\'\n\"ATOM_REBOOT_ESCROW_REBOOT_REPORTED\x10\xd5\x02\x12!\n\x1c\x41TOM_BINDER_LATENCY_REPORTED\x10\xd6\x02\x12,\n\'ATOM_MEDIAMETRICS_AAUDIOSTREAM_REPORTED\x10\xd7\x02\x12)\n$ATOM_MEDIA_TRANSCODING_SESSION_ENDED\x10\xd8\x02\x12&\n!ATOM_MAGNIFICATION_USAGE_REPORTED\x10\xd9\x02\x12\x31\n,ATOM_MAGNIFICATION_MODE_WITH_IME_ON_REPORTED\x10\xda\x02\x12(\n#ATOM_APP_SEARCH_CALL_STATS_REPORTED\x10\xdb\x02\x12\x30\n+ATOM_APP_SEARCH_PUT_DOCUMENT_STATS_REPORTED\x10\xdc\x02\x12 \n\x1b\x41TOM_DEVICE_CONTROL_CHANGED\x10\xdd\x02\x12\x1e\n\x19\x41TOM_DEVICE_STATE_CHANGED\x10\xde\x02\x12 \n\x1b\x41TOM_INPUTDEVICE_REGISTERED\x10\xdf\x02\x12\"\n\x1d\x41TOM_SMARTSPACE_CARD_REPORTED\x10\xe0\x02\x12*\n%ATOM_AUTH_PROMPT_AUTHENTICATE_INVOKED\x10\xe1\x02\x12/\n*ATOM_AUTH_MANAGER_CAN_AUTHENTICATE_INVOKED\x10\xe2\x02\x12$\n\x1f\x41TOM_AUTH_ENROLL_ACTION_INVOKED\x10\xe3\x02\x12\"\n\x1d\x41TOM_AUTH_DEPRECATED_API_USED\x10\xe4\x02\x12$\n\x1f\x41TOM_UNATTENDED_REBOOT_OCCURRED\x10\xe5\x02\x12\'\n\"ATOM_LONG_REBOOT_BLOCKING_REPORTED\x10\xe6\x02\x12\x33\n.ATOM_LOCATION_TIME_ZONE_PROVIDER_STATE_CHANGED\x10\xe7\x02\x12 \n\x1b\x41TOM_FDTRACK_EVENT_OCCURRED\x10\xec\x02\x12(\n#ATOM_TIMEOUT_AUTO_EXTENDED_REPORTED\x10\xed\x02\x12\x1f\n\x1a\x41TOM_ALARM_BATCH_DELIVERED\x10\xef\x02\x12\x19\n\x14\x41TOM_ALARM_SCHEDULED\x10\xf0\x02\x12\x30\n+ATOM_CAR_WATCHDOG_IO_OVERUSE_STATS_REPORTED\x10\xf1\x02\x12.\n)ATOM_USER_LEVEL_HIBERNATION_STATE_CHANGED\x10\xf2\x02\x12.\n)ATOM_APP_SEARCH_INITIALIZE_STATS_REPORTED\x10\xf3\x02\x12)\n$ATOM_APP_SEARCH_QUERY_STATS_REPORTED\x10\xf4\x02\x12\x1a\n\x15\x41TOM_APP_PROCESS_DIED\x10\xf5\x02\x12\x32\n-ATOM_NETWORK_IP_REACHABILITY_MONITOR_REPORTED\x10\xf6\x02\x12#\n\x1e\x41TOM_SLOW_INPUT_EVENT_REPORTED\x10\xf7\x02\x12)\n$ATOM_ANR_OCCURRED_PROCESSING_STARTED\x10\xf8\x02\x12*\n%ATOM_APP_SEARCH_REMOVE_STATS_REPORTED\x10\xf9\x02\x12\x1e\n\x19\x41TOM_MEDIA_CODEC_REPORTED\x10\xfa\x02\x12/\n*ATOM_PERMISSION_USAGE_FRAGMENT_INTERACTION\x10\xfb\x02\x12(\n#ATOM_PERMISSION_DETAILS_INTERACTION\x10\xfc\x02\x12+\n&ATOM_PRIVACY_SENSOR_TOGGLE_INTERACTION\x10\xfd\x02\x12+\n&ATOM_PRIVACY_TOGGLE_DIALOG_INTERACTION\x10\xfe\x02\x12,\n\'ATOM_APP_SEARCH_OPTIMIZE_STATS_REPORTED\x10\xff\x02\x12.\n)ATOM_NON_A11Y_TOOL_SERVICE_WARNING_REPORT\x10\x80\x03\x12\"\n\x1d\x41TOM_APP_COMPAT_STATE_CHANGED\x10\x82\x03\x12\x33\n.ATOM_SIZE_COMPAT_RESTART_BUTTON_EVENT_REPORTED\x10\x83\x03\x12 \n\x1b\x41TOM_SPLITSCREEN_UI_CHANGED\x10\x84\x03\x12(\n#ATOM_NETWORK_DNS_HANDSHAKE_REPORTED\x10\x85\x03\x12%\n ATOM_BLUETOOTH_CODE_PATH_COUNTER\x10\x86\x03\x12.\n)ATOM_BLUETOOTH_LE_BATCH_SCAN_REPORT_DELAY\x10\x88\x03\x12\x30\n+ATOM_ACCESSIBILITY_FLOATING_MENU_UI_CHANGED\x10\x89\x03\x12.\n)ATOM_NEURALNETWORKS_COMPILATION_COMPLETED\x10\x8a\x03\x12,\n\'ATOM_NEURALNETWORKS_EXECUTION_COMPLETED\x10\x8b\x03\x12+\n&ATOM_NEURALNETWORKS_COMPILATION_FAILED\x10\x8c\x03\x12)\n$ATOM_NEURALNETWORKS_EXECUTION_FAILED\x10\x8d\x03\x12\x1c\n\x17\x41TOM_CONTEXT_HUB_BOOTED\x10\x8e\x03\x12\x1f\n\x1a\x41TOM_CONTEXT_HUB_RESTARTED\x10\x8f\x03\x12\x36\n1ATOM_CONTEXT_HUB_LOADED_NANOAPP_SNAPSHOT_REPORTED\x10\x90\x03\x12\'\n\"ATOM_CHRE_CODE_DOWNLOAD_TRANSACTED\x10\x91\x03\x12\x1c\n\x17\x41TOM_UWB_SESSION_INITED\x10\x92\x03\x12\x1c\n\x17\x41TOM_UWB_SESSION_CLOSED\x10\x93\x03\x12$\n\x1f\x41TOM_UWB_FIRST_RANGING_RECEIVED\x10\x94\x03\x12*\n%ATOM_UWB_RANGING_MEASUREMENT_RECEIVED\x10\x95\x03\x12\x31\n,ATOM_TEXT_CLASSIFIER_DOWNLOAD_WORK_SCHEDULED\x10\x96\x03\x12\x31\n,ATOM_TEXT_CLASSIFIER_DOWNLOAD_WORK_COMPLETED\x10\x97\x03\x12\x1b\n\x16\x41TOM_CLIPBOARD_CLEARED\x10\x98\x03\x12\x1f\n\x1a\x41TOM_VM_CREATION_REQUESTED\x10\x99\x03\x12*\n%ATOM_NEARBY_DEVICE_SCAN_STATE_CHANGED\x10\x9a\x03\x12%\n ATOM_APPLICATION_LOCALES_CHANGED\x10\x9c\x03\x12\x30\n+ATOM_MEDIAMETRICS_AUDIOTRACKSTATUS_REPORTED\x10\x9d\x03\x12&\n!ATOM_FOLD_STATE_DURATION_REPORTED\x10\x9e\x03\x12>\n9ATOM_LOCATION_TIME_ZONE_PROVIDER_CONTROLLER_STATE_CHANGED\x10\x9f\x03\x12#\n\x1e\x41TOM_DISPLAY_HBM_STATE_CHANGED\x10\xa0\x03\x12(\n#ATOM_DISPLAY_HBM_BRIGHTNESS_CHANGED\x10\xa1\x03\x12,\n\'ATOM_PERSISTENT_URI_PERMISSIONS_FLUSHED\x10\xa2\x03\x12\x35\n0ATOM_EARLY_BOOT_COMP_OS_ARTIFACTS_CHECK_REPORTED\x10\xa3\x03\x12 \n\x1b\x41TOM_VBMETA_DIGEST_REPORTED\x10\xa4\x03\x12\x1c\n\x17\x41TOM_APEX_INFO_GATHERED\x10\xa5\x03\x12\x1b\n\x16\x41TOM_PVM_INFO_GATHERED\x10\xa6\x03\x12%\n ATOM_WEAR_SETTINGS_UI_INTERACTED\x10\xa7\x03\x12&\n!ATOM_TRACING_SERVICE_REPORT_EVENT\x10\xa8\x03\x12\x31\n,ATOM_MEDIAMETRICS_AUDIORECORDSTATUS_REPORTED\x10\xa9\x03\x12\x1a\n\x15\x41TOM_LAUNCHER_LATENCY\x10\xaa\x03\x12\x1f\n\x1a\x41TOM_DROPBOX_ENTRY_DROPPED\x10\xab\x03\x12&\n!ATOM_WIFI_P2P_CONNECTION_REPORTED\x10\xac\x03\x12\x1c\n\x17\x41TOM_GAME_STATE_CHANGED\x10\xad\x03\x12+\n&ATOM_HOTWORD_DETECTOR_CREATE_REQUESTED\x10\xae\x03\x12\x38\n3ATOM_HOTWORD_DETECTION_SERVICE_INIT_RESULT_REPORTED\x10\xaf\x03\x12-\n(ATOM_HOTWORD_DETECTION_SERVICE_RESTARTED\x10\xb0\x03\x12.\n)ATOM_HOTWORD_DETECTOR_KEYPHRASE_TRIGGERED\x10\xb1\x03\x12!\n\x1c\x41TOM_HOTWORD_DETECTOR_EVENTS\x10\xb2\x03\x12>\n9ATOM_BOOT_COMPLETED_BROADCAST_COMPLETION_LATENCY_REPORTED\x10\xb5\x03\x12\x30\n+ATOM_CONTACTS_INDEXER_UPDATE_STATS_REPORTED\x10\xb8\x03\x12*\n%ATOM_APP_BACKGROUND_RESTRICTIONS_INFO\x10\xb9\x03\x12/\n*ATOM_MMS_SMS_PROVIDER_GET_THREAD_ID_FAILED\x10\xba\x03\x12\x33\n.ATOM_MMS_SMS_DATABASE_HELPER_ON_UPGRADE_FAILED\x10\xbb\x03\x12\x35\n0ATOM_PERMISSION_REMINDER_NOTIFICATION_INTERACTED\x10\xbc\x03\x12\x30\n+ATOM_RECENT_PERMISSION_DECISIONS_INTERACTED\x10\xbd\x03\x12%\n ATOM_GNSS_PSDS_DOWNLOAD_REPORTED\x10\xbe\x03\x12.\n)ATOM_LE_AUDIO_CONNECTION_SESSION_REPORTED\x10\xbf\x03\x12-\n(ATOM_LE_AUDIO_BROADCAST_SESSION_REPORTED\x10\xc0\x03\x12!\n\x1c\x41TOM_DREAM_UI_EVENT_REPORTED\x10\xc1\x03\x12%\n ATOM_TASK_MANAGER_EVENT_REPORTED\x10\xc2\x03\x12 \n\x1b\x41TOM_CDM_ASSOCIATION_ACTION\x10\xc3\x03\x12\x46\nAATOM_MAGNIFICATION_TRIPLE_TAP_AND_HOLD_ACTIVATED_SESSION_REPORTED\x10\xc4\x03\x12\x46\nAATOM_MAGNIFICATION_FOLLOW_TYPING_FOCUS_ACTIVATED_SESSION_REPORTED\x10\xc5\x03\x12\x34\n/ATOM_ACCESSIBILITY_TEXT_READING_OPTIONS_CHANGED\x10\xc6\x03\x12+\n&ATOM_WIFI_SETUP_FAILURE_CRASH_REPORTED\x10\xc7\x03\x12#\n\x1e\x41TOM_UWB_DEVICE_ERROR_REPORTED\x10\xc8\x03\x12(\n#ATOM_ISOLATED_COMPILATION_SCHEDULED\x10\xc9\x03\x12$\n\x1f\x41TOM_ISOLATED_COMPILATION_ENDED\x10\xca\x03\x12\x36\n1ATOM_ONS_OPPORTUNISTIC_ESIM_PROVISIONING_COMPLETE\x10\xcb\x03\x12-\n(ATOM_SYSTEM_SERVER_PRE_WATCHDOG_OCCURRED\x10\xcc\x03\x12$\n\x1f\x41TOM_TELEPHONY_ANOMALY_DETECTED\x10\xcd\x03\x12$\n\x1f\x41TOM_LETTERBOX_POSITION_CHANGED\x10\xce\x03\x12)\n$ATOM_REMOTE_KEY_PROVISIONING_ATTEMPT\x10\xcf\x03\x12.\n)ATOM_REMOTE_KEY_PROVISIONING_NETWORK_INFO\x10\xd0\x03\x12(\n#ATOM_REMOTE_KEY_PROVISIONING_TIMING\x10\xd1\x03\x12+\n&ATOM_MEDIAOUTPUT_OP_INTERACTION_REPORT\x10\xd2\x03\x12!\n\x1c\x41TOM_SYNC_EXEMPTION_OCCURRED\x10\xd4\x03\x12.\n)ATOM_AUTOFILL_PRESENTATION_EVENT_REPORTED\x10\xd5\x03\x12\x1c\n\x17\x41TOM_DOCK_STATE_CHANGED\x10\xd6\x03\x12\'\n\"ATOM_SAFETY_SOURCE_STATE_COLLECTED\x10\xd7\x03\x12-\n(ATOM_SAFETY_CENTER_SYSTEM_EVENT_REPORTED\x10\xd8\x03\x12,\n\'ATOM_SAFETY_CENTER_INTERACTION_REPORTED\x10\xd9\x03\x12+\n&ATOM_SETTINGS_PROVIDER_SETTING_CHANGED\x10\xda\x03\x12+\n&ATOM_BROADCAST_DELIVERY_EVENT_REPORTED\x10\xdb\x03\x12(\n#ATOM_SERVICE_REQUEST_EVENT_REPORTED\x10\xdc\x03\x12-\n(ATOM_PROVIDER_ACQUISITION_EVENT_REPORTED\x10\xdd\x03\x12(\n#ATOM_BLUETOOTH_DEVICE_NAME_REPORTED\x10\xde\x03\x12\x1b\n\x16\x41TOM_CB_CONFIG_UPDATED\x10\xdf\x03\x12\"\n\x1d\x41TOM_CB_MODULE_ERROR_REPORTED\x10\xe0\x03\x12$\n\x1f\x41TOM_CB_SERVICE_FEATURE_CHANGED\x10\xe1\x03\x12%\n ATOM_CB_RECEIVER_FEATURE_CHANGED\x10\xe2\x03\x12\x31\n,ATOM_PRIVACY_SIGNAL_NOTIFICATION_INTERACTION\x10\xe4\x03\x12/\n*ATOM_PRIVACY_SIGNAL_ISSUE_CARD_INTERACTION\x10\xe5\x03\x12%\n ATOM_PRIVACY_SIGNALS_JOB_FAILURE\x10\xe6\x03\x12\x1c\n\x17\x41TOM_VIBRATION_REPORTED\x10\xe7\x03\x12\x1b\n\x16\x41TOM_UWB_RANGING_START\x10\xe9\x03\x12\x1a\n\x15\x41TOM_APP_COMPACTED_V2\x10\xeb\x03\x12$\n\x1f\x41TOM_DISPLAY_BRIGHTNESS_CHANGED\x10\xee\x03\x12!\n\x1c\x41TOM_ACTIVITY_ACTION_BLOCKED\x10\xef\x03\x12-\n(ATOM_NETWORK_DNS_SERVER_SUPPORT_REPORTED\x10\xf8\x03\x12\x13\n\x0e\x41TOM_VM_BOOTED\x10\xf9\x03\x12\x13\n\x0e\x41TOM_VM_EXITED\x10\xfa\x03\x12+\n&ATOM_AMBIENT_BRIGHTNESS_STATS_REPORTED\x10\xfb\x03\x12\x37\n2ATOM_MEDIAMETRICS_SPATIALIZERCAPABILITIES_REPORTED\x10\xfc\x03\x12\x38\n3ATOM_MEDIAMETRICS_SPATIALIZERDEVICEENABLED_REPORTED\x10\xfd\x03\x12\x38\n3ATOM_MEDIAMETRICS_HEADTRACKERDEVICEENABLED_REPORTED\x10\xfe\x03\x12:\n5ATOM_MEDIAMETRICS_HEADTRACKERDEVICESUPPORTED_REPORTED\x10\xff\x03\x12#\n\x1e\x41TOM_HEARING_AID_INFO_REPORTED\x10\x81\x04\x12,\n\'ATOM_DEVICE_WIDE_JOB_CONSTRAINT_CHANGED\x10\x82\x04\x12\x1e\n\x19\x41TOM_AMBIENT_MODE_CHANGED\x10\x83\x04\x12\x1e\n\x19\x41TOM_ANR_LATENCY_REPORTED\x10\x84\x04\x12\x1b\n\x16\x41TOM_RESOURCE_API_INFO\x10\x85\x04\x12(\n#ATOM_SYSTEM_DEFAULT_NETWORK_CHANGED\x10\x86\x04\x12/\n*ATOM_IWLAN_SETUP_DATA_CALL_RESULT_REPORTED\x10\x87\x04\x12\x30\n+ATOM_IWLAN_PDN_DISCONNECTED_REASON_REPORTED\x10\x88\x04\x12(\n#ATOM_AIRPLANE_MODE_SESSION_REPORTED\x10\x89\x04\x12 \n\x1b\x41TOM_VM_CPU_STATUS_REPORTED\x10\x8a\x04\x12 \n\x1b\x41TOM_VM_MEM_STATUS_REPORTED\x10\x8b\x04\x12/\n*ATOM_PACKAGE_INSTALLATION_SESSION_REPORTED\x10\x8c\x04\x12&\n!ATOM_DEFAULT_NETWORK_REMATCH_INFO\x10\x8d\x04\x12\'\n\"ATOM_NETWORK_SELECTION_PERFORMANCE\x10\x8e\x04\x12\x1e\n\x19\x41TOM_NETWORK_NSD_REPORTED\x10\x8f\x04\x12\x31\n,ATOM_BLUETOOTH_DISCONNECTION_REASON_REPORTED\x10\x91\x04\x12+\n&ATOM_BLUETOOTH_LOCAL_VERSIONS_REPORTED\x10\x92\x04\x12\x36\n1ATOM_BLUETOOTH_REMOTE_SUPPORTED_FEATURES_REPORTED\x10\x93\x04\x12\x35\n0ATOM_BLUETOOTH_LOCAL_SUPPORTED_FEATURES_REPORTED\x10\x94\x04\x12!\n\x1c\x41TOM_BLUETOOTH_GATT_APP_INFO\x10\x95\x04\x12*\n%ATOM_BRIGHTNESS_CONFIGURATION_UPDATED\x10\x96\x04\x12-\n(ATOM_WEAR_MEDIA_OUTPUT_SWITCHER_LAUNCHED\x10\x9a\x04\x12-\n(ATOM_WEAR_MEDIA_OUTPUT_SWITCHER_FINISHED\x10\x9b\x04\x12\x38\n3ATOM_WEAR_MEDIA_OUTPUT_SWITCHER_CONNECTION_REPORTED\x10\x9c\x04\x12:\n5ATOM_WEAR_MEDIA_OUTPUT_SWITCHER_DEVICE_SCAN_TRIGGERED\x10\x9d\x04\x12>\n9ATOM_WEAR_MEDIA_OUTPUT_SWITCHER_FIRST_DEVICE_SCAN_LATENCY\x10\x9e\x04\x12;\n6ATOM_WEAR_MEDIA_OUTPUT_SWITCHER_CONNECT_DEVICE_LATENCY\x10\x9f\x04\x12+\n&ATOM_PACKAGE_MANAGER_SNAPSHOT_REPORTED\x10\xa0\x04\x12:\n5ATOM_PACKAGE_MANAGER_APPS_FILTER_CACHE_BUILD_REPORTED\x10\xa1\x04\x12;\n6ATOM_PACKAGE_MANAGER_APPS_FILTER_CACHE_UPDATE_REPORTED\x10\xa2\x04\x12#\n\x1e\x41TOM_LAUNCHER_IMPRESSION_EVENT\x10\xa3\x04\x12=\n8ATOM_WEAR_MEDIA_OUTPUT_SWITCHER_ALL_DEVICES_SCAN_LATENCY\x10\xa5\x04\x12\x1e\n\x19\x41TOM_WS_WATCH_FACE_EDITED\x10\xa7\x04\x12\x30\n+ATOM_WS_WATCH_FACE_FAVORITE_ACTION_REPORTED\x10\xa8\x04\x12+\n&ATOM_WS_WATCH_FACE_SET_ACTION_REPORTED\x10\xa9\x04\x12)\n$ATOM_PACKAGE_UNINSTALLATION_REPORTED\x10\xaa\x04\x12\x1b\n\x16\x41TOM_GAME_MODE_CHANGED\x10\xab\x04\x12)\n$ATOM_GAME_MODE_CONFIGURATION_CHANGED\x10\xac\x04\x12$\n\x1f\x41TOM_BEDTIME_MODE_STATE_CHANGED\x10\xad\x04\x12%\n ATOM_NETWORK_SLICE_SESSION_ENDED\x10\xae\x04\x12\x31\n,ATOM_NETWORK_SLICE_DAILY_DATA_USAGE_REPORTED\x10\xaf\x04\x12\x1f\n\x1a\x41TOM_NFC_TAG_TYPE_OCCURRED\x10\xb0\x04\x12#\n\x1e\x41TOM_NFC_AID_CONFLICT_OCCURRED\x10\xb1\x04\x12&\n!ATOM_NFC_READER_CONFLICT_OCCURRED\x10\xb2\x04\x12\x1e\n\x19\x41TOM_WS_TILE_LIST_CHANGED\x10\xb3\x04\x12.\n)ATOM_GET_TYPE_ACCESSED_WITHOUT_PERMISSION\x10\xb4\x04\x12*\n%ATOM_MOBILE_BUNDLED_APP_INFO_GATHERED\x10\xb6\x04\x12\x30\n+ATOM_WS_WATCH_FACE_COMPLICATION_SET_CHANGED\x10\xb7\x04\x12\x1b\n\x16\x41TOM_MEDIA_DRM_CREATED\x10\xb8\x04\x12\x1b\n\x16\x41TOM_MEDIA_DRM_ERRORED\x10\xb9\x04\x12\"\n\x1d\x41TOM_MEDIA_DRM_SESSION_OPENED\x10\xba\x04\x12\"\n\x1d\x41TOM_MEDIA_DRM_SESSION_CLOSED\x10\xbb\x04\x12\"\n\x1d\x41TOM_USER_SELECTED_RESOLUTION\x10\xbc\x04\x12&\n!ATOM_UNSAFE_INTENT_EVENT_REPORTED\x10\xbd\x04\x12+\n&ATOM_PERFORMANCE_HINT_SESSION_REPORTED\x10\xbe\x04\x12\x31\n,ATOM_MEDIAMETRICS_MIDI_DEVICE_CLOSE_REPORTED\x10\xc0\x04\x12\"\n\x1d\x41TOM_BIOMETRIC_TOUCH_REPORTED\x10\xc1\x04\x12-\n(ATOM_HOTWORD_AUDIO_EGRESS_EVENT_REPORTED\x10\xc2\x04\x12(\n#ATOM_LOCATION_ENABLED_STATE_CHANGED\x10\xc4\x04\x12\x1e\n\x19\x41TOM_IME_REQUEST_FINISHED\x10\xc5\x04\x12*\n%ATOM_USB_COMPLIANCE_WARNINGS_REPORTED\x10\xc6\x04\x12\'\n\"ATOM_APP_SUPPORTED_LOCALES_CHANGED\x10\xc7\x04\x12\x31\n,ATOM_MEDIA_PROVIDER_VOLUME_RECOVERY_REPORTED\x10\xca\x04\x12(\n#ATOM_BIOMETRIC_PROPERTIES_COLLECTED\x10\xcb\x04\x12\"\n\x1d\x41TOM_KERNEL_WAKEUP_ATTRIBUTED\x10\xcc\x04\x12!\n\x1c\x41TOM_SCREEN_STATE_CHANGED_V2\x10\xcd\x04\x12#\n\x1e\x41TOM_WS_BACKUP_ACTION_REPORTED\x10\xce\x04\x12$\n\x1f\x41TOM_WS_RESTORE_ACTION_REPORTED\x10\xcf\x04\x12*\n%ATOM_DEVICE_LOG_ACCESS_EVENT_REPORTED\x10\xd0\x04\x12\x1f\n\x1a\x41TOM_MEDIA_SESSION_UPDATED\x10\xd2\x04\x12!\n\x1c\x41TOM_WEAR_OOBE_STATE_CHANGED\x10\xd3\x04\x12!\n\x1c\x41TOM_WS_NOTIFICATION_UPDATED\x10\xd4\x04\x12\x39\n4ATOM_NETWORK_VALIDATION_FAILURE_STATS_DAILY_REPORTED\x10\xd9\x04\x12 \n\x1b\x41TOM_WS_COMPLICATION_TAPPED\x10\xda\x04\x12\"\n\x1d\x41TOM_WS_NOTIFICATION_BLOCKING\x10\x8c\x06\x12,\n\'ATOM_WS_NOTIFICATION_BRIDGEMODE_UPDATED\x10\xb6\x06\x12,\n\'ATOM_WS_NOTIFICATION_DISMISSAL_ACTIONED\x10\xb7\x06\x12\"\n\x1d\x41TOM_WS_NOTIFICATION_ACTIONED\x10\xb8\x06\x12!\n\x1c\x41TOM_WS_NOTIFICATION_LATENCY\x10\xf0\x06\x12\x1d\n\x18\x41TOM_WIFI_BYTES_TRANSFER\x10\x90N\x12&\n!ATOM_WIFI_BYTES_TRANSFER_BY_FG_BG\x10\x91N\x12\x1f\n\x1a\x41TOM_MOBILE_BYTES_TRANSFER\x10\x92N\x12(\n#ATOM_MOBILE_BYTES_TRANSFER_BY_FG_BG\x10\x93N\x12\"\n\x1d\x41TOM_BLUETOOTH_BYTES_TRANSFER\x10\x96N\x12\x19\n\x14\x41TOM_KERNEL_WAKELOCK\x10\x94N\x12\x1f\n\x1a\x41TOM_SUBSYSTEM_SLEEP_STATE\x10\x95N\x12\x1a\n\x15\x41TOM_CPU_TIME_PER_UID\x10\x99N\x12\x1f\n\x1a\x41TOM_CPU_TIME_PER_UID_FREQ\x10\x9aN\x12\x1c\n\x17\x41TOM_WIFI_ACTIVITY_INFO\x10\x9bN\x12\x1d\n\x18\x41TOM_MODEM_ACTIVITY_INFO\x10\x9cN\x12!\n\x1c\x41TOM_BLUETOOTH_ACTIVITY_INFO\x10\x97N\x12\x1e\n\x19\x41TOM_PROCESS_MEMORY_STATE\x10\x9dN\x12!\n\x1c\x41TOM_SYSTEM_ELAPSED_REALTIME\x10\x9eN\x12\x17\n\x12\x41TOM_SYSTEM_UPTIME\x10\x9fN\x12\x19\n\x14\x41TOM_CPU_ACTIVE_TIME\x10\xa0N\x12\x1a\n\x15\x41TOM_CPU_CLUSTER_TIME\x10\xa1N\x12\x14\n\x0f\x41TOM_DISK_SPACE\x10\xa2N\x12$\n\x1f\x41TOM_REMAINING_BATTERY_CAPACITY\x10\xa3N\x12\x1f\n\x1a\x41TOM_FULL_BATTERY_CAPACITY\x10\xa4N\x12\x15\n\x10\x41TOM_TEMPERATURE\x10\xa5N\x12\x16\n\x11\x41TOM_BINDER_CALLS\x10\xa6N\x12!\n\x1c\x41TOM_BINDER_CALLS_EXCEPTIONS\x10\xa7N\x12\x16\n\x11\x41TOM_LOOPER_STATS\x10\xa8N\x12\x14\n\x0f\x41TOM_DISK_STATS\x10\xa9N\x12\x19\n\x14\x41TOM_DIRECTORY_USAGE\x10\xaaN\x12\x12\n\rATOM_APP_SIZE\x10\xabN\x12\x17\n\x12\x41TOM_CATEGORY_SIZE\x10\xacN\x12\x14\n\x0f\x41TOM_PROC_STATS\x10\xadN\x12\x19\n\x14\x41TOM_BATTERY_VOLTAGE\x10\xaeN\x12#\n\x1e\x41TOM_NUM_FINGERPRINTS_ENROLLED\x10\xafN\x12\x11\n\x0c\x41TOM_DISK_IO\x10\xb0N\x12\x17\n\x12\x41TOM_POWER_PROFILE\x10\xb1N\x12\x1d\n\x18\x41TOM_PROC_STATS_PKG_PROC\x10\xb2N\x12\x1a\n\x15\x41TOM_PROCESS_CPU_TIME\x10\xb3N\x12\"\n\x1d\x41TOM_CPU_TIME_PER_THREAD_FREQ\x10\xb5N\x12%\n ATOM_ON_DEVICE_POWER_MEASUREMENT\x10\xb6N\x12%\n ATOM_DEVICE_CALCULATED_POWER_USE\x10\xb7N\x12(\n#ATOM_PROCESS_MEMORY_HIGH_WATER_MARK\x10\xbaN\x12\x17\n\x12\x41TOM_BATTERY_LEVEL\x10\xbbN\x12\x1b\n\x16\x41TOM_BUILD_INFORMATION\x10\xbcN\x12\x1d\n\x18\x41TOM_BATTERY_CYCLE_COUNT\x10\xbdN\x12\x1d\n\x18\x41TOM_DEBUG_ELAPSED_CLOCK\x10\xbeN\x12%\n ATOM_DEBUG_FAILING_ELAPSED_CLOCK\x10\xbfN\x12\x1c\n\x17\x41TOM_NUM_FACES_ENROLLED\x10\xc0N\x12\x15\n\x10\x41TOM_ROLE_HOLDER\x10\xc1N\x12$\n\x1f\x41TOM_DANGEROUS_PERMISSION_STATE\x10\xc2N\x12\x14\n\x0f\x41TOM_TRAIN_INFO\x10\xc3N\x12\x1d\n\x18\x41TOM_TIME_ZONE_DATA_INFO\x10\xc4N\x12\x1f\n\x1a\x41TOM_EXTERNAL_STORAGE_INFO\x10\xc5N\x12\x1f\n\x1a\x41TOM_GPU_STATS_GLOBAL_INFO\x10\xc6N\x12\x1c\n\x17\x41TOM_GPU_STATS_APP_INFO\x10\xc7N\x12\x1e\n\x19\x41TOM_SYSTEM_ION_HEAP_SIZE\x10\xc8N\x12\'\n\"ATOM_APPS_ON_EXTERNAL_STORAGE_INFO\x10\xc9N\x12\x17\n\x12\x41TOM_FACE_SETTINGS\x10\xcaN\x12\x18\n\x13\x41TOM_COOLING_DEVICE\x10\xcbN\x12\x11\n\x0c\x41TOM_APP_OPS\x10\xccN\x12&\n!ATOM_PROCESS_SYSTEM_ION_HEAP_SIZE\x10\xcdN\x12*\n%ATOM_SURFACEFLINGER_STATS_GLOBAL_INFO\x10\xceN\x12)\n$ATOM_SURFACEFLINGER_STATS_LAYER_INFO\x10\xcfN\x12!\n\x1c\x41TOM_PROCESS_MEMORY_SNAPSHOT\x10\xd0N\x12\x1a\n\x15\x41TOM_VMS_CLIENT_STATS\x10\xd1N\x12#\n\x1e\x41TOM_NOTIFICATION_REMOTE_VIEWS\x10\xd2N\x12,\n\'ATOM_DANGEROUS_PERMISSION_STATE_SAMPLED\x10\xd3N\x12\x18\n\x13\x41TOM_GRAPHICS_STATS\x10\xd4N\x12\x1f\n\x1a\x41TOM_RUNTIME_APP_OP_ACCESS\x10\xd5N\x12\x17\n\x12\x41TOM_ION_HEAP_SIZE\x10\xd6N\x12*\n%ATOM_PACKAGE_NOTIFICATION_PREFERENCES\x10\xd7N\x12\x32\n-ATOM_PACKAGE_NOTIFICATION_CHANNEL_PREFERENCES\x10\xd8N\x12\x38\n3ATOM_PACKAGE_NOTIFICATION_CHANNEL_GROUP_PREFERENCES\x10\xd9N\x12\x14\n\x0f\x41TOM_GNSS_STATS\x10\xdaN\x12\x1c\n\x17\x41TOM_ATTRIBUTED_APP_OPS\x10\xdbN\x12\x1c\n\x17\x41TOM_VOICE_CALL_SESSION\x10\xdcN\x12\x1e\n\x19\x41TOM_VOICE_CALL_RAT_USAGE\x10\xddN\x12\x18\n\x13\x41TOM_SIM_SLOT_STATE\x10\xdeN\x12\'\n\"ATOM_SUPPORTED_RADIO_ACCESS_FAMILY\x10\xdfN\x12\x1a\n\x15\x41TOM_SETTING_SNAPSHOT\x10\xe0N\x12\x13\n\x0e\x41TOM_BLOB_INFO\x10\xe1N\x12#\n\x1e\x41TOM_DATA_USAGE_BYTES_TRANSFER\x10\xe2N\x12+\n&ATOM_BYTES_TRANSFER_BY_TAG_AND_METERED\x10\xe3N\x12\x17\n\x12\x41TOM_DND_MODE_RULE\x10\xe4N\x12/\n*ATOM_GENERAL_EXTERNAL_STORAGE_ACCESS_STATS\x10\xe5N\x12\x16\n\x11\x41TOM_INCOMING_SMS\x10\xe6N\x12\x16\n\x11\x41TOM_OUTGOING_SMS\x10\xe7N\x12\"\n\x1d\x41TOM_CARRIER_ID_TABLE_VERSION\x10\xe8N\x12\x1b\n\x16\x41TOM_DATA_CALL_SESSION\x10\xe9N\x12 \n\x1b\x41TOM_CELLULAR_SERVICE_STATE\x10\xeaN\x12&\n!ATOM_CELLULAR_DATA_SERVICE_SWITCH\x10\xebN\x12\x17\n\x12\x41TOM_SYSTEM_MEMORY\x10\xecN\x12&\n!ATOM_IMS_REGISTRATION_TERMINATION\x10\xedN\x12 \n\x1b\x41TOM_IMS_REGISTRATION_STATS\x10\xeeN\x12#\n\x1e\x41TOM_CPU_TIME_PER_CLUSTER_FREQ\x10\xefN\x12$\n\x1f\x41TOM_CPU_CYCLES_PER_UID_CLUSTER\x10\xf0N\x12\x1d\n\x18\x41TOM_DEVICE_ROTATED_DATA\x10\xf1N\x12-\n(ATOM_CPU_CYCLES_PER_THREAD_GROUP_CLUSTER\x10\xf2N\x12!\n\x1c\x41TOM_MEDIA_DRM_ACTIVITY_INFO\x10\xf3N\x12$\n\x1f\x41TOM_OEM_MANAGED_BYTES_TRANSFER\x10\xf4N\x12\x1a\n\x15\x41TOM_GNSS_POWER_STATS\x10\xf5N\x12\"\n\x1d\x41TOM_TIME_ZONE_DETECTOR_STATE\x10\xf6N\x12!\n\x1c\x41TOM_KEYSTORE2_STORAGE_STATS\x10\xf7N\x12\x18\n\x13\x41TOM_RKP_POOL_STATS\x10\xf8N\x12\x1f\n\x1a\x41TOM_PROCESS_DMABUF_MEMORY\x10\xf9N\x12\x1c\n\x17\x41TOM_PENDING_ALARM_INFO\x10\xfaN\x12$\n\x1f\x41TOM_USER_LEVEL_HIBERNATED_APPS\x10\xfbN\x12\"\n\x1d\x41TOM_LAUNCHER_LAYOUT_SNAPSHOT\x10\xfcN\x12 \n\x1b\x41TOM_GLOBAL_HIBERNATED_APPS\x10\xfdN\x12$\n\x1f\x41TOM_INPUT_EVENT_LATENCY_SKETCH\x10\xfeN\x12*\n%ATOM_BATTERY_USAGE_STATS_BEFORE_RESET\x10\xffN\x12)\n$ATOM_BATTERY_USAGE_STATS_SINCE_RESET\x10\x80O\x12\x43\n>ATOM_BATTERY_USAGE_STATS_SINCE_RESET_USING_POWER_PROFILE_MODEL\x10\x81O\x12\'\n\"ATOM_INSTALLED_INCREMENTAL_PACKAGE\x10\x82O\x12$\n\x1f\x41TOM_TELEPHONY_NETWORK_REQUESTS\x10\x83O\x12!\n\x1c\x41TOM_APP_SEARCH_STORAGE_INFO\x10\x84O\x12\x10\n\x0b\x41TOM_VMSTAT\x10\x85O\x12\x32\n-ATOM_KEYSTORE2_KEY_CREATION_WITH_GENERAL_INFO\x10\x86O\x12/\n*ATOM_KEYSTORE2_KEY_CREATION_WITH_AUTH_INFO\x10\x87O\x12<\n7ATOM_KEYSTORE2_KEY_CREATION_WITH_PURPOSE_AND_MODES_INFO\x10\x88O\x12&\n!ATOM_KEYSTORE2_ATOM_WITH_OVERFLOW\x10\x89O\x12=\n8ATOM_KEYSTORE2_KEY_OPERATION_WITH_PURPOSE_AND_MODES_INFO\x10\x8aO\x12\x33\n.ATOM_KEYSTORE2_KEY_OPERATION_WITH_GENERAL_INFO\x10\x8bO\x12\x19\n\x14\x41TOM_RKP_ERROR_STATS\x10\x8cO\x12\x1f\n\x1a\x41TOM_KEYSTORE2_CRASH_STATS\x10\x8dO\x12\x1a\n\x15\x41TOM_VENDOR_APEX_INFO\x10\x8eO\x12&\n!ATOM_ACCESSIBILITY_SHORTCUT_STATS\x10\x8fO\x12+\n&ATOM_ACCESSIBILITY_FLOATING_MENU_STATS\x10\x90O\x12&\n!ATOM_DATA_USAGE_BYTES_TRANSFER_V2\x10\x91O\x12\x1c\n\x17\x41TOM_MEDIA_CAPABILITIES\x10\x92O\x12.\n)ATOM_CAR_WATCHDOG_SYSTEM_IO_USAGE_SUMMARY\x10\x93O\x12+\n&ATOM_CAR_WATCHDOG_UID_IO_USAGE_SUMMARY\x10\x94O\x12,\n\'ATOM_IMS_REGISTRATION_FEATURE_TAG_STATS\x10\x95O\x12\'\n\"ATOM_RCS_CLIENT_PROVISIONING_STATS\x10\x96O\x12$\n\x1f\x41TOM_RCS_ACS_PROVISIONING_STATS\x10\x97O\x12\x1c\n\x17\x41TOM_SIP_DELEGATE_STATS\x10\x98O\x12)\n$ATOM_SIP_TRANSPORT_FEATURE_TAG_STATS\x10\x99O\x12\x1e\n\x19\x41TOM_SIP_MESSAGE_RESPONSE\x10\x9aO\x12\x1f\n\x1a\x41TOM_SIP_TRANSPORT_SESSION\x10\x9bO\x12-\n(ATOM_IMS_DEDICATED_BEARER_LISTENER_EVENT\x10\x9cO\x12$\n\x1f\x41TOM_IMS_DEDICATED_BEARER_EVENT\x10\x9dO\x12-\n(ATOM_IMS_REGISTRATION_SERVICE_DESC_STATS\x10\x9eO\x12\x19\n\x14\x41TOM_UCE_EVENT_STATS\x10\x9fO\x12\x1f\n\x1a\x41TOM_PRESENCE_NOTIFY_EVENT\x10\xa0O\x12\x13\n\x0e\x41TOM_GBA_EVENT\x10\xa1O\x12\x18\n\x13\x41TOM_PER_SIM_STATUS\x10\xa2O\x12\x1a\n\x15\x41TOM_GPU_WORK_PER_UID\x10\xa3O\x12\x37\n2ATOM_PERSISTENT_URI_PERMISSIONS_AMOUNT_PER_PACKAGE\x10\xa4O\x12\x1f\n\x1a\x41TOM_SIGNED_PARTITION_INFO\x10\xa5O\x12\'\n\"ATOM_PINNED_FILE_SIZES_PER_PACKAGE\x10\xa6O\x12%\n ATOM_PENDING_INTENTS_PER_PACKAGE\x10\xa7O\x12\x13\n\x0e\x41TOM_USER_INFO\x10\xa8O\x12\'\n\"ATOM_TELEPHONY_NETWORK_REQUESTS_V2\x10\xa9O\x12%\n ATOM_DEVICE_TELEPHONY_PROPERTIES\x10\xaaO\x12.\n)ATOM_REMOTE_KEY_PROVISIONING_ERROR_COUNTS\x10\xabO\x12\x16\n\x11\x41TOM_SAFETY_STATE\x10\xacO\x12\x16\n\x11\x41TOM_INCOMING_MMS\x10\xadO\x12\x16\n\x11\x41TOM_OUTGOING_MMS\x10\xaeO\x12\x19\n\x14\x41TOM_MULTI_USER_INFO\x10\xb0O\x12\x1e\n\x19\x41TOM_NETWORK_BPF_MAP_INFO\x10\xb1O\x12!\n\x1c\x41TOM_OUTGOING_SHORT_CODE_SMS\x10\xb2O\x12#\n\x1e\x41TOM_CONNECTIVITY_STATE_SAMPLE\x10\xb3O\x12\x30\n+ATOM_NETWORK_SELECTION_REMATCH_REASONS_INFO\x10\xb4O\x12\x18\n\x13\x41TOM_GAME_MODE_INFO\x10\xb5O\x12!\n\x1c\x41TOM_GAME_MODE_CONFIGURATION\x10\xb6O\x12\x1c\n\x17\x41TOM_GAME_MODE_LISTENER\x10\xb7O\x12%\n ATOM_NETWORK_SLICE_REQUEST_COUNT\x10\xb8O\x12\x1a\n\x15\x41TOM_WS_TILE_SNAPSHOT\x10\xb9O\x12\x38\n3ATOM_WS_ACTIVE_WATCH_FACE_COMPLICATION_SET_SNAPSHOT\x10\xbaO\x12\x17\n\x12\x41TOM_PROCESS_STATE\x10\xbbO\x12\x1d\n\x18\x41TOM_PROCESS_ASSOCIATION\x10\xbcO\x12$\n\x1f\x41TOM_ADPF_SYSTEM_COMPONENT_INFO\x10\xbdO\x12!\n\x1c\x41TOM_NOTIFICATION_MEMORY_USE\x10\xbeO\x12\x1a\n\x15\x41TOM_HDR_CAPABILITIES\x10\xbfO\x12/\n*ATOM_WS_FAVOURITE_WATCH_FACE_LIST_SNAPSHOT\x10\xc0O\x12!\n\x1c\x41TOM_WIFI_AWARE_NDP_REPORTED\x10\xfe\x04\x12$\n\x1f\x41TOM_WIFI_AWARE_ATTACH_REPORTED\x10\xff\x04\x12&\n!ATOM_WIFI_SELF_RECOVERY_TRIGGERED\x10\x95\x05\x12\x19\n\x14\x41TOM_SOFT_AP_STARTED\x10\xa8\x05\x12\x19\n\x14\x41TOM_SOFT_AP_STOPPED\x10\xa9\x05\x12\x1c\n\x17\x41TOM_WIFI_LOCK_RELEASED\x10\xaf\x05\x12\x1f\n\x1a\x41TOM_WIFI_LOCK_DEACTIVATED\x10\xb0\x05\x12\x1b\n\x16\x41TOM_WIFI_CONFIG_SAVED\x10\xb1\x05\x12+\n&ATOM_WIFI_AWARE_RESOURCE_USING_CHANGED\x10\xb2\x05\x12#\n\x1e\x41TOM_WIFI_AWARE_HAL_API_CALLED\x10\xb3\x05\x12*\n%ATOM_WIFI_LOCAL_ONLY_REQUEST_RECEIVED\x10\xb4\x05\x12\x30\n+ATOM_WIFI_LOCAL_ONLY_REQUEST_SCAN_TRIGGERED\x10\xb5\x05\x12#\n\x1e\x41TOM_WIFI_THREAD_TASK_EXECUTED\x10\xb6\x05\x12\x1c\n\x17\x41TOM_WIFI_STATE_CHANGED\x10\xbc\x05\x12\x1a\n\x15\x41TOM_PNO_SCAN_STARTED\x10\xcf\x05\x12\x1a\n\x15\x41TOM_PNO_SCAN_STOPPED\x10\xd0\x05\x12#\n\x1e\x41TOM_WIFI_IS_UNUSABLE_REPORTED\x10\xd2\x05\x12\'\n\"ATOM_WIFI_AP_CAPABILITIES_REPORTED\x10\xd3\x05\x12\x1f\n\x1a\x41TOM_SOFT_AP_STATE_CHANGED\x10\xa5\x06\x12+\n&ATOM_SCORER_PREDICTION_RESULT_REPORTED\x10\xf4\x06\x12!\n\x1c\x41TOM_WIFI_AWARE_CAPABILITIES\x10\xceO\x12\x1a\n\x15\x41TOM_WIFI_MODULE_INFO\x10\xd1O\x12\x1b\n\x16\x41TOM_WIFI_SETTING_INFO\x10\xd2O\x12#\n\x1e\x41TOM_WIFI_COMPLEX_SETTING_INFO\x10\xd3O\x12&\n!ATOM_WIFI_CONFIGURED_NETWORK_INFO\x10\xd6O\x12 \n\x1b\x41TOM_WEAR_POWER_MENU_OPENED\x10\xdb\x05\x12\x1f\n\x1a\x41TOM_WEAR_ASSISTANT_OPENED\x10\xf3\x05\x12%\n ATOM_FIRST_OVERLAY_STATE_CHANGED\x10\x95\x07\x12\x1e\n\x19\x41TOM_WS_WEAR_TIME_SESSION\x10\xe2\x04\x12*\n%ATOM_WS_INCOMING_CALL_ACTION_REPORTED\x10\xf2\x04\x12(\n#ATOM_WS_CALL_DISCONNECTION_REPORTED\x10\xf3\x04\x12#\n\x1e\x41TOM_WS_CALL_DURATION_REPORTED\x10\xf4\x04\x12\x32\n-ATOM_WS_CALL_USER_EXPERIENCE_LATENCY_REPORTED\x10\xf5\x04\x12&\n!ATOM_WS_CALL_INTERACTION_REPORTED\x10\xf6\x04\x12\"\n\x1d\x41TOM_WS_ON_BODY_STATE_CHANGED\x10\x93\x06\x12\x39\n4ATOM_WS_WATCH_FACE_RESTRICTED_COMPLICATIONS_IMPACTED\x10\xa2\x06\x12@\n;ATOM_WS_WATCH_FACE_DEFAULT_RESTRICTED_COMPLICATIONS_REMOVED\x10\xa3\x06\x12?\n:ATOM_WS_COMPLICATIONS_IMPACTED_NOTIFICATION_EVENT_REPORTED\x10\xa4\x06\x12(\n#ATOM_WS_REMOTE_EVENT_USAGE_REPORTED\x10\x98\x07\x12\x30\n+ATOM_WS_NOTIFICATION_MANAGED_DISMISSAL_SYNC\x10\xad\x07\x12%\n ATOM_WS_BUGREPORT_EVENT_REPORTED\x10\xc4\x07\x12%\n ATOM_WS_STANDALONE_MODE_SNAPSHOT\x10\xd5O\x12)\n$ATOM_WS_FAVORITE_WATCH_FACE_SNAPSHOT\x10\xdeO\x12/\n*ATOM_WS_PHOTOS_WATCH_FACE_FEATURE_SNAPSHOT\x10\xf1O\x12.\n)ATOM_WS_WATCH_FACE_CUSTOMIZATION_SNAPSHOT\x10\xf3O\x12.\n)ATOM_WEAR_ADAPTIVE_SUSPEND_STATS_REPORTED\x10\xeb\x04\x12?\n:ATOM_WEAR_POWER_ANOMALY_SERVICE_OPERATIONAL_STATS_REPORTED\x10\xec\x04\x12\x39\n4ATOM_WEAR_POWER_ANOMALY_SERVICE_EVENT_STATS_REPORTED\x10\xed\x04\x12\"\n\x1d\x41TOM_WEAR_TIME_SYNC_REQUESTED\x10\x8f\x07\x12\"\n\x1d\x41TOM_WEAR_TIME_UPDATE_STARTED\x10\x90\x07\x12*\n%ATOM_WEAR_TIME_SYNC_ATTEMPT_COMPLETED\x10\x91\x07\x12\x1b\n\x16\x41TOM_WEAR_TIME_CHANGED\x10\x92\x07\x12\x32\n-ATOM_WEAR_SETUP_WIZARD_DEVICE_STATUS_REPORTED\x10\xb9\x07\x12-\n(ATOM_WEAR_SETUP_WIZARD_PAIRING_COMPLETED\x10\xba\x07\x12\x32\n-ATOM_WEAR_SETUP_WIZARD_CONNECTION_ESTABLISHED\x10\xbb\x07\x12-\n(ATOM_WEAR_SETUP_WIZARD_CHECKIN_COMPLETED\x10\xbc\x07\x12\x33\n.ATOM_WEAR_SETUP_WIZARD_COMPANION_TIME_REPORTED\x10\xbd\x07\x12+\n&ATOM_WEAR_SETUP_WIZARD_STATUS_REPORTED\x10\xbe\x07\x12.\n)ATOM_WEAR_SETUP_WIZARD_HEARTBEAT_REPORTED\x10\xbf\x07\x12)\n$ATOM_WEAR_SETUP_WIZARD_FRP_TRIGGERED\x10\xc0\x07\x12\x33\n.ATOM_WEAR_SETUP_WIZARD_SYSTEM_UPDATE_TRIGGERED\x10\xc1\x07\x12\x32\n-ATOM_WEAR_SETUP_WIZARD_PHONE_SWITCH_TRIGGERED\x10\xc2\x07\x12\x1e\n\x19\x41TOM_RENDERER_INITIALIZED\x10\xe0\x05\x12!\n\x1c\x41TOM_SCHEMA_VERSION_RECEIVED\x10\xe1\x05\x12\x1a\n\x15\x41TOM_LAYOUT_INSPECTED\x10\xe5\x05\x12%\n ATOM_LAYOUT_EXPRESSION_INSPECTED\x10\xe6\x05\x12%\n ATOM_LAYOUT_ANIMATIONS_INSPECTED\x10\xe7\x05\x12\'\n\"ATOM_MATERIAL_COMPONENTS_INSPECTED\x10\xe8\x05\x12\x18\n\x13\x41TOM_TILE_REQUESTED\x10\xe9\x05\x12!\n\x1c\x41TOM_STATE_RESPONSE_RECEIVED\x10\xea\x05\x12 \n\x1b\x41TOM_TILE_RESPONSE_RECEIVED\x10\xeb\x05\x12\x1c\n\x17\x41TOM_INFLATION_FINISHED\x10\xec\x05\x12\x1a\n\x15\x41TOM_INFLATION_FAILED\x10\xed\x05\x12-\n(ATOM_IGNORED_INFLATION_FAILURES_REPORTED\x10\xee\x05\x12\x1b\n\x16\x41TOM_DRAWABLE_RENDERED\x10\xef\x05\x12!\n\x1c\x41TOM_WEAR_MODE_STATE_CHANGED\x10\xcb\x05\x12\x1f\n\x1a\x41TOM_MEDIA_ACTION_REPORTED\x10\xe0\x04\x12!\n\x1c\x41TOM_MEDIA_CONTROLS_LAUNCHED\x10\xe1\x04\x12%\n ATOM_MEDIA_SESSION_STATE_CHANGED\x10\xa5\x05\x12*\n%ATOM_MEDIA_CONTROL_API_USAGE_REPORTED\x10\xc6\x07\x12$\n\x1f\x41TOM_MEDIA_SUBSCRIPTION_CHANGED\x10\xde\x07\x12<\n7ATOM_WEAR_MEDIA_OUTPUT_SWITCHER_DEVICE_SCAN_API_LATENCY\x10\xf5\x05\x12<\n7ATOM_WEAR_MEDIA_OUTPUT_SWITCHER_SASS_DEVICE_UNAVAILABLE\x10\xf6\x05\x12\x39\n4ATOM_WEAR_MEDIA_OUTPUT_SWITCHER_FASTPAIR_API_TIMEOUT\x10\xf7\x05\x12\x1a\n\x15\x41TOM_MEDIATOR_UPDATED\x10\xd1\x05\x12+\n&ATOM_SYSPROXY_BLUETOOTH_BYTES_TRANSFER\x10\xd4O\x12%\n ATOM_SYSPROXY_CONNECTION_UPDATED\x10\x92\x06\x12)\n$ATOM_WEAR_COMPANION_CONNECTION_STATE\x10\x99\x07\x12(\n#ATOM_SYSPROXY_SERVICE_STATE_UPDATED\x10\xb5\x07\x12\x1b\n\x16\x41TOM_UWB_ACTIVITY_INFO\x10\xccO\x12(\n#ATOM_TEST_UPROBESTATS_ATOM_REPORTED\x10\x93\x07\x12%\n ATOM_TV_LOW_POWER_STANDBY_POLICY\x10\xa7\x05\x12!\n\x1c\x41TOM_EXTERNAL_TV_INPUT_EVENT\x10\xcd\x05\x12&\n!ATOM_BOOT_INTEGRITY_INFO_REPORTED\x10\x87\x06\x12/\n*ATOM_THREADNETWORK_TELEMETRY_DATA_REPORTED\x10\xe2\x05\x12+\n&ATOM_THREADNETWORK_TOPO_ENTRY_REPEATED\x10\xe3\x05\x12,\n\'ATOM_THREADNETWORK_DEVICE_INFO_REPORTED\x10\xe4\x05\x12,\n\'ATOM_CELLULAR_RADIO_POWER_STATE_CHANGED\x10\xc9\x05\x12 \n\x1b\x41TOM_EMERGENCY_NUMBERS_INFO\x10\xc4O\x12!\n\x1c\x41TOM_DATA_NETWORK_VALIDATION\x10\xdfO\x12 \n\x1b\x41TOM_DATA_RAT_STATE_CHANGED\x10\xd6\x06\x12#\n\x1e\x41TOM_CONNECTED_CHANNEL_CHANGED\x10\xf2\x06\x12\'\n\"ATOM_CELLULAR_IDENTIFIER_DISCLOSED\x10\xa0\x06\x12\x1e\n\x19\x41TOM_SATELLITE_CONTROLLER\x10\xc6O\x12\x1b\n\x16\x41TOM_SATELLITE_SESSION\x10\xc7O\x12%\n ATOM_SATELLITE_INCOMING_DATAGRAM\x10\xc8O\x12%\n ATOM_SATELLITE_OUTGOING_DATAGRAM\x10\xc9O\x12\x1d\n\x18\x41TOM_SATELLITE_PROVISION\x10\xcaO\x12+\n&ATOM_SATELLITE_SOS_MESSAGE_RECOMMENDER\x10\xcbO\x12+\n&ATOM_CARRIER_ROAMING_SATELLITE_SESSION\x10\xe3O\x12\x34\n/ATOM_CARRIER_ROAMING_SATELLITE_CONTROLLER_STATS\x10\xe4O\x12&\n!ATOM_CONTROLLER_STATS_PER_PACKAGE\x10\xe5O\x12\x1f\n\x1a\x41TOM_SATELLITE_ENTITLEMENT\x10\xe6O\x12\"\n\x1d\x41TOM_SATELLITE_CONFIG_UPDATER\x10\xe7O\x12%\n ATOM_SATELLITE_ACCESS_CONTROLLER\x10\xebO\x12$\n\x1f\x41TOM_QUALIFIED_RAT_LIST_CHANGED\x10\xfa\x04\x12!\n\x1c\x41TOM_QNS_IMS_CALL_DROP_STATS\x10\xfb\x04\x12*\n%ATOM_QNS_FALLBACK_RESTRICTION_CHANGED\x10\xfc\x04\x12*\n%ATOM_QNS_RAT_PREFERENCE_MISMATCH_INFO\x10\xc1O\x12\"\n\x1d\x41TOM_QNS_HANDOVER_TIME_MILLIS\x10\xc2O\x12\x1f\n\x1a\x41TOM_QNS_HANDOVER_PINGPONG\x10\xc3O\x12=\n8ATOM_IWLAN_UNDERLYING_NETWORK_VALIDATION_RESULT_REPORTED\x10\x9b\x07\x12!\n\x1c\x41TOM_EMERGENCY_NUMBER_DIALED\x10\xfd\x04\x12\x14\n\x0f\x41TOM_CALL_STATS\x10\xedO\x12 \n\x1b\x41TOM_CALL_AUDIO_ROUTE_STATS\x10\xeeO\x12\x1b\n\x16\x41TOM_TELECOM_API_STATS\x10\xefO\x12\x1d\n\x18\x41TOM_TELECOM_ERROR_STATS\x10\xf0O\x12&\n!ATOM_LOCKSCREEN_SHORTCUT_SELECTED\x10\xe3\x04\x12\'\n\"ATOM_LOCKSCREEN_SHORTCUT_TRIGGERED\x10\xe4\x04\x12&\n!ATOM_LAUNCHER_IMPRESSION_EVENT_V2\x10\xcc\x05\x12(\n#ATOM_DISPLAY_SWITCH_LATENCY_TRACKED\x10\xf1\x05\x12\'\n\"ATOM_NOTIFICATION_LISTENER_SERVICE\x10\xbd\x06\x12!\n\x1c\x41TOM_NAV_HANDLE_TOUCH_POINTS\x10\xe5\x06\x12,\n\'ATOM_COMMUNAL_HUB_WIDGET_EVENT_REPORTED\x10\x8c\x07\x12&\n!ATOM_PERIPHERAL_TUTORIAL_LAUNCHED\x10\xae\x07\x12(\n#ATOM_CONTEXTUAL_EDUCATION_TRIGGERED\x10\xcb\x07\x12\x1f\n\x1a\x41TOM_COMMUNAL_HUB_SNAPSHOT\x10\xf2O\x12&\n!ATOM_TEST_EXTENSION_ATOM_REPORTED\x10\x94\x05\x12\'\n\"ATOM_TEST_RESTRICTED_ATOM_REPORTED\x10\xa0\x05\x12$\n\x1f\x41TOM_STATS_SOCKET_LOSS_REPORTED\x10\xf0\x05\x12\x1f\n\x1a\x41TOM_SETTINGS_SPA_REPORTED\x10\xee\x04\x12\x1b\n\x16\x41TOM_SELINUX_AUDIT_LOG\x10\x9f\x06\x12\x1c\n\x17\x41TOM_SANDBOX_API_CALLED\x10\xe8\x03\x12)\n$ATOM_SANDBOX_ACTIVITY_EVENT_OCCURRED\x10\xdf\x05\x12\x32\n-ATOM_SDK_SANDBOX_RESTRICTED_ACCESS_IN_SESSION\x10\x9c\x06\x12\x1d\n\x18\x41TOM_SANDBOX_SDK_STORAGE\x10\xafO\x12\x19\n\x14\x41TOM_RKPD_POOL_STATS\x10\x98\x05\x12\x1f\n\x1a\x41TOM_RKPD_CLIENT_OPERATION\x10\x99\x05\x12$\n\x1f\x41TOM_RANGING_SESSION_CONFIGURED\x10\xe1\x07\x12!\n\x1c\x41TOM_RANGING_SESSION_STARTED\x10\xe2\x07\x12 \n\x1b\x41TOM_RANGING_SESSION_CLOSED\x10\xe3\x07\x12$\n\x1f\x41TOM_RANGING_TECHNOLOGY_STARTED\x10\xe4\x07\x12$\n\x1f\x41TOM_RANGING_TECHNOLOGY_STOPPED\x10\xe5\x07\x12\x33\n.ATOM_MEDIA_PROVIDER_DATABASE_ROLLBACK_REPORTED\x10\x90\x06\x12&\n!ATOM_BACKUP_SETUP_STATUS_REPORTED\x10\x91\x06\x12\x1d\n\x18\x41TOM_SCREEN_OFF_REPORTED\x10\x88\x06\x12*\n%ATOM_SCREEN_TIMEOUT_OVERRIDE_REPORTED\x10\xc4\x06\x12-\n(ATOM_SCREEN_INTERACTIVE_SESSION_REPORTED\x10\xc5\x06\x12\x1d\n\x18\x41TOM_SCREEN_DIM_REPORTED\x10\xe3\x06\x12\x13\n\x0e\x41TOM_ATOM_9999\x10\x8fN\x12\x15\n\x0f\x41TOM_ATOM_99999\x10\x9f\x8d\x06\x12+\n&ATOM_PHOTOPICKER_SESSION_INFO_REPORTED\x10\xf6\x06\x12\'\n\"ATOM_PHOTOPICKER_API_INFO_REPORTED\x10\xf7\x06\x12%\n ATOM_PHOTOPICKER_UI_EVENT_LOGGED\x10\xf8\x06\x12\x30\n+ATOM_PHOTOPICKER_MEDIA_ITEM_STATUS_REPORTED\x10\xf9\x06\x12)\n$ATOM_PHOTOPICKER_PREVIEW_INFO_LOGGED\x10\xfa\x06\x12-\n(ATOM_PHOTOPICKER_MENU_INTERACTION_LOGGED\x10\xfb\x06\x12/\n*ATOM_PHOTOPICKER_BANNER_INTERACTION_LOGGED\x10\xfc\x06\x12/\n*ATOM_PHOTOPICKER_MEDIA_LIBRARY_INFO_LOGGED\x10\xfd\x06\x12&\n!ATOM_PHOTOPICKER_PAGE_INFO_LOGGED\x10\xfe\x06\x12\x33\n.ATOM_PHOTOPICKER_MEDIA_GRID_SYNC_INFO_REPORTED\x10\xff\x06\x12.\n)ATOM_PHOTOPICKER_ALBUM_SYNC_INFO_REPORTED\x10\x80\x07\x12*\n%ATOM_PHOTOPICKER_SEARCH_INFO_REPORTED\x10\x81\x07\x12\x31\n,ATOM_SEARCH_DATA_EXTRACTION_DETAILS_REPORTED\x10\x82\x07\x12,\n\'ATOM_EMBEDDED_PHOTOPICKER_INFO_REPORTED\x10\x83\x07\x12,\n\'ATOM_PERMISSION_RATIONALE_DIALOG_VIEWED\x10\x85\x05\x12\x35\n0ATOM_PERMISSION_RATIONALE_DIALOG_ACTION_REPORTED\x10\x86\x05\x12;\n6ATOM_APP_DATA_SHARING_UPDATES_NOTIFICATION_INTERACTION\x10\x87\x05\x12\x32\n-ATOM_APP_DATA_SHARING_UPDATES_FRAGMENT_VIEWED\x10\x88\x05\x12;\n6ATOM_APP_DATA_SHARING_UPDATES_FRAGMENT_ACTION_REPORTED\x10\x89\x05\x12\x36\n1ATOM_ENHANCED_CONFIRMATION_DIALOG_RESULT_REPORTED\x10\xbb\x06\x12\x33\n.ATOM_ENHANCED_CONFIRMATION_RESTRICTION_CLEARED\x10\xbc\x06\x12$\n\x1f\x41TOM_PRESSURE_STALL_INFORMATION\x10\xf5O\x12\x1b\n\x16\x41TOM_PDF_LOAD_REPORTED\x10\xdb\x06\x12 \n\x1b\x41TOM_PDF_API_USAGE_REPORTED\x10\xdc\x06\x12\x1d\n\x18\x41TOM_PDF_SEARCH_REPORTED\x10\xdd\x06\x12*\n%ATOM_COMPONENT_STATE_CHANGED_REPORTED\x10\xdf\x06\x12,\n\'ATOM_ONDEVICEPERSONALIZATION_API_CALLED\x10\xc7\x05\x12-\n(ATOM_ONDEVICEPERSONALIZATION_TRACE_EVENT\x10\xb8\x07\x12(\n#ATOM_NFC_OBSERVE_MODE_STATE_CHANGED\x10\xd7\x06\x12\x1b\n\x16\x41TOM_NFC_FIELD_CHANGED\x10\xd8\x06\x12\x30\n+ATOM_NFC_POLLING_LOOP_NOTIFICATION_REPORTED\x10\xd9\x06\x12/\n*ATOM_NFC_PROPRIETARY_CAPABILITIES_REPORTED\x10\xda\x06\x12&\n!ATOM_NFC_EXIT_FRAME_TABLE_CHANGED\x10\x8c\x08\x12$\n\x1f\x41TOM_NFC_AUTO_TRANSACT_REPORTED\x10\x8e\x08\x12/\n*ATOM_MICROXR_DEVICE_BOOT_COMPLETE_REPORTED\x10\x85\x07\x12\x13\n\x0e\x41TOM_MTE_STATE\x10\xc5O\x12#\n\x1e\x41TOM_ZRAM_MAINTENANCE_EXECUTED\x10\xf7\x07\x12\x1d\n\x18\x41TOM_ZRAM_SETUP_EXECUTED\x10\x85\x08\x12\x1a\n\x15\x41TOM_ZRAM_MM_STAT_MMD\x10\xf8O\x12\x1a\n\x15\x41TOM_ZRAM_BD_STAT_MMD\x10\xf9O\x12&\n!ATOM_MEDIA_EDITING_ENDED_REPORTED\x10\x9e\x06\x12/\n*ATOM_MEDIA_CODEC_RECLAIM_REQUEST_COMPLETED\x10\xd8\x04\x12\x1d\n\x18\x41TOM_MEDIA_CODEC_STARTED\x10\x81\x05\x12\x1d\n\x18\x41TOM_MEDIA_CODEC_STOPPED\x10\x82\x05\x12\x1e\n\x19\x41TOM_MEDIA_CODEC_RENDERED\x10\xac\x05\x12!\n\x1c\x41TOM_EMERGENCY_STATE_CHANGED\x10\xf9\x04\x12/\n*ATOM_CHRE_SIGNIFICANT_MOTION_STATE_CHANGED\x10\xe4\x06\x12\x36\n1ATOM_POPULATION_DENSITY_PROVIDER_LOADING_REPORTED\x10\xea\x07\x12\x37\n2ATOM_DENSITY_BASED_COARSE_LOCATIONS_USAGE_REPORTED\x10\xeb\x07\x12@\n;ATOM_DENSITY_BASED_COARSE_LOCATIONS_PROVIDER_QUERY_REPORTED\x10\xec\x07\x12\"\n\x1d\x41TOM_KERNEL_OOM_KILL_OCCURRED\x10\xf2\x05\x12\x1d\n\x18\x41TOM_KEYBOARD_CONFIGURED\x10\xaa\x05\x12)\n$ATOM_KEYBOARD_SYSTEMS_EVENT_REPORTED\x10\xab\x05\x12$\n\x1f\x41TOM_INPUTDEVICE_USAGE_REPORTED\x10\xae\x05\x12&\n!ATOM_INPUT_EVENT_LATENCY_REPORTED\x10\xa4\x07\x12\x18\n\x13\x41TOM_TOUCHPAD_USAGE\x10\xcfO\x12 \n\x1b\x41TOM_IKE_SESSION_TERMINATED\x10\xa6\x05\x12.\n)ATOM_IKE_LIVENESS_CHECK_SESSION_VALIDATED\x10\xf8\x05\x12)\n$ATOM_NEGOTIATED_SECURITY_ASSOCIATION\x10\xb5\x06\x12+\n&ATOM_HOTWORD_EGRESS_SIZE_ATOM_REPORTED\x10\xf9\x05\x12&\n!ATOM_HEALTH_CONNECT_UI_IMPRESSION\x10\xef\x04\x12\'\n\"ATOM_HEALTH_CONNECT_UI_INTERACTION\x10\xf0\x04\x12,\n\'ATOM_HEALTH_CONNECT_APP_OPENED_REPORTED\x10\xf1\x04\x12#\n\x1e\x41TOM_HEALTH_CONNECT_API_CALLED\x10\xe8\x04\x12$\n\x1f\x41TOM_HEALTH_CONNECT_USAGE_STATS\x10\xe9\x04\x12&\n!ATOM_HEALTH_CONNECT_STORAGE_STATS\x10\xea\x04\x12$\n\x1f\x41TOM_HEALTH_CONNECT_API_INVOKED\x10\x83\x05\x12#\n\x1e\x41TOM_EXERCISE_ROUTE_API_CALLED\x10\x8e\x05\x12\'\n\"ATOM_HEALTH_CONNECT_EXPORT_INVOKED\x10\x8b\x07\x12\'\n\"ATOM_HEALTH_CONNECT_IMPORT_INVOKED\x10\x96\x07\x12\x35\n0ATOM_HEALTH_CONNECT_EXPORT_IMPORT_STATS_REPORTED\x10\x97\x07\x12)\n$ATOM_HEALTH_CONNECT_PERMISSION_STATS\x10\xc3\x07\x12(\n#ATOM_HEALTH_CONNECT_PHR_API_INVOKED\x10\xd4\x07\x12(\n#ATOM_HEALTH_CONNECT_PHR_USAGE_STATS\x10\xd5\x07\x12*\n%ATOM_HEALTH_CONNECT_PHR_STORAGE_STATS\x10\xd8\x07\x12\x33\n.ATOM_HEALTH_CONNECT_RESTRICTED_ECOSYSTEM_STATS\x10\xd9\x07\x12(\n#ATOM_HEALTH_CONNECT_ECOSYSTEM_STATS\x10\xda\x07\x12#\n\x1e\x41TOM_HDMI_EARC_STATUS_REPORTED\x10\xbd\x05\x12,\n\'ATOM_HDMI_SOUNDBAR_MODE_STATUS_REPORTED\x10\xd4\x05\x12?\n:ATOM_HDMI_POWER_STATE_CHANGE_ON_ACTIVE_SOURCE_LOST_TOGGLED\x10\xdf\x07\x12\x18\n\x13\x41TOM_BATTERY_HEALTH\x10\xecO\x12\x1e\n\x19\x41TOM_BIOMETRIC_UNENROLLED\x10\xb0\x07\x12\x1e\n\x19\x41TOM_BIOMETRIC_ENUMERATED\x10\xb1\x07\x12\x34\n/ATOM_APPLICATION_GRAMMATICAL_INFLECTION_CHANGED\x10\xc8\x04\x12/\n*ATOM_SYSTEM_GRAMMATICAL_INFLECTION_CHANGED\x10\xb0\x06\x12%\n ATOM_FULL_SCREEN_INTENT_LAUNCHED\x10\xf7\x04\x12\x15\n\x10\x41TOM_BAL_ALLOWED\x10\xf8\x04\x12\"\n\x1d\x41TOM_IN_TASK_ACTIVITY_STARTED\x10\xad\x05\x12$\n\x1f\x41TOM_DEVICE_ORIENTATION_CHANGED\x10\x8a\x07\x12$\n\x1f\x41TOM_CACHED_APPS_HIGH_WATERMARK\x10\xcdO\x12,\n\'ATOM_STYLUS_PREDICTION_METRICS_REPORTED\x10\xce\x05\x12\"\n\x1d\x41TOM_USER_RISK_EVENT_REPORTED\x10\xd5\x05\x12(\n#ATOM_MEDIA_PROJECTION_STATE_CHANGED\x10\xd9\x05\x12)\n$ATOM_MEDIA_PROJECTION_TARGET_CHANGED\x10\xda\x05\x12/\n*ATOM_EXCESSIVE_BINDER_PROXY_COUNT_REPORTED\x10\xd5\x06\x12\'\n\"ATOM_PROXY_BYTES_TRANSFER_BY_FG_BG\x10\xd8O\x12-\n(ATOM_MOBILE_BYTES_TRANSFER_BY_PROC_STATE\x10\xdcO\x12$\n\x1f\x41TOM_BIOMETRIC_FRR_NOTIFICATION\x10\xb1\x06\x12\x34\n/ATOM_SENSITIVE_CONTENT_MEDIA_PROJECTION_SESSION\x10\xbe\x06\x12\x37\n2ATOM_SENSITIVE_NOTIFICATION_APP_PROTECTION_SESSION\x10\xbf\x06\x12\x37\n2ATOM_SENSITIVE_NOTIFICATION_APP_PROTECTION_APPLIED\x10\xc0\x06\x12*\n%ATOM_SENSITIVE_NOTIFICATION_REDACTION\x10\xc1\x06\x12*\n%ATOM_SENSITIVE_CONTENT_APP_PROTECTION\x10\xc3\x06\x12\'\n\"ATOM_APP_RESTRICTION_STATE_CHANGED\x10\xe2\x06\x12%\n ATOM_BATTERY_USAGE_STATS_PER_UID\x10\xe1O\x12 \n\x1b\x41TOM_POSTGC_MEMORY_SNAPSHOT\x10\x9c\x07\x12+\n&ATOM_POWER_SAVE_TEMP_ALLOWLIST_CHANGED\x10\x9e\x07\x12\x1f\n\x1a\x41TOM_APP_OP_ACCESS_TRACKED\x10\xa3\x07\x12,\n\'ATOM_CONTENT_OR_FILE_URI_EVENT_REPORTED\x10\xa5\x07\x12,\n\'ATOM_DEVICE_IDLE_TEMP_ALLOWLIST_UPDATED\x10\xac\x07\x12\x36\n1ATOM_APP_OP_NOTE_OP_OR_CHECK_OP_BINDER_API_CALLED\x10\xaf\x07\x12!\n\x1c\x41TOM_FRAMEWORK_WAKELOCK_INFO\x10\xf6O\x12-\n(ATOM_JANK_FRAME_COUNT_BY_WIDGET_REPORTED\x10\xb6\x07\x12$\n\x1f\x41TOM_INTENT_CREATOR_TOKEN_ADDED\x10\xd2\x07\x12-\n(ATOM_NOTIFICATION_CHANNEL_CLASSIFICATION\x10\xd7\x07\x12\x31\n,ATOM_CAMERA_STATUS_FOR_COMPATIBILITY_CHANGED\x10\xe7\x07\x12&\n!ATOM_FEDERATED_COMPUTE_API_CALLED\x10\xc8\x05\x12\x33\n.ATOM_FEDERATED_COMPUTE_TRAINING_EVENT_REPORTED\x10\x83\x06\x12\x30\n+ATOM_EXAMPLE_ITERATOR_NEXT_LATENCY_REPORTED\x10\xc6\x06\x12\x30\n+ATOM_FEDERATED_COMPUTE_TRACE_EVENT_REPORTED\x10\xe0\x07\x12 \n\x1b\x41TOM_EXPRESS_EVENT_REPORTED\x10\x90\x04\x12+\n&ATOM_EXPRESS_HISTOGRAM_SAMPLE_REPORTED\x10\xd1\x04\x12$\n\x1f\x41TOM_EXPRESS_UID_EVENT_REPORTED\x10\x84\x05\x12/\n*ATOM_EXPRESS_UID_HISTOGRAM_SAMPLE_REPORTED\x10\x92\x05\x12\x1f\n\x1a\x41TOM_DREAM_SETTING_CHANGED\x10\xc1\x05\x12 \n\x1b\x41TOM_DREAM_SETTING_SNAPSHOT\x10\xd0O\x12\x1b\n\x16\x41TOM_DND_STATE_CHANGED\x10\x91\x05\x12(\n#ATOM_EXTERNAL_DISPLAY_STATE_CHANGED\x10\xa6\x06\x12,\n\'ATOM_DISPLAY_MODE_DIRECTOR_VOTE_CHANGED\x10\x98\x06\x12\'\n\"ATOM_DEVICE_POLICY_MANAGEMENT_MODE\x10\xe8O\x12\x1d\n\x18\x41TOM_DEVICE_POLICY_STATE\x10\xe9O\x12/\n*ATOM_DEVICE_LOCK_CHECK_IN_REQUEST_REPORTED\x10\xd6\x05\x12\x34\n/ATOM_DEVICE_LOCK_PROVISIONING_COMPLETE_REPORTED\x10\xd7\x05\x12\x30\n+ATOM_DEVICE_LOCK_KIOSK_APP_REQUEST_REPORTED\x10\xd8\x05\x12-\n(ATOM_DEVICE_LOCK_CHECK_IN_RETRY_REPORTED\x10\x95\x06\x12\x30\n+ATOM_DEVICE_LOCK_PROVISION_FAILURE_REPORTED\x10\x96\x06\x12\x39\n4ATOM_DEVICE_LOCK_LOCK_UNLOCK_DEVICE_FAILURE_REPORTED\x10\x97\x06\x12!\n\x1c\x41TOM_DESKTOP_MODE_UI_CHANGED\x10\xb2\x06\x12*\n%ATOM_DESKTOP_MODE_SESSION_TASK_UPDATE\x10\xb3\x06\x12(\n#ATOM_DESKTOP_MODE_TASK_SIZE_UPDATED\x10\xa7\x07\x12\x1f\n\x1a\x41TOM_CRONET_ENGINE_CREATED\x10\xbf\x05\x12!\n\x1c\x41TOM_CRONET_TRAFFIC_REPORTED\x10\xc0\x05\x12+\n&ATOM_CRONET_ENGINE_BUILDER_INITIALIZED\x10\xfa\x05\x12\'\n\"ATOM_CRONET_HTTP_FLAGS_INITIALIZED\x10\xfb\x05\x12\x1c\n\x17\x41TOM_CRONET_INITIALIZED\x10\xfc\x05\x12\'\n\"ATOM_CREDENTIAL_MANAGER_API_CALLED\x10\xc9\x04\x12\x30\n+ATOM_CREDENTIAL_MANAGER_INIT_PHASE_REPORTED\x10\x8b\x05\x12\x35\n0ATOM_CREDENTIAL_MANAGER_CANDIDATE_PHASE_REPORTED\x10\x8c\x05\x12\x31\n,ATOM_CREDENTIAL_MANAGER_FINAL_PHASE_REPORTED\x10\x8d\x05\x12+\n&ATOM_CREDENTIAL_MANAGER_TOTAL_REPORTED\x10\x9b\x05\x12\x30\n+ATOM_CREDENTIAL_MANAGER_FINALNOUID_REPORTED\x10\x9c\x05\x12)\n$ATOM_CREDENTIAL_MANAGER_GET_REPORTED\x10\x9d\x05\x12\x30\n+ATOM_CREDENTIAL_MANAGER_AUTH_CLICK_REPORTED\x10\x9e\x05\x12)\n$ATOM_CREDENTIAL_MANAGER_APIV2_CALLED\x10\x9f\x05\x12\x14\n\x0f\x41TOM_CPU_POLICY\x10\xd7O\x12&\n!ATOM_VPN_CONNECTION_STATE_CHANGED\x10\xd2\x06\x12!\n\x1c\x41TOM_VPN_CONNECTION_REPORTED\x10\xd3\x06\x12$\n\x1f\x41TOM_IP_CLIENT_RA_INFO_REPORTED\x10\x8a\x06\x12#\n\x1e\x41TOM_APF_SESSION_INFO_REPORTED\x10\x89\x06\x12\x31\n,ATOM_CORE_NETWORKING_TERRIBLE_ERROR_OCCURRED\x10\xd3\x07\x12.\n)ATOM_NETWORK_STATS_RECORDER_FILE_OPERATED\x10\x8f\x06\x12\'\n\"ATOM_DAILY_KEEPALIVE_INFO_REPORTED\x10\x8a\x05\x12\'\n\"ATOM_NETWORK_REQUEST_STATE_CHANGED\x10\x8b\x06\x12,\n\'ATOM_TETHERING_ACTIVE_SESSIONS_REPORTED\x10\x9d\x07\x12@\n;ATOM_CERTIFICATE_TRANSPARENCY_LOG_LIST_UPDATE_STATE_CHANGED\x10\xcc\x07\x12!\n\x1c\x41TOM_HARDWARE_RENDERER_EVENT\x10\xb2\x07\x12\x1c\n\x17\x41TOM_TEXTURE_VIEW_EVENT\x10\xb3\x07\x12\x1f\n\x1a\x41TOM_SURFACE_CONTROL_EVENT\x10\xb4\x07\x12\x17\n\x12\x41TOM_IMAGE_DECODED\x10\xd1\x07\x12\x39\n4ATOM_CERTIFICATE_TRANSPARENCY_LOG_LIST_STATE_CHANGED\x10\xa6\x07\x12 \n\x1b\x41TOM_CONSCRYPT_SERVICE_USED\x10\xc5\x07\x12\x38\n3ATOM_CERTIFICATE_TRANSPARENCY_VERIFICATION_REPORTED\x10\xdd\x07\x12\x30\n+ATOM_CAMERA_FEATURE_COMBINATION_QUERY_EVENT\x10\x84\x07\x12\x18\n\x13\x41TOM_BROADCAST_SENT\x10\x9a\x07\x12/\n*ATOM_BLUETOOTH_HASHED_DEVICE_NAME_REPORTED\x10\xe5\x04\x12/\n*ATOM_BLUETOOTH_L2CAP_COC_CLIENT_CONNECTION\x10\xe6\x04\x12/\n*ATOM_BLUETOOTH_L2CAP_COC_SERVER_CONNECTION\x10\xe7\x04\x12(\n#ATOM_BLUETOOTH_LE_SESSION_CONNECTED\x10\x90\x05\x12\x33\n.ATOM_RESTRICTED_BLUETOOTH_DEVICE_NAME_REPORTED\x10\x9a\x05\x12\x30\n+ATOM_BLUETOOTH_PROFILE_CONNECTION_ATTEMPTED\x10\xb8\x05\x12\x32\n-ATOM_BLUETOOTH_CONTENT_PROFILE_ERROR_REPORTED\x10\x8d\x06\x12/\n*ATOM_BLUETOOTH_RFCOMM_CONNECTION_ATTEMPTED\x10\x8e\x06\x12\x32\n-ATOM_REMOTE_DEVICE_INFORMATION_WITH_METRIC_ID\x10\xde\x06\x12#\n\x1e\x41TOM_LE_APP_SCAN_STATE_CHANGED\x10\xe6\x06\x12\x1f\n\x1a\x41TOM_LE_RADIO_SCAN_STOPPED\x10\xe7\x06\x12!\n\x1c\x41TOM_LE_SCAN_RESULT_RECEIVED\x10\xe8\x06\x12\x18\n\x13\x41TOM_LE_SCAN_ABUSED\x10\xe9\x06\x12\x1e\n\x19\x41TOM_LE_ADV_STATE_CHANGED\x10\xea\x06\x12\x1f\n\x1a\x41TOM_LE_ADV_ERROR_REPORTED\x10\xeb\x06\x12\x1f\n\x1a\x41TOM_A2DP_SESSION_REPORTED\x10\x88\x07\x12.\n)ATOM_BLUETOOTH_CROSS_LAYER_EVENT_REPORTED\x10\x94\x07\x12*\n%ATOM_BROADCAST_AUDIO_SESSION_REPORTED\x10\x9f\x07\x12\'\n\"ATOM_BROADCAST_AUDIO_SYNC_REPORTED\x10\xa0\x07\x12\x37\n2ATOM_BLUETOOTH_RFCOMM_CONNECTION_REPORTED_AT_CLOSE\x10\xd6\x07\x12!\n\x1c\x41TOM_BLUETOOTH_LE_CONNECTION\x10\xdc\x07\x12.\n)ATOM_HEARING_DEVICE_ACTIVE_EVENT_REPORTED\x10\xfd\x07\x12(\n#ATOM_BACKPORTED_FIX_STATUS_REPORTED\x10\xdb\x07\x12\x1c\n\x17\x41TOM_PLUGIN_INITIALIZED\x10\x8f\x05\x12\x38\n3ATOM_CAR_SYSTEM_UI_DATA_SUBSCRIPTION_EVENT_REPORTED\x10\xce\x07\x12\x37\n2ATOM_CAR_SETTINGS_DATA_SUBSCRIPTION_EVENT_REPORTED\x10\xcf\x07\x12#\n\x1e\x41TOM_CAR_QC_LIB_EVENT_REPORTED\x10\xd0\x07\x12*\n%ATOM_CAR_WAKEUP_FROM_SUSPEND_REPORTED\x10\xd4\x06\x12$\n\x1f\x41TOM_CAR_RECENTS_EVENT_REPORTED\x10\x82\x06\x12&\n!ATOM_CAR_CALM_MODE_EVENT_REPORTED\x10\x9d\x06\x12$\n\x1f\x41TOM_AUTOFILL_UI_EVENT_REPORTED\x10\xdb\x04\x12(\n#ATOM_AUTOFILL_FILL_REQUEST_REPORTED\x10\xdc\x04\x12)\n$ATOM_AUTOFILL_FILL_RESPONSE_REPORTED\x10\xdd\x04\x12&\n!ATOM_AUTOFILL_SAVE_EVENT_REPORTED\x10\xde\x04\x12$\n\x1f\x41TOM_AUTOFILL_SESSION_COMMITTED\x10\xdf\x04\x12\x36\n1ATOM_AUTOFILL_FIELD_CLASSIFICATION_EVENT_REPORTED\x10\x93\x05\x12\x1c\n\x17\x41TOM_ODREFRESH_REPORTED\x10\xee\x02\x12\x19\n\x14\x41TOM_ODSIGN_REPORTED\x10\xa4\x04\x12%\n ATOM_BACKGROUND_DEXOPT_JOB_ENDED\x10\xd3\x03\x12$\n\x1f\x41TOM_PREREBOOT_DEXOPT_JOB_ENDED\x10\xf3\x06\x12\x1c\n\x17\x41TOM_ART_DATUM_REPORTED\x10\xcc\x02\x12#\n\x1e\x41TOM_ART_DEVICE_DATUM_REPORTED\x10\xa6\x04\x12\"\n\x1d\x41TOM_ART_DATUM_DELTA_REPORTED\x10\xb5\x04\x12\x1e\n\x19\x41TOM_ART_DEX2OAT_REPORTED\x10\xa1\x07\x12\x1b\n\x16\x41TOM_ART_DEVICE_STATUS\x10\xddO\x12.\n)ATOM_APP_SEARCH_SET_SCHEMA_STATS_REPORTED\x10\x81\x03\x12\x34\n/ATOM_APP_SEARCH_SCHEMA_MIGRATION_STATS_REPORTED\x10\xc3\x04\x12\x37\n2ATOM_APP_SEARCH_USAGE_SEARCH_INTENT_STATS_REPORTED\x10\xb9\x06\x12\x41\n<ATOM_APP_SEARCH_USAGE_SEARCH_INTENT_RAW_QUERY_STATS_REPORTED\x10\xba\x06\x12\x30\n+ATOM_APP_SEARCH_APPS_INDEXER_STATS_REPORTED\x10\x8d\x07\x12(\n#ATOM_APP_FUNCTIONS_REQUEST_REPORTED\x10\xe6\x07\x12%\n ATOM_APEX_INSTALLATION_REQUESTED\x10\xdc\x05\x12\"\n\x1d\x41TOM_APEX_INSTALLATION_STAGED\x10\xdd\x05\x12!\n\x1c\x41TOM_APEX_INSTALLATION_ENDED\x10\xde\x05\x12&\n!ATOM_AI_WALLPAPERS_BUTTON_PRESSED\x10\xc2\x05\x12)\n$ATOM_AI_WALLPAPERS_TEMPLATE_SELECTED\x10\xc3\x05\x12%\n ATOM_AI_WALLPAPERS_TERM_SELECTED\x10\xc4\x05\x12%\n ATOM_AI_WALLPAPERS_WALLPAPER_SET\x10\xc5\x05\x12\'\n\"ATOM_AI_WALLPAPERS_SESSION_SUMMARY\x10\xc6\x05\x12)\n$ATOM_JSSCRIPTENGINE_LATENCY_REPORTED\x10\xe3\x03\x12 \n\x1b\x41TOM_AD_SERVICES_API_CALLED\x10\xb3\x03\x12\x31\n,ATOM_AD_SERVICES_MESUREMENT_REPORTS_UPLOADED\x10\xb4\x03\x12\x39\n4ATOM_MOBILE_DATA_DOWNLOAD_FILE_GROUP_STATUS_REPORTED\x10\xea\x03\x12\x37\n2ATOM_MOBILE_DATA_DOWNLOAD_DOWNLOAD_RESULT_REPORTED\x10\xf6\x03\x12-\n(ATOM_AD_SERVICES_SETTINGS_USAGE_REPORTED\x10\xed\x03\x12+\n&ATOM_BACKGROUND_FETCH_PROCESS_REPORTED\x10\xf0\x03\x12\x31\n,ATOM_UPDATE_CUSTOM_AUDIENCE_PROCESS_REPORTED\x10\xf1\x03\x12)\n$ATOM_RUN_AD_BIDDING_PROCESS_REPORTED\x10\xf2\x03\x12)\n$ATOM_RUN_AD_SCORING_PROCESS_REPORTED\x10\xf3\x03\x12+\n&ATOM_RUN_AD_SELECTION_PROCESS_REPORTED\x10\xf4\x03\x12\x30\n+ATOM_RUN_AD_BIDDING_PER_CA_PROCESS_REPORTED\x10\xf5\x03\x12@\n;ATOM_MOBILE_DATA_DOWNLOAD_FILE_GROUP_STORAGE_STATS_REPORTED\x10\xf7\x03\x12/\n*ATOM_AD_SERVICES_MEASUREMENT_REGISTRATIONS\x10\x80\x04\x12)\n$ATOM_AD_SERVICES_GET_TOPICS_REPORTED\x10\x97\x04\x12?\n:ATOM_AD_SERVICES_EPOCH_COMPUTATION_GET_TOP_TOPICS_REPORTED\x10\x98\x04\x12;\n6ATOM_AD_SERVICES_EPOCH_COMPUTATION_CLASSIFIER_REPORTED\x10\x99\x04\x12\x35\n0ATOM_AD_SERVICES_BACK_COMPAT_GET_TOPICS_REPORTED\x10\xd6\x04\x12G\nBATOM_AD_SERVICES_BACK_COMPAT_EPOCH_COMPUTATION_CLASSIFIER_REPORTED\x10\xd7\x04\x12,\n\'ATOM_AD_SERVICES_MEASUREMENT_DEBUG_KEYS\x10\x80\x05\x12$\n\x1f\x41TOM_AD_SERVICES_ERROR_REPORTED\x10\x96\x05\x12\x38\n3ATOM_AD_SERVICES_BACKGROUND_JOBS_EXECUTION_REPORTED\x10\x97\x05\x12=\n8ATOM_AD_SERVICES_MEASUREMENT_DELAYED_SOURCE_REGISTRATION\x10\xa1\x05\x12-\n(ATOM_AD_SERVICES_MEASUREMENT_ATTRIBUTION\x10\xa2\x05\x12&\n!ATOM_AD_SERVICES_MEASUREMENT_JOBS\x10\xa3\x05\x12)\n$ATOM_AD_SERVICES_MEASUREMENT_WIPEOUT\x10\xa4\x05\x12<\n7ATOM_AD_SERVICES_MEASUREMENT_AD_ID_MATCH_FOR_DEBUG_KEYS\x10\xb7\x05\x12,\n\'ATOM_AD_SERVICES_ENROLLMENT_DATA_STORED\x10\xb9\x05\x12\x30\n+ATOM_AD_SERVICES_ENROLLMENT_FILE_DOWNLOADED\x10\xba\x05\x12(\n#ATOM_AD_SERVICES_ENROLLMENT_MATCHED\x10\xbb\x05\x12&\n!ATOM_AD_SERVICES_CONSENT_MIGRATED\x10\xbe\x05\x12\'\n\"ATOM_AD_SERVICES_ENROLLMENT_FAILED\x10\xca\x05\x12\x34\n/ATOM_AD_SERVICES_MEASUREMENT_CLICK_VERIFICATION\x10\xf4\x05\x12,\n\'ATOM_AD_SERVICES_ENCRYPTION_KEY_FETCHED\x10\xfd\x05\x12\x39\n4ATOM_AD_SERVICES_ENCRYPTION_KEY_DB_TRANSACTION_ENDED\x10\xfe\x05\x12(\n#ATOM_DESTINATION_REGISTERED_BEACONS\x10\xff\x05\x12\'\n\"ATOM_REPORT_INTERACTION_API_CALLED\x10\x80\x06\x12-\n(ATOM_INTERACTION_REPORTING_TABLE_CLEARED\x10\x81\x06\x12+\n&ATOM_APP_MANIFEST_CONFIG_HELPER_CALLED\x10\x94\x06\x12/\n*ATOM_AD_FILTERING_PROCESS_JOIN_CA_REPORTED\x10\x99\x06\x12\x34\n/ATOM_AD_FILTERING_PROCESS_AD_SELECTION_REPORTED\x10\x9a\x06\x12/\n*ATOM_AD_COUNTER_HISTOGRAM_UPDATER_REPORTED\x10\x9b\x06\x12 \n\x1b\x41TOM_SIGNATURE_VERIFICATION\x10\xa7\x06\x12\x34\n/ATOM_K_ANON_IMMEDIATE_SIGN_JOIN_STATUS_REPORTED\x10\xa8\x06\x12/\n*ATOM_K_ANON_BACKGROUND_JOB_STATUS_REPORTED\x10\xa9\x06\x12+\n&ATOM_K_ANON_INITIALIZE_STATUS_REPORTED\x10\xaa\x06\x12%\n ATOM_K_ANON_SIGN_STATUS_REPORTED\x10\xab\x06\x12%\n ATOM_K_ANON_JOIN_STATUS_REPORTED\x10\xac\x06\x12\x30\n+ATOM_K_ANON_KEY_ATTESTATION_STATUS_REPORTED\x10\xad\x06\x12*\n%ATOM_GET_AD_SELECTION_DATA_API_CALLED\x10\xae\x06\x12\x35\n0ATOM_GET_AD_SELECTION_DATA_BUYER_INPUT_GENERATED\x10\xaf\x06\x12,\n\'ATOM_BACKGROUND_JOB_SCHEDULING_REPORTED\x10\xc2\x06\x12\x36\n1ATOM_TOPICS_ENCRYPTION_EPOCH_COMPUTATION_REPORTED\x10\xc8\x06\x12/\n*ATOM_TOPICS_ENCRYPTION_GET_TOPICS_REPORTED\x10\xc9\x06\x12)\n$ATOM_ADSERVICES_SHELL_COMMAND_CALLED\x10\xca\x06\x12#\n\x1e\x41TOM_UPDATE_SIGNALS_API_CALLED\x10\xcb\x06\x12\x1a\n\x15\x41TOM_ENCODING_JOB_RUN\x10\xcc\x06\x12\x1b\n\x16\x41TOM_ENCODING_JS_FETCH\x10\xcd\x06\x12\x1f\n\x1a\x41TOM_ENCODING_JS_EXECUTION\x10\xce\x06\x12,\n\'ATOM_PERSIST_AD_SELECTION_RESULT_CALLED\x10\xcf\x06\x12)\n$ATOM_SERVER_AUCTION_KEY_FETCH_CALLED\x10\xd0\x06\x12\x35\n0ATOM_SERVER_AUCTION_BACKGROUND_KEY_FETCH_ENABLED\x10\xd1\x06\x12:\n5ATOM_AD_SERVICES_MEASUREMENT_PROCESS_ODP_REGISTRATION\x10\xe0\x06\x12<\n7ATOM_AD_SERVICES_MEASUREMENT_NOTIFY_REGISTRATION_TO_ODP\x10\xe1\x06\x12-\n(ATOM_SELECT_ADS_FROM_OUTCOMES_API_CALLED\x10\xec\x06\x12&\n!ATOM_REPORT_IMPRESSION_API_CALLED\x10\xed\x06\x12\x32\n-ATOM_AD_SERVICES_ENROLLMENT_TRANSACTION_STATS\x10\xf5\x06\x12\x32\n-ATOM_AD_SERVICES_COBALT_LOGGER_EVENT_REPORTED\x10\x86\x07\x12\x38\n3ATOM_AD_SERVICES_COBALT_PERIODIC_JOB_EVENT_REPORTED\x10\x87\x07\x12)\n$ATOM_UPDATE_SIGNALS_PROCESS_REPORTED\x10\x89\x07\x12\x34\n/ATOM_TOPICS_SCHEDULE_EPOCH_JOB_SETTING_REPORTED\x10\xa2\x07\x12=\n8ATOM_SCHEDULED_CUSTOM_AUDIENCE_UPDATE_SCHEDULE_ATTEMPTED\x10\xc7\x07\x12\x34\n/ATOM_SCHEDULED_CUSTOM_AUDIENCE_UPDATE_PERFORMED\x10\xc8\x07\x12O\nJATOM_SCHEDULED_CUSTOM_AUDIENCE_UPDATE_PERFORMED_ATTEMPTED_FAILURE_REPORTED\x10\xc9\x07\x12=\n8ATOM_SCHEDULED_CUSTOM_AUDIENCE_UPDATE_BACKGROUND_JOB_RAN\x10\xca\x07\x12\x1f\n\x1a\x41TOM_THERMAL_STATUS_CALLED\x10\x84\x06\x12!\n\x1c\x41TOM_THERMAL_HEADROOM_CALLED\x10\x85\x06\x12,\n\'ATOM_THERMAL_HEADROOM_THRESHOLDS_CALLED\x10\x86\x06\x12\'\n\"ATOM_ADPF_HINT_SESSION_TID_CLEANUP\x10\xc7\x06\x12%\n ATOM_THERMAL_HEADROOM_THRESHOLDS\x10\xd9O\x12\x1f\n\x1a\x41TOM_ADPF_SESSION_SNAPSHOT\x10\xeaO\x12\x32\n-ATOM_ADAPTIVE_AUTH_UNLOCK_AFTER_LOCK_REPORTED\x10\xb4\x06\x12\x1f\n\x1a\x41TOM_ACCOUNT_MANAGER_EVENT\x10\xb7\x07\x12-\n(ATOM_ACCESSIBILITY_CHECK_RESULT_REPORTED\x10\x8e\x07*\xa5\x07\n\x0fMeminfoCounters\x12\x17\n\x13MEMINFO_UNSPECIFIED\x10\x00\x12\x15\n\x11MEMINFO_MEM_TOTAL\x10\x01\x12\x14\n\x10MEMINFO_MEM_FREE\x10\x02\x12\x19\n\x15MEMINFO_MEM_AVAILABLE\x10\x03\x12\x13\n\x0fMEMINFO_BUFFERS\x10\x04\x12\x12\n\x0eMEMINFO_CACHED\x10\x05\x12\x17\n\x13MEMINFO_SWAP_CACHED\x10\x06\x12\x12\n\x0eMEMINFO_ACTIVE\x10\x07\x12\x14\n\x10MEMINFO_INACTIVE\x10\x08\x12\x17\n\x13MEMINFO_ACTIVE_ANON\x10\t\x12\x19\n\x15MEMINFO_INACTIVE_ANON\x10\n\x12\x17\n\x13MEMINFO_ACTIVE_FILE\x10\x0b\x12\x19\n\x15MEMINFO_INACTIVE_FILE\x10\x0c\x12\x17\n\x13MEMINFO_UNEVICTABLE\x10\r\x12\x13\n\x0fMEMINFO_MLOCKED\x10\x0e\x12\x16\n\x12MEMINFO_SWAP_TOTAL\x10\x0f\x12\x15\n\x11MEMINFO_SWAP_FREE\x10\x10\x12\x11\n\rMEMINFO_DIRTY\x10\x11\x12\x15\n\x11MEMINFO_WRITEBACK\x10\x12\x12\x16\n\x12MEMINFO_ANON_PAGES\x10\x13\x12\x12\n\x0eMEMINFO_MAPPED\x10\x14\x12\x11\n\rMEMINFO_SHMEM\x10\x15\x12\x10\n\x0cMEMINFO_SLAB\x10\x16\x12\x1c\n\x18MEMINFO_SLAB_RECLAIMABLE\x10\x17\x12\x1e\n\x1aMEMINFO_SLAB_UNRECLAIMABLE\x10\x18\x12\x18\n\x14MEMINFO_KERNEL_STACK\x10\x19\x12\x17\n\x13MEMINFO_PAGE_TABLES\x10\x1a\x12\x18\n\x14MEMINFO_COMMIT_LIMIT\x10\x1b\x12\x17\n\x13MEMINFO_COMMITED_AS\x10\x1c\x12\x19\n\x15MEMINFO_VMALLOC_TOTAL\x10\x1d\x12\x18\n\x14MEMINFO_VMALLOC_USED\x10\x1e\x12\x19\n\x15MEMINFO_VMALLOC_CHUNK\x10\x1f\x12\x15\n\x11MEMINFO_CMA_TOTAL\x10 \x12\x14\n\x10MEMINFO_CMA_FREE\x10!\x12\x0f\n\x0bMEMINFO_GPU\x10\"\x12\x10\n\x0cMEMINFO_ZRAM\x10#\x12\x10\n\x0cMEMINFO_MISC\x10$\x12\x14\n\x10MEMINFO_ION_HEAP\x10%\x12\x19\n\x15MEMINFO_ION_HEAP_POOL\x10&*\x81,\n\x0eVmstatCounters\x12\x16\n\x12VMSTAT_UNSPECIFIED\x10\x00\x12\x18\n\x14VMSTAT_NR_FREE_PAGES\x10\x01\x12\x19\n\x15VMSTAT_NR_ALLOC_BATCH\x10\x02\x12\x1b\n\x17VMSTAT_NR_INACTIVE_ANON\x10\x03\x12\x19\n\x15VMSTAT_NR_ACTIVE_ANON\x10\x04\x12\x1b\n\x17VMSTAT_NR_INACTIVE_FILE\x10\x05\x12\x19\n\x15VMSTAT_NR_ACTIVE_FILE\x10\x06\x12\x19\n\x15VMSTAT_NR_UNEVICTABLE\x10\x07\x12\x13\n\x0fVMSTAT_NR_MLOCK\x10\x08\x12\x18\n\x14VMSTAT_NR_ANON_PAGES\x10\t\x12\x14\n\x10VMSTAT_NR_MAPPED\x10\n\x12\x18\n\x14VMSTAT_NR_FILE_PAGES\x10\x0b\x12\x13\n\x0fVMSTAT_NR_DIRTY\x10\x0c\x12\x17\n\x13VMSTAT_NR_WRITEBACK\x10\r\x12\x1e\n\x1aVMSTAT_NR_SLAB_RECLAIMABLE\x10\x0e\x12 \n\x1cVMSTAT_NR_SLAB_UNRECLAIMABLE\x10\x0f\x12\x1e\n\x1aVMSTAT_NR_PAGE_TABLE_PAGES\x10\x10\x12\x1a\n\x16VMSTAT_NR_KERNEL_STACK\x10\x11\x12\x16\n\x12VMSTAT_NR_OVERHEAD\x10\x12\x12\x16\n\x12VMSTAT_NR_UNSTABLE\x10\x13\x12\x14\n\x10VMSTAT_NR_BOUNCE\x10\x14\x12\x1a\n\x16VMSTAT_NR_VMSCAN_WRITE\x10\x15\x12&\n\"VMSTAT_NR_VMSCAN_IMMEDIATE_RECLAIM\x10\x16\x12\x1c\n\x18VMSTAT_NR_WRITEBACK_TEMP\x10\x17\x12\x1b\n\x17VMSTAT_NR_ISOLATED_ANON\x10\x18\x12\x1b\n\x17VMSTAT_NR_ISOLATED_FILE\x10\x19\x12\x13\n\x0fVMSTAT_NR_SHMEM\x10\x1a\x12\x15\n\x11VMSTAT_NR_DIRTIED\x10\x1b\x12\x15\n\x11VMSTAT_NR_WRITTEN\x10\x1c\x12\x1b\n\x17VMSTAT_NR_PAGES_SCANNED\x10\x1d\x12\x1d\n\x19VMSTAT_WORKINGSET_REFAULT\x10\x1e\x12\x1e\n\x1aVMSTAT_WORKINGSET_ACTIVATE\x10\x1f\x12!\n\x1dVMSTAT_WORKINGSET_NODERECLAIM\x10 \x12(\n$VMSTAT_NR_ANON_TRANSPARENT_HUGEPAGES\x10!\x12\x16\n\x12VMSTAT_NR_FREE_CMA\x10\"\x12\x17\n\x13VMSTAT_NR_SWAPCACHE\x10#\x12\x1d\n\x19VMSTAT_NR_DIRTY_THRESHOLD\x10$\x12(\n$VMSTAT_NR_DIRTY_BACKGROUND_THRESHOLD\x10%\x12\x11\n\rVMSTAT_PGPGIN\x10&\x12\x12\n\x0eVMSTAT_PGPGOUT\x10\'\x12\x17\n\x13VMSTAT_PGPGOUTCLEAN\x10(\x12\x11\n\rVMSTAT_PSWPIN\x10)\x12\x12\n\x0eVMSTAT_PSWPOUT\x10*\x12\x16\n\x12VMSTAT_PGALLOC_DMA\x10+\x12\x19\n\x15VMSTAT_PGALLOC_NORMAL\x10,\x12\x1a\n\x16VMSTAT_PGALLOC_MOVABLE\x10-\x12\x11\n\rVMSTAT_PGFREE\x10.\x12\x15\n\x11VMSTAT_PGACTIVATE\x10/\x12\x17\n\x13VMSTAT_PGDEACTIVATE\x10\x30\x12\x12\n\x0eVMSTAT_PGFAULT\x10\x31\x12\x15\n\x11VMSTAT_PGMAJFAULT\x10\x32\x12\x17\n\x13VMSTAT_PGREFILL_DMA\x10\x33\x12\x1a\n\x16VMSTAT_PGREFILL_NORMAL\x10\x34\x12\x1b\n\x17VMSTAT_PGREFILL_MOVABLE\x10\x35\x12\x1d\n\x19VMSTAT_PGSTEAL_KSWAPD_DMA\x10\x36\x12 \n\x1cVMSTAT_PGSTEAL_KSWAPD_NORMAL\x10\x37\x12!\n\x1dVMSTAT_PGSTEAL_KSWAPD_MOVABLE\x10\x38\x12\x1d\n\x19VMSTAT_PGSTEAL_DIRECT_DMA\x10\x39\x12 \n\x1cVMSTAT_PGSTEAL_DIRECT_NORMAL\x10:\x12!\n\x1dVMSTAT_PGSTEAL_DIRECT_MOVABLE\x10;\x12\x1c\n\x18VMSTAT_PGSCAN_KSWAPD_DMA\x10<\x12\x1f\n\x1bVMSTAT_PGSCAN_KSWAPD_NORMAL\x10=\x12 \n\x1cVMSTAT_PGSCAN_KSWAPD_MOVABLE\x10>\x12\x1c\n\x18VMSTAT_PGSCAN_DIRECT_DMA\x10?\x12\x1f\n\x1bVMSTAT_PGSCAN_DIRECT_NORMAL\x10@\x12 \n\x1cVMSTAT_PGSCAN_DIRECT_MOVABLE\x10\x41\x12!\n\x1dVMSTAT_PGSCAN_DIRECT_THROTTLE\x10\x42\x12\x17\n\x13VMSTAT_PGINODESTEAL\x10\x43\x12\x18\n\x14VMSTAT_SLABS_SCANNED\x10\x44\x12\x1c\n\x18VMSTAT_KSWAPD_INODESTEAL\x10\x45\x12\'\n#VMSTAT_KSWAPD_LOW_WMARK_HIT_QUICKLY\x10\x46\x12(\n$VMSTAT_KSWAPD_HIGH_WMARK_HIT_QUICKLY\x10G\x12\x15\n\x11VMSTAT_PAGEOUTRUN\x10H\x12\x15\n\x11VMSTAT_ALLOCSTALL\x10I\x12\x14\n\x10VMSTAT_PGROTATED\x10J\x12\x19\n\x15VMSTAT_DROP_PAGECACHE\x10K\x12\x14\n\x10VMSTAT_DROP_SLAB\x10L\x12\x1c\n\x18VMSTAT_PGMIGRATE_SUCCESS\x10M\x12\x19\n\x15VMSTAT_PGMIGRATE_FAIL\x10N\x12\"\n\x1eVMSTAT_COMPACT_MIGRATE_SCANNED\x10O\x12\x1f\n\x1bVMSTAT_COMPACT_FREE_SCANNED\x10P\x12\x1b\n\x17VMSTAT_COMPACT_ISOLATED\x10Q\x12\x18\n\x14VMSTAT_COMPACT_STALL\x10R\x12\x17\n\x13VMSTAT_COMPACT_FAIL\x10S\x12\x1a\n\x16VMSTAT_COMPACT_SUCCESS\x10T\x12\x1e\n\x1aVMSTAT_COMPACT_DAEMON_WAKE\x10U\x12!\n\x1dVMSTAT_UNEVICTABLE_PGS_CULLED\x10V\x12\"\n\x1eVMSTAT_UNEVICTABLE_PGS_SCANNED\x10W\x12\"\n\x1eVMSTAT_UNEVICTABLE_PGS_RESCUED\x10X\x12\"\n\x1eVMSTAT_UNEVICTABLE_PGS_MLOCKED\x10Y\x12$\n VMSTAT_UNEVICTABLE_PGS_MUNLOCKED\x10Z\x12\"\n\x1eVMSTAT_UNEVICTABLE_PGS_CLEARED\x10[\x12#\n\x1fVMSTAT_UNEVICTABLE_PGS_STRANDED\x10\\\x12\x15\n\x11VMSTAT_NR_ZSPAGES\x10]\x12\x16\n\x12VMSTAT_NR_ION_HEAP\x10^\x12\x16\n\x12VMSTAT_NR_GPU_HEAP\x10_\x12\x19\n\x15VMSTAT_ALLOCSTALL_DMA\x10`\x12\x1d\n\x19VMSTAT_ALLOCSTALL_MOVABLE\x10\x61\x12\x1c\n\x18VMSTAT_ALLOCSTALL_NORMAL\x10\x62\x12&\n\"VMSTAT_COMPACT_DAEMON_FREE_SCANNED\x10\x63\x12)\n%VMSTAT_COMPACT_DAEMON_MIGRATE_SCANNED\x10\x64\x12\x15\n\x11VMSTAT_NR_FASTRPC\x10\x65\x12$\n VMSTAT_NR_INDIRECTLY_RECLAIMABLE\x10\x66\x12\x1b\n\x17VMSTAT_NR_ION_HEAP_POOL\x10g\x12%\n!VMSTAT_NR_KERNEL_MISC_RECLAIMABLE\x10h\x12%\n!VMSTAT_NR_SHADOW_CALL_STACK_BYTES\x10i\x12\x1d\n\x19VMSTAT_NR_SHMEM_HUGEPAGES\x10j\x12\x1d\n\x19VMSTAT_NR_SHMEM_PMDMAPPED\x10k\x12!\n\x1dVMSTAT_NR_UNRECLAIMABLE_PAGES\x10l\x12\x1e\n\x1aVMSTAT_NR_ZONE_ACTIVE_ANON\x10m\x12\x1e\n\x1aVMSTAT_NR_ZONE_ACTIVE_FILE\x10n\x12 \n\x1cVMSTAT_NR_ZONE_INACTIVE_ANON\x10o\x12 \n\x1cVMSTAT_NR_ZONE_INACTIVE_FILE\x10p\x12\x1e\n\x1aVMSTAT_NR_ZONE_UNEVICTABLE\x10q\x12 \n\x1cVMSTAT_NR_ZONE_WRITE_PENDING\x10r\x12\x13\n\x0fVMSTAT_OOM_KILL\x10s\x12\x15\n\x11VMSTAT_PGLAZYFREE\x10t\x12\x16\n\x12VMSTAT_PGLAZYFREED\x10u\x12\x13\n\x0fVMSTAT_PGREFILL\x10v\x12\x18\n\x14VMSTAT_PGSCAN_DIRECT\x10w\x12\x18\n\x14VMSTAT_PGSCAN_KSWAPD\x10x\x12\x15\n\x11VMSTAT_PGSKIP_DMA\x10y\x12\x19\n\x15VMSTAT_PGSKIP_MOVABLE\x10z\x12\x18\n\x14VMSTAT_PGSKIP_NORMAL\x10{\x12\x19\n\x15VMSTAT_PGSTEAL_DIRECT\x10|\x12\x19\n\x15VMSTAT_PGSTEAL_KSWAPD\x10}\x12\x12\n\x0eVMSTAT_SWAP_RA\x10~\x12\x16\n\x12VMSTAT_SWAP_RA_HIT\x10\x7f\x12\x1e\n\x19VMSTAT_WORKINGSET_RESTORE\x10\x80\x01\x12\x1d\n\x18VMSTAT_ALLOCSTALL_DEVICE\x10\x81\x01\x12\x1c\n\x17VMSTAT_ALLOCSTALL_DMA32\x10\x82\x01\x12\x1b\n\x16VMSTAT_BALLOON_DEFLATE\x10\x83\x01\x12\x1b\n\x16VMSTAT_BALLOON_INFLATE\x10\x84\x01\x12\x1b\n\x16VMSTAT_BALLOON_MIGRATE\x10\x85\x01\x12\x1a\n\x15VMSTAT_CMA_ALLOC_FAIL\x10\x86\x01\x12\x1d\n\x18VMSTAT_CMA_ALLOC_SUCCESS\x10\x87\x01\x12\x1d\n\x18VMSTAT_NR_FILE_HUGEPAGES\x10\x88\x01\x12\x1d\n\x18VMSTAT_NR_FILE_PMDMAPPED\x10\x89\x01\x12 \n\x1bVMSTAT_NR_FOLL_PIN_ACQUIRED\x10\x8a\x01\x12 \n\x1bVMSTAT_NR_FOLL_PIN_RELEASED\x10\x8b\x01\x12#\n\x1eVMSTAT_NR_SEC_PAGE_TABLE_PAGES\x10\x8c\x01\x12 \n\x1bVMSTAT_NR_SHADOW_CALL_STACK\x10\x8d\x01\x12\x19\n\x14VMSTAT_NR_SWAPCACHED\x10\x8e\x01\x12 \n\x1bVMSTAT_NR_THROTTLED_WRITTEN\x10\x8f\x01\x12\x1a\n\x15VMSTAT_PGALLOC_DEVICE\x10\x90\x01\x12\x19\n\x14VMSTAT_PGALLOC_DMA32\x10\x91\x01\x12\x1b\n\x16VMSTAT_PGDEMOTE_DIRECT\x10\x92\x01\x12\x1b\n\x16VMSTAT_PGDEMOTE_KSWAPD\x10\x93\x01\x12\x13\n\x0eVMSTAT_PGREUSE\x10\x94\x01\x12\x17\n\x12VMSTAT_PGSCAN_ANON\x10\x95\x01\x12\x17\n\x12VMSTAT_PGSCAN_FILE\x10\x96\x01\x12\x19\n\x14VMSTAT_PGSKIP_DEVICE\x10\x97\x01\x12\x18\n\x13VMSTAT_PGSKIP_DMA32\x10\x98\x01\x12\x18\n\x13VMSTAT_PGSTEAL_ANON\x10\x99\x01\x12\x18\n\x13VMSTAT_PGSTEAL_FILE\x10\x9a\x01\x12\x1e\n\x19VMSTAT_THP_COLLAPSE_ALLOC\x10\x9b\x01\x12%\n VMSTAT_THP_COLLAPSE_ALLOC_FAILED\x10\x9c\x01\x12#\n\x1eVMSTAT_THP_DEFERRED_SPLIT_PAGE\x10\x9d\x01\x12\x1b\n\x16VMSTAT_THP_FAULT_ALLOC\x10\x9e\x01\x12\x1e\n\x19VMSTAT_THP_FAULT_FALLBACK\x10\x9f\x01\x12%\n VMSTAT_THP_FAULT_FALLBACK_CHARGE\x10\xa0\x01\x12\x1a\n\x15VMSTAT_THP_FILE_ALLOC\x10\xa1\x01\x12\x1d\n\x18VMSTAT_THP_FILE_FALLBACK\x10\xa2\x01\x12$\n\x1fVMSTAT_THP_FILE_FALLBACK_CHARGE\x10\xa3\x01\x12\x1b\n\x16VMSTAT_THP_FILE_MAPPED\x10\xa4\x01\x12\x1e\n\x19VMSTAT_THP_MIGRATION_FAIL\x10\xa5\x01\x12\x1f\n\x1aVMSTAT_THP_MIGRATION_SPLIT\x10\xa6\x01\x12!\n\x1cVMSTAT_THP_MIGRATION_SUCCESS\x10\xa7\x01\x12$\n\x1fVMSTAT_THP_SCAN_EXCEED_NONE_PTE\x10\xa8\x01\x12%\n VMSTAT_THP_SCAN_EXCEED_SHARE_PTE\x10\xa9\x01\x12$\n\x1fVMSTAT_THP_SCAN_EXCEED_SWAP_PTE\x10\xaa\x01\x12\x1a\n\x15VMSTAT_THP_SPLIT_PAGE\x10\xab\x01\x12!\n\x1cVMSTAT_THP_SPLIT_PAGE_FAILED\x10\xac\x01\x12\x19\n\x14VMSTAT_THP_SPLIT_PMD\x10\xad\x01\x12\x16\n\x11VMSTAT_THP_SWPOUT\x10\xae\x01\x12\x1f\n\x1aVMSTAT_THP_SWPOUT_FALLBACK\x10\xaf\x01\x12\x1f\n\x1aVMSTAT_THP_ZERO_PAGE_ALLOC\x10\xb0\x01\x12&\n!VMSTAT_THP_ZERO_PAGE_ALLOC_FAILED\x10\xb1\x01\x12\x1a\n\x15VMSTAT_VMA_LOCK_ABORT\x10\xb2\x01\x12\x19\n\x14VMSTAT_VMA_LOCK_MISS\x10\xb3\x01\x12\x1a\n\x15VMSTAT_VMA_LOCK_RETRY\x10\xb4\x01\x12\x1c\n\x17VMSTAT_VMA_LOCK_SUCCESS\x10\xb5\x01\x12$\n\x1fVMSTAT_WORKINGSET_ACTIVATE_ANON\x10\xb6\x01\x12$\n\x1fVMSTAT_WORKINGSET_ACTIVATE_FILE\x10\xb7\x01\x12\x1c\n\x17VMSTAT_WORKINGSET_NODES\x10\xb8\x01\x12#\n\x1eVMSTAT_WORKINGSET_REFAULT_ANON\x10\xb9\x01\x12#\n\x1eVMSTAT_WORKINGSET_REFAULT_FILE\x10\xba\x01\x12#\n\x1eVMSTAT_WORKINGSET_RESTORE_ANON\x10\xbb\x01\x12#\n\x1eVMSTAT_WORKINGSET_RESTORE_FILE\x10\xbc\x01*\xc8\x05\n\x11\x46traceParseStatus\x12\x1d\n\x19\x46TRACE_STATUS_UNSPECIFIED\x10\x00\x12\x14\n\x10\x46TRACE_STATUS_OK\x10\x01\x12\'\n#FTRACE_STATUS_UNEXPECTED_READ_ERROR\x10\x02\x12#\n\x1f\x46TRACE_STATUS_PARTIAL_PAGE_READ\x10\x03\x12)\n%FTRACE_STATUS_ABI_INVALID_PAGE_HEADER\x10\x04\x12(\n$FTRACE_STATUS_ABI_SHORT_EVENT_HEADER\x10\x05\x12\"\n\x1e\x46TRACE_STATUS_ABI_NULL_PADDING\x10\x06\x12*\n&FTRACE_STATUS_ABI_SHORT_PADDING_LENGTH\x10\x07\x12,\n(FTRACE_STATUS_ABI_INVALID_PADDING_LENGTH\x10\x08\x12\'\n#FTRACE_STATUS_ABI_SHORT_TIME_EXTEND\x10\t\x12&\n\"FTRACE_STATUS_ABI_SHORT_TIME_STAMP\x10\n\x12\'\n#FTRACE_STATUS_ABI_SHORT_DATA_LENGTH\x10\x0b\x12&\n\"FTRACE_STATUS_ABI_ZERO_DATA_LENGTH\x10\x0c\x12)\n%FTRACE_STATUS_ABI_INVALID_DATA_LENGTH\x10\r\x12$\n FTRACE_STATUS_ABI_SHORT_EVENT_ID\x10\x0e\x12\"\n\x1e\x46TRACE_STATUS_ABI_END_OVERFLOW\x10\x0f\x12%\n!FTRACE_STATUS_SHORT_COMPACT_EVENT\x10\x10\x12\x1f\n\x1b\x46TRACE_STATUS_INVALID_EVENT\x10\x11*\x91\x01\n\x0b\x46traceClock\x12\x1c\n\x18\x46TRACE_CLOCK_UNSPECIFIED\x10\x00\x12\x18\n\x14\x46TRACE_CLOCK_UNKNOWN\x10\x01\x12\x17\n\x13\x46TRACE_CLOCK_GLOBAL\x10\x02\x12\x16\n\x12\x46TRACE_CLOCK_LOCAL\x10\x03\x12\x19\n\x15\x46TRACE_CLOCK_MONO_RAW\x10\x04*\xb0\x05\n\x1f\x43hromeCompositorSchedulerAction\x12#\n\x1f\x43\x43_SCHEDULER_ACTION_UNSPECIFIED\x10\x00\x12\x1c\n\x18\x43\x43_SCHEDULER_ACTION_NONE\x10\x01\x12-\n)CC_SCHEDULER_ACTION_SEND_BEGIN_MAIN_FRAME\x10\x02\x12\x1e\n\x1a\x43\x43_SCHEDULER_ACTION_COMMIT\x10\x03\x12*\n&CC_SCHEDULER_ACTION_ACTIVATE_SYNC_TREE\x10\x04\x12(\n$CC_SCHEDULER_ACTION_DRAW_IF_POSSIBLE\x10\x05\x12#\n\x1f\x43\x43_SCHEDULER_ACTION_DRAW_FORCED\x10\x06\x12\"\n\x1e\x43\x43_SCHEDULER_ACTION_DRAW_ABORT\x10\x07\x12<\n8CC_SCHEDULER_ACTION_BEGIN_LAYER_TREE_FRAME_SINK_CREATION\x10\x08\x12%\n!CC_SCHEDULER_ACTION_PREPARE_TILES\x10\t\x12\x38\n4CC_SCHEDULER_ACTION_INVALIDATE_LAYER_TREE_FRAME_SINK\x10\n\x12\x36\n2CC_SCHEDULER_ACTION_PERFORM_IMPL_SIDE_INVALIDATION\x10\x0b\x12\x42\n>CC_SCHEDULER_ACTION_NOTIFY_BEGIN_MAIN_FRAME_NOT_EXPECTED_UNTIL\x10\x0c\x12\x41\n=CC_SCHEDULER_ACTION_NOTIFY_BEGIN_MAIN_FRAME_NOT_EXPECTED_SOON\x10\r*}\n\x0e\x43hromeRAILMode\x12\x12\n\x0eRAIL_MODE_NONE\x10\x00\x12\x16\n\x12RAIL_MODE_RESPONSE\x10\x01\x12\x17\n\x13RAIL_MODE_ANIMATION\x10\x02\x12\x12\n\x0eRAIL_MODE_IDLE\x10\x03\x12\x12\n\x0eRAIL_MODE_LOAD\x10\x04\x42+Z)github.com/google/perfetto/perfetto_proto')
 
 _globals = globals()
 _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
@@ -248,32 +248,32 @@
   _globals['_PROCESSTRACKNAMETRANSLATIONTABLE_RAWTODEOBFUSCATEDNAMEENTRY']._serialized_options = b'8\001'
   _globals['_CHROMESTUDYTRANSLATIONTABLE_HASHTONAMEENTRY']._loaded_options = None
   _globals['_CHROMESTUDYTRANSLATIONTABLE_HASHTONAMEENTRY']._serialized_options = b'8\001'
-  _globals['_VMCURSORENUM']._serialized_start=221190
-  _globals['_VMCURSORENUM']._serialized_end=221289
-  _globals['_BUILTINCLOCK']._serialized_start=221292
-  _globals['_BUILTINCLOCK']._serialized_end=221637
-  _globals['_SEMANTICTYPE']._serialized_start=221639
-  _globals['_SEMANTICTYPE']._serialized_end=221761
-  _globals['_ANDROIDLOGID']._serialized_start=221764
-  _globals['_ANDROIDLOGID']._serialized_end=221906
-  _globals['_ANDROIDLOGPRIORITY']._serialized_start=221909
-  _globals['_ANDROIDLOGPRIORITY']._serialized_end=222064
-  _globals['_PROTOLOGLEVEL']._serialized_start=222067
-  _globals['_PROTOLOGLEVEL']._serialized_end=222266
-  _globals['_ATOMID']._serialized_start=222270
-  _globals['_ATOMID']._serialized_end=270897
-  _globals['_MEMINFOCOUNTERS']._serialized_start=270900
-  _globals['_MEMINFOCOUNTERS']._serialized_end=271833
-  _globals['_VMSTATCOUNTERS']._serialized_start=271836
-  _globals['_VMSTATCOUNTERS']._serialized_end=277469
-  _globals['_FTRACEPARSESTATUS']._serialized_start=277472
-  _globals['_FTRACEPARSESTATUS']._serialized_end=278184
-  _globals['_FTRACECLOCK']._serialized_start=278187
-  _globals['_FTRACECLOCK']._serialized_end=278332
-  _globals['_CHROMECOMPOSITORSCHEDULERACTION']._serialized_start=278335
-  _globals['_CHROMECOMPOSITORSCHEDULERACTION']._serialized_end=279023
-  _globals['_CHROMERAILMODE']._serialized_start=279025
-  _globals['_CHROMERAILMODE']._serialized_end=279150
+  _globals['_VMCURSORENUM']._serialized_start=222243
+  _globals['_VMCURSORENUM']._serialized_end=222342
+  _globals['_BUILTINCLOCK']._serialized_start=222345
+  _globals['_BUILTINCLOCK']._serialized_end=222690
+  _globals['_SEMANTICTYPE']._serialized_start=222692
+  _globals['_SEMANTICTYPE']._serialized_end=222814
+  _globals['_ANDROIDLOGID']._serialized_start=222817
+  _globals['_ANDROIDLOGID']._serialized_end=222959
+  _globals['_ANDROIDLOGPRIORITY']._serialized_start=222962
+  _globals['_ANDROIDLOGPRIORITY']._serialized_end=223117
+  _globals['_PROTOLOGLEVEL']._serialized_start=223120
+  _globals['_PROTOLOGLEVEL']._serialized_end=223319
+  _globals['_ATOMID']._serialized_start=223323
+  _globals['_ATOMID']._serialized_end=271950
+  _globals['_MEMINFOCOUNTERS']._serialized_start=271953
+  _globals['_MEMINFOCOUNTERS']._serialized_end=272886
+  _globals['_VMSTATCOUNTERS']._serialized_start=272889
+  _globals['_VMSTATCOUNTERS']._serialized_end=278522
+  _globals['_FTRACEPARSESTATUS']._serialized_start=278525
+  _globals['_FTRACEPARSESTATUS']._serialized_end=279237
+  _globals['_FTRACECLOCK']._serialized_start=279240
+  _globals['_FTRACECLOCK']._serialized_end=279385
+  _globals['_CHROMECOMPOSITORSCHEDULERACTION']._serialized_start=279388
+  _globals['_CHROMECOMPOSITORSCHEDULERACTION']._serialized_end=280076
+  _globals['_CHROMERAILMODE']._serialized_start=280078
+  _globals['_CHROMERAILMODE']._serialized_end=280203
   _globals['_FTRACEDESCRIPTOR']._serialized_start=64
   _globals['_FTRACEDESCRIPTOR']._serialized_end=212
   _globals['_FTRACEDESCRIPTOR_ATRACECATEGORY']._serialized_start=161
@@ -617,1965 +617,1969 @@
   _globals['_SYSTEMINFO']._serialized_start=33059
   _globals['_SYSTEMINFO']._serialized_end=33590
   _globals['_TRACESTATS']._serialized_start=33593
-  _globals['_TRACESTATS']._serialized_end=35263
+  _globals['_TRACESTATS']._serialized_end=35294
   _globals['_TRACESTATS_BUFFERSTATS']._serialized_start=34228
   _globals['_TRACESTATS_BUFFERSTATS']._serialized_end=34867
   _globals['_TRACESTATS_WRITERSTATS']._serialized_start=34870
-  _globals['_TRACESTATS_WRITERSTATS']._serialized_end=35005
-  _globals['_TRACESTATS_FILTERSTATS']._serialized_start=35008
-  _globals['_TRACESTATS_FILTERSTATS']._serialized_end=35162
-  _globals['_TRACESTATS_FINALFLUSHOUTCOME']._serialized_start=35164
-  _globals['_TRACESTATS_FINALFLUSHOUTCOME']._serialized_end=35263
-  _globals['_ANDROIDAFLAGS']._serialized_start=35266
-  _globals['_ANDROIDAFLAGS']._serialized_end=36248
-  _globals['_ANDROIDAFLAGS_FLAG']._serialized_start=35351
-  _globals['_ANDROIDAFLAGS_FLAG']._serialized_end=35737
-  _globals['_ANDROIDAFLAGS_FLAGPERMISSION']._serialized_start=35739
-  _globals['_ANDROIDAFLAGS_FLAGPERMISSION']._serialized_end=35851
-  _globals['_ANDROIDAFLAGS_VALUEPICKEDFROM']._serialized_start=35854
-  _globals['_ANDROIDAFLAGS_VALUEPICKEDFROM']._serialized_end=35996
-  _globals['_ANDROIDAFLAGS_FLAGSTORAGEBACKEND']._serialized_start=35999
-  _globals['_ANDROIDAFLAGS_FLAGSTORAGEBACKEND']._serialized_end=36163
-  _globals['_ANDROIDAFLAGS_FLAGTYPE']._serialized_start=36165
-  _globals['_ANDROIDAFLAGS_FLAGTYPE']._serialized_end=36248
-  _globals['_ANDROIDGAMEINTERVENTIONLIST']._serialized_start=36251
-  _globals['_ANDROIDGAMEINTERVENTIONLIST']._serialized_end=36650
-  _globals['_ANDROIDGAMEINTERVENTIONLIST_GAMEMODEINFO']._serialized_start=36408
-  _globals['_ANDROIDGAMEINTERVENTIONLIST_GAMEMODEINFO']._serialized_end=36498
-  _globals['_ANDROIDGAMEINTERVENTIONLIST_GAMEPACKAGEINFO']._serialized_start=36501
-  _globals['_ANDROIDGAMEINTERVENTIONLIST_GAMEPACKAGEINFO']._serialized_end=36650
-  _globals['_ANDROIDLOGPACKET']._serialized_start=36653
-  _globals['_ANDROIDLOGPACKET']._serialized_end=37215
-  _globals['_ANDROIDLOGPACKET_LOGEVENT']._serialized_start=36790
-  _globals['_ANDROIDLOGPACKET_LOGEVENT']._serialized_end=37146
-  _globals['_ANDROIDLOGPACKET_LOGEVENT_ARG']._serialized_start=37050
-  _globals['_ANDROIDLOGPACKET_LOGEVENT_ARG']._serialized_end=37146
-  _globals['_ANDROIDLOGPACKET_STATS']._serialized_start=37148
-  _globals['_ANDROIDLOGPACKET_STATS']._serialized_end=37215
-  _globals['_ANDROIDSYSTEMPROPERTY']._serialized_start=37218
-  _globals['_ANDROIDSYSTEMPROPERTY']._serialized_end=37357
-  _globals['_ANDROIDSYSTEMPROPERTY_PROPERTYVALUE']._serialized_start=37313
-  _globals['_ANDROIDSYSTEMPROPERTY_PROPERTYVALUE']._serialized_end=37357
-  _globals['_CPUPERUIDDATA']._serialized_start=37359
-  _globals['_CPUPERUIDDATA']._serialized_end=37441
-  _globals['_GRAPHICSFRAMEEVENT']._serialized_start=37444
-  _globals['_GRAPHICSFRAMEEVENT']._serialized_end=37941
-  _globals['_GRAPHICSFRAMEEVENT_BUFFEREVENT']._serialized_start=37538
-  _globals['_GRAPHICSFRAMEEVENT_BUFFEREVENT']._serialized_end=37700
-  _globals['_GRAPHICSFRAMEEVENT_BUFFEREVENTTYPE']._serialized_start=37703
-  _globals['_GRAPHICSFRAMEEVENT_BUFFEREVENTTYPE']._serialized_end=37941
-  _globals['_INITIALDISPLAYSTATE']._serialized_start=37943
-  _globals['_INITIALDISPLAYSTATE']._serialized_end=38007
-  _globals['_KERNELWAKELOCKDATA']._serialized_start=38010
-  _globals['_KERNELWAKELOCKDATA']._serialized_end=38388
-  _globals['_KERNELWAKELOCKDATA_WAKELOCK']._serialized_start=38173
-  _globals['_KERNELWAKELOCKDATA_WAKELOCK']._serialized_end=38388
-  _globals['_KERNELWAKELOCKDATA_WAKELOCK_TYPE']._serialized_start=38303
-  _globals['_KERNELWAKELOCKDATA_WAKELOCK_TYPE']._serialized_end=38388
-  _globals['_PACKAGESLIST']._serialized_start=38391
-  _globals['_PACKAGESLIST']._serialized_end=38645
-  _globals['_PACKAGESLIST_PACKAGEINFO']._serialized_start=38510
-  _globals['_PACKAGESLIST_PACKAGEINFO']._serialized_end=38645
-  _globals['_PIXELMODEMEVENTS']._serialized_start=38647
-  _globals['_PIXELMODEMEVENTS']._serialized_end=38707
-  _globals['_PIXELMODEMTOKENDATABASE']._serialized_start=38709
-  _globals['_PIXELMODEMTOKENDATABASE']._serialized_end=38752
-  _globals['_RECOVEREDTRACEINFO']._serialized_start=38755
-  _globals['_RECOVEREDTRACEINFO']._serialized_end=38958
-  _globals['_RECOVEREDTRACEINFO_REASON']._serialized_start=38896
-  _globals['_RECOVEREDTRACEINFO_REASON']._serialized_end=38958
-  _globals['_ANDROIDUSERLIST']._serialized_start=38961
-  _globals['_ANDROIDUSERLIST']._serialized_end=39090
-  _globals['_ANDROIDUSERLIST_USERINFO']._serialized_start=39053
-  _globals['_ANDROIDUSERLIST_USERINFO']._serialized_end=39090
-  _globals['_CHROMEBENCHMARKMETADATA']._serialized_start=39093
-  _globals['_CHROMEBENCHMARKMETADATA']._serialized_end=39335
-  _globals['_CHROMEMETADATAPACKET']._serialized_start=39338
-  _globals['_CHROMEMETADATAPACKET']._serialized_end=39698
-  _globals['_CHROMEMETADATAPACKET_FINCHHASH']._serialized_start=39658
-  _globals['_CHROMEMETADATAPACKET_FINCHHASH']._serialized_end=39698
-  _globals['_BACKGROUNDTRACINGMETADATA']._serialized_start=39701
-  _globals['_BACKGROUNDTRACINGMETADATA']._serialized_end=40746
-  _globals['_BACKGROUNDTRACINGMETADATA_TRIGGERRULE']._serialized_start=39917
-  _globals['_BACKGROUNDTRACINGMETADATA_TRIGGERRULE']._serialized_end=40746
-  _globals['_BACKGROUNDTRACINGMETADATA_TRIGGERRULE_HISTOGRAMRULE']._serialized_start=40221
-  _globals['_BACKGROUNDTRACINGMETADATA_TRIGGERRULE_HISTOGRAMRULE']._serialized_end=40327
-  _globals['_BACKGROUNDTRACINGMETADATA_TRIGGERRULE_NAMEDRULE']._serialized_start=40330
-  _globals['_BACKGROUNDTRACINGMETADATA_TRIGGERRULE_NAMEDRULE']._serialized_end=40608
-  _globals['_BACKGROUNDTRACINGMETADATA_TRIGGERRULE_NAMEDRULE_EVENTTYPE']._serialized_start=40475
-  _globals['_BACKGROUNDTRACINGMETADATA_TRIGGERRULE_NAMEDRULE_EVENTTYPE']._serialized_end=40608
-  _globals['_BACKGROUNDTRACINGMETADATA_TRIGGERRULE_TRIGGERTYPE']._serialized_start=40611
-  _globals['_BACKGROUNDTRACINGMETADATA_TRIGGERRULE_TRIGGERTYPE']._serialized_end=40746
-  _globals['_CHROMETRACEDVALUE']._serialized_start=40749
-  _globals['_CHROMETRACEDVALUE']._serialized_end=41088
-  _globals['_CHROMETRACEDVALUE_NESTEDTYPE']._serialized_start=41055
-  _globals['_CHROMETRACEDVALUE_NESTEDTYPE']._serialized_end=41088
-  _globals['_CHROMESTRINGTABLEENTRY']._serialized_start=41090
-  _globals['_CHROMESTRINGTABLEENTRY']._serialized_end=41144
-  _globals['_CHROMETRACEEVENT']._serialized_start=41147
-  _globals['_CHROMETRACEEVENT']._serialized_end=41788
-  _globals['_CHROMETRACEEVENT_ARG']._serialized_start=41520
-  _globals['_CHROMETRACEEVENT_ARG']._serialized_end=41788
-  _globals['_CHROMEMETADATA']._serialized_start=41791
-  _globals['_CHROMEMETADATA']._serialized_end=41919
-  _globals['_CHROMELEGACYJSONTRACE']._serialized_start=41922
-  _globals['_CHROMELEGACYJSONTRACE']._serialized_end=42070
-  _globals['_CHROMELEGACYJSONTRACE_TRACETYPE']._serialized_start=42025
-  _globals['_CHROMELEGACYJSONTRACE_TRACETYPE']._serialized_end=42070
-  _globals['_CHROMEEVENTBUNDLE']._serialized_start=42073
-  _globals['_CHROMEEVENTBUNDLE']._serialized_end=42368
-  _globals['_CHROMETRIGGER']._serialized_start=42370
-  _globals['_CHROMETRIGGER']._serialized_end=42451
-  _globals['_V8STRING']._serialized_start=42453
-  _globals['_V8STRING']._serialized_end=42539
-  _globals['_INTERNEDV8STRING']._serialized_start=42541
-  _globals['_INTERNEDV8STRING']._serialized_end=42648
-  _globals['_INTERNEDV8JSSCRIPT']._serialized_start=42651
-  _globals['_INTERNEDV8JSSCRIPT']._serialized_end=42976
-  _globals['_INTERNEDV8JSSCRIPT_TYPE']._serialized_start=42846
-  _globals['_INTERNEDV8JSSCRIPT_TYPE']._serialized_end=42976
-  _globals['_INTERNEDV8WASMSCRIPT']._serialized_start=42978
-  _globals['_INTERNEDV8WASMSCRIPT']._serialized_end=43065
-  _globals['_INTERNEDV8JSFUNCTION']._serialized_start=43068
-  _globals['_INTERNEDV8JSFUNCTION']._serialized_end=44177
-  _globals['_INTERNEDV8JSFUNCTION_KIND']._serialized_start=43295
-  _globals['_INTERNEDV8JSFUNCTION_KIND']._serialized_end=44177
-  _globals['_INTERNEDV8ISOLATE']._serialized_start=44180
-  _globals['_INTERNEDV8ISOLATE']._serialized_end=44507
-  _globals['_INTERNEDV8ISOLATE_CODERANGE']._serialized_start=44388
-  _globals['_INTERNEDV8ISOLATE_CODERANGE']._serialized_end=44507
-  _globals['_V8JSCODE']._serialized_start=44510
-  _globals['_V8JSCODE']._serialized_end=44982
-  _globals['_V8JSCODE_TIER']._serialized_start=44832
-  _globals['_V8JSCODE_TIER']._serialized_end=44952
-  _globals['_V8INTERNALCODE']._serialized_start=44985
-  _globals['_V8INTERNALCODE']._serialized_end=45466
-  _globals['_V8INTERNALCODE_TYPE']._serialized_start=45208
-  _globals['_V8INTERNALCODE_TYPE']._serialized_end=45466
-  _globals['_V8WASMCODE']._serialized_start=45469
-  _globals['_V8WASMCODE']._serialized_end=45792
-  _globals['_V8WASMCODE_TIER']._serialized_start=45731
-  _globals['_V8WASMCODE_TIER']._serialized_end=45792
-  _globals['_V8REGEXPCODE']._serialized_start=45795
-  _globals['_V8REGEXPCODE']._serialized_end=45971
-  _globals['_V8CODEMOVE']._serialized_start=45974
-  _globals['_V8CODEMOVE']._serialized_end=46199
-  _globals['_V8CODEDEFAULTS']._serialized_start=46201
-  _globals['_V8CODEDEFAULTS']._serialized_end=46230
-  _globals['_CLOCKSNAPSHOT']._serialized_start=46233
-  _globals['_CLOCKSNAPSHOT']._serialized_end=46635
-  _globals['_CLOCKSNAPSHOT_CLOCK']._serialized_start=46365
-  _globals['_CLOCKSNAPSHOT_CLOCK']._serialized_end=46635
-  _globals['_CLOCKSNAPSHOT_CLOCK_BUILTINCLOCKS']._serialized_start=46464
-  _globals['_CLOCKSNAPSHOT_CLOCK_BUILTINCLOCKS']._serialized_end=46635
-  _globals['_CSWITCHETWEVENT']._serialized_start=46638
-  _globals['_CSWITCHETWEVENT']._serialized_end=48256
-  _globals['_CSWITCHETWEVENT_OLDTHREADWAITREASON']._serialized_start=47214
-  _globals['_CSWITCHETWEVENT_OLDTHREADWAITREASON']._serialized_end=47959
-  _globals['_CSWITCHETWEVENT_OLDTHREADWAITMODE']._serialized_start=47961
-  _globals['_CSWITCHETWEVENT_OLDTHREADWAITMODE']._serialized_end=48012
-  _globals['_CSWITCHETWEVENT_OLDTHREADSTATE']._serialized_start=48015
-  _globals['_CSWITCHETWEVENT_OLDTHREADSTATE']._serialized_end=48150
-  _globals['_READYTHREADETWEVENT']._serialized_start=48259
-  _globals['_READYTHREADETWEVENT']._serialized_end=48779
-  _globals['_READYTHREADETWEVENT_ADJUSTREASON']._serialized_start=48518
-  _globals['_READYTHREADETWEVENT_ADJUSTREASON']._serialized_end=48606
-  _globals['_READYTHREADETWEVENT_TRACEFLAG']._serialized_start=48608
-  _globals['_READYTHREADETWEVENT_TRACEFLAG']._serialized_end=48730
-  _globals['_MEMINFOETWEVENT']._serialized_start=48782
-  _globals['_MEMINFOETWEVENT']._serialized_end=49182
-  _globals['_FILEIOCREATEETWEVENT']._serialized_start=49185
-  _globals['_FILEIOCREATEETWEVENT']._serialized_end=49349
-  _globals['_FILEIODIRENUMETWEVENT']._serialized_start=49352
-  _globals['_FILEIODIRENUMETWEVENT']._serialized_end=49536
-  _globals['_FILEIOINFOETWEVENT']._serialized_start=49539
-  _globals['_FILEIOINFOETWEVENT']._serialized_end=49685
-  _globals['_FILEIOREADWRITEETWEVENT']._serialized_start=49688
-  _globals['_FILEIOREADWRITEETWEVENT']._serialized_end=49850
-  _globals['_FILEIOSIMPLEOPETWEVENT']._serialized_start=49852
-  _globals['_FILEIOSIMPLEOPETWEVENT']._serialized_end=49962
-  _globals['_FILEIOOPENDETWEVENT']._serialized_start=49964
-  _globals['_FILEIOOPENDETWEVENT']._serialized_end=50041
-  _globals['_FILEIOPATHOPERATIONETWEVENT']._serialized_start=50044
-  _globals['_FILEIOPATHOPERATIONETWEVENT']._serialized_end=50218
-  _globals['_STACKWALKETWEVENT']._serialized_start=50220
-  _globals['_STACKWALKETWEVENT']._serialized_end=50279
-  _globals['_DISKIOETWEVENT']._serialized_start=50282
-  _globals['_DISKIOETWEVENT']._serialized_end=50486
-  _globals['_ETWTRACEEVENT']._serialized_start=50489
-  _globals['_ETWTRACEEVENT']._serialized_end=51324
-  _globals['_ETWTRACEEVENTBUNDLE']._serialized_start=51326
-  _globals['_ETWTRACEEVENTBUNDLE']._serialized_end=51407
-  _globals['_FILEDESCRIPTORSET']._serialized_start=51409
-  _globals['_FILEDESCRIPTORSET']._serialized_end=51480
-  _globals['_FILEDESCRIPTORPROTO']._serialized_start=51483
-  _globals['_FILEDESCRIPTORPROTO']._serialized_end=51802
-  _globals['_DESCRIPTORPROTO']._serialized_start=51805
-  _globals['_DESCRIPTORPROTO']._serialized_end=52271
-  _globals['_DESCRIPTORPROTO_RESERVEDRANGE']._serialized_start=52216
-  _globals['_DESCRIPTORPROTO_RESERVEDRANGE']._serialized_end=52259
-  _globals['_UNINTERPRETEDOPTION']._serialized_start=52274
-  _globals['_UNINTERPRETEDOPTION']._serialized_end=52560
-  _globals['_UNINTERPRETEDOPTION_NAMEPART']._serialized_start=52509
-  _globals['_UNINTERPRETEDOPTION_NAMEPART']._serialized_end=52560
-  _globals['_FIELDOPTIONS']._serialized_start=52562
-  _globals['_FIELDOPTIONS']._serialized_end=52661
-  _globals['_FIELDDESCRIPTORPROTO']._serialized_start=52664
-  _globals['_FIELDDESCRIPTORPROTO']._serialized_end=53351
-  _globals['_FIELDDESCRIPTORPROTO_TYPE']._serialized_start=52966
-  _globals['_FIELDDESCRIPTORPROTO_TYPE']._serialized_end=53276
-  _globals['_FIELDDESCRIPTORPROTO_LABEL']._serialized_start=53278
-  _globals['_FIELDDESCRIPTORPROTO_LABEL']._serialized_end=53345
-  _globals['_ONEOFDESCRIPTORPROTO']._serialized_start=53353
-  _globals['_ONEOFDESCRIPTORPROTO']._serialized_end=53437
-  _globals['_ENUMDESCRIPTORPROTO']._serialized_start=53440
-  _globals['_ENUMDESCRIPTORPROTO']._serialized_end=53568
-  _globals['_ENUMVALUEDESCRIPTORPROTO']._serialized_start=53570
-  _globals['_ENUMVALUEDESCRIPTORPROTO']._serialized_end=53632
-  _globals['_ONEOFOPTIONS']._serialized_start=53634
-  _globals['_ONEOFOPTIONS']._serialized_end=53667
-  _globals['_EXTENSIONDESCRIPTOR']._serialized_start=53670
-  _globals['_EXTENSIONDESCRIPTOR']._serialized_end=53815
-  _globals['_INODEFILEMAP']._serialized_start=53818
-  _globals['_INODEFILEMAP']._serialized_end=54082
-  _globals['_INODEFILEMAP_ENTRY']._serialized_start=53936
-  _globals['_INODEFILEMAP_ENTRY']._serialized_end=54082
-  _globals['_INODEFILEMAP_ENTRY_TYPE']._serialized_start=54038
-  _globals['_INODEFILEMAP_ENTRY_TYPE']._serialized_end=54082
-  _globals['_ANDROIDFSDATAREADENDFTRACEEVENT']._serialized_start=54084
-  _globals['_ANDROIDFSDATAREADENDFTRACEEVENT']._serialized_end=54161
-  _globals['_ANDROIDFSDATAREADSTARTFTRACEEVENT']._serialized_start=54164
-  _globals['_ANDROIDFSDATAREADSTARTFTRACEEVENT']._serialized_end=54306
-  _globals['_ANDROIDFSDATAWRITEENDFTRACEEVENT']._serialized_start=54308
-  _globals['_ANDROIDFSDATAWRITEENDFTRACEEVENT']._serialized_end=54386
-  _globals['_ANDROIDFSDATAWRITESTARTFTRACEEVENT']._serialized_start=54389
-  _globals['_ANDROIDFSDATAWRITESTARTFTRACEEVENT']._serialized_end=54532
-  _globals['_ANDROIDFSFSYNCENDFTRACEEVENT']._serialized_start=54534
-  _globals['_ANDROIDFSFSYNCENDFTRACEEVENT']._serialized_end=54608
-  _globals['_ANDROIDFSFSYNCSTARTFTRACEEVENT']._serialized_start=54610
-  _globals['_ANDROIDFSFSYNCSTARTFTRACEEVENT']._serialized_end=54718
-  _globals['_BCLIRQTRIGGERFTRACEEVENT']._serialized_start=54721
-  _globals['_BCLIRQTRIGGERFTRACEEVENT']._serialized_end=54910
-  _globals['_BINDERTRANSACTIONFTRACEEVENT']._serialized_start=54913
-  _globals['_BINDERTRANSACTIONFTRACEEVENT']._serialized_end=55062
-  _globals['_BINDERTRANSACTIONRECEIVEDFTRACEEVENT']._serialized_start=55064
-  _globals['_BINDERTRANSACTIONRECEIVEDFTRACEEVENT']._serialized_end=55120
-  _globals['_BINDERSETPRIORITYFTRACEEVENT']._serialized_start=55122
-  _globals['_BINDERSETPRIORITYFTRACEEVENT']._serialized_end=55240
-  _globals['_BINDERLOCKFTRACEEVENT']._serialized_start=55242
-  _globals['_BINDERLOCKFTRACEEVENT']._serialized_end=55278
-  _globals['_BINDERLOCKEDFTRACEEVENT']._serialized_start=55280
-  _globals['_BINDERLOCKEDFTRACEEVENT']._serialized_end=55318
-  _globals['_BINDERUNLOCKFTRACEEVENT']._serialized_start=55320
-  _globals['_BINDERUNLOCKFTRACEEVENT']._serialized_end=55358
-  _globals['_BINDERTRANSACTIONALLOCBUFFTRACEEVENT']._serialized_start=55360
-  _globals['_BINDERTRANSACTIONALLOCBUFFTRACEEVENT']._serialized_end=55485
-  _globals['_BINDERCOMMANDFTRACEEVENT']._serialized_start=55487
-  _globals['_BINDERCOMMANDFTRACEEVENT']._serialized_end=55526
-  _globals['_BINDERRETURNFTRACEEVENT']._serialized_start=55528
-  _globals['_BINDERRETURNFTRACEEVENT']._serialized_end=55566
-  _globals['_BLOCKRQISSUEFTRACEEVENT']._serialized_start=55569
-  _globals['_BLOCKRQISSUEFTRACEEVENT']._serialized_end=55698
-  _globals['_BLOCKBIOBACKMERGEFTRACEEVENT']._serialized_start=55700
-  _globals['_BLOCKBIOBACKMERGEFTRACEEVENT']._serialized_end=55806
-  _globals['_BLOCKBIOBOUNCEFTRACEEVENT']._serialized_start=55808
-  _globals['_BLOCKBIOBOUNCEFTRACEEVENT']._serialized_end=55911
-  _globals['_BLOCKBIOCOMPLETEFTRACEEVENT']._serialized_start=55913
-  _globals['_BLOCKBIOCOMPLETEFTRACEEVENT']._serialized_end=56019
-  _globals['_BLOCKBIOFRONTMERGEFTRACEEVENT']._serialized_start=56021
-  _globals['_BLOCKBIOFRONTMERGEFTRACEEVENT']._serialized_end=56128
-  _globals['_BLOCKBIOQUEUEFTRACEEVENT']._serialized_start=56130
-  _globals['_BLOCKBIOQUEUEFTRACEEVENT']._serialized_end=56232
-  _globals['_BLOCKBIOREMAPFTRACEEVENT']._serialized_start=56234
-  _globals['_BLOCKBIOREMAPFTRACEEVENT']._serialized_end=56359
-  _globals['_BLOCKDIRTYBUFFERFTRACEEVENT']._serialized_start=56361
-  _globals['_BLOCKDIRTYBUFFERFTRACEEVENT']._serialized_end=56433
-  _globals['_BLOCKGETRQFTRACEEVENT']._serialized_start=56435
-  _globals['_BLOCKGETRQFTRACEEVENT']._serialized_end=56534
-  _globals['_BLOCKPLUGFTRACEEVENT']._serialized_start=56536
-  _globals['_BLOCKPLUGFTRACEEVENT']._serialized_end=56572
-  _globals['_BLOCKRQABORTFTRACEEVENT']._serialized_start=56574
-  _globals['_BLOCKRQABORTFTRACEEVENT']._serialized_end=56690
-  _globals['_BLOCKRQCOMPLETEFTRACEEVENT']._serialized_start=56693
-  _globals['_BLOCKRQCOMPLETEFTRACEEVENT']._serialized_end=56827
-  _globals['_BLOCKRQINSERTFTRACEEVENT']._serialized_start=56830
-  _globals['_BLOCKRQINSERTFTRACEEVENT']._serialized_end=56960
-  _globals['_BLOCKRQREMAPFTRACEEVENT']._serialized_start=56963
-  _globals['_BLOCKRQREMAPFTRACEEVENT']._serialized_end=57104
-  _globals['_BLOCKRQREQUEUEFTRACEEVENT']._serialized_start=57106
-  _globals['_BLOCKRQREQUEUEFTRACEEVENT']._serialized_end=57224
-  _globals['_BLOCKSLEEPRQFTRACEEVENT']._serialized_start=57226
-  _globals['_BLOCKSLEEPRQFTRACEEVENT']._serialized_end=57327
-  _globals['_BLOCKSPLITFTRACEEVENT']._serialized_start=57329
-  _globals['_BLOCKSPLITFTRACEEVENT']._serialized_end=57429
-  _globals['_BLOCKTOUCHBUFFERFTRACEEVENT']._serialized_start=57431
-  _globals['_BLOCKTOUCHBUFFERFTRACEEVENT']._serialized_end=57503
-  _globals['_BLOCKUNPLUGFTRACEEVENT']._serialized_start=57505
-  _globals['_BLOCKUNPLUGFTRACEEVENT']._serialized_end=57558
-  _globals['_BLOCKIOSTARTFTRACEEVENT']._serialized_start=57561
-  _globals['_BLOCKIOSTARTFTRACEEVENT']._serialized_end=57706
-  _globals['_BLOCKIODONEFTRACEEVENT']._serialized_start=57709
-  _globals['_BLOCKIODONEFTRACEEVENT']._serialized_end=57853
-  _globals['_CGROUPATTACHTASKFTRACEEVENT']._serialized_start=57856
-  _globals['_CGROUPATTACHTASKFTRACEEVENT']._serialized_end=57998
-  _globals['_CGROUPMKDIRFTRACEEVENT']._serialized_start=58000
-  _globals['_CGROUPMKDIRFTRACEEVENT']._serialized_end=58094
-  _globals['_CGROUPREMOUNTFTRACEEVENT']._serialized_start=58096
-  _globals['_CGROUPREMOUNTFTRACEEVENT']._serialized_end=58167
-  _globals['_CGROUPRMDIRFTRACEEVENT']._serialized_start=58169
-  _globals['_CGROUPRMDIRFTRACEEVENT']._serialized_end=58263
-  _globals['_CGROUPTRANSFERTASKSFTRACEEVENT']._serialized_start=58266
-  _globals['_CGROUPTRANSFERTASKSFTRACEEVENT']._serialized_end=58411
-  _globals['_CGROUPDESTROYROOTFTRACEEVENT']._serialized_start=58413
-  _globals['_CGROUPDESTROYROOTFTRACEEVENT']._serialized_end=58488
-  _globals['_CGROUPRELEASEFTRACEEVENT']._serialized_start=58490
-  _globals['_CGROUPRELEASEFTRACEEVENT']._serialized_end=58586
-  _globals['_CGROUPRENAMEFTRACEEVENT']._serialized_start=58588
-  _globals['_CGROUPRENAMEFTRACEEVENT']._serialized_end=58683
-  _globals['_CGROUPSETUPROOTFTRACEEVENT']._serialized_start=58685
-  _globals['_CGROUPSETUPROOTFTRACEEVENT']._serialized_end=58758
-  _globals['_CLKENABLEFTRACEEVENT']._serialized_start=58760
-  _globals['_CLKENABLEFTRACEEVENT']._serialized_end=58796
-  _globals['_CLKDISABLEFTRACEEVENT']._serialized_start=58798
-  _globals['_CLKDISABLEFTRACEEVENT']._serialized_end=58835
-  _globals['_CLKSETRATEFTRACEEVENT']._serialized_start=58837
-  _globals['_CLKSETRATEFTRACEEVENT']._serialized_end=58888
-  _globals['_CMAALLOCSTARTFTRACEEVENT']._serialized_start=58890
-  _globals['_CMAALLOCSTARTFTRACEEVENT']._serialized_end=58960
-  _globals['_CMAALLOCINFOFTRACEEVENT']._serialized_start=58963
-  _globals['_CMAALLOCINFOFTRACEEVENT']._serialized_end=59159
-  _globals['_CMAALLOCFINISHFTRACEEVENT']._serialized_start=59161
-  _globals['_CMAALLOCFINISHFTRACEEVENT']._serialized_end=59276
-  _globals['_MMCOMPACTIONBEGINFTRACEEVENT']._serialized_start=59278
-  _globals['_MMCOMPACTIONBEGINFTRACEEVENT']._serialized_end=59399
-  _globals['_MMCOMPACTIONDEFERCOMPACTIONFTRACEEVENT']._serialized_start=59402
-  _globals['_MMCOMPACTIONDEFERCOMPACTIONFTRACEEVENT']._serialized_end=59546
-  _globals['_MMCOMPACTIONDEFERREDFTRACEEVENT']._serialized_start=59549
-  _globals['_MMCOMPACTIONDEFERREDFTRACEEVENT']._serialized_end=59686
-  _globals['_MMCOMPACTIONDEFERRESETFTRACEEVENT']._serialized_start=59689
-  _globals['_MMCOMPACTIONDEFERRESETFTRACEEVENT']._serialized_end=59828
-  _globals['_MMCOMPACTIONENDFTRACEEVENT']._serialized_start=59831
-  _globals['_MMCOMPACTIONENDFTRACEEVENT']._serialized_end=59966
-  _globals['_MMCOMPACTIONFINISHEDFTRACEEVENT']._serialized_start=59968
-  _globals['_MMCOMPACTIONFINISHEDFTRACEEVENT']._serialized_end=60055
-  _globals['_MMCOMPACTIONISOLATEFREEPAGESFTRACEEVENT']._serialized_start=60057
-  _globals['_MMCOMPACTIONISOLATEFREEPAGESFTRACEEVENT']._serialized_end=60172
-  _globals['_MMCOMPACTIONISOLATEMIGRATEPAGESFTRACEEVENT']._serialized_start=60174
-  _globals['_MMCOMPACTIONISOLATEMIGRATEPAGESFTRACEEVENT']._serialized_end=60292
-  _globals['_MMCOMPACTIONKCOMPACTDSLEEPFTRACEEVENT']._serialized_start=60294
-  _globals['_MMCOMPACTIONKCOMPACTDSLEEPFTRACEEVENT']._serialized_end=60346
-  _globals['_MMCOMPACTIONKCOMPACTDWAKEFTRACEEVENT']._serialized_start=60348
-  _globals['_MMCOMPACTIONKCOMPACTDWAKEFTRACEEVENT']._serialized_end=60462
-  _globals['_MMCOMPACTIONMIGRATEPAGESFTRACEEVENT']._serialized_start=60464
-  _globals['_MMCOMPACTIONMIGRATEPAGESFTRACEEVENT']._serialized_end=60541
-  _globals['_MMCOMPACTIONSUITABLEFTRACEEVENT']._serialized_start=60543
-  _globals['_MMCOMPACTIONSUITABLEFTRACEEVENT']._serialized_end=60630
-  _globals['_MMCOMPACTIONTRYTOCOMPACTPAGESFTRACEEVENT']._serialized_start=60632
-  _globals['_MMCOMPACTIONTRYTOCOMPACTPAGESFTRACEEVENT']._serialized_end=60735
-  _globals['_MMCOMPACTIONWAKEUPKCOMPACTDFTRACEEVENT']._serialized_start=60737
-  _globals['_MMCOMPACTIONWAKEUPKCOMPACTDFTRACEEVENT']._serialized_end=60853
-  _globals['_PARAMSETVALUECPMFTRACEEVENT']._serialized_start=60855
-  _globals['_PARAMSETVALUECPMFTRACEEVENT']._serialized_end=60932
-  _globals['_CPUHPEXITFTRACEEVENT']._serialized_start=60934
-  _globals['_CPUHPEXITFTRACEEVENT']._serialized_end=61010
-  _globals['_CPUHPMULTIENTERFTRACEEVENT']._serialized_start=61012
-  _globals['_CPUHPMULTIENTERFTRACEEVENT']._serialized_end=61095
-  _globals['_CPUHPENTERFTRACEEVENT']._serialized_start=61097
-  _globals['_CPUHPENTERFTRACEEVENT']._serialized_end=61175
-  _globals['_CPUHPLATENCYFTRACEEVENT']._serialized_start=61177
-  _globals['_CPUHPLATENCYFTRACEEVENT']._serialized_end=61257
-  _globals['_CPUHPPAUSEFTRACEEVENT']._serialized_start=61259
-  _globals['_CPUHPPAUSEFTRACEEVENT']._serialized_end=61346
-  _globals['_CROSECSENSORHUBDATAFTRACEEVENT']._serialized_start=61349
-  _globals['_CROSECSENSORHUBDATAFTRACEEVENT']._serialized_end=61519
-  _globals['_DCVSHFREQFTRACEEVENT']._serialized_start=61521
-  _globals['_DCVSHFREQFTRACEEVENT']._serialized_end=61570
-  _globals['_DEVFREQFREQUENCYFTRACEEVENT']._serialized_start=61572
-  _globals['_DEVFREQFREQUENCYFTRACEEVENT']._serialized_end=61691
-  _globals['_DMAFENCEINITFTRACEEVENT']._serialized_start=61693
-  _globals['_DMAFENCEINITFTRACEEVENT']._serialized_end=61784
-  _globals['_DMAFENCEEMITFTRACEEVENT']._serialized_start=61786
-  _globals['_DMAFENCEEMITFTRACEEVENT']._serialized_end=61877
-  _globals['_DMAFENCESIGNALEDFTRACEEVENT']._serialized_start=61879
-  _globals['_DMAFENCESIGNALEDFTRACEEVENT']._serialized_end=61974
-  _globals['_DMAFENCEWAITSTARTFTRACEEVENT']._serialized_start=61976
-  _globals['_DMAFENCEWAITSTARTFTRACEEVENT']._serialized_end=62072
-  _globals['_DMAFENCEWAITENDFTRACEEVENT']._serialized_start=62074
-  _globals['_DMAFENCEWAITENDFTRACEEVENT']._serialized_end=62168
-  _globals['_DMAHEAPSTATFTRACEEVENT']._serialized_start=62170
-  _globals['_DMAHEAPSTATFTRACEEVENT']._serialized_end=62247
-  _globals['_DPUTRACINGMARKWRITEFTRACEEVENT']._serialized_start=62250
-  _globals['_DPUTRACINGMARKWRITEFTRACEEVENT']._serialized_end=62379
-  _globals['_DPUDSICMDFIFOSTATUSFTRACEEVENT']._serialized_start=62381
-  _globals['_DPUDSICMDFIFOSTATUSFTRACEEVENT']._serialized_end=62446
-  _globals['_DPUDSIRXFTRACEEVENT']._serialized_start=62448
-  _globals['_DPUDSIRXFTRACEEVENT']._serialized_end=62498
-  _globals['_DPUDSITXFTRACEEVENT']._serialized_start=62500
-  _globals['_DPUDSITXFTRACEEVENT']._serialized_end=62583
-  _globals['_DPUDISPDPUUNDERRUNFTRACEEVENT']._serialized_start=62585
-  _globals['_DPUDISPDPUUNDERRUNFTRACEEVENT']._serialized_end=62673
-  _globals['_DPUDISPVBLANKIRQENABLEFTRACEEVENT']._serialized_start=62675
-  _globals['_DPUDISPVBLANKIRQENABLEFTRACEEVENT']._serialized_end=62757
-  _globals['_DPUDISPFRAMEDONETIMEOUTFTRACEEVENT']._serialized_start=62760
-  _globals['_DPUDISPFRAMEDONETIMEOUTFTRACEEVENT']._serialized_end=62901
-  _globals['_DPUDISPFRAMESTARTTIMEOUTFTRACEEVENT']._serialized_start=62903
-  _globals['_DPUDISPFRAMESTARTTIMEOUTFTRACEEVENT']._serialized_end=63021
-  _globals['_DPUDISPFRAMEDONEMISSINGFTRACEEVENT']._serialized_start=63023
-  _globals['_DPUDISPFRAMEDONEMISSINGFTRACEEVENT']._serialized_end=63140
-  _globals['_DPUDISPFRAMESTARTMISSINGFTRACEEVENT']._serialized_start=63142
-  _globals['_DPUDISPFRAMESTARTMISSINGFTRACEEVENT']._serialized_end=63260
-  _globals['_DPUDISPDPULINEUNDERRUNFTRACEEVENT']._serialized_start=63262
-  _globals['_DPUDISPDPULINEUNDERRUNFTRACEEVENT']._serialized_end=63354
-  _globals['_DRMVBLANKEVENTFTRACEEVENT']._serialized_start=63356
-  _globals['_DRMVBLANKEVENTFTRACEEVENT']._serialized_end=63443
-  _globals['_DRMVBLANKEVENTDELIVEREDFTRACEEVENT']._serialized_start=63445
-  _globals['_DRMVBLANKEVENTDELIVEREDFTRACEEVENT']._serialized_end=63522
-  _globals['_DWC3ALLOCREQUESTFTRACEEVENT']._serialized_start=63525
-  _globals['_DWC3ALLOCREQUESTFTRACEEVENT']._serialized_end=63687
-  _globals['_DWC3COMPLETETRBFTRACEEVENT']._serialized_start=63690
-  _globals['_DWC3COMPLETETRBFTRACEEVENT']._serialized_end=63882
-  _globals['_DWC3CTRLREQFTRACEEVENT']._serialized_start=63884
-  _globals['_DWC3CTRLREQFTRACEEVENT']._serialized_end=64010
-  _globals['_DWC3EPDEQUEUEFTRACEEVENT']._serialized_start=64013
-  _globals['_DWC3EPDEQUEUEFTRACEEVENT']._serialized_end=64172
-  _globals['_DWC3EPQUEUEFTRACEEVENT']._serialized_start=64175
-  _globals['_DWC3EPQUEUEFTRACEEVENT']._serialized_end=64332
-  _globals['_DWC3EVENTFTRACEEVENT']._serialized_start=64334
-  _globals['_DWC3EVENTFTRACEEVENT']._serialized_end=64402
-  _globals['_DWC3FREEREQUESTFTRACEEVENT']._serialized_start=64405
-  _globals['_DWC3FREEREQUESTFTRACEEVENT']._serialized_end=64566
-  _globals['_DWC3GADGETEPCMDFTRACEEVENT']._serialized_start=64568
-  _globals['_DWC3GADGETEPCMDFTRACEEVENT']._serialized_end=64691
-  _globals['_DWC3GADGETEPDISABLEFTRACEEVENT']._serialized_start=64694
-  _globals['_DWC3GADGETEPDISABLEFTRACEEVENT']._serialized_end=64899
-  _globals['_DWC3GADGETEPENABLEFTRACEEVENT']._serialized_start=64902
-  _globals['_DWC3GADGETEPENABLEFTRACEEVENT']._serialized_end=65106
-  _globals['_DWC3GADGETGENERICCMDFTRACEEVENT']._serialized_start=65108
-  _globals['_DWC3GADGETGENERICCMDFTRACEEVENT']._serialized_end=65185
-  _globals['_DWC3GADGETGIVEBACKFTRACEEVENT']._serialized_start=65188
-  _globals['_DWC3GADGETGIVEBACKFTRACEEVENT']._serialized_end=65352
-  _globals['_DWC3PREPARETRBFTRACEEVENT']._serialized_start=65355
-  _globals['_DWC3PREPARETRBFTRACEEVENT']._serialized_end=65546
-  _globals['_DWC3READLFTRACEEVENT']._serialized_start=65548
-  _globals['_DWC3READLFTRACEEVENT']._serialized_end=65628
-  _globals['_DWC3WRITELFTRACEEVENT']._serialized_start=65630
-  _globals['_DWC3WRITELFTRACEEVENT']._serialized_end=65711
-  _globals['_EXT4DAWRITEBEGINFTRACEEVENT']._serialized_start=65713
-  _globals['_EXT4DAWRITEBEGINFTRACEEVENT']._serialized_end=65809
-  _globals['_EXT4DAWRITEENDFTRACEEVENT']._serialized_start=65811
-  _globals['_EXT4DAWRITEENDFTRACEEVENT']._serialized_end=65906
-  _globals['_EXT4SYNCFILEENTERFTRACEEVENT']._serialized_start=65908
-  _globals['_EXT4SYNCFILEENTERFTRACEEVENT']._serialized_end=65998
-  _globals['_EXT4SYNCFILEEXITFTRACEEVENT']._serialized_start=66000
-  _globals['_EXT4SYNCFILEEXITFTRACEEVENT']._serialized_end=66068
-  _globals['_EXT4ALLOCDABLOCKSFTRACEEVENT']._serialized_start=66070
-  _globals['_EXT4ALLOCDABLOCKSFTRACEEVENT']._serialized_end=66168
-  _globals['_EXT4ALLOCATEBLOCKSFTRACEEVENT']._serialized_start=66171
-  _globals['_EXT4ALLOCATEBLOCKSFTRACEEVENT']._serialized_end=66364
-  _globals['_EXT4ALLOCATEINODEFTRACEEVENT']._serialized_start=66366
-  _globals['_EXT4ALLOCATEINODEFTRACEEVENT']._serialized_end=66449
-  _globals['_EXT4BEGINORDEREDTRUNCATEFTRACEEVENT']._serialized_start=66451
-  _globals['_EXT4BEGINORDEREDTRUNCATEFTRACEEVENT']._serialized_end=66532
-  _globals['_EXT4COLLAPSERANGEFTRACEEVENT']._serialized_start=66534
-  _globals['_EXT4COLLAPSERANGEFTRACEEVENT']._serialized_end=66619
-  _globals['_EXT4DARELEASESPACEFTRACEEVENT']._serialized_start=66622
-  _globals['_EXT4DARELEASESPACEFTRACEEVENT']._serialized_end=66824
-  _globals['_EXT4DARESERVESPACEFTRACEEVENT']._serialized_start=66827
-  _globals['_EXT4DARESERVESPACEFTRACEEVENT']._serialized_end=66995
-  _globals['_EXT4DAUPDATERESERVESPACEFTRACEEVENT']._serialized_start=66998
-  _globals['_EXT4DAUPDATERESERVESPACEFTRACEEVENT']._serialized_end=67226
-  _globals['_EXT4DAWRITEPAGESFTRACEEVENT']._serialized_start=67229
-  _globals['_EXT4DAWRITEPAGESFTRACEEVENT']._serialized_end=67436
-  _globals['_EXT4DAWRITEPAGESEXTENTFTRACEEVENT']._serialized_start=67438
-  _globals['_EXT4DAWRITEPAGESEXTENTFTRACEEVENT']._serialized_end=67541
-  _globals['_EXT4DIRECTIOENTERFTRACEEVENT']._serialized_start=67543
-  _globals['_EXT4DIRECTIOENTERFTRACEEVENT']._serialized_end=67637
-  _globals['_EXT4DIRECTIOEXITFTRACEEVENT']._serialized_start=67639
-  _globals['_EXT4DIRECTIOEXITFTRACEEVENT']._serialized_end=67745
-  _globals['_EXT4DISCARDBLOCKSFTRACEEVENT']._serialized_start=67747
-  _globals['_EXT4DISCARDBLOCKSFTRACEEVENT']._serialized_end=67818
-  _globals['_EXT4DISCARDPREALLOCATIONSFTRACEEVENT']._serialized_start=67820
-  _globals['_EXT4DISCARDPREALLOCATIONSFTRACEEVENT']._serialized_end=67913
-  _globals['_EXT4DROPINODEFTRACEEVENT']._serialized_start=67915
-  _globals['_EXT4DROPINODEFTRACEEVENT']._serialized_end=67981
-  _globals['_EXT4ESCACHEEXTENTFTRACEEVENT']._serialized_start=67983
-  _globals['_EXT4ESCACHEEXTENTFTRACEEVENT']._serialized_end=68096
-  _globals['_EXT4ESFINDDELAYEDEXTENTRANGEENTERFTRACEEVENT']._serialized_start=68098
-  _globals['_EXT4ESFINDDELAYEDEXTENTRANGEENTERFTRACEEVENT']._serialized_end=68184
-  _globals['_EXT4ESFINDDELAYEDEXTENTRANGEEXITFTRACEEVENT']._serialized_start=68187
-  _globals['_EXT4ESFINDDELAYEDEXTENTRANGEEXITFTRACEEVENT']._serialized_end=68315
-  _globals['_EXT4ESINSERTEXTENTFTRACEEVENT']._serialized_start=68317
-  _globals['_EXT4ESINSERTEXTENTFTRACEEVENT']._serialized_end=68431
-  _globals['_EXT4ESLOOKUPEXTENTENTERFTRACEEVENT']._serialized_start=68433
-  _globals['_EXT4ESLOOKUPEXTENTENTERFTRACEEVENT']._serialized_end=68509
-  _globals['_EXT4ESLOOKUPEXTENTEXITFTRACEEVENT']._serialized_start=68512
-  _globals['_EXT4ESLOOKUPEXTENTEXITFTRACEEVENT']._serialized_end=68645
-  _globals['_EXT4ESREMOVEEXTENTFTRACEEVENT']._serialized_start=68647
-  _globals['_EXT4ESREMOVEEXTENTFTRACEEVENT']._serialized_end=68731
-  _globals['_EXT4ESSHRINKFTRACEEVENT']._serialized_start=68733
-  _globals['_EXT4ESSHRINKFTRACEEVENT']._serialized_end=68846
-  _globals['_EXT4ESSHRINKCOUNTFTRACEEVENT']._serialized_start=68848
-  _globals['_EXT4ESSHRINKCOUNTFTRACEEVENT']._serialized_end=68930
-  _globals['_EXT4ESSHRINKSCANENTERFTRACEEVENT']._serialized_start=68932
-  _globals['_EXT4ESSHRINKSCANENTERFTRACEEVENT']._serialized_end=69018
-  _globals['_EXT4ESSHRINKSCANEXITFTRACEEVENT']._serialized_start=69020
-  _globals['_EXT4ESSHRINKSCANEXITFTRACEEVENT']._serialized_end=69104
-  _globals['_EXT4EVICTINODEFTRACEEVENT']._serialized_start=69106
-  _globals['_EXT4EVICTINODEFTRACEEVENT']._serialized_end=69174
-  _globals['_EXT4EXTCONVERTTOINITIALIZEDENTERFTRACEEVENT']._serialized_start=69177
-  _globals['_EXT4EXTCONVERTTOINITIALIZEDENTERFTRACEEVENT']._serialized_end=69326
-  _globals['_EXT4EXTCONVERTTOINITIALIZEDFASTPATHFTRACEEVENT']._serialized_start=69329
-  _globals['_EXT4EXTCONVERTTOINITIALIZEDFASTPATHFTRACEEVENT']._serialized_end=69528
-  _globals['_EXT4EXTHANDLEUNWRITTENEXTENTSFTRACEEVENT']._serialized_start=69531
-  _globals['_EXT4EXTHANDLEUNWRITTENEXTENTSFTRACEEVENT']._serialized_end=69690
-  _globals['_EXT4EXTINCACHEFTRACEEVENT']._serialized_start=69692
-  _globals['_EXT4EXTINCACHEFTRACEEVENT']._serialized_end=69772
-  _globals['_EXT4EXTLOADEXTENTFTRACEEVENT']._serialized_start=69774
-  _globals['_EXT4EXTLOADEXTENTFTRACEEVENT']._serialized_end=69858
-  _globals['_EXT4EXTMAPBLOCKSENTERFTRACEEVENT']._serialized_start=69860
-  _globals['_EXT4EXTMAPBLOCKSENTERFTRACEEVENT']._serialized_end=69962
-  _globals['_EXT4EXTMAPBLOCKSEXITFTRACEEVENT']._serialized_start=69965
-  _globals['_EXT4EXTMAPBLOCKSEXITFTRACEEVENT']._serialized_end=70109
-  _globals['_EXT4EXTPUTINCACHEFTRACEEVENT']._serialized_start=70111
-  _globals['_EXT4EXTPUTINCACHEFTRACEEVENT']._serialized_end=70209
-  _globals['_EXT4EXTREMOVESPACEFTRACEEVENT']._serialized_start=70211
-  _globals['_EXT4EXTREMOVESPACEFTRACEEVENT']._serialized_end=70311
-  _globals['_EXT4EXTREMOVESPACEDONEFTRACEEVENT']._serialized_start=70314
-  _globals['_EXT4EXTREMOVESPACEDONEFTRACEEVENT']._serialized_end=70507
-  _globals['_EXT4EXTRMIDXFTRACEEVENT']._serialized_start=70509
-  _globals['_EXT4EXTRMIDXFTRACEEVENT']._serialized_end=70574
-  _globals['_EXT4EXTRMLEAFFTRACEEVENT']._serialized_start=70577
-  _globals['_EXT4EXTRMLEAFFTRACEEVENT']._serialized_end=70763
-  _globals['_EXT4EXTSHOWEXTENTFTRACEEVENT']._serialized_start=70765
-  _globals['_EXT4EXTSHOWEXTENTFTRACEEVENT']._serialized_end=70862
-  _globals['_EXT4FALLOCATEENTERFTRACEEVENT']._serialized_start=70864
-  _globals['_EXT4FALLOCATEENTERFTRACEEVENT']._serialized_end=70977
-  _globals['_EXT4FALLOCATEEXITFTRACEEVENT']._serialized_start=70979
-  _globals['_EXT4FALLOCATEEXITFTRACEEVENT']._serialized_end=71077
-  _globals['_EXT4FINDDELALLOCRANGEFTRACEEVENT']._serialized_start=71080
-  _globals['_EXT4FINDDELALLOCRANGEFTRACEEVENT']._serialized_end=71217
-  _globals['_EXT4FORGETFTRACEEVENT']._serialized_start=71219
-  _globals['_EXT4FORGETFTRACEEVENT']._serialized_end=71318
-  _globals['_EXT4FREEBLOCKSFTRACEEVENT']._serialized_start=71320
-  _globals['_EXT4FREEBLOCKSFTRACEEVENT']._serialized_end=71432
-  _globals['_EXT4FREEINODEFTRACEEVENT']._serialized_start=71434
-  _globals['_EXT4FREEINODEFTRACEEVENT']._serialized_end=71542
-  _globals['_EXT4GETIMPLIEDCLUSTERALLOCEXITFTRACEEVENT']._serialized_start=71544
-  _globals['_EXT4GETIMPLIEDCLUSTERALLOCEXITFTRACEEVENT']._serialized_end=71669
-  _globals['_EXT4GETRESERVEDCLUSTERALLOCFTRACEEVENT']._serialized_start=71671
-  _globals['_EXT4GETRESERVEDCLUSTERALLOCFTRACEEVENT']._serialized_end=71764
-  _globals['_EXT4INDMAPBLOCKSENTERFTRACEEVENT']._serialized_start=71766
-  _globals['_EXT4INDMAPBLOCKSENTERFTRACEEVENT']._serialized_end=71868
-  _globals['_EXT4INDMAPBLOCKSEXITFTRACEEVENT']._serialized_start=71871
-  _globals['_EXT4INDMAPBLOCKSEXITFTRACEEVENT']._serialized_end=72015
-  _globals['_EXT4INSERTRANGEFTRACEEVENT']._serialized_start=72017
-  _globals['_EXT4INSERTRANGEFTRACEEVENT']._serialized_end=72100
-  _globals['_EXT4INVALIDATEPAGEFTRACEEVENT']._serialized_start=72102
-  _globals['_EXT4INVALIDATEPAGEFTRACEEVENT']._serialized_end=72206
-  _globals['_EXT4JOURNALSTARTFTRACEEVENT']._serialized_start=72209
-  _globals['_EXT4JOURNALSTARTFTRACEEVENT']._serialized_end=72338
-  _globals['_EXT4JOURNALSTARTRESERVEDFTRACEEVENT']._serialized_start=72340
-  _globals['_EXT4JOURNALSTARTRESERVEDFTRACEEVENT']._serialized_end=72418
-  _globals['_EXT4JOURNALLEDINVALIDATEPAGEFTRACEEVENT']._serialized_start=72420
-  _globals['_EXT4JOURNALLEDINVALIDATEPAGEFTRACEEVENT']._serialized_end=72534
-  _globals['_EXT4JOURNALLEDWRITEENDFTRACEEVENT']._serialized_start=72536
-  _globals['_EXT4JOURNALLEDWRITEENDFTRACEEVENT']._serialized_end=72639
-  _globals['_EXT4LOADINODEFTRACEEVENT']._serialized_start=72641
-  _globals['_EXT4LOADINODEFTRACEEVENT']._serialized_end=72693
-  _globals['_EXT4LOADINODEBITMAPFTRACEEVENT']._serialized_start=72695
-  _globals['_EXT4LOADINODEBITMAPFTRACEEVENT']._serialized_end=72755
-  _globals['_EXT4MARKINODEDIRTYFTRACEEVENT']._serialized_start=72757
-  _globals['_EXT4MARKINODEDIRTYFTRACEEVENT']._serialized_end=72826
-  _globals['_EXT4MBBITMAPLOADFTRACEEVENT']._serialized_start=72828
-  _globals['_EXT4MBBITMAPLOADFTRACEEVENT']._serialized_end=72885
-  _globals['_EXT4MBBUDDYBITMAPLOADFTRACEEVENT']._serialized_start=72887
-  _globals['_EXT4MBBUDDYBITMAPLOADFTRACEEVENT']._serialized_end=72949
-  _globals['_EXT4MBDISCARDPREALLOCATIONSFTRACEEVENT']._serialized_start=72951
-  _globals['_EXT4MBDISCARDPREALLOCATIONSFTRACEEVENT']._serialized_end=73020
-  _globals['_EXT4MBNEWGROUPPAFTRACEEVENT']._serialized_start=73022
-  _globals['_EXT4MBNEWGROUPPAFTRACEEVENT']._serialized_end=73131
-  _globals['_EXT4MBNEWINODEPAFTRACEEVENT']._serialized_start=73133
-  _globals['_EXT4MBNEWINODEPAFTRACEEVENT']._serialized_end=73242
-  _globals['_EXT4MBRELEASEGROUPPAFTRACEEVENT']._serialized_start=73244
-  _globals['_EXT4MBRELEASEGROUPPAFTRACEEVENT']._serialized_end=73325
-  _globals['_EXT4MBRELEASEINODEPAFTRACEEVENT']._serialized_start=73327
-  _globals['_EXT4MBRELEASEINODEPAFTRACEEVENT']._serialized_end=73416
-  _globals['_EXT4MBALLOCALLOCFTRACEEVENT']._serialized_start=73419
-  _globals['_EXT4MBALLOCALLOCFTRACEEVENT']._serialized_end=73809
-  _globals['_EXT4MBALLOCDISCARDFTRACEEVENT']._serialized_start=73811
-  _globals['_EXT4MBALLOCDISCARDFTRACEEVENT']._serialized_end=73932
-  _globals['_EXT4MBALLOCFREEFTRACEEVENT']._serialized_start=73934
-  _globals['_EXT4MBALLOCFREEFTRACEEVENT']._serialized_end=74052
-  _globals['_EXT4MBALLOCPREALLOCFTRACEEVENT']._serialized_start=74055
-  _globals['_EXT4MBALLOCPREALLOCFTRACEEVENT']._serialized_end=74281
-  _globals['_EXT4OTHERINODEUPDATETIMEFTRACEEVENT']._serialized_start=74283
-  _globals['_EXT4OTHERINODEUPDATETIMEFTRACEEVENT']._serialized_end=74404
-  _globals['_EXT4PUNCHHOLEFTRACEEVENT']._serialized_start=74406
-  _globals['_EXT4PUNCHHOLEFTRACEEVENT']._serialized_end=74501
-  _globals['_EXT4READBLOCKBITMAPLOADFTRACEEVENT']._serialized_start=74503
-  _globals['_EXT4READBLOCKBITMAPLOADFTRACEEVENT']._serialized_end=74585
-  _globals['_EXT4READPAGEFTRACEEVENT']._serialized_start=74587
-  _globals['_EXT4READPAGEFTRACEEVENT']._serialized_end=74653
-  _globals['_EXT4RELEASEPAGEFTRACEEVENT']._serialized_start=74655
-  _globals['_EXT4RELEASEPAGEFTRACEEVENT']._serialized_end=74724
-  _globals['_EXT4REMOVEBLOCKSFTRACEEVENT']._serialized_start=74727
-  _globals['_EXT4REMOVEBLOCKSFTRACEEVENT']._serialized_end=74927
-  _globals['_EXT4REQUESTBLOCKSFTRACEEVENT']._serialized_start=74930
-  _globals['_EXT4REQUESTBLOCKSFTRACEEVENT']._serialized_end=75107
-  _globals['_EXT4REQUESTINODEFTRACEEVENT']._serialized_start=75109
-  _globals['_EXT4REQUESTINODEFTRACEEVENT']._serialized_end=75178
-  _globals['_EXT4SYNCFSFTRACEEVENT']._serialized_start=75180
-  _globals['_EXT4SYNCFSFTRACEEVENT']._serialized_end=75230
-  _globals['_EXT4TRIMALLFREEFTRACEEVENT']._serialized_start=75232
-  _globals['_EXT4TRIMALLFREEFTRACEEVENT']._serialized_end=75341
-  _globals['_EXT4TRIMEXTENTFTRACEEVENT']._serialized_start=75343
-  _globals['_EXT4TRIMEXTENTFTRACEEVENT']._serialized_end=75451
-  _globals['_EXT4TRUNCATEENTERFTRACEEVENT']._serialized_start=75453
-  _globals['_EXT4TRUNCATEENTERFTRACEEVENT']._serialized_end=75525
-  _globals['_EXT4TRUNCATEEXITFTRACEEVENT']._serialized_start=75527
-  _globals['_EXT4TRUNCATEEXITFTRACEEVENT']._serialized_end=75598
-  _globals['_EXT4UNLINKENTERFTRACEEVENT']._serialized_start=75600
-  _globals['_EXT4UNLINKENTERFTRACEEVENT']._serialized_end=75684
-  _globals['_EXT4UNLINKEXITFTRACEEVENT']._serialized_start=75686
-  _globals['_EXT4UNLINKEXITFTRACEEVENT']._serialized_end=75752
-  _globals['_EXT4WRITEBEGINFTRACEEVENT']._serialized_start=75754
-  _globals['_EXT4WRITEBEGINFTRACEEVENT']._serialized_end=75848
-  _globals['_EXT4WRITEENDFTRACEEVENT']._serialized_start=75850
-  _globals['_EXT4WRITEENDFTRACEEVENT']._serialized_end=75943
-  _globals['_EXT4WRITEPAGEFTRACEEVENT']._serialized_start=75945
-  _globals['_EXT4WRITEPAGEFTRACEEVENT']._serialized_end=76012
-  _globals['_EXT4WRITEPAGESFTRACEEVENT']._serialized_start=76015
-  _globals['_EXT4WRITEPAGESFTRACEEVENT']._serialized_end=76239
-  _globals['_EXT4WRITEPAGESRESULTFTRACEEVENT']._serialized_start=76242
-  _globals['_EXT4WRITEPAGESRESULTFTRACEEVENT']._serialized_end=76404
-  _globals['_EXT4ZERORANGEFTRACEEVENT']._serialized_start=76406
-  _globals['_EXT4ZERORANGEFTRACEEVENT']._serialized_end=76501
-  _globals['_F2FSDOSUBMITBIOFTRACEEVENT']._serialized_start=76503
-  _globals['_F2FSDOSUBMITBIOFTRACEEVENT']._serialized_end=76603
-  _globals['_F2FSEVICTINODEFTRACEEVENT']._serialized_start=76606
-  _globals['_F2FSEVICTINODEFTRACEEVENT']._serialized_end=76748
-  _globals['_F2FSFALLOCATEFTRACEEVENT']._serialized_start=76751
-  _globals['_F2FSFALLOCATEFTRACEEVENT']._serialized_end=76889
-  _globals['_F2FSGETDATABLOCKFTRACEEVENT']._serialized_start=76891
-  _globals['_F2FSGETDATABLOCKFTRACEEVENT']._serialized_end=77010
-  _globals['_F2FSGETVICTIMFTRACEEVENT']._serialized_start=77013
-  _globals['_F2FSGETVICTIMFTRACEEVENT']._serialized_end=77219
-  _globals['_F2FSIGETFTRACEEVENT']._serialized_start=77222
-  _globals['_F2FSIGETFTRACEEVENT']._serialized_end=77358
-  _globals['_F2FSIGETEXITFTRACEEVENT']._serialized_start=77360
-  _globals['_F2FSIGETEXITFTRACEEVENT']._serialized_end=77424
-  _globals['_F2FSNEWINODEFTRACEEVENT']._serialized_start=77426
-  _globals['_F2FSNEWINODEFTRACEEVENT']._serialized_end=77490
-  _globals['_F2FSREADPAGEFTRACEEVENT']._serialized_start=77493
-  _globals['_F2FSREADPAGEFTRACEEVENT']._serialized_end=77636
-  _globals['_F2FSRESERVENEWBLOCKFTRACEEVENT']._serialized_start=77638
-  _globals['_F2FSRESERVENEWBLOCKFTRACEEVENT']._serialized_end=77717
-  _globals['_F2FSSETPAGEDIRTYFTRACEEVENT']._serialized_start=77720
-  _globals['_F2FSSETPAGEDIRTYFTRACEEVENT']._serialized_end=77850
-  _globals['_F2FSSUBMITWRITEPAGEFTRACEEVENT']._serialized_start=77852
-  _globals['_F2FSSUBMITWRITEPAGEFTRACEEVENT']._serialized_end=77954
-  _globals['_F2FSSYNCFILEENTERFTRACEEVENT']._serialized_start=77957
-  _globals['_F2FSSYNCFILEENTERFTRACEEVENT']._serialized_end=78102
-  _globals['_F2FSSYNCFILEEXITFTRACEEVENT']._serialized_start=78104
-  _globals['_F2FSSYNCFILEEXITFTRACEEVENT']._serialized_end=78226
-  _globals['_F2FSSYNCFSFTRACEEVENT']._serialized_start=78228
-  _globals['_F2FSSYNCFSFTRACEEVENT']._serialized_end=78293
-  _globals['_F2FSTRUNCATEFTRACEEVENT']._serialized_start=78296
-  _globals['_F2FSTRUNCATEFTRACEEVENT']._serialized_end=78436
-  _globals['_F2FSTRUNCATEBLOCKSENTERFTRACEEVENT']._serialized_start=78438
-  _globals['_F2FSTRUNCATEBLOCKSENTERFTRACEEVENT']._serialized_end=78544
-  _globals['_F2FSTRUNCATEBLOCKSEXITFTRACEEVENT']._serialized_start=78546
-  _globals['_F2FSTRUNCATEBLOCKSEXITFTRACEEVENT']._serialized_end=78620
-  _globals['_F2FSTRUNCATEDATABLOCKSRANGEFTRACEEVENT']._serialized_start=78622
-  _globals['_F2FSTRUNCATEDATABLOCKSRANGEFTRACEEVENT']._serialized_end=78728
-  _globals['_F2FSTRUNCATEINODEBLOCKSENTERFTRACEEVENT']._serialized_start=78730
-  _globals['_F2FSTRUNCATEINODEBLOCKSENTERFTRACEEVENT']._serialized_end=78841
-  _globals['_F2FSTRUNCATEINODEBLOCKSEXITFTRACEEVENT']._serialized_start=78843
-  _globals['_F2FSTRUNCATEINODEBLOCKSEXITFTRACEEVENT']._serialized_end=78922
-  _globals['_F2FSTRUNCATENODEFTRACEEVENT']._serialized_start=78924
-  _globals['_F2FSTRUNCATENODEFTRACEEVENT']._serialized_end=79010
-  _globals['_F2FSTRUNCATENODESENTERFTRACEEVENT']._serialized_start=79012
-  _globals['_F2FSTRUNCATENODESENTERFTRACEEVENT']._serialized_end=79104
-  _globals['_F2FSTRUNCATENODESEXITFTRACEEVENT']._serialized_start=79106
-  _globals['_F2FSTRUNCATENODESEXITFTRACEEVENT']._serialized_end=79179
-  _globals['_F2FSTRUNCATEPARTIALNODESFTRACEEVENT']._serialized_start=79181
-  _globals['_F2FSTRUNCATEPARTIALNODESFTRACEEVENT']._serialized_end=79285
-  _globals['_F2FSUNLINKENTERFTRACEEVENT']._serialized_start=79287
-  _globals['_F2FSUNLINKENTERFTRACEEVENT']._serialized_end=79385
-  _globals['_F2FSUNLINKEXITFTRACEEVENT']._serialized_start=79387
-  _globals['_F2FSUNLINKEXITFTRACEEVENT']._serialized_end=79453
-  _globals['_F2FSVMPAGEMKWRITEFTRACEEVENT']._serialized_start=79456
-  _globals['_F2FSVMPAGEMKWRITEFTRACEEVENT']._serialized_end=79587
-  _globals['_F2FSWRITEBEGINFTRACEEVENT']._serialized_start=79589
-  _globals['_F2FSWRITEBEGINFTRACEEVENT']._serialized_end=79683
-  _globals['_F2FSWRITECHECKPOINTFTRACEEVENT']._serialized_start=79685
-  _globals['_F2FSWRITECHECKPOINTFTRACEEVENT']._serialized_end=79793
-  _globals['_F2FSWRITEENDFTRACEEVENT']._serialized_start=79795
-  _globals['_F2FSWRITEENDFTRACEEVENT']._serialized_end=79888
-  _globals['_F2FSIOSTATFTRACEEVENT']._serialized_start=79891
-  _globals['_F2FSIOSTATFTRACEEVENT']._serialized_end=80316
-  _globals['_F2FSIOSTATLATENCYFTRACEEVENT']._serialized_start=80319
-  _globals['_F2FSIOSTATLATENCYFTRACEEVENT']._serialized_end=80902
-  _globals['_F2FSBACKGROUNDGCFTRACEEVENT']._serialized_start=80904
-  _globals['_F2FSBACKGROUNDGCFTRACEEVENT']._serialized_end=80994
-  _globals['_F2FSGCBEGINFTRACEEVENT']._serialized_start=80997
-  _globals['_F2FSGCBEGINFTRACEEVENT']._serialized_end=81267
-  _globals['_F2FSGCENDFTRACEEVENT']._serialized_start=81270
-  _globals['_F2FSGCENDFTRACEEVENT']._serialized_end=81498
-  _globals['_F2FSLOCKELAPSEDTIMEFTRACEEVENT']._serialized_start=81501
-  _globals['_F2FSLOCKELAPSEDTIMEFTRACEEVENT']._serialized_end=81775
-  _globals['_FASTRPCDMASTATFTRACEEVENT']._serialized_start=81777
-  _globals['_FASTRPCDMASTATFTRACEEVENT']._serialized_end=81855
-  _globals['_FASTRPCDMAFREEFTRACEEVENT']._serialized_start=81857
-  _globals['_FASTRPCDMAFREEFTRACEEVENT']._serialized_end=81925
-  _globals['_FASTRPCDMAALLOCFTRACEEVENT']._serialized_start=81927
-  _globals['_FASTRPCDMAALLOCFTRACEEVENT']._serialized_end=82026
-  _globals['_FASTRPCDMAUNMAPFTRACEEVENT']._serialized_start=82028
-  _globals['_FASTRPCDMAUNMAPFTRACEEVENT']._serialized_end=82097
-  _globals['_FASTRPCDMAMAPFTRACEEVENT']._serialized_start=82099
-  _globals['_FASTRPCDMAMAPFTRACEEVENT']._serialized_end=82221
-  _globals['_FENCEINITFTRACEEVENT']._serialized_start=82223
-  _globals['_FENCEINITFTRACEEVENT']._serialized_end=82311
-  _globals['_FENCEDESTROYFTRACEEVENT']._serialized_start=82313
-  _globals['_FENCEDESTROYFTRACEEVENT']._serialized_end=82404
-  _globals['_FENCEENABLESIGNALFTRACEEVENT']._serialized_start=82406
-  _globals['_FENCEENABLESIGNALFTRACEEVENT']._serialized_end=82502
-  _globals['_FENCESIGNALEDFTRACEEVENT']._serialized_start=82504
-  _globals['_FENCESIGNALEDFTRACEEVENT']._serialized_end=82596
-  _globals['_MMFILEMAPADDTOPAGECACHEFTRACEEVENT']._serialized_start=82598
-  _globals['_MMFILEMAPADDTOPAGECACHEFTRACEEVENT']._serialized_end=82706
-  _globals['_MMFILEMAPDELETEFROMPAGECACHEFTRACEEVENT']._serialized_start=82708
-  _globals['_MMFILEMAPDELETEFROMPAGECACHEFTRACEEVENT']._serialized_end=82821
-  _globals['_DOSYSOPENFTRACEEVENT']._serialized_start=82823
-  _globals['_DOSYSOPENFTRACEEVENT']._serialized_end=82892
-  _globals['_OPENEXECFTRACEEVENT']._serialized_start=82894
-  _globals['_OPENEXECFTRACEEVENT']._serialized_end=82933
-  _globals['_PRINTFTRACEEVENT']._serialized_start=82935
-  _globals['_PRINTFTRACEEVENT']._serialized_end=82978
-  _globals['_FUNCGRAPHENTRYFTRACEEVENT']._serialized_start=82980
-  _globals['_FUNCGRAPHENTRYFTRACEEVENT']._serialized_end=83036
-  _globals['_FUNCGRAPHEXITFTRACEEVENT']._serialized_start=83038
-  _globals['_FUNCGRAPHEXITFTRACEEVENT']._serialized_end=83145
-  _globals['_FWTPPERFETTOCOUNTERFTRACEEVENT']._serialized_start=83147
-  _globals['_FWTPPERFETTOCOUNTERFTRACEEVENT']._serialized_end=83263
-  _globals['_FWTPPERFETTOSLICEFTRACEEVENT']._serialized_start=83265
-  _globals['_FWTPPERFETTOSLICEFTRACEEVENT']._serialized_end=83379
-  _globals['_G2DTRACINGMARKWRITEFTRACEEVENT']._serialized_start=83381
-  _globals['_G2DTRACINGMARKWRITEFTRACEEVENT']._serialized_end=83469
-  _globals['_GENERICFTRACEEVENT']._serialized_start=83472
-  _globals['_GENERICFTRACEEVENT']._serialized_end=83666
-  _globals['_GENERICFTRACEEVENT_FIELD']._serialized_start=83572
-  _globals['_GENERICFTRACEEVENT_FIELD']._serialized_end=83666
-  _globals['_KPROBEEVENT']._serialized_start=83669
-  _globals['_KPROBEEVENT']._serialized_end=83859
-  _globals['_KPROBEEVENT_KPROBETYPE']._serialized_start=83753
-  _globals['_KPROBEEVENT_KPROBETYPE']._serialized_end=83859
-  _globals['_GOOGLEICCEVENTFTRACEEVENT']._serialized_start=83861
-  _globals['_GOOGLEICCEVENTFTRACEEVENT']._serialized_end=83922
-  _globals['_GOOGLEIRMEVENTFTRACEEVENT']._serialized_start=83924
-  _globals['_GOOGLEIRMEVENTFTRACEEVENT']._serialized_end=83985
-  _globals['_GPUMEMTOTALFTRACEEVENT']._serialized_start=83987
-  _globals['_GPUMEMTOTALFTRACEEVENT']._serialized_end=84054
-  _globals['_DRMSCHEDJOBFTRACEEVENT']._serialized_start=84056
-  _globals['_DRMSCHEDJOBFTRACEEVENT']._serialized_end=84178
-  _globals['_DRMRUNJOBFTRACEEVENT']._serialized_start=84180
-  _globals['_DRMRUNJOBFTRACEEVENT']._serialized_end=84300
-  _globals['_DRMSCHEDPROCESSJOBFTRACEEVENT']._serialized_start=84302
-  _globals['_DRMSCHEDPROCESSJOBFTRACEEVENT']._serialized_end=84348
-  _globals['_DRMSCHEDJOBADDDEPFTRACEEVENT']._serialized_start=84350
-  _globals['_DRMSCHEDJOBADDDEPFTRACEEVENT']._serialized_end=84452
-  _globals['_DRMSCHEDJOBDONEFTRACEEVENT']._serialized_start=84454
-  _globals['_DRMSCHEDJOBDONEFTRACEEVENT']._serialized_end=84526
-  _globals['_DRMSCHEDJOBQUEUEFTRACEEVENT']._serialized_start=84529
-  _globals['_DRMSCHEDJOBQUEUEFTRACEEVENT']._serialized_end=84689
-  _globals['_DRMSCHEDJOBRUNFTRACEEVENT']._serialized_start=84692
-  _globals['_DRMSCHEDJOBRUNFTRACEEVENT']._serialized_end=84850
-  _globals['_DRMSCHEDJOBUNSCHEDULABLEFTRACEEVENT']._serialized_start=84852
-  _globals['_DRMSCHEDJOBUNSCHEDULABLEFTRACEEVENT']._serialized_end=84961
-  _globals['_HYPENTERFTRACEEVENT']._serialized_start=84963
-  _globals['_HYPENTERFTRACEEVENT']._serialized_end=84984
-  _globals['_HYPEXITFTRACEEVENT']._serialized_start=84986
-  _globals['_HYPEXITFTRACEEVENT']._serialized_end=85006
-  _globals['_HOSTHCALLFTRACEEVENT']._serialized_start=85008
-  _globals['_HOSTHCALLFTRACEEVENT']._serialized_end=85059
-  _globals['_HOSTSMCFTRACEEVENT']._serialized_start=85061
-  _globals['_HOSTSMCFTRACEEVENT']._serialized_end=85112
-  _globals['_HOSTMEMABORTFTRACEEVENT']._serialized_start=85114
-  _globals['_HOSTMEMABORTFTRACEEVENT']._serialized_end=85166
-  _globals['_HOSTFFACALLFTRACEEVENT']._serialized_start=85169
-  _globals['_HOSTFFACALLFTRACEEVENT']._serialized_end=85304
-  _globals['_IOMMUIDMAPFTRACEEVENT']._serialized_start=85306
-  _globals['_IOMMUIDMAPFTRACEEVENT']._serialized_end=85369
-  _globals['_PSCIMEMPROTECTFTRACEEVENT']._serialized_start=85371
-  _globals['_PSCIMEMPROTECTFTRACEEVENT']._serialized_end=85426
-  _globals['_HYPERVISORHOSTHCALLFTRACEEVENT']._serialized_start=85428
-  _globals['_HYPERVISORHOSTHCALLFTRACEEVENT']._serialized_end=85489
-  _globals['_HYPERVISORHOSTSMCFTRACEEVENT']._serialized_start=85491
-  _globals['_HYPERVISORHOSTSMCFTRACEEVENT']._serialized_end=85552
-  _globals['_HYPERVISORHYPEXITFTRACEEVENT']._serialized_start=85554
-  _globals['_HYPERVISORHYPEXITFTRACEEVENT']._serialized_end=85584
-  _globals['_HYPERVISORIOMMUIDMAPFTRACEEVENT']._serialized_start=85586
-  _globals['_HYPERVISORIOMMUIDMAPFTRACEEVENT']._serialized_end=85659
-  _globals['_HYPERVISORPSCIMEMPROTECTFTRACEEVENT']._serialized_start=85661
-  _globals['_HYPERVISORPSCIMEMPROTECTFTRACEEVENT']._serialized_end=85726
-  _globals['_HYPERVISORHOSTMEMABORTFTRACEEVENT']._serialized_start=85728
-  _globals['_HYPERVISORHOSTMEMABORTFTRACEEVENT']._serialized_end=85790
-  _globals['_HYPERVISORHYPENTERFTRACEEVENT']._serialized_start=85792
-  _globals['_HYPERVISORHYPENTERFTRACEEVENT']._serialized_end=85823
-  _globals['_HYPERVISORIOMMUIDMAPCOMPLETEFTRACEEVENT']._serialized_start=85825
-  _globals['_HYPERVISORIOMMUIDMAPCOMPLETEFTRACEEVENT']._serialized_end=85879
-  _globals['_HYPERVISORVCPUILLEGALTRAPFTRACEEVENT']._serialized_start=85881
-  _globals['_HYPERVISORVCPUILLEGALTRAPFTRACEEVENT']._serialized_end=85932
-  _globals['_I2CREADFTRACEEVENT']._serialized_start=85934
-  _globals['_I2CREADFTRACEEVENT']._serialized_end=86032
-  _globals['_I2CWRITEFTRACEEVENT']._serialized_start=86034
-  _globals['_I2CWRITEFTRACEEVENT']._serialized_end=86146
-  _globals['_I2CRESULTFTRACEEVENT']._serialized_start=86148
-  _globals['_I2CRESULTFTRACEEVENT']._serialized_end=86220
-  _globals['_I2CREPLYFTRACEEVENT']._serialized_start=86222
-  _globals['_I2CREPLYFTRACEEVENT']._serialized_end=86334
-  _globals['_SMBUSREADFTRACEEVENT']._serialized_start=86336
-  _globals['_SMBUSREADFTRACEEVENT']._serialized_end=86442
-  _globals['_SMBUSWRITEFTRACEEVENT']._serialized_start=86444
-  _globals['_SMBUSWRITEFTRACEEVENT']._serialized_end=86564
-  _globals['_SMBUSRESULTFTRACEEVENT']._serialized_start=86567
-  _globals['_SMBUSRESULTFTRACEEVENT']._serialized_end=86708
-  _globals['_SMBUSREPLYFTRACEEVENT']._serialized_start=86710
-  _globals['_SMBUSREPLYFTRACEEVENT']._serialized_end=86830
-  _globals['_IONSTATFTRACEEVENT']._serialized_start=86832
-  _globals['_IONSTATFTRACEEVENT']._serialized_end=86909
-  _globals['_IPIENTRYFTRACEEVENT']._serialized_start=86911
-  _globals['_IPIENTRYFTRACEEVENT']._serialized_end=86948
-  _globals['_IPIEXITFTRACEEVENT']._serialized_start=86950
-  _globals['_IPIEXITFTRACEEVENT']._serialized_end=86986
-  _globals['_IPIRAISEFTRACEEVENT']._serialized_start=86988
-  _globals['_IPIRAISEFTRACEEVENT']._serialized_end=87046
-  _globals['_SOFTIRQENTRYFTRACEEVENT']._serialized_start=87048
-  _globals['_SOFTIRQENTRYFTRACEEVENT']._serialized_end=87086
-  _globals['_SOFTIRQEXITFTRACEEVENT']._serialized_start=87088
-  _globals['_SOFTIRQEXITFTRACEEVENT']._serialized_end=87125
-  _globals['_SOFTIRQRAISEFTRACEEVENT']._serialized_start=87127
-  _globals['_SOFTIRQRAISEFTRACEEVENT']._serialized_end=87165
-  _globals['_IRQHANDLERENTRYFTRACEEVENT']._serialized_start=87167
-  _globals['_IRQHANDLERENTRYFTRACEEVENT']._serialized_end=87239
-  _globals['_IRQHANDLEREXITFTRACEEVENT']._serialized_start=87241
-  _globals['_IRQHANDLEREXITFTRACEEVENT']._serialized_end=87294
-  _globals['_LOCALTIMERENTRYFTRACEEVENT']._serialized_start=87296
-  _globals['_LOCALTIMERENTRYFTRACEEVENT']._serialized_end=87340
-  _globals['_LOCALTIMEREXITFTRACEEVENT']._serialized_start=87342
-  _globals['_LOCALTIMEREXITFTRACEEVENT']._serialized_end=87385
-  _globals['_KGSLGPUFREQUENCYFTRACEEVENT']._serialized_start=87387
-  _globals['_KGSLGPUFREQUENCYFTRACEEVENT']._serialized_end=87450
-  _globals['_KGSLADRENOCMDBATCHQUEUEDFTRACEEVENT']._serialized_start=87452
-  _globals['_KGSLADRENOCMDBATCHQUEUEDFTRACEEVENT']._serialized_end=87565
-  _globals['_KGSLADRENOCMDBATCHSUBMITTEDFTRACEEVENT']._serialized_start=87568
-  _globals['_KGSLADRENOCMDBATCHSUBMITTEDFTRACEEVENT']._serialized_end=87817
-  _globals['_KGSLADRENOCMDBATCHSYNCFTRACEEVENT']._serialized_start=87819
-  _globals['_KGSLADRENOCMDBATCHSYNCFTRACEEVENT']._serialized_end=87914
-  _globals['_KGSLADRENOCMDBATCHRETIREDFTRACEEVENT']._serialized_start=87917
-  _globals['_KGSLADRENOCMDBATCHRETIREDFTRACEEVENT']._serialized_end=88258
-  _globals['_ALLOCPAGESIOMMUENDFTRACEEVENT']._serialized_start=88260
-  _globals['_ALLOCPAGESIOMMUENDFTRACEEVENT']._serialized_end=88325
-  _globals['_ALLOCPAGESIOMMUFAILFTRACEEVENT']._serialized_start=88327
-  _globals['_ALLOCPAGESIOMMUFAILFTRACEEVENT']._serialized_end=88393
-  _globals['_ALLOCPAGESIOMMUSTARTFTRACEEVENT']._serialized_start=88395
-  _globals['_ALLOCPAGESIOMMUSTARTFTRACEEVENT']._serialized_end=88462
-  _globals['_ALLOCPAGESSYSENDFTRACEEVENT']._serialized_start=88464
-  _globals['_ALLOCPAGESSYSENDFTRACEEVENT']._serialized_end=88527
-  _globals['_ALLOCPAGESSYSFAILFTRACEEVENT']._serialized_start=88529
-  _globals['_ALLOCPAGESSYSFAILFTRACEEVENT']._serialized_end=88593
-  _globals['_ALLOCPAGESSYSSTARTFTRACEEVENT']._serialized_start=88595
-  _globals['_ALLOCPAGESSYSSTARTFTRACEEVENT']._serialized_end=88660
-  _globals['_DMAALLOCCONTIGUOUSRETRYFTRACEEVENT']._serialized_start=88662
-  _globals['_DMAALLOCCONTIGUOUSRETRYFTRACEEVENT']._serialized_end=88713
-  _globals['_IOMMUMAPRANGEFTRACEEVENT']._serialized_start=88715
-  _globals['_IOMMUMAPRANGEFTRACEEVENT']._serialized_end=88798
-  _globals['_IOMMUSECPTBLMAPRANGEENDFTRACEEVENT']._serialized_start=88800
-  _globals['_IOMMUSECPTBLMAPRANGEENDFTRACEEVENT']._serialized_end=88902
-  _globals['_IOMMUSECPTBLMAPRANGESTARTFTRACEEVENT']._serialized_start=88904
-  _globals['_IOMMUSECPTBLMAPRANGESTARTFTRACEEVENT']._serialized_end=89008
-  _globals['_IONALLOCBUFFERENDFTRACEEVENT']._serialized_start=89010
-  _globals['_IONALLOCBUFFERENDFTRACEEVENT']._serialized_end=89122
-  _globals['_IONALLOCBUFFERFAILFTRACEEVENT']._serialized_start=89125
-  _globals['_IONALLOCBUFFERFAILFTRACEEVENT']._serialized_end=89253
-  _globals['_IONALLOCBUFFERFALLBACKFTRACEEVENT']._serialized_start=89256
-  _globals['_IONALLOCBUFFERFALLBACKFTRACEEVENT']._serialized_end=89388
-  _globals['_IONALLOCBUFFERSTARTFTRACEEVENT']._serialized_start=89390
-  _globals['_IONALLOCBUFFERSTARTFTRACEEVENT']._serialized_end=89504
-  _globals['_IONCPALLOCRETRYFTRACEEVENT']._serialized_start=89506
-  _globals['_IONCPALLOCRETRYFTRACEEVENT']._serialized_end=89549
-  _globals['_IONCPSECUREBUFFERENDFTRACEEVENT']._serialized_start=89551
-  _globals['_IONCPSECUREBUFFERENDFTRACEEVENT']._serialized_end=89646
-  _globals['_IONCPSECUREBUFFERSTARTFTRACEEVENT']._serialized_start=89648
-  _globals['_IONCPSECUREBUFFERSTARTFTRACEEVENT']._serialized_end=89745
-  _globals['_IONPREFETCHINGFTRACEEVENT']._serialized_start=89747
-  _globals['_IONPREFETCHINGFTRACEEVENT']._serialized_end=89787
-  _globals['_IONSECURECMAADDTOPOOLENDFTRACEEVENT']._serialized_start=89789
-  _globals['_IONSECURECMAADDTOPOOLENDFTRACEEVENT']._serialized_end=89880
-  _globals['_IONSECURECMAADDTOPOOLSTARTFTRACEEVENT']._serialized_start=89882
-  _globals['_IONSECURECMAADDTOPOOLSTARTFTRACEEVENT']._serialized_end=89975
-  _globals['_IONSECURECMAALLOCATEENDFTRACEEVENT']._serialized_start=89977
-  _globals['_IONSECURECMAALLOCATEENDFTRACEEVENT']._serialized_end=90075
-  _globals['_IONSECURECMAALLOCATESTARTFTRACEEVENT']._serialized_start=90077
-  _globals['_IONSECURECMAALLOCATESTARTFTRACEEVENT']._serialized_end=90177
-  _globals['_IONSECURECMASHRINKPOOLENDFTRACEEVENT']._serialized_start=90179
-  _globals['_IONSECURECMASHRINKPOOLENDFTRACEEVENT']._serialized_end=90261
-  _globals['_IONSECURECMASHRINKPOOLSTARTFTRACEEVENT']._serialized_start=90263
-  _globals['_IONSECURECMASHRINKPOOLSTARTFTRACEEVENT']._serialized_end=90347
-  _globals['_KFREEFTRACEEVENT']._serialized_start=90349
-  _globals['_KFREEFTRACEEVENT']._serialized_end=90399
-  _globals['_KMALLOCFTRACEEVENT']._serialized_start=90401
-  _globals['_KMALLOCFTRACEEVENT']._serialized_end=90512
-  _globals['_KMALLOCNODEFTRACEEVENT']._serialized_start=90515
-  _globals['_KMALLOCNODEFTRACEEVENT']._serialized_end=90644
-  _globals['_KMEMCACHEALLOCFTRACEEVENT']._serialized_start=90646
-  _globals['_KMEMCACHEALLOCFTRACEEVENT']._serialized_end=90764
-  _globals['_KMEMCACHEALLOCNODEFTRACEEVENT']._serialized_start=90767
-  _globals['_KMEMCACHEALLOCNODEFTRACEEVENT']._serialized_end=90903
-  _globals['_KMEMCACHEFREEFTRACEEVENT']._serialized_start=90905
-  _globals['_KMEMCACHEFREEFTRACEEVENT']._serialized_end=90963
-  _globals['_MIGRATEPAGESENDFTRACEEVENT']._serialized_start=90965
-  _globals['_MIGRATEPAGESENDFTRACEEVENT']._serialized_end=91007
-  _globals['_MIGRATEPAGESSTARTFTRACEEVENT']._serialized_start=91009
-  _globals['_MIGRATEPAGESSTARTFTRACEEVENT']._serialized_end=91053
-  _globals['_MIGRATERETRYFTRACEEVENT']._serialized_start=91055
-  _globals['_MIGRATERETRYFTRACEEVENT']._serialized_end=91095
-  _globals['_MMPAGEALLOCFTRACEEVENT']._serialized_start=91097
-  _globals['_MMPAGEALLOCFTRACEEVENT']._serialized_end=91203
-  _globals['_MMPAGEALLOCEXTFRAGFTRACEEVENT']._serialized_start=91206
-  _globals['_MMPAGEALLOCEXTFRAGFTRACEEVENT']._serialized_end=91392
-  _globals['_MMPAGEALLOCZONELOCKEDFTRACEEVENT']._serialized_start=91394
-  _globals['_MMPAGEALLOCZONELOCKEDFTRACEEVENT']._serialized_end=91491
-  _globals['_MMPAGEFREEFTRACEEVENT']._serialized_start=91493
-  _globals['_MMPAGEFREEFTRACEEVENT']._serialized_end=91558
-  _globals['_MMPAGEFREEBATCHEDFTRACEEVENT']._serialized_start=91560
-  _globals['_MMPAGEFREEBATCHEDFTRACEEVENT']._serialized_end=91631
-  _globals['_MMPAGEPCPUDRAINFTRACEEVENT']._serialized_start=91633
-  _globals['_MMPAGEPCPUDRAINFTRACEEVENT']._serialized_end=91724
-  _globals['_RSSSTATFTRACEEVENT']._serialized_start=91726
-  _globals['_RSSSTATFTRACEEVENT']._serialized_end=91805
-  _globals['_IONHEAPSHRINKFTRACEEVENT']._serialized_start=91807
-  _globals['_IONHEAPSHRINKFTRACEEVENT']._serialized_end=91890
-  _globals['_IONHEAPGROWFTRACEEVENT']._serialized_start=91892
-  _globals['_IONHEAPGROWFTRACEEVENT']._serialized_end=91973
-  _globals['_IONBUFFERCREATEFTRACEEVENT']._serialized_start=91975
-  _globals['_IONBUFFERCREATEFTRACEEVENT']._serialized_end=92030
-  _globals['_IONBUFFERDESTROYFTRACEEVENT']._serialized_start=92032
-  _globals['_IONBUFFERDESTROYFTRACEEVENT']._serialized_end=92088
-  _globals['_MMALLOCCONTIGMIGRATERANGEINFOFTRACEEVENT']._serialized_start=92091
-  _globals['_MMALLOCCONTIGMIGRATERANGEINFOFTRACEEVENT']._serialized_end=92244
-  _globals['_DMABUFRSSSTATFTRACEEVENT']._serialized_start=92246
-  _globals['_DMABUFRSSSTATFTRACEEVENT']._serialized_end=92319
-  _globals['_KVMACCESSFAULTFTRACEEVENT']._serialized_start=92321
-  _globals['_KVMACCESSFAULTFTRACEEVENT']._serialized_end=92361
-  _globals['_KVMACKIRQFTRACEEVENT']._serialized_start=92363
-  _globals['_KVMACKIRQFTRACEEVENT']._serialized_end=92415
-  _globals['_KVMAGEHVAFTRACEEVENT']._serialized_start=92417
-  _globals['_KVMAGEHVAFTRACEEVENT']._serialized_end=92467
-  _globals['_KVMAGEPAGEFTRACEEVENT']._serialized_start=92469
-  _globals['_KVMAGEPAGEFTRACEEVENT']._serialized_end=92553
-  _globals['_KVMARMCLEARDEBUGFTRACEEVENT']._serialized_start=92555
-  _globals['_KVMARMCLEARDEBUGFTRACEEVENT']._serialized_end=92605
-  _globals['_KVMARMSETDREG32FTRACEEVENT']._serialized_start=92607
-  _globals['_KVMARMSETDREG32FTRACEEVENT']._serialized_end=92664
-  _globals['_KVMARMSETREGSETFTRACEEVENT']._serialized_start=92666
-  _globals['_KVMARMSETREGSETFTRACEEVENT']._serialized_end=92721
-  _globals['_KVMARMSETUPDEBUGFTRACEEVENT']._serialized_start=92723
-  _globals['_KVMARMSETUPDEBUGFTRACEEVENT']._serialized_end=92787
-  _globals['_KVMENTRYFTRACEEVENT']._serialized_start=92789
-  _globals['_KVMENTRYFTRACEEVENT']._serialized_end=92827
-  _globals['_KVMEXITFTRACEEVENT']._serialized_start=92829
-  _globals['_KVMEXITFTRACEEVENT']._serialized_end=92895
-  _globals['_KVMFPUFTRACEEVENT']._serialized_start=92897
-  _globals['_KVMFPUFTRACEEVENT']._serialized_end=92930
-  _globals['_KVMGETTIMERMAPFTRACEEVENT']._serialized_start=92932
-  _globals['_KVMGETTIMERMAPFTRACEEVENT']._serialized_end=93043
-  _globals['_KVMGUESTFAULTFTRACEEVENT']._serialized_start=93045
-  _globals['_KVMGUESTFAULTFTRACEEVENT']._serialized_end=93129
-  _globals['_KVMHANDLESYSREGFTRACEEVENT']._serialized_start=93131
-  _globals['_KVMHANDLESYSREGFTRACEEVENT']._serialized_end=93172
-  _globals['_KVMHVCARM64FTRACEEVENT']._serialized_start=93174
-  _globals['_KVMHVCARM64FTRACEEVENT']._serialized_end=93240
-  _globals['_KVMIRQLINEFTRACEEVENT']._serialized_start=93242
-  _globals['_KVMIRQLINEFTRACEEVENT']._serialized_end=93329
-  _globals['_KVMMMIOFTRACEEVENT']._serialized_start=93331
-  _globals['_KVMMMIOFTRACEEVENT']._serialized_end=93404
-  _globals['_KVMMMIOEMULATEFTRACEEVENT']._serialized_start=93406
-  _globals['_KVMMMIOEMULATEFTRACEEVENT']._serialized_end=93479
-  _globals['_KVMSETGUESTDEBUGFTRACEEVENT']._serialized_start=93481
-  _globals['_KVMSETGUESTDEBUGFTRACEEVENT']._serialized_end=93545
-  _globals['_KVMSETIRQFTRACEEVENT']._serialized_start=93547
-  _globals['_KVMSETIRQFTRACEEVENT']._serialized_end=93620
-  _globals['_KVMSETSPTEHVAFTRACEEVENT']._serialized_start=93622
-  _globals['_KVMSETSPTEHVAFTRACEEVENT']._serialized_end=93661
-  _globals['_KVMSETWAYFLUSHFTRACEEVENT']._serialized_start=93663
-  _globals['_KVMSETWAYFLUSHFTRACEEVENT']._serialized_end=93722
-  _globals['_KVMSYSACCESSFTRACEEVENT']._serialized_start=93725
-  _globals['_KVMSYSACCESSFTRACEEVENT']._serialized_end=93864
-  _globals['_KVMTESTAGEHVAFTRACEEVENT']._serialized_start=93866
-  _globals['_KVMTESTAGEHVAFTRACEEVENT']._serialized_end=93905
-  _globals['_KVMTIMEREMULATEFTRACEEVENT']._serialized_start=93907
-  _globals['_KVMTIMEREMULATEFTRACEEVENT']._serialized_end=93975
-  _globals['_KVMTIMERHRTIMEREXPIREFTRACEEVENT']._serialized_start=93977
-  _globals['_KVMTIMERHRTIMEREXPIREFTRACEEVENT']._serialized_end=94030
-  _globals['_KVMTIMERRESTORESTATEFTRACEEVENT']._serialized_start=94032
-  _globals['_KVMTIMERRESTORESTATEFTRACEEVENT']._serialized_end=94111
-  _globals['_KVMTIMERSAVESTATEFTRACEEVENT']._serialized_start=94113
-  _globals['_KVMTIMERSAVESTATEFTRACEEVENT']._serialized_end=94189
-  _globals['_KVMTIMERUPDATEIRQFTRACEEVENT']._serialized_start=94191
-  _globals['_KVMTIMERUPDATEIRQFTRACEEVENT']._serialized_end=94266
-  _globals['_KVMTOGGLECACHEFTRACEEVENT']._serialized_start=94268
-  _globals['_KVMTOGGLECACHEFTRACEEVENT']._serialized_end=94338
-  _globals['_KVMUNMAPHVARANGEFTRACEEVENT']._serialized_start=94340
-  _globals['_KVMUNMAPHVARANGEFTRACEEVENT']._serialized_end=94397
-  _globals['_KVMUSERSPACEEXITFTRACEEVENT']._serialized_start=94399
-  _globals['_KVMUSERSPACEEXITFTRACEEVENT']._serialized_end=94444
-  _globals['_KVMVCPUWAKEUPFTRACEEVENT']._serialized_start=94446
-  _globals['_KVMVCPUWAKEUPFTRACEEVENT']._serialized_end=94515
-  _globals['_KVMWFXARM64FTRACEEVENT']._serialized_start=94517
-  _globals['_KVMWFXARM64FTRACEEVENT']._serialized_end=94574
-  _globals['_TRAPREGFTRACEEVENT']._serialized_start=94576
-  _globals['_TRAPREGFTRACEEVENT']._serialized_end=94660
-  _globals['_VGICUPDATEIRQPENDINGFTRACEEVENT']._serialized_start=94662
-  _globals['_VGICUPDATEIRQPENDINGFTRACEEVENT']._serialized_end=94740
-  _globals['_LOWMEMORYKILLFTRACEEVENT']._serialized_start=94742
-  _globals['_LOWMEMORYKILLFTRACEEVENT']._serialized_end=94858
-  _globals['_LWISTRACINGMARKWRITEFTRACEEVENT']._serialized_start=94860
-  _globals['_LWISTRACINGMARKWRITEFTRACEEVENT']._serialized_end=94973
-  _globals['_MALITRACINGMARKWRITEFTRACEEVENT']._serialized_start=94975
-  _globals['_MALITRACINGMARKWRITEFTRACEEVENT']._serialized_end=95064
-  _globals['_MALIMALIKCPUCQSSETFTRACEEVENT']._serialized_start=95066
-  _globals['_MALIMALIKCPUCQSSETFTRACEEVENT']._serialized_end=95183
-  _globals['_MALIMALIKCPUCQSWAITSTARTFTRACEEVENT']._serialized_start=95185
-  _globals['_MALIMALIKCPUCQSWAITSTARTFTRACEEVENT']._serialized_end=95308
-  _globals['_MALIMALIKCPUCQSWAITENDFTRACEEVENT']._serialized_start=95310
-  _globals['_MALIMALIKCPUCQSWAITENDFTRACEEVENT']._serialized_end=95431
-  _globals['_MALIMALIKCPUFENCESIGNALFTRACEEVENT']._serialized_start=95433
-  _globals['_MALIMALIKCPUFENCESIGNALFTRACEEVENT']._serialized_end=95555
-  _globals['_MALIMALIKCPUFENCEWAITSTARTFTRACEEVENT']._serialized_start=95557
-  _globals['_MALIMALIKCPUFENCEWAITSTARTFTRACEEVENT']._serialized_end=95682
-  _globals['_MALIMALIKCPUFENCEWAITENDFTRACEEVENT']._serialized_start=95684
-  _globals['_MALIMALIKCPUFENCEWAITENDFTRACEEVENT']._serialized_end=95807
-  _globals['_MALIMALICSFINTERRUPTSTARTFTRACEEVENT']._serialized_start=95809
-  _globals['_MALIMALICSFINTERRUPTSTARTFTRACEEVENT']._serialized_end=95901
-  _globals['_MALIMALICSFINTERRUPTENDFTRACEEVENT']._serialized_start=95903
-  _globals['_MALIMALICSFINTERRUPTENDFTRACEEVENT']._serialized_end=95993
-  _globals['_MALIMALIPMMCUHCTLCORESDOWNSCALENOTIFYPENDFTRACEEVENT']._serialized_start=95995
-  _globals['_MALIMALIPMMCUHCTLCORESDOWNSCALENOTIFYPENDFTRACEEVENT']._serialized_end=96103
-  _globals['_MALIMALIPMMCUHCTLCORESNOTIFYPENDFTRACEEVENT']._serialized_start=96105
-  _globals['_MALIMALIPMMCUHCTLCORESNOTIFYPENDFTRACEEVENT']._serialized_end=96204
-  _globals['_MALIMALIPMMCUHCTLCOREINACTIVEPENDFTRACEEVENT']._serialized_start=96206
-  _globals['_MALIMALIPMMCUHCTLCOREINACTIVEPENDFTRACEEVENT']._serialized_end=96306
-  _globals['_MALIMALIPMMCUHCTLMCUONRECHECKFTRACEEVENT']._serialized_start=96308
-  _globals['_MALIMALIPMMCUHCTLMCUONRECHECKFTRACEEVENT']._serialized_end=96404
-  _globals['_MALIMALIPMMCUHCTLSHADERSCOREOFFPENDFTRACEEVENT']._serialized_start=96406
-  _globals['_MALIMALIPMMCUHCTLSHADERSCOREOFFPENDFTRACEEVENT']._serialized_end=96508
-  _globals['_MALIMALIPMMCUHCTLSHADERSPENDOFFFTRACEEVENT']._serialized_start=96510
-  _globals['_MALIMALIPMMCUHCTLSHADERSPENDOFFFTRACEEVENT']._serialized_end=96608
-  _globals['_MALIMALIPMMCUHCTLSHADERSPENDONFTRACEEVENT']._serialized_start=96610
-  _globals['_MALIMALIPMMCUHCTLSHADERSPENDONFTRACEEVENT']._serialized_end=96707
-  _globals['_MALIMALIPMMCUHCTLSHADERSREADYOFFFTRACEEVENT']._serialized_start=96709
-  _globals['_MALIMALIPMMCUHCTLSHADERSREADYOFFFTRACEEVENT']._serialized_end=96808
-  _globals['_MALIMALIPMMCUINSLEEPFTRACEEVENT']._serialized_start=96810
-  _globals['_MALIMALIPMMCUINSLEEPFTRACEEVENT']._serialized_end=96897
-  _globals['_MALIMALIPMMCUOFFFTRACEEVENT']._serialized_start=96899
-  _globals['_MALIMALIPMMCUOFFFTRACEEVENT']._serialized_end=96982
-  _globals['_MALIMALIPMMCUONFTRACEEVENT']._serialized_start=96984
-  _globals['_MALIMALIPMMCUONFTRACEEVENT']._serialized_end=97066
-  _globals['_MALIMALIPMMCUONCOREATTRUPDATEPENDFTRACEEVENT']._serialized_start=97068
-  _globals['_MALIMALIPMMCUONCOREATTRUPDATEPENDFTRACEEVENT']._serialized_end=97168
-  _globals['_MALIMALIPMMCUONGLBREINITPENDFTRACEEVENT']._serialized_start=97170
-  _globals['_MALIMALIPMMCUONGLBREINITPENDFTRACEEVENT']._serialized_end=97265
-  _globals['_MALIMALIPMMCUONHALTFTRACEEVENT']._serialized_start=97267
-  _globals['_MALIMALIPMMCUONHALTFTRACEEVENT']._serialized_end=97353
-  _globals['_MALIMALIPMMCUONHWCNTDISABLEFTRACEEVENT']._serialized_start=97355
-  _globals['_MALIMALIPMMCUONHWCNTDISABLEFTRACEEVENT']._serialized_end=97449
-  _globals['_MALIMALIPMMCUONHWCNTENABLEFTRACEEVENT']._serialized_start=97451
-  _globals['_MALIMALIPMMCUONHWCNTENABLEFTRACEEVENT']._serialized_end=97544
-  _globals['_MALIMALIPMMCUONPENDHALTFTRACEEVENT']._serialized_start=97546
-  _globals['_MALIMALIPMMCUONPENDHALTFTRACEEVENT']._serialized_end=97636
-  _globals['_MALIMALIPMMCUONPENDSLEEPFTRACEEVENT']._serialized_start=97638
-  _globals['_MALIMALIPMMCUONPENDSLEEPFTRACEEVENT']._serialized_end=97729
-  _globals['_MALIMALIPMMCUONSLEEPINITIATEFTRACEEVENT']._serialized_start=97731
-  _globals['_MALIMALIPMMCUONSLEEPINITIATEFTRACEEVENT']._serialized_end=97826
-  _globals['_MALIMALIPMMCUPENDOFFFTRACEEVENT']._serialized_start=97828
-  _globals['_MALIMALIPMMCUPENDOFFFTRACEEVENT']._serialized_end=97915
-  _globals['_MALIMALIPMMCUPENDONRELOADFTRACEEVENT']._serialized_start=97917
-  _globals['_MALIMALIPMMCUPENDONRELOADFTRACEEVENT']._serialized_end=98009
-  _globals['_MALIMALIPMMCUPOWERDOWNFTRACEEVENT']._serialized_start=98011
-  _globals['_MALIMALIPMMCUPOWERDOWNFTRACEEVENT']._serialized_end=98100
-  _globals['_MALIMALIPMMCURESETWAITFTRACEEVENT']._serialized_start=98102
-  _globals['_MALIMALIPMMCURESETWAITFTRACEEVENT']._serialized_end=98191
-  _globals['_MALIGPUPOWERSTATEFTRACEEVENT']._serialized_start=98193
-  _globals['_MALIGPUPOWERSTATEFTRACEEVENT']._serialized_end=98280
-  _globals['_MDPCMDKICKOFFFTRACEEVENT']._serialized_start=98282
-  _globals['_MDPCMDKICKOFFFTRACEEVENT']._serialized_end=98346
-  _globals['_MDPCOMMITFTRACEEVENT']._serialized_start=98348
-  _globals['_MDPCOMMITFTRACEEVENT']._serialized_end=98438
-  _globals['_MDPPERFSETOTFTRACEEVENT']._serialized_start=98440
-  _globals['_MDPPERFSETOTFTRACEEVENT']._serialized_end=98531
-  _globals['_MDPSSPPCHANGEFTRACEEVENT']._serialized_start=98534
-  _globals['_MDPSSPPCHANGEFTRACEEVENT']._serialized_end=98802
-  _globals['_TRACINGMARKWRITEFTRACEEVENT']._serialized_start=98804
-  _globals['_TRACINGMARKWRITEFTRACEEVENT']._serialized_end=98887
-  _globals['_MDPCMDPINGPONGDONEFTRACEEVENT']._serialized_start=98889
-  _globals['_MDPCMDPINGPONGDONEFTRACEEVENT']._serialized_end=98989
-  _globals['_MDPCOMPAREBWFTRACEEVENT']._serialized_start=98992
-  _globals['_MDPCOMPAREBWFTRACEEVENT']._serialized_end=99156
-  _globals['_MDPPERFSETPANICLUTSFTRACEEVENT']._serialized_start=99158
-  _globals['_MDPPERFSETPANICLUTSFTRACEEVENT']._serialized_end=99270
-  _globals['_MDPSSPPSETFTRACEEVENT']._serialized_start=99273
-  _globals['_MDPSSPPSETFTRACEEVENT']._serialized_end=99538
-  _globals['_MDPCMDREADPTRDONEFTRACEEVENT']._serialized_start=99540
-  _globals['_MDPCMDREADPTRDONEFTRACEEVENT']._serialized_end=99605
-  _globals['_MDPMISRCRCFTRACEEVENT']._serialized_start=99607
-  _globals['_MDPMISRCRCFTRACEEVENT']._serialized_end=99680
-  _globals['_MDPPERFSETQOSLUTSFTRACEEVENT']._serialized_start=99682
-  _globals['_MDPPERFSETQOSLUTSFTRACEEVENT']._serialized_end=99807
-  _globals['_MDPTRACECOUNTERFTRACEEVENT']._serialized_start=99809
-  _globals['_MDPTRACECOUNTERFTRACEEVENT']._serialized_end=99887
-  _globals['_MDPCMDRELEASEBWFTRACEEVENT']._serialized_start=99889
-  _globals['_MDPCMDRELEASEBWFTRACEEVENT']._serialized_end=99934
-  _globals['_MDPMIXERUPDATEFTRACEEVENT']._serialized_start=99936
-  _globals['_MDPMIXERUPDATEFTRACEEVENT']._serialized_end=99982
-  _globals['_MDPPERFSETWMLEVELSFTRACEEVENT']._serialized_start=99985
-  _globals['_MDPPERFSETWMLEVELSFTRACEEVENT']._serialized_end=100145
-  _globals['_MDPVIDEOUNDERRUNDONEFTRACEEVENT']._serialized_start=100147
-  _globals['_MDPVIDEOUNDERRUNDONEFTRACEEVENT']._serialized_end=100219
-  _globals['_MDPCMDWAITPINGPONGFTRACEEVENT']._serialized_start=100221
-  _globals['_MDPCMDWAITPINGPONGFTRACEEVENT']._serialized_end=100290
-  _globals['_MDPPERFPREFILLCALCFTRACEEVENT']._serialized_start=100293
-  _globals['_MDPPERFPREFILLCALCFTRACEEVENT']._serialized_end=100499
-  _globals['_MDPPERFUPDATEBUSFTRACEEVENT']._serialized_start=100501
-  _globals['_MDPPERFUPDATEBUSFTRACEEVENT']._serialized_end=100582
-  _globals['_ROTATORBWAOASCONTEXTFTRACEEVENT']._serialized_start=100584
-  _globals['_ROTATORBWAOASCONTEXTFTRACEEVENT']._serialized_end=100632
-  _globals['_MMEVENTRECORDFTRACEEVENT']._serialized_start=100634
-  _globals['_MMEVENTRECORDFTRACEEVENT']._serialized_end=100723
-  _globals['_NETIFRECEIVESKBFTRACEEVENT']._serialized_start=100725
-  _globals['_NETIFRECEIVESKBFTRACEEVENT']._serialized_end=100797
-  _globals['_NETDEVXMITFTRACEEVENT']._serialized_start=100799
-  _globals['_NETDEVXMITFTRACEEVENT']._serialized_end=100878
-  _globals['_NAPIGRORECEIVEENTRYFTRACEEVENT']._serialized_start=100881
-  _globals['_NAPIGRORECEIVEENTRYFTRACEEVENT']._serialized_end=101260
-  _globals['_NAPIGRORECEIVEEXITFTRACEEVENT']._serialized_start=101262
-  _globals['_NAPIGRORECEIVEEXITFTRACEEVENT']._serialized_end=101306
-  _globals['_OOMSCOREADJUPDATEFTRACEEVENT']._serialized_start=101308
-  _globals['_OOMSCOREADJUPDATEFTRACEEVENT']._serialized_end=101388
-  _globals['_MARKVICTIMFTRACEEVENT']._serialized_start=101390
-  _globals['_MARKVICTIMFTRACEEVENT']._serialized_end=101426
-  _globals['_DSICMDFIFOSTATUSFTRACEEVENT']._serialized_start=101428
-  _globals['_DSICMDFIFOSTATUSFTRACEEVENT']._serialized_end=101490
-  _globals['_DSIRXFTRACEEVENT']._serialized_start=101492
-  _globals['_DSIRXFTRACEEVENT']._serialized_end=101539
-  _globals['_DSITXFTRACEEVENT']._serialized_start=101541
-  _globals['_DSITXFTRACEEVENT']._serialized_end=101603
-  _globals['_PANELWRITEGENERICFTRACEEVENT']._serialized_start=101605
-  _globals['_PANELWRITEGENERICFTRACEEVENT']._serialized_end=101732
-  _globals['_GRAMCOLLISIONFTRACEEVENT']._serialized_start=101734
-  _globals['_GRAMCOLLISIONFTRACEEVENT']._serialized_end=101804
-  _globals['_PANELSETTINGSFULLFTRACEEVENT']._serialized_start=101807
-  _globals['_PANELSETTINGSFULLFTRACEEVENT']._serialized_end=102004
-  _globals['_PANELSETTINGSLITEFTRACEEVENT']._serialized_start=102006
-  _globals['_PANELSETTINGSLITEFTRACEEVENT']._serialized_end=102119
-  _globals['_SCHEDSWITCHWITHCTRSFTRACEEVENT']._serialized_start=102122
-  _globals['_SCHEDSWITCHWITHCTRSFTRACEEVENT']._serialized_end=102510
-  _globals['_LONGIRQFTRACEEVENT']._serialized_start=102512
-  _globals['_LONGIRQFTRACEEVENT']._serialized_end=102577
-  _globals['_LONGSOFTIRQFTRACEEVENT']._serialized_start=102579
-  _globals['_LONGSOFTIRQFTRACEEVENT']._serialized_end=102651
-  _globals['_PIXELMMKSWAPDWAKEFTRACEEVENT']._serialized_start=102653
-  _globals['_PIXELMMKSWAPDWAKEFTRACEEVENT']._serialized_end=102701
-  _globals['_PIXELMMKSWAPDDONEFTRACEEVENT']._serialized_start=102704
-  _globals['_PIXELMMKSWAPDDONEFTRACEEVENT']._serialized_end=102837
-  _globals['_CPUFREQUENCYFTRACEEVENT']._serialized_start=102839
-  _globals['_CPUFREQUENCYFTRACEEVENT']._serialized_end=102895
-  _globals['_CPUFREQUENCYLIMITSFTRACEEVENT']._serialized_start=102897
-  _globals['_CPUFREQUENCYLIMITSFTRACEEVENT']._serialized_end=102980
-  _globals['_CPUIDLEFTRACEEVENT']._serialized_start=102982
-  _globals['_CPUIDLEFTRACEEVENT']._serialized_end=103033
-  _globals['_CLOCKENABLEFTRACEEVENT']._serialized_start=103035
-  _globals['_CLOCKENABLEFTRACEEVENT']._serialized_end=103104
-  _globals['_CLOCKDISABLEFTRACEEVENT']._serialized_start=103106
-  _globals['_CLOCKDISABLEFTRACEEVENT']._serialized_end=103176
-  _globals['_CLOCKSETRATEFTRACEEVENT']._serialized_start=103178
-  _globals['_CLOCKSETRATEFTRACEEVENT']._serialized_end=103248
-  _globals['_SUSPENDRESUMEFTRACEEVENT']._serialized_start=103250
-  _globals['_SUSPENDRESUMEFTRACEEVENT']._serialized_end=103320
-  _globals['_GPUFREQUENCYFTRACEEVENT']._serialized_start=103322
-  _globals['_GPUFREQUENCYFTRACEEVENT']._serialized_end=103378
-  _globals['_WAKEUPSOURCEACTIVATEFTRACEEVENT']._serialized_start=103380
-  _globals['_WAKEUPSOURCEACTIVATEFTRACEEVENT']._serialized_end=103442
-  _globals['_WAKEUPSOURCEDEACTIVATEFTRACEEVENT']._serialized_start=103444
-  _globals['_WAKEUPSOURCEDEACTIVATEFTRACEEVENT']._serialized_end=103508
-  _globals['_GPUWORKPERIODFTRACEEVENT']._serialized_start=103511
-  _globals['_GPUWORKPERIODFTRACEEVENT']._serialized_end=103644
-  _globals['_DEVICEPMCALLBACKSTARTFTRACEEVENT']._serialized_start=103646
-  _globals['_DEVICEPMCALLBACKSTARTFTRACEEVENT']._serialized_end=103759
-  _globals['_DEVICEPMCALLBACKENDFTRACEEVENT']._serialized_start=103761
-  _globals['_DEVICEPMCALLBACKENDFTRACEEVENT']._serialized_end=103840
-  _globals['_GPUPOWERSTATEFTRACEEVENT']._serialized_start=103842
-  _globals['_GPUPOWERSTATEFTRACEEVENT']._serialized_end=103906
-  _globals['_PSCIDOMAINIDLEEXITFTRACEEVENT']._serialized_start=103908
-  _globals['_PSCIDOMAINIDLEEXITFTRACEEVENT']._serialized_end=103986
-  _globals['_PSCIDOMAINIDLEENTERFTRACEEVENT']._serialized_start=103988
-  _globals['_PSCIDOMAINIDLEENTERFTRACEEVENT']._serialized_end=104067
-  _globals['_CONSOLEFTRACEEVENT']._serialized_start=104069
-  _globals['_CONSOLEFTRACEEVENT']._serialized_end=104102
-  _globals['_SYSENTERFTRACEEVENT']._serialized_start=104104
-  _globals['_SYSENTERFTRACEEVENT']._serialized_end=104151
-  _globals['_SYSEXITFTRACEEVENT']._serialized_start=104153
-  _globals['_SYSEXITFTRACEEVENT']._serialized_end=104198
-  _globals['_REGULATORDISABLEFTRACEEVENT']._serialized_start=104200
-  _globals['_REGULATORDISABLEFTRACEEVENT']._serialized_end=104243
-  _globals['_REGULATORDISABLECOMPLETEFTRACEEVENT']._serialized_start=104245
-  _globals['_REGULATORDISABLECOMPLETEFTRACEEVENT']._serialized_end=104296
-  _globals['_REGULATORENABLEFTRACEEVENT']._serialized_start=104298
-  _globals['_REGULATORENABLEFTRACEEVENT']._serialized_end=104340
-  _globals['_REGULATORENABLECOMPLETEFTRACEEVENT']._serialized_start=104342
-  _globals['_REGULATORENABLECOMPLETEFTRACEEVENT']._serialized_end=104392
-  _globals['_REGULATORENABLEDELAYFTRACEEVENT']._serialized_start=104394
-  _globals['_REGULATORENABLEDELAYFTRACEEVENT']._serialized_end=104441
-  _globals['_REGULATORSETVOLTAGEFTRACEEVENT']._serialized_start=104443
-  _globals['_REGULATORSETVOLTAGEFTRACEEVENT']._serialized_end=104515
-  _globals['_REGULATORSETVOLTAGECOMPLETEFTRACEEVENT']._serialized_start=104517
-  _globals['_REGULATORSETVOLTAGECOMPLETEFTRACEEVENT']._serialized_end=104584
-  _globals['_RPMSTATUSFTRACEEVENT']._serialized_start=104586
-  _globals['_RPMSTATUSFTRACEEVENT']._serialized_end=104638
-  _globals['_SAMSUNGTRACINGMARKWRITEFTRACEEVENT']._serialized_start=104640
-  _globals['_SAMSUNGTRACINGMARKWRITEFTRACEEVENT']._serialized_end=104765
-  _globals['_SCHEDSWITCHFTRACEEVENT']._serialized_start=104768
-  _globals['_SCHEDSWITCHFTRACEEVENT']._serialized_end=104924
-  _globals['_SCHEDWAKEUPFTRACEEVENT']._serialized_start=104926
-  _globals['_SCHEDWAKEUPFTRACEEVENT']._serialized_end=105028
-  _globals['_SCHEDBLOCKEDREASONFTRACEEVENT']._serialized_start=105030
-  _globals['_SCHEDBLOCKEDREASONFTRACEEVENT']._serialized_end=105107
-  _globals['_SCHEDCPUHOTPLUGFTRACEEVENT']._serialized_start=105109
-  _globals['_SCHEDCPUHOTPLUGFTRACEEVENT']._serialized_end=105190
-  _globals['_SCHEDWAKINGFTRACEEVENT']._serialized_start=105192
-  _globals['_SCHEDWAKINGFTRACEEVENT']._serialized_end=105294
-  _globals['_SCHEDWAKEUPNEWFTRACEEVENT']._serialized_start=105296
-  _globals['_SCHEDWAKEUPNEWFTRACEEVENT']._serialized_end=105401
-  _globals['_SCHEDPROCESSEXECFTRACEEVENT']._serialized_start=105403
-  _globals['_SCHEDPROCESSEXECFTRACEEVENT']._serialized_end=105480
-  _globals['_SCHEDPROCESSEXITFTRACEEVENT']._serialized_start=105482
-  _globals['_SCHEDPROCESSEXITFTRACEEVENT']._serialized_end=105566
-  _globals['_SCHEDPROCESSFORKFTRACEEVENT']._serialized_start=105568
-  _globals['_SCHEDPROCESSFORKFTRACEEVENT']._serialized_end=105677
-  _globals['_SCHEDPROCESSFREEFTRACEEVENT']._serialized_start=105679
-  _globals['_SCHEDPROCESSFREEFTRACEEVENT']._serialized_end=105749
-  _globals['_SCHEDPROCESSHANGFTRACEEVENT']._serialized_start=105751
-  _globals['_SCHEDPROCESSHANGFTRACEEVENT']._serialized_end=105807
-  _globals['_SCHEDPROCESSWAITFTRACEEVENT']._serialized_start=105809
-  _globals['_SCHEDPROCESSWAITFTRACEEVENT']._serialized_end=105879
-  _globals['_SCHEDPISETPRIOFTRACEEVENT']._serialized_start=105881
-  _globals['_SCHEDPISETPRIOFTRACEEVENT']._serialized_end=105969
-  _globals['_SCHEDCPUUTILCFSFTRACEEVENT']._serialized_start=105972
-  _globals['_SCHEDCPUUTILCFSFTRACEEVENT']._serialized_end=106300
-  _globals['_SCHEDMIGRATETASKFTRACEEVENT']._serialized_start=106303
-  _globals['_SCHEDMIGRATETASKFTRACEEVENT']._serialized_end=106440
-  _globals['_SCHEDWAKEUPTASKATTRFTRACEEVENT']._serialized_start=106443
-  _globals['_SCHEDWAKEUPTASKATTRFTRACEEVENT']._serialized_end=106683
-  _globals['_SCHEDGROUPTRACKERFTRACEEVENT']._serialized_start=106685
-  _globals['_SCHEDGROUPTRACKERFTRACEEVENT']._serialized_end=106776
-  _globals['_SCMCALLSTARTFTRACEEVENT']._serialized_start=106778
-  _globals['_SCMCALLSTARTFTRACEEVENT']._serialized_end=106844
-  _globals['_SCMCALLENDFTRACEEVENT']._serialized_start=106846
-  _globals['_SCMCALLENDFTRACEEVENT']._serialized_end=106869
-  _globals['_SCSIDISPATCHCMDERRORFTRACEEVENT']._serialized_start=106872
-  _globals['_SCSIDISPATCHCMDERRORFTRACEEVENT']._serialized_end=107124
-  _globals['_SCSIDISPATCHCMDTIMEOUTFTRACEEVENT']._serialized_start=107127
-  _globals['_SCSIDISPATCHCMDTIMEOUTFTRACEEVENT']._serialized_end=107430
-  _globals['_SCSIEHWAKEUPFTRACEEVENT']._serialized_start=107432
-  _globals['_SCSIEHWAKEUPFTRACEEVENT']._serialized_end=107474
-  _globals['_SDETRACINGMARKWRITEFTRACEEVENT']._serialized_start=107476
-  _globals['_SDETRACINGMARKWRITEFTRACEEVENT']._serialized_end=107597
-  _globals['_SDESDEEVTLOGFTRACEEVENT']._serialized_start=107600
-  _globals['_SDESDEEVTLOGFTRACEEVENT']._serialized_end=107869
-  _globals['_SDESDEPERFCALCCRTCFTRACEEVENT']._serialized_start=107872
-  _globals['_SDESDEPERFCALCCRTCFTRACEEVENT']._serialized_end=108052
-  _globals['_SDESDEPERFCRTCUPDATEFTRACEEVENT']._serialized_start=108055
-  _globals['_SDESDEPERFCRTCUPDATEFTRACEEVENT']._serialized_end=108338
-  _globals['_SDESDEPERFSETQOSLUTSFTRACEEVENT']._serialized_start=108340
-  _globals['_SDESDEPERFSETQOSLUTSFTRACEEVENT']._serialized_end=108456
-  _globals['_SDESDEPERFUPDATEBUSFTRACEEVENT']._serialized_start=108458
-  _globals['_SDESDEPERFUPDATEBUSFTRACEEVENT']._serialized_end=108558
-  _globals['_SIGNALDELIVERFTRACEEVENT']._serialized_start=108560
-  _globals['_SIGNALDELIVERFTRACEEVENT']._serialized_end=108631
-  _globals['_SIGNALGENERATEFTRACEEVENT']._serialized_start=108633
-  _globals['_SIGNALGENERATEFTRACEEVENT']._serialized_end=108745
-  _globals['_KFREESKBFTRACEEVENT']._serialized_start=108747
-  _globals['_KFREESKBFTRACEEVENT']._serialized_end=108821
-  _globals['_INETSOCKSETSTATEFTRACEEVENT']._serialized_start=108824
-  _globals['_INETSOCKSETSTATEFTRACEEVENT']._serialized_end=108999
-  _globals['_SYNCPTFTRACEEVENT']._serialized_start=109001
-  _globals['_SYNCPTFTRACEEVENT']._serialized_end=109053
-  _globals['_SYNCTIMELINEFTRACEEVENT']._serialized_start=109055
-  _globals['_SYNCTIMELINEFTRACEEVENT']._serialized_end=109109
-  _globals['_SYNCWAITFTRACEEVENT']._serialized_start=109111
-  _globals['_SYNCWAITFTRACEEVENT']._serialized_end=109177
-  _globals['_RSSSTATTHROTTLEDFTRACEEVENT']._serialized_start=109179
-  _globals['_RSSSTATTHROTTLEDFTRACEEVENT']._serialized_end=109267
-  _globals['_SUSPENDRESUMEMINIMALFTRACEEVENT']._serialized_start=109269
-  _globals['_SUSPENDRESUMEMINIMALFTRACEEVENT']._serialized_end=109317
-  _globals['_ZEROFTRACEEVENT']._serialized_start=109319
-  _globals['_ZEROFTRACEEVENT']._serialized_end=109392
-  _globals['_TASKNEWTASKFTRACEEVENT']._serialized_start=109394
-  _globals['_TASKNEWTASKFTRACEEVENT']._serialized_end=109489
-  _globals['_TASKRENAMEFTRACEEVENT']._serialized_start=109491
-  _globals['_TASKRENAMEFTRACEEVENT']._serialized_end=109584
-  _globals['_TCPRETRANSMITSKBFTRACEEVENT']._serialized_start=109587
-  _globals['_TCPRETRANSMITSKBFTRACEEVENT']._serialized_end=109724
-  _globals['_THERMALTEMPERATUREFTRACEEVENT']._serialized_start=109726
-  _globals['_THERMALTEMPERATUREFTRACEEVENT']._serialized_end=109824
-  _globals['_CDEVUPDATEFTRACEEVENT']._serialized_start=109826
-  _globals['_CDEVUPDATEFTRACEEVENT']._serialized_end=109879
-  _globals['_THERMALEXYNOSACPMBULKFTRACEEVENT']._serialized_start=109882
-  _globals['_THERMALEXYNOSACPMBULKFTRACEEVENT']._serialized_end=110110
-  _globals['_THERMALEXYNOSACPMHIGHOVERHEADFTRACEEVENT']._serialized_start=110113
-  _globals['_THERMALEXYNOSACPMHIGHOVERHEADFTRACEEVENT']._serialized_end=110275
-  _globals['_HRTIMERSTARTFTRACEEVENT']._serialized_start=110277
-  _globals['_HRTIMERSTARTFTRACEEVENT']._serialized_end=110389
-  _globals['_HRTIMERCANCELFTRACEEVENT']._serialized_start=110391
-  _globals['_HRTIMERCANCELFTRACEEVENT']._serialized_end=110434
-  _globals['_HRTIMEREXPIREENTRYFTRACEEVENT']._serialized_start=110436
-  _globals['_HRTIMEREXPIREENTRYFTRACEEVENT']._serialized_end=110515
-  _globals['_HRTIMEREXPIREEXITFTRACEEVENT']._serialized_start=110517
-  _globals['_HRTIMEREXPIREEXITFTRACEEVENT']._serialized_end=110564
-  _globals['_TIMERSTARTFTRACEEVENT']._serialized_start=110567
-  _globals['_TIMERSTARTFTRACEEVENT']._serialized_end=110711
-  _globals['_TIMERCANCELFTRACEEVENT']._serialized_start=110713
-  _globals['_TIMERCANCELFTRACEEVENT']._serialized_end=110752
-  _globals['_TIMEREXPIREENTRYFTRACEEVENT']._serialized_start=110754
-  _globals['_TIMEREXPIREENTRYFTRACEEVENT']._serialized_end=110846
-  _globals['_TIMEREXPIREEXITFTRACEEVENT']._serialized_start=110848
-  _globals['_TIMEREXPIREEXITFTRACEEVENT']._serialized_end=110891
-  _globals['_TRUSTYSMCFTRACEEVENT']._serialized_start=110893
-  _globals['_TRUSTYSMCFTRACEEVENT']._serialized_end=110963
-  _globals['_TRUSTYSMCDONEFTRACEEVENT']._serialized_start=110965
-  _globals['_TRUSTYSMCDONEFTRACEEVENT']._serialized_end=111004
-  _globals['_TRUSTYSTDCALL32FTRACEEVENT']._serialized_start=111006
-  _globals['_TRUSTYSTDCALL32FTRACEEVENT']._serialized_end=111082
-  _globals['_TRUSTYSTDCALL32DONEFTRACEEVENT']._serialized_start=111084
-  _globals['_TRUSTYSTDCALL32DONEFTRACEEVENT']._serialized_end=111129
-  _globals['_TRUSTYSHAREMEMORYFTRACEEVENT']._serialized_start=111131
-  _globals['_TRUSTYSHAREMEMORYFTRACEEVENT']._serialized_end=111203
-  _globals['_TRUSTYSHAREMEMORYDONEFTRACEEVENT']._serialized_start=111205
-  _globals['_TRUSTYSHAREMEMORYDONEFTRACEEVENT']._serialized_end=111310
-  _globals['_TRUSTYRECLAIMMEMORYFTRACEEVENT']._serialized_start=111312
-  _globals['_TRUSTYRECLAIMMEMORYFTRACEEVENT']._serialized_end=111356
-  _globals['_TRUSTYRECLAIMMEMORYDONEFTRACEEVENT']._serialized_start=111358
-  _globals['_TRUSTYRECLAIMMEMORYDONEFTRACEEVENT']._serialized_end=111419
-  _globals['_TRUSTYIRQFTRACEEVENT']._serialized_start=111421
-  _globals['_TRUSTYIRQFTRACEEVENT']._serialized_end=111456
-  _globals['_TRUSTYIPCHANDLEEVENTFTRACEEVENT']._serialized_start=111458
-  _globals['_TRUSTYIPCHANDLEEVENTFTRACEEVENT']._serialized_end=111541
-  _globals['_TRUSTYIPCCONNECTFTRACEEVENT']._serialized_start=111543
-  _globals['_TRUSTYIPCCONNECTFTRACEEVENT']._serialized_end=111615
-  _globals['_TRUSTYIPCCONNECTENDFTRACEEVENT']._serialized_start=111617
-  _globals['_TRUSTYIPCCONNECTENDFTRACEEVENT']._serialized_end=111691
-  _globals['_TRUSTYIPCWRITEFTRACEEVENT']._serialized_start=111694
-  _globals['_TRUSTYIPCWRITEFTRACEEVENT']._serialized_end=111824
-  _globals['_TRUSTYIPCPOLLFTRACEEVENT']._serialized_start=111826
-  _globals['_TRUSTYIPCPOLLFTRACEEVENT']._serialized_end=111903
-  _globals['_TRUSTYIPCREADFTRACEEVENT']._serialized_start=111905
-  _globals['_TRUSTYIPCREADFTRACEEVENT']._serialized_end=111963
-  _globals['_TRUSTYIPCREADENDFTRACEEVENT']._serialized_start=111965
-  _globals['_TRUSTYIPCREADENDFTRACEEVENT']._serialized_end=112079
-  _globals['_TRUSTYIPCRXFTRACEEVENT']._serialized_start=112081
-  _globals['_TRUSTYIPCRXFTRACEEVENT']._serialized_end=112153
-  _globals['_TRUSTYENQUEUENOPFTRACEEVENT']._serialized_start=112155
-  _globals['_TRUSTYENQUEUENOPFTRACEEVENT']._serialized_end=112226
-  _globals['_UFSHCDCOMMANDFTRACEEVENT']._serialized_start=112229
-  _globals['_UFSHCDCOMMANDFTRACEEVENT']._serialized_end=112415
-  _globals['_UFSHCDCLKGATINGFTRACEEVENT']._serialized_start=112417
-  _globals['_UFSHCDCLKGATINGFTRACEEVENT']._serialized_end=112478
-  _globals['_V4L2QBUFFTRACEEVENT']._serialized_start=112481
-  _globals['_V4L2QBUFFTRACEEVENT']._serialized_end=112892
-  _globals['_V4L2DQBUFFTRACEEVENT']._serialized_start=112895
-  _globals['_V4L2DQBUFFTRACEEVENT']._serialized_end=113307
-  _globals['_VB2V4L2BUFQUEUEFTRACEEVENT']._serialized_start=113310
-  _globals['_VB2V4L2BUFQUEUEFTRACEEVENT']._serialized_end=113680
-  _globals['_VB2V4L2BUFDONEFTRACEEVENT']._serialized_start=113683
-  _globals['_VB2V4L2BUFDONEFTRACEEVENT']._serialized_end=114052
-  _globals['_VB2V4L2QBUFFTRACEEVENT']._serialized_start=114055
-  _globals['_VB2V4L2QBUFFTRACEEVENT']._serialized_end=114421
-  _globals['_VB2V4L2DQBUFFTRACEEVENT']._serialized_start=114424
-  _globals['_VB2V4L2DQBUFFTRACEEVENT']._serialized_end=114791
-  _globals['_VIRTIOGPUCMDQUEUEFTRACEEVENT']._serialized_start=114794
-  _globals['_VIRTIOGPUCMDQUEUEFTRACEEVENT']._serialized_end=114959
-  _globals['_VIRTIOGPUCMDRESPONSEFTRACEEVENT']._serialized_start=114962
-  _globals['_VIRTIOGPUCMDRESPONSEFTRACEEVENT']._serialized_end=115130
-  _globals['_VIRTIOVIDEOCMDFTRACEEVENT']._serialized_start=115132
-  _globals['_VIRTIOVIDEOCMDFTRACEEVENT']._serialized_end=115192
-  _globals['_VIRTIOVIDEOCMDDONEFTRACEEVENT']._serialized_start=115194
-  _globals['_VIRTIOVIDEOCMDDONEFTRACEEVENT']._serialized_end=115258
-  _globals['_VIRTIOVIDEORESOURCEQUEUEFTRACEEVENT']._serialized_start=115261
-  _globals['_VIRTIOVIDEORESOURCEQUEUEFTRACEEVENT']._serialized_end=115457
-  _globals['_VIRTIOVIDEORESOURCEQUEUEDONEFTRACEEVENT']._serialized_start=115460
-  _globals['_VIRTIOVIDEORESOURCEQUEUEDONEFTRACEEVENT']._serialized_end=115660
-  _globals['_MMVMSCANDIRECTRECLAIMBEGINFTRACEEVENT']._serialized_start=115662
-  _globals['_MMVMSCANDIRECTRECLAIMBEGINFTRACEEVENT']._serialized_end=115758
-  _globals['_MMVMSCANDIRECTRECLAIMENDFTRACEEVENT']._serialized_start=115760
-  _globals['_MMVMSCANDIRECTRECLAIMENDFTRACEEVENT']._serialized_end=115819
-  _globals['_MMVMSCANKSWAPDWAKEFTRACEEVENT']._serialized_start=115821
-  _globals['_MMVMSCANKSWAPDWAKEFTRACEEVENT']._serialized_end=115893
-  _globals['_MMVMSCANKSWAPDSLEEPFTRACEEVENT']._serialized_start=115895
-  _globals['_MMVMSCANKSWAPDSLEEPFTRACEEVENT']._serialized_end=115940
-  _globals['_MMSHRINKSLABSTARTFTRACEEVENT']._serialized_start=115943
-  _globals['_MMSHRINKSLABSTARTFTRACEEVENT']._serialized_end=116176
-  _globals['_MMSHRINKSLABENDFTRACEEVENT']._serialized_start=116179
-  _globals['_MMSHRINKSLABENDFTRACEEVENT']._serialized_end=116324
-  _globals['_MMVMSCANMEMCGRECLAIMBEGINFTRACEEVENT']._serialized_start=116326
-  _globals['_MMVMSCANMEMCGRECLAIMBEGINFTRACEEVENT']._serialized_end=116421
-  _globals['_MMVMSCANMEMCGRECLAIMENDFTRACEEVENT']._serialized_start=116423
-  _globals['_MMVMSCANMEMCGRECLAIMENDFTRACEEVENT']._serialized_end=116481
-  _globals['_WORKQUEUEACTIVATEWORKFTRACEEVENT']._serialized_start=116483
-  _globals['_WORKQUEUEACTIVATEWORKFTRACEEVENT']._serialized_end=116549
-  _globals['_WORKQUEUEEXECUTEENDFTRACEEVENT']._serialized_start=116551
-  _globals['_WORKQUEUEEXECUTEENDFTRACEEVENT']._serialized_end=116615
-  _globals['_WORKQUEUEEXECUTESTARTFTRACEEVENT']._serialized_start=116617
-  _globals['_WORKQUEUEEXECUTESTARTFTRACEEVENT']._serialized_end=116683
-  _globals['_WORKQUEUEQUEUEWORKFTRACEEVENT']._serialized_start=116685
-  _globals['_WORKQUEUEQUEUEWORKFTRACEEVENT']._serialized_end=116797
-  _globals['_FTRACEEVENT']._serialized_start=116801
-  _globals['_FTRACEEVENT']._serialized_end=163520
-  _globals['_FTRACECPUSTATS']._serialized_start=163523
-  _globals['_FTRACECPUSTATS']._serialized_end=163716
-  _globals['_FTRACEKPROBESTATS']._serialized_start=163718
-  _globals['_FTRACEKPROBESTATS']._serialized_end=163767
-  _globals['_FTRACESTATS']._serialized_start=163770
-  _globals['_FTRACESTATS']._serialized_end=164353
-  _globals['_FTRACESTATS_PHASE']._serialized_start=164291
-  _globals['_FTRACESTATS_PHASE']._serialized_end=164353
-  _globals['_FTRACEEVENTBUNDLE']._serialized_start=164356
-  _globals['_FTRACEEVENTBUNDLE']._serialized_end=165436
-  _globals['_FTRACEEVENTBUNDLE_COMPACTSCHED']._serialized_start=164894
-  _globals['_FTRACEEVENTBUNDLE_COMPACTSCHED']._serialized_end=165260
-  _globals['_FTRACEEVENTBUNDLE_FTRACEERROR']._serialized_start=165262
-  _globals['_FTRACEEVENTBUNDLE_FTRACEERROR']._serialized_end=165346
-  _globals['_FTRACEEVENTBUNDLE_GENERICEVENTDESCRIPTOR']._serialized_start=165348
-  _globals['_FTRACEEVENTBUNDLE_GENERICEVENTDESCRIPTOR']._serialized_end=165436
-  _globals['_GENERICGPUFREQUENCYEVENT']._serialized_start=165438
-  _globals['_GENERICGPUFREQUENCYEVENT']._serialized_end=165503
-  _globals['_GENERICKERNELCPUFREQUENCYEVENT']._serialized_start=165505
-  _globals['_GENERICKERNELCPUFREQUENCYEVENT']._serialized_end=165567
-  _globals['_GENERICKERNELTASKSTATEEVENT']._serialized_start=165570
-  _globals['_GENERICKERNELTASKSTATEEVENT']._serialized_end=165988
-  _globals['_GENERICKERNELTASKSTATEEVENT_TASKSTATEENUM']._serialized_start=165731
-  _globals['_GENERICKERNELTASKSTATEEVENT_TASKSTATEENUM']._serialized_end=165988
-  _globals['_GENERICKERNELTASKRENAMEEVENT']._serialized_start=165990
-  _globals['_GENERICKERNELTASKRENAMEEVENT']._serialized_end=166047
-  _globals['_GENERICKERNELPROCESSTREE']._serialized_start=166050
-  _globals['_GENERICKERNELPROCESSTREE']._serialized_end=166359
-  _globals['_GENERICKERNELPROCESSTREE_THREAD']._serialized_start=166215
-  _globals['_GENERICKERNELPROCESSTREE_THREAD']._serialized_end=166304
-  _globals['_GENERICKERNELPROCESSTREE_PROCESS']._serialized_start=166306
-  _globals['_GENERICKERNELPROCESSTREE_PROCESS']._serialized_end=166359
-  _globals['_GPUCOUNTEREVENT']._serialized_start=166362
-  _globals['_GPUCOUNTEREVENT']._serialized_end=166657
-  _globals['_GPUCOUNTEREVENT_GPUCOUNTER']._serialized_start=166563
-  _globals['_GPUCOUNTEREVENT_GPUCOUNTER']._serialized_end=166649
-  _globals['_INTERNEDGPUCOUNTERDESCRIPTOR']._serialized_start=166659
-  _globals['_INTERNEDGPUCOUNTERDESCRIPTOR']._serialized_end=166785
-  _globals['_GPULOG']._serialized_start=166788
-  _globals['_GPULOG']._serialized_end=167048
-  _globals['_GPULOG_SEVERITY']._serialized_start=166885
-  _globals['_GPULOG_SEVERITY']._serialized_end=167048
-  _globals['_GPUMEMTOTALEVENT']._serialized_start=167050
-  _globals['_GPUMEMTOTALEVENT']._serialized_end=167111
-  _globals['_GPURENDERSTAGEEVENT']._serialized_start=167114
-  _globals['_GPURENDERSTAGEEVENT']._serialized_end=168661
-  _globals['_GPURENDERSTAGEEVENT_EXTRADATA']._serialized_start=167777
-  _globals['_GPURENDERSTAGEEVENT_EXTRADATA']._serialized_end=167817
-  _globals['_GPURENDERSTAGEEVENT_DIM3']._serialized_start=167819
-  _globals['_GPURENDERSTAGEEVENT_DIM3']._serialized_end=167858
-  _globals['_GPURENDERSTAGEEVENT_EXTRACOMPUTEARG']._serialized_start=167861
-  _globals['_GPURENDERSTAGEEVENT_EXTRACOMPUTEARG']._serialized_end=168056
-  _globals['_GPURENDERSTAGEEVENT_COMPUTEKERNELLAUNCH']._serialized_start=168059
-  _globals['_GPURENDERSTAGEEVENT_COMPUTEKERNELLAUNCH']._serialized_end=168277
-  _globals['_GPURENDERSTAGEEVENT_SPECIFICATIONS']._serialized_start=168280
-  _globals['_GPURENDERSTAGEEVENT_SPECIFICATIONS']._serialized_end=168641
-  _globals['_GPURENDERSTAGEEVENT_SPECIFICATIONS_CONTEXTSPEC']._serialized_start=168548
-  _globals['_GPURENDERSTAGEEVENT_SPECIFICATIONS_CONTEXTSPEC']._serialized_end=168591
-  _globals['_GPURENDERSTAGEEVENT_SPECIFICATIONS_DESCRIPTION']._serialized_start=168593
-  _globals['_GPURENDERSTAGEEVENT_SPECIFICATIONS_DESCRIPTION']._serialized_end=168641
-  _globals['_INTERNEDGRAPHICSCONTEXT']._serialized_start=168664
-  _globals['_INTERNEDGRAPHICSCONTEXT']._serialized_end=168853
-  _globals['_INTERNEDGRAPHICSCONTEXT_API']._serialized_start=168776
-  _globals['_INTERNEDGRAPHICSCONTEXT_API']._serialized_end=168853
-  _globals['_INTERNEDGPURENDERSTAGESPECIFICATION']._serialized_start=168856
-  _globals['_INTERNEDGPURENDERSTAGESPECIFICATION']._serialized_end=169094
-  _globals['_INTERNEDGPURENDERSTAGESPECIFICATION_RENDERSTAGECATEGORY']._serialized_start=169035
-  _globals['_INTERNEDGPURENDERSTAGESPECIFICATION_RENDERSTAGECATEGORY']._serialized_end=169094
-  _globals['_INTERNEDCOMPUTEKERNEL']._serialized_start=169097
-  _globals['_INTERNEDCOMPUTEKERNEL']._serialized_end=169253
-  _globals['_INTERNEDCOMPUTEARGNAME']._serialized_start=169255
-  _globals['_INTERNEDCOMPUTEARGNAME']._serialized_end=169306
-  _globals['_VULKANAPIEVENT']._serialized_start=169309
-  _globals['_VULKANAPIEVENT']._serialized_end=169752
-  _globals['_VULKANAPIEVENT_VKDEBUGUTILSOBJECTNAME']._serialized_start=169495
-  _globals['_VULKANAPIEVENT_VKDEBUGUTILSOBJECTNAME']._serialized_end=169609
-  _globals['_VULKANAPIEVENT_VKQUEUESUBMIT']._serialized_start=169612
-  _globals['_VULKANAPIEVENT_VKQUEUESUBMIT']._serialized_end=169743
-  _globals['_VULKANMEMORYEVENTANNOTATION']._serialized_start=169754
-  _globals['_VULKANMEMORYEVENTANNOTATION']._serialized_end=169876
-  _globals['_VULKANMEMORYEVENT']._serialized_start=169879
-  _globals['_VULKANMEMORYEVENT']._serialized_end=170751
-  _globals['_VULKANMEMORYEVENT_SOURCE']._serialized_start=170364
-  _globals['_VULKANMEMORYEVENT_SOURCE']._serialized_end=170497
-  _globals['_VULKANMEMORYEVENT_OPERATION']._serialized_start=170499
-  _globals['_VULKANMEMORYEVENT_OPERATION']._serialized_end=170616
-  _globals['_VULKANMEMORYEVENT_ALLOCATIONSCOPE']._serialized_start=170619
-  _globals['_VULKANMEMORYEVENT_ALLOCATIONSCOPE']._serialized_end=170751
-  _globals['_INTERNEDSTRING']._serialized_start=170753
-  _globals['_INTERNEDSTRING']._serialized_end=170795
-  _globals['_LINE']._serialized_start=170797
-  _globals['_LINE']._serialized_end=170873
-  _globals['_ADDRESSSYMBOLS']._serialized_start=170875
-  _globals['_ADDRESSSYMBOLS']._serialized_end=170946
-  _globals['_MODULESYMBOLS']._serialized_start=170948
-  _globals['_MODULESYMBOLS']._serialized_end=171053
-  _globals['_MAPPING']._serialized_start=171056
-  _globals['_MAPPING']._serialized_end=171212
-  _globals['_FRAME']._serialized_start=171215
-  _globals['_FRAME']._serialized_end=171549
-  _globals['_FRAME_KIND']._serialized_start=171410
-  _globals['_FRAME_KIND']._serialized_end=171535
-  _globals['_CALLSTACK']._serialized_start=171551
-  _globals['_CALLSTACK']._serialized_end=171594
-  _globals['_INLINECALLSTACK']._serialized_start=171597
-  _globals['_INLINECALLSTACK']._serialized_end=171744
-  _globals['_INLINECALLSTACK_FRAME']._serialized_start=171672
-  _globals['_INLINECALLSTACK_FRAME']._serialized_end=171744
-  _globals['_STACKSAMPLE']._serialized_start=171747
-  _globals['_STACKSAMPLE']._serialized_end=173411
-  _globals['_STACKSAMPLE_TASKCONTEXT']._serialized_start=172379
-  _globals['_STACKSAMPLE_TASKCONTEXT']._serialized_end=172449
-  _globals['_STACKSAMPLE_ASYNCCONTEXTDESCRIPTOR']._serialized_start=172451
-  _globals['_STACKSAMPLE_ASYNCCONTEXTDESCRIPTOR']._serialized_end=172536
-  _globals['_STACKSAMPLE_EXECUTIONCONTEXT']._serialized_start=172538
-  _globals['_STACKSAMPLE_EXECUTIONCONTEXT']._serialized_end=172631
-  _globals['_STACKSAMPLE_COUNTERDESCRIPTOR']._serialized_start=172634
-  _globals['_STACKSAMPLE_COUNTERDESCRIPTOR']._serialized_end=172945
-  _globals['_STACKSAMPLE_COUNTERDESCRIPTOR_SCOPE']._serialized_start=172868
-  _globals['_STACKSAMPLE_COUNTERDESCRIPTOR_SCOPE']._serialized_end=172931
-  _globals['_STACKSAMPLE_MODE']._serialized_start=172947
-  _globals['_STACKSAMPLE_MODE']._serialized_end=173068
-  _globals['_STACKSAMPLE_UNIT']._serialized_start=173071
-  _globals['_STACKSAMPLE_UNIT']._serialized_end=173293
-  _globals['_STACKSAMPLEDEFAULTS']._serialized_start=173414
-  _globals['_STACKSAMPLEDEFAULTS']._serialized_end=173605
-  _globals['_HISTOGRAMNAME']._serialized_start=173607
-  _globals['_HISTOGRAMNAME']._serialized_end=173649
-  _globals['_CHROMEHISTOGRAMSAMPLE']._serialized_start=173651
-  _globals['_CHROMEHISTOGRAMSAMPLE']._serialized_end=173741
-  _globals['_DEBUGANNOTATION']._serialized_start=173744
-  _globals['_DEBUGANNOTATION']._serialized_end=174684
-  _globals['_DEBUGANNOTATION_NESTEDVALUE']._serialized_start=174256
-  _globals['_DEBUGANNOTATION_NESTEDVALUE']._serialized_end=174636
-  _globals['_DEBUGANNOTATION_NESTEDVALUE_NESTEDTYPE']._serialized_start=174586
-  _globals['_DEBUGANNOTATION_NESTEDVALUE_NESTEDTYPE']._serialized_end=174636
-  _globals['_DEBUGANNOTATIONNAME']._serialized_start=174686
-  _globals['_DEBUGANNOTATIONNAME']._serialized_end=174734
-  _globals['_DEBUGANNOTATIONVALUETYPENAME']._serialized_start=174736
-  _globals['_DEBUGANNOTATIONVALUETYPENAME']._serialized_end=174793
-  _globals['_LOGMESSAGE']._serialized_start=174796
-  _globals['_LOGMESSAGE']._serialized_end=175055
-  _globals['_LOGMESSAGE_PRIORITY']._serialized_start=174910
-  _globals['_LOGMESSAGE_PRIORITY']._serialized_end=175055
-  _globals['_LOGMESSAGEBODY']._serialized_start=175057
-  _globals['_LOGMESSAGEBODY']._serialized_end=175100
-  _globals['_UNSYMBOLIZEDSOURCELOCATION']._serialized_start=175102
-  _globals['_UNSYMBOLIZEDSOURCELOCATION']._serialized_end=175179
-  _globals['_SOURCELOCATION']._serialized_start=175181
-  _globals['_SOURCELOCATION']._serialized_end=175273
-  _globals['_CHROMEACTIVEPROCESSES']._serialized_start=175275
-  _globals['_CHROMEACTIVEPROCESSES']._serialized_end=175311
-  _globals['_CHROMEAPPLICATIONSTATEINFO']._serialized_start=175314
-  _globals['_CHROMEAPPLICATIONSTATEINFO']._serialized_end=175680
-  _globals['_CHROMEAPPLICATIONSTATEINFO_CHROMEAPPLICATIONSTATE']._serialized_start=175440
-  _globals['_CHROMEAPPLICATIONSTATEINFO_CHROMEAPPLICATIONSTATE']._serialized_end=175680
-  _globals['_CHROMECOMPOSITORSCHEDULERSTATE']._serialized_start=175683
-  _globals['_CHROMECOMPOSITORSCHEDULERSTATE']._serialized_end=176770
-  _globals['_CHROMECOMPOSITORSCHEDULERSTATE_BEGINIMPLFRAMEDEADLINEMODE']._serialized_start=176574
-  _globals['_CHROMECOMPOSITORSCHEDULERSTATE_BEGINIMPLFRAMEDEADLINEMODE']._serialized_end=176764
-  _globals['_CHROMECOMPOSITORSTATEMACHINE']._serialized_start=176773
-  _globals['_CHROMECOMPOSITORSTATEMACHINE']._serialized_end=180483
-  _globals['_CHROMECOMPOSITORSTATEMACHINE_MAJORSTATE']._serialized_start=176964
-  _globals['_CHROMECOMPOSITORSTATEMACHINE_MAJORSTATE']._serialized_end=178263
-  _globals['_CHROMECOMPOSITORSTATEMACHINE_MAJORSTATE_BEGINIMPLFRAMESTATE']._serialized_start=177503
-  _globals['_CHROMECOMPOSITORSTATEMACHINE_MAJORSTATE_BEGINIMPLFRAMESTATE']._serialized_end=177664
-  _globals['_CHROMECOMPOSITORSTATEMACHINE_MAJORSTATE_BEGINMAINFRAMESTATE']._serialized_start=177667
-  _globals['_CHROMECOMPOSITORSTATEMACHINE_MAJORSTATE_BEGINMAINFRAMESTATE']._serialized_end=177814
-  _globals['_CHROMECOMPOSITORSTATEMACHINE_MAJORSTATE_LAYERTREEFRAMESINKSTATE']._serialized_start=177817
-  _globals['_CHROMECOMPOSITORSTATEMACHINE_MAJORSTATE_LAYERTREEFRAMESINKSTATE']._serialized_end=178061
-  _globals['_CHROMECOMPOSITORSTATEMACHINE_MAJORSTATE_FORCEDREDRAWONTIMEOUTSTATE']._serialized_start=178064
-  _globals['_CHROMECOMPOSITORSTATEMACHINE_MAJORSTATE_FORCEDREDRAWONTIMEOUTSTATE']._serialized_end=178263
-  _globals['_CHROMECOMPOSITORSTATEMACHINE_MINORSTATE']._serialized_start=178266
-  _globals['_CHROMECOMPOSITORSTATEMACHINE_MINORSTATE']._serialized_end=180483
-  _globals['_CHROMECOMPOSITORSTATEMACHINE_MINORSTATE_TREEPRIORITY']._serialized_start=180160
-  _globals['_CHROMECOMPOSITORSTATEMACHINE_MINORSTATE_TREEPRIORITY']._serialized_end=180344
-  _globals['_CHROMECOMPOSITORSTATEMACHINE_MINORSTATE_SCROLLHANDLERSTATE']._serialized_start=180347
-  _globals['_CHROMECOMPOSITORSTATEMACHINE_MINORSTATE_SCROLLHANDLERSTATE']._serialized_end=180477
-  _globals['_BEGINFRAMEARGS']._serialized_start=180486
-  _globals['_BEGINFRAMEARGS']._serialized_end=181040
-  _globals['_BEGINFRAMEARGS_BEGINFRAMEARGSTYPE']._serialized_start=180862
-  _globals['_BEGINFRAMEARGS_BEGINFRAMEARGSTYPE']._serialized_end=181024
-  _globals['_BEGINIMPLFRAMEARGS']._serialized_start=181043
-  _globals['_BEGINIMPLFRAMEARGS']._serialized_end=181619
-  _globals['_BEGINIMPLFRAMEARGS_TIMESTAMPSINUS']._serialized_start=181360
-  _globals['_BEGINIMPLFRAMEARGS_TIMESTAMPSINUS']._serialized_end=181553
-  _globals['_BEGINIMPLFRAMEARGS_STATE']._serialized_start=181555
-  _globals['_BEGINIMPLFRAMEARGS_STATE']._serialized_end=181611
-  _globals['_BEGINFRAMEOBSERVERSTATE']._serialized_start=181621
-  _globals['_BEGINFRAMEOBSERVERSTATE']._serialized_end=181744
-  _globals['_BEGINFRAMESOURCESTATE']._serialized_start=181747
-  _globals['_BEGINFRAMESOURCESTATE']._serialized_end=181892
-  _globals['_COMPOSITORTIMINGHISTORY']._serialized_start=181895
-  _globals['_COMPOSITORTIMINGHISTORY']._serialized_end=182275
-  _globals['_CHROMECONTENTSETTINGSEVENTINFO']._serialized_start=182277
-  _globals['_CHROMECONTENTSETTINGSEVENTINFO']._serialized_end=182339
-  _globals['_CHROMEFRAMEREPORTER']._serialized_start=182342
-  _globals['_CHROMEFRAMEREPORTER']._serialized_end=183462
-  _globals['_CHROMEFRAMEREPORTER_STATE']._serialized_start=183057
-  _globals['_CHROMEFRAMEREPORTER_STATE']._serialized_end=183166
-  _globals['_CHROMEFRAMEREPORTER_FRAMEDROPREASON']._serialized_start=183168
-  _globals['_CHROMEFRAMEREPORTER_FRAMEDROPREASON']._serialized_end=183294
-  _globals['_CHROMEFRAMEREPORTER_SCROLLSTATE']._serialized_start=183296
-  _globals['_CHROMEFRAMEREPORTER_SCROLLSTATE']._serialized_end=183419
-  _globals['_CHROMEFRAMEREPORTER_FRAMETYPE']._serialized_start=183421
-  _globals['_CHROMEFRAMEREPORTER_FRAMETYPE']._serialized_end=183458
-  _globals['_CHROMEKEYEDSERVICE']._serialized_start=183464
-  _globals['_CHROMEKEYEDSERVICE']._serialized_end=183498
-  _globals['_CHROMELATENCYINFO']._serialized_start=183501
-  _globals['_CHROMELATENCYINFO']._serialized_end=185283
-  _globals['_CHROMELATENCYINFO_COMPONENTINFO']._serialized_start=183830
-  _globals['_CHROMELATENCYINFO_COMPONENTINFO']._serialized_end=183943
-  _globals['_CHROMELATENCYINFO_STEP']._serialized_start=183946
-  _globals['_CHROMELATENCYINFO_STEP']._serialized_end=184348
-  _globals['_CHROMELATENCYINFO_LATENCYCOMPONENTTYPE']._serialized_start=184351
-  _globals['_CHROMELATENCYINFO_LATENCYCOMPONENTTYPE']._serialized_end=185108
-  _globals['_CHROMELATENCYINFO_INPUTTYPE']._serialized_start=185111
-  _globals['_CHROMELATENCYINFO_INPUTTYPE']._serialized_end=185283
-  _globals['_CHROMELEGACYIPC']._serialized_start=185286
-  _globals['_CHROMELEGACYIPC']._serialized_end=186260
-  _globals['_CHROMELEGACYIPC_MESSAGECLASS']._serialized_start=185398
-  _globals['_CHROMELEGACYIPC_MESSAGECLASS']._serialized_end=186260
-  _globals['_CHROMEMESSAGEPUMP']._serialized_start=186262
-  _globals['_CHROMEMESSAGEPUMP']._serialized_end=186346
-  _globals['_CHROMEMOJOEVENTINFO']._serialized_start=186349
-  _globals['_CHROMEMOJOEVENTINFO']._serialized_end=186553
-  _globals['_CHROMERENDERERSCHEDULERSTATE']._serialized_start=186555
-  _globals['_CHROMERENDERERSCHEDULERSTATE']._serialized_end=186681
-  _globals['_CHROMEUSEREVENT']._serialized_start=186683
-  _globals['_CHROMEUSEREVENT']._serialized_end=186737
-  _globals['_CHROMEWINDOWHANDLEEVENTINFO']._serialized_start=186739
-  _globals['_CHROMEWINDOWHANDLEEVENTINFO']._serialized_end=186819
-  _globals['_SCREENSHOT']._serialized_start=186821
-  _globals['_SCREENSHOT']._serialized_end=186890
-  _globals['_TASKEXECUTION']._serialized_start=186892
-  _globals['_TASKEXECUTION']._serialized_end=186932
-  _globals['_TRACKEVENT']._serialized_start=186935
-  _globals['_TRACKEVENT']._serialized_end=190383
-  _globals['_TRACKEVENT_INLINECALLSTACK']._serialized_start=189241
-  _globals['_TRACKEVENT_INLINECALLSTACK']._serialized_end=189399
-  _globals['_TRACKEVENT_INLINECALLSTACK_FRAME']._serialized_start=171672
-  _globals['_TRACKEVENT_INLINECALLSTACK_FRAME']._serialized_end=171744
-  _globals['_TRACKEVENT_LEGACYEVENT']._serialized_start=189402
-  _globals['_TRACKEVENT_LEGACYEVENT']._serialized_end=190084
-  _globals['_TRACKEVENT_LEGACYEVENT_FLOWDIRECTION']._serialized_start=189893
-  _globals['_TRACKEVENT_LEGACYEVENT_FLOWDIRECTION']._serialized_end=189973
-  _globals['_TRACKEVENT_LEGACYEVENT_INSTANTEVENTSCOPE']._serialized_start=189975
-  _globals['_TRACKEVENT_LEGACYEVENT_INSTANTEVENTSCOPE']._serialized_end=190072
-  _globals['_TRACKEVENT_TYPE']._serialized_start=190086
-  _globals['_TRACKEVENT_TYPE']._serialized_end=190208
-  _globals['_TRACKEVENTDEFAULTS']._serialized_start=190385
-  _globals['_TRACKEVENTDEFAULTS']._serialized_end=190502
-  _globals['_EVENTCATEGORY']._serialized_start=190504
-  _globals['_EVENTCATEGORY']._serialized_end=190546
-  _globals['_EVENTNAME']._serialized_start=190548
-  _globals['_EVENTNAME']._serialized_end=190586
-  _globals['_INTERNEDDATA']._serialized_start=190589
-  _globals['_INTERNEDDATA']._serialized_end=192706
-  _globals['_SYSTEMDJOURNALDEVENT']._serialized_start=192709
-  _globals['_SYSTEMDJOURNALDEVENT']._serialized_end=192952
-  _globals['_MEMORYTRACKERSNAPSHOT']._serialized_start=192955
-  _globals['_MEMORYTRACKERSNAPSHOT']._serialized_end=193963
-  _globals['_MEMORYTRACKERSNAPSHOT_PROCESSSNAPSHOT']._serialized_start=193170
-  _globals['_MEMORYTRACKERSNAPSHOT_PROCESSSNAPSHOT']._serialized_end=193888
-  _globals['_MEMORYTRACKERSNAPSHOT_PROCESSSNAPSHOT_MEMORYNODE']._serialized_start=193384
-  _globals['_MEMORYTRACKERSNAPSHOT_PROCESSSNAPSHOT_MEMORYNODE']._serialized_end=193795
-  _globals['_MEMORYTRACKERSNAPSHOT_PROCESSSNAPSHOT_MEMORYNODE_MEMORYNODEENTRY']._serialized_start=193568
-  _globals['_MEMORYTRACKERSNAPSHOT_PROCESSSNAPSHOT_MEMORYNODE_MEMORYNODEENTRY']._serialized_end=193795
-  _globals['_MEMORYTRACKERSNAPSHOT_PROCESSSNAPSHOT_MEMORYNODE_MEMORYNODEENTRY_UNITS']._serialized_start=193749
-  _globals['_MEMORYTRACKERSNAPSHOT_PROCESSSNAPSHOT_MEMORYNODE_MEMORYNODEENTRY_UNITS']._serialized_end=193795
-  _globals['_MEMORYTRACKERSNAPSHOT_PROCESSSNAPSHOT_MEMORYEDGE']._serialized_start=193797
-  _globals['_MEMORYTRACKERSNAPSHOT_PROCESSSNAPSHOT_MEMORYEDGE']._serialized_end=193888
-  _globals['_MEMORYTRACKERSNAPSHOT_LEVELOFDETAIL']._serialized_start=193890
-  _globals['_MEMORYTRACKERSNAPSHOT_LEVELOFDETAIL']._serialized_end=193963
-  _globals['_CONCURRENTSESSIONEVENT']._serialized_start=193966
-  _globals['_CONCURRENTSESSIONEVENT']._serialized_end=194303
-  _globals['_CONCURRENTSESSIONEVENT_STATE']._serialized_start=194145
-  _globals['_CONCURRENTSESSIONEVENT_STATE']._serialized_end=194303
-  _globals['_PERFETTOMETATRACE']._serialized_start=194306
-  _globals['_PERFETTOMETATRACE']._serialized_end=194851
-  _globals['_PERFETTOMETATRACE_ARG']._serialized_start=194663
-  _globals['_PERFETTOMETATRACE_ARG']._serialized_end=194790
-  _globals['_PERFETTOMETATRACE_INTERNEDSTRING']._serialized_start=194792
-  _globals['_PERFETTOMETATRACE_INTERNEDSTRING']._serialized_end=194836
-  _globals['_TRACEPROVENANCE']._serialized_start=194854
-  _globals['_TRACEPROVENANCE']._serialized_end=195046
-  _globals['_TRACEPROVENANCE_SEQUENCE']._serialized_start=194931
-  _globals['_TRACEPROVENANCE_SEQUENCE']._serialized_end=194974
-  _globals['_TRACEPROVENANCE_BUFFER']._serialized_start=194976
-  _globals['_TRACEPROVENANCE_BUFFER']._serialized_end=195046
-  _globals['_TRACINGSERVICEEVENT']._serialized_start=195049
-  _globals['_TRACINGSERVICEEVENT']._serialized_end=195699
-  _globals['_TRACINGSERVICEEVENT_DATASOURCES']._serialized_start=195527
-  _globals['_TRACINGSERVICEEVENT_DATASOURCES']._serialized_end=195685
-  _globals['_TRACINGSERVICEEVENT_DATASOURCES_DATASOURCE']._serialized_start=195624
-  _globals['_TRACINGSERVICEEVENT_DATASOURCES_DATASOURCE']._serialized_end=195685
-  _globals['_ANDROIDENERGYCONSUMER']._serialized_start=195701
-  _globals['_ANDROIDENERGYCONSUMER']._serialized_end=195797
-  _globals['_ANDROIDENERGYCONSUMERDESCRIPTOR']._serialized_start=195799
-  _globals['_ANDROIDENERGYCONSUMERDESCRIPTOR']._serialized_end=195898
-  _globals['_ANDROIDENERGYESTIMATIONBREAKDOWN']._serialized_start=195901
-  _globals['_ANDROIDENERGYESTIMATIONBREAKDOWN']._serialized_end=196221
-  _globals['_ANDROIDENERGYESTIMATIONBREAKDOWN_ENERGYUIDBREAKDOWN']._serialized_start=196168
-  _globals['_ANDROIDENERGYESTIMATIONBREAKDOWN_ENERGYUIDBREAKDOWN']._serialized_end=196221
-  _globals['_ENTITYSTATERESIDENCY']._serialized_start=196224
-  _globals['_ENTITYSTATERESIDENCY']._serialized_end=196667
-  _globals['_ENTITYSTATERESIDENCY_POWERENTITYSTATE']._serialized_start=196405
-  _globals['_ENTITYSTATERESIDENCY_POWERENTITYSTATE']._serialized_end=196507
-  _globals['_ENTITYSTATERESIDENCY_STATERESIDENCY']._serialized_start=196510
-  _globals['_ENTITYSTATERESIDENCY_STATERESIDENCY']._serialized_end=196667
-  _globals['_BATTERYCOUNTERS']._serialized_start=196670
-  _globals['_BATTERYCOUNTERS']._serialized_end=196847
-  _globals['_POWERRAILS']._serialized_start=196850
-  _globals['_POWERRAILS']._serialized_end=197177
-  _globals['_POWERRAILS_RAILDESCRIPTOR']._serialized_start=197016
-  _globals['_POWERRAILS_RAILDESCRIPTOR']._serialized_end=197110
-  _globals['_POWERRAILS_ENERGYDATA']._serialized_start=197112
-  _globals['_POWERRAILS_ENERGYDATA']._serialized_end=197177
-  _globals['_JAVAFRAME']._serialized_start=197179
-  _globals['_JAVAFRAME']._serialized_end=197253
-  _globals['_JAVASTACK']._serialized_start=197255
-  _globals['_JAVASTACK']._serialized_end=197310
-  _globals['_ARTPROCESSMETADATA']._serialized_start=197313
-  _globals['_ARTPROCESSMETADATA']._serialized_end=197578
-  _globals['_OBFUSCATEDMEMBER']._serialized_start=197581
-  _globals['_OBFUSCATEDMEMBER']._serialized_end=197763
-  _globals['_OBFUSCATEDCLASS']._serialized_start=197766
-  _globals['_OBFUSCATEDCLASS']._serialized_end=198301
-  _globals['_OBFUSCATEDCLASS_MERGEDCLASS']._serialized_start=198035
-  _globals['_OBFUSCATEDCLASS_MERGEDCLASS']._serialized_end=198152
-  _globals['_OBFUSCATEDCLASS_MERGEDCLASSES']._serialized_start=198155
-  _globals['_OBFUSCATEDCLASS_MERGEDCLASSES']._serialized_end=198301
-  _globals['_DEOBFUSCATIONMAPPING']._serialized_start=198304
-  _globals['_DEOBFUSCATIONMAPPING']._serialized_end=198432
-  _globals['_PROFILEPACKET']._serialized_start=198435
-  _globals['_PROFILEPACKET']._serialized_end=199928
-  _globals['_PROFILEPACKET_HEAPSAMPLE']._serialized_start=198743
-  _globals['_PROFILEPACKET_HEAPSAMPLE']._serialized_end=198929
-  _globals['_PROFILEPACKET_HISTOGRAM']._serialized_start=198932
-  _globals['_PROFILEPACKET_HISTOGRAM']._serialized_end=199075
-  _globals['_PROFILEPACKET_HISTOGRAM_BUCKET']._serialized_start=199011
-  _globals['_PROFILEPACKET_HISTOGRAM_BUCKET']._serialized_end=199075
-  _globals['_PROFILEPACKET_PROCESSSTATS']._serialized_start=199078
-  _globals['_PROFILEPACKET_PROCESSSTATS']._serialized_end=199300
-  _globals['_PROFILEPACKET_PROCESSHEAPSAMPLES']._serialized_start=199303
-  _globals['_PROFILEPACKET_PROCESSHEAPSAMPLES']._serialized_end=199928
-  _globals['_PROFILEPACKET_PROCESSHEAPSAMPLES_CLIENTERROR']._serialized_start=199823
-  _globals['_PROFILEPACKET_PROCESSHEAPSAMPLES_CLIENTERROR']._serialized_end=199928
-  _globals['_STREAMINGALLOCATION']._serialized_start=199931
-  _globals['_STREAMINGALLOCATION']._serialized_end=200088
-  _globals['_STREAMINGFREE']._serialized_start=200090
-  _globals['_STREAMINGFREE']._serialized_end=200164
-  _globals['_STREAMINGPROFILEPACKET']._serialized_start=200166
-  _globals['_STREAMINGPROFILEPACKET']._serialized_end=200267
-  _globals['_PROFILING']._serialized_start=200270
-  _globals['_PROFILING']._serialized_end=200926
-  _globals['_PROFILING_CPUMODE']._serialized_start=200283
-  _globals['_PROFILING_CPUMODE']._serialized_end=200407
-  _globals['_PROFILING_STACKUNWINDERROR']._serialized_start=200410
-  _globals['_PROFILING_STACKUNWINDERROR']._serialized_end=200926
-  _globals['_PERFSAMPLE']._serialized_start=200929
-  _globals['_PERFSAMPLE']._serialized_end=201808
-  _globals['_PERFSAMPLE_PRODUCEREVENT']._serialized_start=201353
-  _globals['_PERFSAMPLE_PRODUCEREVENT']._serialized_end=201573
-  _globals['_PERFSAMPLE_PRODUCEREVENT_DATASOURCESTOPREASON']._serialized_start=201464
-  _globals['_PERFSAMPLE_PRODUCEREVENT_DATASOURCESTOPREASON']._serialized_end=201542
-  _globals['_PERFSAMPLE_SAMPLESKIPREASON']._serialized_start=201576
-  _globals['_PERFSAMPLE_SAMPLESKIPREASON']._serialized_end=201749
-  _globals['_PERFSAMPLEDEFAULTS']._serialized_start=201811
-  _globals['_PERFSAMPLEDEFAULTS']._serialized_end=201997
-  _globals['_SMAPSENTRY']._serialized_start=202000
-  _globals['_SMAPSENTRY']._serialized_end=202387
-  _globals['_PACKEDSMAPS']._serialized_start=202390
-  _globals['_PACKEDSMAPS']._serialized_end=202775
-  _globals['_SMAPSPACKET']._serialized_start=202778
-  _globals['_SMAPSPACKET']._serialized_end=203126
-  _globals['_SMAPSPACKET_RECORDINGTYPE']._serialized_start=202975
-  _globals['_SMAPSPACKET_RECORDINGTYPE']._serialized_end=203126
-  _globals['_PROCESSSTATS']._serialized_start=203129
-  _globals['_PROCESSSTATS']._serialized_end=203956
-  _globals['_PROCESSSTATS_THREAD']._serialized_start=203237
-  _globals['_PROCESSSTATS_THREAD']._serialized_end=203276
-  _globals['_PROCESSSTATS_FDINFO']._serialized_start=203278
-  _globals['_PROCESSSTATS_FDINFO']._serialized_end=203312
-  _globals['_PROCESSSTATS_PROCESS']._serialized_start=203315
-  _globals['_PROCESSSTATS_PROCESS']._serialized_end=203956
-  _globals['_PROCESSTREE']._serialized_start=203959
-  _globals['_PROCESSTREE']._serialized_end=204351
-  _globals['_PROCESSTREE_THREAD']._serialized_start=204119
-  _globals['_PROCESSTREE_THREAD']._serialized_end=204183
-  _globals['_PROCESSTREE_PROCESS']._serialized_start=204186
-  _globals['_PROCESSTREE_PROCESS']._serialized_end=204351
-  _globals['_REMOTECLOCKSYNC']._serialized_start=204354
-  _globals['_REMOTECLOCKSYNC']._serialized_end=204565
-  _globals['_REMOTECLOCKSYNC_SYNCEDCLOCKS']._serialized_start=204443
-  _globals['_REMOTECLOCKSYNC_SYNCEDCLOCKS']._serialized_end=204565
-  _globals['_ATOM']._serialized_start=204567
-  _globals['_ATOM']._serialized_end=204573
-  _globals['_STATSDATOM']._serialized_start=204575
-  _globals['_STATSDATOM']._serialized_end=204649
-  _globals['_SYSSTATS']._serialized_start=204652
-  _globals['_SYSSTATS']._serialized_end=206800
-  _globals['_SYSSTATS_MEMINFOVALUE']._serialized_start=205495
-  _globals['_SYSSTATS_MEMINFOVALUE']._serialized_end=205571
-  _globals['_SYSSTATS_VMSTATVALUE']._serialized_start=205573
-  _globals['_SYSSTATS_VMSTATVALUE']._serialized_end=205647
-  _globals['_SYSSTATS_CPUTIMES']._serialized_start=205650
-  _globals['_SYSSTATS_CPUTIMES']._serialized_end=205830
-  _globals['_SYSSTATS_INTERRUPTCOUNT']._serialized_start=205832
-  _globals['_SYSSTATS_INTERRUPTCOUNT']._serialized_end=205876
-  _globals['_SYSSTATS_DEVFREQVALUE']._serialized_start=205878
-  _globals['_SYSSTATS_DEVFREQVALUE']._serialized_end=205920
-  _globals['_SYSSTATS_BUDDYINFO']._serialized_start=205922
-  _globals['_SYSSTATS_BUDDYINFO']._serialized_end=205982
-  _globals['_SYSSTATS_DISKSTAT']._serialized_start=205985
-  _globals['_SYSSTATS_DISKSTAT']._serialized_end=206200
-  _globals['_SYSSTATS_PSISAMPLE']._serialized_start=206203
-  _globals['_SYSSTATS_PSISAMPLE']._serialized_end=206511
-  _globals['_SYSSTATS_PSISAMPLE_PSIRESOURCE']._serialized_start=206302
-  _globals['_SYSSTATS_PSISAMPLE_PSIRESOURCE']._serialized_end=206511
-  _globals['_SYSSTATS_THERMALZONE']._serialized_start=206513
-  _globals['_SYSSTATS_THERMALZONE']._serialized_end=206568
-  _globals['_SYSSTATS_CPUIDLESTATEENTRY']._serialized_start=206570
-  _globals['_SYSSTATS_CPUIDLESTATEENTRY']._serialized_end=206625
-  _globals['_SYSSTATS_CPUIDLESTATE']._serialized_start=206627
-  _globals['_SYSSTATS_CPUIDLESTATE']._serialized_end=206731
-  _globals['_SYSSTATS_SLABINFO']._serialized_start=206733
-  _globals['_SYSSTATS_SLABINFO']._serialized_end=206800
-  _globals['_CPUINFO']._serialized_start=206803
-  _globals['_CPUINFO']._serialized_end=207135
-  _globals['_CPUINFO_ARMCPUIDENTIFIER']._serialized_start=206858
-  _globals['_CPUINFO_ARMCPUIDENTIFIER']._serialized_end=206968
-  _globals['_CPUINFO_CPU']._serialized_start=206971
-  _globals['_CPUINFO_CPU']._serialized_end=207135
-  _globals['_GPUINFO']._serialized_start=207138
-  _globals['_GPUINFO']._serialized_end=207396
-  _globals['_GPUINFO_GPU']._serialized_start=207194
-  _globals['_GPUINFO_GPU']._serialized_end=207396
-  _globals['_GPUINFO_GPU_KEYVALUE']._serialized_start=207358
-  _globals['_GPUINFO_GPU_KEYVALUE']._serialized_end=207396
-  _globals['_INTERRUPTINFO']._serialized_start=207399
-  _globals['_INTERRUPTINFO']._serialized_end=207534
-  _globals['_INTERRUPTINFO_INTERRUPTMAPPING']._serialized_start=207486
-  _globals['_INTERRUPTINFO_INTERRUPTMAPPING']._serialized_end=207534
-  _globals['_TESTEVENT']._serialized_start=207537
-  _globals['_TESTEVENT']._serialized_end=208639
-  _globals['_TESTEVENT_TESTPAYLOAD']._serialized_start=207825
-  _globals['_TESTEVENT_TESTPAYLOAD']._serialized_end=208067
-  _globals['_TESTEVENT_PROTOVMMESSAGE']._serialized_start=208070
-  _globals['_TESTEVENT_PROTOVMMESSAGE']._serialized_end=208220
-  _globals['_TESTEVENT_PROTOVMMESSAGE_PROTOVMSUBMESSAGE']._serialized_start=208181
-  _globals['_TESTEVENT_PROTOVMMESSAGE_PROTOVMSUBMESSAGE']._serialized_end=208220
-  _globals['_TESTEVENT_PROTOVMPATCH']._serialized_start=208223
-  _globals['_TESTEVENT_PROTOVMPATCH']._serialized_end=208440
-  _globals['_TESTEVENT_PROTOVMINCREMENTALSTATE']._serialized_start=208443
-  _globals['_TESTEVENT_PROTOVMINCREMENTALSTATE']._serialized_end=208639
-  _globals['_TRACEPACKETDEFAULTS']._serialized_start=208642
-  _globals['_TRACEPACKETDEFAULTS']._serialized_end=208953
-  _globals['_TRACEUUID']._serialized_start=208955
-  _globals['_TRACEUUID']._serialized_end=208992
-  _globals['_PROCESSDESCRIPTOR']._serialized_start=208995
-  _globals['_PROCESSDESCRIPTOR']._serialized_end=209482
-  _globals['_PROCESSDESCRIPTOR_CHROMEPROCESSTYPE']._serialized_start=209257
-  _globals['_PROCESSDESCRIPTOR_CHROMEPROCESSTYPE']._serialized_end=209482
-  _globals['_TRACKEVENTRANGEOFINTEREST']._serialized_start=209484
-  _globals['_TRACKEVENTRANGEOFINTEREST']._serialized_end=209529
-  _globals['_THREADDESCRIPTOR']._serialized_start=209532
-  _globals['_THREADDESCRIPTOR']._serialized_end=210288
-  _globals['_THREADDESCRIPTOR_CHROMETHREADTYPE']._serialized_start=209817
-  _globals['_THREADDESCRIPTOR_CHROMETHREADTYPE']._serialized_end=210288
-  _globals['_CHROMEPROCESSDESCRIPTOR']._serialized_start=210291
-  _globals['_CHROMEPROCESSDESCRIPTOR']._serialized_end=210446
-  _globals['_CHROMETHREADDESCRIPTOR']._serialized_start=210448
-  _globals['_CHROMETHREADDESCRIPTOR']._serialized_end=210546
-  _globals['_COUNTERDESCRIPTOR']._serialized_start=210549
-  _globals['_COUNTERDESCRIPTOR']._serialized_end=211004
-  _globals['_COUNTERDESCRIPTOR_BUILTINCOUNTERTYPE']._serialized_start=210808
-  _globals['_COUNTERDESCRIPTOR_BUILTINCOUNTERTYPE']._serialized_end=210919
-  _globals['_COUNTERDESCRIPTOR_UNIT']._serialized_start=210921
-  _globals['_COUNTERDESCRIPTOR_UNIT']._serialized_end=211004
-  _globals['_STATEDESCRIPTOR']._serialized_start=211006
-  _globals['_STATEDESCRIPTOR']._serialized_end=211023
-  _globals['_TRACKDESCRIPTOR']._serialized_start=211026
-  _globals['_TRACKDESCRIPTOR']._serialized_end=212442
-  _globals['_TRACKDESCRIPTOR_CHILDTRACKSORDERING']._serialized_start=211949
-  _globals['_TRACKDESCRIPTOR_CHILDTRACKSORDERING']._serialized_end=212035
-  _globals['_TRACKDESCRIPTOR_SIBLINGMERGEBEHAVIOR']._serialized_start=212038
-  _globals['_TRACKDESCRIPTOR_SIBLINGMERGEBEHAVIOR']._serialized_end=212224
-  _globals['_TRACKDESCRIPTOR_PROCESSORDERING']._serialized_start=212226
-  _globals['_TRACKDESCRIPTOR_PROCESSORDERING']._serialized_end=212308
-  _globals['_TRACKDESCRIPTOR_THREADORDERING']._serialized_start=212310
-  _globals['_TRACKDESCRIPTOR_THREADORDERING']._serialized_end=212389
-  _globals['_TRANSLATIONTABLE']._serialized_start=212445
-  _globals['_TRANSLATIONTABLE']._serialized_end=212938
-  _globals['_CHROMEHISTORGRAMTRANSLATIONTABLE']._serialized_start=212941
-  _globals['_CHROMEHISTORGRAMTRANSLATIONTABLE']._serialized_end=213115
-  _globals['_CHROMEHISTORGRAMTRANSLATIONTABLE_HASHTONAMEENTRY']._serialized_start=213066
-  _globals['_CHROMEHISTORGRAMTRANSLATIONTABLE_HASHTONAMEENTRY']._serialized_end=213115
-  _globals['_CHROMEUSEREVENTTRANSLATIONTABLE']._serialized_start=213118
-  _globals['_CHROMEUSEREVENTTRANSLATIONTABLE']._serialized_end=213309
-  _globals['_CHROMEUSEREVENTTRANSLATIONTABLE_ACTIONHASHTONAMEENTRY']._serialized_start=213254
-  _globals['_CHROMEUSEREVENTTRANSLATIONTABLE_ACTIONHASHTONAMEENTRY']._serialized_end=213309
-  _globals['_CHROMEPERFORMANCEMARKTRANSLATIONTABLE']._serialized_start=213312
-  _globals['_CHROMEPERFORMANCEMARKTRANSLATIONTABLE']._serialized_end=213667
-  _globals['_CHROMEPERFORMANCEMARKTRANSLATIONTABLE_SITEHASHTONAMEENTRY']._serialized_start=213559
-  _globals['_CHROMEPERFORMANCEMARKTRANSLATIONTABLE_SITEHASHTONAMEENTRY']._serialized_end=213612
-  _globals['_CHROMEPERFORMANCEMARKTRANSLATIONTABLE_MARKHASHTONAMEENTRY']._serialized_start=213614
-  _globals['_CHROMEPERFORMANCEMARKTRANSLATIONTABLE_MARKHASHTONAMEENTRY']._serialized_end=213667
-  _globals['_SLICENAMETRANSLATIONTABLE']._serialized_start=213670
-  _globals['_SLICENAMETRANSLATIONTABLE']._serialized_end=213864
-  _globals['_SLICENAMETRANSLATIONTABLE_RAWTODEOBFUSCATEDNAMEENTRY']._serialized_start=213804
-  _globals['_SLICENAMETRANSLATIONTABLE_RAWTODEOBFUSCATEDNAMEENTRY']._serialized_end=213864
-  _globals['_PROCESSTRACKNAMETRANSLATIONTABLE']._serialized_start=213867
-  _globals['_PROCESSTRACKNAMETRANSLATIONTABLE']._serialized_end=214075
-  _globals['_PROCESSTRACKNAMETRANSLATIONTABLE_RAWTODEOBFUSCATEDNAMEENTRY']._serialized_start=213804
-  _globals['_PROCESSTRACKNAMETRANSLATIONTABLE_RAWTODEOBFUSCATEDNAMEENTRY']._serialized_end=213864
-  _globals['_CHROMESTUDYTRANSLATIONTABLE']._serialized_start=214078
-  _globals['_CHROMESTUDYTRANSLATIONTABLE']._serialized_end=214242
-  _globals['_CHROMESTUDYTRANSLATIONTABLE_HASHTONAMEENTRY']._serialized_start=213066
-  _globals['_CHROMESTUDYTRANSLATIONTABLE_HASHTONAMEENTRY']._serialized_end=213115
-  _globals['_TRIGGER']._serialized_start=214244
-  _globals['_TRIGGER']._serialized_end=214351
-  _globals['_UISTATE']._serialized_start=214354
-  _globals['_UISTATE']._serialized_end=214551
-  _globals['_UISTATE_HIGHLIGHTPROCESS']._serialized_start=214487
-  _globals['_UISTATE_HIGHLIGHTPROCESS']._serialized_end=214551
-  _globals['_TRACEPACKET']._serialized_start=214554
-  _globals['_TRACEPACKET']._serialized_end=221133
-  _globals['_TRACEPACKET_PROTOVMS']._serialized_start=220308
-  _globals['_TRACEPACKET_PROTOVMS']._serialized_end=220533
-  _globals['_TRACEPACKET_PROTOVMS_INSTANCE']._serialized_start=220387
-  _globals['_TRACEPACKET_PROTOVMS_INSTANCE']._serialized_end=220533
-  _globals['_TRACEPACKET_SEQUENCEFLAGS']._serialized_start=220535
-  _globals['_TRACEPACKET_SEQUENCEFLAGS']._serialized_end=220639
-  _globals['_TRACEPACKET_DATALOSSREASON']._serialized_start=220642
-  _globals['_TRACEPACKET_DATALOSSREASON']._serialized_end=220946
-  _globals['_TRACE']._serialized_start=221135
-  _globals['_TRACE']._serialized_end=221188
+  _globals['_TRACESTATS_WRITERSTATS']._serialized_end=35036
+  _globals['_TRACESTATS_FILTERSTATS']._serialized_start=35039
+  _globals['_TRACESTATS_FILTERSTATS']._serialized_end=35193
+  _globals['_TRACESTATS_FINALFLUSHOUTCOME']._serialized_start=35195
+  _globals['_TRACESTATS_FINALFLUSHOUTCOME']._serialized_end=35294
+  _globals['_ANDROIDAFLAGS']._serialized_start=35297
+  _globals['_ANDROIDAFLAGS']._serialized_end=36279
+  _globals['_ANDROIDAFLAGS_FLAG']._serialized_start=35382
+  _globals['_ANDROIDAFLAGS_FLAG']._serialized_end=35768
+  _globals['_ANDROIDAFLAGS_FLAGPERMISSION']._serialized_start=35770
+  _globals['_ANDROIDAFLAGS_FLAGPERMISSION']._serialized_end=35882
+  _globals['_ANDROIDAFLAGS_VALUEPICKEDFROM']._serialized_start=35885
+  _globals['_ANDROIDAFLAGS_VALUEPICKEDFROM']._serialized_end=36027
+  _globals['_ANDROIDAFLAGS_FLAGSTORAGEBACKEND']._serialized_start=36030
+  _globals['_ANDROIDAFLAGS_FLAGSTORAGEBACKEND']._serialized_end=36194
+  _globals['_ANDROIDAFLAGS_FLAGTYPE']._serialized_start=36196
+  _globals['_ANDROIDAFLAGS_FLAGTYPE']._serialized_end=36279
+  _globals['_ANDROIDGAMEINTERVENTIONLIST']._serialized_start=36282
+  _globals['_ANDROIDGAMEINTERVENTIONLIST']._serialized_end=36681
+  _globals['_ANDROIDGAMEINTERVENTIONLIST_GAMEMODEINFO']._serialized_start=36439
+  _globals['_ANDROIDGAMEINTERVENTIONLIST_GAMEMODEINFO']._serialized_end=36529
+  _globals['_ANDROIDGAMEINTERVENTIONLIST_GAMEPACKAGEINFO']._serialized_start=36532
+  _globals['_ANDROIDGAMEINTERVENTIONLIST_GAMEPACKAGEINFO']._serialized_end=36681
+  _globals['_ANDROIDLOGPACKET']._serialized_start=36684
+  _globals['_ANDROIDLOGPACKET']._serialized_end=37246
+  _globals['_ANDROIDLOGPACKET_LOGEVENT']._serialized_start=36821
+  _globals['_ANDROIDLOGPACKET_LOGEVENT']._serialized_end=37177
+  _globals['_ANDROIDLOGPACKET_LOGEVENT_ARG']._serialized_start=37081
+  _globals['_ANDROIDLOGPACKET_LOGEVENT_ARG']._serialized_end=37177
+  _globals['_ANDROIDLOGPACKET_STATS']._serialized_start=37179
+  _globals['_ANDROIDLOGPACKET_STATS']._serialized_end=37246
+  _globals['_ANDROIDSYSTEMPROPERTY']._serialized_start=37249
+  _globals['_ANDROIDSYSTEMPROPERTY']._serialized_end=37388
+  _globals['_ANDROIDSYSTEMPROPERTY_PROPERTYVALUE']._serialized_start=37344
+  _globals['_ANDROIDSYSTEMPROPERTY_PROPERTYVALUE']._serialized_end=37388
+  _globals['_CPUPERUIDDATA']._serialized_start=37390
+  _globals['_CPUPERUIDDATA']._serialized_end=37472
+  _globals['_GRAPHICSFRAMEEVENT']._serialized_start=37475
+  _globals['_GRAPHICSFRAMEEVENT']._serialized_end=37972
+  _globals['_GRAPHICSFRAMEEVENT_BUFFEREVENT']._serialized_start=37569
+  _globals['_GRAPHICSFRAMEEVENT_BUFFEREVENT']._serialized_end=37731
+  _globals['_GRAPHICSFRAMEEVENT_BUFFEREVENTTYPE']._serialized_start=37734
+  _globals['_GRAPHICSFRAMEEVENT_BUFFEREVENTTYPE']._serialized_end=37972
+  _globals['_INITIALDISPLAYSTATE']._serialized_start=37974
+  _globals['_INITIALDISPLAYSTATE']._serialized_end=38038
+  _globals['_KERNELWAKELOCKDATA']._serialized_start=38041
+  _globals['_KERNELWAKELOCKDATA']._serialized_end=38419
+  _globals['_KERNELWAKELOCKDATA_WAKELOCK']._serialized_start=38204
+  _globals['_KERNELWAKELOCKDATA_WAKELOCK']._serialized_end=38419
+  _globals['_KERNELWAKELOCKDATA_WAKELOCK_TYPE']._serialized_start=38334
+  _globals['_KERNELWAKELOCKDATA_WAKELOCK_TYPE']._serialized_end=38419
+  _globals['_PACKAGESLIST']._serialized_start=38422
+  _globals['_PACKAGESLIST']._serialized_end=38676
+  _globals['_PACKAGESLIST_PACKAGEINFO']._serialized_start=38541
+  _globals['_PACKAGESLIST_PACKAGEINFO']._serialized_end=38676
+  _globals['_PIXELMODEMEVENTS']._serialized_start=38678
+  _globals['_PIXELMODEMEVENTS']._serialized_end=38738
+  _globals['_PIXELMODEMTOKENDATABASE']._serialized_start=38740
+  _globals['_PIXELMODEMTOKENDATABASE']._serialized_end=38783
+  _globals['_RECOVEREDTRACEINFO']._serialized_start=38786
+  _globals['_RECOVEREDTRACEINFO']._serialized_end=38989
+  _globals['_RECOVEREDTRACEINFO_REASON']._serialized_start=38927
+  _globals['_RECOVEREDTRACEINFO_REASON']._serialized_end=38989
+  _globals['_ANDROIDUSERLIST']._serialized_start=38992
+  _globals['_ANDROIDUSERLIST']._serialized_end=39121
+  _globals['_ANDROIDUSERLIST_USERINFO']._serialized_start=39084
+  _globals['_ANDROIDUSERLIST_USERINFO']._serialized_end=39121
+  _globals['_CHROMEBENCHMARKMETADATA']._serialized_start=39124
+  _globals['_CHROMEBENCHMARKMETADATA']._serialized_end=39366
+  _globals['_CHROMEMETADATAPACKET']._serialized_start=39369
+  _globals['_CHROMEMETADATAPACKET']._serialized_end=39729
+  _globals['_CHROMEMETADATAPACKET_FINCHHASH']._serialized_start=39689
+  _globals['_CHROMEMETADATAPACKET_FINCHHASH']._serialized_end=39729
+  _globals['_BACKGROUNDTRACINGMETADATA']._serialized_start=39732
+  _globals['_BACKGROUNDTRACINGMETADATA']._serialized_end=40777
+  _globals['_BACKGROUNDTRACINGMETADATA_TRIGGERRULE']._serialized_start=39948
+  _globals['_BACKGROUNDTRACINGMETADATA_TRIGGERRULE']._serialized_end=40777
+  _globals['_BACKGROUNDTRACINGMETADATA_TRIGGERRULE_HISTOGRAMRULE']._serialized_start=40252
+  _globals['_BACKGROUNDTRACINGMETADATA_TRIGGERRULE_HISTOGRAMRULE']._serialized_end=40358
+  _globals['_BACKGROUNDTRACINGMETADATA_TRIGGERRULE_NAMEDRULE']._serialized_start=40361
+  _globals['_BACKGROUNDTRACINGMETADATA_TRIGGERRULE_NAMEDRULE']._serialized_end=40639
+  _globals['_BACKGROUNDTRACINGMETADATA_TRIGGERRULE_NAMEDRULE_EVENTTYPE']._serialized_start=40506
+  _globals['_BACKGROUNDTRACINGMETADATA_TRIGGERRULE_NAMEDRULE_EVENTTYPE']._serialized_end=40639
+  _globals['_BACKGROUNDTRACINGMETADATA_TRIGGERRULE_TRIGGERTYPE']._serialized_start=40642
+  _globals['_BACKGROUNDTRACINGMETADATA_TRIGGERRULE_TRIGGERTYPE']._serialized_end=40777
+  _globals['_CHROMETRACEDVALUE']._serialized_start=40780
+  _globals['_CHROMETRACEDVALUE']._serialized_end=41119
+  _globals['_CHROMETRACEDVALUE_NESTEDTYPE']._serialized_start=41086
+  _globals['_CHROMETRACEDVALUE_NESTEDTYPE']._serialized_end=41119
+  _globals['_CHROMESTRINGTABLEENTRY']._serialized_start=41121
+  _globals['_CHROMESTRINGTABLEENTRY']._serialized_end=41175
+  _globals['_CHROMETRACEEVENT']._serialized_start=41178
+  _globals['_CHROMETRACEEVENT']._serialized_end=41819
+  _globals['_CHROMETRACEEVENT_ARG']._serialized_start=41551
+  _globals['_CHROMETRACEEVENT_ARG']._serialized_end=41819
+  _globals['_CHROMEMETADATA']._serialized_start=41822
+  _globals['_CHROMEMETADATA']._serialized_end=41950
+  _globals['_CHROMELEGACYJSONTRACE']._serialized_start=41953
+  _globals['_CHROMELEGACYJSONTRACE']._serialized_end=42101
+  _globals['_CHROMELEGACYJSONTRACE_TRACETYPE']._serialized_start=42056
+  _globals['_CHROMELEGACYJSONTRACE_TRACETYPE']._serialized_end=42101
+  _globals['_CHROMEEVENTBUNDLE']._serialized_start=42104
+  _globals['_CHROMEEVENTBUNDLE']._serialized_end=42399
+  _globals['_CHROMETRIGGER']._serialized_start=42401
+  _globals['_CHROMETRIGGER']._serialized_end=42482
+  _globals['_V8STRING']._serialized_start=42484
+  _globals['_V8STRING']._serialized_end=42570
+  _globals['_INTERNEDV8STRING']._serialized_start=42572
+  _globals['_INTERNEDV8STRING']._serialized_end=42679
+  _globals['_INTERNEDV8JSSCRIPT']._serialized_start=42682
+  _globals['_INTERNEDV8JSSCRIPT']._serialized_end=43007
+  _globals['_INTERNEDV8JSSCRIPT_TYPE']._serialized_start=42877
+  _globals['_INTERNEDV8JSSCRIPT_TYPE']._serialized_end=43007
+  _globals['_INTERNEDV8WASMSCRIPT']._serialized_start=43009
+  _globals['_INTERNEDV8WASMSCRIPT']._serialized_end=43096
+  _globals['_INTERNEDV8JSFUNCTION']._serialized_start=43099
+  _globals['_INTERNEDV8JSFUNCTION']._serialized_end=44208
+  _globals['_INTERNEDV8JSFUNCTION_KIND']._serialized_start=43326
+  _globals['_INTERNEDV8JSFUNCTION_KIND']._serialized_end=44208
+  _globals['_INTERNEDV8ISOLATE']._serialized_start=44211
+  _globals['_INTERNEDV8ISOLATE']._serialized_end=44538
+  _globals['_INTERNEDV8ISOLATE_CODERANGE']._serialized_start=44419
+  _globals['_INTERNEDV8ISOLATE_CODERANGE']._serialized_end=44538
+  _globals['_V8JSCODE']._serialized_start=44541
+  _globals['_V8JSCODE']._serialized_end=45013
+  _globals['_V8JSCODE_TIER']._serialized_start=44863
+  _globals['_V8JSCODE_TIER']._serialized_end=44983
+  _globals['_V8INTERNALCODE']._serialized_start=45016
+  _globals['_V8INTERNALCODE']._serialized_end=45497
+  _globals['_V8INTERNALCODE_TYPE']._serialized_start=45239
+  _globals['_V8INTERNALCODE_TYPE']._serialized_end=45497
+  _globals['_V8WASMCODE']._serialized_start=45500
+  _globals['_V8WASMCODE']._serialized_end=45823
+  _globals['_V8WASMCODE_TIER']._serialized_start=45762
+  _globals['_V8WASMCODE_TIER']._serialized_end=45823
+  _globals['_V8REGEXPCODE']._serialized_start=45826
+  _globals['_V8REGEXPCODE']._serialized_end=46002
+  _globals['_V8CODEMOVE']._serialized_start=46005
+  _globals['_V8CODEMOVE']._serialized_end=46230
+  _globals['_V8CODEDEFAULTS']._serialized_start=46232
+  _globals['_V8CODEDEFAULTS']._serialized_end=46261
+  _globals['_CLOCKSNAPSHOT']._serialized_start=46264
+  _globals['_CLOCKSNAPSHOT']._serialized_end=46666
+  _globals['_CLOCKSNAPSHOT_CLOCK']._serialized_start=46396
+  _globals['_CLOCKSNAPSHOT_CLOCK']._serialized_end=46666
+  _globals['_CLOCKSNAPSHOT_CLOCK_BUILTINCLOCKS']._serialized_start=46495
+  _globals['_CLOCKSNAPSHOT_CLOCK_BUILTINCLOCKS']._serialized_end=46666
+  _globals['_CSWITCHETWEVENT']._serialized_start=46669
+  _globals['_CSWITCHETWEVENT']._serialized_end=48287
+  _globals['_CSWITCHETWEVENT_OLDTHREADWAITREASON']._serialized_start=47245
+  _globals['_CSWITCHETWEVENT_OLDTHREADWAITREASON']._serialized_end=47990
+  _globals['_CSWITCHETWEVENT_OLDTHREADWAITMODE']._serialized_start=47992
+  _globals['_CSWITCHETWEVENT_OLDTHREADWAITMODE']._serialized_end=48043
+  _globals['_CSWITCHETWEVENT_OLDTHREADSTATE']._serialized_start=48046
+  _globals['_CSWITCHETWEVENT_OLDTHREADSTATE']._serialized_end=48181
+  _globals['_READYTHREADETWEVENT']._serialized_start=48290
+  _globals['_READYTHREADETWEVENT']._serialized_end=48810
+  _globals['_READYTHREADETWEVENT_ADJUSTREASON']._serialized_start=48549
+  _globals['_READYTHREADETWEVENT_ADJUSTREASON']._serialized_end=48637
+  _globals['_READYTHREADETWEVENT_TRACEFLAG']._serialized_start=48639
+  _globals['_READYTHREADETWEVENT_TRACEFLAG']._serialized_end=48761
+  _globals['_MEMINFOETWEVENT']._serialized_start=48813
+  _globals['_MEMINFOETWEVENT']._serialized_end=49213
+  _globals['_FILEIOCREATEETWEVENT']._serialized_start=49216
+  _globals['_FILEIOCREATEETWEVENT']._serialized_end=49380
+  _globals['_FILEIODIRENUMETWEVENT']._serialized_start=49383
+  _globals['_FILEIODIRENUMETWEVENT']._serialized_end=49567
+  _globals['_FILEIOINFOETWEVENT']._serialized_start=49570
+  _globals['_FILEIOINFOETWEVENT']._serialized_end=49716
+  _globals['_FILEIOREADWRITEETWEVENT']._serialized_start=49719
+  _globals['_FILEIOREADWRITEETWEVENT']._serialized_end=49881
+  _globals['_FILEIOSIMPLEOPETWEVENT']._serialized_start=49883
+  _globals['_FILEIOSIMPLEOPETWEVENT']._serialized_end=49993
+  _globals['_FILEIOOPENDETWEVENT']._serialized_start=49995
+  _globals['_FILEIOOPENDETWEVENT']._serialized_end=50072
+  _globals['_FILEIOPATHOPERATIONETWEVENT']._serialized_start=50075
+  _globals['_FILEIOPATHOPERATIONETWEVENT']._serialized_end=50249
+  _globals['_STACKWALKETWEVENT']._serialized_start=50251
+  _globals['_STACKWALKETWEVENT']._serialized_end=50310
+  _globals['_DISKIOETWEVENT']._serialized_start=50313
+  _globals['_DISKIOETWEVENT']._serialized_end=50517
+  _globals['_ETWTRACEEVENT']._serialized_start=50520
+  _globals['_ETWTRACEEVENT']._serialized_end=51355
+  _globals['_ETWTRACEEVENTBUNDLE']._serialized_start=51357
+  _globals['_ETWTRACEEVENTBUNDLE']._serialized_end=51438
+  _globals['_FILEDESCRIPTORSET']._serialized_start=51440
+  _globals['_FILEDESCRIPTORSET']._serialized_end=51511
+  _globals['_FILEDESCRIPTORPROTO']._serialized_start=51514
+  _globals['_FILEDESCRIPTORPROTO']._serialized_end=51833
+  _globals['_DESCRIPTORPROTO']._serialized_start=51836
+  _globals['_DESCRIPTORPROTO']._serialized_end=52302
+  _globals['_DESCRIPTORPROTO_RESERVEDRANGE']._serialized_start=52247
+  _globals['_DESCRIPTORPROTO_RESERVEDRANGE']._serialized_end=52290
+  _globals['_UNINTERPRETEDOPTION']._serialized_start=52305
+  _globals['_UNINTERPRETEDOPTION']._serialized_end=52591
+  _globals['_UNINTERPRETEDOPTION_NAMEPART']._serialized_start=52540
+  _globals['_UNINTERPRETEDOPTION_NAMEPART']._serialized_end=52591
+  _globals['_FIELDOPTIONS']._serialized_start=52593
+  _globals['_FIELDOPTIONS']._serialized_end=52692
+  _globals['_FIELDDESCRIPTORPROTO']._serialized_start=52695
+  _globals['_FIELDDESCRIPTORPROTO']._serialized_end=53382
+  _globals['_FIELDDESCRIPTORPROTO_TYPE']._serialized_start=52997
+  _globals['_FIELDDESCRIPTORPROTO_TYPE']._serialized_end=53307
+  _globals['_FIELDDESCRIPTORPROTO_LABEL']._serialized_start=53309
+  _globals['_FIELDDESCRIPTORPROTO_LABEL']._serialized_end=53376
+  _globals['_ONEOFDESCRIPTORPROTO']._serialized_start=53384
+  _globals['_ONEOFDESCRIPTORPROTO']._serialized_end=53468
+  _globals['_ENUMDESCRIPTORPROTO']._serialized_start=53471
+  _globals['_ENUMDESCRIPTORPROTO']._serialized_end=53599
+  _globals['_ENUMVALUEDESCRIPTORPROTO']._serialized_start=53601
+  _globals['_ENUMVALUEDESCRIPTORPROTO']._serialized_end=53663
+  _globals['_ONEOFOPTIONS']._serialized_start=53665
+  _globals['_ONEOFOPTIONS']._serialized_end=53698
+  _globals['_EXTENSIONDESCRIPTOR']._serialized_start=53701
+  _globals['_EXTENSIONDESCRIPTOR']._serialized_end=53846
+  _globals['_INODEFILEMAP']._serialized_start=53849
+  _globals['_INODEFILEMAP']._serialized_end=54113
+  _globals['_INODEFILEMAP_ENTRY']._serialized_start=53967
+  _globals['_INODEFILEMAP_ENTRY']._serialized_end=54113
+  _globals['_INODEFILEMAP_ENTRY_TYPE']._serialized_start=54069
+  _globals['_INODEFILEMAP_ENTRY_TYPE']._serialized_end=54113
+  _globals['_ANDROIDFSDATAREADENDFTRACEEVENT']._serialized_start=54115
+  _globals['_ANDROIDFSDATAREADENDFTRACEEVENT']._serialized_end=54192
+  _globals['_ANDROIDFSDATAREADSTARTFTRACEEVENT']._serialized_start=54195
+  _globals['_ANDROIDFSDATAREADSTARTFTRACEEVENT']._serialized_end=54337
+  _globals['_ANDROIDFSDATAWRITEENDFTRACEEVENT']._serialized_start=54339
+  _globals['_ANDROIDFSDATAWRITEENDFTRACEEVENT']._serialized_end=54417
+  _globals['_ANDROIDFSDATAWRITESTARTFTRACEEVENT']._serialized_start=54420
+  _globals['_ANDROIDFSDATAWRITESTARTFTRACEEVENT']._serialized_end=54563
+  _globals['_ANDROIDFSFSYNCENDFTRACEEVENT']._serialized_start=54565
+  _globals['_ANDROIDFSFSYNCENDFTRACEEVENT']._serialized_end=54639
+  _globals['_ANDROIDFSFSYNCSTARTFTRACEEVENT']._serialized_start=54641
+  _globals['_ANDROIDFSFSYNCSTARTFTRACEEVENT']._serialized_end=54749
+  _globals['_BCLIRQTRIGGERFTRACEEVENT']._serialized_start=54752
+  _globals['_BCLIRQTRIGGERFTRACEEVENT']._serialized_end=54941
+  _globals['_BINDERTRANSACTIONFTRACEEVENT']._serialized_start=54944
+  _globals['_BINDERTRANSACTIONFTRACEEVENT']._serialized_end=55093
+  _globals['_BINDERTRANSACTIONRECEIVEDFTRACEEVENT']._serialized_start=55095
+  _globals['_BINDERTRANSACTIONRECEIVEDFTRACEEVENT']._serialized_end=55151
+  _globals['_BINDERSETPRIORITYFTRACEEVENT']._serialized_start=55153
+  _globals['_BINDERSETPRIORITYFTRACEEVENT']._serialized_end=55271
+  _globals['_BINDERLOCKFTRACEEVENT']._serialized_start=55273
+  _globals['_BINDERLOCKFTRACEEVENT']._serialized_end=55309
+  _globals['_BINDERLOCKEDFTRACEEVENT']._serialized_start=55311
+  _globals['_BINDERLOCKEDFTRACEEVENT']._serialized_end=55349
+  _globals['_BINDERUNLOCKFTRACEEVENT']._serialized_start=55351
+  _globals['_BINDERUNLOCKFTRACEEVENT']._serialized_end=55389
+  _globals['_BINDERTRANSACTIONALLOCBUFFTRACEEVENT']._serialized_start=55391
+  _globals['_BINDERTRANSACTIONALLOCBUFFTRACEEVENT']._serialized_end=55516
+  _globals['_BINDERCOMMANDFTRACEEVENT']._serialized_start=55518
+  _globals['_BINDERCOMMANDFTRACEEVENT']._serialized_end=55557
+  _globals['_BINDERRETURNFTRACEEVENT']._serialized_start=55559
+  _globals['_BINDERRETURNFTRACEEVENT']._serialized_end=55597
+  _globals['_BLOCKRQISSUEFTRACEEVENT']._serialized_start=55600
+  _globals['_BLOCKRQISSUEFTRACEEVENT']._serialized_end=55729
+  _globals['_BLOCKBIOBACKMERGEFTRACEEVENT']._serialized_start=55731
+  _globals['_BLOCKBIOBACKMERGEFTRACEEVENT']._serialized_end=55837
+  _globals['_BLOCKBIOBOUNCEFTRACEEVENT']._serialized_start=55839
+  _globals['_BLOCKBIOBOUNCEFTRACEEVENT']._serialized_end=55942
+  _globals['_BLOCKBIOCOMPLETEFTRACEEVENT']._serialized_start=55944
+  _globals['_BLOCKBIOCOMPLETEFTRACEEVENT']._serialized_end=56050
+  _globals['_BLOCKBIOFRONTMERGEFTRACEEVENT']._serialized_start=56052
+  _globals['_BLOCKBIOFRONTMERGEFTRACEEVENT']._serialized_end=56159
+  _globals['_BLOCKBIOQUEUEFTRACEEVENT']._serialized_start=56161
+  _globals['_BLOCKBIOQUEUEFTRACEEVENT']._serialized_end=56263
+  _globals['_BLOCKBIOREMAPFTRACEEVENT']._serialized_start=56265
+  _globals['_BLOCKBIOREMAPFTRACEEVENT']._serialized_end=56390
+  _globals['_BLOCKDIRTYBUFFERFTRACEEVENT']._serialized_start=56392
+  _globals['_BLOCKDIRTYBUFFERFTRACEEVENT']._serialized_end=56464
+  _globals['_BLOCKGETRQFTRACEEVENT']._serialized_start=56466
+  _globals['_BLOCKGETRQFTRACEEVENT']._serialized_end=56565
+  _globals['_BLOCKPLUGFTRACEEVENT']._serialized_start=56567
+  _globals['_BLOCKPLUGFTRACEEVENT']._serialized_end=56603
+  _globals['_BLOCKRQABORTFTRACEEVENT']._serialized_start=56605
+  _globals['_BLOCKRQABORTFTRACEEVENT']._serialized_end=56721
+  _globals['_BLOCKRQCOMPLETEFTRACEEVENT']._serialized_start=56724
+  _globals['_BLOCKRQCOMPLETEFTRACEEVENT']._serialized_end=56858
+  _globals['_BLOCKRQINSERTFTRACEEVENT']._serialized_start=56861
+  _globals['_BLOCKRQINSERTFTRACEEVENT']._serialized_end=56991
+  _globals['_BLOCKRQREMAPFTRACEEVENT']._serialized_start=56994
+  _globals['_BLOCKRQREMAPFTRACEEVENT']._serialized_end=57135
+  _globals['_BLOCKRQREQUEUEFTRACEEVENT']._serialized_start=57137
+  _globals['_BLOCKRQREQUEUEFTRACEEVENT']._serialized_end=57255
+  _globals['_BLOCKSLEEPRQFTRACEEVENT']._serialized_start=57257
+  _globals['_BLOCKSLEEPRQFTRACEEVENT']._serialized_end=57358
+  _globals['_BLOCKSPLITFTRACEEVENT']._serialized_start=57360
+  _globals['_BLOCKSPLITFTRACEEVENT']._serialized_end=57460
+  _globals['_BLOCKTOUCHBUFFERFTRACEEVENT']._serialized_start=57462
+  _globals['_BLOCKTOUCHBUFFERFTRACEEVENT']._serialized_end=57534
+  _globals['_BLOCKUNPLUGFTRACEEVENT']._serialized_start=57536
+  _globals['_BLOCKUNPLUGFTRACEEVENT']._serialized_end=57589
+  _globals['_BLOCKIOSTARTFTRACEEVENT']._serialized_start=57592
+  _globals['_BLOCKIOSTARTFTRACEEVENT']._serialized_end=57737
+  _globals['_BLOCKIODONEFTRACEEVENT']._serialized_start=57740
+  _globals['_BLOCKIODONEFTRACEEVENT']._serialized_end=57884
+  _globals['_CGROUPATTACHTASKFTRACEEVENT']._serialized_start=57887
+  _globals['_CGROUPATTACHTASKFTRACEEVENT']._serialized_end=58029
+  _globals['_CGROUPMKDIRFTRACEEVENT']._serialized_start=58031
+  _globals['_CGROUPMKDIRFTRACEEVENT']._serialized_end=58125
+  _globals['_CGROUPREMOUNTFTRACEEVENT']._serialized_start=58127
+  _globals['_CGROUPREMOUNTFTRACEEVENT']._serialized_end=58198
+  _globals['_CGROUPRMDIRFTRACEEVENT']._serialized_start=58200
+  _globals['_CGROUPRMDIRFTRACEEVENT']._serialized_end=58294
+  _globals['_CGROUPTRANSFERTASKSFTRACEEVENT']._serialized_start=58297
+  _globals['_CGROUPTRANSFERTASKSFTRACEEVENT']._serialized_end=58442
+  _globals['_CGROUPDESTROYROOTFTRACEEVENT']._serialized_start=58444
+  _globals['_CGROUPDESTROYROOTFTRACEEVENT']._serialized_end=58519
+  _globals['_CGROUPRELEASEFTRACEEVENT']._serialized_start=58521
+  _globals['_CGROUPRELEASEFTRACEEVENT']._serialized_end=58617
+  _globals['_CGROUPRENAMEFTRACEEVENT']._serialized_start=58619
+  _globals['_CGROUPRENAMEFTRACEEVENT']._serialized_end=58714
+  _globals['_CGROUPSETUPROOTFTRACEEVENT']._serialized_start=58716
+  _globals['_CGROUPSETUPROOTFTRACEEVENT']._serialized_end=58789
+  _globals['_CLKENABLEFTRACEEVENT']._serialized_start=58791
+  _globals['_CLKENABLEFTRACEEVENT']._serialized_end=58827
+  _globals['_CLKDISABLEFTRACEEVENT']._serialized_start=58829
+  _globals['_CLKDISABLEFTRACEEVENT']._serialized_end=58866
+  _globals['_CLKSETRATEFTRACEEVENT']._serialized_start=58868
+  _globals['_CLKSETRATEFTRACEEVENT']._serialized_end=58919
+  _globals['_CMAALLOCSTARTFTRACEEVENT']._serialized_start=58921
+  _globals['_CMAALLOCSTARTFTRACEEVENT']._serialized_end=58991
+  _globals['_CMAALLOCINFOFTRACEEVENT']._serialized_start=58994
+  _globals['_CMAALLOCINFOFTRACEEVENT']._serialized_end=59190
+  _globals['_CMAALLOCFINISHFTRACEEVENT']._serialized_start=59192
+  _globals['_CMAALLOCFINISHFTRACEEVENT']._serialized_end=59307
+  _globals['_MMCOMPACTIONBEGINFTRACEEVENT']._serialized_start=59309
+  _globals['_MMCOMPACTIONBEGINFTRACEEVENT']._serialized_end=59430
+  _globals['_MMCOMPACTIONDEFERCOMPACTIONFTRACEEVENT']._serialized_start=59433
+  _globals['_MMCOMPACTIONDEFERCOMPACTIONFTRACEEVENT']._serialized_end=59577
+  _globals['_MMCOMPACTIONDEFERREDFTRACEEVENT']._serialized_start=59580
+  _globals['_MMCOMPACTIONDEFERREDFTRACEEVENT']._serialized_end=59717
+  _globals['_MMCOMPACTIONDEFERRESETFTRACEEVENT']._serialized_start=59720
+  _globals['_MMCOMPACTIONDEFERRESETFTRACEEVENT']._serialized_end=59859
+  _globals['_MMCOMPACTIONENDFTRACEEVENT']._serialized_start=59862
+  _globals['_MMCOMPACTIONENDFTRACEEVENT']._serialized_end=59997
+  _globals['_MMCOMPACTIONFINISHEDFTRACEEVENT']._serialized_start=59999
+  _globals['_MMCOMPACTIONFINISHEDFTRACEEVENT']._serialized_end=60086
+  _globals['_MMCOMPACTIONISOLATEFREEPAGESFTRACEEVENT']._serialized_start=60088
+  _globals['_MMCOMPACTIONISOLATEFREEPAGESFTRACEEVENT']._serialized_end=60203
+  _globals['_MMCOMPACTIONISOLATEMIGRATEPAGESFTRACEEVENT']._serialized_start=60205
+  _globals['_MMCOMPACTIONISOLATEMIGRATEPAGESFTRACEEVENT']._serialized_end=60323
+  _globals['_MMCOMPACTIONKCOMPACTDSLEEPFTRACEEVENT']._serialized_start=60325
+  _globals['_MMCOMPACTIONKCOMPACTDSLEEPFTRACEEVENT']._serialized_end=60377
+  _globals['_MMCOMPACTIONKCOMPACTDWAKEFTRACEEVENT']._serialized_start=60379
+  _globals['_MMCOMPACTIONKCOMPACTDWAKEFTRACEEVENT']._serialized_end=60493
+  _globals['_MMCOMPACTIONMIGRATEPAGESFTRACEEVENT']._serialized_start=60495
+  _globals['_MMCOMPACTIONMIGRATEPAGESFTRACEEVENT']._serialized_end=60572
+  _globals['_MMCOMPACTIONSUITABLEFTRACEEVENT']._serialized_start=60574
+  _globals['_MMCOMPACTIONSUITABLEFTRACEEVENT']._serialized_end=60661
+  _globals['_MMCOMPACTIONTRYTOCOMPACTPAGESFTRACEEVENT']._serialized_start=60663
+  _globals['_MMCOMPACTIONTRYTOCOMPACTPAGESFTRACEEVENT']._serialized_end=60766
+  _globals['_MMCOMPACTIONWAKEUPKCOMPACTDFTRACEEVENT']._serialized_start=60768
+  _globals['_MMCOMPACTIONWAKEUPKCOMPACTDFTRACEEVENT']._serialized_end=60884
+  _globals['_PARAMSETVALUECPMFTRACEEVENT']._serialized_start=60886
+  _globals['_PARAMSETVALUECPMFTRACEEVENT']._serialized_end=60963
+  _globals['_CPUHPEXITFTRACEEVENT']._serialized_start=60965
+  _globals['_CPUHPEXITFTRACEEVENT']._serialized_end=61041
+  _globals['_CPUHPMULTIENTERFTRACEEVENT']._serialized_start=61043
+  _globals['_CPUHPMULTIENTERFTRACEEVENT']._serialized_end=61126
+  _globals['_CPUHPENTERFTRACEEVENT']._serialized_start=61128
+  _globals['_CPUHPENTERFTRACEEVENT']._serialized_end=61206
+  _globals['_CPUHPLATENCYFTRACEEVENT']._serialized_start=61208
+  _globals['_CPUHPLATENCYFTRACEEVENT']._serialized_end=61288
+  _globals['_CPUHPPAUSEFTRACEEVENT']._serialized_start=61290
+  _globals['_CPUHPPAUSEFTRACEEVENT']._serialized_end=61377
+  _globals['_CROSECSENSORHUBDATAFTRACEEVENT']._serialized_start=61380
+  _globals['_CROSECSENSORHUBDATAFTRACEEVENT']._serialized_end=61550
+  _globals['_DCVSHFREQFTRACEEVENT']._serialized_start=61552
+  _globals['_DCVSHFREQFTRACEEVENT']._serialized_end=61601
+  _globals['_DEVFREQFREQUENCYFTRACEEVENT']._serialized_start=61603
+  _globals['_DEVFREQFREQUENCYFTRACEEVENT']._serialized_end=61722
+  _globals['_DMAFENCEINITFTRACEEVENT']._serialized_start=61724
+  _globals['_DMAFENCEINITFTRACEEVENT']._serialized_end=61815
+  _globals['_DMAFENCEEMITFTRACEEVENT']._serialized_start=61817
+  _globals['_DMAFENCEEMITFTRACEEVENT']._serialized_end=61908
+  _globals['_DMAFENCESIGNALEDFTRACEEVENT']._serialized_start=61910
+  _globals['_DMAFENCESIGNALEDFTRACEEVENT']._serialized_end=62005
+  _globals['_DMAFENCEWAITSTARTFTRACEEVENT']._serialized_start=62007
+  _globals['_DMAFENCEWAITSTARTFTRACEEVENT']._serialized_end=62103
+  _globals['_DMAFENCEWAITENDFTRACEEVENT']._serialized_start=62105
+  _globals['_DMAFENCEWAITENDFTRACEEVENT']._serialized_end=62199
+  _globals['_DMAHEAPSTATFTRACEEVENT']._serialized_start=62201
+  _globals['_DMAHEAPSTATFTRACEEVENT']._serialized_end=62278
+  _globals['_DPUTRACINGMARKWRITEFTRACEEVENT']._serialized_start=62281
+  _globals['_DPUTRACINGMARKWRITEFTRACEEVENT']._serialized_end=62410
+  _globals['_DPUDSICMDFIFOSTATUSFTRACEEVENT']._serialized_start=62412
+  _globals['_DPUDSICMDFIFOSTATUSFTRACEEVENT']._serialized_end=62477
+  _globals['_DPUDSIRXFTRACEEVENT']._serialized_start=62479
+  _globals['_DPUDSIRXFTRACEEVENT']._serialized_end=62529
+  _globals['_DPUDSITXFTRACEEVENT']._serialized_start=62531
+  _globals['_DPUDSITXFTRACEEVENT']._serialized_end=62614
+  _globals['_DPUDISPDPUUNDERRUNFTRACEEVENT']._serialized_start=62616
+  _globals['_DPUDISPDPUUNDERRUNFTRACEEVENT']._serialized_end=62704
+  _globals['_DPUDISPVBLANKIRQENABLEFTRACEEVENT']._serialized_start=62706
+  _globals['_DPUDISPVBLANKIRQENABLEFTRACEEVENT']._serialized_end=62788
+  _globals['_DPUDISPFRAMEDONETIMEOUTFTRACEEVENT']._serialized_start=62791
+  _globals['_DPUDISPFRAMEDONETIMEOUTFTRACEEVENT']._serialized_end=62932
+  _globals['_DPUDISPFRAMESTARTTIMEOUTFTRACEEVENT']._serialized_start=62934
+  _globals['_DPUDISPFRAMESTARTTIMEOUTFTRACEEVENT']._serialized_end=63052
+  _globals['_DPUDISPFRAMEDONEMISSINGFTRACEEVENT']._serialized_start=63054
+  _globals['_DPUDISPFRAMEDONEMISSINGFTRACEEVENT']._serialized_end=63171
+  _globals['_DPUDISPFRAMESTARTMISSINGFTRACEEVENT']._serialized_start=63173
+  _globals['_DPUDISPFRAMESTARTMISSINGFTRACEEVENT']._serialized_end=63291
+  _globals['_DPUDISPDPULINEUNDERRUNFTRACEEVENT']._serialized_start=63293
+  _globals['_DPUDISPDPULINEUNDERRUNFTRACEEVENT']._serialized_end=63385
+  _globals['_DRMVBLANKEVENTFTRACEEVENT']._serialized_start=63387
+  _globals['_DRMVBLANKEVENTFTRACEEVENT']._serialized_end=63474
+  _globals['_DRMVBLANKEVENTDELIVEREDFTRACEEVENT']._serialized_start=63476
+  _globals['_DRMVBLANKEVENTDELIVEREDFTRACEEVENT']._serialized_end=63553
+  _globals['_DWC3ALLOCREQUESTFTRACEEVENT']._serialized_start=63556
+  _globals['_DWC3ALLOCREQUESTFTRACEEVENT']._serialized_end=63718
+  _globals['_DWC3COMPLETETRBFTRACEEVENT']._serialized_start=63721
+  _globals['_DWC3COMPLETETRBFTRACEEVENT']._serialized_end=63913
+  _globals['_DWC3CTRLREQFTRACEEVENT']._serialized_start=63915
+  _globals['_DWC3CTRLREQFTRACEEVENT']._serialized_end=64041
+  _globals['_DWC3EPDEQUEUEFTRACEEVENT']._serialized_start=64044
+  _globals['_DWC3EPDEQUEUEFTRACEEVENT']._serialized_end=64203
+  _globals['_DWC3EPQUEUEFTRACEEVENT']._serialized_start=64206
+  _globals['_DWC3EPQUEUEFTRACEEVENT']._serialized_end=64363
+  _globals['_DWC3EVENTFTRACEEVENT']._serialized_start=64365
+  _globals['_DWC3EVENTFTRACEEVENT']._serialized_end=64433
+  _globals['_DWC3FREEREQUESTFTRACEEVENT']._serialized_start=64436
+  _globals['_DWC3FREEREQUESTFTRACEEVENT']._serialized_end=64597
+  _globals['_DWC3GADGETEPCMDFTRACEEVENT']._serialized_start=64599
+  _globals['_DWC3GADGETEPCMDFTRACEEVENT']._serialized_end=64722
+  _globals['_DWC3GADGETEPDISABLEFTRACEEVENT']._serialized_start=64725
+  _globals['_DWC3GADGETEPDISABLEFTRACEEVENT']._serialized_end=64930
+  _globals['_DWC3GADGETEPENABLEFTRACEEVENT']._serialized_start=64933
+  _globals['_DWC3GADGETEPENABLEFTRACEEVENT']._serialized_end=65137
+  _globals['_DWC3GADGETGENERICCMDFTRACEEVENT']._serialized_start=65139
+  _globals['_DWC3GADGETGENERICCMDFTRACEEVENT']._serialized_end=65216
+  _globals['_DWC3GADGETGIVEBACKFTRACEEVENT']._serialized_start=65219
+  _globals['_DWC3GADGETGIVEBACKFTRACEEVENT']._serialized_end=65383
+  _globals['_DWC3PREPARETRBFTRACEEVENT']._serialized_start=65386
+  _globals['_DWC3PREPARETRBFTRACEEVENT']._serialized_end=65577
+  _globals['_DWC3READLFTRACEEVENT']._serialized_start=65579
+  _globals['_DWC3READLFTRACEEVENT']._serialized_end=65659
+  _globals['_DWC3WRITELFTRACEEVENT']._serialized_start=65661
+  _globals['_DWC3WRITELFTRACEEVENT']._serialized_end=65742
+  _globals['_EXT4DAWRITEBEGINFTRACEEVENT']._serialized_start=65744
+  _globals['_EXT4DAWRITEBEGINFTRACEEVENT']._serialized_end=65840
+  _globals['_EXT4DAWRITEENDFTRACEEVENT']._serialized_start=65842
+  _globals['_EXT4DAWRITEENDFTRACEEVENT']._serialized_end=65937
+  _globals['_EXT4SYNCFILEENTERFTRACEEVENT']._serialized_start=65939
+  _globals['_EXT4SYNCFILEENTERFTRACEEVENT']._serialized_end=66029
+  _globals['_EXT4SYNCFILEEXITFTRACEEVENT']._serialized_start=66031
+  _globals['_EXT4SYNCFILEEXITFTRACEEVENT']._serialized_end=66099
+  _globals['_EXT4ALLOCDABLOCKSFTRACEEVENT']._serialized_start=66101
+  _globals['_EXT4ALLOCDABLOCKSFTRACEEVENT']._serialized_end=66199
+  _globals['_EXT4ALLOCATEBLOCKSFTRACEEVENT']._serialized_start=66202
+  _globals['_EXT4ALLOCATEBLOCKSFTRACEEVENT']._serialized_end=66395
+  _globals['_EXT4ALLOCATEINODEFTRACEEVENT']._serialized_start=66397
+  _globals['_EXT4ALLOCATEINODEFTRACEEVENT']._serialized_end=66480
+  _globals['_EXT4BEGINORDEREDTRUNCATEFTRACEEVENT']._serialized_start=66482
+  _globals['_EXT4BEGINORDEREDTRUNCATEFTRACEEVENT']._serialized_end=66563
+  _globals['_EXT4COLLAPSERANGEFTRACEEVENT']._serialized_start=66565
+  _globals['_EXT4COLLAPSERANGEFTRACEEVENT']._serialized_end=66650
+  _globals['_EXT4DARELEASESPACEFTRACEEVENT']._serialized_start=66653
+  _globals['_EXT4DARELEASESPACEFTRACEEVENT']._serialized_end=66855
+  _globals['_EXT4DARESERVESPACEFTRACEEVENT']._serialized_start=66858
+  _globals['_EXT4DARESERVESPACEFTRACEEVENT']._serialized_end=67026
+  _globals['_EXT4DAUPDATERESERVESPACEFTRACEEVENT']._serialized_start=67029
+  _globals['_EXT4DAUPDATERESERVESPACEFTRACEEVENT']._serialized_end=67257
+  _globals['_EXT4DAWRITEPAGESFTRACEEVENT']._serialized_start=67260
+  _globals['_EXT4DAWRITEPAGESFTRACEEVENT']._serialized_end=67467
+  _globals['_EXT4DAWRITEPAGESEXTENTFTRACEEVENT']._serialized_start=67469
+  _globals['_EXT4DAWRITEPAGESEXTENTFTRACEEVENT']._serialized_end=67572
+  _globals['_EXT4DIRECTIOENTERFTRACEEVENT']._serialized_start=67574
+  _globals['_EXT4DIRECTIOENTERFTRACEEVENT']._serialized_end=67668
+  _globals['_EXT4DIRECTIOEXITFTRACEEVENT']._serialized_start=67670
+  _globals['_EXT4DIRECTIOEXITFTRACEEVENT']._serialized_end=67776
+  _globals['_EXT4DISCARDBLOCKSFTRACEEVENT']._serialized_start=67778
+  _globals['_EXT4DISCARDBLOCKSFTRACEEVENT']._serialized_end=67849
+  _globals['_EXT4DISCARDPREALLOCATIONSFTRACEEVENT']._serialized_start=67851
+  _globals['_EXT4DISCARDPREALLOCATIONSFTRACEEVENT']._serialized_end=67944
+  _globals['_EXT4DROPINODEFTRACEEVENT']._serialized_start=67946
+  _globals['_EXT4DROPINODEFTRACEEVENT']._serialized_end=68012
+  _globals['_EXT4ESCACHEEXTENTFTRACEEVENT']._serialized_start=68014
+  _globals['_EXT4ESCACHEEXTENTFTRACEEVENT']._serialized_end=68127
+  _globals['_EXT4ESFINDDELAYEDEXTENTRANGEENTERFTRACEEVENT']._serialized_start=68129
+  _globals['_EXT4ESFINDDELAYEDEXTENTRANGEENTERFTRACEEVENT']._serialized_end=68215
+  _globals['_EXT4ESFINDDELAYEDEXTENTRANGEEXITFTRACEEVENT']._serialized_start=68218
+  _globals['_EXT4ESFINDDELAYEDEXTENTRANGEEXITFTRACEEVENT']._serialized_end=68346
+  _globals['_EXT4ESINSERTEXTENTFTRACEEVENT']._serialized_start=68348
+  _globals['_EXT4ESINSERTEXTENTFTRACEEVENT']._serialized_end=68462
+  _globals['_EXT4ESLOOKUPEXTENTENTERFTRACEEVENT']._serialized_start=68464
+  _globals['_EXT4ESLOOKUPEXTENTENTERFTRACEEVENT']._serialized_end=68540
+  _globals['_EXT4ESLOOKUPEXTENTEXITFTRACEEVENT']._serialized_start=68543
+  _globals['_EXT4ESLOOKUPEXTENTEXITFTRACEEVENT']._serialized_end=68676
+  _globals['_EXT4ESREMOVEEXTENTFTRACEEVENT']._serialized_start=68678
+  _globals['_EXT4ESREMOVEEXTENTFTRACEEVENT']._serialized_end=68762
+  _globals['_EXT4ESSHRINKFTRACEEVENT']._serialized_start=68764
+  _globals['_EXT4ESSHRINKFTRACEEVENT']._serialized_end=68877
+  _globals['_EXT4ESSHRINKCOUNTFTRACEEVENT']._serialized_start=68879
+  _globals['_EXT4ESSHRINKCOUNTFTRACEEVENT']._serialized_end=68961
+  _globals['_EXT4ESSHRINKSCANENTERFTRACEEVENT']._serialized_start=68963
+  _globals['_EXT4ESSHRINKSCANENTERFTRACEEVENT']._serialized_end=69049
+  _globals['_EXT4ESSHRINKSCANEXITFTRACEEVENT']._serialized_start=69051
+  _globals['_EXT4ESSHRINKSCANEXITFTRACEEVENT']._serialized_end=69135
+  _globals['_EXT4EVICTINODEFTRACEEVENT']._serialized_start=69137
+  _globals['_EXT4EVICTINODEFTRACEEVENT']._serialized_end=69205
+  _globals['_EXT4EXTCONVERTTOINITIALIZEDENTERFTRACEEVENT']._serialized_start=69208
+  _globals['_EXT4EXTCONVERTTOINITIALIZEDENTERFTRACEEVENT']._serialized_end=69357
+  _globals['_EXT4EXTCONVERTTOINITIALIZEDFASTPATHFTRACEEVENT']._serialized_start=69360
+  _globals['_EXT4EXTCONVERTTOINITIALIZEDFASTPATHFTRACEEVENT']._serialized_end=69559
+  _globals['_EXT4EXTHANDLEUNWRITTENEXTENTSFTRACEEVENT']._serialized_start=69562
+  _globals['_EXT4EXTHANDLEUNWRITTENEXTENTSFTRACEEVENT']._serialized_end=69721
+  _globals['_EXT4EXTINCACHEFTRACEEVENT']._serialized_start=69723
+  _globals['_EXT4EXTINCACHEFTRACEEVENT']._serialized_end=69803
+  _globals['_EXT4EXTLOADEXTENTFTRACEEVENT']._serialized_start=69805
+  _globals['_EXT4EXTLOADEXTENTFTRACEEVENT']._serialized_end=69889
+  _globals['_EXT4EXTMAPBLOCKSENTERFTRACEEVENT']._serialized_start=69891
+  _globals['_EXT4EXTMAPBLOCKSENTERFTRACEEVENT']._serialized_end=69993
+  _globals['_EXT4EXTMAPBLOCKSEXITFTRACEEVENT']._serialized_start=69996
+  _globals['_EXT4EXTMAPBLOCKSEXITFTRACEEVENT']._serialized_end=70140
+  _globals['_EXT4EXTPUTINCACHEFTRACEEVENT']._serialized_start=70142
+  _globals['_EXT4EXTPUTINCACHEFTRACEEVENT']._serialized_end=70240
+  _globals['_EXT4EXTREMOVESPACEFTRACEEVENT']._serialized_start=70242
+  _globals['_EXT4EXTREMOVESPACEFTRACEEVENT']._serialized_end=70342
+  _globals['_EXT4EXTREMOVESPACEDONEFTRACEEVENT']._serialized_start=70345
+  _globals['_EXT4EXTREMOVESPACEDONEFTRACEEVENT']._serialized_end=70538
+  _globals['_EXT4EXTRMIDXFTRACEEVENT']._serialized_start=70540
+  _globals['_EXT4EXTRMIDXFTRACEEVENT']._serialized_end=70605
+  _globals['_EXT4EXTRMLEAFFTRACEEVENT']._serialized_start=70608
+  _globals['_EXT4EXTRMLEAFFTRACEEVENT']._serialized_end=70794
+  _globals['_EXT4EXTSHOWEXTENTFTRACEEVENT']._serialized_start=70796
+  _globals['_EXT4EXTSHOWEXTENTFTRACEEVENT']._serialized_end=70893
+  _globals['_EXT4FALLOCATEENTERFTRACEEVENT']._serialized_start=70895
+  _globals['_EXT4FALLOCATEENTERFTRACEEVENT']._serialized_end=71008
+  _globals['_EXT4FALLOCATEEXITFTRACEEVENT']._serialized_start=71010
+  _globals['_EXT4FALLOCATEEXITFTRACEEVENT']._serialized_end=71108
+  _globals['_EXT4FINDDELALLOCRANGEFTRACEEVENT']._serialized_start=71111
+  _globals['_EXT4FINDDELALLOCRANGEFTRACEEVENT']._serialized_end=71248
+  _globals['_EXT4FORGETFTRACEEVENT']._serialized_start=71250
+  _globals['_EXT4FORGETFTRACEEVENT']._serialized_end=71349
+  _globals['_EXT4FREEBLOCKSFTRACEEVENT']._serialized_start=71351
+  _globals['_EXT4FREEBLOCKSFTRACEEVENT']._serialized_end=71463
+  _globals['_EXT4FREEINODEFTRACEEVENT']._serialized_start=71465
+  _globals['_EXT4FREEINODEFTRACEEVENT']._serialized_end=71573
+  _globals['_EXT4GETIMPLIEDCLUSTERALLOCEXITFTRACEEVENT']._serialized_start=71575
+  _globals['_EXT4GETIMPLIEDCLUSTERALLOCEXITFTRACEEVENT']._serialized_end=71700
+  _globals['_EXT4GETRESERVEDCLUSTERALLOCFTRACEEVENT']._serialized_start=71702
+  _globals['_EXT4GETRESERVEDCLUSTERALLOCFTRACEEVENT']._serialized_end=71795
+  _globals['_EXT4INDMAPBLOCKSENTERFTRACEEVENT']._serialized_start=71797
+  _globals['_EXT4INDMAPBLOCKSENTERFTRACEEVENT']._serialized_end=71899
+  _globals['_EXT4INDMAPBLOCKSEXITFTRACEEVENT']._serialized_start=71902
+  _globals['_EXT4INDMAPBLOCKSEXITFTRACEEVENT']._serialized_end=72046
+  _globals['_EXT4INSERTRANGEFTRACEEVENT']._serialized_start=72048
+  _globals['_EXT4INSERTRANGEFTRACEEVENT']._serialized_end=72131
+  _globals['_EXT4INVALIDATEPAGEFTRACEEVENT']._serialized_start=72133
+  _globals['_EXT4INVALIDATEPAGEFTRACEEVENT']._serialized_end=72237
+  _globals['_EXT4JOURNALSTARTFTRACEEVENT']._serialized_start=72240
+  _globals['_EXT4JOURNALSTARTFTRACEEVENT']._serialized_end=72369
+  _globals['_EXT4JOURNALSTARTRESERVEDFTRACEEVENT']._serialized_start=72371
+  _globals['_EXT4JOURNALSTARTRESERVEDFTRACEEVENT']._serialized_end=72449
+  _globals['_EXT4JOURNALLEDINVALIDATEPAGEFTRACEEVENT']._serialized_start=72451
+  _globals['_EXT4JOURNALLEDINVALIDATEPAGEFTRACEEVENT']._serialized_end=72565
+  _globals['_EXT4JOURNALLEDWRITEENDFTRACEEVENT']._serialized_start=72567
+  _globals['_EXT4JOURNALLEDWRITEENDFTRACEEVENT']._serialized_end=72670
+  _globals['_EXT4LOADINODEFTRACEEVENT']._serialized_start=72672
+  _globals['_EXT4LOADINODEFTRACEEVENT']._serialized_end=72724
+  _globals['_EXT4LOADINODEBITMAPFTRACEEVENT']._serialized_start=72726
+  _globals['_EXT4LOADINODEBITMAPFTRACEEVENT']._serialized_end=72786
+  _globals['_EXT4MARKINODEDIRTYFTRACEEVENT']._serialized_start=72788
+  _globals['_EXT4MARKINODEDIRTYFTRACEEVENT']._serialized_end=72857
+  _globals['_EXT4MBBITMAPLOADFTRACEEVENT']._serialized_start=72859
+  _globals['_EXT4MBBITMAPLOADFTRACEEVENT']._serialized_end=72916
+  _globals['_EXT4MBBUDDYBITMAPLOADFTRACEEVENT']._serialized_start=72918
+  _globals['_EXT4MBBUDDYBITMAPLOADFTRACEEVENT']._serialized_end=72980
+  _globals['_EXT4MBDISCARDPREALLOCATIONSFTRACEEVENT']._serialized_start=72982
+  _globals['_EXT4MBDISCARDPREALLOCATIONSFTRACEEVENT']._serialized_end=73051
+  _globals['_EXT4MBNEWGROUPPAFTRACEEVENT']._serialized_start=73053
+  _globals['_EXT4MBNEWGROUPPAFTRACEEVENT']._serialized_end=73162
+  _globals['_EXT4MBNEWINODEPAFTRACEEVENT']._serialized_start=73164
+  _globals['_EXT4MBNEWINODEPAFTRACEEVENT']._serialized_end=73273
+  _globals['_EXT4MBRELEASEGROUPPAFTRACEEVENT']._serialized_start=73275
+  _globals['_EXT4MBRELEASEGROUPPAFTRACEEVENT']._serialized_end=73356
+  _globals['_EXT4MBRELEASEINODEPAFTRACEEVENT']._serialized_start=73358
+  _globals['_EXT4MBRELEASEINODEPAFTRACEEVENT']._serialized_end=73447
+  _globals['_EXT4MBALLOCALLOCFTRACEEVENT']._serialized_start=73450
+  _globals['_EXT4MBALLOCALLOCFTRACEEVENT']._serialized_end=73840
+  _globals['_EXT4MBALLOCDISCARDFTRACEEVENT']._serialized_start=73842
+  _globals['_EXT4MBALLOCDISCARDFTRACEEVENT']._serialized_end=73963
+  _globals['_EXT4MBALLOCFREEFTRACEEVENT']._serialized_start=73965
+  _globals['_EXT4MBALLOCFREEFTRACEEVENT']._serialized_end=74083
+  _globals['_EXT4MBALLOCPREALLOCFTRACEEVENT']._serialized_start=74086
+  _globals['_EXT4MBALLOCPREALLOCFTRACEEVENT']._serialized_end=74312
+  _globals['_EXT4OTHERINODEUPDATETIMEFTRACEEVENT']._serialized_start=74314
+  _globals['_EXT4OTHERINODEUPDATETIMEFTRACEEVENT']._serialized_end=74435
+  _globals['_EXT4PUNCHHOLEFTRACEEVENT']._serialized_start=74437
+  _globals['_EXT4PUNCHHOLEFTRACEEVENT']._serialized_end=74532
+  _globals['_EXT4READBLOCKBITMAPLOADFTRACEEVENT']._serialized_start=74534
+  _globals['_EXT4READBLOCKBITMAPLOADFTRACEEVENT']._serialized_end=74616
+  _globals['_EXT4READPAGEFTRACEEVENT']._serialized_start=74618
+  _globals['_EXT4READPAGEFTRACEEVENT']._serialized_end=74684
+  _globals['_EXT4RELEASEPAGEFTRACEEVENT']._serialized_start=74686
+  _globals['_EXT4RELEASEPAGEFTRACEEVENT']._serialized_end=74755
+  _globals['_EXT4REMOVEBLOCKSFTRACEEVENT']._serialized_start=74758
+  _globals['_EXT4REMOVEBLOCKSFTRACEEVENT']._serialized_end=74958
+  _globals['_EXT4REQUESTBLOCKSFTRACEEVENT']._serialized_start=74961
+  _globals['_EXT4REQUESTBLOCKSFTRACEEVENT']._serialized_end=75138
+  _globals['_EXT4REQUESTINODEFTRACEEVENT']._serialized_start=75140
+  _globals['_EXT4REQUESTINODEFTRACEEVENT']._serialized_end=75209
+  _globals['_EXT4SYNCFSFTRACEEVENT']._serialized_start=75211
+  _globals['_EXT4SYNCFSFTRACEEVENT']._serialized_end=75261
+  _globals['_EXT4TRIMALLFREEFTRACEEVENT']._serialized_start=75263
+  _globals['_EXT4TRIMALLFREEFTRACEEVENT']._serialized_end=75372
+  _globals['_EXT4TRIMEXTENTFTRACEEVENT']._serialized_start=75374
+  _globals['_EXT4TRIMEXTENTFTRACEEVENT']._serialized_end=75482
+  _globals['_EXT4TRUNCATEENTERFTRACEEVENT']._serialized_start=75484
+  _globals['_EXT4TRUNCATEENTERFTRACEEVENT']._serialized_end=75556
+  _globals['_EXT4TRUNCATEEXITFTRACEEVENT']._serialized_start=75558
+  _globals['_EXT4TRUNCATEEXITFTRACEEVENT']._serialized_end=75629
+  _globals['_EXT4UNLINKENTERFTRACEEVENT']._serialized_start=75631
+  _globals['_EXT4UNLINKENTERFTRACEEVENT']._serialized_end=75715
+  _globals['_EXT4UNLINKEXITFTRACEEVENT']._serialized_start=75717
+  _globals['_EXT4UNLINKEXITFTRACEEVENT']._serialized_end=75783
+  _globals['_EXT4WRITEBEGINFTRACEEVENT']._serialized_start=75785
+  _globals['_EXT4WRITEBEGINFTRACEEVENT']._serialized_end=75879
+  _globals['_EXT4WRITEENDFTRACEEVENT']._serialized_start=75881
+  _globals['_EXT4WRITEENDFTRACEEVENT']._serialized_end=75974
+  _globals['_EXT4WRITEPAGEFTRACEEVENT']._serialized_start=75976
+  _globals['_EXT4WRITEPAGEFTRACEEVENT']._serialized_end=76043
+  _globals['_EXT4WRITEPAGESFTRACEEVENT']._serialized_start=76046
+  _globals['_EXT4WRITEPAGESFTRACEEVENT']._serialized_end=76270
+  _globals['_EXT4WRITEPAGESRESULTFTRACEEVENT']._serialized_start=76273
+  _globals['_EXT4WRITEPAGESRESULTFTRACEEVENT']._serialized_end=76435
+  _globals['_EXT4ZERORANGEFTRACEEVENT']._serialized_start=76437
+  _globals['_EXT4ZERORANGEFTRACEEVENT']._serialized_end=76532
+  _globals['_F2FSDOSUBMITBIOFTRACEEVENT']._serialized_start=76534
+  _globals['_F2FSDOSUBMITBIOFTRACEEVENT']._serialized_end=76634
+  _globals['_F2FSEVICTINODEFTRACEEVENT']._serialized_start=76637
+  _globals['_F2FSEVICTINODEFTRACEEVENT']._serialized_end=76779
+  _globals['_F2FSFALLOCATEFTRACEEVENT']._serialized_start=76782
+  _globals['_F2FSFALLOCATEFTRACEEVENT']._serialized_end=76920
+  _globals['_F2FSGETDATABLOCKFTRACEEVENT']._serialized_start=76922
+  _globals['_F2FSGETDATABLOCKFTRACEEVENT']._serialized_end=77041
+  _globals['_F2FSGETVICTIMFTRACEEVENT']._serialized_start=77044
+  _globals['_F2FSGETVICTIMFTRACEEVENT']._serialized_end=77250
+  _globals['_F2FSIGETFTRACEEVENT']._serialized_start=77253
+  _globals['_F2FSIGETFTRACEEVENT']._serialized_end=77389
+  _globals['_F2FSIGETEXITFTRACEEVENT']._serialized_start=77391
+  _globals['_F2FSIGETEXITFTRACEEVENT']._serialized_end=77455
+  _globals['_F2FSNEWINODEFTRACEEVENT']._serialized_start=77457
+  _globals['_F2FSNEWINODEFTRACEEVENT']._serialized_end=77521
+  _globals['_F2FSREADPAGEFTRACEEVENT']._serialized_start=77524
+  _globals['_F2FSREADPAGEFTRACEEVENT']._serialized_end=77667
+  _globals['_F2FSRESERVENEWBLOCKFTRACEEVENT']._serialized_start=77669
+  _globals['_F2FSRESERVENEWBLOCKFTRACEEVENT']._serialized_end=77748
+  _globals['_F2FSSETPAGEDIRTYFTRACEEVENT']._serialized_start=77751
+  _globals['_F2FSSETPAGEDIRTYFTRACEEVENT']._serialized_end=77881
+  _globals['_F2FSSUBMITWRITEPAGEFTRACEEVENT']._serialized_start=77883
+  _globals['_F2FSSUBMITWRITEPAGEFTRACEEVENT']._serialized_end=77985
+  _globals['_F2FSSYNCFILEENTERFTRACEEVENT']._serialized_start=77988
+  _globals['_F2FSSYNCFILEENTERFTRACEEVENT']._serialized_end=78133
+  _globals['_F2FSSYNCFILEEXITFTRACEEVENT']._serialized_start=78135
+  _globals['_F2FSSYNCFILEEXITFTRACEEVENT']._serialized_end=78257
+  _globals['_F2FSSYNCFSFTRACEEVENT']._serialized_start=78259
+  _globals['_F2FSSYNCFSFTRACEEVENT']._serialized_end=78324
+  _globals['_F2FSTRUNCATEFTRACEEVENT']._serialized_start=78327
+  _globals['_F2FSTRUNCATEFTRACEEVENT']._serialized_end=78467
+  _globals['_F2FSTRUNCATEBLOCKSENTERFTRACEEVENT']._serialized_start=78469
+  _globals['_F2FSTRUNCATEBLOCKSENTERFTRACEEVENT']._serialized_end=78575
+  _globals['_F2FSTRUNCATEBLOCKSEXITFTRACEEVENT']._serialized_start=78577
+  _globals['_F2FSTRUNCATEBLOCKSEXITFTRACEEVENT']._serialized_end=78651
+  _globals['_F2FSTRUNCATEDATABLOCKSRANGEFTRACEEVENT']._serialized_start=78653
+  _globals['_F2FSTRUNCATEDATABLOCKSRANGEFTRACEEVENT']._serialized_end=78759
+  _globals['_F2FSTRUNCATEINODEBLOCKSENTERFTRACEEVENT']._serialized_start=78761
+  _globals['_F2FSTRUNCATEINODEBLOCKSENTERFTRACEEVENT']._serialized_end=78872
+  _globals['_F2FSTRUNCATEINODEBLOCKSEXITFTRACEEVENT']._serialized_start=78874
+  _globals['_F2FSTRUNCATEINODEBLOCKSEXITFTRACEEVENT']._serialized_end=78953
+  _globals['_F2FSTRUNCATENODEFTRACEEVENT']._serialized_start=78955
+  _globals['_F2FSTRUNCATENODEFTRACEEVENT']._serialized_end=79041
+  _globals['_F2FSTRUNCATENODESENTERFTRACEEVENT']._serialized_start=79043
+  _globals['_F2FSTRUNCATENODESENTERFTRACEEVENT']._serialized_end=79135
+  _globals['_F2FSTRUNCATENODESEXITFTRACEEVENT']._serialized_start=79137
+  _globals['_F2FSTRUNCATENODESEXITFTRACEEVENT']._serialized_end=79210
+  _globals['_F2FSTRUNCATEPARTIALNODESFTRACEEVENT']._serialized_start=79212
+  _globals['_F2FSTRUNCATEPARTIALNODESFTRACEEVENT']._serialized_end=79316
+  _globals['_F2FSUNLINKENTERFTRACEEVENT']._serialized_start=79318
+  _globals['_F2FSUNLINKENTERFTRACEEVENT']._serialized_end=79416
+  _globals['_F2FSUNLINKEXITFTRACEEVENT']._serialized_start=79418
+  _globals['_F2FSUNLINKEXITFTRACEEVENT']._serialized_end=79484
+  _globals['_F2FSVMPAGEMKWRITEFTRACEEVENT']._serialized_start=79487
+  _globals['_F2FSVMPAGEMKWRITEFTRACEEVENT']._serialized_end=79618
+  _globals['_F2FSWRITEBEGINFTRACEEVENT']._serialized_start=79620
+  _globals['_F2FSWRITEBEGINFTRACEEVENT']._serialized_end=79714
+  _globals['_F2FSWRITECHECKPOINTFTRACEEVENT']._serialized_start=79716
+  _globals['_F2FSWRITECHECKPOINTFTRACEEVENT']._serialized_end=79824
+  _globals['_F2FSWRITEENDFTRACEEVENT']._serialized_start=79826
+  _globals['_F2FSWRITEENDFTRACEEVENT']._serialized_end=79919
+  _globals['_F2FSIOSTATFTRACEEVENT']._serialized_start=79922
+  _globals['_F2FSIOSTATFTRACEEVENT']._serialized_end=80347
+  _globals['_F2FSIOSTATLATENCYFTRACEEVENT']._serialized_start=80350
+  _globals['_F2FSIOSTATLATENCYFTRACEEVENT']._serialized_end=80933
+  _globals['_F2FSBACKGROUNDGCFTRACEEVENT']._serialized_start=80935
+  _globals['_F2FSBACKGROUNDGCFTRACEEVENT']._serialized_end=81025
+  _globals['_F2FSGCBEGINFTRACEEVENT']._serialized_start=81028
+  _globals['_F2FSGCBEGINFTRACEEVENT']._serialized_end=81298
+  _globals['_F2FSGCENDFTRACEEVENT']._serialized_start=81301
+  _globals['_F2FSGCENDFTRACEEVENT']._serialized_end=81529
+  _globals['_F2FSLOCKELAPSEDTIMEFTRACEEVENT']._serialized_start=81532
+  _globals['_F2FSLOCKELAPSEDTIMEFTRACEEVENT']._serialized_end=81806
+  _globals['_FASTRPCDMASTATFTRACEEVENT']._serialized_start=81808
+  _globals['_FASTRPCDMASTATFTRACEEVENT']._serialized_end=81886
+  _globals['_FASTRPCDMAFREEFTRACEEVENT']._serialized_start=81888
+  _globals['_FASTRPCDMAFREEFTRACEEVENT']._serialized_end=81956
+  _globals['_FASTRPCDMAALLOCFTRACEEVENT']._serialized_start=81958
+  _globals['_FASTRPCDMAALLOCFTRACEEVENT']._serialized_end=82057
+  _globals['_FASTRPCDMAUNMAPFTRACEEVENT']._serialized_start=82059
+  _globals['_FASTRPCDMAUNMAPFTRACEEVENT']._serialized_end=82128
+  _globals['_FASTRPCDMAMAPFTRACEEVENT']._serialized_start=82130
+  _globals['_FASTRPCDMAMAPFTRACEEVENT']._serialized_end=82252
+  _globals['_FENCEINITFTRACEEVENT']._serialized_start=82254
+  _globals['_FENCEINITFTRACEEVENT']._serialized_end=82342
+  _globals['_FENCEDESTROYFTRACEEVENT']._serialized_start=82344
+  _globals['_FENCEDESTROYFTRACEEVENT']._serialized_end=82435
+  _globals['_FENCEENABLESIGNALFTRACEEVENT']._serialized_start=82437
+  _globals['_FENCEENABLESIGNALFTRACEEVENT']._serialized_end=82533
+  _globals['_FENCESIGNALEDFTRACEEVENT']._serialized_start=82535
+  _globals['_FENCESIGNALEDFTRACEEVENT']._serialized_end=82627
+  _globals['_MMFILEMAPADDTOPAGECACHEFTRACEEVENT']._serialized_start=82629
+  _globals['_MMFILEMAPADDTOPAGECACHEFTRACEEVENT']._serialized_end=82737
+  _globals['_MMFILEMAPDELETEFROMPAGECACHEFTRACEEVENT']._serialized_start=82739
+  _globals['_MMFILEMAPDELETEFROMPAGECACHEFTRACEEVENT']._serialized_end=82852
+  _globals['_DOSYSOPENFTRACEEVENT']._serialized_start=82854
+  _globals['_DOSYSOPENFTRACEEVENT']._serialized_end=82923
+  _globals['_OPENEXECFTRACEEVENT']._serialized_start=82925
+  _globals['_OPENEXECFTRACEEVENT']._serialized_end=82964
+  _globals['_PRINTFTRACEEVENT']._serialized_start=82966
+  _globals['_PRINTFTRACEEVENT']._serialized_end=83009
+  _globals['_FUNCGRAPHENTRYFTRACEEVENT']._serialized_start=83011
+  _globals['_FUNCGRAPHENTRYFTRACEEVENT']._serialized_end=83067
+  _globals['_FUNCGRAPHEXITFTRACEEVENT']._serialized_start=83069
+  _globals['_FUNCGRAPHEXITFTRACEEVENT']._serialized_end=83176
+  _globals['_FWTPPERFETTOCOUNTERFTRACEEVENT']._serialized_start=83178
+  _globals['_FWTPPERFETTOCOUNTERFTRACEEVENT']._serialized_end=83294
+  _globals['_FWTPPERFETTOSLICEFTRACEEVENT']._serialized_start=83296
+  _globals['_FWTPPERFETTOSLICEFTRACEEVENT']._serialized_end=83410
+  _globals['_G2DTRACINGMARKWRITEFTRACEEVENT']._serialized_start=83412
+  _globals['_G2DTRACINGMARKWRITEFTRACEEVENT']._serialized_end=83500
+  _globals['_GENERICFTRACEEVENT']._serialized_start=83503
+  _globals['_GENERICFTRACEEVENT']._serialized_end=83697
+  _globals['_GENERICFTRACEEVENT_FIELD']._serialized_start=83603
+  _globals['_GENERICFTRACEEVENT_FIELD']._serialized_end=83697
+  _globals['_KPROBEEVENT']._serialized_start=83700
+  _globals['_KPROBEEVENT']._serialized_end=83890
+  _globals['_KPROBEEVENT_KPROBETYPE']._serialized_start=83784
+  _globals['_KPROBEEVENT_KPROBETYPE']._serialized_end=83890
+  _globals['_GOOGLEICCEVENTFTRACEEVENT']._serialized_start=83892
+  _globals['_GOOGLEICCEVENTFTRACEEVENT']._serialized_end=83953
+  _globals['_GOOGLEIRMEVENTFTRACEEVENT']._serialized_start=83955
+  _globals['_GOOGLEIRMEVENTFTRACEEVENT']._serialized_end=84016
+  _globals['_GPUMEMTOTALFTRACEEVENT']._serialized_start=84018
+  _globals['_GPUMEMTOTALFTRACEEVENT']._serialized_end=84085
+  _globals['_DRMSCHEDJOBFTRACEEVENT']._serialized_start=84087
+  _globals['_DRMSCHEDJOBFTRACEEVENT']._serialized_end=84209
+  _globals['_DRMRUNJOBFTRACEEVENT']._serialized_start=84211
+  _globals['_DRMRUNJOBFTRACEEVENT']._serialized_end=84331
+  _globals['_DRMSCHEDPROCESSJOBFTRACEEVENT']._serialized_start=84333
+  _globals['_DRMSCHEDPROCESSJOBFTRACEEVENT']._serialized_end=84379
+  _globals['_DRMSCHEDJOBADDDEPFTRACEEVENT']._serialized_start=84381
+  _globals['_DRMSCHEDJOBADDDEPFTRACEEVENT']._serialized_end=84483
+  _globals['_DRMSCHEDJOBDONEFTRACEEVENT']._serialized_start=84485
+  _globals['_DRMSCHEDJOBDONEFTRACEEVENT']._serialized_end=84557
+  _globals['_DRMSCHEDJOBQUEUEFTRACEEVENT']._serialized_start=84560
+  _globals['_DRMSCHEDJOBQUEUEFTRACEEVENT']._serialized_end=84720
+  _globals['_DRMSCHEDJOBRUNFTRACEEVENT']._serialized_start=84723
+  _globals['_DRMSCHEDJOBRUNFTRACEEVENT']._serialized_end=84881
+  _globals['_DRMSCHEDJOBUNSCHEDULABLEFTRACEEVENT']._serialized_start=84883
+  _globals['_DRMSCHEDJOBUNSCHEDULABLEFTRACEEVENT']._serialized_end=84992
+  _globals['_HYPENTERFTRACEEVENT']._serialized_start=84994
+  _globals['_HYPENTERFTRACEEVENT']._serialized_end=85015
+  _globals['_HYPEXITFTRACEEVENT']._serialized_start=85017
+  _globals['_HYPEXITFTRACEEVENT']._serialized_end=85037
+  _globals['_HOSTHCALLFTRACEEVENT']._serialized_start=85039
+  _globals['_HOSTHCALLFTRACEEVENT']._serialized_end=85090
+  _globals['_HOSTSMCFTRACEEVENT']._serialized_start=85092
+  _globals['_HOSTSMCFTRACEEVENT']._serialized_end=85143
+  _globals['_HOSTMEMABORTFTRACEEVENT']._serialized_start=85145
+  _globals['_HOSTMEMABORTFTRACEEVENT']._serialized_end=85197
+  _globals['_HOSTFFACALLFTRACEEVENT']._serialized_start=85200
+  _globals['_HOSTFFACALLFTRACEEVENT']._serialized_end=85335
+  _globals['_IOMMUIDMAPFTRACEEVENT']._serialized_start=85337
+  _globals['_IOMMUIDMAPFTRACEEVENT']._serialized_end=85400
+  _globals['_PSCIMEMPROTECTFTRACEEVENT']._serialized_start=85402
+  _globals['_PSCIMEMPROTECTFTRACEEVENT']._serialized_end=85457
+  _globals['_HYPERVISORHOSTHCALLFTRACEEVENT']._serialized_start=85459
+  _globals['_HYPERVISORHOSTHCALLFTRACEEVENT']._serialized_end=85520
+  _globals['_HYPERVISORHOSTSMCFTRACEEVENT']._serialized_start=85522
+  _globals['_HYPERVISORHOSTSMCFTRACEEVENT']._serialized_end=85583
+  _globals['_HYPERVISORHYPEXITFTRACEEVENT']._serialized_start=85585
+  _globals['_HYPERVISORHYPEXITFTRACEEVENT']._serialized_end=85615
+  _globals['_HYPERVISORIOMMUIDMAPFTRACEEVENT']._serialized_start=85617
+  _globals['_HYPERVISORIOMMUIDMAPFTRACEEVENT']._serialized_end=85690
+  _globals['_HYPERVISORPSCIMEMPROTECTFTRACEEVENT']._serialized_start=85692
+  _globals['_HYPERVISORPSCIMEMPROTECTFTRACEEVENT']._serialized_end=85757
+  _globals['_HYPERVISORHOSTMEMABORTFTRACEEVENT']._serialized_start=85759
+  _globals['_HYPERVISORHOSTMEMABORTFTRACEEVENT']._serialized_end=85821
+  _globals['_HYPERVISORHYPENTERFTRACEEVENT']._serialized_start=85823
+  _globals['_HYPERVISORHYPENTERFTRACEEVENT']._serialized_end=85854
+  _globals['_HYPERVISORIOMMUIDMAPCOMPLETEFTRACEEVENT']._serialized_start=85856
+  _globals['_HYPERVISORIOMMUIDMAPCOMPLETEFTRACEEVENT']._serialized_end=85910
+  _globals['_HYPERVISORVCPUILLEGALTRAPFTRACEEVENT']._serialized_start=85912
+  _globals['_HYPERVISORVCPUILLEGALTRAPFTRACEEVENT']._serialized_end=85963
+  _globals['_I2CREADFTRACEEVENT']._serialized_start=85965
+  _globals['_I2CREADFTRACEEVENT']._serialized_end=86063
+  _globals['_I2CWRITEFTRACEEVENT']._serialized_start=86065
+  _globals['_I2CWRITEFTRACEEVENT']._serialized_end=86177
+  _globals['_I2CRESULTFTRACEEVENT']._serialized_start=86179
+  _globals['_I2CRESULTFTRACEEVENT']._serialized_end=86251
+  _globals['_I2CREPLYFTRACEEVENT']._serialized_start=86253
+  _globals['_I2CREPLYFTRACEEVENT']._serialized_end=86365
+  _globals['_SMBUSREADFTRACEEVENT']._serialized_start=86367
+  _globals['_SMBUSREADFTRACEEVENT']._serialized_end=86473
+  _globals['_SMBUSWRITEFTRACEEVENT']._serialized_start=86475
+  _globals['_SMBUSWRITEFTRACEEVENT']._serialized_end=86595
+  _globals['_SMBUSRESULTFTRACEEVENT']._serialized_start=86598
+  _globals['_SMBUSRESULTFTRACEEVENT']._serialized_end=86739
+  _globals['_SMBUSREPLYFTRACEEVENT']._serialized_start=86741
+  _globals['_SMBUSREPLYFTRACEEVENT']._serialized_end=86861
+  _globals['_IONSTATFTRACEEVENT']._serialized_start=86863
+  _globals['_IONSTATFTRACEEVENT']._serialized_end=86940
+  _globals['_IPIENTRYFTRACEEVENT']._serialized_start=86942
+  _globals['_IPIENTRYFTRACEEVENT']._serialized_end=86979
+  _globals['_IPIEXITFTRACEEVENT']._serialized_start=86981
+  _globals['_IPIEXITFTRACEEVENT']._serialized_end=87017
+  _globals['_IPIRAISEFTRACEEVENT']._serialized_start=87019
+  _globals['_IPIRAISEFTRACEEVENT']._serialized_end=87077
+  _globals['_SOFTIRQENTRYFTRACEEVENT']._serialized_start=87079
+  _globals['_SOFTIRQENTRYFTRACEEVENT']._serialized_end=87117
+  _globals['_SOFTIRQEXITFTRACEEVENT']._serialized_start=87119
+  _globals['_SOFTIRQEXITFTRACEEVENT']._serialized_end=87156
+  _globals['_SOFTIRQRAISEFTRACEEVENT']._serialized_start=87158
+  _globals['_SOFTIRQRAISEFTRACEEVENT']._serialized_end=87196
+  _globals['_IRQHANDLERENTRYFTRACEEVENT']._serialized_start=87198
+  _globals['_IRQHANDLERENTRYFTRACEEVENT']._serialized_end=87270
+  _globals['_IRQHANDLEREXITFTRACEEVENT']._serialized_start=87272
+  _globals['_IRQHANDLEREXITFTRACEEVENT']._serialized_end=87325
+  _globals['_LOCALTIMERENTRYFTRACEEVENT']._serialized_start=87327
+  _globals['_LOCALTIMERENTRYFTRACEEVENT']._serialized_end=87371
+  _globals['_LOCALTIMEREXITFTRACEEVENT']._serialized_start=87373
+  _globals['_LOCALTIMEREXITFTRACEEVENT']._serialized_end=87416
+  _globals['_KGSLGPUFREQUENCYFTRACEEVENT']._serialized_start=87418
+  _globals['_KGSLGPUFREQUENCYFTRACEEVENT']._serialized_end=87481
+  _globals['_KGSLADRENOCMDBATCHQUEUEDFTRACEEVENT']._serialized_start=87483
+  _globals['_KGSLADRENOCMDBATCHQUEUEDFTRACEEVENT']._serialized_end=87596
+  _globals['_KGSLADRENOCMDBATCHSUBMITTEDFTRACEEVENT']._serialized_start=87599
+  _globals['_KGSLADRENOCMDBATCHSUBMITTEDFTRACEEVENT']._serialized_end=87848
+  _globals['_KGSLADRENOCMDBATCHSYNCFTRACEEVENT']._serialized_start=87850
+  _globals['_KGSLADRENOCMDBATCHSYNCFTRACEEVENT']._serialized_end=87945
+  _globals['_KGSLADRENOCMDBATCHRETIREDFTRACEEVENT']._serialized_start=87948
+  _globals['_KGSLADRENOCMDBATCHRETIREDFTRACEEVENT']._serialized_end=88289
+  _globals['_ALLOCPAGESIOMMUENDFTRACEEVENT']._serialized_start=88291
+  _globals['_ALLOCPAGESIOMMUENDFTRACEEVENT']._serialized_end=88356
+  _globals['_ALLOCPAGESIOMMUFAILFTRACEEVENT']._serialized_start=88358
+  _globals['_ALLOCPAGESIOMMUFAILFTRACEEVENT']._serialized_end=88424
+  _globals['_ALLOCPAGESIOMMUSTARTFTRACEEVENT']._serialized_start=88426
+  _globals['_ALLOCPAGESIOMMUSTARTFTRACEEVENT']._serialized_end=88493
+  _globals['_ALLOCPAGESSYSENDFTRACEEVENT']._serialized_start=88495
+  _globals['_ALLOCPAGESSYSENDFTRACEEVENT']._serialized_end=88558
+  _globals['_ALLOCPAGESSYSFAILFTRACEEVENT']._serialized_start=88560
+  _globals['_ALLOCPAGESSYSFAILFTRACEEVENT']._serialized_end=88624
+  _globals['_ALLOCPAGESSYSSTARTFTRACEEVENT']._serialized_start=88626
+  _globals['_ALLOCPAGESSYSSTARTFTRACEEVENT']._serialized_end=88691
+  _globals['_DMAALLOCCONTIGUOUSRETRYFTRACEEVENT']._serialized_start=88693
+  _globals['_DMAALLOCCONTIGUOUSRETRYFTRACEEVENT']._serialized_end=88744
+  _globals['_IOMMUMAPRANGEFTRACEEVENT']._serialized_start=88746
+  _globals['_IOMMUMAPRANGEFTRACEEVENT']._serialized_end=88829
+  _globals['_IOMMUSECPTBLMAPRANGEENDFTRACEEVENT']._serialized_start=88831
+  _globals['_IOMMUSECPTBLMAPRANGEENDFTRACEEVENT']._serialized_end=88933
+  _globals['_IOMMUSECPTBLMAPRANGESTARTFTRACEEVENT']._serialized_start=88935
+  _globals['_IOMMUSECPTBLMAPRANGESTARTFTRACEEVENT']._serialized_end=89039
+  _globals['_IONALLOCBUFFERENDFTRACEEVENT']._serialized_start=89041
+  _globals['_IONALLOCBUFFERENDFTRACEEVENT']._serialized_end=89153
+  _globals['_IONALLOCBUFFERFAILFTRACEEVENT']._serialized_start=89156
+  _globals['_IONALLOCBUFFERFAILFTRACEEVENT']._serialized_end=89284
+  _globals['_IONALLOCBUFFERFALLBACKFTRACEEVENT']._serialized_start=89287
+  _globals['_IONALLOCBUFFERFALLBACKFTRACEEVENT']._serialized_end=89419
+  _globals['_IONALLOCBUFFERSTARTFTRACEEVENT']._serialized_start=89421
+  _globals['_IONALLOCBUFFERSTARTFTRACEEVENT']._serialized_end=89535
+  _globals['_IONCPALLOCRETRYFTRACEEVENT']._serialized_start=89537
+  _globals['_IONCPALLOCRETRYFTRACEEVENT']._serialized_end=89580
+  _globals['_IONCPSECUREBUFFERENDFTRACEEVENT']._serialized_start=89582
+  _globals['_IONCPSECUREBUFFERENDFTRACEEVENT']._serialized_end=89677
+  _globals['_IONCPSECUREBUFFERSTARTFTRACEEVENT']._serialized_start=89679
+  _globals['_IONCPSECUREBUFFERSTARTFTRACEEVENT']._serialized_end=89776
+  _globals['_IONPREFETCHINGFTRACEEVENT']._serialized_start=89778
+  _globals['_IONPREFETCHINGFTRACEEVENT']._serialized_end=89818
+  _globals['_IONSECURECMAADDTOPOOLENDFTRACEEVENT']._serialized_start=89820
+  _globals['_IONSECURECMAADDTOPOOLENDFTRACEEVENT']._serialized_end=89911
+  _globals['_IONSECURECMAADDTOPOOLSTARTFTRACEEVENT']._serialized_start=89913
+  _globals['_IONSECURECMAADDTOPOOLSTARTFTRACEEVENT']._serialized_end=90006
+  _globals['_IONSECURECMAALLOCATEENDFTRACEEVENT']._serialized_start=90008
+  _globals['_IONSECURECMAALLOCATEENDFTRACEEVENT']._serialized_end=90106
+  _globals['_IONSECURECMAALLOCATESTARTFTRACEEVENT']._serialized_start=90108
+  _globals['_IONSECURECMAALLOCATESTARTFTRACEEVENT']._serialized_end=90208
+  _globals['_IONSECURECMASHRINKPOOLENDFTRACEEVENT']._serialized_start=90210
+  _globals['_IONSECURECMASHRINKPOOLENDFTRACEEVENT']._serialized_end=90292
+  _globals['_IONSECURECMASHRINKPOOLSTARTFTRACEEVENT']._serialized_start=90294
+  _globals['_IONSECURECMASHRINKPOOLSTARTFTRACEEVENT']._serialized_end=90378
+  _globals['_KFREEFTRACEEVENT']._serialized_start=90380
+  _globals['_KFREEFTRACEEVENT']._serialized_end=90430
+  _globals['_KMALLOCFTRACEEVENT']._serialized_start=90432
+  _globals['_KMALLOCFTRACEEVENT']._serialized_end=90543
+  _globals['_KMALLOCNODEFTRACEEVENT']._serialized_start=90546
+  _globals['_KMALLOCNODEFTRACEEVENT']._serialized_end=90675
+  _globals['_KMEMCACHEALLOCFTRACEEVENT']._serialized_start=90677
+  _globals['_KMEMCACHEALLOCFTRACEEVENT']._serialized_end=90795
+  _globals['_KMEMCACHEALLOCNODEFTRACEEVENT']._serialized_start=90798
+  _globals['_KMEMCACHEALLOCNODEFTRACEEVENT']._serialized_end=90934
+  _globals['_KMEMCACHEFREEFTRACEEVENT']._serialized_start=90936
+  _globals['_KMEMCACHEFREEFTRACEEVENT']._serialized_end=90994
+  _globals['_MIGRATEPAGESENDFTRACEEVENT']._serialized_start=90996
+  _globals['_MIGRATEPAGESENDFTRACEEVENT']._serialized_end=91038
+  _globals['_MIGRATEPAGESSTARTFTRACEEVENT']._serialized_start=91040
+  _globals['_MIGRATEPAGESSTARTFTRACEEVENT']._serialized_end=91084
+  _globals['_MIGRATERETRYFTRACEEVENT']._serialized_start=91086
+  _globals['_MIGRATERETRYFTRACEEVENT']._serialized_end=91126
+  _globals['_MMPAGEALLOCFTRACEEVENT']._serialized_start=91128
+  _globals['_MMPAGEALLOCFTRACEEVENT']._serialized_end=91234
+  _globals['_MMPAGEALLOCEXTFRAGFTRACEEVENT']._serialized_start=91237
+  _globals['_MMPAGEALLOCEXTFRAGFTRACEEVENT']._serialized_end=91423
+  _globals['_MMPAGEALLOCZONELOCKEDFTRACEEVENT']._serialized_start=91425
+  _globals['_MMPAGEALLOCZONELOCKEDFTRACEEVENT']._serialized_end=91522
+  _globals['_MMPAGEFREEFTRACEEVENT']._serialized_start=91524
+  _globals['_MMPAGEFREEFTRACEEVENT']._serialized_end=91589
+  _globals['_MMPAGEFREEBATCHEDFTRACEEVENT']._serialized_start=91591
+  _globals['_MMPAGEFREEBATCHEDFTRACEEVENT']._serialized_end=91662
+  _globals['_MMPAGEPCPUDRAINFTRACEEVENT']._serialized_start=91664
+  _globals['_MMPAGEPCPUDRAINFTRACEEVENT']._serialized_end=91755
+  _globals['_RSSSTATFTRACEEVENT']._serialized_start=91757
+  _globals['_RSSSTATFTRACEEVENT']._serialized_end=91836
+  _globals['_IONHEAPSHRINKFTRACEEVENT']._serialized_start=91838
+  _globals['_IONHEAPSHRINKFTRACEEVENT']._serialized_end=91921
+  _globals['_IONHEAPGROWFTRACEEVENT']._serialized_start=91923
+  _globals['_IONHEAPGROWFTRACEEVENT']._serialized_end=92004
+  _globals['_IONBUFFERCREATEFTRACEEVENT']._serialized_start=92006
+  _globals['_IONBUFFERCREATEFTRACEEVENT']._serialized_end=92061
+  _globals['_IONBUFFERDESTROYFTRACEEVENT']._serialized_start=92063
+  _globals['_IONBUFFERDESTROYFTRACEEVENT']._serialized_end=92119
+  _globals['_MMALLOCCONTIGMIGRATERANGEINFOFTRACEEVENT']._serialized_start=92122
+  _globals['_MMALLOCCONTIGMIGRATERANGEINFOFTRACEEVENT']._serialized_end=92275
+  _globals['_DMABUFRSSSTATFTRACEEVENT']._serialized_start=92277
+  _globals['_DMABUFRSSSTATFTRACEEVENT']._serialized_end=92350
+  _globals['_KVMACCESSFAULTFTRACEEVENT']._serialized_start=92352
+  _globals['_KVMACCESSFAULTFTRACEEVENT']._serialized_end=92392
+  _globals['_KVMACKIRQFTRACEEVENT']._serialized_start=92394
+  _globals['_KVMACKIRQFTRACEEVENT']._serialized_end=92446
+  _globals['_KVMAGEHVAFTRACEEVENT']._serialized_start=92448
+  _globals['_KVMAGEHVAFTRACEEVENT']._serialized_end=92498
+  _globals['_KVMAGEPAGEFTRACEEVENT']._serialized_start=92500
+  _globals['_KVMAGEPAGEFTRACEEVENT']._serialized_end=92584
+  _globals['_KVMARMCLEARDEBUGFTRACEEVENT']._serialized_start=92586
+  _globals['_KVMARMCLEARDEBUGFTRACEEVENT']._serialized_end=92636
+  _globals['_KVMARMSETDREG32FTRACEEVENT']._serialized_start=92638
+  _globals['_KVMARMSETDREG32FTRACEEVENT']._serialized_end=92695
+  _globals['_KVMARMSETREGSETFTRACEEVENT']._serialized_start=92697
+  _globals['_KVMARMSETREGSETFTRACEEVENT']._serialized_end=92752
+  _globals['_KVMARMSETUPDEBUGFTRACEEVENT']._serialized_start=92754
+  _globals['_KVMARMSETUPDEBUGFTRACEEVENT']._serialized_end=92818
+  _globals['_KVMENTRYFTRACEEVENT']._serialized_start=92820
+  _globals['_KVMENTRYFTRACEEVENT']._serialized_end=92858
+  _globals['_KVMEXITFTRACEEVENT']._serialized_start=92860
+  _globals['_KVMEXITFTRACEEVENT']._serialized_end=92926
+  _globals['_KVMFPUFTRACEEVENT']._serialized_start=92928
+  _globals['_KVMFPUFTRACEEVENT']._serialized_end=92961
+  _globals['_KVMGETTIMERMAPFTRACEEVENT']._serialized_start=92963
+  _globals['_KVMGETTIMERMAPFTRACEEVENT']._serialized_end=93074
+  _globals['_KVMGUESTFAULTFTRACEEVENT']._serialized_start=93076
+  _globals['_KVMGUESTFAULTFTRACEEVENT']._serialized_end=93160
+  _globals['_KVMHANDLESYSREGFTRACEEVENT']._serialized_start=93162
+  _globals['_KVMHANDLESYSREGFTRACEEVENT']._serialized_end=93203
+  _globals['_KVMHVCARM64FTRACEEVENT']._serialized_start=93205
+  _globals['_KVMHVCARM64FTRACEEVENT']._serialized_end=93271
+  _globals['_KVMIRQLINEFTRACEEVENT']._serialized_start=93273
+  _globals['_KVMIRQLINEFTRACEEVENT']._serialized_end=93360
+  _globals['_KVMMMIOFTRACEEVENT']._serialized_start=93362
+  _globals['_KVMMMIOFTRACEEVENT']._serialized_end=93435
+  _globals['_KVMMMIOEMULATEFTRACEEVENT']._serialized_start=93437
+  _globals['_KVMMMIOEMULATEFTRACEEVENT']._serialized_end=93510
+  _globals['_KVMSETGUESTDEBUGFTRACEEVENT']._serialized_start=93512
+  _globals['_KVMSETGUESTDEBUGFTRACEEVENT']._serialized_end=93576
+  _globals['_KVMSETIRQFTRACEEVENT']._serialized_start=93578
+  _globals['_KVMSETIRQFTRACEEVENT']._serialized_end=93651
+  _globals['_KVMSETSPTEHVAFTRACEEVENT']._serialized_start=93653
+  _globals['_KVMSETSPTEHVAFTRACEEVENT']._serialized_end=93692
+  _globals['_KVMSETWAYFLUSHFTRACEEVENT']._serialized_start=93694
+  _globals['_KVMSETWAYFLUSHFTRACEEVENT']._serialized_end=93753
+  _globals['_KVMSYSACCESSFTRACEEVENT']._serialized_start=93756
+  _globals['_KVMSYSACCESSFTRACEEVENT']._serialized_end=93895
+  _globals['_KVMTESTAGEHVAFTRACEEVENT']._serialized_start=93897
+  _globals['_KVMTESTAGEHVAFTRACEEVENT']._serialized_end=93936
+  _globals['_KVMTIMEREMULATEFTRACEEVENT']._serialized_start=93938
+  _globals['_KVMTIMEREMULATEFTRACEEVENT']._serialized_end=94006
+  _globals['_KVMTIMERHRTIMEREXPIREFTRACEEVENT']._serialized_start=94008
+  _globals['_KVMTIMERHRTIMEREXPIREFTRACEEVENT']._serialized_end=94061
+  _globals['_KVMTIMERRESTORESTATEFTRACEEVENT']._serialized_start=94063
+  _globals['_KVMTIMERRESTORESTATEFTRACEEVENT']._serialized_end=94142
+  _globals['_KVMTIMERSAVESTATEFTRACEEVENT']._serialized_start=94144
+  _globals['_KVMTIMERSAVESTATEFTRACEEVENT']._serialized_end=94220
+  _globals['_KVMTIMERUPDATEIRQFTRACEEVENT']._serialized_start=94222
+  _globals['_KVMTIMERUPDATEIRQFTRACEEVENT']._serialized_end=94297
+  _globals['_KVMTOGGLECACHEFTRACEEVENT']._serialized_start=94299
+  _globals['_KVMTOGGLECACHEFTRACEEVENT']._serialized_end=94369
+  _globals['_KVMUNMAPHVARANGEFTRACEEVENT']._serialized_start=94371
+  _globals['_KVMUNMAPHVARANGEFTRACEEVENT']._serialized_end=94428
+  _globals['_KVMUSERSPACEEXITFTRACEEVENT']._serialized_start=94430
+  _globals['_KVMUSERSPACEEXITFTRACEEVENT']._serialized_end=94475
+  _globals['_KVMVCPUWAKEUPFTRACEEVENT']._serialized_start=94477
+  _globals['_KVMVCPUWAKEUPFTRACEEVENT']._serialized_end=94546
+  _globals['_KVMWFXARM64FTRACEEVENT']._serialized_start=94548
+  _globals['_KVMWFXARM64FTRACEEVENT']._serialized_end=94605
+  _globals['_TRAPREGFTRACEEVENT']._serialized_start=94607
+  _globals['_TRAPREGFTRACEEVENT']._serialized_end=94691
+  _globals['_VGICUPDATEIRQPENDINGFTRACEEVENT']._serialized_start=94693
+  _globals['_VGICUPDATEIRQPENDINGFTRACEEVENT']._serialized_end=94771
+  _globals['_LOWMEMORYKILLFTRACEEVENT']._serialized_start=94773
+  _globals['_LOWMEMORYKILLFTRACEEVENT']._serialized_end=94889
+  _globals['_LWISTRACINGMARKWRITEFTRACEEVENT']._serialized_start=94891
+  _globals['_LWISTRACINGMARKWRITEFTRACEEVENT']._serialized_end=95004
+  _globals['_MALITRACINGMARKWRITEFTRACEEVENT']._serialized_start=95006
+  _globals['_MALITRACINGMARKWRITEFTRACEEVENT']._serialized_end=95095
+  _globals['_MALIMALIKCPUCQSSETFTRACEEVENT']._serialized_start=95097
+  _globals['_MALIMALIKCPUCQSSETFTRACEEVENT']._serialized_end=95214
+  _globals['_MALIMALIKCPUCQSWAITSTARTFTRACEEVENT']._serialized_start=95216
+  _globals['_MALIMALIKCPUCQSWAITSTARTFTRACEEVENT']._serialized_end=95339
+  _globals['_MALIMALIKCPUCQSWAITENDFTRACEEVENT']._serialized_start=95341
+  _globals['_MALIMALIKCPUCQSWAITENDFTRACEEVENT']._serialized_end=95462
+  _globals['_MALIMALIKCPUFENCESIGNALFTRACEEVENT']._serialized_start=95464
+  _globals['_MALIMALIKCPUFENCESIGNALFTRACEEVENT']._serialized_end=95586
+  _globals['_MALIMALIKCPUFENCEWAITSTARTFTRACEEVENT']._serialized_start=95588
+  _globals['_MALIMALIKCPUFENCEWAITSTARTFTRACEEVENT']._serialized_end=95713
+  _globals['_MALIMALIKCPUFENCEWAITENDFTRACEEVENT']._serialized_start=95715
+  _globals['_MALIMALIKCPUFENCEWAITENDFTRACEEVENT']._serialized_end=95838
+  _globals['_MALIMALICSFINTERRUPTSTARTFTRACEEVENT']._serialized_start=95840
+  _globals['_MALIMALICSFINTERRUPTSTARTFTRACEEVENT']._serialized_end=95932
+  _globals['_MALIMALICSFINTERRUPTENDFTRACEEVENT']._serialized_start=95934
+  _globals['_MALIMALICSFINTERRUPTENDFTRACEEVENT']._serialized_end=96024
+  _globals['_MALIMALIPMMCUHCTLCORESDOWNSCALENOTIFYPENDFTRACEEVENT']._serialized_start=96026
+  _globals['_MALIMALIPMMCUHCTLCORESDOWNSCALENOTIFYPENDFTRACEEVENT']._serialized_end=96134
+  _globals['_MALIMALIPMMCUHCTLCORESNOTIFYPENDFTRACEEVENT']._serialized_start=96136
+  _globals['_MALIMALIPMMCUHCTLCORESNOTIFYPENDFTRACEEVENT']._serialized_end=96235
+  _globals['_MALIMALIPMMCUHCTLCOREINACTIVEPENDFTRACEEVENT']._serialized_start=96237
+  _globals['_MALIMALIPMMCUHCTLCOREINACTIVEPENDFTRACEEVENT']._serialized_end=96337
+  _globals['_MALIMALIPMMCUHCTLMCUONRECHECKFTRACEEVENT']._serialized_start=96339
+  _globals['_MALIMALIPMMCUHCTLMCUONRECHECKFTRACEEVENT']._serialized_end=96435
+  _globals['_MALIMALIPMMCUHCTLSHADERSCOREOFFPENDFTRACEEVENT']._serialized_start=96437
+  _globals['_MALIMALIPMMCUHCTLSHADERSCOREOFFPENDFTRACEEVENT']._serialized_end=96539
+  _globals['_MALIMALIPMMCUHCTLSHADERSPENDOFFFTRACEEVENT']._serialized_start=96541
+  _globals['_MALIMALIPMMCUHCTLSHADERSPENDOFFFTRACEEVENT']._serialized_end=96639
+  _globals['_MALIMALIPMMCUHCTLSHADERSPENDONFTRACEEVENT']._serialized_start=96641
+  _globals['_MALIMALIPMMCUHCTLSHADERSPENDONFTRACEEVENT']._serialized_end=96738
+  _globals['_MALIMALIPMMCUHCTLSHADERSREADYOFFFTRACEEVENT']._serialized_start=96740
+  _globals['_MALIMALIPMMCUHCTLSHADERSREADYOFFFTRACEEVENT']._serialized_end=96839
+  _globals['_MALIMALIPMMCUINSLEEPFTRACEEVENT']._serialized_start=96841
+  _globals['_MALIMALIPMMCUINSLEEPFTRACEEVENT']._serialized_end=96928
+  _globals['_MALIMALIPMMCUOFFFTRACEEVENT']._serialized_start=96930
+  _globals['_MALIMALIPMMCUOFFFTRACEEVENT']._serialized_end=97013
+  _globals['_MALIMALIPMMCUONFTRACEEVENT']._serialized_start=97015
+  _globals['_MALIMALIPMMCUONFTRACEEVENT']._serialized_end=97097
+  _globals['_MALIMALIPMMCUONCOREATTRUPDATEPENDFTRACEEVENT']._serialized_start=97099
+  _globals['_MALIMALIPMMCUONCOREATTRUPDATEPENDFTRACEEVENT']._serialized_end=97199
+  _globals['_MALIMALIPMMCUONGLBREINITPENDFTRACEEVENT']._serialized_start=97201
+  _globals['_MALIMALIPMMCUONGLBREINITPENDFTRACEEVENT']._serialized_end=97296
+  _globals['_MALIMALIPMMCUONHALTFTRACEEVENT']._serialized_start=97298
+  _globals['_MALIMALIPMMCUONHALTFTRACEEVENT']._serialized_end=97384
+  _globals['_MALIMALIPMMCUONHWCNTDISABLEFTRACEEVENT']._serialized_start=97386
+  _globals['_MALIMALIPMMCUONHWCNTDISABLEFTRACEEVENT']._serialized_end=97480
+  _globals['_MALIMALIPMMCUONHWCNTENABLEFTRACEEVENT']._serialized_start=97482
+  _globals['_MALIMALIPMMCUONHWCNTENABLEFTRACEEVENT']._serialized_end=97575
+  _globals['_MALIMALIPMMCUONPENDHALTFTRACEEVENT']._serialized_start=97577
+  _globals['_MALIMALIPMMCUONPENDHALTFTRACEEVENT']._serialized_end=97667
+  _globals['_MALIMALIPMMCUONPENDSLEEPFTRACEEVENT']._serialized_start=97669
+  _globals['_MALIMALIPMMCUONPENDSLEEPFTRACEEVENT']._serialized_end=97760
+  _globals['_MALIMALIPMMCUONSLEEPINITIATEFTRACEEVENT']._serialized_start=97762
+  _globals['_MALIMALIPMMCUONSLEEPINITIATEFTRACEEVENT']._serialized_end=97857
+  _globals['_MALIMALIPMMCUPENDOFFFTRACEEVENT']._serialized_start=97859
+  _globals['_MALIMALIPMMCUPENDOFFFTRACEEVENT']._serialized_end=97946
+  _globals['_MALIMALIPMMCUPENDONRELOADFTRACEEVENT']._serialized_start=97948
+  _globals['_MALIMALIPMMCUPENDONRELOADFTRACEEVENT']._serialized_end=98040
+  _globals['_MALIMALIPMMCUPOWERDOWNFTRACEEVENT']._serialized_start=98042
+  _globals['_MALIMALIPMMCUPOWERDOWNFTRACEEVENT']._serialized_end=98131
+  _globals['_MALIMALIPMMCURESETWAITFTRACEEVENT']._serialized_start=98133
+  _globals['_MALIMALIPMMCURESETWAITFTRACEEVENT']._serialized_end=98222
+  _globals['_MALIGPUPOWERSTATEFTRACEEVENT']._serialized_start=98224
+  _globals['_MALIGPUPOWERSTATEFTRACEEVENT']._serialized_end=98311
+  _globals['_MDPCMDKICKOFFFTRACEEVENT']._serialized_start=98313
+  _globals['_MDPCMDKICKOFFFTRACEEVENT']._serialized_end=98377
+  _globals['_MDPCOMMITFTRACEEVENT']._serialized_start=98379
+  _globals['_MDPCOMMITFTRACEEVENT']._serialized_end=98469
+  _globals['_MDPPERFSETOTFTRACEEVENT']._serialized_start=98471
+  _globals['_MDPPERFSETOTFTRACEEVENT']._serialized_end=98562
+  _globals['_MDPSSPPCHANGEFTRACEEVENT']._serialized_start=98565
+  _globals['_MDPSSPPCHANGEFTRACEEVENT']._serialized_end=98833
+  _globals['_TRACINGMARKWRITEFTRACEEVENT']._serialized_start=98835
+  _globals['_TRACINGMARKWRITEFTRACEEVENT']._serialized_end=98918
+  _globals['_MDPCMDPINGPONGDONEFTRACEEVENT']._serialized_start=98920
+  _globals['_MDPCMDPINGPONGDONEFTRACEEVENT']._serialized_end=99020
+  _globals['_MDPCOMPAREBWFTRACEEVENT']._serialized_start=99023
+  _globals['_MDPCOMPAREBWFTRACEEVENT']._serialized_end=99187
+  _globals['_MDPPERFSETPANICLUTSFTRACEEVENT']._serialized_start=99189
+  _globals['_MDPPERFSETPANICLUTSFTRACEEVENT']._serialized_end=99301
+  _globals['_MDPSSPPSETFTRACEEVENT']._serialized_start=99304
+  _globals['_MDPSSPPSETFTRACEEVENT']._serialized_end=99569
+  _globals['_MDPCMDREADPTRDONEFTRACEEVENT']._serialized_start=99571
+  _globals['_MDPCMDREADPTRDONEFTRACEEVENT']._serialized_end=99636
+  _globals['_MDPMISRCRCFTRACEEVENT']._serialized_start=99638
+  _globals['_MDPMISRCRCFTRACEEVENT']._serialized_end=99711
+  _globals['_MDPPERFSETQOSLUTSFTRACEEVENT']._serialized_start=99713
+  _globals['_MDPPERFSETQOSLUTSFTRACEEVENT']._serialized_end=99838
+  _globals['_MDPTRACECOUNTERFTRACEEVENT']._serialized_start=99840
+  _globals['_MDPTRACECOUNTERFTRACEEVENT']._serialized_end=99918
+  _globals['_MDPCMDRELEASEBWFTRACEEVENT']._serialized_start=99920
+  _globals['_MDPCMDRELEASEBWFTRACEEVENT']._serialized_end=99965
+  _globals['_MDPMIXERUPDATEFTRACEEVENT']._serialized_start=99967
+  _globals['_MDPMIXERUPDATEFTRACEEVENT']._serialized_end=100013
+  _globals['_MDPPERFSETWMLEVELSFTRACEEVENT']._serialized_start=100016
+  _globals['_MDPPERFSETWMLEVELSFTRACEEVENT']._serialized_end=100176
+  _globals['_MDPVIDEOUNDERRUNDONEFTRACEEVENT']._serialized_start=100178
+  _globals['_MDPVIDEOUNDERRUNDONEFTRACEEVENT']._serialized_end=100250
+  _globals['_MDPCMDWAITPINGPONGFTRACEEVENT']._serialized_start=100252
+  _globals['_MDPCMDWAITPINGPONGFTRACEEVENT']._serialized_end=100321
+  _globals['_MDPPERFPREFILLCALCFTRACEEVENT']._serialized_start=100324
+  _globals['_MDPPERFPREFILLCALCFTRACEEVENT']._serialized_end=100530
+  _globals['_MDPPERFUPDATEBUSFTRACEEVENT']._serialized_start=100532
+  _globals['_MDPPERFUPDATEBUSFTRACEEVENT']._serialized_end=100613
+  _globals['_ROTATORBWAOASCONTEXTFTRACEEVENT']._serialized_start=100615
+  _globals['_ROTATORBWAOASCONTEXTFTRACEEVENT']._serialized_end=100663
+  _globals['_MMEVENTRECORDFTRACEEVENT']._serialized_start=100665
+  _globals['_MMEVENTRECORDFTRACEEVENT']._serialized_end=100754
+  _globals['_NETIFRECEIVESKBFTRACEEVENT']._serialized_start=100756
+  _globals['_NETIFRECEIVESKBFTRACEEVENT']._serialized_end=100828
+  _globals['_NETDEVXMITFTRACEEVENT']._serialized_start=100830
+  _globals['_NETDEVXMITFTRACEEVENT']._serialized_end=100909
+  _globals['_NAPIGRORECEIVEENTRYFTRACEEVENT']._serialized_start=100912
+  _globals['_NAPIGRORECEIVEENTRYFTRACEEVENT']._serialized_end=101291
+  _globals['_NAPIGRORECEIVEEXITFTRACEEVENT']._serialized_start=101293
+  _globals['_NAPIGRORECEIVEEXITFTRACEEVENT']._serialized_end=101337
+  _globals['_OOMSCOREADJUPDATEFTRACEEVENT']._serialized_start=101339
+  _globals['_OOMSCOREADJUPDATEFTRACEEVENT']._serialized_end=101419
+  _globals['_MARKVICTIMFTRACEEVENT']._serialized_start=101421
+  _globals['_MARKVICTIMFTRACEEVENT']._serialized_end=101457
+  _globals['_DSICMDFIFOSTATUSFTRACEEVENT']._serialized_start=101459
+  _globals['_DSICMDFIFOSTATUSFTRACEEVENT']._serialized_end=101521
+  _globals['_DSIRXFTRACEEVENT']._serialized_start=101523
+  _globals['_DSIRXFTRACEEVENT']._serialized_end=101570
+  _globals['_DSITXFTRACEEVENT']._serialized_start=101572
+  _globals['_DSITXFTRACEEVENT']._serialized_end=101634
+  _globals['_PANELWRITEGENERICFTRACEEVENT']._serialized_start=101636
+  _globals['_PANELWRITEGENERICFTRACEEVENT']._serialized_end=101763
+  _globals['_GRAMCOLLISIONFTRACEEVENT']._serialized_start=101765
+  _globals['_GRAMCOLLISIONFTRACEEVENT']._serialized_end=101835
+  _globals['_PANELSETTINGSFULLFTRACEEVENT']._serialized_start=101838
+  _globals['_PANELSETTINGSFULLFTRACEEVENT']._serialized_end=102035
+  _globals['_PANELSETTINGSLITEFTRACEEVENT']._serialized_start=102037
+  _globals['_PANELSETTINGSLITEFTRACEEVENT']._serialized_end=102150
+  _globals['_SCHEDSWITCHWITHCTRSFTRACEEVENT']._serialized_start=102153
+  _globals['_SCHEDSWITCHWITHCTRSFTRACEEVENT']._serialized_end=102541
+  _globals['_LONGIRQFTRACEEVENT']._serialized_start=102543
+  _globals['_LONGIRQFTRACEEVENT']._serialized_end=102608
+  _globals['_LONGSOFTIRQFTRACEEVENT']._serialized_start=102610
+  _globals['_LONGSOFTIRQFTRACEEVENT']._serialized_end=102682
+  _globals['_PIXELMMKSWAPDWAKEFTRACEEVENT']._serialized_start=102684
+  _globals['_PIXELMMKSWAPDWAKEFTRACEEVENT']._serialized_end=102732
+  _globals['_PIXELMMKSWAPDDONEFTRACEEVENT']._serialized_start=102735
+  _globals['_PIXELMMKSWAPDDONEFTRACEEVENT']._serialized_end=102868
+  _globals['_CPUFREQUENCYFTRACEEVENT']._serialized_start=102870
+  _globals['_CPUFREQUENCYFTRACEEVENT']._serialized_end=102926
+  _globals['_CPUFREQUENCYLIMITSFTRACEEVENT']._serialized_start=102928
+  _globals['_CPUFREQUENCYLIMITSFTRACEEVENT']._serialized_end=103011
+  _globals['_CPUIDLEFTRACEEVENT']._serialized_start=103013
+  _globals['_CPUIDLEFTRACEEVENT']._serialized_end=103064
+  _globals['_CLOCKENABLEFTRACEEVENT']._serialized_start=103066
+  _globals['_CLOCKENABLEFTRACEEVENT']._serialized_end=103135
+  _globals['_CLOCKDISABLEFTRACEEVENT']._serialized_start=103137
+  _globals['_CLOCKDISABLEFTRACEEVENT']._serialized_end=103207
+  _globals['_CLOCKSETRATEFTRACEEVENT']._serialized_start=103209
+  _globals['_CLOCKSETRATEFTRACEEVENT']._serialized_end=103279
+  _globals['_SUSPENDRESUMEFTRACEEVENT']._serialized_start=103281
+  _globals['_SUSPENDRESUMEFTRACEEVENT']._serialized_end=103351
+  _globals['_GPUFREQUENCYFTRACEEVENT']._serialized_start=103353
+  _globals['_GPUFREQUENCYFTRACEEVENT']._serialized_end=103409
+  _globals['_WAKEUPSOURCEACTIVATEFTRACEEVENT']._serialized_start=103411
+  _globals['_WAKEUPSOURCEACTIVATEFTRACEEVENT']._serialized_end=103473
+  _globals['_WAKEUPSOURCEDEACTIVATEFTRACEEVENT']._serialized_start=103475
+  _globals['_WAKEUPSOURCEDEACTIVATEFTRACEEVENT']._serialized_end=103539
+  _globals['_GPUWORKPERIODFTRACEEVENT']._serialized_start=103542
+  _globals['_GPUWORKPERIODFTRACEEVENT']._serialized_end=103675
+  _globals['_DEVICEPMCALLBACKSTARTFTRACEEVENT']._serialized_start=103677
+  _globals['_DEVICEPMCALLBACKSTARTFTRACEEVENT']._serialized_end=103790
+  _globals['_DEVICEPMCALLBACKENDFTRACEEVENT']._serialized_start=103792
+  _globals['_DEVICEPMCALLBACKENDFTRACEEVENT']._serialized_end=103871
+  _globals['_GPUPOWERSTATEFTRACEEVENT']._serialized_start=103873
+  _globals['_GPUPOWERSTATEFTRACEEVENT']._serialized_end=103937
+  _globals['_PSCIDOMAINIDLEEXITFTRACEEVENT']._serialized_start=103939
+  _globals['_PSCIDOMAINIDLEEXITFTRACEEVENT']._serialized_end=104017
+  _globals['_PSCIDOMAINIDLEENTERFTRACEEVENT']._serialized_start=104019
+  _globals['_PSCIDOMAINIDLEENTERFTRACEEVENT']._serialized_end=104098
+  _globals['_CONSOLEFTRACEEVENT']._serialized_start=104100
+  _globals['_CONSOLEFTRACEEVENT']._serialized_end=104133
+  _globals['_SYSENTERFTRACEEVENT']._serialized_start=104135
+  _globals['_SYSENTERFTRACEEVENT']._serialized_end=104182
+  _globals['_SYSEXITFTRACEEVENT']._serialized_start=104184
+  _globals['_SYSEXITFTRACEEVENT']._serialized_end=104229
+  _globals['_REGULATORDISABLEFTRACEEVENT']._serialized_start=104231
+  _globals['_REGULATORDISABLEFTRACEEVENT']._serialized_end=104274
+  _globals['_REGULATORDISABLECOMPLETEFTRACEEVENT']._serialized_start=104276
+  _globals['_REGULATORDISABLECOMPLETEFTRACEEVENT']._serialized_end=104327
+  _globals['_REGULATORENABLEFTRACEEVENT']._serialized_start=104329
+  _globals['_REGULATORENABLEFTRACEEVENT']._serialized_end=104371
+  _globals['_REGULATORENABLECOMPLETEFTRACEEVENT']._serialized_start=104373
+  _globals['_REGULATORENABLECOMPLETEFTRACEEVENT']._serialized_end=104423
+  _globals['_REGULATORENABLEDELAYFTRACEEVENT']._serialized_start=104425
+  _globals['_REGULATORENABLEDELAYFTRACEEVENT']._serialized_end=104472
+  _globals['_REGULATORSETVOLTAGEFTRACEEVENT']._serialized_start=104474
+  _globals['_REGULATORSETVOLTAGEFTRACEEVENT']._serialized_end=104546
+  _globals['_REGULATORSETVOLTAGECOMPLETEFTRACEEVENT']._serialized_start=104548
+  _globals['_REGULATORSETVOLTAGECOMPLETEFTRACEEVENT']._serialized_end=104615
+  _globals['_RPMSTATUSFTRACEEVENT']._serialized_start=104617
+  _globals['_RPMSTATUSFTRACEEVENT']._serialized_end=104669
+  _globals['_SAMSUNGTRACINGMARKWRITEFTRACEEVENT']._serialized_start=104671
+  _globals['_SAMSUNGTRACINGMARKWRITEFTRACEEVENT']._serialized_end=104796
+  _globals['_SCHEDSWITCHFTRACEEVENT']._serialized_start=104799
+  _globals['_SCHEDSWITCHFTRACEEVENT']._serialized_end=104955
+  _globals['_SCHEDWAKEUPFTRACEEVENT']._serialized_start=104957
+  _globals['_SCHEDWAKEUPFTRACEEVENT']._serialized_end=105059
+  _globals['_SCHEDBLOCKEDREASONFTRACEEVENT']._serialized_start=105061
+  _globals['_SCHEDBLOCKEDREASONFTRACEEVENT']._serialized_end=105138
+  _globals['_SCHEDCPUHOTPLUGFTRACEEVENT']._serialized_start=105140
+  _globals['_SCHEDCPUHOTPLUGFTRACEEVENT']._serialized_end=105221
+  _globals['_SCHEDWAKINGFTRACEEVENT']._serialized_start=105223
+  _globals['_SCHEDWAKINGFTRACEEVENT']._serialized_end=105325
+  _globals['_SCHEDWAKEUPNEWFTRACEEVENT']._serialized_start=105327
+  _globals['_SCHEDWAKEUPNEWFTRACEEVENT']._serialized_end=105432
+  _globals['_SCHEDPROCESSEXECFTRACEEVENT']._serialized_start=105434
+  _globals['_SCHEDPROCESSEXECFTRACEEVENT']._serialized_end=105511
+  _globals['_SCHEDPROCESSEXITFTRACEEVENT']._serialized_start=105513
+  _globals['_SCHEDPROCESSEXITFTRACEEVENT']._serialized_end=105597
+  _globals['_SCHEDPROCESSFORKFTRACEEVENT']._serialized_start=105599
+  _globals['_SCHEDPROCESSFORKFTRACEEVENT']._serialized_end=105708
+  _globals['_SCHEDPROCESSFREEFTRACEEVENT']._serialized_start=105710
+  _globals['_SCHEDPROCESSFREEFTRACEEVENT']._serialized_end=105780
+  _globals['_SCHEDPROCESSHANGFTRACEEVENT']._serialized_start=105782
+  _globals['_SCHEDPROCESSHANGFTRACEEVENT']._serialized_end=105838
+  _globals['_SCHEDPROCESSWAITFTRACEEVENT']._serialized_start=105840
+  _globals['_SCHEDPROCESSWAITFTRACEEVENT']._serialized_end=105910
+  _globals['_SCHEDPISETPRIOFTRACEEVENT']._serialized_start=105912
+  _globals['_SCHEDPISETPRIOFTRACEEVENT']._serialized_end=106000
+  _globals['_SCHEDCPUUTILCFSFTRACEEVENT']._serialized_start=106003
+  _globals['_SCHEDCPUUTILCFSFTRACEEVENT']._serialized_end=106331
+  _globals['_SCHEDMIGRATETASKFTRACEEVENT']._serialized_start=106334
+  _globals['_SCHEDMIGRATETASKFTRACEEVENT']._serialized_end=106471
+  _globals['_SCHEDWAKEUPTASKATTRFTRACEEVENT']._serialized_start=106474
+  _globals['_SCHEDWAKEUPTASKATTRFTRACEEVENT']._serialized_end=106714
+  _globals['_SCHEDGROUPTRACKERFTRACEEVENT']._serialized_start=106716
+  _globals['_SCHEDGROUPTRACKERFTRACEEVENT']._serialized_end=106807
+  _globals['_SCMCALLSTARTFTRACEEVENT']._serialized_start=106809
+  _globals['_SCMCALLSTARTFTRACEEVENT']._serialized_end=106875
+  _globals['_SCMCALLENDFTRACEEVENT']._serialized_start=106877
+  _globals['_SCMCALLENDFTRACEEVENT']._serialized_end=106900
+  _globals['_SCSIDISPATCHCMDERRORFTRACEEVENT']._serialized_start=106903
+  _globals['_SCSIDISPATCHCMDERRORFTRACEEVENT']._serialized_end=107155
+  _globals['_SCSIDISPATCHCMDTIMEOUTFTRACEEVENT']._serialized_start=107158
+  _globals['_SCSIDISPATCHCMDTIMEOUTFTRACEEVENT']._serialized_end=107461
+  _globals['_SCSIEHWAKEUPFTRACEEVENT']._serialized_start=107463
+  _globals['_SCSIEHWAKEUPFTRACEEVENT']._serialized_end=107505
+  _globals['_SDETRACINGMARKWRITEFTRACEEVENT']._serialized_start=107507
+  _globals['_SDETRACINGMARKWRITEFTRACEEVENT']._serialized_end=107628
+  _globals['_SDESDEEVTLOGFTRACEEVENT']._serialized_start=107631
+  _globals['_SDESDEEVTLOGFTRACEEVENT']._serialized_end=107900
+  _globals['_SDESDEPERFCALCCRTCFTRACEEVENT']._serialized_start=107903
+  _globals['_SDESDEPERFCALCCRTCFTRACEEVENT']._serialized_end=108083
+  _globals['_SDESDEPERFCRTCUPDATEFTRACEEVENT']._serialized_start=108086
+  _globals['_SDESDEPERFCRTCUPDATEFTRACEEVENT']._serialized_end=108369
+  _globals['_SDESDEPERFSETQOSLUTSFTRACEEVENT']._serialized_start=108371
+  _globals['_SDESDEPERFSETQOSLUTSFTRACEEVENT']._serialized_end=108487
+  _globals['_SDESDEPERFUPDATEBUSFTRACEEVENT']._serialized_start=108489
+  _globals['_SDESDEPERFUPDATEBUSFTRACEEVENT']._serialized_end=108589
+  _globals['_SIGNALDELIVERFTRACEEVENT']._serialized_start=108591
+  _globals['_SIGNALDELIVERFTRACEEVENT']._serialized_end=108662
+  _globals['_SIGNALGENERATEFTRACEEVENT']._serialized_start=108664
+  _globals['_SIGNALGENERATEFTRACEEVENT']._serialized_end=108776
+  _globals['_KFREESKBFTRACEEVENT']._serialized_start=108778
+  _globals['_KFREESKBFTRACEEVENT']._serialized_end=108852
+  _globals['_INETSOCKSETSTATEFTRACEEVENT']._serialized_start=108855
+  _globals['_INETSOCKSETSTATEFTRACEEVENT']._serialized_end=109030
+  _globals['_SYNCPTFTRACEEVENT']._serialized_start=109032
+  _globals['_SYNCPTFTRACEEVENT']._serialized_end=109084
+  _globals['_SYNCTIMELINEFTRACEEVENT']._serialized_start=109086
+  _globals['_SYNCTIMELINEFTRACEEVENT']._serialized_end=109140
+  _globals['_SYNCWAITFTRACEEVENT']._serialized_start=109142
+  _globals['_SYNCWAITFTRACEEVENT']._serialized_end=109208
+  _globals['_RSSSTATTHROTTLEDFTRACEEVENT']._serialized_start=109210
+  _globals['_RSSSTATTHROTTLEDFTRACEEVENT']._serialized_end=109298
+  _globals['_SUSPENDRESUMEMINIMALFTRACEEVENT']._serialized_start=109300
+  _globals['_SUSPENDRESUMEMINIMALFTRACEEVENT']._serialized_end=109348
+  _globals['_ZEROFTRACEEVENT']._serialized_start=109350
+  _globals['_ZEROFTRACEEVENT']._serialized_end=109423
+  _globals['_TASKNEWTASKFTRACEEVENT']._serialized_start=109425
+  _globals['_TASKNEWTASKFTRACEEVENT']._serialized_end=109520
+  _globals['_TASKRENAMEFTRACEEVENT']._serialized_start=109522
+  _globals['_TASKRENAMEFTRACEEVENT']._serialized_end=109615
+  _globals['_TCPRETRANSMITSKBFTRACEEVENT']._serialized_start=109618
+  _globals['_TCPRETRANSMITSKBFTRACEEVENT']._serialized_end=109755
+  _globals['_THERMALTEMPERATUREFTRACEEVENT']._serialized_start=109757
+  _globals['_THERMALTEMPERATUREFTRACEEVENT']._serialized_end=109855
+  _globals['_CDEVUPDATEFTRACEEVENT']._serialized_start=109857
+  _globals['_CDEVUPDATEFTRACEEVENT']._serialized_end=109910
+  _globals['_THERMALEXYNOSACPMBULKFTRACEEVENT']._serialized_start=109913
+  _globals['_THERMALEXYNOSACPMBULKFTRACEEVENT']._serialized_end=110141
+  _globals['_THERMALEXYNOSACPMHIGHOVERHEADFTRACEEVENT']._serialized_start=110144
+  _globals['_THERMALEXYNOSACPMHIGHOVERHEADFTRACEEVENT']._serialized_end=110306
+  _globals['_HRTIMERSTARTFTRACEEVENT']._serialized_start=110308
+  _globals['_HRTIMERSTARTFTRACEEVENT']._serialized_end=110420
+  _globals['_HRTIMERCANCELFTRACEEVENT']._serialized_start=110422
+  _globals['_HRTIMERCANCELFTRACEEVENT']._serialized_end=110465
+  _globals['_HRTIMEREXPIREENTRYFTRACEEVENT']._serialized_start=110467
+  _globals['_HRTIMEREXPIREENTRYFTRACEEVENT']._serialized_end=110546
+  _globals['_HRTIMEREXPIREEXITFTRACEEVENT']._serialized_start=110548
+  _globals['_HRTIMEREXPIREEXITFTRACEEVENT']._serialized_end=110595
+  _globals['_TIMERSTARTFTRACEEVENT']._serialized_start=110598
+  _globals['_TIMERSTARTFTRACEEVENT']._serialized_end=110742
+  _globals['_TIMERCANCELFTRACEEVENT']._serialized_start=110744
+  _globals['_TIMERCANCELFTRACEEVENT']._serialized_end=110783
+  _globals['_TIMEREXPIREENTRYFTRACEEVENT']._serialized_start=110785
+  _globals['_TIMEREXPIREENTRYFTRACEEVENT']._serialized_end=110877
+  _globals['_TIMEREXPIREEXITFTRACEEVENT']._serialized_start=110879
+  _globals['_TIMEREXPIREEXITFTRACEEVENT']._serialized_end=110922
+  _globals['_TRUSTYSMCFTRACEEVENT']._serialized_start=110924
+  _globals['_TRUSTYSMCFTRACEEVENT']._serialized_end=110994
+  _globals['_TRUSTYSMCDONEFTRACEEVENT']._serialized_start=110996
+  _globals['_TRUSTYSMCDONEFTRACEEVENT']._serialized_end=111035
+  _globals['_TRUSTYSTDCALL32FTRACEEVENT']._serialized_start=111037
+  _globals['_TRUSTYSTDCALL32FTRACEEVENT']._serialized_end=111113
+  _globals['_TRUSTYSTDCALL32DONEFTRACEEVENT']._serialized_start=111115
+  _globals['_TRUSTYSTDCALL32DONEFTRACEEVENT']._serialized_end=111160
+  _globals['_TRUSTYSHAREMEMORYFTRACEEVENT']._serialized_start=111162
+  _globals['_TRUSTYSHAREMEMORYFTRACEEVENT']._serialized_end=111234
+  _globals['_TRUSTYSHAREMEMORYDONEFTRACEEVENT']._serialized_start=111236
+  _globals['_TRUSTYSHAREMEMORYDONEFTRACEEVENT']._serialized_end=111341
+  _globals['_TRUSTYRECLAIMMEMORYFTRACEEVENT']._serialized_start=111343
+  _globals['_TRUSTYRECLAIMMEMORYFTRACEEVENT']._serialized_end=111387
+  _globals['_TRUSTYRECLAIMMEMORYDONEFTRACEEVENT']._serialized_start=111389
+  _globals['_TRUSTYRECLAIMMEMORYDONEFTRACEEVENT']._serialized_end=111450
+  _globals['_TRUSTYIRQFTRACEEVENT']._serialized_start=111452
+  _globals['_TRUSTYIRQFTRACEEVENT']._serialized_end=111487
+  _globals['_TRUSTYIPCHANDLEEVENTFTRACEEVENT']._serialized_start=111489
+  _globals['_TRUSTYIPCHANDLEEVENTFTRACEEVENT']._serialized_end=111572
+  _globals['_TRUSTYIPCCONNECTFTRACEEVENT']._serialized_start=111574
+  _globals['_TRUSTYIPCCONNECTFTRACEEVENT']._serialized_end=111646
+  _globals['_TRUSTYIPCCONNECTENDFTRACEEVENT']._serialized_start=111648
+  _globals['_TRUSTYIPCCONNECTENDFTRACEEVENT']._serialized_end=111722
+  _globals['_TRUSTYIPCWRITEFTRACEEVENT']._serialized_start=111725
+  _globals['_TRUSTYIPCWRITEFTRACEEVENT']._serialized_end=111855
+  _globals['_TRUSTYIPCPOLLFTRACEEVENT']._serialized_start=111857
+  _globals['_TRUSTYIPCPOLLFTRACEEVENT']._serialized_end=111934
+  _globals['_TRUSTYIPCREADFTRACEEVENT']._serialized_start=111936
+  _globals['_TRUSTYIPCREADFTRACEEVENT']._serialized_end=111994
+  _globals['_TRUSTYIPCREADENDFTRACEEVENT']._serialized_start=111996
+  _globals['_TRUSTYIPCREADENDFTRACEEVENT']._serialized_end=112110
+  _globals['_TRUSTYIPCRXFTRACEEVENT']._serialized_start=112112
+  _globals['_TRUSTYIPCRXFTRACEEVENT']._serialized_end=112184
+  _globals['_TRUSTYENQUEUENOPFTRACEEVENT']._serialized_start=112186
+  _globals['_TRUSTYENQUEUENOPFTRACEEVENT']._serialized_end=112257
+  _globals['_UFSHCDCOMMANDFTRACEEVENT']._serialized_start=112260
+  _globals['_UFSHCDCOMMANDFTRACEEVENT']._serialized_end=112446
+  _globals['_UFSHCDCLKGATINGFTRACEEVENT']._serialized_start=112448
+  _globals['_UFSHCDCLKGATINGFTRACEEVENT']._serialized_end=112509
+  _globals['_V4L2QBUFFTRACEEVENT']._serialized_start=112512
+  _globals['_V4L2QBUFFTRACEEVENT']._serialized_end=112923
+  _globals['_V4L2DQBUFFTRACEEVENT']._serialized_start=112926
+  _globals['_V4L2DQBUFFTRACEEVENT']._serialized_end=113338
+  _globals['_VB2V4L2BUFQUEUEFTRACEEVENT']._serialized_start=113341
+  _globals['_VB2V4L2BUFQUEUEFTRACEEVENT']._serialized_end=113711
+  _globals['_VB2V4L2BUFDONEFTRACEEVENT']._serialized_start=113714
+  _globals['_VB2V4L2BUFDONEFTRACEEVENT']._serialized_end=114083
+  _globals['_VB2V4L2QBUFFTRACEEVENT']._serialized_start=114086
+  _globals['_VB2V4L2QBUFFTRACEEVENT']._serialized_end=114452
+  _globals['_VB2V4L2DQBUFFTRACEEVENT']._serialized_start=114455
+  _globals['_VB2V4L2DQBUFFTRACEEVENT']._serialized_end=114822
+  _globals['_VIRTIOGPUCMDQUEUEFTRACEEVENT']._serialized_start=114825
+  _globals['_VIRTIOGPUCMDQUEUEFTRACEEVENT']._serialized_end=114990
+  _globals['_VIRTIOGPUCMDRESPONSEFTRACEEVENT']._serialized_start=114993
+  _globals['_VIRTIOGPUCMDRESPONSEFTRACEEVENT']._serialized_end=115161
+  _globals['_VIRTIOVIDEOCMDFTRACEEVENT']._serialized_start=115163
+  _globals['_VIRTIOVIDEOCMDFTRACEEVENT']._serialized_end=115223
+  _globals['_VIRTIOVIDEOCMDDONEFTRACEEVENT']._serialized_start=115225
+  _globals['_VIRTIOVIDEOCMDDONEFTRACEEVENT']._serialized_end=115289
+  _globals['_VIRTIOVIDEORESOURCEQUEUEFTRACEEVENT']._serialized_start=115292
+  _globals['_VIRTIOVIDEORESOURCEQUEUEFTRACEEVENT']._serialized_end=115488
+  _globals['_VIRTIOVIDEORESOURCEQUEUEDONEFTRACEEVENT']._serialized_start=115491
+  _globals['_VIRTIOVIDEORESOURCEQUEUEDONEFTRACEEVENT']._serialized_end=115691
+  _globals['_MMVMSCANDIRECTRECLAIMBEGINFTRACEEVENT']._serialized_start=115693
+  _globals['_MMVMSCANDIRECTRECLAIMBEGINFTRACEEVENT']._serialized_end=115789
+  _globals['_MMVMSCANDIRECTRECLAIMENDFTRACEEVENT']._serialized_start=115791
+  _globals['_MMVMSCANDIRECTRECLAIMENDFTRACEEVENT']._serialized_end=115850
+  _globals['_MMVMSCANKSWAPDWAKEFTRACEEVENT']._serialized_start=115852
+  _globals['_MMVMSCANKSWAPDWAKEFTRACEEVENT']._serialized_end=115924
+  _globals['_MMVMSCANKSWAPDSLEEPFTRACEEVENT']._serialized_start=115926
+  _globals['_MMVMSCANKSWAPDSLEEPFTRACEEVENT']._serialized_end=115971
+  _globals['_MMSHRINKSLABSTARTFTRACEEVENT']._serialized_start=115974
+  _globals['_MMSHRINKSLABSTARTFTRACEEVENT']._serialized_end=116207
+  _globals['_MMSHRINKSLABENDFTRACEEVENT']._serialized_start=116210
+  _globals['_MMSHRINKSLABENDFTRACEEVENT']._serialized_end=116355
+  _globals['_MMVMSCANMEMCGRECLAIMBEGINFTRACEEVENT']._serialized_start=116357
+  _globals['_MMVMSCANMEMCGRECLAIMBEGINFTRACEEVENT']._serialized_end=116452
+  _globals['_MMVMSCANMEMCGRECLAIMENDFTRACEEVENT']._serialized_start=116454
+  _globals['_MMVMSCANMEMCGRECLAIMENDFTRACEEVENT']._serialized_end=116512
+  _globals['_WORKQUEUEACTIVATEWORKFTRACEEVENT']._serialized_start=116514
+  _globals['_WORKQUEUEACTIVATEWORKFTRACEEVENT']._serialized_end=116580
+  _globals['_WORKQUEUEEXECUTEENDFTRACEEVENT']._serialized_start=116582
+  _globals['_WORKQUEUEEXECUTEENDFTRACEEVENT']._serialized_end=116646
+  _globals['_WORKQUEUEEXECUTESTARTFTRACEEVENT']._serialized_start=116648
+  _globals['_WORKQUEUEEXECUTESTARTFTRACEEVENT']._serialized_end=116714
+  _globals['_WORKQUEUEQUEUEWORKFTRACEEVENT']._serialized_start=116716
+  _globals['_WORKQUEUEQUEUEWORKFTRACEEVENT']._serialized_end=116828
+  _globals['_FTRACEEVENT']._serialized_start=116832
+  _globals['_FTRACEEVENT']._serialized_end=163551
+  _globals['_FTRACECPUSTATS']._serialized_start=163554
+  _globals['_FTRACECPUSTATS']._serialized_end=163747
+  _globals['_FTRACEKPROBESTATS']._serialized_start=163749
+  _globals['_FTRACEKPROBESTATS']._serialized_end=163798
+  _globals['_FTRACESTATS']._serialized_start=163801
+  _globals['_FTRACESTATS']._serialized_end=164384
+  _globals['_FTRACESTATS_PHASE']._serialized_start=164322
+  _globals['_FTRACESTATS_PHASE']._serialized_end=164384
+  _globals['_FTRACEEVENTBUNDLE']._serialized_start=164387
+  _globals['_FTRACEEVENTBUNDLE']._serialized_end=165467
+  _globals['_FTRACEEVENTBUNDLE_COMPACTSCHED']._serialized_start=164925
+  _globals['_FTRACEEVENTBUNDLE_COMPACTSCHED']._serialized_end=165291
+  _globals['_FTRACEEVENTBUNDLE_FTRACEERROR']._serialized_start=165293
+  _globals['_FTRACEEVENTBUNDLE_FTRACEERROR']._serialized_end=165377
+  _globals['_FTRACEEVENTBUNDLE_GENERICEVENTDESCRIPTOR']._serialized_start=165379
+  _globals['_FTRACEEVENTBUNDLE_GENERICEVENTDESCRIPTOR']._serialized_end=165467
+  _globals['_GENERICGPUFREQUENCYEVENT']._serialized_start=165469
+  _globals['_GENERICGPUFREQUENCYEVENT']._serialized_end=165534
+  _globals['_GENERICKERNELCPUFREQUENCYEVENT']._serialized_start=165536
+  _globals['_GENERICKERNELCPUFREQUENCYEVENT']._serialized_end=165598
+  _globals['_GENERICKERNELTASKSTATEEVENT']._serialized_start=165601
+  _globals['_GENERICKERNELTASKSTATEEVENT']._serialized_end=166019
+  _globals['_GENERICKERNELTASKSTATEEVENT_TASKSTATEENUM']._serialized_start=165762
+  _globals['_GENERICKERNELTASKSTATEEVENT_TASKSTATEENUM']._serialized_end=166019
+  _globals['_GENERICKERNELTASKRENAMEEVENT']._serialized_start=166021
+  _globals['_GENERICKERNELTASKRENAMEEVENT']._serialized_end=166078
+  _globals['_GENERICKERNELPROCESSTREE']._serialized_start=166081
+  _globals['_GENERICKERNELPROCESSTREE']._serialized_end=166390
+  _globals['_GENERICKERNELPROCESSTREE_THREAD']._serialized_start=166246
+  _globals['_GENERICKERNELPROCESSTREE_THREAD']._serialized_end=166335
+  _globals['_GENERICKERNELPROCESSTREE_PROCESS']._serialized_start=166337
+  _globals['_GENERICKERNELPROCESSTREE_PROCESS']._serialized_end=166390
+  _globals['_GPUCOUNTEREVENT']._serialized_start=166393
+  _globals['_GPUCOUNTEREVENT']._serialized_end=166688
+  _globals['_GPUCOUNTEREVENT_GPUCOUNTER']._serialized_start=166594
+  _globals['_GPUCOUNTEREVENT_GPUCOUNTER']._serialized_end=166680
+  _globals['_INTERNEDGPUCOUNTERDESCRIPTOR']._serialized_start=166690
+  _globals['_INTERNEDGPUCOUNTERDESCRIPTOR']._serialized_end=166816
+  _globals['_GPULOG']._serialized_start=166819
+  _globals['_GPULOG']._serialized_end=167079
+  _globals['_GPULOG_SEVERITY']._serialized_start=166916
+  _globals['_GPULOG_SEVERITY']._serialized_end=167079
+  _globals['_GPUMEMTOTALEVENT']._serialized_start=167081
+  _globals['_GPUMEMTOTALEVENT']._serialized_end=167142
+  _globals['_GPURENDERSTAGEEVENT']._serialized_start=167145
+  _globals['_GPURENDERSTAGEEVENT']._serialized_end=168692
+  _globals['_GPURENDERSTAGEEVENT_EXTRADATA']._serialized_start=167808
+  _globals['_GPURENDERSTAGEEVENT_EXTRADATA']._serialized_end=167848
+  _globals['_GPURENDERSTAGEEVENT_DIM3']._serialized_start=167850
+  _globals['_GPURENDERSTAGEEVENT_DIM3']._serialized_end=167889
+  _globals['_GPURENDERSTAGEEVENT_EXTRACOMPUTEARG']._serialized_start=167892
+  _globals['_GPURENDERSTAGEEVENT_EXTRACOMPUTEARG']._serialized_end=168087
+  _globals['_GPURENDERSTAGEEVENT_COMPUTEKERNELLAUNCH']._serialized_start=168090
+  _globals['_GPURENDERSTAGEEVENT_COMPUTEKERNELLAUNCH']._serialized_end=168308
+  _globals['_GPURENDERSTAGEEVENT_SPECIFICATIONS']._serialized_start=168311
+  _globals['_GPURENDERSTAGEEVENT_SPECIFICATIONS']._serialized_end=168672
+  _globals['_GPURENDERSTAGEEVENT_SPECIFICATIONS_CONTEXTSPEC']._serialized_start=168579
+  _globals['_GPURENDERSTAGEEVENT_SPECIFICATIONS_CONTEXTSPEC']._serialized_end=168622
+  _globals['_GPURENDERSTAGEEVENT_SPECIFICATIONS_DESCRIPTION']._serialized_start=168624
+  _globals['_GPURENDERSTAGEEVENT_SPECIFICATIONS_DESCRIPTION']._serialized_end=168672
+  _globals['_INTERNEDGRAPHICSCONTEXT']._serialized_start=168695
+  _globals['_INTERNEDGRAPHICSCONTEXT']._serialized_end=168884
+  _globals['_INTERNEDGRAPHICSCONTEXT_API']._serialized_start=168807
+  _globals['_INTERNEDGRAPHICSCONTEXT_API']._serialized_end=168884
+  _globals['_INTERNEDGPURENDERSTAGESPECIFICATION']._serialized_start=168887
+  _globals['_INTERNEDGPURENDERSTAGESPECIFICATION']._serialized_end=169125
+  _globals['_INTERNEDGPURENDERSTAGESPECIFICATION_RENDERSTAGECATEGORY']._serialized_start=169066
+  _globals['_INTERNEDGPURENDERSTAGESPECIFICATION_RENDERSTAGECATEGORY']._serialized_end=169125
+  _globals['_INTERNEDCOMPUTEKERNEL']._serialized_start=169128
+  _globals['_INTERNEDCOMPUTEKERNEL']._serialized_end=169284
+  _globals['_INTERNEDCOMPUTEARGNAME']._serialized_start=169286
+  _globals['_INTERNEDCOMPUTEARGNAME']._serialized_end=169337
+  _globals['_VULKANAPIEVENT']._serialized_start=169340
+  _globals['_VULKANAPIEVENT']._serialized_end=169783
+  _globals['_VULKANAPIEVENT_VKDEBUGUTILSOBJECTNAME']._serialized_start=169526
+  _globals['_VULKANAPIEVENT_VKDEBUGUTILSOBJECTNAME']._serialized_end=169640
+  _globals['_VULKANAPIEVENT_VKQUEUESUBMIT']._serialized_start=169643
+  _globals['_VULKANAPIEVENT_VKQUEUESUBMIT']._serialized_end=169774
+  _globals['_VULKANMEMORYEVENTANNOTATION']._serialized_start=169785
+  _globals['_VULKANMEMORYEVENTANNOTATION']._serialized_end=169907
+  _globals['_VULKANMEMORYEVENT']._serialized_start=169910
+  _globals['_VULKANMEMORYEVENT']._serialized_end=170782
+  _globals['_VULKANMEMORYEVENT_SOURCE']._serialized_start=170395
+  _globals['_VULKANMEMORYEVENT_SOURCE']._serialized_end=170528
+  _globals['_VULKANMEMORYEVENT_OPERATION']._serialized_start=170530
+  _globals['_VULKANMEMORYEVENT_OPERATION']._serialized_end=170647
+  _globals['_VULKANMEMORYEVENT_ALLOCATIONSCOPE']._serialized_start=170650
+  _globals['_VULKANMEMORYEVENT_ALLOCATIONSCOPE']._serialized_end=170782
+  _globals['_INTERNEDSTRING']._serialized_start=170784
+  _globals['_INTERNEDSTRING']._serialized_end=170826
+  _globals['_LINE']._serialized_start=170828
+  _globals['_LINE']._serialized_end=170904
+  _globals['_ADDRESSSYMBOLS']._serialized_start=170906
+  _globals['_ADDRESSSYMBOLS']._serialized_end=170977
+  _globals['_MODULESYMBOLS']._serialized_start=170979
+  _globals['_MODULESYMBOLS']._serialized_end=171084
+  _globals['_MAPPING']._serialized_start=171087
+  _globals['_MAPPING']._serialized_end=171243
+  _globals['_FRAME']._serialized_start=171246
+  _globals['_FRAME']._serialized_end=171580
+  _globals['_FRAME_KIND']._serialized_start=171441
+  _globals['_FRAME_KIND']._serialized_end=171566
+  _globals['_CALLSTACK']._serialized_start=171582
+  _globals['_CALLSTACK']._serialized_end=171625
+  _globals['_INLINECALLSTACK']._serialized_start=171628
+  _globals['_INLINECALLSTACK']._serialized_end=171775
+  _globals['_INLINECALLSTACK_FRAME']._serialized_start=171703
+  _globals['_INLINECALLSTACK_FRAME']._serialized_end=171775
+  _globals['_STACKSAMPLE']._serialized_start=171778
+  _globals['_STACKSAMPLE']._serialized_end=173442
+  _globals['_STACKSAMPLE_TASKCONTEXT']._serialized_start=172410
+  _globals['_STACKSAMPLE_TASKCONTEXT']._serialized_end=172480
+  _globals['_STACKSAMPLE_ASYNCCONTEXTDESCRIPTOR']._serialized_start=172482
+  _globals['_STACKSAMPLE_ASYNCCONTEXTDESCRIPTOR']._serialized_end=172567
+  _globals['_STACKSAMPLE_EXECUTIONCONTEXT']._serialized_start=172569
+  _globals['_STACKSAMPLE_EXECUTIONCONTEXT']._serialized_end=172662
+  _globals['_STACKSAMPLE_COUNTERDESCRIPTOR']._serialized_start=172665
+  _globals['_STACKSAMPLE_COUNTERDESCRIPTOR']._serialized_end=172976
+  _globals['_STACKSAMPLE_COUNTERDESCRIPTOR_SCOPE']._serialized_start=172899
+  _globals['_STACKSAMPLE_COUNTERDESCRIPTOR_SCOPE']._serialized_end=172962
+  _globals['_STACKSAMPLE_MODE']._serialized_start=172978
+  _globals['_STACKSAMPLE_MODE']._serialized_end=173099
+  _globals['_STACKSAMPLE_UNIT']._serialized_start=173102
+  _globals['_STACKSAMPLE_UNIT']._serialized_end=173324
+  _globals['_STACKSAMPLEDEFAULTS']._serialized_start=173445
+  _globals['_STACKSAMPLEDEFAULTS']._serialized_end=173636
+  _globals['_HISTOGRAMNAME']._serialized_start=173638
+  _globals['_HISTOGRAMNAME']._serialized_end=173680
+  _globals['_CHROMEHISTOGRAMSAMPLE']._serialized_start=173682
+  _globals['_CHROMEHISTOGRAMSAMPLE']._serialized_end=173772
+  _globals['_DEBUGANNOTATION']._serialized_start=173775
+  _globals['_DEBUGANNOTATION']._serialized_end=174715
+  _globals['_DEBUGANNOTATION_NESTEDVALUE']._serialized_start=174287
+  _globals['_DEBUGANNOTATION_NESTEDVALUE']._serialized_end=174667
+  _globals['_DEBUGANNOTATION_NESTEDVALUE_NESTEDTYPE']._serialized_start=174617
+  _globals['_DEBUGANNOTATION_NESTEDVALUE_NESTEDTYPE']._serialized_end=174667
+  _globals['_DEBUGANNOTATIONNAME']._serialized_start=174717
+  _globals['_DEBUGANNOTATIONNAME']._serialized_end=174765
+  _globals['_DEBUGANNOTATIONVALUETYPENAME']._serialized_start=174767
+  _globals['_DEBUGANNOTATIONVALUETYPENAME']._serialized_end=174824
+  _globals['_LOGMESSAGE']._serialized_start=174827
+  _globals['_LOGMESSAGE']._serialized_end=175086
+  _globals['_LOGMESSAGE_PRIORITY']._serialized_start=174941
+  _globals['_LOGMESSAGE_PRIORITY']._serialized_end=175086
+  _globals['_LOGMESSAGEBODY']._serialized_start=175088
+  _globals['_LOGMESSAGEBODY']._serialized_end=175131
+  _globals['_UNSYMBOLIZEDSOURCELOCATION']._serialized_start=175133
+  _globals['_UNSYMBOLIZEDSOURCELOCATION']._serialized_end=175210
+  _globals['_SOURCELOCATION']._serialized_start=175212
+  _globals['_SOURCELOCATION']._serialized_end=175304
+  _globals['_CHROMEACTIVEPROCESSES']._serialized_start=175306
+  _globals['_CHROMEACTIVEPROCESSES']._serialized_end=175342
+  _globals['_CHROMEAPPLICATIONSTATEINFO']._serialized_start=175345
+  _globals['_CHROMEAPPLICATIONSTATEINFO']._serialized_end=175711
+  _globals['_CHROMEAPPLICATIONSTATEINFO_CHROMEAPPLICATIONSTATE']._serialized_start=175471
+  _globals['_CHROMEAPPLICATIONSTATEINFO_CHROMEAPPLICATIONSTATE']._serialized_end=175711
+  _globals['_CHROMECOMPOSITORSCHEDULERSTATE']._serialized_start=175714
+  _globals['_CHROMECOMPOSITORSCHEDULERSTATE']._serialized_end=176801
+  _globals['_CHROMECOMPOSITORSCHEDULERSTATE_BEGINIMPLFRAMEDEADLINEMODE']._serialized_start=176605
+  _globals['_CHROMECOMPOSITORSCHEDULERSTATE_BEGINIMPLFRAMEDEADLINEMODE']._serialized_end=176795
+  _globals['_CHROMECOMPOSITORSTATEMACHINE']._serialized_start=176804
+  _globals['_CHROMECOMPOSITORSTATEMACHINE']._serialized_end=180514
+  _globals['_CHROMECOMPOSITORSTATEMACHINE_MAJORSTATE']._serialized_start=176995
+  _globals['_CHROMECOMPOSITORSTATEMACHINE_MAJORSTATE']._serialized_end=178294
+  _globals['_CHROMECOMPOSITORSTATEMACHINE_MAJORSTATE_BEGINIMPLFRAMESTATE']._serialized_start=177534
+  _globals['_CHROMECOMPOSITORSTATEMACHINE_MAJORSTATE_BEGINIMPLFRAMESTATE']._serialized_end=177695
+  _globals['_CHROMECOMPOSITORSTATEMACHINE_MAJORSTATE_BEGINMAINFRAMESTATE']._serialized_start=177698
+  _globals['_CHROMECOMPOSITORSTATEMACHINE_MAJORSTATE_BEGINMAINFRAMESTATE']._serialized_end=177845
+  _globals['_CHROMECOMPOSITORSTATEMACHINE_MAJORSTATE_LAYERTREEFRAMESINKSTATE']._serialized_start=177848
+  _globals['_CHROMECOMPOSITORSTATEMACHINE_MAJORSTATE_LAYERTREEFRAMESINKSTATE']._serialized_end=178092
+  _globals['_CHROMECOMPOSITORSTATEMACHINE_MAJORSTATE_FORCEDREDRAWONTIMEOUTSTATE']._serialized_start=178095
+  _globals['_CHROMECOMPOSITORSTATEMACHINE_MAJORSTATE_FORCEDREDRAWONTIMEOUTSTATE']._serialized_end=178294
+  _globals['_CHROMECOMPOSITORSTATEMACHINE_MINORSTATE']._serialized_start=178297
+  _globals['_CHROMECOMPOSITORSTATEMACHINE_MINORSTATE']._serialized_end=180514
+  _globals['_CHROMECOMPOSITORSTATEMACHINE_MINORSTATE_TREEPRIORITY']._serialized_start=180191
+  _globals['_CHROMECOMPOSITORSTATEMACHINE_MINORSTATE_TREEPRIORITY']._serialized_end=180375
+  _globals['_CHROMECOMPOSITORSTATEMACHINE_MINORSTATE_SCROLLHANDLERSTATE']._serialized_start=180378
+  _globals['_CHROMECOMPOSITORSTATEMACHINE_MINORSTATE_SCROLLHANDLERSTATE']._serialized_end=180508
+  _globals['_BEGINFRAMEARGS']._serialized_start=180517
+  _globals['_BEGINFRAMEARGS']._serialized_end=181071
+  _globals['_BEGINFRAMEARGS_BEGINFRAMEARGSTYPE']._serialized_start=180893
+  _globals['_BEGINFRAMEARGS_BEGINFRAMEARGSTYPE']._serialized_end=181055
+  _globals['_BEGINIMPLFRAMEARGS']._serialized_start=181074
+  _globals['_BEGINIMPLFRAMEARGS']._serialized_end=181650
+  _globals['_BEGINIMPLFRAMEARGS_TIMESTAMPSINUS']._serialized_start=181391
+  _globals['_BEGINIMPLFRAMEARGS_TIMESTAMPSINUS']._serialized_end=181584
+  _globals['_BEGINIMPLFRAMEARGS_STATE']._serialized_start=181586
+  _globals['_BEGINIMPLFRAMEARGS_STATE']._serialized_end=181642
+  _globals['_BEGINFRAMEOBSERVERSTATE']._serialized_start=181652
+  _globals['_BEGINFRAMEOBSERVERSTATE']._serialized_end=181775
+  _globals['_BEGINFRAMESOURCESTATE']._serialized_start=181778
+  _globals['_BEGINFRAMESOURCESTATE']._serialized_end=181923
+  _globals['_COMPOSITORTIMINGHISTORY']._serialized_start=181926
+  _globals['_COMPOSITORTIMINGHISTORY']._serialized_end=182306
+  _globals['_CHROMECONTENTSETTINGSEVENTINFO']._serialized_start=182308
+  _globals['_CHROMECONTENTSETTINGSEVENTINFO']._serialized_end=182370
+  _globals['_CHROMEFRAMEREPORTER']._serialized_start=182373
+  _globals['_CHROMEFRAMEREPORTER']._serialized_end=183493
+  _globals['_CHROMEFRAMEREPORTER_STATE']._serialized_start=183088
+  _globals['_CHROMEFRAMEREPORTER_STATE']._serialized_end=183197
+  _globals['_CHROMEFRAMEREPORTER_FRAMEDROPREASON']._serialized_start=183199
+  _globals['_CHROMEFRAMEREPORTER_FRAMEDROPREASON']._serialized_end=183325
+  _globals['_CHROMEFRAMEREPORTER_SCROLLSTATE']._serialized_start=183327
+  _globals['_CHROMEFRAMEREPORTER_SCROLLSTATE']._serialized_end=183450
+  _globals['_CHROMEFRAMEREPORTER_FRAMETYPE']._serialized_start=183452
+  _globals['_CHROMEFRAMEREPORTER_FRAMETYPE']._serialized_end=183489
+  _globals['_CHROMEKEYEDSERVICE']._serialized_start=183495
+  _globals['_CHROMEKEYEDSERVICE']._serialized_end=183529
+  _globals['_CHROMELATENCYINFO']._serialized_start=183532
+  _globals['_CHROMELATENCYINFO']._serialized_end=185314
+  _globals['_CHROMELATENCYINFO_COMPONENTINFO']._serialized_start=183861
+  _globals['_CHROMELATENCYINFO_COMPONENTINFO']._serialized_end=183974
+  _globals['_CHROMELATENCYINFO_STEP']._serialized_start=183977
+  _globals['_CHROMELATENCYINFO_STEP']._serialized_end=184379
+  _globals['_CHROMELATENCYINFO_LATENCYCOMPONENTTYPE']._serialized_start=184382
+  _globals['_CHROMELATENCYINFO_LATENCYCOMPONENTTYPE']._serialized_end=185139
+  _globals['_CHROMELATENCYINFO_INPUTTYPE']._serialized_start=185142
+  _globals['_CHROMELATENCYINFO_INPUTTYPE']._serialized_end=185314
+  _globals['_CHROMELEGACYIPC']._serialized_start=185317
+  _globals['_CHROMELEGACYIPC']._serialized_end=186291
+  _globals['_CHROMELEGACYIPC_MESSAGECLASS']._serialized_start=185429
+  _globals['_CHROMELEGACYIPC_MESSAGECLASS']._serialized_end=186291
+  _globals['_CHROMEMESSAGEPUMP']._serialized_start=186293
+  _globals['_CHROMEMESSAGEPUMP']._serialized_end=186377
+  _globals['_CHROMEMOJOEVENTINFO']._serialized_start=186380
+  _globals['_CHROMEMOJOEVENTINFO']._serialized_end=186584
+  _globals['_CHROMERENDERERSCHEDULERSTATE']._serialized_start=186586
+  _globals['_CHROMERENDERERSCHEDULERSTATE']._serialized_end=186712
+  _globals['_CHROMEUSEREVENT']._serialized_start=186714
+  _globals['_CHROMEUSEREVENT']._serialized_end=186768
+  _globals['_CHROMEWINDOWHANDLEEVENTINFO']._serialized_start=186770
+  _globals['_CHROMEWINDOWHANDLEEVENTINFO']._serialized_end=186850
+  _globals['_SCREENSHOT']._serialized_start=186852
+  _globals['_SCREENSHOT']._serialized_end=186921
+  _globals['_TASKEXECUTION']._serialized_start=186923
+  _globals['_TASKEXECUTION']._serialized_end=186963
+  _globals['_TRACKEVENT']._serialized_start=186966
+  _globals['_TRACKEVENT']._serialized_end=190414
+  _globals['_TRACKEVENT_INLINECALLSTACK']._serialized_start=189272
+  _globals['_TRACKEVENT_INLINECALLSTACK']._serialized_end=189430
+  _globals['_TRACKEVENT_INLINECALLSTACK_FRAME']._serialized_start=171703
+  _globals['_TRACKEVENT_INLINECALLSTACK_FRAME']._serialized_end=171775
+  _globals['_TRACKEVENT_LEGACYEVENT']._serialized_start=189433
+  _globals['_TRACKEVENT_LEGACYEVENT']._serialized_end=190115
+  _globals['_TRACKEVENT_LEGACYEVENT_FLOWDIRECTION']._serialized_start=189924
+  _globals['_TRACKEVENT_LEGACYEVENT_FLOWDIRECTION']._serialized_end=190004
+  _globals['_TRACKEVENT_LEGACYEVENT_INSTANTEVENTSCOPE']._serialized_start=190006
+  _globals['_TRACKEVENT_LEGACYEVENT_INSTANTEVENTSCOPE']._serialized_end=190103
+  _globals['_TRACKEVENT_TYPE']._serialized_start=190117
+  _globals['_TRACKEVENT_TYPE']._serialized_end=190239
+  _globals['_TRACKEVENTDEFAULTS']._serialized_start=190416
+  _globals['_TRACKEVENTDEFAULTS']._serialized_end=190533
+  _globals['_EVENTCATEGORY']._serialized_start=190535
+  _globals['_EVENTCATEGORY']._serialized_end=190577
+  _globals['_EVENTNAME']._serialized_start=190579
+  _globals['_EVENTNAME']._serialized_end=190617
+  _globals['_INTERNEDDATA']._serialized_start=190620
+  _globals['_INTERNEDDATA']._serialized_end=192803
+  _globals['_SYSTEMDJOURNALDEVENT']._serialized_start=192806
+  _globals['_SYSTEMDJOURNALDEVENT']._serialized_end=193049
+  _globals['_MEMORYTRACKERSNAPSHOT']._serialized_start=193052
+  _globals['_MEMORYTRACKERSNAPSHOT']._serialized_end=194060
+  _globals['_MEMORYTRACKERSNAPSHOT_PROCESSSNAPSHOT']._serialized_start=193267
+  _globals['_MEMORYTRACKERSNAPSHOT_PROCESSSNAPSHOT']._serialized_end=193985
+  _globals['_MEMORYTRACKERSNAPSHOT_PROCESSSNAPSHOT_MEMORYNODE']._serialized_start=193481
+  _globals['_MEMORYTRACKERSNAPSHOT_PROCESSSNAPSHOT_MEMORYNODE']._serialized_end=193892
+  _globals['_MEMORYTRACKERSNAPSHOT_PROCESSSNAPSHOT_MEMORYNODE_MEMORYNODEENTRY']._serialized_start=193665
+  _globals['_MEMORYTRACKERSNAPSHOT_PROCESSSNAPSHOT_MEMORYNODE_MEMORYNODEENTRY']._serialized_end=193892
+  _globals['_MEMORYTRACKERSNAPSHOT_PROCESSSNAPSHOT_MEMORYNODE_MEMORYNODEENTRY_UNITS']._serialized_start=193846
+  _globals['_MEMORYTRACKERSNAPSHOT_PROCESSSNAPSHOT_MEMORYNODE_MEMORYNODEENTRY_UNITS']._serialized_end=193892
+  _globals['_MEMORYTRACKERSNAPSHOT_PROCESSSNAPSHOT_MEMORYEDGE']._serialized_start=193894
+  _globals['_MEMORYTRACKERSNAPSHOT_PROCESSSNAPSHOT_MEMORYEDGE']._serialized_end=193985
+  _globals['_MEMORYTRACKERSNAPSHOT_LEVELOFDETAIL']._serialized_start=193987
+  _globals['_MEMORYTRACKERSNAPSHOT_LEVELOFDETAIL']._serialized_end=194060
+  _globals['_CONCURRENTSESSIONEVENT']._serialized_start=194063
+  _globals['_CONCURRENTSESSIONEVENT']._serialized_end=194400
+  _globals['_CONCURRENTSESSIONEVENT_STATE']._serialized_start=194242
+  _globals['_CONCURRENTSESSIONEVENT_STATE']._serialized_end=194400
+  _globals['_PERFETTOMETATRACE']._serialized_start=194403
+  _globals['_PERFETTOMETATRACE']._serialized_end=194948
+  _globals['_PERFETTOMETATRACE_ARG']._serialized_start=194760
+  _globals['_PERFETTOMETATRACE_ARG']._serialized_end=194887
+  _globals['_PERFETTOMETATRACE_INTERNEDSTRING']._serialized_start=194889
+  _globals['_PERFETTOMETATRACE_INTERNEDSTRING']._serialized_end=194933
+  _globals['_TRACEPROVENANCE']._serialized_start=194951
+  _globals['_TRACEPROVENANCE']._serialized_end=195143
+  _globals['_TRACEPROVENANCE_SEQUENCE']._serialized_start=195028
+  _globals['_TRACEPROVENANCE_SEQUENCE']._serialized_end=195071
+  _globals['_TRACEPROVENANCE_BUFFER']._serialized_start=195073
+  _globals['_TRACEPROVENANCE_BUFFER']._serialized_end=195143
+  _globals['_TRACINGSERVICEEVENT']._serialized_start=195146
+  _globals['_TRACINGSERVICEEVENT']._serialized_end=195796
+  _globals['_TRACINGSERVICEEVENT_DATASOURCES']._serialized_start=195624
+  _globals['_TRACINGSERVICEEVENT_DATASOURCES']._serialized_end=195782
+  _globals['_TRACINGSERVICEEVENT_DATASOURCES_DATASOURCE']._serialized_start=195721
+  _globals['_TRACINGSERVICEEVENT_DATASOURCES_DATASOURCE']._serialized_end=195782
+  _globals['_EXPERIMENTALTRACINGV2PRODUCERSTATS']._serialized_start=195799
+  _globals['_EXPERIMENTALTRACINGV2PRODUCERSTATS']._serialized_end=196381
+  _globals['_ANDROIDENERGYCONSUMER']._serialized_start=196383
+  _globals['_ANDROIDENERGYCONSUMER']._serialized_end=196479
+  _globals['_ANDROIDENERGYCONSUMERDESCRIPTOR']._serialized_start=196481
+  _globals['_ANDROIDENERGYCONSUMERDESCRIPTOR']._serialized_end=196580
+  _globals['_ANDROIDENERGYESTIMATIONBREAKDOWN']._serialized_start=196583
+  _globals['_ANDROIDENERGYESTIMATIONBREAKDOWN']._serialized_end=196903
+  _globals['_ANDROIDENERGYESTIMATIONBREAKDOWN_ENERGYUIDBREAKDOWN']._serialized_start=196850
+  _globals['_ANDROIDENERGYESTIMATIONBREAKDOWN_ENERGYUIDBREAKDOWN']._serialized_end=196903
+  _globals['_ENTITYSTATERESIDENCY']._serialized_start=196906
+  _globals['_ENTITYSTATERESIDENCY']._serialized_end=197349
+  _globals['_ENTITYSTATERESIDENCY_POWERENTITYSTATE']._serialized_start=197087
+  _globals['_ENTITYSTATERESIDENCY_POWERENTITYSTATE']._serialized_end=197189
+  _globals['_ENTITYSTATERESIDENCY_STATERESIDENCY']._serialized_start=197192
+  _globals['_ENTITYSTATERESIDENCY_STATERESIDENCY']._serialized_end=197349
+  _globals['_BATTERYCOUNTERS']._serialized_start=197352
+  _globals['_BATTERYCOUNTERS']._serialized_end=197529
+  _globals['_POWERRAILS']._serialized_start=197532
+  _globals['_POWERRAILS']._serialized_end=197859
+  _globals['_POWERRAILS_RAILDESCRIPTOR']._serialized_start=197698
+  _globals['_POWERRAILS_RAILDESCRIPTOR']._serialized_end=197792
+  _globals['_POWERRAILS_ENERGYDATA']._serialized_start=197794
+  _globals['_POWERRAILS_ENERGYDATA']._serialized_end=197859
+  _globals['_JAVAFRAME']._serialized_start=197861
+  _globals['_JAVAFRAME']._serialized_end=197935
+  _globals['_JAVASTACK']._serialized_start=197937
+  _globals['_JAVASTACK']._serialized_end=197992
+  _globals['_ARTPROCESSMETADATA']._serialized_start=197995
+  _globals['_ARTPROCESSMETADATA']._serialized_end=198260
+  _globals['_OBFUSCATEDMEMBER']._serialized_start=198263
+  _globals['_OBFUSCATEDMEMBER']._serialized_end=198445
+  _globals['_OBFUSCATEDCLASS']._serialized_start=198448
+  _globals['_OBFUSCATEDCLASS']._serialized_end=198983
+  _globals['_OBFUSCATEDCLASS_MERGEDCLASS']._serialized_start=198717
+  _globals['_OBFUSCATEDCLASS_MERGEDCLASS']._serialized_end=198834
+  _globals['_OBFUSCATEDCLASS_MERGEDCLASSES']._serialized_start=198837
+  _globals['_OBFUSCATEDCLASS_MERGEDCLASSES']._serialized_end=198983
+  _globals['_DEOBFUSCATIONMAPPING']._serialized_start=198986
+  _globals['_DEOBFUSCATIONMAPPING']._serialized_end=199114
+  _globals['_PROFILEPACKET']._serialized_start=199117
+  _globals['_PROFILEPACKET']._serialized_end=200610
+  _globals['_PROFILEPACKET_HEAPSAMPLE']._serialized_start=199425
+  _globals['_PROFILEPACKET_HEAPSAMPLE']._serialized_end=199611
+  _globals['_PROFILEPACKET_HISTOGRAM']._serialized_start=199614
+  _globals['_PROFILEPACKET_HISTOGRAM']._serialized_end=199757
+  _globals['_PROFILEPACKET_HISTOGRAM_BUCKET']._serialized_start=199693
+  _globals['_PROFILEPACKET_HISTOGRAM_BUCKET']._serialized_end=199757
+  _globals['_PROFILEPACKET_PROCESSSTATS']._serialized_start=199760
+  _globals['_PROFILEPACKET_PROCESSSTATS']._serialized_end=199982
+  _globals['_PROFILEPACKET_PROCESSHEAPSAMPLES']._serialized_start=199985
+  _globals['_PROFILEPACKET_PROCESSHEAPSAMPLES']._serialized_end=200610
+  _globals['_PROFILEPACKET_PROCESSHEAPSAMPLES_CLIENTERROR']._serialized_start=200505
+  _globals['_PROFILEPACKET_PROCESSHEAPSAMPLES_CLIENTERROR']._serialized_end=200610
+  _globals['_STREAMINGALLOCATION']._serialized_start=200613
+  _globals['_STREAMINGALLOCATION']._serialized_end=200770
+  _globals['_STREAMINGFREE']._serialized_start=200772
+  _globals['_STREAMINGFREE']._serialized_end=200846
+  _globals['_STREAMINGPROFILEPACKET']._serialized_start=200848
+  _globals['_STREAMINGPROFILEPACKET']._serialized_end=200949
+  _globals['_PROFILING']._serialized_start=200952
+  _globals['_PROFILING']._serialized_end=201608
+  _globals['_PROFILING_CPUMODE']._serialized_start=200965
+  _globals['_PROFILING_CPUMODE']._serialized_end=201089
+  _globals['_PROFILING_STACKUNWINDERROR']._serialized_start=201092
+  _globals['_PROFILING_STACKUNWINDERROR']._serialized_end=201608
+  _globals['_PERFSAMPLE']._serialized_start=201611
+  _globals['_PERFSAMPLE']._serialized_end=202490
+  _globals['_PERFSAMPLE_PRODUCEREVENT']._serialized_start=202035
+  _globals['_PERFSAMPLE_PRODUCEREVENT']._serialized_end=202255
+  _globals['_PERFSAMPLE_PRODUCEREVENT_DATASOURCESTOPREASON']._serialized_start=202146
+  _globals['_PERFSAMPLE_PRODUCEREVENT_DATASOURCESTOPREASON']._serialized_end=202224
+  _globals['_PERFSAMPLE_SAMPLESKIPREASON']._serialized_start=202258
+  _globals['_PERFSAMPLE_SAMPLESKIPREASON']._serialized_end=202431
+  _globals['_PERFSAMPLEDEFAULTS']._serialized_start=202493
+  _globals['_PERFSAMPLEDEFAULTS']._serialized_end=202679
+  _globals['_SMAPSENTRY']._serialized_start=202682
+  _globals['_SMAPSENTRY']._serialized_end=203069
+  _globals['_PACKEDSMAPS']._serialized_start=203072
+  _globals['_PACKEDSMAPS']._serialized_end=203457
+  _globals['_SMAPSPACKET']._serialized_start=203460
+  _globals['_SMAPSPACKET']._serialized_end=203808
+  _globals['_SMAPSPACKET_RECORDINGTYPE']._serialized_start=203657
+  _globals['_SMAPSPACKET_RECORDINGTYPE']._serialized_end=203808
+  _globals['_PROCESSSTATS']._serialized_start=203811
+  _globals['_PROCESSSTATS']._serialized_end=204638
+  _globals['_PROCESSSTATS_THREAD']._serialized_start=203919
+  _globals['_PROCESSSTATS_THREAD']._serialized_end=203958
+  _globals['_PROCESSSTATS_FDINFO']._serialized_start=203960
+  _globals['_PROCESSSTATS_FDINFO']._serialized_end=203994
+  _globals['_PROCESSSTATS_PROCESS']._serialized_start=203997
+  _globals['_PROCESSSTATS_PROCESS']._serialized_end=204638
+  _globals['_PROCESSTREE']._serialized_start=204641
+  _globals['_PROCESSTREE']._serialized_end=205033
+  _globals['_PROCESSTREE_THREAD']._serialized_start=204801
+  _globals['_PROCESSTREE_THREAD']._serialized_end=204865
+  _globals['_PROCESSTREE_PROCESS']._serialized_start=204868
+  _globals['_PROCESSTREE_PROCESS']._serialized_end=205033
+  _globals['_REMOTECLOCKSYNC']._serialized_start=205036
+  _globals['_REMOTECLOCKSYNC']._serialized_end=205247
+  _globals['_REMOTECLOCKSYNC_SYNCEDCLOCKS']._serialized_start=205125
+  _globals['_REMOTECLOCKSYNC_SYNCEDCLOCKS']._serialized_end=205247
+  _globals['_ATOM']._serialized_start=205249
+  _globals['_ATOM']._serialized_end=205255
+  _globals['_STATSDATOM']._serialized_start=205257
+  _globals['_STATSDATOM']._serialized_end=205331
+  _globals['_SYSSTATS']._serialized_start=205334
+  _globals['_SYSSTATS']._serialized_end=207482
+  _globals['_SYSSTATS_MEMINFOVALUE']._serialized_start=206177
+  _globals['_SYSSTATS_MEMINFOVALUE']._serialized_end=206253
+  _globals['_SYSSTATS_VMSTATVALUE']._serialized_start=206255
+  _globals['_SYSSTATS_VMSTATVALUE']._serialized_end=206329
+  _globals['_SYSSTATS_CPUTIMES']._serialized_start=206332
+  _globals['_SYSSTATS_CPUTIMES']._serialized_end=206512
+  _globals['_SYSSTATS_INTERRUPTCOUNT']._serialized_start=206514
+  _globals['_SYSSTATS_INTERRUPTCOUNT']._serialized_end=206558
+  _globals['_SYSSTATS_DEVFREQVALUE']._serialized_start=206560
+  _globals['_SYSSTATS_DEVFREQVALUE']._serialized_end=206602
+  _globals['_SYSSTATS_BUDDYINFO']._serialized_start=206604
+  _globals['_SYSSTATS_BUDDYINFO']._serialized_end=206664
+  _globals['_SYSSTATS_DISKSTAT']._serialized_start=206667
+  _globals['_SYSSTATS_DISKSTAT']._serialized_end=206882
+  _globals['_SYSSTATS_PSISAMPLE']._serialized_start=206885
+  _globals['_SYSSTATS_PSISAMPLE']._serialized_end=207193
+  _globals['_SYSSTATS_PSISAMPLE_PSIRESOURCE']._serialized_start=206984
+  _globals['_SYSSTATS_PSISAMPLE_PSIRESOURCE']._serialized_end=207193
+  _globals['_SYSSTATS_THERMALZONE']._serialized_start=207195
+  _globals['_SYSSTATS_THERMALZONE']._serialized_end=207250
+  _globals['_SYSSTATS_CPUIDLESTATEENTRY']._serialized_start=207252
+  _globals['_SYSSTATS_CPUIDLESTATEENTRY']._serialized_end=207307
+  _globals['_SYSSTATS_CPUIDLESTATE']._serialized_start=207309
+  _globals['_SYSSTATS_CPUIDLESTATE']._serialized_end=207413
+  _globals['_SYSSTATS_SLABINFO']._serialized_start=207415
+  _globals['_SYSSTATS_SLABINFO']._serialized_end=207482
+  _globals['_CPUINFO']._serialized_start=207485
+  _globals['_CPUINFO']._serialized_end=207817
+  _globals['_CPUINFO_ARMCPUIDENTIFIER']._serialized_start=207540
+  _globals['_CPUINFO_ARMCPUIDENTIFIER']._serialized_end=207650
+  _globals['_CPUINFO_CPU']._serialized_start=207653
+  _globals['_CPUINFO_CPU']._serialized_end=207817
+  _globals['_GPUINFO']._serialized_start=207820
+  _globals['_GPUINFO']._serialized_end=208078
+  _globals['_GPUINFO_GPU']._serialized_start=207876
+  _globals['_GPUINFO_GPU']._serialized_end=208078
+  _globals['_GPUINFO_GPU_KEYVALUE']._serialized_start=208040
+  _globals['_GPUINFO_GPU_KEYVALUE']._serialized_end=208078
+  _globals['_INTERRUPTINFO']._serialized_start=208081
+  _globals['_INTERRUPTINFO']._serialized_end=208216
+  _globals['_INTERRUPTINFO_INTERRUPTMAPPING']._serialized_start=208168
+  _globals['_INTERRUPTINFO_INTERRUPTMAPPING']._serialized_end=208216
+  _globals['_TESTEVENT']._serialized_start=208219
+  _globals['_TESTEVENT']._serialized_end=209321
+  _globals['_TESTEVENT_TESTPAYLOAD']._serialized_start=208507
+  _globals['_TESTEVENT_TESTPAYLOAD']._serialized_end=208749
+  _globals['_TESTEVENT_PROTOVMMESSAGE']._serialized_start=208752
+  _globals['_TESTEVENT_PROTOVMMESSAGE']._serialized_end=208902
+  _globals['_TESTEVENT_PROTOVMMESSAGE_PROTOVMSUBMESSAGE']._serialized_start=208863
+  _globals['_TESTEVENT_PROTOVMMESSAGE_PROTOVMSUBMESSAGE']._serialized_end=208902
+  _globals['_TESTEVENT_PROTOVMPATCH']._serialized_start=208905
+  _globals['_TESTEVENT_PROTOVMPATCH']._serialized_end=209122
+  _globals['_TESTEVENT_PROTOVMINCREMENTALSTATE']._serialized_start=209125
+  _globals['_TESTEVENT_PROTOVMINCREMENTALSTATE']._serialized_end=209321
+  _globals['_TRACEPACKETDEFAULTS']._serialized_start=209324
+  _globals['_TRACEPACKETDEFAULTS']._serialized_end=209635
+  _globals['_TRACEUUID']._serialized_start=209637
+  _globals['_TRACEUUID']._serialized_end=209674
+  _globals['_PROCESSDESCRIPTOR']._serialized_start=209677
+  _globals['_PROCESSDESCRIPTOR']._serialized_end=210164
+  _globals['_PROCESSDESCRIPTOR_CHROMEPROCESSTYPE']._serialized_start=209939
+  _globals['_PROCESSDESCRIPTOR_CHROMEPROCESSTYPE']._serialized_end=210164
+  _globals['_TRACKEVENTRANGEOFINTEREST']._serialized_start=210166
+  _globals['_TRACKEVENTRANGEOFINTEREST']._serialized_end=210211
+  _globals['_THREADDESCRIPTOR']._serialized_start=210214
+  _globals['_THREADDESCRIPTOR']._serialized_end=210970
+  _globals['_THREADDESCRIPTOR_CHROMETHREADTYPE']._serialized_start=210499
+  _globals['_THREADDESCRIPTOR_CHROMETHREADTYPE']._serialized_end=210970
+  _globals['_CHROMEPROCESSDESCRIPTOR']._serialized_start=210973
+  _globals['_CHROMEPROCESSDESCRIPTOR']._serialized_end=211128
+  _globals['_CHROMETHREADDESCRIPTOR']._serialized_start=211130
+  _globals['_CHROMETHREADDESCRIPTOR']._serialized_end=211228
+  _globals['_COUNTERDESCRIPTOR']._serialized_start=211231
+  _globals['_COUNTERDESCRIPTOR']._serialized_end=211686
+  _globals['_COUNTERDESCRIPTOR_BUILTINCOUNTERTYPE']._serialized_start=211490
+  _globals['_COUNTERDESCRIPTOR_BUILTINCOUNTERTYPE']._serialized_end=211601
+  _globals['_COUNTERDESCRIPTOR_UNIT']._serialized_start=211603
+  _globals['_COUNTERDESCRIPTOR_UNIT']._serialized_end=211686
+  _globals['_STATEDESCRIPTOR']._serialized_start=211688
+  _globals['_STATEDESCRIPTOR']._serialized_end=211705
+  _globals['_TRACKDIMENSION']._serialized_start=211708
+  _globals['_TRACKDIMENSION']._serialized_end=211919
+  _globals['_TRACKDESCRIPTOR']._serialized_start=211922
+  _globals['_TRACKDESCRIPTOR']._serialized_end=213391
+  _globals['_TRACKDESCRIPTOR_CHILDTRACKSORDERING']._serialized_start=212898
+  _globals['_TRACKDESCRIPTOR_CHILDTRACKSORDERING']._serialized_end=212984
+  _globals['_TRACKDESCRIPTOR_SIBLINGMERGEBEHAVIOR']._serialized_start=212987
+  _globals['_TRACKDESCRIPTOR_SIBLINGMERGEBEHAVIOR']._serialized_end=213173
+  _globals['_TRACKDESCRIPTOR_PROCESSORDERING']._serialized_start=213175
+  _globals['_TRACKDESCRIPTOR_PROCESSORDERING']._serialized_end=213257
+  _globals['_TRACKDESCRIPTOR_THREADORDERING']._serialized_start=213259
+  _globals['_TRACKDESCRIPTOR_THREADORDERING']._serialized_end=213338
+  _globals['_TRANSLATIONTABLE']._serialized_start=213394
+  _globals['_TRANSLATIONTABLE']._serialized_end=213887
+  _globals['_CHROMEHISTORGRAMTRANSLATIONTABLE']._serialized_start=213890
+  _globals['_CHROMEHISTORGRAMTRANSLATIONTABLE']._serialized_end=214064
+  _globals['_CHROMEHISTORGRAMTRANSLATIONTABLE_HASHTONAMEENTRY']._serialized_start=214015
+  _globals['_CHROMEHISTORGRAMTRANSLATIONTABLE_HASHTONAMEENTRY']._serialized_end=214064
+  _globals['_CHROMEUSEREVENTTRANSLATIONTABLE']._serialized_start=214067
+  _globals['_CHROMEUSEREVENTTRANSLATIONTABLE']._serialized_end=214258
+  _globals['_CHROMEUSEREVENTTRANSLATIONTABLE_ACTIONHASHTONAMEENTRY']._serialized_start=214203
+  _globals['_CHROMEUSEREVENTTRANSLATIONTABLE_ACTIONHASHTONAMEENTRY']._serialized_end=214258
+  _globals['_CHROMEPERFORMANCEMARKTRANSLATIONTABLE']._serialized_start=214261
+  _globals['_CHROMEPERFORMANCEMARKTRANSLATIONTABLE']._serialized_end=214616
+  _globals['_CHROMEPERFORMANCEMARKTRANSLATIONTABLE_SITEHASHTONAMEENTRY']._serialized_start=214508
+  _globals['_CHROMEPERFORMANCEMARKTRANSLATIONTABLE_SITEHASHTONAMEENTRY']._serialized_end=214561
+  _globals['_CHROMEPERFORMANCEMARKTRANSLATIONTABLE_MARKHASHTONAMEENTRY']._serialized_start=214563
+  _globals['_CHROMEPERFORMANCEMARKTRANSLATIONTABLE_MARKHASHTONAMEENTRY']._serialized_end=214616
+  _globals['_SLICENAMETRANSLATIONTABLE']._serialized_start=214619
+  _globals['_SLICENAMETRANSLATIONTABLE']._serialized_end=214813
+  _globals['_SLICENAMETRANSLATIONTABLE_RAWTODEOBFUSCATEDNAMEENTRY']._serialized_start=214753
+  _globals['_SLICENAMETRANSLATIONTABLE_RAWTODEOBFUSCATEDNAMEENTRY']._serialized_end=214813
+  _globals['_PROCESSTRACKNAMETRANSLATIONTABLE']._serialized_start=214816
+  _globals['_PROCESSTRACKNAMETRANSLATIONTABLE']._serialized_end=215024
+  _globals['_PROCESSTRACKNAMETRANSLATIONTABLE_RAWTODEOBFUSCATEDNAMEENTRY']._serialized_start=214753
+  _globals['_PROCESSTRACKNAMETRANSLATIONTABLE_RAWTODEOBFUSCATEDNAMEENTRY']._serialized_end=214813
+  _globals['_CHROMESTUDYTRANSLATIONTABLE']._serialized_start=215027
+  _globals['_CHROMESTUDYTRANSLATIONTABLE']._serialized_end=215191
+  _globals['_CHROMESTUDYTRANSLATIONTABLE_HASHTONAMEENTRY']._serialized_start=214015
+  _globals['_CHROMESTUDYTRANSLATIONTABLE_HASHTONAMEENTRY']._serialized_end=214064
+  _globals['_TRIGGER']._serialized_start=215193
+  _globals['_TRIGGER']._serialized_end=215300
+  _globals['_UISTATE']._serialized_start=215303
+  _globals['_UISTATE']._serialized_end=215500
+  _globals['_UISTATE_HIGHLIGHTPROCESS']._serialized_start=215436
+  _globals['_UISTATE_HIGHLIGHTPROCESS']._serialized_end=215500
+  _globals['_TRACEPACKET']._serialized_start=215503
+  _globals['_TRACEPACKET']._serialized_end=222186
+  _globals['_TRACEPACKET_PROTOVMS']._serialized_start=221361
+  _globals['_TRACEPACKET_PROTOVMS']._serialized_end=221586
+  _globals['_TRACEPACKET_PROTOVMS_INSTANCE']._serialized_start=221440
+  _globals['_TRACEPACKET_PROTOVMS_INSTANCE']._serialized_end=221586
+  _globals['_TRACEPACKET_SEQUENCEFLAGS']._serialized_start=221588
+  _globals['_TRACEPACKET_SEQUENCEFLAGS']._serialized_end=221692
+  _globals['_TRACEPACKET_DATALOSSREASON']._serialized_start=221695
+  _globals['_TRACEPACKET_DATALOSSREASON']._serialized_end=221999
+  _globals['_TRACE']._serialized_start=222188
+  _globals['_TRACE']._serialized_end=222241
 # @@protoc_insertion_point(module_scope)
diff --git a/python/perfetto/protos/perfetto/trace/perfetto_trace_pb2.pyi b/python/perfetto/protos/perfetto/trace/perfetto_trace_pb2.pyi
index e13db6d..a94a8ed 100644
--- a/python/perfetto/protos/perfetto/trace/perfetto_trace_pb2.pyi
+++ b/python/perfetto/protos/perfetto/trace/perfetto_trace_pb2.pyi
@@ -5433,16 +5433,18 @@
         oversized_packets_dropped: int
         def __init__(self, buffer_size: _Optional[int] = ..., bytes_written: _Optional[int] = ..., bytes_overwritten: _Optional[int] = ..., bytes_read: _Optional[int] = ..., padding_bytes_written: _Optional[int] = ..., padding_bytes_cleared: _Optional[int] = ..., chunks_written: _Optional[int] = ..., chunks_rewritten: _Optional[int] = ..., chunks_relocated: _Optional[int] = ..., chunks_overwritten: _Optional[int] = ..., chunks_discarded: _Optional[int] = ..., chunks_read: _Optional[int] = ..., chunks_committed_out_of_order: _Optional[int] = ..., write_wrap_count: _Optional[int] = ..., compactions: _Optional[int] = ..., compactions_skipped: _Optional[int] = ..., patches_succeeded: _Optional[int] = ..., patches_failed: _Optional[int] = ..., readaheads_succeeded: _Optional[int] = ..., readaheads_failed: _Optional[int] = ..., abi_violations: _Optional[int] = ..., trace_writer_packet_loss: _Optional[int] = ..., oversized_packets_dropped: _Optional[int] = ...) -> None: ...
     class WriterStats(_message.Message):
-        __slots__ = ("sequence_id", "buffer", "chunk_payload_histogram_counts", "chunk_payload_histogram_sum")
+        __slots__ = ("sequence_id", "buffer", "protocol_abi_versions", "chunk_payload_histogram_counts", "chunk_payload_histogram_sum")
         SEQUENCE_ID_FIELD_NUMBER: _ClassVar[int]
         BUFFER_FIELD_NUMBER: _ClassVar[int]
+        PROTOCOL_ABI_VERSIONS_FIELD_NUMBER: _ClassVar[int]
         CHUNK_PAYLOAD_HISTOGRAM_COUNTS_FIELD_NUMBER: _ClassVar[int]
         CHUNK_PAYLOAD_HISTOGRAM_SUM_FIELD_NUMBER: _ClassVar[int]
         sequence_id: int
         buffer: int
+        protocol_abi_versions: int
         chunk_payload_histogram_counts: _containers.RepeatedScalarFieldContainer[int]
         chunk_payload_histogram_sum: _containers.RepeatedScalarFieldContainer[int]
-        def __init__(self, sequence_id: _Optional[int] = ..., buffer: _Optional[int] = ..., chunk_payload_histogram_counts: _Optional[_Iterable[int]] = ..., chunk_payload_histogram_sum: _Optional[_Iterable[int]] = ...) -> None: ...
+        def __init__(self, sequence_id: _Optional[int] = ..., buffer: _Optional[int] = ..., protocol_abi_versions: _Optional[int] = ..., chunk_payload_histogram_counts: _Optional[_Iterable[int]] = ..., chunk_payload_histogram_sum: _Optional[_Iterable[int]] = ...) -> None: ...
     class FilterStats(_message.Message):
         __slots__ = ("input_packets", "input_bytes", "output_bytes", "errors", "time_taken_ns", "bytes_discarded_per_buffer")
         INPUT_PACKETS_FIELD_NUMBER: _ClassVar[int]
@@ -17914,7 +17916,7 @@
     def __init__(self, iid: _Optional[int] = ..., name: _Optional[str] = ...) -> None: ...
 
 class InternedData(_message.Message):
-    __slots__ = ("event_categories", "event_names", "debug_annotation_names", "debug_annotation_value_type_names", "debug_annotation_string_values", "correlation_id_str", "build_ids", "mapping_paths", "source_paths", "function_names", "mappings", "frames", "callstacks", "stack_sample_task_contexts", "stack_sample_execution_contexts", "stack_sample_counter_descriptors", "stack_sample_async_context_descriptors", "source_locations", "unsymbolized_source_locations", "log_message_body", "histogram_names", "vulkan_memory_keys", "graphics_contexts", "gpu_specifications", "gpu_counter_descriptors", "kernel_symbols", "v8_js_function_name", "v8_js_function", "v8_js_script", "v8_wasm_script", "v8_isolate")
+    __slots__ = ("event_categories", "event_names", "debug_annotation_names", "debug_annotation_value_type_names", "debug_annotation_string_values", "correlation_id_str", "track_dimension_strings", "build_ids", "mapping_paths", "source_paths", "function_names", "mappings", "frames", "callstacks", "stack_sample_task_contexts", "stack_sample_execution_contexts", "stack_sample_counter_descriptors", "stack_sample_async_context_descriptors", "source_locations", "unsymbolized_source_locations", "log_message_body", "histogram_names", "vulkan_memory_keys", "graphics_contexts", "gpu_specifications", "gpu_counter_descriptors", "kernel_symbols", "v8_js_function_name", "v8_js_function", "v8_js_script", "v8_wasm_script", "v8_isolate")
     Extensions: _python_message._ExtensionDict
     EVENT_CATEGORIES_FIELD_NUMBER: _ClassVar[int]
     EVENT_NAMES_FIELD_NUMBER: _ClassVar[int]
@@ -17922,6 +17924,7 @@
     DEBUG_ANNOTATION_VALUE_TYPE_NAMES_FIELD_NUMBER: _ClassVar[int]
     DEBUG_ANNOTATION_STRING_VALUES_FIELD_NUMBER: _ClassVar[int]
     CORRELATION_ID_STR_FIELD_NUMBER: _ClassVar[int]
+    TRACK_DIMENSION_STRINGS_FIELD_NUMBER: _ClassVar[int]
     BUILD_IDS_FIELD_NUMBER: _ClassVar[int]
     MAPPING_PATHS_FIELD_NUMBER: _ClassVar[int]
     SOURCE_PATHS_FIELD_NUMBER: _ClassVar[int]
@@ -17953,6 +17956,7 @@
     debug_annotation_value_type_names: _containers.RepeatedCompositeFieldContainer[DebugAnnotationValueTypeName]
     debug_annotation_string_values: _containers.RepeatedCompositeFieldContainer[InternedString]
     correlation_id_str: _containers.RepeatedCompositeFieldContainer[InternedString]
+    track_dimension_strings: _containers.RepeatedCompositeFieldContainer[InternedString]
     build_ids: _containers.RepeatedCompositeFieldContainer[InternedString]
     mapping_paths: _containers.RepeatedCompositeFieldContainer[InternedString]
     source_paths: _containers.RepeatedCompositeFieldContainer[InternedString]
@@ -17978,7 +17982,7 @@
     v8_js_script: _containers.RepeatedCompositeFieldContainer[InternedV8JsScript]
     v8_wasm_script: _containers.RepeatedCompositeFieldContainer[InternedV8WasmScript]
     v8_isolate: _containers.RepeatedCompositeFieldContainer[InternedV8Isolate]
-    def __init__(self, event_categories: _Optional[_Iterable[_Union[EventCategory, _Mapping]]] = ..., event_names: _Optional[_Iterable[_Union[EventName, _Mapping]]] = ..., debug_annotation_names: _Optional[_Iterable[_Union[DebugAnnotationName, _Mapping]]] = ..., debug_annotation_value_type_names: _Optional[_Iterable[_Union[DebugAnnotationValueTypeName, _Mapping]]] = ..., debug_annotation_string_values: _Optional[_Iterable[_Union[InternedString, _Mapping]]] = ..., correlation_id_str: _Optional[_Iterable[_Union[InternedString, _Mapping]]] = ..., build_ids: _Optional[_Iterable[_Union[InternedString, _Mapping]]] = ..., mapping_paths: _Optional[_Iterable[_Union[InternedString, _Mapping]]] = ..., source_paths: _Optional[_Iterable[_Union[InternedString, _Mapping]]] = ..., function_names: _Optional[_Iterable[_Union[InternedString, _Mapping]]] = ..., mappings: _Optional[_Iterable[_Union[Mapping, _Mapping]]] = ..., frames: _Optional[_Iterable[_Union[Frame, _Mapping]]] = ..., callstacks: _Optional[_Iterable[_Union[Callstack, _Mapping]]] = ..., stack_sample_task_contexts: _Optional[_Iterable[_Union[StackSample.TaskContext, _Mapping]]] = ..., stack_sample_execution_contexts: _Optional[_Iterable[_Union[StackSample.ExecutionContext, _Mapping]]] = ..., stack_sample_counter_descriptors: _Optional[_Iterable[_Union[StackSample.CounterDescriptor, _Mapping]]] = ..., stack_sample_async_context_descriptors: _Optional[_Iterable[_Union[StackSample.AsyncContextDescriptor, _Mapping]]] = ..., source_locations: _Optional[_Iterable[_Union[SourceLocation, _Mapping]]] = ..., unsymbolized_source_locations: _Optional[_Iterable[_Union[UnsymbolizedSourceLocation, _Mapping]]] = ..., log_message_body: _Optional[_Iterable[_Union[LogMessageBody, _Mapping]]] = ..., histogram_names: _Optional[_Iterable[_Union[HistogramName, _Mapping]]] = ..., vulkan_memory_keys: _Optional[_Iterable[_Union[InternedString, _Mapping]]] = ..., graphics_contexts: _Optional[_Iterable[_Union[InternedGraphicsContext, _Mapping]]] = ..., gpu_specifications: _Optional[_Iterable[_Union[InternedGpuRenderStageSpecification, _Mapping]]] = ..., gpu_counter_descriptors: _Optional[_Iterable[_Union[InternedGpuCounterDescriptor, _Mapping]]] = ..., kernel_symbols: _Optional[_Iterable[_Union[InternedString, _Mapping]]] = ..., v8_js_function_name: _Optional[_Iterable[_Union[InternedV8String, _Mapping]]] = ..., v8_js_function: _Optional[_Iterable[_Union[InternedV8JsFunction, _Mapping]]] = ..., v8_js_script: _Optional[_Iterable[_Union[InternedV8JsScript, _Mapping]]] = ..., v8_wasm_script: _Optional[_Iterable[_Union[InternedV8WasmScript, _Mapping]]] = ..., v8_isolate: _Optional[_Iterable[_Union[InternedV8Isolate, _Mapping]]] = ...) -> None: ...
+    def __init__(self, event_categories: _Optional[_Iterable[_Union[EventCategory, _Mapping]]] = ..., event_names: _Optional[_Iterable[_Union[EventName, _Mapping]]] = ..., debug_annotation_names: _Optional[_Iterable[_Union[DebugAnnotationName, _Mapping]]] = ..., debug_annotation_value_type_names: _Optional[_Iterable[_Union[DebugAnnotationValueTypeName, _Mapping]]] = ..., debug_annotation_string_values: _Optional[_Iterable[_Union[InternedString, _Mapping]]] = ..., correlation_id_str: _Optional[_Iterable[_Union[InternedString, _Mapping]]] = ..., track_dimension_strings: _Optional[_Iterable[_Union[InternedString, _Mapping]]] = ..., build_ids: _Optional[_Iterable[_Union[InternedString, _Mapping]]] = ..., mapping_paths: _Optional[_Iterable[_Union[InternedString, _Mapping]]] = ..., source_paths: _Optional[_Iterable[_Union[InternedString, _Mapping]]] = ..., function_names: _Optional[_Iterable[_Union[InternedString, _Mapping]]] = ..., mappings: _Optional[_Iterable[_Union[Mapping, _Mapping]]] = ..., frames: _Optional[_Iterable[_Union[Frame, _Mapping]]] = ..., callstacks: _Optional[_Iterable[_Union[Callstack, _Mapping]]] = ..., stack_sample_task_contexts: _Optional[_Iterable[_Union[StackSample.TaskContext, _Mapping]]] = ..., stack_sample_execution_contexts: _Optional[_Iterable[_Union[StackSample.ExecutionContext, _Mapping]]] = ..., stack_sample_counter_descriptors: _Optional[_Iterable[_Union[StackSample.CounterDescriptor, _Mapping]]] = ..., stack_sample_async_context_descriptors: _Optional[_Iterable[_Union[StackSample.AsyncContextDescriptor, _Mapping]]] = ..., source_locations: _Optional[_Iterable[_Union[SourceLocation, _Mapping]]] = ..., unsymbolized_source_locations: _Optional[_Iterable[_Union[UnsymbolizedSourceLocation, _Mapping]]] = ..., log_message_body: _Optional[_Iterable[_Union[LogMessageBody, _Mapping]]] = ..., histogram_names: _Optional[_Iterable[_Union[HistogramName, _Mapping]]] = ..., vulkan_memory_keys: _Optional[_Iterable[_Union[InternedString, _Mapping]]] = ..., graphics_contexts: _Optional[_Iterable[_Union[InternedGraphicsContext, _Mapping]]] = ..., gpu_specifications: _Optional[_Iterable[_Union[InternedGpuRenderStageSpecification, _Mapping]]] = ..., gpu_counter_descriptors: _Optional[_Iterable[_Union[InternedGpuCounterDescriptor, _Mapping]]] = ..., kernel_symbols: _Optional[_Iterable[_Union[InternedString, _Mapping]]] = ..., v8_js_function_name: _Optional[_Iterable[_Union[InternedV8String, _Mapping]]] = ..., v8_js_function: _Optional[_Iterable[_Union[InternedV8JsFunction, _Mapping]]] = ..., v8_js_script: _Optional[_Iterable[_Union[InternedV8JsScript, _Mapping]]] = ..., v8_wasm_script: _Optional[_Iterable[_Union[InternedV8WasmScript, _Mapping]]] = ..., v8_isolate: _Optional[_Iterable[_Union[InternedV8Isolate, _Mapping]]] = ...) -> None: ...
 
 class SystemdJournaldEvent(_message.Message):
     __slots__ = ("pid", "tid", "uid", "gid", "prio", "tag", "message", "comm", "exe", "systemd_unit", "hostname", "transport", "num_total", "num_failed")
@@ -18210,6 +18214,52 @@
     buffer_cloned: int
     def __init__(self, tracing_started: bool = ..., all_data_sources_started: bool = ..., flush_started: bool = ..., all_data_sources_flushed: bool = ..., read_tracing_buffers_completed: bool = ..., tracing_disabled: bool = ..., seized_for_bugreport: bool = ..., slow_starting_data_sources: _Optional[_Union[TracingServiceEvent.DataSources, _Mapping]] = ..., last_flush_slow_data_sources: _Optional[_Union[TracingServiceEvent.DataSources, _Mapping]] = ..., clone_started: bool = ..., buffer_cloned: _Optional[int] = ...) -> None: ...
 
+class ExperimentalTracingV2ProducerStats(_message.Message):
+    __slots__ = ("producer_id", "pid", "producer_name", "chunk_size_bytes", "num_chunks", "chunks_read", "bytes_read", "data_loss_chunks", "malformed_chunks", "unsupported_format_chunks", "invalid_writer_chunks", "invalid_destination_chunks", "trace_buffer_rejected_chunks", "rewrite_requests", "positions_skipped", "drain_passes", "drain_time_ns", "drain_max_time_ns", "writer_dropped_packets", "writer_stalls", "writer_stall_time_ms")
+    PRODUCER_ID_FIELD_NUMBER: _ClassVar[int]
+    PID_FIELD_NUMBER: _ClassVar[int]
+    PRODUCER_NAME_FIELD_NUMBER: _ClassVar[int]
+    CHUNK_SIZE_BYTES_FIELD_NUMBER: _ClassVar[int]
+    NUM_CHUNKS_FIELD_NUMBER: _ClassVar[int]
+    CHUNKS_READ_FIELD_NUMBER: _ClassVar[int]
+    BYTES_READ_FIELD_NUMBER: _ClassVar[int]
+    DATA_LOSS_CHUNKS_FIELD_NUMBER: _ClassVar[int]
+    MALFORMED_CHUNKS_FIELD_NUMBER: _ClassVar[int]
+    UNSUPPORTED_FORMAT_CHUNKS_FIELD_NUMBER: _ClassVar[int]
+    INVALID_WRITER_CHUNKS_FIELD_NUMBER: _ClassVar[int]
+    INVALID_DESTINATION_CHUNKS_FIELD_NUMBER: _ClassVar[int]
+    TRACE_BUFFER_REJECTED_CHUNKS_FIELD_NUMBER: _ClassVar[int]
+    REWRITE_REQUESTS_FIELD_NUMBER: _ClassVar[int]
+    POSITIONS_SKIPPED_FIELD_NUMBER: _ClassVar[int]
+    DRAIN_PASSES_FIELD_NUMBER: _ClassVar[int]
+    DRAIN_TIME_NS_FIELD_NUMBER: _ClassVar[int]
+    DRAIN_MAX_TIME_NS_FIELD_NUMBER: _ClassVar[int]
+    WRITER_DROPPED_PACKETS_FIELD_NUMBER: _ClassVar[int]
+    WRITER_STALLS_FIELD_NUMBER: _ClassVar[int]
+    WRITER_STALL_TIME_MS_FIELD_NUMBER: _ClassVar[int]
+    producer_id: int
+    pid: int
+    producer_name: str
+    chunk_size_bytes: int
+    num_chunks: int
+    chunks_read: int
+    bytes_read: int
+    data_loss_chunks: int
+    malformed_chunks: int
+    unsupported_format_chunks: int
+    invalid_writer_chunks: int
+    invalid_destination_chunks: int
+    trace_buffer_rejected_chunks: int
+    rewrite_requests: int
+    positions_skipped: int
+    drain_passes: int
+    drain_time_ns: int
+    drain_max_time_ns: int
+    writer_dropped_packets: int
+    writer_stalls: int
+    writer_stall_time_ms: int
+    def __init__(self, producer_id: _Optional[int] = ..., pid: _Optional[int] = ..., producer_name: _Optional[str] = ..., chunk_size_bytes: _Optional[int] = ..., num_chunks: _Optional[int] = ..., chunks_read: _Optional[int] = ..., bytes_read: _Optional[int] = ..., data_loss_chunks: _Optional[int] = ..., malformed_chunks: _Optional[int] = ..., unsupported_format_chunks: _Optional[int] = ..., invalid_writer_chunks: _Optional[int] = ..., invalid_destination_chunks: _Optional[int] = ..., trace_buffer_rejected_chunks: _Optional[int] = ..., rewrite_requests: _Optional[int] = ..., positions_skipped: _Optional[int] = ..., drain_passes: _Optional[int] = ..., drain_time_ns: _Optional[int] = ..., drain_max_time_ns: _Optional[int] = ..., writer_dropped_packets: _Optional[int] = ..., writer_stalls: _Optional[int] = ..., writer_stall_time_ms: _Optional[int] = ...) -> None: ...
+
 class AndroidEnergyConsumer(_message.Message):
     __slots__ = ("energy_consumer_id", "ordinal", "type", "name")
     ENERGY_CONSUMER_ID_FIELD_NUMBER: _ClassVar[int]
@@ -19407,8 +19457,26 @@
     __slots__ = ()
     def __init__(self) -> None: ...
 
+class TrackDimension(_message.Message):
+    __slots__ = ("name", "name_iid", "int_value", "string_value", "string_value_iid", "display_name", "display_name_iid")
+    NAME_FIELD_NUMBER: _ClassVar[int]
+    NAME_IID_FIELD_NUMBER: _ClassVar[int]
+    INT_VALUE_FIELD_NUMBER: _ClassVar[int]
+    STRING_VALUE_FIELD_NUMBER: _ClassVar[int]
+    STRING_VALUE_IID_FIELD_NUMBER: _ClassVar[int]
+    DISPLAY_NAME_FIELD_NUMBER: _ClassVar[int]
+    DISPLAY_NAME_IID_FIELD_NUMBER: _ClassVar[int]
+    name: str
+    name_iid: int
+    int_value: int
+    string_value: str
+    string_value_iid: int
+    display_name: str
+    display_name_iid: int
+    def __init__(self, name: _Optional[str] = ..., name_iid: _Optional[int] = ..., int_value: _Optional[int] = ..., string_value: _Optional[str] = ..., string_value_iid: _Optional[int] = ..., display_name: _Optional[str] = ..., display_name_iid: _Optional[int] = ...) -> None: ...
+
 class TrackDescriptor(_message.Message):
-    __slots__ = ("uuid", "parent_uuid", "name", "static_name", "atrace_name", "description", "process", "chrome_process", "thread", "chrome_thread", "counter", "state", "disallow_merging_with_system_tracks", "child_ordering", "sibling_order_rank", "sibling_merge_behavior", "sibling_merge_key", "sibling_merge_key_int", "process_ordering", "thread_ordering")
+    __slots__ = ("uuid", "parent_uuid", "name", "static_name", "atrace_name", "description", "process", "chrome_process", "thread", "chrome_thread", "counter", "state", "disallow_merging_with_system_tracks", "child_ordering", "sibling_order_rank", "sibling_merge_behavior", "sibling_merge_key", "sibling_merge_key_int", "process_ordering", "thread_ordering", "dimensions")
     class ChildTracksOrdering(int, metaclass=_enum_type_wrapper.EnumTypeWrapper):
         __slots__ = ()
         UNKNOWN: _ClassVar[TrackDescriptor.ChildTracksOrdering]
@@ -19461,6 +19529,7 @@
     SIBLING_MERGE_KEY_INT_FIELD_NUMBER: _ClassVar[int]
     PROCESS_ORDERING_FIELD_NUMBER: _ClassVar[int]
     THREAD_ORDERING_FIELD_NUMBER: _ClassVar[int]
+    DIMENSIONS_FIELD_NUMBER: _ClassVar[int]
     uuid: int
     parent_uuid: int
     name: str
@@ -19481,7 +19550,8 @@
     sibling_merge_key_int: int
     process_ordering: TrackDescriptor.ProcessOrdering
     thread_ordering: TrackDescriptor.ThreadOrdering
-    def __init__(self, uuid: _Optional[int] = ..., parent_uuid: _Optional[int] = ..., name: _Optional[str] = ..., static_name: _Optional[str] = ..., atrace_name: _Optional[str] = ..., description: _Optional[str] = ..., process: _Optional[_Union[ProcessDescriptor, _Mapping]] = ..., chrome_process: _Optional[_Union[ChromeProcessDescriptor, _Mapping]] = ..., thread: _Optional[_Union[ThreadDescriptor, _Mapping]] = ..., chrome_thread: _Optional[_Union[ChromeThreadDescriptor, _Mapping]] = ..., counter: _Optional[_Union[CounterDescriptor, _Mapping]] = ..., state: _Optional[_Union[StateDescriptor, _Mapping]] = ..., disallow_merging_with_system_tracks: bool = ..., child_ordering: _Optional[_Union[TrackDescriptor.ChildTracksOrdering, str]] = ..., sibling_order_rank: _Optional[int] = ..., sibling_merge_behavior: _Optional[_Union[TrackDescriptor.SiblingMergeBehavior, str]] = ..., sibling_merge_key: _Optional[str] = ..., sibling_merge_key_int: _Optional[int] = ..., process_ordering: _Optional[_Union[TrackDescriptor.ProcessOrdering, str]] = ..., thread_ordering: _Optional[_Union[TrackDescriptor.ThreadOrdering, str]] = ...) -> None: ...
+    dimensions: _containers.RepeatedCompositeFieldContainer[TrackDimension]
+    def __init__(self, uuid: _Optional[int] = ..., parent_uuid: _Optional[int] = ..., name: _Optional[str] = ..., static_name: _Optional[str] = ..., atrace_name: _Optional[str] = ..., description: _Optional[str] = ..., process: _Optional[_Union[ProcessDescriptor, _Mapping]] = ..., chrome_process: _Optional[_Union[ChromeProcessDescriptor, _Mapping]] = ..., thread: _Optional[_Union[ThreadDescriptor, _Mapping]] = ..., chrome_thread: _Optional[_Union[ChromeThreadDescriptor, _Mapping]] = ..., counter: _Optional[_Union[CounterDescriptor, _Mapping]] = ..., state: _Optional[_Union[StateDescriptor, _Mapping]] = ..., disallow_merging_with_system_tracks: bool = ..., child_ordering: _Optional[_Union[TrackDescriptor.ChildTracksOrdering, str]] = ..., sibling_order_rank: _Optional[int] = ..., sibling_merge_behavior: _Optional[_Union[TrackDescriptor.SiblingMergeBehavior, str]] = ..., sibling_merge_key: _Optional[str] = ..., sibling_merge_key_int: _Optional[int] = ..., process_ordering: _Optional[_Union[TrackDescriptor.ProcessOrdering, str]] = ..., thread_ordering: _Optional[_Union[TrackDescriptor.ThreadOrdering, str]] = ..., dimensions: _Optional[_Iterable[_Union[TrackDimension, _Mapping]]] = ...) -> None: ...
 
 class TranslationTable(_message.Message):
     __slots__ = ("chrome_histogram", "chrome_user_event", "chrome_performance_mark", "slice_name", "process_track_name", "chrome_study")
@@ -19616,7 +19686,7 @@
     def __init__(self, timeline_start_ts: _Optional[int] = ..., timeline_end_ts: _Optional[int] = ..., highlight_process: _Optional[_Union[UiState.HighlightProcess, _Mapping]] = ...) -> None: ...
 
 class TracePacket(_message.Message):
-    __slots__ = ("timestamp", "timestamp_clock_id", "track_event", "track_descriptor", "generic_kernel_task_state_event", "generic_kernel_cpu_freq_event", "generic_kernel_task_rename_event", "generic_kernel_process_tree", "generic_gpu_frequency_event", "process_tree", "track_event_range_of_interest", "process_stats", "inode_file_map", "chrome_events", "clock_snapshot", "sys_stats", "trace_uuid", "trace_config", "ftrace_stats", "trace_stats", "profile_packet", "streaming_allocation", "streaming_free", "battery", "power_rails", "android_log", "system_info", "trigger", "chrome_trigger", "packages_list", "chrome_benchmark_metadata", "perfetto_metatrace", "chrome_metadata", "gpu_counter_event", "gpu_render_stage_event", "streaming_profile_packet", "art_process_metadata", "graphics_frame_event", "vulkan_memory_event", "gpu_log", "vulkan_api_event", "perf_sample", "cpu_info", "smaps_packet", "service_event", "concurrent_session_event", "stack_sample", "initial_display_state", "gpu_mem_total_event", "memory_tracker_snapshot", "android_energy_estimation_breakdown", "ui_state", "translation_table", "android_game_intervention_list", "statsd_atom", "android_system_property", "entity_state_residency", "trace_provenance", "protovms", "trace_attributes", "android_aflags", "gpu_info", "interrupt_info", "module_symbols", "deobfuscation_mapping", "process_descriptor", "thread_descriptor", "ftrace_events", "synchronization_marker", "compressed_packets", "zstd_compressed_packets", "extension_descriptor", "etw_events", "v8_js_code", "v8_internal_code", "v8_wasm_code", "v8_reg_exp_code", "v8_code_move", "remote_clock_sync", "pixel_modem_events", "pixel_modem_token_database", "clone_snapshot_trigger", "kernel_wakelock_data", "cpu_per_uid_data", "user_list", "journald_event", "recovered_trace_info", "for_testing", "trusted_uid", "trusted_packet_sequence_id", "trusted_pid", "interned_data", "sequence_flags", "incremental_state_cleared", "trace_packet_defaults", "previous_packet_dropped", "first_packet_on_sequence", "machine_id")
+    __slots__ = ("timestamp", "timestamp_clock_id", "track_event", "track_descriptor", "generic_kernel_task_state_event", "generic_kernel_cpu_freq_event", "generic_kernel_task_rename_event", "generic_kernel_process_tree", "generic_gpu_frequency_event", "process_tree", "track_event_range_of_interest", "process_stats", "inode_file_map", "chrome_events", "clock_snapshot", "sys_stats", "trace_uuid", "trace_config", "ftrace_stats", "trace_stats", "experimental_tracing_v2_producer_stats", "profile_packet", "streaming_allocation", "streaming_free", "battery", "power_rails", "android_log", "system_info", "trigger", "chrome_trigger", "packages_list", "chrome_benchmark_metadata", "perfetto_metatrace", "chrome_metadata", "gpu_counter_event", "gpu_render_stage_event", "streaming_profile_packet", "art_process_metadata", "graphics_frame_event", "vulkan_memory_event", "gpu_log", "vulkan_api_event", "perf_sample", "cpu_info", "smaps_packet", "service_event", "concurrent_session_event", "stack_sample", "initial_display_state", "gpu_mem_total_event", "memory_tracker_snapshot", "android_energy_estimation_breakdown", "ui_state", "translation_table", "android_game_intervention_list", "statsd_atom", "android_system_property", "entity_state_residency", "trace_provenance", "protovms", "trace_attributes", "android_aflags", "gpu_info", "interrupt_info", "module_symbols", "deobfuscation_mapping", "process_descriptor", "thread_descriptor", "ftrace_events", "synchronization_marker", "compressed_packets", "zstd_compressed_packets", "extension_descriptor", "etw_events", "v8_js_code", "v8_internal_code", "v8_wasm_code", "v8_reg_exp_code", "v8_code_move", "remote_clock_sync", "pixel_modem_events", "pixel_modem_token_database", "clone_snapshot_trigger", "kernel_wakelock_data", "cpu_per_uid_data", "user_list", "journald_event", "recovered_trace_info", "for_testing", "trusted_uid", "trusted_packet_sequence_id", "trusted_pid", "interned_data", "sequence_flags", "incremental_state_cleared", "trace_packet_defaults", "previous_packet_dropped", "first_packet_on_sequence", "machine_id")
     Extensions: _python_message._ExtensionDict
     class SequenceFlags(int, metaclass=_enum_type_wrapper.EnumTypeWrapper):
         __slots__ = ()
@@ -19684,6 +19754,7 @@
     TRACE_CONFIG_FIELD_NUMBER: _ClassVar[int]
     FTRACE_STATS_FIELD_NUMBER: _ClassVar[int]
     TRACE_STATS_FIELD_NUMBER: _ClassVar[int]
+    EXPERIMENTAL_TRACING_V2_PRODUCER_STATS_FIELD_NUMBER: _ClassVar[int]
     PROFILE_PACKET_FIELD_NUMBER: _ClassVar[int]
     STREAMING_ALLOCATION_FIELD_NUMBER: _ClassVar[int]
     STREAMING_FREE_FIELD_NUMBER: _ClassVar[int]
@@ -19782,6 +19853,7 @@
     trace_config: TraceConfig
     ftrace_stats: FtraceStats
     trace_stats: TraceStats
+    experimental_tracing_v2_producer_stats: ExperimentalTracingV2ProducerStats
     profile_packet: ProfilePacket
     streaming_allocation: StreamingAllocation
     streaming_free: StreamingFree
@@ -19860,7 +19932,7 @@
     previous_packet_dropped: int
     first_packet_on_sequence: bool
     machine_id: int
-    def __init__(self, timestamp: _Optional[int] = ..., timestamp_clock_id: _Optional[int] = ..., track_event: _Optional[_Union[TrackEvent, _Mapping]] = ..., track_descriptor: _Optional[_Union[TrackDescriptor, _Mapping]] = ..., generic_kernel_task_state_event: _Optional[_Union[GenericKernelTaskStateEvent, _Mapping]] = ..., generic_kernel_cpu_freq_event: _Optional[_Union[GenericKernelCpuFrequencyEvent, _Mapping]] = ..., generic_kernel_task_rename_event: _Optional[_Union[GenericKernelTaskRenameEvent, _Mapping]] = ..., generic_kernel_process_tree: _Optional[_Union[GenericKernelProcessTree, _Mapping]] = ..., generic_gpu_frequency_event: _Optional[_Union[GenericGpuFrequencyEvent, _Mapping]] = ..., process_tree: _Optional[_Union[ProcessTree, _Mapping]] = ..., track_event_range_of_interest: _Optional[_Union[TrackEventRangeOfInterest, _Mapping]] = ..., process_stats: _Optional[_Union[ProcessStats, _Mapping]] = ..., inode_file_map: _Optional[_Union[InodeFileMap, _Mapping]] = ..., chrome_events: _Optional[_Union[ChromeEventBundle, _Mapping]] = ..., clock_snapshot: _Optional[_Union[ClockSnapshot, _Mapping]] = ..., sys_stats: _Optional[_Union[SysStats, _Mapping]] = ..., trace_uuid: _Optional[_Union[TraceUuid, _Mapping]] = ..., trace_config: _Optional[_Union[TraceConfig, _Mapping]] = ..., ftrace_stats: _Optional[_Union[FtraceStats, _Mapping]] = ..., trace_stats: _Optional[_Union[TraceStats, _Mapping]] = ..., profile_packet: _Optional[_Union[ProfilePacket, _Mapping]] = ..., streaming_allocation: _Optional[_Union[StreamingAllocation, _Mapping]] = ..., streaming_free: _Optional[_Union[StreamingFree, _Mapping]] = ..., battery: _Optional[_Union[BatteryCounters, _Mapping]] = ..., power_rails: _Optional[_Union[PowerRails, _Mapping]] = ..., android_log: _Optional[_Union[AndroidLogPacket, _Mapping]] = ..., system_info: _Optional[_Union[SystemInfo, _Mapping]] = ..., trigger: _Optional[_Union[Trigger, _Mapping]] = ..., chrome_trigger: _Optional[_Union[ChromeTrigger, _Mapping]] = ..., packages_list: _Optional[_Union[PackagesList, _Mapping]] = ..., chrome_benchmark_metadata: _Optional[_Union[ChromeBenchmarkMetadata, _Mapping]] = ..., perfetto_metatrace: _Optional[_Union[PerfettoMetatrace, _Mapping]] = ..., chrome_metadata: _Optional[_Union[ChromeMetadataPacket, _Mapping]] = ..., gpu_counter_event: _Optional[_Union[GpuCounterEvent, _Mapping]] = ..., gpu_render_stage_event: _Optional[_Union[GpuRenderStageEvent, _Mapping]] = ..., streaming_profile_packet: _Optional[_Union[StreamingProfilePacket, _Mapping]] = ..., art_process_metadata: _Optional[_Union[ArtProcessMetadata, _Mapping]] = ..., graphics_frame_event: _Optional[_Union[GraphicsFrameEvent, _Mapping]] = ..., vulkan_memory_event: _Optional[_Union[VulkanMemoryEvent, _Mapping]] = ..., gpu_log: _Optional[_Union[GpuLog, _Mapping]] = ..., vulkan_api_event: _Optional[_Union[VulkanApiEvent, _Mapping]] = ..., perf_sample: _Optional[_Union[PerfSample, _Mapping]] = ..., cpu_info: _Optional[_Union[CpuInfo, _Mapping]] = ..., smaps_packet: _Optional[_Union[SmapsPacket, _Mapping]] = ..., service_event: _Optional[_Union[TracingServiceEvent, _Mapping]] = ..., concurrent_session_event: _Optional[_Union[ConcurrentSessionEvent, _Mapping]] = ..., stack_sample: _Optional[_Union[StackSample, _Mapping]] = ..., initial_display_state: _Optional[_Union[InitialDisplayState, _Mapping]] = ..., gpu_mem_total_event: _Optional[_Union[GpuMemTotalEvent, _Mapping]] = ..., memory_tracker_snapshot: _Optional[_Union[MemoryTrackerSnapshot, _Mapping]] = ..., android_energy_estimation_breakdown: _Optional[_Union[AndroidEnergyEstimationBreakdown, _Mapping]] = ..., ui_state: _Optional[_Union[UiState, _Mapping]] = ..., translation_table: _Optional[_Union[TranslationTable, _Mapping]] = ..., android_game_intervention_list: _Optional[_Union[AndroidGameInterventionList, _Mapping]] = ..., statsd_atom: _Optional[_Union[StatsdAtom, _Mapping]] = ..., android_system_property: _Optional[_Union[AndroidSystemProperty, _Mapping]] = ..., entity_state_residency: _Optional[_Union[EntityStateResidency, _Mapping]] = ..., trace_provenance: _Optional[_Union[TraceProvenance, _Mapping]] = ..., protovms: _Optional[_Union[TracePacket.ProtoVms, _Mapping]] = ..., trace_attributes: _Optional[_Union[TraceAttributes, _Mapping]] = ..., android_aflags: _Optional[_Union[AndroidAflags, _Mapping]] = ..., gpu_info: _Optional[_Union[GpuInfo, _Mapping]] = ..., interrupt_info: _Optional[_Union[InterruptInfo, _Mapping]] = ..., module_symbols: _Optional[_Union[ModuleSymbols, _Mapping]] = ..., deobfuscation_mapping: _Optional[_Union[DeobfuscationMapping, _Mapping]] = ..., process_descriptor: _Optional[_Union[ProcessDescriptor, _Mapping]] = ..., thread_descriptor: _Optional[_Union[ThreadDescriptor, _Mapping]] = ..., ftrace_events: _Optional[_Union[FtraceEventBundle, _Mapping]] = ..., synchronization_marker: _Optional[bytes] = ..., compressed_packets: _Optional[bytes] = ..., zstd_compressed_packets: _Optional[bytes] = ..., extension_descriptor: _Optional[_Union[ExtensionDescriptor, _Mapping]] = ..., etw_events: _Optional[_Union[EtwTraceEventBundle, _Mapping]] = ..., v8_js_code: _Optional[_Union[V8JsCode, _Mapping]] = ..., v8_internal_code: _Optional[_Union[V8InternalCode, _Mapping]] = ..., v8_wasm_code: _Optional[_Union[V8WasmCode, _Mapping]] = ..., v8_reg_exp_code: _Optional[_Union[V8RegExpCode, _Mapping]] = ..., v8_code_move: _Optional[_Union[V8CodeMove, _Mapping]] = ..., remote_clock_sync: _Optional[_Union[RemoteClockSync, _Mapping]] = ..., pixel_modem_events: _Optional[_Union[PixelModemEvents, _Mapping]] = ..., pixel_modem_token_database: _Optional[_Union[PixelModemTokenDatabase, _Mapping]] = ..., clone_snapshot_trigger: _Optional[_Union[Trigger, _Mapping]] = ..., kernel_wakelock_data: _Optional[_Union[KernelWakelockData, _Mapping]] = ..., cpu_per_uid_data: _Optional[_Union[CpuPerUidData, _Mapping]] = ..., user_list: _Optional[_Union[AndroidUserList, _Mapping]] = ..., journald_event: _Optional[_Union[SystemdJournaldEvent, _Mapping]] = ..., recovered_trace_info: _Optional[_Union[RecoveredTraceInfo, _Mapping]] = ..., for_testing: _Optional[_Union[TestEvent, _Mapping]] = ..., trusted_uid: _Optional[int] = ..., trusted_packet_sequence_id: _Optional[int] = ..., trusted_pid: _Optional[int] = ..., interned_data: _Optional[_Union[InternedData, _Mapping]] = ..., sequence_flags: _Optional[int] = ..., incremental_state_cleared: bool = ..., trace_packet_defaults: _Optional[_Union[TracePacketDefaults, _Mapping]] = ..., previous_packet_dropped: _Optional[int] = ..., first_packet_on_sequence: bool = ..., machine_id: _Optional[int] = ...) -> None: ...
+    def __init__(self, timestamp: _Optional[int] = ..., timestamp_clock_id: _Optional[int] = ..., track_event: _Optional[_Union[TrackEvent, _Mapping]] = ..., track_descriptor: _Optional[_Union[TrackDescriptor, _Mapping]] = ..., generic_kernel_task_state_event: _Optional[_Union[GenericKernelTaskStateEvent, _Mapping]] = ..., generic_kernel_cpu_freq_event: _Optional[_Union[GenericKernelCpuFrequencyEvent, _Mapping]] = ..., generic_kernel_task_rename_event: _Optional[_Union[GenericKernelTaskRenameEvent, _Mapping]] = ..., generic_kernel_process_tree: _Optional[_Union[GenericKernelProcessTree, _Mapping]] = ..., generic_gpu_frequency_event: _Optional[_Union[GenericGpuFrequencyEvent, _Mapping]] = ..., process_tree: _Optional[_Union[ProcessTree, _Mapping]] = ..., track_event_range_of_interest: _Optional[_Union[TrackEventRangeOfInterest, _Mapping]] = ..., process_stats: _Optional[_Union[ProcessStats, _Mapping]] = ..., inode_file_map: _Optional[_Union[InodeFileMap, _Mapping]] = ..., chrome_events: _Optional[_Union[ChromeEventBundle, _Mapping]] = ..., clock_snapshot: _Optional[_Union[ClockSnapshot, _Mapping]] = ..., sys_stats: _Optional[_Union[SysStats, _Mapping]] = ..., trace_uuid: _Optional[_Union[TraceUuid, _Mapping]] = ..., trace_config: _Optional[_Union[TraceConfig, _Mapping]] = ..., ftrace_stats: _Optional[_Union[FtraceStats, _Mapping]] = ..., trace_stats: _Optional[_Union[TraceStats, _Mapping]] = ..., experimental_tracing_v2_producer_stats: _Optional[_Union[ExperimentalTracingV2ProducerStats, _Mapping]] = ..., profile_packet: _Optional[_Union[ProfilePacket, _Mapping]] = ..., streaming_allocation: _Optional[_Union[StreamingAllocation, _Mapping]] = ..., streaming_free: _Optional[_Union[StreamingFree, _Mapping]] = ..., battery: _Optional[_Union[BatteryCounters, _Mapping]] = ..., power_rails: _Optional[_Union[PowerRails, _Mapping]] = ..., android_log: _Optional[_Union[AndroidLogPacket, _Mapping]] = ..., system_info: _Optional[_Union[SystemInfo, _Mapping]] = ..., trigger: _Optional[_Union[Trigger, _Mapping]] = ..., chrome_trigger: _Optional[_Union[ChromeTrigger, _Mapping]] = ..., packages_list: _Optional[_Union[PackagesList, _Mapping]] = ..., chrome_benchmark_metadata: _Optional[_Union[ChromeBenchmarkMetadata, _Mapping]] = ..., perfetto_metatrace: _Optional[_Union[PerfettoMetatrace, _Mapping]] = ..., chrome_metadata: _Optional[_Union[ChromeMetadataPacket, _Mapping]] = ..., gpu_counter_event: _Optional[_Union[GpuCounterEvent, _Mapping]] = ..., gpu_render_stage_event: _Optional[_Union[GpuRenderStageEvent, _Mapping]] = ..., streaming_profile_packet: _Optional[_Union[StreamingProfilePacket, _Mapping]] = ..., art_process_metadata: _Optional[_Union[ArtProcessMetadata, _Mapping]] = ..., graphics_frame_event: _Optional[_Union[GraphicsFrameEvent, _Mapping]] = ..., vulkan_memory_event: _Optional[_Union[VulkanMemoryEvent, _Mapping]] = ..., gpu_log: _Optional[_Union[GpuLog, _Mapping]] = ..., vulkan_api_event: _Optional[_Union[VulkanApiEvent, _Mapping]] = ..., perf_sample: _Optional[_Union[PerfSample, _Mapping]] = ..., cpu_info: _Optional[_Union[CpuInfo, _Mapping]] = ..., smaps_packet: _Optional[_Union[SmapsPacket, _Mapping]] = ..., service_event: _Optional[_Union[TracingServiceEvent, _Mapping]] = ..., concurrent_session_event: _Optional[_Union[ConcurrentSessionEvent, _Mapping]] = ..., stack_sample: _Optional[_Union[StackSample, _Mapping]] = ..., initial_display_state: _Optional[_Union[InitialDisplayState, _Mapping]] = ..., gpu_mem_total_event: _Optional[_Union[GpuMemTotalEvent, _Mapping]] = ..., memory_tracker_snapshot: _Optional[_Union[MemoryTrackerSnapshot, _Mapping]] = ..., android_energy_estimation_breakdown: _Optional[_Union[AndroidEnergyEstimationBreakdown, _Mapping]] = ..., ui_state: _Optional[_Union[UiState, _Mapping]] = ..., translation_table: _Optional[_Union[TranslationTable, _Mapping]] = ..., android_game_intervention_list: _Optional[_Union[AndroidGameInterventionList, _Mapping]] = ..., statsd_atom: _Optional[_Union[StatsdAtom, _Mapping]] = ..., android_system_property: _Optional[_Union[AndroidSystemProperty, _Mapping]] = ..., entity_state_residency: _Optional[_Union[EntityStateResidency, _Mapping]] = ..., trace_provenance: _Optional[_Union[TraceProvenance, _Mapping]] = ..., protovms: _Optional[_Union[TracePacket.ProtoVms, _Mapping]] = ..., trace_attributes: _Optional[_Union[TraceAttributes, _Mapping]] = ..., android_aflags: _Optional[_Union[AndroidAflags, _Mapping]] = ..., gpu_info: _Optional[_Union[GpuInfo, _Mapping]] = ..., interrupt_info: _Optional[_Union[InterruptInfo, _Mapping]] = ..., module_symbols: _Optional[_Union[ModuleSymbols, _Mapping]] = ..., deobfuscation_mapping: _Optional[_Union[DeobfuscationMapping, _Mapping]] = ..., process_descriptor: _Optional[_Union[ProcessDescriptor, _Mapping]] = ..., thread_descriptor: _Optional[_Union[ThreadDescriptor, _Mapping]] = ..., ftrace_events: _Optional[_Union[FtraceEventBundle, _Mapping]] = ..., synchronization_marker: _Optional[bytes] = ..., compressed_packets: _Optional[bytes] = ..., zstd_compressed_packets: _Optional[bytes] = ..., extension_descriptor: _Optional[_Union[ExtensionDescriptor, _Mapping]] = ..., etw_events: _Optional[_Union[EtwTraceEventBundle, _Mapping]] = ..., v8_js_code: _Optional[_Union[V8JsCode, _Mapping]] = ..., v8_internal_code: _Optional[_Union[V8InternalCode, _Mapping]] = ..., v8_wasm_code: _Optional[_Union[V8WasmCode, _Mapping]] = ..., v8_reg_exp_code: _Optional[_Union[V8RegExpCode, _Mapping]] = ..., v8_code_move: _Optional[_Union[V8CodeMove, _Mapping]] = ..., remote_clock_sync: _Optional[_Union[RemoteClockSync, _Mapping]] = ..., pixel_modem_events: _Optional[_Union[PixelModemEvents, _Mapping]] = ..., pixel_modem_token_database: _Optional[_Union[PixelModemTokenDatabase, _Mapping]] = ..., clone_snapshot_trigger: _Optional[_Union[Trigger, _Mapping]] = ..., kernel_wakelock_data: _Optional[_Union[KernelWakelockData, _Mapping]] = ..., cpu_per_uid_data: _Optional[_Union[CpuPerUidData, _Mapping]] = ..., user_list: _Optional[_Union[AndroidUserList, _Mapping]] = ..., journald_event: _Optional[_Union[SystemdJournaldEvent, _Mapping]] = ..., recovered_trace_info: _Optional[_Union[RecoveredTraceInfo, _Mapping]] = ..., for_testing: _Optional[_Union[TestEvent, _Mapping]] = ..., trusted_uid: _Optional[int] = ..., trusted_packet_sequence_id: _Optional[int] = ..., trusted_pid: _Optional[int] = ..., interned_data: _Optional[_Union[InternedData, _Mapping]] = ..., sequence_flags: _Optional[int] = ..., incremental_state_cleared: bool = ..., trace_packet_defaults: _Optional[_Union[TracePacketDefaults, _Mapping]] = ..., previous_packet_dropped: _Optional[int] = ..., first_packet_on_sequence: bool = ..., machine_id: _Optional[int] = ...) -> None: ...
 
 class Trace(_message.Message):
     __slots__ = ("packet",)
diff --git a/python/perfetto/trace_processor/api.py b/python/perfetto/trace_processor/api.py
index 83a43bc..883de36 100644
--- a/python/perfetto/trace_processor/api.py
+++ b/python/perfetto/trace_processor/api.py
@@ -303,6 +303,9 @@
     Returns:
       The metrics data as a proto message
     """
+    # A bare string would otherwise be split into one metric per character.
+    if isinstance(metrics, str):
+      metrics = [metrics]
     response = self._backend.compute_metric(metrics)
     if response.error:
       raise TraceProcessorException(response.error)
diff --git a/python/perfetto/trace_processor/rpc.py b/python/perfetto/trace_processor/rpc.py
index 0378a29..820a895 100644
--- a/python/perfetto/trace_processor/rpc.py
+++ b/python/perfetto/trace_processor/rpc.py
@@ -12,6 +12,8 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+from typing import List
+
 from perfetto.common.exceptions import PerfettoException
 from perfetto.trace_processor.protos import ProtoFactory
 from perfetto.trace_processor.backend import TraceProcessorBackend
@@ -20,7 +22,7 @@
 def _not_supported_yet(what: str) -> NotImplementedError:
   return NotImplementedError(
       f'{what} is not supported yet when connected to a trace processor '
-      'session; only query() is.')
+      'session; only query() and metric() are.')
 
 
 class TraceProcessorRpc(TraceProcessorBackend):
@@ -48,9 +50,8 @@
     merged here so callers get the same shape TraceProcessorHttp returns.
     """
     stream = self.protos.TraceProcessorRpcStream()
-    # Fill in the request in place inside the stream, so it isn't copied.
-    request = stream.msg.add()
-    request.request = self.protos.TraceProcessorRpc.TPM_QUERY_STREAMING
+    request = self._add_request(
+        stream, self.protos.TraceProcessorRpc.TPM_QUERY_STREAMING)
     request.query_args.sql_query = query
     self.transport.send(stream.SerializeToString())
 
@@ -63,6 +64,21 @@
       if result.batch and result.batch[-1].is_last_batch:
         return result
 
+  def compute_metric(self, metrics: List[str]):
+    """Computes `metrics` and returns a ComputeMetricResult."""
+    stream = self.protos.TraceProcessorRpcStream()
+    request = self._add_request(
+        stream, self.protos.TraceProcessorRpc.TPM_COMPUTE_METRIC)
+    # format is left unset: the default is BINARY_PROTOBUF, as over HTTP.
+    request.compute_metric_args.metric_names.extend(metrics)
+    self.transport.send(stream.SerializeToString())
+
+    # Unlike queries, the server answers with exactly one message.
+    rpc_message = self.protos.TraceProcessorRpc()
+    rpc_message.ParseFromString(self._read_payload())
+    self._check_envelope(rpc_message)
+    return rpc_message.metric_result
+
   def close(self):
     self.transport.close()
 
@@ -71,9 +87,6 @@
   # so fail with a clear message.
   # TODO(gabiyev): implement these over the RPC protocol in a follow-up.
 
-  def compute_metric(self, metrics):
-    raise _not_supported_yet('metric()')
-
   def trace_summary(self, specs, metric_ids=None, metadata_query_id=None):
     raise _not_supported_yet('trace_summary()')
 
@@ -92,6 +105,12 @@
   def notify_eof(self):
     raise _not_supported_yet('Loading a trace')
 
+  def _add_request(self, out_rpc_stream, method):
+    """Appends an empty `method` request to `out_rpc_stream` and returns it."""
+    request = out_rpc_stream.msg.add()
+    request.request = method
+    return request
+
   def _check_envelope(self, rpc_message):
     """Raises if the server replied with an error instead of a result.
 
diff --git a/python/test/api_integrationtest.py b/python/test/api_integrationtest.py
index 3692059..acf334a 100644
--- a/python/test/api_integrationtest.py
+++ b/python/test/api_integrationtest.py
@@ -826,6 +826,23 @@
       # usable for the next query.
       self.assertEqual(next(tp.query('select 1 as x')).x, 1)
 
+  def test_metric(self):
+    with TraceProcessor(remote=self.SESSION_NAME) as tp:
+      startups = tp.metric(['android_startup']).android_startup.startup
+      self.assertEqual(
+          [s.package_name for s in startups],
+          ['com.android.chrome', 'com.google.android.GoogleCamera'])
+      self.assertEqual(startups[0].startup_type, 'cold')
+      self.assertEqual(startups[0].to_first_frame.dur_ns, 373584672)
+
+  def test_metric_error_then_recovers(self):
+    with TraceProcessor(remote=self.SESSION_NAME) as tp:
+      with self.assertRaisesRegex(TraceProcessorException, 'Unknown metric'):
+        tp.metric(['no_such_metric'])
+      # The error comes back inside the single reply message, leaving the
+      # connection usable for the next request.
+      self.assertEqual(next(tp.query('select 1 as x')).x, 1)
+
   def test_missing_session(self):
     with self.assertRaisesRegex(TraceProcessorException,
                                 'No live trace processor session') as ctx:
diff --git a/python/tools/check_ratchet.py b/python/tools/check_ratchet.py
index b748c84..f6dada0 100755
--- a/python/tools/check_ratchet.py
+++ b/python/tools/check_ratchet.py
@@ -36,7 +36,7 @@
 
 from dataclasses import dataclass
 
-EXPECTED_ANY_COUNT = 28
+EXPECTED_ANY_COUNT = 26
 EXPECTED_RUN_METRIC_COUNT = 2
 
 ROOT_DIR = os.path.dirname(
diff --git a/src/android_sdk/java/main/dev/perfetto/sdk/PerfettoTrackEventBuilder.java b/src/android_sdk/java/main/dev/perfetto/sdk/PerfettoTrackEventBuilder.java
index bac78bd..0515e3f 100644
--- a/src/android_sdk/java/main/dev/perfetto/sdk/PerfettoTrackEventBuilder.java
+++ b/src/android_sdk/java/main/dev/perfetto/sdk/PerfettoTrackEventBuilder.java
@@ -139,14 +139,24 @@
   private static final PerfettoTrackEventBuilder NO_OP_BUILDER =
       new PerfettoTrackEventBuilder(/* isCategoryEnabled= */ false, /* parent= */ null);
 
-  public static final ThreadLocal<PerfettoTrackEventBuilder> sThreadLocalBuilder =
-      ThreadLocal.withInitial(
-          () -> new PerfettoTrackEventBuilder(/* isCategoryEnabled= */ true, /* parent= */ null));
+  private static final int MAX_POOLED_BUILDERS = 2;
+
+  private static final ThreadLocal<PerfettoTrackEventBuilder[]> sThreadLocalBuilder =
+      ThreadLocal.withInitial(() -> new PerfettoTrackEventBuilder[MAX_POOLED_BUILDERS]);
 
   public static PerfettoTrackEventBuilder newEvent(
       int traceType, Category category, boolean isDebug) {
     if (category.isRegistered() && category.isEnabled()) {
-      return sThreadLocalBuilder.get().initNewEvent(traceType, category, isDebug);
+      PerfettoTrackEventBuilder[] pool = sThreadLocalBuilder.get();
+      for (int i = MAX_POOLED_BUILDERS - 1; i >= 0; i--) {
+        PerfettoTrackEventBuilder builder = pool[i];
+        if (builder != null) {
+          pool[i] = null;
+          return builder.initNewEvent(traceType, category, isDebug);
+        }
+      }
+      return new PerfettoTrackEventBuilder(/* isCategoryEnabled= */ true, /* parent= */ null)
+          .initNewEvent(traceType, category, isDebug);
     }
     return NO_OP_BUILDER;
   }
@@ -184,10 +194,22 @@
     if (mIsDebug) {
       checkNotBuildingProto();
     }
+    if (mIsBuilt) {
+      return;
+    }
 
     mIsBuilt = true;
     PerfettoTrackEventExtra.native_emit(
         mTraceType, mCategory.getPtr(), mEventName, mExtra.getPtr());
+    if (mParent == null) {
+      PerfettoTrackEventBuilder[] pool = sThreadLocalBuilder.get();
+      for (int i = 0; i < MAX_POOLED_BUILDERS; i++) {
+        if (pool[i] == null) {
+          pool[i] = this;
+          break;
+        }
+      }
+    }
   }
 
   /** Initialize the builder for a new trace event. */
diff --git a/src/android_sdk/java/test/dev/perfetto/sdk/test/PerfettoTraceTest.java b/src/android_sdk/java/test/dev/perfetto/sdk/test/PerfettoTraceTest.java
index fc09d8b..42f4e67 100644
--- a/src/android_sdk/java/test/dev/perfetto/sdk/test/PerfettoTraceTest.java
+++ b/src/android_sdk/java/test/dev/perfetto/sdk/test/PerfettoTraceTest.java
@@ -1064,6 +1064,90 @@
     assertThat(mDebugAnnotationNames).containsExactly("arg");
   }
 
+  private static long emitInnerEvent(long value) {
+    PerfettoTrace.instant(FOO_CATEGORY, "inner")
+        .addArg("inner_arg", value)
+        .addArg("inner_str", "inner_string_that_clobbers_shared_buffer")
+        .emit();
+    return value;
+  }
+
+  @Test
+  public void testEventEmittedWhileBuildingAnother() throws Exception {
+    TraceConfig traceConfig = getTraceConfig(FOO);
+    PerfettoTrace.Session session = new PerfettoTrace.Session(true, traceConfig.toByteArray());
+
+    // Inner events are emitted from the outer event's argument list, both for a
+    // debug arg and inside a proto field. Strings (including one that spills
+    // into overflow_strings) are set before the inner emits to verify that the
+    // inner emit does not overwrite or free the outer event's strings.
+    PerfettoTrace.instant(FOO_CATEGORY, "outer")
+        .setCorrelationId("outer_corr")
+        .addArg("outer_str", "hello")
+        .addArg("outer_long_str", TEXT_ABOVE_4K_SIZE)
+        .addArg("outer_arg", emitInnerEvent(1))
+        .beginProto()
+        .beginNested(33L)
+        .addField(3, "outer_function")
+        .addField(4L, emitInnerEvent(2))
+        .endNested()
+        .endProto()
+        .emit();
+
+    byte[] traceBytes = session.close();
+    Trace trace = Trace.parseFrom(traceBytes);
+    for (TracePacket packet : trace.getPacketList()) {
+      collectInternedData(packet);
+    }
+
+    TrackEvent inner1 = getTrackEvent(trace, 0);
+    TrackEvent inner2 = getTrackEvent(trace, 1);
+    TrackEvent outer = getTrackEvent(trace, 2);
+    assertThat(getTrackEvent(trace, 3)).isNull();
+
+    assertThat(inner1.getDebugAnnotations(0).getIntValue()).isEqualTo(1);
+    assertThat(inner1.hasSourceLocation()).isFalse();
+    assertThat(inner2.getDebugAnnotations(0).getIntValue()).isEqualTo(2);
+    assertThat(inner2.hasSourceLocation()).isFalse();
+
+    assertThat(outer.getCorrelationIdStr()).isEqualTo("outer_corr");
+    assertThat(outer.getDebugAnnotationsCount()).isEqualTo(3);
+    assertThat(outer.getDebugAnnotations(0).getStringValue()).isEqualTo("hello");
+    assertThat(outer.getDebugAnnotations(1).getStringValue()).isEqualTo(TEXT_ABOVE_4K_SIZE);
+    assertThat(outer.getDebugAnnotations(2).getIntValue()).isEqualTo(1);
+    assertThat(outer.getSourceLocation().getFunctionName()).isEqualTo("outer_function");
+    assertThat(outer.getSourceLocation().getLineNumber()).isEqualTo(2);
+
+    assertThat(mEventNames).containsExactly("inner", "outer");
+    assertThat(mDebugAnnotationNames)
+        .containsExactly("inner_arg", "inner_str", "outer_str", "outer_long_str", "outer_arg");
+  }
+
+  @Test
+  public void testAbandonedEventsDoNotBreakLaterEvents() throws Exception {
+    TraceConfig traceConfig = getTraceConfig(FOO);
+    PerfettoTrace.Session session = new PerfettoTrace.Session(true, traceConfig.toByteArray());
+
+    // More abandoned (never emitted) events than there are builders pooled per
+    // thread, followed by a nested event.
+    for (int i = 0; i < 20; i++) {
+      PerfettoTrace.instant(FOO_CATEGORY, "abandoned").addArg("abandoned_arg", i);
+    }
+    PerfettoTrace.instant(FOO_CATEGORY, "outer").addArg("outer_arg", emitInnerEvent(42)).emit();
+
+    byte[] traceBytes = session.close();
+    Trace trace = Trace.parseFrom(traceBytes);
+    for (TracePacket packet : trace.getPacketList()) {
+      collectInternedData(packet);
+    }
+
+    assertThat(getTrackEvent(trace, 0).getDebugAnnotations(0).getIntValue()).isEqualTo(42);
+    assertThat(getTrackEvent(trace, 1).getDebugAnnotations(0).getIntValue()).isEqualTo(42);
+    assertThat(getTrackEvent(trace, 2)).isNull();
+    assertThat(mEventNames).containsExactly("inner", "outer");
+    assertThat(mDebugAnnotationNames).containsExactly("inner_arg", "inner_str", "outer_arg");
+  }
+
   private TrackEvent getTrackEvent(Trace trace, int idx) {
     int curIdx = 0;
     for (TracePacket packet : trace.getPacketList()) {
diff --git a/src/android_sdk/jni/dev_perfetto_sdk_PerfettoTrackEventExtra.cc b/src/android_sdk/jni/dev_perfetto_sdk_PerfettoTrackEventExtra.cc
index fb55e00..4db6c98 100644
--- a/src/android_sdk/jni/dev_perfetto_sdk_PerfettoTrackEventExtra.cc
+++ b/src/android_sdk/jni/dev_perfetto_sdk_PerfettoTrackEventExtra.cc
@@ -225,7 +225,7 @@
   auto& arg_string = arg->get()->arg_string;
   arg_string.header.type = PERFETTO_TE_HL_EXTRA_TYPE_DEBUG_ARG_STRING;
   arg_string.name = arg->name();
-  arg_string.value = StringBuffer::utf16_to_ascii(env, val).data();
+  arg_string.value = arg->set_value(StringBuffer::utf16_to_ascii(env, val));
 }
 
 static jlong dev_perfetto_sdk_PerfettoTrackEventExtraField_init(
@@ -293,7 +293,7 @@
   auto& field_cstr = field->get()->field_cstr;
   field_cstr.header.type = PERFETTO_TE_HL_PROTO_TYPE_CSTR;
   field_cstr.header.id = static_cast<uint32_t>(id);
-  field_cstr.str = StringBuffer::utf16_to_ascii(env, val).data();
+  field_cstr.str = field->set_str(StringBuffer::utf16_to_ascii(env, val));
 }
 
 static void
@@ -308,7 +308,7 @@
   auto& field_cstr = field->get()->field_cstr_interned;
   field_cstr.header.type = PERFETTO_TE_HL_PROTO_TYPE_CSTR_INTERNED;
   field_cstr.header.id = static_cast<uint32_t>(id);
-  field_cstr.str = StringBuffer::utf16_to_ascii(env, val).data();
+  field_cstr.str = field->set_str(StringBuffer::utf16_to_ascii(env, val));
   field_cstr.interned_type_id = static_cast<uint32_t>(interned_type_id);
 }
 
@@ -553,7 +553,7 @@
       toPointer<sdk_for_jni::CorrelationId>(ptr);
   auto& id_str = correlation_id->get()->correlation_id_str;
   id_str.header.type = PERFETTO_TE_HL_EXTRA_TYPE_CORRELATION_ID_STR;
-  id_str.str = StringBuffer::utf16_to_ascii(env, val).data();
+  id_str.str = correlation_id->set_str(StringBuffer::utf16_to_ascii(env, val));
 }
 
 static jlong dev_perfetto_sdk_PerfettoTrackEventExtraCounter_init(
diff --git a/src/android_sdk/perfetto_sdk_for_jni/tracing_sdk.h b/src/android_sdk/perfetto_sdk_for_jni/tracing_sdk.h
index dadcd1e..7ccc273 100644
--- a/src/android_sdk/perfetto_sdk_for_jni/tracing_sdk.h
+++ b/src/android_sdk/perfetto_sdk_for_jni/tracing_sdk.h
@@ -23,6 +23,7 @@
 
 #include <optional>
 #include <string>
+#include <string_view>
 #include <vector>
 
 #include "perfetto/public/abi/track_event_hl_abi.h"
@@ -286,11 +287,16 @@
 
   static void delete_correlation_id(CorrelationId* ptr) { delete ptr; }
 
+  const char* set_str(std::string_view val) {
+    str_ = val;
+    return str_.c_str();
+  }
   PerfettoTeHlExtraCorrelationIdUnion* get() { return &correlation_id_; }
 
  private:
   DISALLOW_COPY_AND_ASSIGN(CorrelationId);
   PerfettoTeHlExtraCorrelationIdUnion correlation_id_;
+  std::string str_;
 };
 
 /**
@@ -303,12 +309,17 @@
   static void delete_arg(DebugArg* arg) { delete arg; }
 
   const char* name() const { return name_.c_str(); }
+  const char* set_value(std::string_view val) {
+    value_ = val;
+    return value_.c_str();
+  }
   PerfettoTeHlExtraDebugArgUnion* get() { return &arg_; }
 
  private:
   DISALLOW_COPY_AND_ASSIGN(DebugArg);
   PerfettoTeHlExtraDebugArgUnion arg_;
   const std::string name_;
+  std::string value_;
 };
 
 class ProtoField {
@@ -316,11 +327,16 @@
   ProtoField() {}
   static void delete_field(ProtoField* field) { delete field; }
 
+  const char* set_str(std::string_view val) {
+    str_ = val;
+    return str_.c_str();
+  }
   PerfettoTeHlProtoFieldUnion* get() { return &arg_; }
 
  private:
   DISALLOW_COPY_AND_ASSIGN(ProtoField);
   PerfettoTeHlProtoFieldUnion arg_;
+  std::string str_;
 };
 
 class ProtoFieldNested {
diff --git a/src/base/BUILD.gn b/src/base/BUILD.gn
index e8df743..e389faf 100644
--- a/src/base/BUILD.gn
+++ b/src/base/BUILD.gn
@@ -341,6 +341,7 @@
       "flat_set_benchmark.cc",
       "regex/regex_benchmark.cc",
       "rt_mutex_benchmark.cc",
+      "status_benchmark.cc",
       "task_runner_benchmark.cc",
     ]
   }
diff --git a/src/base/circular_queue_unittest.cc b/src/base/circular_queue_unittest.cc
index 2fb52fa..0ee5f03 100644
--- a/src/base/circular_queue_unittest.cc
+++ b/src/base/circular_queue_unittest.cc
@@ -322,6 +322,54 @@
   ASSERT_THAT(queue, ElementsAre(10, 20, 25, 30, 40));
 }
 
+// Grow a full queue for every possible internal begin_ offset, so that the
+// elements are split in two runs ([begin, capacity) and [0, end)) of all the
+// possible lengths, including the non-wrapped case.
+TEST(CircularQueueTest, GrowWhileWrapped) {
+  for (int offset = 0; offset < 8; offset++) {
+    CircularQueue<int> queue(/*initial_capacity=*/8);
+    for (int i = 0; i < offset; i++)
+      queue.emplace_back(-1);
+    queue.erase_front(static_cast<size_t>(offset));
+    for (int i = 0; i < 8; i++)
+      queue.emplace_back(i);
+    ASSERT_EQ(queue.capacity(), 8u);
+
+    queue.emplace_back(8);  // Triggers the growth.
+    ASSERT_EQ(queue.capacity(), 16u);
+    ASSERT_THAT(queue, ElementsAre(0, 1, 2, 3, 4, 5, 6, 7, 8));
+  }
+}
+
+TEST(CircularQueueTest, ShrinkWhileWrapped) {
+  CircularQueue<int> queue(/*initial_capacity=*/8192);
+  for (int i = 0; i < 8000; i++)
+    queue.emplace_back(-1);
+  queue.erase_front(7950);
+  for (int i = 0; i < 200; i++)  // Wraps after the first 192.
+    queue.emplace_back(i);
+  ASSERT_EQ(queue.capacity(), 8192u);
+  ASSERT_EQ(queue.size(), 250u);
+
+  queue.shrink_to_fit();
+  ASSERT_EQ(queue.capacity(), 4096u);
+  ASSERT_EQ(queue.size(), 250u);
+  for (size_t i = 0; i < 50; i++)
+    ASSERT_EQ(queue.at(i), -1);
+  for (size_t i = 0; i < 200; i++)
+    ASSERT_EQ(queue.at(50 + i), static_cast<int>(i));
+}
+
+TEST(CircularQueueTest, EraseFrontMoreThanSize) {
+  CircularQueue<int> queue(/*initial_capacity=*/4);
+  queue.emplace_back(1);
+  queue.emplace_back(2);
+  queue.erase_front(10);
+  ASSERT_TRUE(queue.empty());
+  queue.emplace_back(3);
+  ASSERT_THAT(queue, ElementsAre(3));
+}
+
 TEST(CircularQueueTest, ObjectLifetime) {
   class Checker {
    public:
@@ -428,6 +476,27 @@
     ASSERT_TRUE(std::is_sorted(q2.begin(), q2.end(), comparer));
     ASSERT_EQ(stats.num_alive, 200);
   }
+
+  // Check moves and dtors when growing while the queue is wrapped.
+  stats = Checker::Stats();
+  {
+    CircularQueue<Checker> queue(/*initial_capacity=*/4);
+    queue.emplace_back(&stats, 0);
+    queue.emplace_back(&stats, 1);
+    queue.erase_front(2);
+    ASSERT_EQ(stats.num_dtors, 2);
+    for (int i = 0; i < 4; i++)  // Occupies slots 2, 3, 0, 1.
+      queue.emplace_back(&stats, 10 + i);
+
+    queue.emplace_back(&stats, 14);  // Grows, moving the 4 wrapped elements.
+    ASSERT_EQ(queue.capacity(), 8u);
+    ASSERT_EQ(stats.num_dtors, 2 + 4);
+    ASSERT_EQ(stats.num_alive, 5);
+    for (size_t i = 0; i < 5; i++)
+      ASSERT_EQ(queue.at(i).n_, 10 + static_cast<int>(i));
+  }
+  ASSERT_EQ(stats.num_alive, 0);
+  ASSERT_EQ(stats.num_dtors, 2 + 4 + 5);
 }
 
 }  // namespace
diff --git a/src/base/status.cc b/src/base/status.cc
index edf2f90..a1a27c1 100644
--- a/src/base/status.cc
+++ b/src/base/status.cc
@@ -21,9 +21,48 @@
 #include <cstdio>
 #include <string>
 #include <utility>
+#include <vector>
+
+#include "perfetto/ext/base/no_destructor.h"
 
 namespace perfetto::base {
 
+struct Status::Rep {
+  struct Payload {
+    std::string type_url;
+    std::string payload;
+  };
+  std::string message;
+  std::vector<Payload> payloads;
+};
+
+Status::Status(std::string msg) {
+  PERFETTO_CHECK(!msg.empty());
+  rep_ = reinterpret_cast<uintptr_t>(new Rep{std::move(msg), {}});
+}
+
+void Status::Delete(uintptr_t rep) {
+  delete reinterpret_cast<Rep*>(rep);
+}
+
+uintptr_t Status::Clone(uintptr_t rep) {
+  return reinterpret_cast<uintptr_t>(new Rep(*reinterpret_cast<Rep*>(rep)));
+}
+
+// The status's Rep, or null if it has none.
+Status::Rep* Status::rep() const {
+  return rep_ > kMovedFrom ? reinterpret_cast<Rep*>(rep_) : nullptr;
+}
+
+const std::string& Status::message() const {
+  static NoDestructor<std::string> empty;
+  static NoDestructor<std::string> moved_from("Status accessed after move");
+  if (rep_ == kOk) {
+    return empty.ref();
+  }
+  return rep_ == kMovedFrom ? moved_from.ref() : rep()->message;
+}
+
 Status ErrStatus(const char* format, ...) {
   std::string buf;
   buf.resize(1024);
@@ -67,10 +106,10 @@
 
 std::optional<std::string_view> Status::GetPayload(
     std::string_view type_url) const {
-  if (ok()) {
+  if (!rep()) {
     return std::nullopt;
   }
-  for (const auto& kv : payloads_) {
+  for (const auto& kv : rep()->payloads) {
     if (kv.type_url == type_url) {
       return kv.payload;
     }
@@ -79,27 +118,29 @@
 }
 
 void Status::SetPayload(std::string_view type_url, std::string value) {
-  if (ok()) {
+  if (!rep()) {
     return;
   }
-  for (auto& kv : payloads_) {
+  for (auto& kv : rep()->payloads) {
     if (kv.type_url == type_url) {
       kv.payload = value;
       return;
     }
   }
-  payloads_.push_back(Payload{std::string(type_url), std::move(value)});
+  rep()->payloads.push_back(
+      Rep::Payload{std::string(type_url), std::move(value)});
 }
 
 bool Status::ErasePayload(std::string_view type_url) {
-  if (ok()) {
+  if (!rep()) {
     return false;
   }
+  auto& payloads = rep()->payloads;
   auto it = std::remove_if(
-      payloads_.begin(), payloads_.end(),
-      [type_url](const Payload& p) { return p.type_url == type_url; });
-  bool erased = it != payloads_.end();
-  payloads_.erase(it, payloads_.end());
+      payloads.begin(), payloads.end(),
+      [type_url](const Rep::Payload& p) { return p.type_url == type_url; });
+  bool erased = it != payloads.end();
+  payloads.erase(it, payloads.end());
   return erased;
 }
 
diff --git a/src/base/status_benchmark.cc b/src/base/status_benchmark.cc
new file mode 100644
index 0000000..3fbbd71
--- /dev/null
+++ b/src/base/status_benchmark.cc
@@ -0,0 +1,103 @@
+// Copyright (C) 2019 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.
+
+#include <random>
+
+#include <benchmark/benchmark.h>
+
+#include <cstdint>
+
+#include "perfetto/base/compiler.h"
+#include "perfetto/base/status.h"
+#include "perfetto/ext/base/status_macros.h"
+#include "perfetto/ext/base/status_or.h"
+
+namespace perfetto::base {
+namespace {
+
+// Chains of calls each returning a Status or StatusOr, as code propagating
+// errors through layers does. Kept out of line so each return is a real one.
+PERFETTO_NO_INLINE Status Leaf(int64_t i) {
+  benchmark::DoNotOptimize(i);
+  return i < 0 ? ErrStatus("negative: %d", static_cast<int>(i)) : OkStatus();
+}
+
+PERFETTO_NO_INLINE Status Middle(int64_t i) {
+  RETURN_IF_ERROR(Leaf(i));
+  RETURN_IF_ERROR(Leaf(i + 1));
+  return OkStatus();
+}
+
+PERFETTO_NO_INLINE Status Top(int64_t i) {
+  RETURN_IF_ERROR(Middle(i));
+  RETURN_IF_ERROR(Middle(i + 2));
+  return OkStatus();
+}
+
+PERFETTO_NO_INLINE StatusOr<int64_t> LeafOr(int64_t i) {
+  benchmark::DoNotOptimize(i);
+  if (i < 0) {
+    return ErrStatus("negative: %d", static_cast<int>(i));
+  }
+  return i * 2;
+}
+
+PERFETTO_NO_INLINE StatusOr<int64_t> MiddleOr(int64_t i) {
+  ASSIGN_OR_RETURN(int64_t a, LeafOr(i));
+  ASSIGN_OR_RETURN(int64_t b, LeafOr(i + 1));
+  return a + b;
+}
+
+PERFETTO_NO_INLINE StatusOr<int64_t> TopOr(int64_t i) {
+  ASSIGN_OR_RETURN(int64_t a, MiddleOr(i));
+  ASSIGN_OR_RETURN(int64_t b, MiddleOr(i + 2));
+  return a + b;
+}
+
+void BM_StatusOkChain(benchmark::State& state) {
+  int64_t i = 0;
+  for (auto _ : state) {
+    Status status = Top(i++);
+    benchmark::DoNotOptimize(status.ok());
+  }
+}
+BENCHMARK(BM_StatusOkChain);
+
+void BM_StatusErrorChain(benchmark::State& state) {
+  for (auto _ : state) {
+    Status status = Top(-10);
+    benchmark::DoNotOptimize(status.ok());
+  }
+}
+BENCHMARK(BM_StatusErrorChain);
+
+void BM_StatusOrOkChain(benchmark::State& state) {
+  int64_t i = 0;
+  for (auto _ : state) {
+    StatusOr<int64_t> value = TopOr(i++);
+    benchmark::DoNotOptimize(value.ok());
+  }
+}
+BENCHMARK(BM_StatusOrOkChain);
+
+void BM_StatusOrErrorChain(benchmark::State& state) {
+  for (auto _ : state) {
+    StatusOr<int64_t> value = TopOr(-10);
+    benchmark::DoNotOptimize(value.ok());
+  }
+}
+BENCHMARK(BM_StatusOrErrorChain);
+
+}  // namespace
+}  // namespace perfetto::base
diff --git a/src/base/status_or_unittest.cc b/src/base/status_or_unittest.cc
index 16489b3..f1b7721 100644
--- a/src/base/status_or_unittest.cc
+++ b/src/base/status_or_unittest.cc
@@ -17,7 +17,11 @@
 #include "perfetto/ext/base/status_or.h"
 
 #include <memory>
+#include <string>
 #include <utility>
+#include <vector>
+
+#include "perfetto/ext/base/status_macros.h"
 
 #include "test/gtest_and_gmock.h"
 
@@ -66,5 +70,114 @@
   ASSERT_DEATH_IF_SUPPORTED(std::move(result).ValueOrDie(), "");
 }
 
+// Counts the live objects of its type, so that a value constructed or
+// destroyed the wrong number of times shows.
+struct Counted {
+  static int live;
+  explicit Counted(int v) : value(v) { ++live; }
+  Counted(const Counted& other) : value(other.value) { ++live; }
+  Counted(Counted&& other) noexcept : value(other.value) { ++live; }
+  Counted& operator=(const Counted&) = default;
+  Counted& operator=(Counted&&) = default;
+  ~Counted() { --live; }
+  int value;
+};
+int Counted::live = 0;
+
+TEST(StatusOrTest, CopyAndMove) {
+  {
+    StatusOr<Counted> ok(Counted(1));
+    StatusOr<Counted> err(ErrStatus("bad"));
+    EXPECT_EQ(Counted::live, 1);
+
+    StatusOr<Counted> ok_copy(ok);
+    StatusOr<Counted> err_copy(err);
+    EXPECT_EQ(Counted::live, 2);
+    EXPECT_EQ(ok_copy->value, 1);
+    EXPECT_EQ(err_copy.status().message(), "bad");
+
+    // A moved-from StatusOr keeps its moved-from value.
+    StatusOr<Counted> ok_moved(std::move(ok));
+    StatusOr<Counted> err_moved(std::move(err));
+    EXPECT_EQ(Counted::live, 3);
+    EXPECT_EQ(ok_moved->value, 1);
+    EXPECT_EQ(err_moved.status().message(), "bad");
+  }
+  EXPECT_EQ(Counted::live, 0);
+}
+
+// Every transition between holding a value and holding an error.
+TEST(StatusOrTest, Assign) {
+  {
+    StatusOr<Counted> a(Counted(1));
+    StatusOr<Counted> b(Counted(2));
+    StatusOr<Counted> err(ErrStatus("bad"));
+
+    a = b;  // Value over value.
+    EXPECT_EQ(a->value, 2);
+    EXPECT_EQ(Counted::live, 2);
+
+    a = err;  // Error over value.
+    EXPECT_FALSE(a.ok());
+    EXPECT_EQ(a.status().message(), "bad");
+    EXPECT_EQ(Counted::live, 1);
+
+    a = b;  // Value over error.
+    EXPECT_EQ(a->value, 2);
+    EXPECT_EQ(Counted::live, 2);
+
+    a = StatusOr<Counted>(Counted(3));  // Value over value, moved.
+    EXPECT_EQ(a->value, 3);
+    EXPECT_EQ(Counted::live, 2);
+
+    a = StatusOr<Counted>(ErrStatus("worse"));  // Error over value, moved.
+    EXPECT_EQ(a.status().message(), "worse");
+    EXPECT_EQ(Counted::live, 1);
+
+    a = StatusOr<Counted>(Counted(4));  // Value over error, moved.
+    EXPECT_EQ(a->value, 4);
+    EXPECT_EQ(Counted::live, 2);
+
+    StatusOr<Counted>& self = a;
+    a = self;  // Self assignment.
+    EXPECT_EQ(a->value, 4);
+    EXPECT_EQ(Counted::live, 2);
+  }
+  EXPECT_EQ(Counted::live, 0);
+}
+
+TEST(StatusOrTest, StatusMovesErrorOut) {
+  StatusOr<std::string> err(ErrStatus("bad"));
+  Status status = std::move(err).status();
+  EXPECT_EQ(status.message(), "bad");
+
+  // An ok StatusOr keeps its value.
+  StatusOr<std::string> ok(std::string("value"));
+  EXPECT_TRUE(std::move(ok).status().ok());
+  EXPECT_EQ(ok.value(), "value");
+}
+
+namespace {
+
+StatusOr<int> Half(int x) {
+  if (x % 2 != 0) {
+    return ErrStatus("odd: %d", x);
+  }
+  return x / 2;
+}
+
+StatusOr<int> Quarter(int x) {
+  ASSIGN_OR_RETURN(int half, Half(x));
+  ASSIGN_OR_RETURN(int quarter, Half(half));
+  return quarter;
+}
+
+}  // namespace
+
+TEST(StatusOrTest, AssignOrReturn) {
+  EXPECT_EQ(Quarter(12).value(), 3);
+  EXPECT_EQ(Quarter(6).status().message(), "odd: 3");
+}
+
 }  // namespace base
 }  // namespace perfetto
diff --git a/src/base/status_unittest.cc b/src/base/status_unittest.cc
index 3978379..b9aa014 100644
--- a/src/base/status_unittest.cc
+++ b/src/base/status_unittest.cc
@@ -16,6 +16,7 @@
 
 #include "perfetto/base/status.h"
 #include <string>
+#include <utility>
 
 #include "test/gtest_and_gmock.h"
 
@@ -69,4 +70,42 @@
   ASSERT_EQ(status.GetPayload("test.foo.com/bar2"), "2");
 }
 
+TEST(StatusTest, OkHasEmptyMessage) {
+  Status status = OkStatus();
+  EXPECT_TRUE(status.ok());
+  EXPECT_EQ(status.message(), "");
+}
+
+TEST(StatusTest, CopyClonesError) {
+  Status error = ErrStatus("bad");
+  error.SetPayload("test.foo.com/bar", "1");
+  Status copy = error;
+  copy.SetPayload("test.foo.com/bar", "2");
+  EXPECT_EQ(copy.message(), "bad");
+  EXPECT_EQ(error.GetPayload("test.foo.com/bar"), "1");
+  EXPECT_EQ(copy.GetPayload("test.foo.com/bar"), "2");
+
+  copy = OkStatus();
+  EXPECT_TRUE(copy.ok());
+  copy = error;
+  EXPECT_EQ(copy.message(), "bad");
+}
+
+// Using a moved-from status is a bug, so it must not pass for ok.
+TEST(StatusTest, MovedFromIsAnError) {
+  Status ok = OkStatus();
+  Status error = ErrStatus("bad");
+  Status ok_moved = std::move(ok);
+  Status error_moved = std::move(error);
+  EXPECT_TRUE(ok_moved.ok());
+  EXPECT_EQ(error_moved.message(), "bad");
+  EXPECT_FALSE(ok.ok());     // NOLINT(bugprone-use-after-move)
+  EXPECT_FALSE(error.ok());  // NOLINT(bugprone-use-after-move)
+  EXPECT_EQ(error.message(), "Status accessed after move");
+
+  // A moved-from status can be assigned again.
+  error = ErrStatus("again");
+  EXPECT_EQ(error.message(), "again");
+}
+
 }  // namespace perfetto::base
diff --git a/src/base/type_set_unittest.cc b/src/base/type_set_unittest.cc
index 44edbf0..802f3dd 100644
--- a/src/base/type_set_unittest.cc
+++ b/src/base/type_set_unittest.cc
@@ -16,6 +16,8 @@
 
 #include "perfetto/ext/base/type_set.h"
 
+#include <cstdint>
+#include <optional>
 #include <string>
 #include <type_traits>
 #include <utility>
@@ -66,6 +68,17 @@
   EXPECT_EQ(c_first.index(), 2u);
 }
 
+TEST(TypeSet, FromIndex) {
+  using ABC = TypeSet<A, B, C>;
+  for (ABC set : {ABC(A{}), ABC(B{}), ABC(C{})}) {
+    std::optional<ABC> read = ABC::FromIndex(set.index());
+    ASSERT_TRUE(read.has_value());
+    EXPECT_EQ(*read, set);
+  }
+  EXPECT_FALSE(ABC::FromIndex(3).has_value());
+  EXPECT_FALSE(ABC::FromIndex(static_cast<uint32_t>(-1)).has_value());
+}
+
 TEST(TypeSet, MapByIndex) {
   // Maps to the type at the same position, not the same type.
   using ABC = TypeSet<A, B, C>;
diff --git a/src/base/unix_socket.cc b/src/base/unix_socket.cc
index a8920b2..e4926cd 100644
--- a/src/base/unix_socket.cc
+++ b/src/base/unix_socket.cc
@@ -25,7 +25,6 @@
 #include "perfetto/base/compiler.h"
 #include "perfetto/ext/base/android_utils.h"
 #include "perfetto/ext/base/file_utils.h"
-#include "perfetto/ext/base/flags.h"
 #include "perfetto/ext/base/string_utils.h"
 
 #if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
@@ -1339,7 +1338,9 @@
     TaskRunner* task_runner,
     const char* sock_name,
     std::function<void()> callback) {
-  if constexpr (!PERFETTO_FLAGS(USE_UNIX_SOCKET_INOTIFY))
+  // Disabled where inotify is unavailable or forbidden (e.g. chromium's
+  // sandbox, see gn/perfetto.gni).
+  if constexpr (!PERFETTO_BUILDFLAG(PERFETTO_ENABLE_SOCK_INOTIFY))
     return nullptr;
 
   if (!sock_name || base::GetSockFamily(sock_name) != base::SockFamily::kUnix ||
diff --git a/src/kernel_utils/syscall_table.cc b/src/kernel_utils/syscall_table.cc
index 40bb835..e78e471 100644
--- a/src/kernel_utils/syscall_table.cc
+++ b/src/kernel_utils/syscall_table.cc
@@ -40,6 +40,9 @@
     case Architecture::kX86:
       *this = SyscallTable::Load<SyscallTable_x86>();
       break;
+    case Architecture::kS390x:
+      *this = SyscallTable::Load<SyscallTable_s390x>();
+      break;
     case Architecture::kUnknown:
       // The default field initializers take care of the null initialization.
       break;
@@ -56,6 +59,8 @@
     return Architecture::kX86_64;
   } else if (machine == "i686") {
     return Architecture::kX86;
+  } else if (machine == "s390x") {
+    return Architecture::kS390x;
   } else {
     return Architecture::kUnknown;
   }
diff --git a/src/kernel_utils/syscall_table.h b/src/kernel_utils/syscall_table.h
index a80bc7b..cb75376 100644
--- a/src/kernel_utils/syscall_table.h
+++ b/src/kernel_utils/syscall_table.h
@@ -33,6 +33,7 @@
   kArm32,
   kX86_64,
   kX86,
+  kS390x,
 };
 
 class SyscallTable {
diff --git a/src/kernel_utils/syscall_table_generated.h b/src/kernel_utils/syscall_table_generated.h
index 8bb1956..0c1d463 100644
--- a/src/kernel_utils/syscall_table_generated.h
+++ b/src/kernel_utils/syscall_table_generated.h
@@ -340,6 +340,11 @@
     "sys_rt_sigtimedwait\0"
     "sys_rt_sigtimedwait_time64\0"
     "sys_rt_tgsigqueueinfo\0"
+    "sys_s390_guarded_storage\0"
+    "sys_s390_pci_mmio_read\0"
+    "sys_s390_pci_mmio_write\0"
+    "sys_s390_runtime_instr\0"
+    "sys_s390_sthyi\0"
     "sys_sched_get_priority_max\0"
     "sys_sched_get_priority_min\0"
     "sys_sched_getaffinity\0"
@@ -451,6 +456,7 @@
     "sys_timer_gettime64\0"
     "sys_timer_settime\0"
     "sys_timer_settime64\0"
+    "sys_timerfd\0"
     "sys_timerfd_create\0"
     "sys_timerfd_gettime\0"
     "sys_timerfd_gettime64\0"
@@ -499,7 +505,7 @@
       2293,  // 2: sys_io_submit
       2191,  // 3: sys_io_cancel
       2220,  // 4: sys_io_getevents
-      5719,  // 5: sys_setxattr
+      5829,  // 5: sys_setxattr
       2770,  // 6: sys_lsetxattr
       1251,  // 7: sys_fsetxattr
       2051,  // 8: sys_getxattr
@@ -529,17 +535,17 @@
       1202,  // 32: sys_flock
       3025,  // 33: sys_mknodat
       3003,  // 34: sys_mkdirat
-      6631,  // 35: sys_unlinkat
-      6130,  // 36: sys_symlinkat
+      6753,  // 35: sys_unlinkat
+      6240,  // 36: sys_symlinkat
       2623,  // 37: sys_linkat
       4468,  // 38: sys_renameat
-      6598,  // 39: sys_umount2
+      6720,  // 39: sys_umount2
       3105,  // 40: sys_mount
       3850,  // 41: sys_pivot_root
       3494,  // 42: sys_nfsservctl
-      6028,  // 43: sys_statfs
+      6138,  // 43: sys_statfs
       1335,  // 44: sys_fstatfs
-      6511,  // 45: sys_truncate
+      6633,  // 45: sys_truncate
       1381,  // 46: sys_ftruncate
       950,   // 47: sys_fallocate
       890,   // 48: sys_faccessat
@@ -552,81 +558,81 @@
       1049,  // 55: sys_fchown
       3649,  // 56: sys_openat
       553,   // 57: sys_close
-      6784,  // 58: sys_vhangup
+      6906,  // 58: sys_vhangup
       3840,  // 59: sys_pipe2
       4222,  // 60: sys_quotactl
       1629,  // 61: sys_getdents64
       2760,  // 62: sys_lseek
       4251,  // 63: sys_read
-      6875,  // 64: sys_write
+      6997,  // 64: sys_write
       4314,  // 65: sys_readv
-      6885,  // 66: sys_writev
+      7007,  // 66: sys_writev
       3958,  // 67: sys_pread64
       4167,  // 68: sys_pwrite64
       3970,  // 69: sys_preadv
       4180,  // 70: sys_pwritev
-      5156,  // 71: sys_sendfile
+      5266,  // 71: sys_sendfile
       4111,  // 72: sys_pselect6
       3921,  // 73: sys_ppoll
-      5869,  // 74: sys_signalfd4
-      6817,  // 75: sys_vmsplice
-      5984,  // 76: sys_splice
-      6229,  // 77: sys_tee
+      5979,  // 74: sys_signalfd4
+      6939,  // 75: sys_vmsplice
+      6094,  // 76: sys_splice
+      6339,  // 77: sys_tee
       4299,  // 78: sys_readlinkat
       3479,  // 79: sys_newfstatat
       1299,  // 80: sys_fstat
-      6144,  // 81: sys_sync
+      6254,  // 81: sys_sync
       1361,  // 82: sys_fsync
       1108,  // 83: sys_fdatasync
-      6153,  // 84: sys_sync_file_range
-      6388,  // 85: sys_timerfd_create
-      6449,  // 86: sys_timerfd_settime
-      6407,  // 87: sys_timerfd_gettime
-      6728,  // 88: sys_utimensat
+      6263,  // 84: sys_sync_file_range
+      6510,  // 85: sys_timerfd_create
+      6571,  // 86: sys_timerfd_settime
+      6529,  // 87: sys_timerfd_gettime
+      6850,  // 88: sys_utimensat
       74,    // 89: sys_acct
       255,   // 90: sys_capget
       266,   // 91: sys_capset
       3762,  // 92: sys_personality
       866,   // 93: sys_exit
       875,   // 94: sys_exit_group
-      6852,  // 95: sys_waitid
-      5306,  // 96: sys_set_tid_address
-      6644,  // 97: sys_unshare
+      6974,  // 95: sys_waitid
+      5416,  // 96: sys_set_tid_address
+      6766,  // 97: sys_unshare
       1411,  // 98: sys_futex
-      5266,  // 99: sys_set_robust_list
+      5376,  // 99: sys_set_robust_list
       1554,  // 100: sys_get_robust_list
       3465,  // 101: sys_nanosleep
       1750,  // 102: sys_getitimer
-      5470,  // 103: sys_setitimer
+      5580,  // 103: sys_setitimer
       2464,  // 104: sys_kexec_load
       2097,  // 105: sys_init_module
       639,   // 106: sys_delete_module
-      6257,  // 107: sys_timer_create
-      6312,  // 108: sys_timer_gettime
-      6291,  // 109: sys_timer_getoverrun
-      6350,  // 110: sys_timer_settime
-      6274,  // 111: sys_timer_delete
+      6367,  // 107: sys_timer_create
+      6422,  // 108: sys_timer_gettime
+      6401,  // 109: sys_timer_getoverrun
+      6460,  // 110: sys_timer_settime
+      6384,  // 111: sys_timer_delete
       494,   // 112: sys_clock_settime
       409,   // 113: sys_clock_gettime
       368,   // 114: sys_clock_getres
       447,   // 115: sys_clock_nanosleep
-      6218,  // 116: sys_syslog
+      6328,  // 116: sys_syslog
       4144,  // 117: sys_ptrace
-      4984,  // 118: sys_sched_setparam
-      5003,  // 119: sys_sched_setscheduler
-      4862,  // 120: sys_sched_getscheduler
-      4843,  // 121: sys_sched_getparam
-      4944,  // 122: sys_sched_setaffinity
-      4803,  // 123: sys_sched_getaffinity
-      5026,  // 124: sys_sched_yield
-      4749,  // 125: sys_sched_get_priority_max
-      4776,  // 126: sys_sched_get_priority_min
-      4885,  // 127: sys_sched_rr_get_interval
+      5094,  // 118: sys_sched_setparam
+      5113,  // 119: sys_sched_setscheduler
+      4972,  // 120: sys_sched_getscheduler
+      4953,  // 121: sys_sched_getparam
+      5054,  // 122: sys_sched_setaffinity
+      4913,  // 123: sys_sched_getaffinity
+      5136,  // 124: sys_sched_yield
+      4859,  // 125: sys_sched_get_priority_max
+      4886,  // 126: sys_sched_get_priority_min
+      4995,  // 127: sys_sched_rr_get_interval
       4511,  // 128: sys_restart_syscall
       2490,  // 129: sys_kill
-      6501,  // 130: sys_tkill
-      6237,  // 131: sys_tgkill
-      5829,  // 132: sys_sigaltstack
+      6623,  // 130: sys_tkill
+      6347,  // 131: sys_tgkill
+      5939,  // 132: sys_sigaltstack
       4662,  // 133: sys_rt_sigsuspend
       4571,  // 134: sys_rt_sigaction
       4606,  // 135: sys_rt_sigprocmask
@@ -634,37 +640,37 @@
       4680,  // 137: sys_rt_sigtimedwait
       4625,  // 138: sys_rt_sigqueueinfo
       4645,  // 139: sys_rt_sigreturn
-      5506,  // 140: sys_setpriority
+      5616,  // 140: sys_setpriority
       1839,  // 141: sys_getpriority
       4324,  // 142: sys_reboot
-      5522,  // 143: sys_setregid
-      5400,  // 144: sys_setgid
-      5610,  // 145: sys_setreuid
-      5695,  // 146: sys_setuid
-      5580,  // 147: sys_setresuid
+      5632,  // 143: sys_setregid
+      5510,  // 144: sys_setgid
+      5720,  // 145: sys_setreuid
+      5805,  // 146: sys_setuid
+      5690,  // 147: sys_setresuid
       1899,  // 148: sys_getresuid
-      5550,  // 149: sys_setresgid
+      5660,  // 149: sys_setresgid
       1869,  // 150: sys_getresgid
-      5372,  // 151: sys_setfsuid
-      5344,  // 152: sys_setfsgid
-      6491,  // 153: sys_times
-      5494,  // 154: sys_setpgid
+      5482,  // 151: sys_setfsuid
+      5454,  // 152: sys_setfsgid
+      6613,  // 153: sys_times
+      5604,  // 154: sys_setpgid
       1780,  // 155: sys_getpgid
       1957,  // 156: sys_getsid
-      5652,  // 157: sys_setsid
+      5762,  // 157: sys_setsid
       1720,  // 158: sys_getgroups
-      5424,  // 159: sys_setgroups
-      6610,  // 160: sys_uname
-      5454,  // 161: sys_sethostname
-      5326,  // 162: sys_setdomainname
+      5534,  // 159: sys_setgroups
+      6732,  // 160: sys_uname
+      5564,  // 161: sys_sethostname
+      5436,  // 162: sys_setdomainname
       1929,  // 163: sys_getrlimit
-      5638,  // 164: sys_setrlimit
+      5748,  // 164: sys_setrlimit
       1943,  // 165: sys_getrusage
-      6577,  // 166: sys_umask
+      6699,  // 166: sys_umask
       3948,  // 167: sys_prctl
       1594,  // 168: sys_getcpu
       2010,  // 169: sys_gettimeofday
-      5678,  // 170: sys_settimeofday
+      5788,  // 170: sys_settimeofday
       95,    // 171: sys_adjtimex
       1804,  // 172: sys_getpid
       1827,  // 173: sys_getppid
@@ -673,7 +679,7 @@
       1696,  // 176: sys_getgid
       1644,  // 177: sys_getegid
       1999,  // 178: sys_gettid
-      6206,  // 179: sys_sysinfo
+      6316,  // 179: sys_sysinfo
       3216,  // 180: sys_mq_open
       3316,  // 181: sys_mq_unlink
       3275,  // 182: sys_mq_timedsend
@@ -684,28 +690,28 @@
       3351,  // 187: sys_msgctl
       3373,  // 188: sys_msgrcv
       3384,  // 189: sys_msgsnd
-      5089,  // 190: sys_semget
-      5078,  // 191: sys_semctl
-      5110,  // 192: sys_semtimedop
-      5100,  // 193: sys_semop
-      5791,  // 194: sys_shmget
-      5770,  // 195: sys_shmctl
-      5760,  // 196: sys_shmat
-      5781,  // 197: sys_shmdt
-      5943,  // 198: sys_socket
-      5969,  // 199: sys_socketpair
+      5199,  // 190: sys_semget
+      5188,  // 191: sys_semctl
+      5220,  // 192: sys_semtimedop
+      5210,  // 193: sys_semop
+      5901,  // 194: sys_shmget
+      5880,  // 195: sys_shmctl
+      5870,  // 196: sys_shmat
+      5891,  // 197: sys_shmdt
+      6053,  // 198: sys_socket
+      6079,  // 199: sys_socketpair
       206,   // 200: sys_bind
       2634,  // 201: sys_listen
       40,    // 202: sys_accept
       579,   // 203: sys_connect
       1968,  // 204: sys_getsockname
       1764,  // 205: sys_getpeername
-      5209,  // 206: sys_sendto
+      5319,  // 206: sys_sendto
       4344,  // 207: sys_recvfrom
-      5663,  // 208: sys_setsockopt
+      5773,  // 208: sys_setsockopt
       1984,  // 209: sys_getsockopt
-      5802,  // 210: sys_shutdown
-      5197,  // 211: sys_sendmsg
+      5912,  // 210: sys_shutdown
+      5307,  // 211: sys_sendmsg
       4390,  // 212: sys_recvmsg
       4260,  // 213: sys_readahead
       233,   // 214: sys_brk
@@ -718,8 +724,8 @@
       842,   // 221: sys_execve
       3071,  // 222: sys_mmap
       919,   // 223: sys_fadvise64
-      6107,  // 224: sys_swapon
-      6095,  // 225: sys_swapoff
+      6217,  // 224: sys_swapon
+      6205,  // 225: sys_swapoff
       3163,  // 226: sys_mprotect
       3395,  // 227: sys_msync
       3037,  // 228: sys_mlock
@@ -731,7 +737,7 @@
       4402,  // 234: sys_remap_file_pages
       2904,  // 235: sys_mbind
       1536,  // 236: sys_get_mempolicy
-      5220,  // 237: sys_set_mempolicy
+      5330,  // 237: sys_set_mempolicy
       2963,  // 238: sys_migrate_pages
       3148,  // 239: sys_move_pages
       4727,  // 240: sys_rt_tgsigqueueinfo
@@ -754,29 +760,29 @@
       0,     // 257:
       0,     // 258:
       0,     // 259:
-      6842,  // 260: sys_wait4
+      6964,  // 260: sys_wait4
       3993,  // 261: sys_prlimit64
       964,   // 262: sys_fanotify_init
       982,   // 263: sys_fanotify_mark
       3443,  // 264: sys_name_to_handle_at
       3594,  // 265: sys_open_by_handle_at
       330,   // 266: sys_clock_adjtime
-      6173,  // 267: sys_syncfs
-      5484,  // 268: sys_setns
-      5184,  // 269: sys_sendmmsg
+      6283,  // 267: sys_syncfs
+      5594,  // 268: sys_setns
+      5294,  // 269: sys_sendmmsg
       4048,  // 270: sys_process_vm_readv
       4069,  // 271: sys_process_vm_writev
       2435,  // 272: sys_kcmp
       1170,  // 273: sys_finit_module
-      4966,  // 274: sys_sched_setattr
-      4825,  // 275: sys_sched_getattr
+      5076,  // 274: sys_sched_setattr
+      4935,  // 275: sys_sched_getattr
       4481,  // 276: sys_renameat2
-      5042,  // 277: sys_seccomp
+      5152,  // 277: sys_seccomp
       1855,  // 278: sys_getrandom
       2929,  // 279: sys_memfd_create
       215,   // 280: sys_bpf
       853,   // 281: sys_execveat
-      6692,  // 282: sys_userfaultfd
+      6814,  // 282: sys_userfaultfd
       2914,  // 283: sys_membarrier
       3047,  // 284: sys_mlock2
       591,   // 285: sys_copy_file_range
@@ -785,7 +791,7 @@
       3894,  // 288: sys_pkey_mprotect
       3865,  // 289: sys_pkey_alloc
       3880,  // 290: sys_pkey_free
-      6066,  // 291: sys_statx
+      6176,  // 291: sys_statx
       2237,  // 292: sys_io_pgetevents
       4541,  // 293: sys_rseq
       2444,  // 294: sys_kexec_file_load
@@ -944,20 +950,20 @@
       2946,  // 447: sys_memfd_secret
       4027,  // 448: sys_process_mrelease
       1471,  // 449: sys_futex_waitv
-      5238,  // 450: sys_set_mempolicy_home_node
+      5348,  // 450: sys_set_mempolicy_home_node
       241,   // 451: sys_cachestat
       1035,  // 452: sys_fchmodat2
       2883,  // 453: sys_map_shadow_stack
       1487,  // 454: sys_futex_wake
       1456,  // 455: sys_futex_wait
       1421,  // 456: sys_futex_requeue
-      6052,  // 457: sys_statmount
+      6162,  // 457: sys_statmount
       2645,  // 458: sys_listmount
       2784,  // 459: sys_lsm_get_self_attr
       2827,  // 460: sys_lsm_set_self_attr
       2806,  // 461: sys_lsm_list_modules
       3341,  // 462: sys_mseal
-      5732,  // 463: sys_setxattrat
+      5842,  // 463: sys_setxattrat
       2064,  // 464: sys_getxattrat
       2684,  // 465: sys_listxattrat
       4439,  // 466: sys_removexattrat
@@ -976,16 +982,16 @@
       866,   // 1: sys_exit
       1212,  // 2: sys_fork
       4251,  // 3: sys_read
-      6875,  // 4: sys_write
+      6997,  // 4: sys_write
       3585,  // 5: sys_open
       553,   // 6: sys_close
       0,     // 7:
       611,   // 8: sys_creat
       2614,  // 9: sys_link
-      6620,  // 10: sys_unlink
+      6742,  // 10: sys_unlink
       842,   // 11: sys_execve
       277,   // 12: sys_chdir
-      6248,  // 13: sys_time
+      6358,  // 13: sys_time
       3015,  // 14: sys_mknod
       287,   // 15: sys_chmod
       2576,  // 16: sys_lchown
@@ -994,111 +1000,111 @@
       2760,  // 19: sys_lseek
       1804,  // 20: sys_getpid
       3105,  // 21: sys_mount
-      6587,  // 22: sys_umount
-      5695,  // 23: sys_setuid
+      6709,  // 22: sys_umount
+      5805,  // 23: sys_setuid
       2027,  // 24: sys_getuid
-      6076,  // 25: sys_stime
+      6186,  // 25: sys_stime
       4144,  // 26: sys_ptrace
       124,   // 27: sys_alarm
       0,     // 28:
       3672,  // 29: sys_pause
-      6718,  // 30: sys_utime
+      6840,  // 30: sys_utime
       0,     // 31:
       0,     // 32:
       63,    // 33: sys_access
       3509,  // 34: sys_nice
       0,     // 35:
-      6144,  // 36: sys_sync
+      6254,  // 36: sys_sync
       2490,  // 37: sys_kill
       4457,  // 38: sys_rename
       2993,  // 39: sys_mkdir
       4531,  // 40: sys_rmdir
       657,   // 41: sys_dup
       3831,  // 42: sys_pipe
-      6491,  // 43: sys_times
+      6613,  // 43: sys_times
       0,     // 44:
       233,   // 45: sys_brk
-      5400,  // 46: sys_setgid
+      5510,  // 46: sys_setgid
       1696,  // 47: sys_getgid
       0,     // 48:
       1670,  // 49: sys_geteuid
       1644,  // 50: sys_getegid
       74,    // 51: sys_acct
-      6598,  // 52: sys_umount2
+      6720,  // 52: sys_umount2
       0,     // 53:
       2367,  // 54: sys_ioctl
       1086,  // 55: sys_fcntl
       0,     // 56:
-      5494,  // 57: sys_setpgid
+      5604,  // 57: sys_setpgid
       0,     // 58:
       0,     // 59:
-      6577,  // 60: sys_umask
+      6699,  // 60: sys_umask
       319,   // 61: sys_chroot
-      6708,  // 62: sys_ustat
+      6830,  // 62: sys_ustat
       665,   // 63: sys_dup2
       1827,  // 64: sys_getppid
       1792,  // 65: sys_getpgrp
-      5652,  // 66: sys_setsid
-      5815,  // 67: sys_sigaction
+      5762,  // 66: sys_setsid
+      5925,  // 67: sys_sigaction
       0,     // 68:
       0,     // 69:
-      5610,  // 70: sys_setreuid
-      5522,  // 71: sys_setregid
-      5928,  // 72: sys_sigsuspend
-      5883,  // 73: sys_sigpending
-      5454,  // 74: sys_sethostname
-      5638,  // 75: sys_setrlimit
+      5720,  // 70: sys_setreuid
+      5632,  // 71: sys_setregid
+      6038,  // 72: sys_sigsuspend
+      5993,  // 73: sys_sigpending
+      5564,  // 74: sys_sethostname
+      5748,  // 75: sys_setrlimit
       1929,  // 76: sys_getrlimit
       1943,  // 77: sys_getrusage
       2010,  // 78: sys_gettimeofday
-      5678,  // 79: sys_settimeofday
+      5788,  // 79: sys_settimeofday
       1720,  // 80: sys_getgroups
-      5424,  // 81: sys_setgroups
-      5067,  // 82: sys_select
-      6118,  // 83: sys_symlink
+      5534,  // 81: sys_setgroups
+      5177,  // 82: sys_select
+      6228,  // 83: sys_symlink
       0,     // 84:
       4286,  // 85: sys_readlink
-      6681,  // 86: sys_uselib
-      6107,  // 87: sys_swapon
+      6803,  // 86: sys_uselib
+      6217,  // 87: sys_swapon
       4324,  // 88: sys_reboot
       4274,  // 89: sys_readdir
       3071,  // 90: sys_mmap
       3432,  // 91: sys_munmap
-      6511,  // 92: sys_truncate
+      6633,  // 92: sys_truncate
       1381,  // 93: sys_ftruncate
       1011,  // 94: sys_fchmod
       1049,  // 95: sys_fchown
       1839,  // 96: sys_getpriority
-      5506,  // 97: sys_setpriority
+      5616,  // 97: sys_setpriority
       0,     // 98:
-      6028,  // 99: sys_statfs
+      6138,  // 99: sys_statfs
       1335,  // 100: sys_fstatfs
       0,     // 101:
-      5954,  // 102: sys_socketcall
-      6218,  // 103: sys_syslog
-      5470,  // 104: sys_setitimer
+      6064,  // 102: sys_socketcall
+      6328,  // 103: sys_syslog
+      5580,  // 104: sys_setitimer
       1750,  // 105: sys_getitimer
-      6008,  // 106: sys_stat
+      6118,  // 106: sys_stat
       2849,  // 107: sys_lstat
       1299,  // 108: sys_fstat
       0,     // 109:
       0,     // 110:
-      6784,  // 111: sys_vhangup
+      6906,  // 111: sys_vhangup
       0,     // 112:
-      6184,  // 113: sys_syscall
-      6842,  // 114: sys_wait4
-      6095,  // 115: sys_swapoff
-      6206,  // 116: sys_sysinfo
+      6294,  // 113: sys_syscall
+      6964,  // 114: sys_wait4
+      6205,  // 115: sys_swapoff
+      6316,  // 116: sys_sysinfo
       2427,  // 117: sys_ipc
       1361,  // 118: sys_fsync
-      5914,  // 119: sys_sigreturn
+      6024,  // 119: sys_sigreturn
       532,   // 120: sys_clone
-      5326,  // 121: sys_setdomainname
-      6610,  // 122: sys_uname
+      5436,  // 121: sys_setdomainname
+      6732,  // 122: sys_uname
       0,     // 123:
       95,    // 124: sys_adjtimex
       3163,  // 125: sys_mprotect
-      5898,  // 126: sys_sigprocmask
+      6008,  // 126: sys_sigprocmask
       0,     // 127:
       2097,  // 128: sys_init_module
       639,   // 129: sys_delete_module
@@ -1107,18 +1113,18 @@
       1780,  // 132: sys_getpgid
       1000,  // 133: sys_fchdir
       194,   // 134: sys_bdflush
-      6196,  // 135: sys_sysfs
+      6306,  // 135: sys_sysfs
       3762,  // 136: sys_personality
       0,     // 137:
-      5372,  // 138: sys_setfsuid
-      5344,  // 139: sys_setfsgid
+      5482,  // 138: sys_setfsuid
+      5454,  // 139: sys_setfsgid
       1,     // 140: sys__llseek
       1616,  // 141: sys_getdents
       13,    // 142: sys__newselect
       1202,  // 143: sys_flock
       3395,  // 144: sys_msync
       4314,  // 145: sys_readv
-      6885,  // 146: sys_writev
+      7007,  // 146: sys_writev
       1957,  // 147: sys_getsid
       1108,  // 148: sys_fdatasync
       28,    // 149: sys__sysctl
@@ -1126,23 +1132,23 @@
       3405,  // 151: sys_munlock
       3058,  // 152: sys_mlockall
       3417,  // 153: sys_munlockall
-      4984,  // 154: sys_sched_setparam
-      4843,  // 155: sys_sched_getparam
-      5003,  // 156: sys_sched_setscheduler
-      4862,  // 157: sys_sched_getscheduler
-      5026,  // 158: sys_sched_yield
-      4749,  // 159: sys_sched_get_priority_max
-      4776,  // 160: sys_sched_get_priority_min
-      4885,  // 161: sys_sched_rr_get_interval
+      5094,  // 154: sys_sched_setparam
+      4953,  // 155: sys_sched_getparam
+      5113,  // 156: sys_sched_setscheduler
+      4972,  // 157: sys_sched_getscheduler
+      5136,  // 158: sys_sched_yield
+      4859,  // 159: sys_sched_get_priority_max
+      4886,  // 160: sys_sched_get_priority_min
+      4995,  // 161: sys_sched_rr_get_interval
       3465,  // 162: sys_nanosleep
       3330,  // 163: sys_mremap
-      5580,  // 164: sys_setresuid
+      5690,  // 164: sys_setresuid
       1899,  // 165: sys_getresuid
       0,     // 166:
       0,     // 167:
       3912,  // 168: sys_poll
       3494,  // 169: sys_nfsservctl
-      5550,  // 170: sys_setresgid
+      5660,  // 170: sys_setresgid
       1869,  // 171: sys_getresgid
       3948,  // 172: sys_prctl
       4645,  // 173: sys_rt_sigreturn
@@ -1158,16 +1164,16 @@
       1605,  // 183: sys_getcwd
       255,   // 184: sys_capget
       266,   // 185: sys_capset
-      5829,  // 186: sys_sigaltstack
-      5156,  // 187: sys_sendfile
+      5939,  // 186: sys_sigaltstack
+      5266,  // 187: sys_sendfile
       0,     // 188:
       0,     // 189:
-      6774,  // 190: sys_vfork
-      6551,  // 191: sys_ugetrlimit
+      6896,  // 190: sys_vfork
+      6673,  // 191: sys_ugetrlimit
       3080,  // 192: sys_mmap2
-      6524,  // 193: sys_truncate64
+      6646,  // 193: sys_truncate64
       1395,  // 194: sys_ftruncate64
-      6017,  // 195: sys_stat64
+      6127,  // 195: sys_stat64
       2859,  // 196: sys_lstat64
       1309,  // 197: sys_fstat64
       2587,  // 198: sys_lchown32
@@ -1175,20 +1181,20 @@
       1707,  // 200: sys_getgid32
       1682,  // 201: sys_geteuid32
       1656,  // 202: sys_getegid32
-      5623,  // 203: sys_setreuid32
-      5535,  // 204: sys_setregid32
+      5733,  // 203: sys_setreuid32
+      5645,  // 204: sys_setregid32
       1734,  // 205: sys_getgroups32
-      5438,  // 206: sys_setgroups32
+      5548,  // 206: sys_setgroups32
       1060,  // 207: sys_fchown32
-      5594,  // 208: sys_setresuid32
+      5704,  // 208: sys_setresuid32
       1913,  // 209: sys_getresuid32
-      5564,  // 210: sys_setresgid32
+      5674,  // 210: sys_setresgid32
       1883,  // 211: sys_getresgid32
       307,   // 212: sys_chown32
-      5706,  // 213: sys_setuid32
-      5411,  // 214: sys_setgid32
-      5385,  // 215: sys_setfsuid32
-      5357,  // 216: sys_setfsgid32
+      5816,  // 213: sys_setuid32
+      5521,  // 214: sys_setgid32
+      5495,  // 215: sys_setfsuid32
+      5467,  // 216: sys_setfsgid32
       1629,  // 217: sys_getdents64
       3850,  // 218: sys_pivot_root
       2981,  // 219: sys_mincore
@@ -1198,7 +1204,7 @@
       0,     // 223:
       1999,  // 224: sys_gettid
       4260,  // 225: sys_readahead
-      5719,  // 226: sys_setxattr
+      5829,  // 226: sys_setxattr
       2770,  // 227: sys_lsetxattr
       1251,  // 228: sys_fsetxattr
       2051,  // 229: sys_getxattr
@@ -1210,11 +1216,11 @@
       4423,  // 235: sys_removexattr
       2743,  // 236: sys_lremovexattr
       1221,  // 237: sys_fremovexattr
-      6501,  // 238: sys_tkill
-      5169,  // 239: sys_sendfile64
+      6623,  // 238: sys_tkill
+      5279,  // 239: sys_sendfile64
       1411,  // 240: sys_futex
-      4944,  // 241: sys_sched_setaffinity
-      4803,  // 242: sys_sched_getaffinity
+      5054,  // 241: sys_sched_setaffinity
+      4913,  // 242: sys_sched_getaffinity
       2280,  // 243: sys_io_setup
       2205,  // 244: sys_io_destroy
       2220,  // 245: sys_io_getevents
@@ -1228,20 +1234,20 @@
       4402,  // 253: sys_remap_file_pages
       0,     // 254:
       0,     // 255:
-      5306,  // 256: sys_set_tid_address
-      6257,  // 257: sys_timer_create
-      6350,  // 258: sys_timer_settime
-      6312,  // 259: sys_timer_gettime
-      6291,  // 260: sys_timer_getoverrun
-      6274,  // 261: sys_timer_delete
+      5416,  // 256: sys_set_tid_address
+      6367,  // 257: sys_timer_create
+      6460,  // 258: sys_timer_settime
+      6422,  // 259: sys_timer_gettime
+      6401,  // 260: sys_timer_getoverrun
+      6384,  // 261: sys_timer_delete
       494,   // 262: sys_clock_settime
       409,   // 263: sys_clock_gettime
       368,   // 264: sys_clock_getres
       447,   // 265: sys_clock_nanosleep
-      6039,  // 266: sys_statfs64
+      6149,  // 266: sys_statfs64
       1347,  // 267: sys_fstatfs64
-      6237,  // 268: sys_tgkill
-      6763,  // 269: sys_utimes
+      6347,  // 268: sys_tgkill
+      6885,  // 269: sys_utimes
       149,   // 270: sys_arm_fadvise64_64
       3682,  // 271: sys_pciconfig_iobase
       3703,  // 272: sys_pciconfig_read
@@ -1252,40 +1258,40 @@
       3228,  // 277: sys_mq_timedreceive
       3202,  // 278: sys_mq_notify
       3184,  // 279: sys_mq_getsetattr
-      6852,  // 280: sys_waitid
-      5943,  // 281: sys_socket
+      6974,  // 280: sys_waitid
+      6053,  // 281: sys_socket
       206,   // 282: sys_bind
       579,   // 283: sys_connect
       2634,  // 284: sys_listen
       40,    // 285: sys_accept
       1968,  // 286: sys_getsockname
       1764,  // 287: sys_getpeername
-      5969,  // 288: sys_socketpair
-      5147,  // 289: sys_send
-      5209,  // 290: sys_sendto
+      6079,  // 288: sys_socketpair
+      5257,  // 289: sys_send
+      5319,  // 290: sys_sendto
       4335,  // 291: sys_recv
       4344,  // 292: sys_recvfrom
-      5802,  // 293: sys_shutdown
-      5663,  // 294: sys_setsockopt
+      5912,  // 293: sys_shutdown
+      5773,  // 294: sys_setsockopt
       1984,  // 295: sys_getsockopt
-      5197,  // 296: sys_sendmsg
+      5307,  // 296: sys_sendmsg
       4390,  // 297: sys_recvmsg
-      5100,  // 298: sys_semop
-      5089,  // 299: sys_semget
-      5078,  // 300: sys_semctl
+      5210,  // 298: sys_semop
+      5199,  // 299: sys_semget
+      5188,  // 300: sys_semctl
       3384,  // 301: sys_msgsnd
       3373,  // 302: sys_msgrcv
       3362,  // 303: sys_msgget
       3351,  // 304: sys_msgctl
-      5760,  // 305: sys_shmat
-      5781,  // 306: sys_shmdt
-      5791,  // 307: sys_shmget
-      5770,  // 308: sys_shmctl
+      5870,  // 305: sys_shmat
+      5891,  // 306: sys_shmdt
+      5901,  // 307: sys_shmget
+      5880,  // 308: sys_shmctl
       83,    // 309: sys_add_key
       4495,  // 310: sys_request_key
       2479,  // 311: sys_keyctl
-      5110,  // 312: sys_semtimedop
-      6830,  // 313: sys_vserver
+      5220,  // 312: sys_semtimedop
+      6952,  // 313: sys_vserver
       2412,  // 314: sys_ioprio_set
       2397,  // 315: sys_ioprio_get
       2135,  // 316: sys_inotify_init
@@ -1293,41 +1299,41 @@
       2170,  // 318: sys_inotify_rm_watch
       2904,  // 319: sys_mbind
       1536,  // 320: sys_get_mempolicy
-      5220,  // 321: sys_set_mempolicy
+      5330,  // 321: sys_set_mempolicy
       3649,  // 322: sys_openat
       3003,  // 323: sys_mkdirat
       3025,  // 324: sys_mknodat
       1073,  // 325: sys_fchownat
       1502,  // 326: sys_futimesat
       1321,  // 327: sys_fstatat64
-      6631,  // 328: sys_unlinkat
+      6753,  // 328: sys_unlinkat
       4468,  // 329: sys_renameat
       2623,  // 330: sys_linkat
-      6130,  // 331: sys_symlinkat
+      6240,  // 331: sys_symlinkat
       4299,  // 332: sys_readlinkat
       1022,  // 333: sys_fchmodat
       890,   // 334: sys_faccessat
       4111,  // 335: sys_pselect6
       3921,  // 336: sys_ppoll
-      6644,  // 337: sys_unshare
-      5266,  // 338: sys_set_robust_list
+      6766,  // 337: sys_unshare
+      5376,  // 338: sys_set_robust_list
       1554,  // 339: sys_get_robust_list
-      5984,  // 340: sys_splice
+      6094,  // 340: sys_splice
       170,   // 341: sys_arm_sync_file_range
-      6229,  // 342: sys_tee
-      6817,  // 343: sys_vmsplice
+      6339,  // 342: sys_tee
+      6939,  // 343: sys_vmsplice
       3148,  // 344: sys_move_pages
       1594,  // 345: sys_getcpu
       750,   // 346: sys_epoll_pwait
       2464,  // 347: sys_kexec_load
-      6728,  // 348: sys_utimensat
-      5856,  // 349: sys_signalfd
-      6388,  // 350: sys_timerfd_create
+      6850,  // 348: sys_utimensat
+      5966,  // 349: sys_signalfd
+      6510,  // 350: sys_timerfd_create
       817,   // 351: sys_eventfd
       950,   // 352: sys_fallocate
-      6449,  // 353: sys_timerfd_settime
-      6407,  // 354: sys_timerfd_gettime
-      5869,  // 355: sys_signalfd4
+      6571,  // 353: sys_timerfd_settime
+      6529,  // 354: sys_timerfd_gettime
+      5979,  // 355: sys_signalfd4
       829,   // 356: sys_eventfd2
       700,   // 357: sys_epoll_create1
       674,   // 358: sys_dup3
@@ -1345,22 +1351,22 @@
       3443,  // 370: sys_name_to_handle_at
       3594,  // 371: sys_open_by_handle_at
       330,   // 372: sys_clock_adjtime
-      6173,  // 373: sys_syncfs
-      5184,  // 374: sys_sendmmsg
-      5484,  // 375: sys_setns
+      6283,  // 373: sys_syncfs
+      5294,  // 374: sys_sendmmsg
+      5594,  // 375: sys_setns
       4048,  // 376: sys_process_vm_readv
       4069,  // 377: sys_process_vm_writev
       2435,  // 378: sys_kcmp
       1170,  // 379: sys_finit_module
-      4966,  // 380: sys_sched_setattr
-      4825,  // 381: sys_sched_getattr
+      5076,  // 380: sys_sched_setattr
+      4935,  // 381: sys_sched_getattr
       4481,  // 382: sys_renameat2
-      5042,  // 383: sys_seccomp
+      5152,  // 383: sys_seccomp
       1855,  // 384: sys_getrandom
       2929,  // 385: sys_memfd_create
       215,   // 386: sys_bpf
       853,   // 387: sys_execveat
-      6692,  // 388: sys_userfaultfd
+      6814,  // 388: sys_userfaultfd
       2914,  // 389: sys_membarrier
       3047,  // 390: sys_mlock2
       591,   // 391: sys_copy_file_range
@@ -1369,7 +1375,7 @@
       3894,  // 394: sys_pkey_mprotect
       3865,  // 395: sys_pkey_alloc
       3880,  // 396: sys_pkey_free
-      6066,  // 397: sys_statx
+      6176,  // 397: sys_statx
       4541,  // 398: sys_rseq
       2237,  // 399: sys_io_pgetevents
       2963,  // 400: sys_migrate_pages
@@ -1380,11 +1386,11 @@
       348,   // 405: sys_clock_adjtime64
       385,   // 406: sys_clock_getres_time64
       467,   // 407: sys_clock_nanosleep_time64
-      6330,  // 408: sys_timer_gettime64
-      6368,  // 409: sys_timer_settime64
-      6427,  // 410: sys_timerfd_gettime64
-      6469,  // 411: sys_timerfd_settime64
-      6742,  // 412: sys_utimensat_time64
+      6440,  // 408: sys_timer_gettime64
+      6478,  // 409: sys_timer_settime64
+      6549,  // 410: sys_timerfd_gettime64
+      6591,  // 411: sys_timerfd_settime64
+      6864,  // 412: sys_utimensat_time64
       4124,  // 413: sys_pselect6_time64
       3931,  // 414: sys_ppoll_time64
       0,     // 415:
@@ -1392,10 +1398,10 @@
       4370,  // 417: sys_recvmmsg_time64
       3292,  // 418: sys_mq_timedsend_time64
       3248,  // 419: sys_mq_timedreceive_time64
-      5125,  // 420: sys_semtimedop_time64
+      5235,  // 420: sys_semtimedop_time64
       4700,  // 421: sys_rt_sigtimedwait_time64
       1439,  // 422: sys_futex_time64
-      4911,  // 423: sys_sched_rr_get_interval_time64
+      5021,  // 423: sys_sched_rr_get_interval_time64
       3809,  // 424: sys_pidfd_send_signal
       2348,  // 425: sys_io_uring_setup
       2307,  // 426: sys_io_uring_enter
@@ -1422,20 +1428,20 @@
       0,     // 447:
       4027,  // 448: sys_process_mrelease
       1471,  // 449: sys_futex_waitv
-      5238,  // 450: sys_set_mempolicy_home_node
+      5348,  // 450: sys_set_mempolicy_home_node
       241,   // 451: sys_cachestat
       1035,  // 452: sys_fchmodat2
       2883,  // 453: sys_map_shadow_stack
       1487,  // 454: sys_futex_wake
       1456,  // 455: sys_futex_wait
       1421,  // 456: sys_futex_requeue
-      6052,  // 457: sys_statmount
+      6162,  // 457: sys_statmount
       2645,  // 458: sys_listmount
       2784,  // 459: sys_lsm_get_self_attr
       2827,  // 460: sys_lsm_set_self_attr
       2806,  // 461: sys_lsm_list_modules
       3341,  // 462: sys_mseal
-      5732,  // 463: sys_setxattrat
+      5842,  // 463: sys_setxattrat
       2064,  // 464: sys_getxattrat
       2684,  // 465: sys_listxattrat
       4439,  // 466: sys_removexattrat
@@ -1454,16 +1460,16 @@
       866,   // 1: sys_exit
       1212,  // 2: sys_fork
       4251,  // 3: sys_read
-      6875,  // 4: sys_write
+      6997,  // 4: sys_write
       3585,  // 5: sys_open
       553,   // 6: sys_close
-      6863,  // 7: sys_waitpid
+      6985,  // 7: sys_waitpid
       611,   // 8: sys_creat
       2614,  // 9: sys_link
-      6620,  // 10: sys_unlink
+      6742,  // 10: sys_unlink
       842,   // 11: sys_execve
       277,   // 12: sys_chdir
-      6248,  // 13: sys_time
+      6358,  // 13: sys_time
       3015,  // 14: sys_mknod
       287,   // 15: sys_chmod
       2576,  // 16: sys_lchown
@@ -1472,111 +1478,111 @@
       2760,  // 19: sys_lseek
       1804,  // 20: sys_getpid
       3105,  // 21: sys_mount
-      6587,  // 22: sys_umount
-      5695,  // 23: sys_setuid
+      6709,  // 22: sys_umount
+      5805,  // 23: sys_setuid
       2027,  // 24: sys_getuid
-      6076,  // 25: sys_stime
+      6186,  // 25: sys_stime
       4144,  // 26: sys_ptrace
       124,   // 27: sys_alarm
       3518,  // 28: sys_oldfstat
       3672,  // 29: sys_pause
-      6718,  // 30: sys_utime
-      6086,  // 31: sys_stty
+      6840,  // 30: sys_utime
+      6196,  // 31: sys_stty
       2079,  // 32: sys_gtty
       63,    // 33: sys_access
       3509,  // 34: sys_nice
       1371,  // 35: sys_ftime
-      6144,  // 36: sys_sync
+      6254,  // 36: sys_sync
       2490,  // 37: sys_kill
       4457,  // 38: sys_rename
       2993,  // 39: sys_mkdir
       4531,  // 40: sys_rmdir
       657,   // 41: sys_dup
       3831,  // 42: sys_pipe
-      6491,  // 43: sys_times
+      6613,  // 43: sys_times
       4091,  // 44: sys_prof
       233,   // 45: sys_brk
-      5400,  // 46: sys_setgid
+      5510,  // 46: sys_setgid
       1696,  // 47: sys_getgid
-      5845,  // 48: sys_signal
+      5955,  // 48: sys_signal
       1670,  // 49: sys_geteuid
       1644,  // 50: sys_getegid
       74,    // 51: sys_acct
-      6598,  // 52: sys_umount2
+      6720,  // 52: sys_umount2
       2715,  // 53: sys_lock
       2367,  // 54: sys_ioctl
       1086,  // 55: sys_fcntl
       3176,  // 56: sys_mpx
-      5494,  // 57: sys_setpgid
-      6566,  // 58: sys_ulimit
+      5604,  // 57: sys_setpgid
+      6688,  // 58: sys_ulimit
       3544,  // 59: sys_oldolduname
-      6577,  // 60: sys_umask
+      6699,  // 60: sys_umask
       319,   // 61: sys_chroot
-      6708,  // 62: sys_ustat
+      6830,  // 62: sys_ustat
       665,   // 63: sys_dup2
       1827,  // 64: sys_getppid
       1792,  // 65: sys_getpgrp
-      5652,  // 66: sys_setsid
-      5815,  // 67: sys_sigaction
-      5747,  // 68: sys_sgetmask
-      5995,  // 69: sys_ssetmask
-      5610,  // 70: sys_setreuid
-      5522,  // 71: sys_setregid
-      5928,  // 72: sys_sigsuspend
-      5883,  // 73: sys_sigpending
-      5454,  // 74: sys_sethostname
-      5638,  // 75: sys_setrlimit
+      5762,  // 66: sys_setsid
+      5925,  // 67: sys_sigaction
+      5857,  // 68: sys_sgetmask
+      6105,  // 69: sys_ssetmask
+      5720,  // 70: sys_setreuid
+      5632,  // 71: sys_setregid
+      6038,  // 72: sys_sigsuspend
+      5993,  // 73: sys_sigpending
+      5564,  // 74: sys_sethostname
+      5748,  // 75: sys_setrlimit
       1929,  // 76: sys_getrlimit
       1943,  // 77: sys_getrusage
       2010,  // 78: sys_gettimeofday
-      5678,  // 79: sys_settimeofday
+      5788,  // 79: sys_settimeofday
       1720,  // 80: sys_getgroups
-      5424,  // 81: sys_setgroups
-      5067,  // 82: sys_select
-      6118,  // 83: sys_symlink
+      5534,  // 81: sys_setgroups
+      5177,  // 82: sys_select
+      6228,  // 83: sys_symlink
       3531,  // 84: sys_oldlstat
       4286,  // 85: sys_readlink
-      6681,  // 86: sys_uselib
-      6107,  // 87: sys_swapon
+      6803,  // 86: sys_uselib
+      6217,  // 87: sys_swapon
       4324,  // 88: sys_reboot
       4274,  // 89: sys_readdir
       3071,  // 90: sys_mmap
       3432,  // 91: sys_munmap
-      6511,  // 92: sys_truncate
+      6633,  // 92: sys_truncate
       1381,  // 93: sys_ftruncate
       1011,  // 94: sys_fchmod
       1049,  // 95: sys_fchown
       1839,  // 96: sys_getpriority
-      5506,  // 97: sys_setpriority
+      5616,  // 97: sys_setpriority
       4100,  // 98: sys_profil
-      6028,  // 99: sys_statfs
+      6138,  // 99: sys_statfs
       1335,  // 100: sys_fstatfs
       2377,  // 101: sys_ioperm
-      5954,  // 102: sys_socketcall
-      6218,  // 103: sys_syslog
-      5470,  // 104: sys_setitimer
+      6064,  // 102: sys_socketcall
+      6328,  // 103: sys_syslog
+      5580,  // 104: sys_setitimer
       1750,  // 105: sys_getitimer
-      6008,  // 106: sys_stat
+      6118,  // 106: sys_stat
       2849,  // 107: sys_lstat
       1299,  // 108: sys_fstat
       3572,  // 109: sys_olduname
       2388,  // 110: sys_iopl
-      6784,  // 111: sys_vhangup
+      6906,  // 111: sys_vhangup
       2088,  // 112: sys_idle
-      6805,  // 113: sys_vm86old
-      6842,  // 114: sys_wait4
-      6095,  // 115: sys_swapoff
-      6206,  // 116: sys_sysinfo
+      6927,  // 113: sys_vm86old
+      6964,  // 114: sys_wait4
+      6205,  // 115: sys_swapoff
+      6316,  // 116: sys_sysinfo
       2427,  // 117: sys_ipc
       1361,  // 118: sys_fsync
-      5914,  // 119: sys_sigreturn
+      6024,  // 119: sys_sigreturn
       532,   // 120: sys_clone
-      5326,  // 121: sys_setdomainname
-      6610,  // 122: sys_uname
+      5436,  // 121: sys_setdomainname
+      6732,  // 122: sys_uname
       3090,  // 123: sys_modify_ldt
       95,    // 124: sys_adjtimex
       3163,  // 125: sys_mprotect
-      5898,  // 126: sys_sigprocmask
+      6008,  // 126: sys_sigprocmask
       621,   // 127: sys_create_module
       2097,  // 128: sys_init_module
       639,   // 129: sys_delete_module
@@ -1585,18 +1591,18 @@
       1780,  // 132: sys_getpgid
       1000,  // 133: sys_fchdir
       194,   // 134: sys_bdflush
-      6196,  // 135: sys_sysfs
+      6306,  // 135: sys_sysfs
       3762,  // 136: sys_personality
       108,   // 137: sys_afs_syscall
-      5372,  // 138: sys_setfsuid
-      5344,  // 139: sys_setfsgid
+      5482,  // 138: sys_setfsuid
+      5454,  // 139: sys_setfsgid
       1,     // 140: sys__llseek
       1616,  // 141: sys_getdents
       13,    // 142: sys__newselect
       1202,  // 143: sys_flock
       3395,  // 144: sys_msync
       4314,  // 145: sys_readv
-      6885,  // 146: sys_writev
+      7007,  // 146: sys_writev
       1957,  // 147: sys_getsid
       1108,  // 148: sys_fdatasync
       28,    // 149: sys__sysctl
@@ -1604,23 +1610,23 @@
       3405,  // 151: sys_munlock
       3058,  // 152: sys_mlockall
       3417,  // 153: sys_munlockall
-      4984,  // 154: sys_sched_setparam
-      4843,  // 155: sys_sched_getparam
-      5003,  // 156: sys_sched_setscheduler
-      4862,  // 157: sys_sched_getscheduler
-      5026,  // 158: sys_sched_yield
-      4749,  // 159: sys_sched_get_priority_max
-      4776,  // 160: sys_sched_get_priority_min
-      4885,  // 161: sys_sched_rr_get_interval
+      5094,  // 154: sys_sched_setparam
+      4953,  // 155: sys_sched_getparam
+      5113,  // 156: sys_sched_setscheduler
+      4972,  // 157: sys_sched_getscheduler
+      5136,  // 158: sys_sched_yield
+      4859,  // 159: sys_sched_get_priority_max
+      4886,  // 160: sys_sched_get_priority_min
+      4995,  // 161: sys_sched_rr_get_interval
       3465,  // 162: sys_nanosleep
       3330,  // 163: sys_mremap
-      5580,  // 164: sys_setresuid
+      5690,  // 164: sys_setresuid
       1899,  // 165: sys_getresuid
-      6796,  // 166: sys_vm86
+      6918,  // 166: sys_vm86
       4205,  // 167: sys_query_module
       3912,  // 168: sys_poll
       3494,  // 169: sys_nfsservctl
-      5550,  // 170: sys_setresgid
+      5660,  // 170: sys_setresgid
       1869,  // 171: sys_getresgid
       3948,  // 172: sys_prctl
       4645,  // 173: sys_rt_sigreturn
@@ -1636,16 +1642,16 @@
       1605,  // 183: sys_getcwd
       255,   // 184: sys_capget
       266,   // 185: sys_capset
-      5829,  // 186: sys_sigaltstack
-      5156,  // 187: sys_sendfile
+      5939,  // 186: sys_sigaltstack
+      5266,  // 187: sys_sendfile
       1815,  // 188: sys_getpmsg
       4155,  // 189: sys_putpmsg
-      6774,  // 190: sys_vfork
-      6551,  // 191: sys_ugetrlimit
+      6896,  // 190: sys_vfork
+      6673,  // 191: sys_ugetrlimit
       3080,  // 192: sys_mmap2
-      6524,  // 193: sys_truncate64
+      6646,  // 193: sys_truncate64
       1395,  // 194: sys_ftruncate64
-      6017,  // 195: sys_stat64
+      6127,  // 195: sys_stat64
       2859,  // 196: sys_lstat64
       1309,  // 197: sys_fstat64
       2587,  // 198: sys_lchown32
@@ -1653,20 +1659,20 @@
       1707,  // 200: sys_getgid32
       1682,  // 201: sys_geteuid32
       1656,  // 202: sys_getegid32
-      5623,  // 203: sys_setreuid32
-      5535,  // 204: sys_setregid32
+      5733,  // 203: sys_setreuid32
+      5645,  // 204: sys_setregid32
       1734,  // 205: sys_getgroups32
-      5438,  // 206: sys_setgroups32
+      5548,  // 206: sys_setgroups32
       1060,  // 207: sys_fchown32
-      5594,  // 208: sys_setresuid32
+      5704,  // 208: sys_setresuid32
       1913,  // 209: sys_getresuid32
-      5564,  // 210: sys_setresgid32
+      5674,  // 210: sys_setresgid32
       1883,  // 211: sys_getresgid32
       307,   // 212: sys_chown32
-      5706,  // 213: sys_setuid32
-      5411,  // 214: sys_setgid32
-      5385,  // 215: sys_setfsuid32
-      5357,  // 216: sys_setfsgid32
+      5816,  // 213: sys_setuid32
+      5521,  // 214: sys_setgid32
+      5495,  // 215: sys_setfsuid32
+      5467,  // 216: sys_setfsgid32
       3850,  // 217: sys_pivot_root
       2981,  // 218: sys_mincore
       2871,  // 219: sys_madvise
@@ -1676,7 +1682,7 @@
       0,     // 223:
       1999,  // 224: sys_gettid
       4260,  // 225: sys_readahead
-      5719,  // 226: sys_setxattr
+      5829,  // 226: sys_setxattr
       2770,  // 227: sys_lsetxattr
       1251,  // 228: sys_fsetxattr
       2051,  // 229: sys_getxattr
@@ -1688,12 +1694,12 @@
       4423,  // 235: sys_removexattr
       2743,  // 236: sys_lremovexattr
       1221,  // 237: sys_fremovexattr
-      6501,  // 238: sys_tkill
-      5169,  // 239: sys_sendfile64
+      6623,  // 238: sys_tkill
+      5279,  // 239: sys_sendfile64
       1411,  // 240: sys_futex
-      4944,  // 241: sys_sched_setaffinity
-      4803,  // 242: sys_sched_getaffinity
-      5286,  // 243: sys_set_thread_area
+      5054,  // 241: sys_sched_setaffinity
+      4913,  // 242: sys_sched_getaffinity
+      5396,  // 243: sys_set_thread_area
       1574,  // 244: sys_get_thread_area
       2280,  // 245: sys_io_setup
       2205,  // 246: sys_io_destroy
@@ -1708,25 +1714,25 @@
       718,   // 255: sys_epoll_ctl
       783,   // 256: sys_epoll_wait
       4402,  // 257: sys_remap_file_pages
-      5306,  // 258: sys_set_tid_address
-      6257,  // 259: sys_timer_create
-      6350,  // 260: sys_timer_settime
-      6312,  // 261: sys_timer_gettime
-      6291,  // 262: sys_timer_getoverrun
-      6274,  // 263: sys_timer_delete
+      5416,  // 258: sys_set_tid_address
+      6367,  // 259: sys_timer_create
+      6460,  // 260: sys_timer_settime
+      6422,  // 261: sys_timer_gettime
+      6401,  // 262: sys_timer_getoverrun
+      6384,  // 263: sys_timer_delete
       494,   // 264: sys_clock_settime
       409,   // 265: sys_clock_gettime
       368,   // 266: sys_clock_getres
       447,   // 267: sys_clock_nanosleep
-      6039,  // 268: sys_statfs64
+      6149,  // 268: sys_statfs64
       1347,  // 269: sys_fstatfs64
-      6237,  // 270: sys_tgkill
-      6763,  // 271: sys_utimes
+      6347,  // 270: sys_tgkill
+      6885,  // 271: sys_utimes
       933,   // 272: sys_fadvise64_64
-      6830,  // 273: sys_vserver
+      6952,  // 273: sys_vserver
       2904,  // 274: sys_mbind
       1536,  // 275: sys_get_mempolicy
-      5220,  // 276: sys_set_mempolicy
+      5330,  // 276: sys_set_mempolicy
       3216,  // 277: sys_mq_open
       3316,  // 278: sys_mq_unlink
       3275,  // 279: sys_mq_timedsend
@@ -1734,7 +1740,7 @@
       3202,  // 281: sys_mq_notify
       3184,  // 282: sys_mq_getsetattr
       2464,  // 283: sys_kexec_load
-      6852,  // 284: sys_waitid
+      6974,  // 284: sys_waitid
       0,     // 285:
       83,    // 286: sys_add_key
       4495,  // 287: sys_request_key
@@ -1751,33 +1757,33 @@
       1073,  // 298: sys_fchownat
       1502,  // 299: sys_futimesat
       1321,  // 300: sys_fstatat64
-      6631,  // 301: sys_unlinkat
+      6753,  // 301: sys_unlinkat
       4468,  // 302: sys_renameat
       2623,  // 303: sys_linkat
-      6130,  // 304: sys_symlinkat
+      6240,  // 304: sys_symlinkat
       4299,  // 305: sys_readlinkat
       1022,  // 306: sys_fchmodat
       890,   // 307: sys_faccessat
       4111,  // 308: sys_pselect6
       3921,  // 309: sys_ppoll
-      6644,  // 310: sys_unshare
-      5266,  // 311: sys_set_robust_list
+      6766,  // 310: sys_unshare
+      5376,  // 311: sys_set_robust_list
       1554,  // 312: sys_get_robust_list
-      5984,  // 313: sys_splice
-      6153,  // 314: sys_sync_file_range
-      6229,  // 315: sys_tee
-      6817,  // 316: sys_vmsplice
+      6094,  // 313: sys_splice
+      6263,  // 314: sys_sync_file_range
+      6339,  // 315: sys_tee
+      6939,  // 316: sys_vmsplice
       3148,  // 317: sys_move_pages
       1594,  // 318: sys_getcpu
       750,   // 319: sys_epoll_pwait
-      6728,  // 320: sys_utimensat
-      5856,  // 321: sys_signalfd
-      6388,  // 322: sys_timerfd_create
+      6850,  // 320: sys_utimensat
+      5966,  // 321: sys_signalfd
+      6510,  // 322: sys_timerfd_create
       817,   // 323: sys_eventfd
       950,   // 324: sys_fallocate
-      6449,  // 325: sys_timerfd_settime
-      6407,  // 326: sys_timerfd_gettime
-      5869,  // 327: sys_signalfd4
+      6571,  // 325: sys_timerfd_settime
+      6529,  // 326: sys_timerfd_gettime
+      5979,  // 327: sys_signalfd4
       829,   // 328: sys_eventfd2
       700,   // 329: sys_epoll_create1
       674,   // 330: sys_dup3
@@ -1794,37 +1800,37 @@
       3443,  // 341: sys_name_to_handle_at
       3594,  // 342: sys_open_by_handle_at
       330,   // 343: sys_clock_adjtime
-      6173,  // 344: sys_syncfs
-      5184,  // 345: sys_sendmmsg
-      5484,  // 346: sys_setns
+      6283,  // 344: sys_syncfs
+      5294,  // 345: sys_sendmmsg
+      5594,  // 346: sys_setns
       4048,  // 347: sys_process_vm_readv
       4069,  // 348: sys_process_vm_writev
       2435,  // 349: sys_kcmp
       1170,  // 350: sys_finit_module
-      4966,  // 351: sys_sched_setattr
-      4825,  // 352: sys_sched_getattr
+      5076,  // 351: sys_sched_setattr
+      4935,  // 352: sys_sched_getattr
       4481,  // 353: sys_renameat2
-      5042,  // 354: sys_seccomp
+      5152,  // 354: sys_seccomp
       1855,  // 355: sys_getrandom
       2929,  // 356: sys_memfd_create
       215,   // 357: sys_bpf
       853,   // 358: sys_execveat
-      5943,  // 359: sys_socket
-      5969,  // 360: sys_socketpair
+      6053,  // 359: sys_socket
+      6079,  // 360: sys_socketpair
       206,   // 361: sys_bind
       579,   // 362: sys_connect
       2634,  // 363: sys_listen
       51,    // 364: sys_accept4
       1984,  // 365: sys_getsockopt
-      5663,  // 366: sys_setsockopt
+      5773,  // 366: sys_setsockopt
       1968,  // 367: sys_getsockname
       1764,  // 368: sys_getpeername
-      5209,  // 369: sys_sendto
-      5197,  // 370: sys_sendmsg
+      5319,  // 369: sys_sendto
+      5307,  // 370: sys_sendmsg
       4344,  // 371: sys_recvfrom
       4390,  // 372: sys_recvmsg
-      5802,  // 373: sys_shutdown
-      6692,  // 374: sys_userfaultfd
+      5912,  // 373: sys_shutdown
+      6814,  // 374: sys_userfaultfd
       2914,  // 375: sys_membarrier
       3047,  // 376: sys_mlock2
       591,   // 377: sys_copy_file_range
@@ -1833,7 +1839,7 @@
       3894,  // 380: sys_pkey_mprotect
       3865,  // 381: sys_pkey_alloc
       3880,  // 382: sys_pkey_free
-      6066,  // 383: sys_statx
+      6176,  // 383: sys_statx
       134,   // 384: sys_arch_prctl
       2237,  // 385: sys_io_pgetevents
       4541,  // 386: sys_rseq
@@ -1843,12 +1849,12 @@
       0,     // 390:
       0,     // 391:
       0,     // 392:
-      5089,  // 393: sys_semget
-      5078,  // 394: sys_semctl
-      5791,  // 395: sys_shmget
-      5770,  // 396: sys_shmctl
-      5760,  // 397: sys_shmat
-      5781,  // 398: sys_shmdt
+      5199,  // 393: sys_semget
+      5188,  // 394: sys_semctl
+      5901,  // 395: sys_shmget
+      5880,  // 396: sys_shmctl
+      5870,  // 397: sys_shmat
+      5891,  // 398: sys_shmdt
       3362,  // 399: sys_msgget
       3384,  // 400: sys_msgsnd
       3373,  // 401: sys_msgrcv
@@ -1858,11 +1864,11 @@
       348,   // 405: sys_clock_adjtime64
       385,   // 406: sys_clock_getres_time64
       467,   // 407: sys_clock_nanosleep_time64
-      6330,  // 408: sys_timer_gettime64
-      6368,  // 409: sys_timer_settime64
-      6427,  // 410: sys_timerfd_gettime64
-      6469,  // 411: sys_timerfd_settime64
-      6742,  // 412: sys_utimensat_time64
+      6440,  // 408: sys_timer_gettime64
+      6478,  // 409: sys_timer_settime64
+      6549,  // 410: sys_timerfd_gettime64
+      6591,  // 411: sys_timerfd_settime64
+      6864,  // 412: sys_utimensat_time64
       4124,  // 413: sys_pselect6_time64
       3931,  // 414: sys_ppoll_time64
       0,     // 415:
@@ -1870,10 +1876,10 @@
       4370,  // 417: sys_recvmmsg_time64
       3292,  // 418: sys_mq_timedsend_time64
       3248,  // 419: sys_mq_timedreceive_time64
-      5125,  // 420: sys_semtimedop_time64
+      5235,  // 420: sys_semtimedop_time64
       4700,  // 421: sys_rt_sigtimedwait_time64
       1439,  // 422: sys_futex_time64
-      4911,  // 423: sys_sched_rr_get_interval_time64
+      5021,  // 423: sys_sched_rr_get_interval_time64
       3809,  // 424: sys_pidfd_send_signal
       2348,  // 425: sys_io_uring_setup
       2307,  // 426: sys_io_uring_enter
@@ -1900,20 +1906,20 @@
       2946,  // 447: sys_memfd_secret
       4027,  // 448: sys_process_mrelease
       1471,  // 449: sys_futex_waitv
-      5238,  // 450: sys_set_mempolicy_home_node
+      5348,  // 450: sys_set_mempolicy_home_node
       241,   // 451: sys_cachestat
       1035,  // 452: sys_fchmodat2
       2883,  // 453: sys_map_shadow_stack
       1487,  // 454: sys_futex_wake
       1456,  // 455: sys_futex_wait
       1421,  // 456: sys_futex_requeue
-      6052,  // 457: sys_statmount
+      6162,  // 457: sys_statmount
       2645,  // 458: sys_listmount
       2784,  // 459: sys_lsm_get_self_attr
       2827,  // 460: sys_lsm_set_self_attr
       2806,  // 461: sys_lsm_list_modules
       3341,  // 462: sys_mseal
-      5732,  // 463: sys_setxattrat
+      5842,  // 463: sys_setxattrat
       2064,  // 464: sys_getxattrat
       2684,  // 465: sys_listxattrat
       4439,  // 466: sys_removexattrat
@@ -1929,10 +1935,10 @@
   static constexpr const char* names = kAllSyscalllNames;
   static constexpr SyscallTable::OffT offsets[]{
       4251,  // 0: sys_read
-      6875,  // 1: sys_write
+      6997,  // 1: sys_write
       3585,  // 2: sys_open
       553,   // 3: sys_close
-      6008,  // 4: sys_stat
+      6118,  // 4: sys_stat
       1299,  // 5: sys_fstat
       2849,  // 6: sys_lstat
       3912,  // 7: sys_poll
@@ -1948,54 +1954,54 @@
       3958,  // 17: sys_pread64
       4167,  // 18: sys_pwrite64
       4314,  // 19: sys_readv
-      6885,  // 20: sys_writev
+      7007,  // 20: sys_writev
       63,    // 21: sys_access
       3831,  // 22: sys_pipe
-      5067,  // 23: sys_select
-      5026,  // 24: sys_sched_yield
+      5177,  // 23: sys_select
+      5136,  // 24: sys_sched_yield
       3330,  // 25: sys_mremap
       3395,  // 26: sys_msync
       2981,  // 27: sys_mincore
       2871,  // 28: sys_madvise
-      5791,  // 29: sys_shmget
-      5760,  // 30: sys_shmat
-      5770,  // 31: sys_shmctl
+      5901,  // 29: sys_shmget
+      5870,  // 30: sys_shmat
+      5880,  // 31: sys_shmctl
       657,   // 32: sys_dup
       665,   // 33: sys_dup2
       3672,  // 34: sys_pause
       3465,  // 35: sys_nanosleep
       1750,  // 36: sys_getitimer
       124,   // 37: sys_alarm
-      5470,  // 38: sys_setitimer
+      5580,  // 38: sys_setitimer
       1804,  // 39: sys_getpid
-      5156,  // 40: sys_sendfile
-      5943,  // 41: sys_socket
+      5266,  // 40: sys_sendfile
+      6053,  // 41: sys_socket
       579,   // 42: sys_connect
       40,    // 43: sys_accept
-      5209,  // 44: sys_sendto
+      5319,  // 44: sys_sendto
       4344,  // 45: sys_recvfrom
-      5197,  // 46: sys_sendmsg
+      5307,  // 46: sys_sendmsg
       4390,  // 47: sys_recvmsg
-      5802,  // 48: sys_shutdown
+      5912,  // 48: sys_shutdown
       206,   // 49: sys_bind
       2634,  // 50: sys_listen
       1968,  // 51: sys_getsockname
       1764,  // 52: sys_getpeername
-      5969,  // 53: sys_socketpair
-      5663,  // 54: sys_setsockopt
+      6079,  // 53: sys_socketpair
+      5773,  // 54: sys_setsockopt
       1984,  // 55: sys_getsockopt
       532,   // 56: sys_clone
       1212,  // 57: sys_fork
-      6774,  // 58: sys_vfork
+      6896,  // 58: sys_vfork
       842,   // 59: sys_execve
       866,   // 60: sys_exit
-      6842,  // 61: sys_wait4
+      6964,  // 61: sys_wait4
       2490,  // 62: sys_kill
-      6610,  // 63: sys_uname
-      5089,  // 64: sys_semget
-      5100,  // 65: sys_semop
-      5078,  // 66: sys_semctl
-      5781,  // 67: sys_shmdt
+      6732,  // 63: sys_uname
+      5199,  // 64: sys_semget
+      5210,  // 65: sys_semop
+      5188,  // 66: sys_semctl
+      5891,  // 67: sys_shmdt
       3362,  // 68: sys_msgget
       3384,  // 69: sys_msgsnd
       3373,  // 70: sys_msgrcv
@@ -2004,7 +2010,7 @@
       1202,  // 73: sys_flock
       1361,  // 74: sys_fsync
       1108,  // 75: sys_fdatasync
-      6511,  // 76: sys_truncate
+      6633,  // 76: sys_truncate
       1381,  // 77: sys_ftruncate
       1616,  // 78: sys_getdents
       1605,  // 79: sys_getcwd
@@ -2015,43 +2021,43 @@
       4531,  // 84: sys_rmdir
       611,   // 85: sys_creat
       2614,  // 86: sys_link
-      6620,  // 87: sys_unlink
-      6118,  // 88: sys_symlink
+      6742,  // 87: sys_unlink
+      6228,  // 88: sys_symlink
       4286,  // 89: sys_readlink
       287,   // 90: sys_chmod
       1011,  // 91: sys_fchmod
       297,   // 92: sys_chown
       1049,  // 93: sys_fchown
       2576,  // 94: sys_lchown
-      6577,  // 95: sys_umask
+      6699,  // 95: sys_umask
       2010,  // 96: sys_gettimeofday
       1929,  // 97: sys_getrlimit
       1943,  // 98: sys_getrusage
-      6206,  // 99: sys_sysinfo
-      6491,  // 100: sys_times
+      6316,  // 99: sys_sysinfo
+      6613,  // 100: sys_times
       4144,  // 101: sys_ptrace
       2027,  // 102: sys_getuid
-      6218,  // 103: sys_syslog
+      6328,  // 103: sys_syslog
       1696,  // 104: sys_getgid
-      5695,  // 105: sys_setuid
-      5400,  // 106: sys_setgid
+      5805,  // 105: sys_setuid
+      5510,  // 106: sys_setgid
       1670,  // 107: sys_geteuid
       1644,  // 108: sys_getegid
-      5494,  // 109: sys_setpgid
+      5604,  // 109: sys_setpgid
       1827,  // 110: sys_getppid
       1792,  // 111: sys_getpgrp
-      5652,  // 112: sys_setsid
-      5610,  // 113: sys_setreuid
-      5522,  // 114: sys_setregid
+      5762,  // 112: sys_setsid
+      5720,  // 113: sys_setreuid
+      5632,  // 114: sys_setregid
       1720,  // 115: sys_getgroups
-      5424,  // 116: sys_setgroups
-      5580,  // 117: sys_setresuid
+      5534,  // 116: sys_setgroups
+      5690,  // 117: sys_setresuid
       1899,  // 118: sys_getresuid
-      5550,  // 119: sys_setresgid
+      5660,  // 119: sys_setresgid
       1869,  // 120: sys_getresgid
       1780,  // 121: sys_getpgid
-      5372,  // 122: sys_setfsuid
-      5344,  // 123: sys_setfsgid
+      5482,  // 122: sys_setfsuid
+      5454,  // 123: sys_setfsgid
       1957,  // 124: sys_getsid
       255,   // 125: sys_capget
       266,   // 126: sys_capset
@@ -2059,47 +2065,47 @@
       4680,  // 128: sys_rt_sigtimedwait
       4625,  // 129: sys_rt_sigqueueinfo
       4662,  // 130: sys_rt_sigsuspend
-      5829,  // 131: sys_sigaltstack
-      6718,  // 132: sys_utime
+      5939,  // 131: sys_sigaltstack
+      6840,  // 132: sys_utime
       3015,  // 133: sys_mknod
-      6681,  // 134: sys_uselib
+      6803,  // 134: sys_uselib
       3762,  // 135: sys_personality
-      6708,  // 136: sys_ustat
-      6028,  // 137: sys_statfs
+      6830,  // 136: sys_ustat
+      6138,  // 137: sys_statfs
       1335,  // 138: sys_fstatfs
-      6196,  // 139: sys_sysfs
+      6306,  // 139: sys_sysfs
       1839,  // 140: sys_getpriority
-      5506,  // 141: sys_setpriority
-      4984,  // 142: sys_sched_setparam
-      4843,  // 143: sys_sched_getparam
-      5003,  // 144: sys_sched_setscheduler
-      4862,  // 145: sys_sched_getscheduler
-      4749,  // 146: sys_sched_get_priority_max
-      4776,  // 147: sys_sched_get_priority_min
-      4885,  // 148: sys_sched_rr_get_interval
+      5616,  // 141: sys_setpriority
+      5094,  // 142: sys_sched_setparam
+      4953,  // 143: sys_sched_getparam
+      5113,  // 144: sys_sched_setscheduler
+      4972,  // 145: sys_sched_getscheduler
+      4859,  // 146: sys_sched_get_priority_max
+      4886,  // 147: sys_sched_get_priority_min
+      4995,  // 148: sys_sched_rr_get_interval
       3037,  // 149: sys_mlock
       3405,  // 150: sys_munlock
       3058,  // 151: sys_mlockall
       3417,  // 152: sys_munlockall
-      6784,  // 153: sys_vhangup
+      6906,  // 153: sys_vhangup
       3090,  // 154: sys_modify_ldt
       3850,  // 155: sys_pivot_root
       28,    // 156: sys__sysctl
       3948,  // 157: sys_prctl
       134,   // 158: sys_arch_prctl
       95,    // 159: sys_adjtimex
-      5638,  // 160: sys_setrlimit
+      5748,  // 160: sys_setrlimit
       319,   // 161: sys_chroot
-      6144,  // 162: sys_sync
+      6254,  // 162: sys_sync
       74,    // 163: sys_acct
-      5678,  // 164: sys_settimeofday
+      5788,  // 164: sys_settimeofday
       3105,  // 165: sys_mount
-      6598,  // 166: sys_umount2
-      6107,  // 167: sys_swapon
-      6095,  // 168: sys_swapoff
+      6720,  // 166: sys_umount2
+      6217,  // 167: sys_swapon
+      6205,  // 168: sys_swapoff
       4324,  // 169: sys_reboot
-      5454,  // 170: sys_sethostname
-      5326,  // 171: sys_setdomainname
+      5564,  // 170: sys_sethostname
+      5436,  // 171: sys_setdomainname
       2388,  // 172: sys_iopl
       2377,  // 173: sys_ioperm
       621,   // 174: sys_create_module
@@ -2112,11 +2118,11 @@
       1815,  // 181: sys_getpmsg
       4155,  // 182: sys_putpmsg
       108,   // 183: sys_afs_syscall
-      6539,  // 184: sys_tuxcall
-      5054,  // 185: sys_security
+      6661,  // 184: sys_tuxcall
+      5164,  // 185: sys_security
       1999,  // 186: sys_gettid
       4260,  // 187: sys_readahead
-      5719,  // 188: sys_setxattr
+      5829,  // 188: sys_setxattr
       2770,  // 189: sys_lsetxattr
       1251,  // 190: sys_fsetxattr
       2051,  // 191: sys_getxattr
@@ -2128,12 +2134,12 @@
       4423,  // 197: sys_removexattr
       2743,  // 198: sys_lremovexattr
       1221,  // 199: sys_fremovexattr
-      6501,  // 200: sys_tkill
-      6248,  // 201: sys_time
+      6623,  // 200: sys_tkill
+      6358,  // 201: sys_time
       1411,  // 202: sys_futex
-      4944,  // 203: sys_sched_setaffinity
-      4803,  // 204: sys_sched_getaffinity
-      5286,  // 205: sys_set_thread_area
+      5054,  // 203: sys_sched_setaffinity
+      4913,  // 204: sys_sched_getaffinity
+      5396,  // 205: sys_set_thread_area
       2280,  // 206: sys_io_setup
       2205,  // 207: sys_io_destroy
       2220,  // 208: sys_io_getevents
@@ -2146,15 +2152,15 @@
       798,   // 215: sys_epoll_wait_old
       4402,  // 216: sys_remap_file_pages
       1629,  // 217: sys_getdents64
-      5306,  // 218: sys_set_tid_address
+      5416,  // 218: sys_set_tid_address
       4511,  // 219: sys_restart_syscall
-      5110,  // 220: sys_semtimedop
+      5220,  // 220: sys_semtimedop
       919,   // 221: sys_fadvise64
-      6257,  // 222: sys_timer_create
-      6350,  // 223: sys_timer_settime
-      6312,  // 224: sys_timer_gettime
-      6291,  // 225: sys_timer_getoverrun
-      6274,  // 226: sys_timer_delete
+      6367,  // 222: sys_timer_create
+      6460,  // 223: sys_timer_settime
+      6422,  // 224: sys_timer_gettime
+      6401,  // 225: sys_timer_getoverrun
+      6384,  // 226: sys_timer_delete
       494,   // 227: sys_clock_settime
       409,   // 228: sys_clock_gettime
       368,   // 229: sys_clock_getres
@@ -2162,11 +2168,11 @@
       875,   // 231: sys_exit_group
       783,   // 232: sys_epoll_wait
       718,   // 233: sys_epoll_ctl
-      6237,  // 234: sys_tgkill
-      6763,  // 235: sys_utimes
-      6830,  // 236: sys_vserver
+      6347,  // 234: sys_tgkill
+      6885,  // 235: sys_utimes
+      6952,  // 236: sys_vserver
       2904,  // 237: sys_mbind
-      5220,  // 238: sys_set_mempolicy
+      5330,  // 238: sys_set_mempolicy
       1536,  // 239: sys_get_mempolicy
       3216,  // 240: sys_mq_open
       3316,  // 241: sys_mq_unlink
@@ -2175,7 +2181,7 @@
       3202,  // 244: sys_mq_notify
       3184,  // 245: sys_mq_getsetattr
       2464,  // 246: sys_kexec_load
-      6852,  // 247: sys_waitid
+      6974,  // 247: sys_waitid
       83,    // 248: sys_add_key
       4495,  // 249: sys_request_key
       2479,  // 250: sys_keyctl
@@ -2191,33 +2197,33 @@
       1073,  // 260: sys_fchownat
       1502,  // 261: sys_futimesat
       3479,  // 262: sys_newfstatat
-      6631,  // 263: sys_unlinkat
+      6753,  // 263: sys_unlinkat
       4468,  // 264: sys_renameat
       2623,  // 265: sys_linkat
-      6130,  // 266: sys_symlinkat
+      6240,  // 266: sys_symlinkat
       4299,  // 267: sys_readlinkat
       1022,  // 268: sys_fchmodat
       890,   // 269: sys_faccessat
       4111,  // 270: sys_pselect6
       3921,  // 271: sys_ppoll
-      6644,  // 272: sys_unshare
-      5266,  // 273: sys_set_robust_list
+      6766,  // 272: sys_unshare
+      5376,  // 273: sys_set_robust_list
       1554,  // 274: sys_get_robust_list
-      5984,  // 275: sys_splice
-      6229,  // 276: sys_tee
-      6153,  // 277: sys_sync_file_range
-      6817,  // 278: sys_vmsplice
+      6094,  // 275: sys_splice
+      6339,  // 276: sys_tee
+      6263,  // 277: sys_sync_file_range
+      6939,  // 278: sys_vmsplice
       3148,  // 279: sys_move_pages
-      6728,  // 280: sys_utimensat
+      6850,  // 280: sys_utimensat
       750,   // 281: sys_epoll_pwait
-      5856,  // 282: sys_signalfd
-      6388,  // 283: sys_timerfd_create
+      5966,  // 282: sys_signalfd
+      6510,  // 283: sys_timerfd_create
       817,   // 284: sys_eventfd
       950,   // 285: sys_fallocate
-      6449,  // 286: sys_timerfd_settime
-      6407,  // 287: sys_timerfd_gettime
+      6571,  // 286: sys_timerfd_settime
+      6529,  // 287: sys_timerfd_gettime
       51,    // 288: sys_accept4
-      5869,  // 289: sys_signalfd4
+      5979,  // 289: sys_signalfd4
       829,   // 290: sys_eventfd2
       700,   // 291: sys_epoll_create1
       674,   // 292: sys_dup3
@@ -2234,24 +2240,24 @@
       3443,  // 303: sys_name_to_handle_at
       3594,  // 304: sys_open_by_handle_at
       330,   // 305: sys_clock_adjtime
-      6173,  // 306: sys_syncfs
-      5184,  // 307: sys_sendmmsg
-      5484,  // 308: sys_setns
+      6283,  // 306: sys_syncfs
+      5294,  // 307: sys_sendmmsg
+      5594,  // 308: sys_setns
       1594,  // 309: sys_getcpu
       4048,  // 310: sys_process_vm_readv
       4069,  // 311: sys_process_vm_writev
       2435,  // 312: sys_kcmp
       1170,  // 313: sys_finit_module
-      4966,  // 314: sys_sched_setattr
-      4825,  // 315: sys_sched_getattr
+      5076,  // 314: sys_sched_setattr
+      4935,  // 315: sys_sched_getattr
       4481,  // 316: sys_renameat2
-      5042,  // 317: sys_seccomp
+      5152,  // 317: sys_seccomp
       1855,  // 318: sys_getrandom
       2929,  // 319: sys_memfd_create
       2444,  // 320: sys_kexec_file_load
       215,   // 321: sys_bpf
       853,   // 322: sys_execveat
-      6692,  // 323: sys_userfaultfd
+      6814,  // 323: sys_userfaultfd
       2914,  // 324: sys_membarrier
       3047,  // 325: sys_mlock2
       591,   // 326: sys_copy_file_range
@@ -2260,11 +2266,11 @@
       3894,  // 329: sys_pkey_mprotect
       3865,  // 330: sys_pkey_alloc
       3880,  // 331: sys_pkey_free
-      6066,  // 332: sys_statx
+      6176,  // 332: sys_statx
       2237,  // 333: sys_io_pgetevents
       4541,  // 334: sys_rseq
-      6667,  // 335: sys_uretprobe
-      6656,  // 336: sys_uprobe
+      6789,  // 335: sys_uretprobe
+      6778,  // 336: sys_uprobe
       0,     // 337:
       0,     // 338:
       0,     // 339:
@@ -2378,20 +2384,20 @@
       2946,  // 447: sys_memfd_secret
       4027,  // 448: sys_process_mrelease
       1471,  // 449: sys_futex_waitv
-      5238,  // 450: sys_set_mempolicy_home_node
+      5348,  // 450: sys_set_mempolicy_home_node
       241,   // 451: sys_cachestat
       1035,  // 452: sys_fchmodat2
       2883,  // 453: sys_map_shadow_stack
       1487,  // 454: sys_futex_wake
       1456,  // 455: sys_futex_wait
       1421,  // 456: sys_futex_requeue
-      6052,  // 457: sys_statmount
+      6162,  // 457: sys_statmount
       2645,  // 458: sys_listmount
       2784,  // 459: sys_lsm_get_self_attr
       2827,  // 460: sys_lsm_set_self_attr
       2806,  // 461: sys_lsm_list_modules
       3341,  // 462: sys_mseal
-      5732,  // 463: sys_setxattrat
+      5842,  // 463: sys_setxattrat
       2064,  // 464: sys_getxattrat
       2684,  // 465: sys_listxattrat
       4439,  // 466: sys_removexattrat
@@ -2444,32 +2450,32 @@
       4645,  // 513: sys_rt_sigreturn
       2367,  // 514: sys_ioctl
       4314,  // 515: sys_readv
-      6885,  // 516: sys_writev
+      7007,  // 516: sys_writev
       4344,  // 517: sys_recvfrom
-      5197,  // 518: sys_sendmsg
+      5307,  // 518: sys_sendmsg
       4390,  // 519: sys_recvmsg
       842,   // 520: sys_execve
       4144,  // 521: sys_ptrace
       4588,  // 522: sys_rt_sigpending
       4680,  // 523: sys_rt_sigtimedwait
       4625,  // 524: sys_rt_sigqueueinfo
-      5829,  // 525: sys_sigaltstack
-      6257,  // 526: sys_timer_create
+      5939,  // 525: sys_sigaltstack
+      6367,  // 526: sys_timer_create
       3202,  // 527: sys_mq_notify
       2464,  // 528: sys_kexec_load
-      6852,  // 529: sys_waitid
-      5266,  // 530: sys_set_robust_list
+      6974,  // 529: sys_waitid
+      5376,  // 530: sys_set_robust_list
       1554,  // 531: sys_get_robust_list
-      6817,  // 532: sys_vmsplice
+      6939,  // 532: sys_vmsplice
       3148,  // 533: sys_move_pages
       3970,  // 534: sys_preadv
       4180,  // 535: sys_pwritev
       4727,  // 536: sys_rt_tgsigqueueinfo
       4357,  // 537: sys_recvmmsg
-      5184,  // 538: sys_sendmmsg
+      5294,  // 538: sys_sendmmsg
       4048,  // 539: sys_process_vm_readv
       4069,  // 540: sys_process_vm_writev
-      5663,  // 541: sys_setsockopt
+      5773,  // 541: sys_setsockopt
       1984,  // 542: sys_getsockopt
       2280,  // 543: sys_io_setup
       2293,  // 544: sys_io_submit
@@ -2479,5 +2485,483 @@
   };
 };
 
+struct SyscallTable_s390x {
+  static constexpr const char* names = kAllSyscalllNames;
+  static constexpr SyscallTable::OffT offsets[]{
+      0,     // 0:
+      866,   // 1: sys_exit
+      1212,  // 2: sys_fork
+      4251,  // 3: sys_read
+      6997,  // 4: sys_write
+      3585,  // 5: sys_open
+      553,   // 6: sys_close
+      4511,  // 7: sys_restart_syscall
+      611,   // 8: sys_creat
+      2614,  // 9: sys_link
+      6742,  // 10: sys_unlink
+      842,   // 11: sys_execve
+      277,   // 12: sys_chdir
+      0,     // 13:
+      3015,  // 14: sys_mknod
+      287,   // 15: sys_chmod
+      0,     // 16:
+      0,     // 17:
+      0,     // 18:
+      2760,  // 19: sys_lseek
+      1804,  // 20: sys_getpid
+      3105,  // 21: sys_mount
+      6709,  // 22: sys_umount
+      0,     // 23:
+      0,     // 24:
+      0,     // 25:
+      4144,  // 26: sys_ptrace
+      124,   // 27: sys_alarm
+      0,     // 28:
+      3672,  // 29: sys_pause
+      6840,  // 30: sys_utime
+      0,     // 31:
+      0,     // 32:
+      63,    // 33: sys_access
+      3509,  // 34: sys_nice
+      0,     // 35:
+      6254,  // 36: sys_sync
+      2490,  // 37: sys_kill
+      4457,  // 38: sys_rename
+      2993,  // 39: sys_mkdir
+      4531,  // 40: sys_rmdir
+      657,   // 41: sys_dup
+      3831,  // 42: sys_pipe
+      6613,  // 43: sys_times
+      0,     // 44:
+      233,   // 45: sys_brk
+      0,     // 46:
+      0,     // 47:
+      5955,  // 48: sys_signal
+      0,     // 49:
+      0,     // 50:
+      74,    // 51: sys_acct
+      6720,  // 52: sys_umount2
+      0,     // 53:
+      2367,  // 54: sys_ioctl
+      1086,  // 55: sys_fcntl
+      0,     // 56:
+      5604,  // 57: sys_setpgid
+      0,     // 58:
+      0,     // 59:
+      6699,  // 60: sys_umask
+      319,   // 61: sys_chroot
+      6830,  // 62: sys_ustat
+      665,   // 63: sys_dup2
+      1827,  // 64: sys_getppid
+      1792,  // 65: sys_getpgrp
+      5762,  // 66: sys_setsid
+      5925,  // 67: sys_sigaction
+      0,     // 68:
+      0,     // 69:
+      0,     // 70:
+      0,     // 71:
+      6038,  // 72: sys_sigsuspend
+      5993,  // 73: sys_sigpending
+      5564,  // 74: sys_sethostname
+      5748,  // 75: sys_setrlimit
+      0,     // 76:
+      1943,  // 77: sys_getrusage
+      2010,  // 78: sys_gettimeofday
+      5788,  // 79: sys_settimeofday
+      0,     // 80:
+      0,     // 81:
+      0,     // 82:
+      6228,  // 83: sys_symlink
+      0,     // 84:
+      4286,  // 85: sys_readlink
+      6803,  // 86: sys_uselib
+      6217,  // 87: sys_swapon
+      4324,  // 88: sys_reboot
+      4274,  // 89: sys_readdir
+      3071,  // 90: sys_mmap
+      3432,  // 91: sys_munmap
+      6633,  // 92: sys_truncate
+      1381,  // 93: sys_ftruncate
+      1011,  // 94: sys_fchmod
+      0,     // 95:
+      1839,  // 96: sys_getpriority
+      5616,  // 97: sys_setpriority
+      0,     // 98:
+      6138,  // 99: sys_statfs
+      1335,  // 100: sys_fstatfs
+      0,     // 101:
+      6064,  // 102: sys_socketcall
+      6328,  // 103: sys_syslog
+      5580,  // 104: sys_setitimer
+      1750,  // 105: sys_getitimer
+      6118,  // 106: sys_stat
+      2849,  // 107: sys_lstat
+      1299,  // 108: sys_fstat
+      0,     // 109:
+      2724,  // 110: sys_lookup_dcookie
+      6906,  // 111: sys_vhangup
+      2088,  // 112: sys_idle
+      0,     // 113:
+      6964,  // 114: sys_wait4
+      6205,  // 115: sys_swapoff
+      6316,  // 116: sys_sysinfo
+      2427,  // 117: sys_ipc
+      1361,  // 118: sys_fsync
+      6024,  // 119: sys_sigreturn
+      532,   // 120: sys_clone
+      5436,  // 121: sys_setdomainname
+      6732,  // 122: sys_uname
+      0,     // 123:
+      95,    // 124: sys_adjtimex
+      3163,  // 125: sys_mprotect
+      6008,  // 126: sys_sigprocmask
+      621,   // 127: sys_create_module
+      2097,  // 128: sys_init_module
+      639,   // 129: sys_delete_module
+      1516,  // 130: sys_get_kernel_syms
+      4222,  // 131: sys_quotactl
+      1780,  // 132: sys_getpgid
+      1000,  // 133: sys_fchdir
+      194,   // 134: sys_bdflush
+      6306,  // 135: sys_sysfs
+      3762,  // 136: sys_personality
+      108,   // 137: sys_afs_syscall
+      0,     // 138:
+      0,     // 139:
+      0,     // 140:
+      1616,  // 141: sys_getdents
+      5177,  // 142: sys_select
+      1202,  // 143: sys_flock
+      3395,  // 144: sys_msync
+      4314,  // 145: sys_readv
+      7007,  // 146: sys_writev
+      1957,  // 147: sys_getsid
+      1108,  // 148: sys_fdatasync
+      28,    // 149: sys__sysctl
+      3037,  // 150: sys_mlock
+      3405,  // 151: sys_munlock
+      3058,  // 152: sys_mlockall
+      3417,  // 153: sys_munlockall
+      5094,  // 154: sys_sched_setparam
+      4953,  // 155: sys_sched_getparam
+      5113,  // 156: sys_sched_setscheduler
+      4972,  // 157: sys_sched_getscheduler
+      5136,  // 158: sys_sched_yield
+      4859,  // 159: sys_sched_get_priority_max
+      4886,  // 160: sys_sched_get_priority_min
+      4995,  // 161: sys_sched_rr_get_interval
+      3465,  // 162: sys_nanosleep
+      3330,  // 163: sys_mremap
+      0,     // 164:
+      0,     // 165:
+      0,     // 166:
+      4205,  // 167: sys_query_module
+      3912,  // 168: sys_poll
+      3494,  // 169: sys_nfsservctl
+      0,     // 170:
+      0,     // 171:
+      3948,  // 172: sys_prctl
+      4645,  // 173: sys_rt_sigreturn
+      4571,  // 174: sys_rt_sigaction
+      4606,  // 175: sys_rt_sigprocmask
+      4588,  // 176: sys_rt_sigpending
+      4680,  // 177: sys_rt_sigtimedwait
+      4625,  // 178: sys_rt_sigqueueinfo
+      4662,  // 179: sys_rt_sigsuspend
+      3958,  // 180: sys_pread64
+      4167,  // 181: sys_pwrite64
+      0,     // 182:
+      1605,  // 183: sys_getcwd
+      255,   // 184: sys_capget
+      266,   // 185: sys_capset
+      5939,  // 186: sys_sigaltstack
+      5266,  // 187: sys_sendfile
+      1815,  // 188: sys_getpmsg
+      4155,  // 189: sys_putpmsg
+      6896,  // 190: sys_vfork
+      1929,  // 191: sys_getrlimit
+      0,     // 192:
+      0,     // 193:
+      0,     // 194:
+      0,     // 195:
+      0,     // 196:
+      0,     // 197:
+      2576,  // 198: sys_lchown
+      2027,  // 199: sys_getuid
+      1696,  // 200: sys_getgid
+      1670,  // 201: sys_geteuid
+      1644,  // 202: sys_getegid
+      5720,  // 203: sys_setreuid
+      5632,  // 204: sys_setregid
+      1720,  // 205: sys_getgroups
+      5534,  // 206: sys_setgroups
+      1049,  // 207: sys_fchown
+      5690,  // 208: sys_setresuid
+      1899,  // 209: sys_getresuid
+      5660,  // 210: sys_setresgid
+      1869,  // 211: sys_getresgid
+      297,   // 212: sys_chown
+      5805,  // 213: sys_setuid
+      5510,  // 214: sys_setgid
+      5482,  // 215: sys_setfsuid
+      5454,  // 216: sys_setfsgid
+      3850,  // 217: sys_pivot_root
+      2981,  // 218: sys_mincore
+      2871,  // 219: sys_madvise
+      1629,  // 220: sys_getdents64
+      0,     // 221:
+      4260,  // 222: sys_readahead
+      0,     // 223:
+      5829,  // 224: sys_setxattr
+      2770,  // 225: sys_lsetxattr
+      1251,  // 226: sys_fsetxattr
+      2051,  // 227: sys_getxattr
+      2600,  // 228: sys_lgetxattr
+      1122,  // 229: sys_fgetxattr
+      2670,  // 230: sys_listxattr
+      2700,  // 231: sys_llistxattr
+      1187,  // 232: sys_flistxattr
+      4423,  // 233: sys_removexattr
+      2743,  // 234: sys_lremovexattr
+      1221,  // 235: sys_fremovexattr
+      1999,  // 236: sys_gettid
+      6623,  // 237: sys_tkill
+      1411,  // 238: sys_futex
+      5054,  // 239: sys_sched_setaffinity
+      4913,  // 240: sys_sched_getaffinity
+      6347,  // 241: sys_tgkill
+      0,     // 242:
+      2280,  // 243: sys_io_setup
+      2205,  // 244: sys_io_destroy
+      2220,  // 245: sys_io_getevents
+      2293,  // 246: sys_io_submit
+      2191,  // 247: sys_io_cancel
+      875,   // 248: sys_exit_group
+      683,   // 249: sys_epoll_create
+      718,   // 250: sys_epoll_ctl
+      783,   // 251: sys_epoll_wait
+      5416,  // 252: sys_set_tid_address
+      919,   // 253: sys_fadvise64
+      6367,  // 254: sys_timer_create
+      6460,  // 255: sys_timer_settime
+      6422,  // 256: sys_timer_gettime
+      6401,  // 257: sys_timer_getoverrun
+      6384,  // 258: sys_timer_delete
+      494,   // 259: sys_clock_settime
+      409,   // 260: sys_clock_gettime
+      368,   // 261: sys_clock_getres
+      447,   // 262: sys_clock_nanosleep
+      0,     // 263:
+      0,     // 264:
+      6149,  // 265: sys_statfs64
+      1347,  // 266: sys_fstatfs64
+      4402,  // 267: sys_remap_file_pages
+      2904,  // 268: sys_mbind
+      1536,  // 269: sys_get_mempolicy
+      5330,  // 270: sys_set_mempolicy
+      3216,  // 271: sys_mq_open
+      3316,  // 272: sys_mq_unlink
+      3275,  // 273: sys_mq_timedsend
+      3228,  // 274: sys_mq_timedreceive
+      3202,  // 275: sys_mq_notify
+      3184,  // 276: sys_mq_getsetattr
+      2464,  // 277: sys_kexec_load
+      83,    // 278: sys_add_key
+      4495,  // 279: sys_request_key
+      2479,  // 280: sys_keyctl
+      6974,  // 281: sys_waitid
+      2412,  // 282: sys_ioprio_set
+      2397,  // 283: sys_ioprio_get
+      2135,  // 284: sys_inotify_init
+      2113,  // 285: sys_inotify_add_watch
+      2170,  // 286: sys_inotify_rm_watch
+      2963,  // 287: sys_migrate_pages
+      3649,  // 288: sys_openat
+      3003,  // 289: sys_mkdirat
+      3025,  // 290: sys_mknodat
+      1073,  // 291: sys_fchownat
+      1502,  // 292: sys_futimesat
+      3479,  // 293: sys_newfstatat
+      6753,  // 294: sys_unlinkat
+      4468,  // 295: sys_renameat
+      2623,  // 296: sys_linkat
+      6240,  // 297: sys_symlinkat
+      4299,  // 298: sys_readlinkat
+      1022,  // 299: sys_fchmodat
+      890,   // 300: sys_faccessat
+      4111,  // 301: sys_pselect6
+      3921,  // 302: sys_ppoll
+      6766,  // 303: sys_unshare
+      5376,  // 304: sys_set_robust_list
+      1554,  // 305: sys_get_robust_list
+      6094,  // 306: sys_splice
+      6263,  // 307: sys_sync_file_range
+      6339,  // 308: sys_tee
+      6939,  // 309: sys_vmsplice
+      3148,  // 310: sys_move_pages
+      1594,  // 311: sys_getcpu
+      750,   // 312: sys_epoll_pwait
+      6885,  // 313: sys_utimes
+      950,   // 314: sys_fallocate
+      6850,  // 315: sys_utimensat
+      5966,  // 316: sys_signalfd
+      6498,  // 317: sys_timerfd
+      817,   // 318: sys_eventfd
+      6510,  // 319: sys_timerfd_create
+      6571,  // 320: sys_timerfd_settime
+      6529,  // 321: sys_timerfd_gettime
+      5979,  // 322: sys_signalfd4
+      829,   // 323: sys_eventfd2
+      2152,  // 324: sys_inotify_init1
+      3840,  // 325: sys_pipe2
+      674,   // 326: sys_dup3
+      700,   // 327: sys_epoll_create1
+      3970,  // 328: sys_preadv
+      4180,  // 329: sys_pwritev
+      4727,  // 330: sys_rt_tgsigqueueinfo
+      3742,  // 331: sys_perf_event_open
+      964,   // 332: sys_fanotify_init
+      982,   // 333: sys_fanotify_mark
+      3993,  // 334: sys_prlimit64
+      3443,  // 335: sys_name_to_handle_at
+      3594,  // 336: sys_open_by_handle_at
+      330,   // 337: sys_clock_adjtime
+      6283,  // 338: sys_syncfs
+      5594,  // 339: sys_setns
+      4048,  // 340: sys_process_vm_readv
+      4069,  // 341: sys_process_vm_writev
+      4821,  // 342: sys_s390_runtime_instr
+      2435,  // 343: sys_kcmp
+      1170,  // 344: sys_finit_module
+      5076,  // 345: sys_sched_setattr
+      4935,  // 346: sys_sched_getattr
+      4481,  // 347: sys_renameat2
+      5152,  // 348: sys_seccomp
+      1855,  // 349: sys_getrandom
+      2929,  // 350: sys_memfd_create
+      215,   // 351: sys_bpf
+      4797,  // 352: sys_s390_pci_mmio_write
+      4774,  // 353: sys_s390_pci_mmio_read
+      853,   // 354: sys_execveat
+      6814,  // 355: sys_userfaultfd
+      2914,  // 356: sys_membarrier
+      4357,  // 357: sys_recvmmsg
+      5294,  // 358: sys_sendmmsg
+      6053,  // 359: sys_socket
+      6079,  // 360: sys_socketpair
+      206,   // 361: sys_bind
+      579,   // 362: sys_connect
+      2634,  // 363: sys_listen
+      51,    // 364: sys_accept4
+      1984,  // 365: sys_getsockopt
+      5773,  // 366: sys_setsockopt
+      1968,  // 367: sys_getsockname
+      1764,  // 368: sys_getpeername
+      5319,  // 369: sys_sendto
+      5307,  // 370: sys_sendmsg
+      4344,  // 371: sys_recvfrom
+      4390,  // 372: sys_recvmsg
+      5912,  // 373: sys_shutdown
+      3047,  // 374: sys_mlock2
+      591,   // 375: sys_copy_file_range
+      3981,  // 376: sys_preadv2
+      4192,  // 377: sys_pwritev2
+      4749,  // 378: sys_s390_guarded_storage
+      6176,  // 379: sys_statx
+      4844,  // 380: sys_s390_sthyi
+      2444,  // 381: sys_kexec_file_load
+      2237,  // 382: sys_io_pgetevents
+      4541,  // 383: sys_rseq
+      3894,  // 384: sys_pkey_mprotect
+      3865,  // 385: sys_pkey_alloc
+      3880,  // 386: sys_pkey_free
+      0,     // 387:
+      0,     // 388:
+      0,     // 389:
+      0,     // 390:
+      0,     // 391:
+      5220,  // 392: sys_semtimedop
+      5199,  // 393: sys_semget
+      5188,  // 394: sys_semctl
+      5901,  // 395: sys_shmget
+      5880,  // 396: sys_shmctl
+      5870,  // 397: sys_shmat
+      5891,  // 398: sys_shmdt
+      3362,  // 399: sys_msgget
+      3384,  // 400: sys_msgsnd
+      3373,  // 401: sys_msgrcv
+      3351,  // 402: sys_msgctl
+      0,     // 403:
+      0,     // 404:
+      0,     // 405:
+      0,     // 406:
+      0,     // 407:
+      0,     // 408:
+      0,     // 409:
+      0,     // 410:
+      0,     // 411:
+      0,     // 412:
+      0,     // 413:
+      0,     // 414:
+      0,     // 415:
+      0,     // 416:
+      0,     // 417:
+      0,     // 418:
+      0,     // 419:
+      0,     // 420:
+      0,     // 421:
+      0,     // 422:
+      0,     // 423:
+      3809,  // 424: sys_pidfd_send_signal
+      2348,  // 425: sys_io_uring_setup
+      2307,  // 426: sys_io_uring_enter
+      2326,  // 427: sys_io_uring_register
+      3616,  // 428: sys_open_tree
+      3133,  // 429: sys_move_mount
+      1277,  // 430: sys_fsopen
+      1238,  // 431: sys_fsconfig
+      1265,  // 432: sys_fsmount
+      1288,  // 433: sys_fspick
+      3794,  // 434: sys_pidfd_open
+      542,   // 435: sys_clone3
+      563,   // 436: sys_close_range
+      3660,  // 437: sys_openat2
+      3778,  // 438: sys_pidfd_getfd
+      904,   // 439: sys_faccessat2
+      4007,  // 440: sys_process_madvise
+      766,   // 441: sys_epoll_pwait2
+      3115,  // 442: sys_mount_setattr
+      4235,  // 443: sys_quotactl_fd
+      2521,  // 444: sys_landlock_create_ruleset
+      2499,  // 445: sys_landlock_add_rule
+      2549,  // 446: sys_landlock_restrict_self
+      2946,  // 447: sys_memfd_secret
+      4027,  // 448: sys_process_mrelease
+      1471,  // 449: sys_futex_waitv
+      5348,  // 450: sys_set_mempolicy_home_node
+      241,   // 451: sys_cachestat
+      1035,  // 452: sys_fchmodat2
+      2883,  // 453: sys_map_shadow_stack
+      1487,  // 454: sys_futex_wake
+      1456,  // 455: sys_futex_wait
+      1421,  // 456: sys_futex_requeue
+      6162,  // 457: sys_statmount
+      2645,  // 458: sys_listmount
+      2784,  // 459: sys_lsm_get_self_attr
+      2827,  // 460: sys_lsm_set_self_attr
+      2806,  // 461: sys_lsm_list_modules
+      3341,  // 462: sys_mseal
+      5842,  // 463: sys_setxattrat
+      2064,  // 464: sys_getxattrat
+      2684,  // 465: sys_listxattrat
+      4439,  // 466: sys_removexattrat
+      3630,  // 467: sys_open_tree_attr
+      1136,  // 468: sys_file_getattr
+      1153,  // 469: sys_file_setattr
+      2659,  // 470: sys_listns
+      4550,  // 471: sys_rseq_slice_yield
+  };
+};
+
 }  // namespace perfetto
 #endif  // SRC_KERNEL_UTILS_SYSCALL_TABLE_GENERATED_H_
diff --git a/src/perfetto_sql/analysis/relation.cc b/src/perfetto_sql/analysis/relation.cc
index 0ae3f90..d55e488 100644
--- a/src/perfetto_sql/analysis/relation.cc
+++ b/src/perfetto_sql/analysis/relation.cc
@@ -320,7 +320,21 @@
              Within(p, node->compound_select.right, at);
     case SYNTAQLITE_NODE_PERFETTO_PIPELINE:
       return Within(p, node->perfetto_pipeline.from, at) ||
-             Within(p, node->perfetto_pipeline.intersection, at);
+             Within(p, node->perfetto_pipeline.intersection, at) ||
+             Within(p, node->perfetto_pipeline.stages, at);
+    case SYNTAQLITE_NODE_PERFETTO_PIPE_STAGE_LIST: {
+      const void* list = syntaqlite_parser_node(p, id);
+      for (uint32_t i = 0; i < syntaqlite_list_count(list); ++i) {
+        if (Within(p, syntaqlite_list_child_id(list, i), at)) {
+          return true;
+        }
+      }
+      return false;
+    }
+    // A stage that reads another relation, like FILL GAPS reads its
+    // background.
+    case SYNTAQLITE_NODE_PERFETTO_INTERVAL_FILL_GAPS:
+      return Within(p, node->perfetto_interval_fill_gaps.background, at);
     case SYNTAQLITE_NODE_PERFETTO_INTERVAL_INTERSECTION: {
       const void* list = syntaqlite_parser_node(
           p, node->perfetto_interval_intersection.operands);
diff --git a/src/perfetto_sql/analysis/relation_unittest.cc b/src/perfetto_sql/analysis/relation_unittest.cc
index c7c4244..ce612a3 100644
--- a/src/perfetto_sql/analysis/relation_unittest.cc
+++ b/src/perfetto_sql/analysis/relation_unittest.cc
@@ -284,6 +284,17 @@
   EXPECT_EQ(result->row_origin(), std::nullopt);
 }
 
+// A relation read by a pipe stage is in scope, like a pipeline's source.
+TEST_F(RelationAnalyzerTest, ReadsWithinPipeStages) {
+  const std::string kHere = "SELECT 1 AS here";
+  std::vector<std::string> from = ReadAt("FROM (SELECT 1 AS here)", kHere, "");
+  ASSERT_FALSE(from.empty());
+  EXPECT_NE(from[0][0], '!') << from[0];
+  EXPECT_EQ(ReadAt("FROM slice |> INTERVAL FILL GAPS WITH (SELECT 1 AS here)",
+                   kHere, ""),
+            from);
+}
+
 // What is read at a node of a statement sees the CTEs in scope there, and only
 // those.
 TEST_F(RelationAnalyzerTest, ReadsSeeTheCtesInScope) {
diff --git a/src/perfetto_sql/syntaqlite/perfetto.synq b/src/perfetto_sql/syntaqlite/perfetto.synq
index b3b1110..cce755e 100644
--- a/src/perfetto_sql/syntaqlite/perfetto.synq
+++ b/src/perfetto_sql/syntaqlite/perfetto.synq
@@ -368,8 +368,20 @@
   }
 }
 
+// A column a SELECT or EXTEND lists: `expr [AS name]`. Only a column
+// reference may go without a name.
+node PerfettoPipeExprItem {
+  expr: index Expr
+  alias: inline SyntaqliteTextSpan
+
+  fmt {
+    child(expr)
+    if_span(alias) { space "AS" space span(alias) }
+  }
+}
+
 abstract PerfettoPipeSelectItem {
-  PerfettoPipeColumn
+  PerfettoPipeExprItem
   PerfettoPipeStar
 }
 
@@ -378,8 +390,7 @@
   fmt { for_each(sep: "," line) { child(_item) } }
 }
 
-// `SELECT item, ...`: picks, orders and renames columns. A computed column
-// has no spelling here yet.
+// `SELECT item, ...`: picks, orders, renames and computes columns.
 node PerfettoPipeSelect {
   columns: index PerfettoPipeSelectItemList
 
@@ -407,10 +418,10 @@
   fmt { group { "RENAME" nest { line child(columns) } } }
 }
 
-// One assignment of a SET stage: `name = column`.
+// One assignment of a SET stage: `name = expr`.
 node PerfettoPipeSetItem {
   name: inline SyntaqliteTextSpan
-  value: index PerfettoPipeColumn
+  value: index Expr
 
   fmt { span(name) space "=" space child(value) }
 }
@@ -420,7 +431,7 @@
   fmt { for_each(sep: "," line) { child(_item) } }
 }
 
-// `SET name = column, ...`: replaces the values of columns.
+// `SET name = expr, ...`: replaces the values of columns.
 node PerfettoPipeSet {
   items: index PerfettoPipeSetItemList
 
diff --git a/src/perfetto_sql/syntaqlite/perfetto.y b/src/perfetto_sql/syntaqlite/perfetto.y
index 87766d5..c966818 100644
--- a/src/perfetto_sql/syntaqlite/perfetto.y
+++ b/src/perfetto_sql/syntaqlite/perfetto.y
@@ -288,8 +288,12 @@
 // One item of a SELECT or EXTEND stage: a column, optionally qualified and
 // named, or a star.
 %type perfetto_pipe_select_item {uint32_t}
-perfetto_pipe_select_item(A) ::= perfetto_pipe_column(X). { A = X; }
-perfetto_pipe_select_item(A) ::= perfetto_pipe_named_column(X). { A = X; }
+perfetto_pipe_select_item(A) ::= expr(E). {
+    A = synq_parse_perfetto_pipe_expr_item(pCtx, E, SYNQ_NO_SPAN);
+}
+perfetto_pipe_select_item(A) ::= expr(E) AS nm(N). {
+    A = synq_parse_perfetto_pipe_expr_item(pCtx, E, synq_span_dequote(pCtx, N));
+}
 perfetto_pipe_select_item(A) ::= STAR perfetto_pipe_except(E)
                                  perfetto_pipe_replace(R). {
     A = synq_parse_perfetto_pipe_star(pCtx, SYNQ_NO_SPAN, E, R);
@@ -327,7 +331,7 @@
 
 // SET's list: `name = column, ...`.
 %type perfetto_pipe_set_item {uint32_t}
-perfetto_pipe_set_item(A) ::= nm(N) EQ perfetto_pipe_column(V). {
+perfetto_pipe_set_item(A) ::= nm(N) EQ expr(V). {
     A = synq_parse_perfetto_pipe_set_item(pCtx, synq_span_dequote(pCtx, N), V);
 }
 
diff --git a/src/perfetto_sql/syntaqlite/syntaqlite_perfetto.c b/src/perfetto_sql/syntaqlite/syntaqlite_perfetto.c
index 98df7fb..0bb458b 100644
--- a/src/perfetto_sql/syntaqlite/syntaqlite_perfetto.c
+++ b/src/perfetto_sql/syntaqlite/syntaqlite_perfetto.c
@@ -2043,6 +2043,11 @@
     {offsetof(SyntaqlitePerfettoPipeStar, replace), SYNTAQLITE_FIELD_NODE_ID, "replace", NULL, 0},
 };
 
+static const SyntaqliteFieldMeta field_meta_perfetto_pipe_expr_item[] = {
+    {offsetof(SyntaqlitePerfettoPipeExprItem, expr), SYNTAQLITE_FIELD_NODE_ID, "expr", NULL, 0},
+    {offsetof(SyntaqlitePerfettoPipeExprItem, alias), SYNTAQLITE_FIELD_SPAN, "alias", NULL, 0},
+};
+
 static const SyntaqliteFieldMeta field_meta_perfetto_pipe_select[] = {
     {offsetof(SyntaqlitePerfettoPipeSelect, columns), SYNTAQLITE_FIELD_NODE_ID, "columns", NULL, 0},
 };
@@ -2351,6 +2356,10 @@
     {offsetof(SyntaqlitePerfettoPipeStar, qualifier), 1},
 };
 
+static const SyntaqliteFieldRangeMeta range_meta_perfetto_pipe_expr_item[] = {
+    {offsetof(SyntaqlitePerfettoPipeExprItem, alias), 1},
+};
+
 static const SyntaqliteFieldRangeMeta range_meta_perfetto_pipe_set_item[] = {
     {offsetof(SyntaqlitePerfettoPipeSetItem, name), 1},
 };
@@ -2480,6 +2489,7 @@
     "PerfettoPipeName",
     "PerfettoPipeNameList",
     "PerfettoPipeStar",
+    "PerfettoPipeExprItem",
     "PerfettoPipeSelectItemList",
     "PerfettoPipeSelect",
     "PerfettoPipeExtend",
@@ -2622,6 +2632,7 @@
     field_meta_perfetto_pipe_name, /* PerfettoPipeName */
     NULL, /* PerfettoPipeNameList */
     field_meta_perfetto_pipe_star, /* PerfettoPipeStar */
+    field_meta_perfetto_pipe_expr_item, /* PerfettoPipeExprItem */
     NULL, /* PerfettoPipeSelectItemList */
     field_meta_perfetto_pipe_select, /* PerfettoPipeSelect */
     field_meta_perfetto_pipe_extend, /* PerfettoPipeExtend */
@@ -2762,6 +2773,7 @@
     1, /* PerfettoPipeName */
     0, /* PerfettoPipeNameList */
     3, /* PerfettoPipeStar */
+    2, /* PerfettoPipeExprItem */
     0, /* PerfettoPipeSelectItemList */
     1, /* PerfettoPipeSelect */
     1, /* PerfettoPipeExtend */
@@ -2904,6 +2916,7 @@
     0, /* PerfettoPipeName */
     1, /* PerfettoPipeNameList */
     0, /* PerfettoPipeStar */
+    0, /* PerfettoPipeExprItem */
     1, /* PerfettoPipeSelectItemList */
     0, /* PerfettoPipeSelect */
     0, /* PerfettoPipeExtend */
@@ -3046,6 +3059,7 @@
     {range_meta_perfetto_pipe_name, 1}, /* PerfettoPipeName */
     {NULL, 0}, /* PerfettoPipeNameList */
     {range_meta_perfetto_pipe_star, 1}, /* PerfettoPipeStar */
+    {range_meta_perfetto_pipe_expr_item, 1}, /* PerfettoPipeExprItem */
     {NULL, 0}, /* PerfettoPipeSelectItemList */
     {NULL, 0}, /* PerfettoPipeSelect */
     {NULL, 0}, /* PerfettoPipeExtend */
@@ -5904,6 +5918,13 @@
     2,2,0,0,0,0,
     0,0,6,0,0,0,
     12,0,0,0,0,0,
+    2,0,0,0,0,0,
+    20,1,0,0,5,0,
+    0,0,2,0,0,0,
+    0,0,13,0,0,0,
+    0,0,2,0,0,0,
+    1,1,0,0,0,0,
+    12,0,0,0,0,0,
     22,0,0,0,0,0,
     14,0,0,0,0,0,
     15,0,74,0,0,0,
@@ -6087,7 +6108,7 @@
     12,0,0,0,0,0,
 };
 
-static const uint32_t perfetto_fmt_ops_count = 17280;
+static const uint32_t perfetto_fmt_ops_count = 17322;
 
 static const uint32_t perfetto_fmt_dispatch[] = {
     0xffff0000,0x00000031,0x0031003a,0x006b0008,0x00730009,0x007c0025,0x00a10009,0x00aa000b,
@@ -6104,13 +6125,13 @@
     0x093d0006,0x09430005,0x09480003,0x094b0005,0x09500001,0x09510005,0x0956000f,0x09650001,
     0x0966002c,0x0992001a,0x09ac001e,0x09ca001f,0x09e90018,0x0a01001e,0x0a1f0005,0x0a240009,
     0x0a2d0008,0x0a350017,0x0a4c0005,0x0a510005,0x0a56000a,0x0a60000b,0x0a6b0005,0x0a700001,
-    0x0a710005,0x0a760015,0x0a8b0005,0x0a900007,0x0a970007,0x0a9e0007,0x0aa50007,0x0aac0005,
-    0x0ab10005,0x0ab60007,0x0abd0003,0x0ac0000a,0x0aca0005,0x0acf0008,0x0ad70010,0x0ae70007,
-    0x0aee0001,0x0aef0007,0x0af60005,0x0afb0001,0x0afc0005,0x0b010010,0x0b11000e,0x0b1f0013,
-    0x0b32000e,
+    0x0a710005,0x0a760015,0x0a8b0007,0x0a920005,0x0a970007,0x0a9e0007,0x0aa50007,0x0aac0007,
+    0x0ab30005,0x0ab80005,0x0abd0007,0x0ac40003,0x0ac7000a,0x0ad10005,0x0ad60008,0x0ade0010,
+    0x0aee0007,0x0af50001,0x0af60007,0x0afd0005,0x0b020001,0x0b030005,0x0b080010,0x0b18000e,
+    0x0b260013,0x0b39000e,
 };
 
-static const uint32_t perfetto_fmt_dispatch_count = 137;
+static const uint32_t perfetto_fmt_dispatch_count = 138;
 
 static const uint8_t perfetto_fmt_prec_table[] = {
     6,0,6,0,7,0,7,0,7,0,4,0,4,0,4,0,
@@ -6139,10 +6160,10 @@
     0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,
     0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,
     0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff,
-    0xffffffff,
+    0xffffffff,0xffffffff,
 };
 
-static const uint32_t perfetto_fmt_expr_meta_count = 137;
+static const uint32_t perfetto_fmt_expr_meta_count = 138;
 
 
 #endif  /* SYNTAQLITE_PERFETTO_DIALECT_FMT_H */
@@ -6300,9 +6321,10 @@
     0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
     0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
     0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+    0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
 };
 
-static const uint32_t perfetto_roles_count = 137;
+static const uint32_t perfetto_roles_count = 138;
 
 /* Macro definition metadata for the perfetto dialect. */
 /* Each entry is 8 bytes: node_tag(u16) + 4 field indices + 2 pad. */
@@ -12660,6 +12682,19 @@
         }, (uint32_t)sizeof(SyntaqlitePerfettoPipeStar));
 }
 
+static inline uint32_t synq_parse_perfetto_pipe_expr_item(
+    SynqParseCtx *ctx,
+    uint32_t expr,
+    SyntaqliteTextSpan alias
+) {
+    return synq_parse_build(ctx,
+        &(SyntaqlitePerfettoPipeExprItem){
+            .tag = SYNTAQLITE_NODE_PERFETTO_PIPE_EXPR_ITEM,
+            .expr = expr,
+            .alias = alias
+        }, (uint32_t)sizeof(SyntaqlitePerfettoPipeExprItem));
+}
+
 static inline uint32_t synq_parse_perfetto_pipe_select(
     SynqParseCtx *ctx,
     uint32_t columns
@@ -13690,18 +13725,18 @@
 #define YYERRORSYMBOL 212
 #define YYERRSYMDT yy781
 #define YYFALLBACK 1
-#define YYNSTATE             775
+#define YYNSTATE             776
 #define YYNRULE              525
 #define YYNRULE_WITH_ACTION  525
 #define YYNTOKEN             208
-#define YY_MAX_SHIFT         774
-#define YY_MIN_SHIFTREDUCE   1114
-#define YY_MAX_SHIFTREDUCE   1638
-#define YY_ERROR_ACTION      1639
-#define YY_ACCEPT_ACTION     1640
-#define YY_NO_ACTION         1641
-#define YY_MIN_REDUCE        1642
-#define YY_MAX_REDUCE        2166
+#define YY_MAX_SHIFT         775
+#define YY_MIN_SHIFTREDUCE   1112
+#define YY_MAX_SHIFTREDUCE   1636
+#define YY_ERROR_ACTION      1637
+#define YY_ACCEPT_ACTION     1638
+#define YY_NO_ACTION         1639
+#define YY_MIN_REDUCE        1640
+#define YY_MAX_REDUCE        2164
 #define YY_MIN_DSTRCTR       0
 #define YY_MAX_DSTRCTR       0
 /************* End control #defines *******************************************/
@@ -13786,565 +13821,570 @@
 **  yy_default[]       Default action for each state.
 **
 *********** Begin parsing tables **********************************************/
-#define YY_ACTTAB_COUNT (2743)
+#define YY_ACTTAB_COUNT (2792)
 static const YYACTIONTYPE yy_action[] = {
- /*     0 */   286, 1316, 1724, 1316, 1316, 1326,  106,  108, 1710,  358,
- /*    10 */  1898,  710, 2144,  286, 1843, 1327, 1843, 1843,  673,  106,
- /*    20 */   108, 1789,   99,  100,  518,   55, 1707, 1160, 1160, 1157,
- /*    30 */  1142, 1151, 1151,  101,  101,  102,  102,  102,  102, 1592,
- /*    40 */  1790, 1762,  413,  358, 1898,  506,  582,  708, 1704, 1593,
- /*    50 */   483,  102,  102,  102,  102,  105,   99,  100,  518,   55,
- /*    60 */  1790, 1160, 1160, 1157, 1142, 1151, 1151,  101,  101,  102,
- /*    70 */   102,  102,  102, 2019,  494, 1313,  366,  358, 1898,  364,
- /*    80 */  2085,  768,  688, 1894,  335,  286, 1551,  282,  671,  539,
- /*    90 */   645,  106,  108,   98,   98,   98,   98,  104,  104,  103,
- /*   100 */   103,  103,   97,   96,  563,  751,  749, 1973, 1313,   98,
- /*   110 */    98,   98,   98,  104,  104,  103,  103,  103,   97,   96,
- /*   120 */   563, 1733,  484, 1760,  614, 1758, 1839,   98,   98,   98,
- /*   130 */    98,  104,  104,  103,  103,  103,   97,   96,  563,  751,
- /*   140 */   749, 1992, 1313, 1314, 1313, 1551, 1161, 1161, 1158, 1143,
- /*   150 */    99,  100,  518,   55, 1973, 1160, 1160, 1157, 1142, 1151,
- /*   160 */  1151,  101,  101,  102,  102,  102,  102,  401,  327, 1551,
- /*   170 */   700,  697,  696,  751,  749, 1313, 1314, 1313, 1980, 1981,
- /*   180 */   695,   78,   99,  100,  518,   55, 1316, 1160, 1160, 1157,
- /*   190 */  1142, 1151, 1151,  101,  101,  102,  102,  102,  102, 1843,
- /*   200 */  1972,  642,  643,  563,   99,  100,  518,   55,  616, 1160,
- /*   210 */  1160, 1157, 1142, 1151, 1151,  101,  101,  102,  102,  102,
- /*   220 */   102,   98,   98,   98,   98,  104,  104,  103,  103,  103,
- /*   230 */    97,   96,  563,   61,  473, 1515,  509, 1515,  103,  103,
- /*   240 */   103,   97,   96,  563, 1152,  409,   77, 1972, 1970, 1968,
- /*   250 */   487,  492, 2052,   98,   98,   98,   98,  104,  104,  103,
- /*   260 */   103,  103,   97,   96,  563,  263,  104,  104,  103,  103,
- /*   270 */   103,   97,   96,  563, 2118,   98,   98,   98,   98,  104,
- /*   280 */   104,  103,  103,  103,   97,   96,  563,   99,  100,  518,
- /*   290 */    55,  549, 1160, 1160, 1157, 1142, 1151, 1151,  101,  101,
- /*   300 */   102,  102,  102,  102, 1713,  358, 1898,  497,  536,  604,
- /*   310 */   536,   19,   99,  100,  518,   55,  534, 1160, 1160, 1157,
- /*   320 */  1142, 1151, 1151,  101,  101,  102,  102,  102,  102,  358,
- /*   330 */  1898,  499,  358, 1898,  501,  664,  449,   99,  100,  518,
- /*   340 */    55, 1552, 1160, 1160, 1157, 1142, 1151, 1151,  101,  101,
- /*   350 */   102,  102,  102,  102, 1313, 1716, 2114,  615,   98,   98,
- /*   360 */    98,   98,  104,  104,  103,  103,  103,   97,   96,  563,
- /*   370 */    98,   98,   98,   98,  104,  104,  103,  103,  103,   97,
- /*   380 */    96,  563,  297,   98,   98,   98,   98,  104,  104,  103,
- /*   390 */   103,  103,   97,   96,  563,  354,  287,  729,  286,  727,
- /*   400 */  1552,  751,  749,  720,  106,  108,  230,   62,   98,   98,
- /*   410 */    98,   98,  104,  104,  103,  103,  103,   97,   96,  563,
- /*   420 */   759, 1313, 1314, 1313, 1552,  751,  749,   44,  751,  749,
- /*   430 */    99,  100,  518,   55,  391, 1160, 1160, 1157, 1142, 1151,
- /*   440 */  1151,  101,  101,  102,  102,  102,  102, 2107, 2108, 2107,
- /*   450 */  2108,  358, 1898,  624, 2112, 1715, 2111,  618, 2101,  533,
- /*   460 */    99,  100,  518,   55,  270, 1160, 1160, 1157, 1142, 1151,
- /*   470 */  1151,  101,  101,  102,  102,  102,  102, 1313,  355, 1898,
- /*   480 */   623,  287,  729,   99,  100,  518,   55,  407, 1160, 1160,
- /*   490 */  1157, 1142, 1151, 1151,  101,  101,  102,  102,  102,  102,
- /*   500 */   675,   98,   98,   98,   98,  104,  104,  103,  103,  103,
- /*   510 */    97,   96,  563,  614,    6, 2027, 1289, 1750,  132,  718,
- /*   520 */  2033,  536,    6,  460,  358, 1898,  373, 1313, 2034,  767,
- /*   530 */  1313,   98,   98,   98,   98,  104,  104,  103,  103,  103,
- /*   540 */    97,   96,  563,  123, 1313, 1314, 1313,  751,  749,  474,
- /*   550 */   246, 1510,  531,  701,   98,   98,   98,   98,  104,  104,
- /*   560 */   103,  103,  103,   97,   96,  563,  771, 1818, 1510,  356,
- /*   570 */  1898, 1510,  720,  665,  751,  749, 1194,   99,  100,  518,
- /*   580 */    55,  444, 1160, 1160, 1157, 1142, 1151, 1151,  101,  101,
- /*   590 */   102,  102,  102,  102, 1313, 1314, 1313, 1313, 1314, 1313,
- /*   600 */    99,  100,  518,   55,  731, 1160, 1160, 1157, 1142, 1151,
- /*   610 */  1151,  101,  101,  102,  102,  102,  102,  358, 1898, 2004,
- /*   620 */   751,  749, 2145,   99,  100,  518,   55,  673, 1160, 1160,
- /*   630 */  1157, 1142, 1151, 1151,  101,  101,  102,  102,  102,  102,
- /*   640 */   358, 1898, 1702, 1543,  482, 2147, 2039,  530,   98,   98,
- /*   650 */    98,   98,  104,  104,  103,  103,  103,   97,   96,  563,
- /*   660 */  2107, 2108, 1926, 2117,  612,  751,  749, 2111,  619,  531,
- /*   670 */  1186,   98,   98,   98,   98,  104,  104,  103,  103,  103,
- /*   680 */    97,   96,  563,  721, 2026,  369,  358, 1898,  760,  116,
- /*   690 */   613, 2124, 2125,  209,   98,   98,   98,   98,  104,  104,
- /*   700 */   103,  103,  103,   97,   96,  563, 2126,  603, 1289,  762,
- /*   710 */   133, 1139, 1139,  751,  749,  202, 1528,   99,  100,  518,
- /*   720 */    55,  767, 1160, 1160, 1157, 1142, 1151, 1151,  101,  101,
- /*   730 */   102,  102,  102,  102, 1313,  592,  751,  749,  616,  293,
- /*   740 */    99,  100,  518,   55,  759, 1160, 1160, 1157, 1142, 1151,
- /*   750 */  1151,  101,  101,  102,  102,  102,  102, 1313,  391, 1818,
- /*   760 */   358, 1898,  763,   99,  100,  518,   55,  759, 1160, 1160,
- /*   770 */  1157, 1142, 1151, 1151,  101,  101,  102,  102,  102,  102,
- /*   780 */  1313,  391,  751,  749, 1313, 1769,  715,  334,   98,   98,
- /*   790 */    98,   98,  104,  104,  103,  103,  103,   97,   96,  563,
- /*   800 */   125, 1313, 1314, 1313,  306, 1259,  609,  247, 2124, 2125,
- /*   810 */  1308,   98,   98,   98,   98,  104,  104,  103,  103,  103,
- /*   820 */    97,   96,  563, 2127, 1313, 1314, 1313,  291,  491, 2116,
- /*   830 */   540,  127, 1767, 1291,   98,   98,   98,   98,  104,  104,
- /*   840 */   103,  103,  103,   97,   96,  563,  292, 1313, 1314, 1313,
- /*   850 */   679, 1313, 1314, 1313,  286,  283,  751,  749, 2091,  601,
- /*   860 */   106,  108,  540, 1313,  289, 1769, 2097,   99,  100,  518,
- /*   870 */    55,   87, 1160, 1160, 1157, 1142, 1151, 1151,  101,  101,
- /*   880 */   102,  102,  102,  102, 1313,  431, 2115,  447,  657,  434,
- /*   890 */    99,  100,  518,   55, 1316, 1160, 1160, 1157, 1142, 1151,
- /*   900 */  1151,  101,  101,  102,  102,  102,  102, 1843,  491,   17,
- /*   910 */  1313,  129, 1767,   99,  100,  518,   55,  261, 1160, 1160,
- /*   920 */  1157, 1142, 1151, 1151,  101,  101,  102,  102,  102,  102,
- /*   930 */  1313, 1314, 1313, 1492, 1664,  368,    5, 1313,   98,   98,
- /*   940 */    98,   98,  104,  104,  103,  103,  103,   97,   96,  563,
- /*   950 */  1986, 1313, 1314, 1313, 1494,  353, 2016,    3,  282, 2016,
- /*   960 */  1333,   98,   98,   98,   98,  104,  104,  103,  103,  103,
- /*   970 */    97,   96,  563,  688,   97,   96,  563, 1313, 1314, 1313,
- /*   980 */  1872,  766, 1510,  113,   98,   98,   98,   98,  104,  104,
- /*   990 */   103,  103,  103,   97,   96,  563,  403,  733,   94, 1510,
- /*  1000 */   680,  116, 1510,  566, 1313, 1314, 1313,  617,  265,   99,
- /*  1010 */   100,  518,   55, 1316, 1160, 1160, 1157, 1142, 1151, 1151,
- /*  1020 */   101,  101,  102,  102,  102,  102, 1843,  407, 1313,  751,
- /*  1030 */   749,   99,  107,  518,   55,  732, 1160, 1160, 1157, 1142,
- /*  1040 */  1151, 1151,  101,  101,  102,  102,  102,  102,  100,  518,
- /*  1050 */    55, 1769, 1160, 1160, 1157, 1142, 1151, 1151,  101,  101,
- /*  1060 */   102,  102,  102,  102,  518,   55,  651, 1160, 1160, 1157,
- /*  1070 */  1142, 1151, 1151,  101,  101,  102,  102,  102,  102,  759,
- /*  1080 */    98,   98,   98,   98,  104,  104,  103,  103,  103,   97,
- /*  1090 */    96,  563,  688,  391,  491, 1313, 1314, 1313, 1768, 1871,
- /*  1100 */  1980, 1981,   98,   98,   98,   98,  104,  104,  103,  103,
- /*  1110 */   103,   97,   96,  563, 1840,  673, 1313,  486,   98,   98,
- /*  1120 */    98,   98,  104,  104,  103,  103,  103,   97,   96,  563,
- /*  1130 */   712, 2055,  187,   98,   98,   98,   98,  104,  104,  103,
- /*  1140 */   103,  103,   97,   96,  563, 1642, 1421, 1421,  685,  308,
- /*  1150 */  1189,  415, 1407,  346, 1289, 1707,  132,  606,  565,  564,
- /*  1160 */   294,  414, 2146,  422, 1326,  571,  308,  767,  415, 1603,
- /*  1170 */   346, 1450, 1450,  372, 1327, 1321, 1316, 1705,  414,  284,
- /*  1180 */   422, 1379,  571, 1313, 1314, 1313,  186,  653, 1405, 1843,
- /*  1190 */  1289,   58,  176, 1318, 2097, 1317, 1319,  237, 1798,  309,
- /*  1200 */  1321,  534,  419,  767,   36, 1818,  407,  421,  191, 1130,
- /*  1210 */  1319,  222,   74,  713,  115,  673,  309, 1189, 1318,  419,
- /*  1220 */  1317, 1319,   59,  575,  421,  191,  504,  407,  222,   17,
- /*  1230 */  1289,  115,  132,  307, 1405, 1319, 1319, 1320,  602,  492,
- /*  1240 */  2052, 1818,  532,  767, 1212,   35, 1316,   10,  331, 1379,
- /*  1250 */   307, 1289,  522,  130,   13,  263, 1418, 1117,  201, 1843,
- /*  1260 */  1418, 1319, 1320,  586,  767, 1640,    1, 1644,  774,  773,
- /*  1270 */  1648,  714,  221,  374, 1117, 1478,  712, 1130, 1289,  659,
- /*  1280 */   133, 1818,  704,  481, 2041, 1943,  358, 1898, 1896,  221,
- /*  1290 */  1316,  767,  759, 1213, 1289, 1289,  169,  133,  711,  517,
- /*  1300 */   683,  647, 1818, 1843,  422,  681,  391,  767,  767,  759,
- /*  1310 */  1497,  362,  380,  770,  198,  662,  517,  257,  647,  540,
- /*  1320 */   663,  422,  456,  391,  452,  688,   91,  523,  362, 1818,
- /*  1330 */   316,  493, 1870, 1496,  576,  535, 1289,  588,  169,  574,
- /*  1340 */   742,  398,  569, 2102,  600, 1818, 1818, 1472,  546,  767,
- /*  1350 */  1510,  576, 1289, 1259,  130, 1316,  574,  756,  737,  713,
- /*  1360 */  2039,  600,  503,  487,  116,  767, 2001, 1510, 1843,  688,
- /*  1370 */  1510,  116,  743,  770,  262, 1943, 1869,  552,  641,    2,
- /*  1380 */  1648,  640,  751,  749,  577,  677,   91, 1818, 1289,  458,
- /*  1390 */   133,    8, 1321,  679, 1751,  377,  358, 1898, 1896,   93,
- /*  1400 */    93,  767,  569, 1818,  558,  514, 1289,   92,  169,  569,
- /*  1410 */   757,  569, 1317, 1319,  743,    4, 2123,  756, 1316,  767,
- /*  1420 */  1357,  589,  380,   74,  198, 1359,  764, 1319, 2091,  361,
- /*  1430 */    31, 1843, 1943, 1416,  263,  447,  735,  679,  547, 1818,
- /*  1440 */   316,  734,  759, 1131, 2153, 2091,  610,  596, 1289,  759,
- /*  1450 */   169, 1358, 1321, 1319, 1320, 1322,  391, 1818,  384,   93,
- /*  1460 */    93,  767,  327,  391,  700,  697,  696,   92,  678,  569,
- /*  1470 */   757,  569, 1317, 1319,  695,    4, 1928,  308,  446,  415,
- /*  1480 */  1943,  346,  714, 1289,  716,   51,  764, 1319,  541,  414,
- /*  1490 */    31,  422,  751,  749,  577,  548,  767,  688,  669, 1818,
- /*  1500 */  1643,  774,  773, 1648,  454,  395, 1769,  102,  102,  102,
- /*  1510 */   102, 1131, 1769, 1319, 1320, 1322,  204, 2122,  605,  358,
- /*  1520 */  1898, 1896,  375,  284, 1316, 1943,  386,  309,  477,  351,
- /*  1530 */   419,  426, 1405,  428, 1818,  421,  191, 1843, 2092,  222,
- /*  1540 */  1335,  272,  115,  684,  230,  380,  221,  198, 2057,  491,
- /*  1550 */   476,  770,  126, 1767, 2153,  491,  664,  449,  128, 1767,
- /*  1560 */  1336,  307, 2141,  316,   91,   98,   98,   98,   98,  104,
- /*  1570 */   104,  103,  103,  103,   97,   96,  563, 1289, 1405,   51,
- /*  1580 */   569, 1492,  544, 1263,  692, 1497, 1737,  331,  555,   95,
- /*  1590 */   767,   89, 1289,    6,  169,  756,  745, 1264,  429, 2031,
- /*  1600 */   221, 1334, 1494, 1893, 2017,  767,  493, 2017, 1493,  358,
- /*  1610 */  1898,  744,    2, 1652,  735,  751,  749,  577,  600,  736,
- /*  1620 */   759,  427, 1289, 1289,  169,  143,  568,  517, 1818,  647,
- /*  1630 */  1321,  770,  422,   82,  391,  767,  767,   93,   93,  362,
- /*  1640 */   358, 1898,  765, 1818,   91,   92, 1313,  569,  757,  569,
- /*  1650 */  1317, 1319,    6,    4, 1203,  649, 1382,  730, 2033,   43,
- /*  1660 */   569, 1381,  576, 1316,  764, 1319,  523,  574,   31, 1510,
- /*  1670 */   743, 2148,  600, 1818, 1818,  756, 1843, 2153,  330,  329,
- /*  1680 */   328,    6, 1313, 1289, 1379,   51, 1510, 2032,  550, 1510,
- /*  1690 */  2156, 1319, 1320, 1322,  735, 2090,  767,  723, 1650,  734,
- /*  1700 */   743,  746,    6,  770,  463,  751,  749, 1289, 2030,   51,
- /*  1710 */  1321,  367,  376, 1313, 1314, 1313,   91,   93,   93, 1382,
- /*  1720 */   767, 2094, 1798,  741, 1381,   92,   82,  569,  757,  569,
- /*  1730 */  1317, 1319,  569,    4, 1818, 1351,  751,  749,  492, 2052,
- /*  1740 */   770, 1132, 1895, 1335,  764, 1319,  667,  756,   31, 1313,
- /*  1750 */  1314, 1313, 1379,   54,  370, 1289,    6,   51, 1818, 2113,
- /*  1760 */   254,  201, 2029, 1336, 1289,  300,  167,  295,  767,  569,
- /*  1770 */  1406, 1319, 1320, 1322, 1880,  524,  200,  767, 1289, 1289,
- /*  1780 */    51,  180, 1321,  255,  756, 1749,  755,  489, 1224,   93,
- /*  1790 */    93,  767,  767,  111, 1316,  769,  524,   92,  280,  569,
- /*  1800 */   757,  569, 1317, 1319, 1334,    4, 1818, 1843, 1289, 1289,
- /*  1810 */    51,  169,  770,  740, 2095, 1818,  764, 1319,  753, 1321,
- /*  1820 */    31,  767,  767,  492, 2052,   91,   93,   93,   75, 1818,
- /*  1830 */  1818,  513,  512, 1289,   92,   53,  569,  757,  569, 1317,
- /*  1840 */  1319,  569,    4, 1319, 1320, 1322,  722,   73,  770,  280,
- /*  1850 */   739,  196, 1316,  764, 1319,  752,  756,   31,  273, 1818,
- /*  1860 */  1818,   91, 1289,  554,  169, 1843, 1289,  399,   51,  608,
- /*  1870 */  1316,  567,  110, 1875,   40,  767,  738,  569,   47,  767,
- /*  1880 */  1319, 1320, 1322, 1843, 1818, 1521, 2100,  560, 1316,  741,
- /*  1890 */  1316, 1321,  756,   84,  581,  585,  525,  231,   93,   93,
- /*  1900 */  1374, 1843, 1316, 1843,  594,  595,   92, 1375,  569,  757,
- /*  1910 */   569, 1317, 1319, 1818,    4, 1843,  273, 1818, 1521, 1289,
- /*  1920 */  1289,  148,  169,  703,  620,  764, 1319, 1321,  303,   31,
- /*  1930 */   302, 1874,  767,  767,   93,   93,  655,  515, 1486, 1313,
- /*  1940 */   561,  495,   92,  551,  569,  757,  569, 1317, 1319,  646,
- /*  1950 */     4, 2099, 1319, 1320, 1322,  363,  464,  656,  515,  666,
- /*  1960 */   515,  764, 1319, 2098,  472,   31, 1289, 1873,  169, 1866,
- /*  1970 */  1818, 1818,  333,  349,  706,  467,  705,  332,  300,  767,
- /*  1980 */   279, 1906, 1197,  463,  670,  515,  385,  515, 1319, 1320,
- /*  1990 */  1322, 1289,  498,  149, 1560, 1561,  565,  564,  562, 2096,
- /*  2000 */  1289,  412,  150, 1635,  767, 1446, 1313, 1314, 1313, 1450,
- /*  2010 */  1450,  542, 1289,  767,  151,  416, 1289, 1818,  152, 1289,
- /*  2020 */   425,   52, 1289, 2164,  134,  767, 1289,  652,  135,  767,
- /*  2030 */    64,  269,  767, 1448, 1289,  767,  153,  417, 1632,  767,
- /*  2040 */  1447,  587, 1818, 1289,  387,  154, 1289,  767,  155,  418,
- /*  2050 */  1197, 1818, 1289, 1289,  156,  157,  767, 1890, 1289,  767,
- /*  2060 */   136, 2166,  313, 1818,  315,  767,  767, 1818,  591, 1544,
- /*  2070 */  1818,  767,  629, 1818, 1289,  397,  137, 1818,  219, 1289,
- /*  2080 */  1578,  138,   21,  238,  648, 1818, 1576,  767, 1289,  304,
- /*  2090 */   139,  471,  767, 1289, 1818,  158, 1540, 1818, 1796,  629,
- /*  2100 */  1289,  767,  159, 1818, 1818, 1289,  767,  160,  439, 1818,
- /*  2110 */   470,   82,  445,  767, 1218,   82, 1795, 1210,  767, 1289,
- /*  2120 */  1280,  161, 1289,  337,  162, 1818, 1211, 1289,  672,  131,
- /*  2130 */  1818,  337,  767,  654, 1289,  767,  140, 1329, 1330, 1818,
- /*  2140 */   767, 2015, 1250,  437, 1818, 1219, 1289,  767,  141, 1451,
- /*  2150 */  1451, 1818, 1289, 1289,   50,  142, 1818,  660, 1289,  767,
- /*  2160 */   163, 1289,  747,  174, 1323,  767,  767, 1289,  440,  175,
- /*  2170 */  1818,  767, 1961, 1818,  767, 1289,  357,  164, 1818, 1289,
- /*  2180 */   767,  144, 1841,  674, 1959, 1818,  337, 1289,  767,  165,
- /*  2190 */  1736,  693,  767,  461,  341,  451,   82, 1818, 1410, 1246,
- /*  2200 */   767,  337,  341, 1818, 1818,  455, 1289,  457,  145, 1818,
- /*  2210 */  1250, 1289, 1818,  171,  459, 1289, 1754,  214, 1818,  767,
- /*  2220 */  1289, 1289,  215,  166,  767, 1243, 1818, 1289,  767,  146,
- /*  2230 */  1818, 1734, 1323,  767,  767, 1289,  466,  212, 1818, 1289,
- /*  2240 */   767,  213, 1289, 1482,  182, 1289,   84,  170,  767, 1735,
- /*  2250 */  1481, 1480,  767,   84,   84,  767, 1712, 1818,  767, 1449,
- /*  2260 */  1449, 1289, 1818,  172,  772,  205, 1818, 1289, 1289,  177,
- /*  2270 */   181, 1818, 1818, 1706,  767, 1940, 1128, 1942, 1818,  203,
- /*  2280 */   767,  767,  210,  252, 1676,   82, 1818, 1289, 2046,  206,
- /*  2290 */  1818,  488, 1289, 1818,  183, 1663, 1818,  689,  754,  572,
- /*  2300 */   767, 1289,  276,  178,  423,  767,  347, 1289, 1289,  173,
- /*  2310 */   179,  211, 1818, 1289,  767,  168,  381,  382, 1818, 1818,
- /*  2320 */   767,  767, 1289,   15,  147,  383,  767,  528, 1901,    9,
- /*  2330 */   639, 2140,  195,  443,  433,  767, 1784,  365, 1818,  436,
- /*  2340 */   442,  281,  676, 1818,  698, 1812,  469, 1811, 1733,  371,
- /*  2350 */   507, 1931, 1818, 1699, 1775,  448, 1932, 1776, 1818, 1818,
- /*  2360 */   258,  480,  259,  758, 1818, 1634, 1930,  274,  526, 1545,
- /*  2370 */   527,  410, 1555, 1818,  233,  621,  622,  529, 1929,  275,
- /*  2380 */   189,  597,  406,  502, 2138,  611,  340,  637,  628, 2109,
- /*  2390 */  2110,  400,  625,  632,  638, 2087, 2086,   59, 1460, 1985,
- /*  2400 */  1983, 1363,  537,  402,   60,  538,  310,  190,   63,  192,
- /*  2410 */  1993,  644, 1882, 1881, 1351,  650,  118,  193,  119,  271,
- /*  2420 */   120, 1785,  121,  122,  411,  244,   39,   79, 1783,  741,
- /*  2430 */   227,  241,  432,  658,  691, 1782,  435,  318,   75,  661,
- /*  2440 */   320, 1814, 1813, 1786,  248,   45, 1999,  505,  668,  256,
- /*  2450 */   682,  450,  323,  508,   69,  687,  453, 1945,  348,  324,
- /*  2460 */  1700,  325,  510,  707, 1757, 1756, 1755,  553, 1744,   71,
- /*  2470 */  1721,  511, 1203, 1727, 1726, 1720,  468, 1743,   16, 1719,
- /*  2480 */   338, 1900, 1718, 1899,  475,   76,  709,  717,  264,  478,
- /*  2490 */   339,  556,   14,  479, 1674,  557,  485,  388,   88, 1852,
- /*  2500 */  2037, 1853,  390,  559, 2036,  389,  761,  490,  287,  578,
- /*  2510 */   216,  520,  521,  232,  199,  396,  404, 1965, 2051, 1966,
- /*  2520 */  1964, 1963,  217,  378,  277,  278,  218,   56, 1470,  345,
- /*  2530 */   570,  573, 2158, 2157,  519,   57,  288,  268,   41,   42,
- /*  2540 */   392,  579,  496,  580, 2155, 1549, 1550,  583,  584,  266,
- /*  2550 */  1546,  393,  290, 1631,  590,  394,  359,  629,  593,  599,
- /*  2560 */   267,  500,  184,  598,  360,   37,   19,   11,  117,   18,
- /*  2570 */   607,  296,  220,  234,   12,  298,  235,  236,  299,  188,
- /*  2580 */   304,  114,  301,  239,  305,  260,  405,  408, 1538,  633,
- /*  2590 */   635,  626,  627, 1537,  630,  631, 1532,  634,  636, 1542,
- /*  2600 */   516, 1530, 1468, 1443, 1441,  311,  317,  430, 1339,  420,
- /*  2610 */   240,  314,  424,  312,  194,   38, 1375,   20,  242,  438,
- /*  2620 */   223,  319,  243,  543, 1429,  545,   65,   66,   67,   68,
- /*  2630 */  1434,  321, 1428,  322,  207,  224,  225, 1419,   46,  249,
- /*  2640 */   226,  441,  245,  337, 1425,  686,  197,  124, 1475,  690,
- /*  2650 */   250,  694,  470,   70,  326,  699, 1201,   22,  702,   23,
- /*  2660 */   462, 1214,  379,  228,   72,  465,  336, 1413,  185,  350,
- /*  2670 */   229,   24,  352, 1408,  251,   80,   81,  112, 1500,   25,
- /*  2680 */    84,   26,  719,  208,  253,  724,  285,  725,  726,  728,
- /*  2690 */  1526,   27, 1512, 1516, 1514, 1520,    7,   82,   28, 1519,
- /*  2700 */    83, 1150, 1842, 1145, 1144, 1244, 1164,   85,  748,   29,
- /*  2710 */    30,   33,   34, 1641,  342,   32,  750,   90,   86, 1641,
- /*  2720 */  1332, 1238,   48, 1141, 1138,   49,  343, 1641, 1641, 1140,
- /*  2730 */  1641, 1641, 1641, 1641, 1641, 1641, 1129,  109, 1125,  344,
- /*  2740 */  1641, 1119, 1118,
+ /*     0 */   288, 1314, 1722, 1314, 1314, 1324,  108,  110, 1708,  360,
+ /*    10 */  1896,  711, 2142,  288, 1841, 1325, 1841, 1841,  674,  108,
+ /*    20 */   110, 1787,  101,  102,  520,   56, 1705, 1158, 1158, 1155,
+ /*    30 */  1140, 1149, 1149,  103,  103,  104,  104,  104,  104, 1590,
+ /*    40 */  1788, 1760, 1416,  360, 1896,  508, 1416,  709, 1702, 1591,
+ /*    50 */   485,  104,  104,  104,  104,  107,  101,  102,  520,   56,
+ /*    60 */  1788, 1158, 1158, 1155, 1140, 1149, 1149,  103,  103,  104,
+ /*    70 */   104,  104,  104, 2017,  496, 1311,  368,  360, 1896,  366,
+ /*    80 */  2083,  769,  689, 1892,  337,  288,  684,  284,  672,  540,
+ /*    90 */   646,  108,  110,  100,  100,  100,  100,  106,  106,  105,
+ /*   100 */   105,  105,   99,   98,  564,  752,  750, 1971, 1311,  100,
+ /*   110 */   100,  100,  100,  106,  106,  105,  105,  105,   99,   98,
+ /*   120 */   564, 1731,  486, 1758,  124, 1756,  617,  100,  100,  100,
+ /*   130 */   100,  106,  106,  105,  105,  105,   99,   98,  564,  752,
+ /*   140 */   750,  615, 1311, 1312, 1311,  674, 1159, 1159, 1156, 1141,
+ /*   150 */   101,  102,  520,   56, 1971, 1158, 1158, 1155, 1140, 1149,
+ /*   160 */  1149,  103,  103,  104,  104,  104,  104,  564,  329,  728,
+ /*   170 */   701,  698,  697,  752,  750, 1311, 1312, 1311, 1978, 1979,
+ /*   180 */   696,   80,  101,  102,  520,   56, 1314, 1158, 1158, 1155,
+ /*   190 */  1140, 1149, 1149,  103,  103,  104,  104,  104,  104, 1841,
+ /*   200 */  1970,  643,  644,  371,  101,  102,  520,   56,  617, 1158,
+ /*   210 */  1158, 1155, 1140, 1149, 1149,  103,  103,  104,  104,  104,
+ /*   220 */   104,  100,  100,  100,  100,  106,  106,  105,  105,  105,
+ /*   230 */    99,   98,  564,   63,  475, 1513,  511, 1513,  105,  105,
+ /*   240 */   105,   99,   98,  564, 1150, 2145,   79, 1970, 1968, 1966,
+ /*   250 */    19,  289,  730,  100,  100,  100,  100,  106,  106,  105,
+ /*   260 */   105,  105,   99,   98,  564,  265,  106,  106,  105,  105,
+ /*   270 */   105,   99,   98,  564, 2113,  100,  100,  100,  100,  106,
+ /*   280 */   106,  105,  105,  105,   99,   98,  564,  101,  102,  520,
+ /*   290 */    56, 2116, 1158, 1158, 1155, 1140, 1149, 1149,  103,  103,
+ /*   300 */   104,  104,  104,  104,  583,  360, 1896,  499,  360, 1896,
+ /*   310 */   501, 1380,  101,  102,  520,   56, 1379, 1158, 1158, 1155,
+ /*   320 */  1140, 1149, 1149,  103,  103,  104,  104,  104,  104, 1311,
+ /*   330 */   365,  360, 1896,  503,  360, 1896,  625,  101,  102,  520,
+ /*   340 */    56,  681, 1158, 1158, 1155, 1140, 1149, 1149,  103,  103,
+ /*   350 */   104,  104,  104,  104,  665,  451, 2112,  616,  100,  100,
+ /*   360 */   100,  100,  106,  106,  105,  105,  105,   99,   98,  564,
+ /*   370 */   100,  100,  100,  100,  106,  106,  105,  105,  105,   99,
+ /*   380 */    98,  564,  301,  100,  100,  100,  100,  106,  106,  105,
+ /*   390 */   105,  105,   99,   98,  564,  427, 1311, 1312, 1311,  533,
+ /*   400 */   415,  752,  750, 1705,  752,  750,  611,  303,  100,  100,
+ /*   410 */   100,  100,  106,  106,  105,  105,  105,   99,   98,  564,
+ /*   420 */   104,  104,  104,  104, 1287, 1703,  133,  752,  750, 1311,
+ /*   430 */   752,  750,   64,  101,  102,  520,   56,  768, 1158, 1158,
+ /*   440 */  1155, 1140, 1149, 1149,  103,  103,  104,  104,  104,  104,
+ /*   450 */   360, 1896,  375, 1405, 1311,  101,  102,  520,   56,  336,
+ /*   460 */  1158, 1158, 1155, 1140, 1149, 1149,  103,  103,  104,  104,
+ /*   470 */   104,  104,  411, 1767,  763, 1816, 1137, 1137,  100,  100,
+ /*   480 */   100,  100,  106,  106,  105,  105,  105,   99,   98,  564,
+ /*   490 */  1287,  409,  133,   99,   98,  564, 1311, 1312, 1311, 1990,
+ /*   500 */   360, 1896, 2002,  768,  100,  100,  100,  100,  106,  106,
+ /*   510 */   105,  105,  105,   99,   98,  564,  493, 1257,  674,  128,
+ /*   520 */  1765, 1311, 1312, 1311,  289,  730,  100,  100,  100,  100,
+ /*   530 */   106,  106,  105,  105,  105,   99,   98,  564, 2122, 2123,
+ /*   540 */  1414, 1816, 1711,  360, 1896, 1700,  752,  750,  462,  360,
+ /*   550 */  1896,  761,  484, 2125, 2037, 1311,  101,  102,  520,   56,
+ /*   560 */   272, 1158, 1158, 1155, 1140, 1149, 1149,  103,  103,  104,
+ /*   570 */   104,  104,  104,  360, 1896,  764,  374,  233, 1404,  101,
+ /*   580 */   102,  520,   56,  333, 1158, 1158, 1155, 1140, 1149, 1149,
+ /*   590 */   103,  103,  104,  104,  104,  104,  752,  750, 1311,  449,
+ /*   600 */   658,  436,  101,  102,  520,   56,  721, 1158, 1158, 1155,
+ /*   610 */  1140, 1149, 1149,  103,  103,  104,  104,  104,  104,  483,
+ /*   620 */  2039, 1490, 1311, 1312, 1311, 1311, 2144,  100,  100,  100,
+ /*   630 */   100,  106,  106,  105,  105,  105,   99,   98,  564,  752,
+ /*   640 */   750,  126, 1492,  567, 2014,  752,  750, 2014,  533,  702,
+ /*   650 */   100,  100,  100,  100,  106,  106,  105,  105,  105,   99,
+ /*   660 */    98,  564,  525,  665,  451, 1311, 1312, 1311,  117,  752,
+ /*   670 */   750,   45, 1192,  100,  100,  100,  100,  106,  106,  105,
+ /*   680 */   105,  105,   99,   98,  564,    6,  536,  357, 1896, 1714,
+ /*   690 */   719, 2031, 1311, 1312, 1311, 1184,  101,  102,  520,   56,
+ /*   700 */  1837, 1158, 1158, 1155, 1140, 1149, 1149,  103,  103,  104,
+ /*   710 */   104,  104,  104, 1311, 1662, 2095, 1495,  722, 2024,  101,
+ /*   720 */   102,  520,   56, 1713, 1158, 1158, 1155, 1140, 1149, 1149,
+ /*   730 */   103,  103,  104,  104,  104,  104,  767,  495, 1311, 1494,
+ /*   740 */  1978, 1979,  101,  102,  520,   56,  760, 1158, 1158, 1155,
+ /*   750 */  1140, 1149, 1149,  103,  103,  104,  104,  104,  104,  288,
+ /*   760 */   393, 1767, 1419, 1419,  686,  108,  110,  100,  100,  100,
+ /*   770 */   100,  106,  106,  105,  105,  105,   99,   98,  564,    6,
+ /*   780 */  1311, 1312, 1311,  752,  750, 2032,  248, 2122, 2123,  212,
+ /*   790 */   100,  100,  100,  100,  106,  106,  105,  105,  105,   99,
+ /*   800 */    98,  564, 2124,  604,  493, 1311, 1312, 1311, 1766,  752,
+ /*   810 */   750,  249, 1526,  100,  100,  100,  100,  106,  106,  105,
+ /*   820 */   105,  105,   99,   98,  564,  494, 2050, 1287, 2100,  172,
+ /*   830 */   536,  712,  479, 1311, 1767, 1306,  101,  102,  520,   56,
+ /*   840 */   768, 1158, 1158, 1155, 1140, 1149, 1149,  103,  103,  104,
+ /*   850 */   104,  104,  104, 1311,  478, 1984,  618,  233,  409,  101,
+ /*   860 */   102,  520,   56,  489, 1158, 1158, 1155, 1140, 1149, 1149,
+ /*   870 */   103,  103,  104,  104,  104,  104,  355,  493, 1816,  284,
+ /*   880 */   130, 1765,  101,  102,  520,   56,  713, 1158, 1158, 1155,
+ /*   890 */  1140, 1149, 1149,  103,  103,  104,  104,  104,  104, 1748,
+ /*   900 */  1311, 1312, 1311, 1767,  550,  744,    5,  100,  100,  100,
+ /*   910 */   100,  106,  106,  105,  105,  105,   99,   98,  564,  286,
+ /*   920 */  1311, 1312, 1311,  358, 1896, 1633,    3, 1508, 1403, 1289,
+ /*   930 */   100,  100,  100,  100,  106,  106,  105,  105,  105,   99,
+ /*   940 */    98,  564,  734,  742, 1508, 2162,  493, 1508, 1311,  127,
+ /*   950 */  1765,  409,  760,  100,  100,  100,  100,  106,  106,  105,
+ /*   960 */   105,  105,   99,   98,  564,    6,  393,   89,   76,  714,
+ /*   970 */   731, 2031, 2099,  535, 1403, 1331,  101,  102,  520,   56,
+ /*   980 */   733, 1158, 1158, 1155, 1140, 1149, 1149,  103,  103,  104,
+ /*   990 */   104,  104,  104, 2143,   19, 1129,  203, 1767,  101,  102,
+ /*  1000 */   520,   56,  680, 1158, 1158, 1155, 1140, 1149, 1149,  103,
+ /*  1010 */   103,  104,  104,  104,  104, 1311, 1312, 1311,  532,  752,
+ /*  1020 */   750,  115, 1311,  101,  102,  520,   56,  715, 1158, 1158,
+ /*  1030 */  1155, 1140, 1149, 1149,  103,  103,  104,  104,  104,  104,
+ /*  1040 */   493, 1490,  680,  129, 1765, 1333,  676,  100,  100,  100,
+ /*  1050 */   100,  106,  106,  105,  105,  105,   99,   98,  564,  332,
+ /*  1060 */   331,  330, 1492, 1129, 2015, 1334, 1838, 2015,  207,  100,
+ /*  1070 */   100,  100,  100,  106,  106,  105,  105,  105,   99,   98,
+ /*  1080 */   564,  405,  259, 2095,   96,  664,  400,  370,  756, 1311,
+ /*  1090 */  1312, 1311, 1941,  267,  100,  100,  100,  100,  106,  106,
+ /*  1100 */   105,  105,  105,   99,   98,  564, 1332,  101,  109,  520,
+ /*  1110 */    56,  476, 1158, 1158, 1155, 1140, 1149, 1149,  103,  103,
+ /*  1120 */   104,  104,  104,  104,  102,  520,   56,  448, 1158, 1158,
+ /*  1130 */  1155, 1140, 1149, 1149,  103,  103,  104,  104,  104,  104,
+ /*  1140 */   520,   56,  409, 1158, 1158, 1155, 1140, 1149, 1149,  103,
+ /*  1150 */   103,  104,  104,  104,  104,  547,  329, 1508,  701,  698,
+ /*  1160 */   697,  356, 1476, 1311,  288,  674,  660,  641,  696, 1549,
+ /*  1170 */   108,  110, 1941,  458, 1508,  454,  721, 1508,  100,  100,
+ /*  1180 */   100,  100,  106,  106,  105,  105,  105,   99,   98,  564,
+ /*  1190 */   716,  494, 2050, 1314,  100,  100,  100,  100,  106,  106,
+ /*  1200 */   105,  105,  105,   99,   98,  564, 1841,  653,  190,  100,
+ /*  1210 */   100,  100,  100,  106,  106,  105,  105,  105,   99,   98,
+ /*  1220 */   564, 1640, 1130,  376,  537,  310, 1187,  417, 1549,  348,
+ /*  1230 */  1311, 1312, 1311,  608, 1470,  548,  296,  416,  117,  424,
+ /*  1240 */   460,  572,  310,  506,  417, 1601,  348, 1287, 1287,  172,
+ /*  1250 */   135,  746, 1549, 1999,  416,  541,  424,  541,  572, 1377,
+ /*  1260 */   768,  624,  189,  285,  360, 1896,  745,   60, 1941, 1287,
+ /*  1270 */  1257,  131,  265,  239, 1355,  311, 1319,  505,  421, 1357,
+ /*  1280 */    10,  117,  768,  423,  194,  680,  524,  225, 2025, 1287,
+ /*  1290 */   116,  133,  311, 1187, 1316,  421, 1315, 1317, 1816, 1816,
+ /*  1300 */   423,  194,  768,  652,  225, 1356, 1287,  116,  135,  309,
+ /*  1310 */   433, 1317,  263,  488,  603, 1287,  760,  179,  534,  624,
+ /*  1320 */  1816,    9,   44,   12,  541,  744,  309, 1377,  768,  386,
+ /*  1330 */   393,  549,   15, 1115, 2055, 1941,  204, 1317, 1318,  682,
+ /*  1340 */  1816, 1638,    1, 1642,  775,  774, 1646, 1926,  224,  663,
+ /*  1350 */  1115, 1319,  449, 2154, 1287, 1311,  134, 1816, 1924,  760,
+ /*  1360 */   752,  750,  360, 1896, 1894,  224, 1816,  768,  760, 1316,
+ /*  1370 */   377, 1315, 1317,  393,  740,  519, 1508,  648,  713,  264,
+ /*  1380 */   424,  693,  393, 1941,  333,  760, 1317,  364,  382,  771,
+ /*  1390 */   201,  772,  519, 1508,  648,  489, 1508,  424,  685,  393,
+ /*  1400 */   739, 1314,   93,  724,  364, 1816,  318, 2109,  619, 1519,
+ /*  1410 */   577, 1349, 1317, 1318, 1841,  575, 1650,  738,  570, 2037,
+ /*  1420 */   601,  205, 1311, 1312, 1311, 1380, 1287,  577,   52,  732,
+ /*  1430 */  1379,  542,  575,  757, 2120,  607,  559,  601, 2053,  768,
+ /*  1440 */  1749,  379, 1519,  615, 1314, 1747,  556,  117, 1222,  771,
+ /*  1450 */   760,  516, 1878,  526,  642,    2, 1646, 1841,  752,  750,
+ /*  1460 */   578,  714,   93,  525,  393, 2109,  620,    8, 1319, 1210,
+ /*  1470 */   654,  670,  360, 1896, 1894,   95,   95, 1816,  570, 1314,
+ /*  1480 */   265, 1796, 1287,   94,  135,  570,  758,  570, 1315, 1317,
+ /*  1490 */     6,    4, 1841,  757,  576,  624, 2029, 1550,  382, 1648,
+ /*  1500 */   201,  465,  765, 1317, 2089,  602,   34,  705, 1287, 1287,
+ /*  1510 */   134,  172,  736,  743,  274, 1311,  318,  735, 1211,  587,
+ /*  1520 */  2151,  768,  768, 1891, 1287,  760,  131,  199, 1319, 1317,
+ /*  1530 */  1318, 1320, 1311, 1816, 1541,   95,   95,  768,  428,  393,
+ /*  1540 */   430,  494, 2050,   94,    6,  570,  758,  570, 1315, 1317,
+ /*  1550 */  2030,    4, 1377,  310,  555,  417, 1550,  348, 1893, 1816,
+ /*  1560 */  1816,  678,  765, 1317,  224,  416,   34,  424,  752,  750,
+ /*  1570 */   578, 1484,  566,  565,  497, 1816, 1641,  775,  774, 1646,
+ /*  1580 */  1550, 1444, 1311, 1312, 1311, 1448, 1448,  744, 1333, 1317,
+ /*  1590 */  1318, 1320,  282, 2115,  614,  360, 1896, 1894,  286, 1311,
+ /*  1600 */  1312, 1311,  553,  311,  353,  431,  421, 1403, 1334, 1446,
+ /*  1610 */   589,  423,  194,  590,  704,  225, 1445, 1128,  116, 1314,
+ /*  1620 */  1377,  382,   77,  201,  494, 2050,  593,  771,  429,  204,
+ /*  1630 */  2151, 1261, 1841, 1287,  552,  145,  601,  309,   61,  318,
+ /*  1640 */    93, 2110,    6,  369,  679, 1262,  768,  466, 2028, 1332,
+ /*  1650 */   360, 1896,  766, 1403, 1796,  474,  570,   41, 2089,  363,
+ /*  1660 */  1314,   48,  650,  335,  351,  707,  469,  706,  334,    6,
+ /*  1670 */   606,  757,   22, 1841,  465, 2027,  224,  770,  526,  500,
+ /*  1680 */  1508, 1287, 1735,  134, 1816, 1128,  515,  514,    2, 2121,
+ /*  1690 */   736,  752,  750,  578,  768,  737,  760, 1508, 1873, 1287,
+ /*  1700 */  1508,   52,   75,  519,  545,  648, 1319,  771,  424,   84,
+ /*  1710 */   393,  747,  768,   95,   95,  364,  582,  586, 1314,  282,
+ /*  1720 */    93,   94,  597,  570,  758,  570, 1315, 1317,  275,    4,
+ /*  1730 */  1201, 1841, 1816, 1495,  595,  596,  570,   84,  577, 1872,
+ /*  1740 */   765, 1317, 1324,  575,   34,  742,  752,  750,  601,   86,
+ /*  1750 */  1816,  757, 1325, 2151,  495,  592, 1491,  527,  234, 1287,
+ /*  1760 */  1287,  172,  134,  569, 1314,  656,  517, 1317, 1318, 1320,
+ /*  1770 */   736,   76,  768,  768, 1734,  735, 1287, 1841,   52,  771,
+ /*  1780 */   666,  551, 1287, 1287,   52,  172, 1319,  378,  446,  768,
+ /*  1790 */   657,  517,   93,   95,   95,  768,  768,  647,  667,  517,
+ /*  1800 */  1287,   94,  183,  570,  758,  570, 1315, 1317,  570,    4,
+ /*  1810 */  1816, 1816, 1287,  768,   54,  771, 1314,  671,  517, 1630,
+ /*  1820 */   765, 1317,  588,  757,   34,  723, 1733, 1816,   93, 1841,
+ /*  1830 */   715, 2089,  612, 1816, 1816,  387,  517,  744,  295,   97,
+ /*  1840 */  1287,   91,   52,  689,  570,  256,  359, 1317, 1318, 1320,
+ /*  1850 */  1870, 1816, 1839,  768, 1558, 1559,   66,  271, 1319,  757,
+ /*  1860 */  1373,  717,  297, 1816,  299,   95,   95,  403, 1542,  275,
+ /*  1870 */   397,  630, 1287,   94,  172,  570,  758,  570, 1315, 1317,
+ /*  1880 */   399,    4,  113,  222, 1287,  768,   52,  771,  401,  257,
+ /*  1890 */   610, 1816,  765, 1317, 1319, 1871,   34,  768, 2139,  668,
+ /*  1900 */    55,   95,   95,  308,  306, 1576,  305,  372,  240,   94,
+ /*  1910 */  2090,  570,  758,  570, 1315, 1317,  570,    4, 2093, 1317,
+ /*  1920 */  1318, 1320,  543, 1816,  771, 1287,  293,  170,  765, 1317,
+ /*  1930 */   754,  757,   34, 1208, 2094, 1816, 1314,   93,  768, 1287,
+ /*  1940 */  1574,   52, 1209,  307,  741,  294,  566,  565,  491, 1841,
+ /*  1950 */   388, 1314,  768,  570,  605, 1317, 1318, 1320,  254, 1448,
+ /*  1960 */  1448,  112, 2044,  291, 1841, 1195, 1319, 1538,  757,  441,
+ /*  1970 */   630, 2146,   84,   95,   95, 1314, 1816,  315,  755,  317,
+ /*  1980 */   473,   94,  748,  570,  758,  570, 1315, 1317, 1841,    4,
+ /*  1990 */  1816, 2088, 1287,   24,  172, 1287,  771,  172, 2111,  472,
+ /*  2000 */   765, 1317,  753, 1319,   34,  768, 1327, 1328,  768,   93,
+ /*  2010 */    95,   95, 1372,  447, 2106, 1864,   84, 1216,   94, 2098,
+ /*  2020 */   570,  758,  570, 1315, 1317,  570,    4, 1317, 1318, 1320,
+ /*  2030 */  1904,  621, 1278, 1195, 1287,  339,  172,  765, 1317,  673,
+ /*  2040 */   757,   34,  339, 1816, 2097, 1241, 1816,  768, 1217, 1248,
+ /*  2050 */  1287, 1321,  172,  675,  689, 1287,  339,   52, 2096,  694,
+ /*  2060 */   568, 1869,  343,  768, 1317, 1318, 1320,  414,  768,  418,
+ /*  2070 */   561, 1449, 1449,  562, 1287, 1319,  150,  573, 1287,  425,
+ /*  2080 */   151, 1408,   95,   95,  339, 1816,  463,  768,  419,   84,
+ /*  2090 */    94,  768,  570,  758,  570, 1315, 1317, 1244,    4,  420,
+ /*  2100 */   343, 1816, 1287, 1888,  152, 1287, 1816,  153, 1480,  765,
+ /*  2110 */  1317,   86,  563,   34, 1287,  768,  154, 1248,  768, 1321,
+ /*  2120 */  1479, 2164, 1287,   86,  155, 1816,  649,  768,  389, 1816,
+ /*  2130 */  1287, 1478,   53, 1794,   86,  768, 1317, 1318, 1320, 1287,
+ /*  2140 */  1793,  136, 1287,  768,  137, 1287, 1126,  156, 1287,  206,
+ /*  2150 */   157,  213,  768, 1816,   84,  768, 1816, 1287,  768,  158,
+ /*  2160 */   655,  768, 1447, 1447, 2013, 1816, 1287,  439,  159, 1287,
+ /*  2170 */   768,  160,  661, 1816,  773,  208, 1287,  442,  138,  768,
+ /*  2180 */  1959, 1816,  768,  690, 1674, 1957,  278,  453, 1314,  768,
+ /*  2190 */  1816,  349,  457, 1816,  459,  461, 1816, 1752, 1287, 1816,
+ /*  2200 */   139, 1841, 1287, 1287,  140,  141, 1732,  383, 1816,  468,
+ /*  2210 */  1287,  768,  161, 1314, 1710,  768,  768, 1816,  214, 1704,
+ /*  2220 */  1816, 1938, 1287,  768,  162, 1940, 1841, 1816,  384,  490,
+ /*  2230 */    17, 1287, 1661,  163, 1287,  768,  164, 1287, 1287,  165,
+ /*  2240 */   132,  385,  530, 1899,  768,   11, 2138,  768,  640, 1816,
+ /*  2250 */   768,  768, 1782, 1816, 1816,  435, 1287,  367,  142,  450,
+ /*  2260 */   198, 1816,  444, 1287,  438,  143,  445,  689, 1287,  768,
+ /*  2270 */    51,  699,  373, 1816, 1868, 1810,  768, 1287, 1287,  144,
+ /*  2280 */   166,  768, 1816,  283, 1809, 1816,  509, 1731, 1816, 1816,
+ /*  2290 */   768,  768,  689, 1287, 1697,  177, 1287,  471,  178, 1867,
+ /*  2300 */  1287,  482,  167, 1287,  677,  146,  768, 1816, 1287,  768,
+ /*  2310 */   168, 1773, 1774,  768, 1816,  260,  768, 1929, 1287, 1816,
+ /*  2320 */   147,  768, 1287, 1287,  174,  217, 1930,  759, 1816, 1816,
+ /*  2330 */   261,  768, 1928, 1927,  276,  768,  768, 1287, 1632,  218,
+ /*  2340 */  1287, 1543,  169, 1287, 1816,  148,  412, 1816, 1314, 1553,
+ /*  2350 */   768, 1816,  622,  768, 1816, 1287,  768,  215, 1287, 1816,
+ /*  2360 */   216, 1841,  598, 1287,  236,  185,  529,  623,  768, 1816,
+ /*  2370 */  1287,  768,  173, 1816, 1816,  192,  768,  531,  277, 1287,
+ /*  2380 */   342,  175, 1287,  768,  180,  504,  638,  408, 1816,  639,
+ /*  2390 */    61, 1816,  768, 2107, 1816,  768, 2085, 1991, 1458, 2084,
+ /*  2400 */   629,  633, 1287, 1287,  184,  209, 1816,  528,  626, 1816,
+ /*  2410 */   402, 1287, 2108,  186, 1816,  768,  768,  538, 1287,  404,
+ /*  2420 */   181, 1816, 2136, 1287,  768,  176,  613,  689,  413,   62,
+ /*  2430 */  1816,  768,   65, 1816,  456, 1287,  768,  182, 1983, 1361,
+ /*  2440 */  1981,  539,  312,  193, 1287,  195,  171, 1287,  768,  149,
+ /*  2450 */   645, 1880, 1879, 1816, 1816, 1349,  651,  768,  119,  196,
+ /*  2460 */   768,  120, 1816,  273,  121,  122,  123, 1783,  246, 1816,
+ /*  2470 */    40,   81,  742,  434, 1816, 1781,  230,  243, 1780,  437,
+ /*  2480 */   659,  692,   77, 1997,  320,  662, 1816,  322, 1812,  507,
+ /*  2490 */   669, 1784,   46, 1811,  510, 1816,  250,  258, 1816,  683,
+ /*  2500 */   452,  325,   71, 1943,  688,  350,  455,  326, 1698,  327,
+ /*  2510 */   708, 1755,  512, 1754, 1753,  554,   73, 1742, 1725,  513,
+ /*  2520 */  1201, 1724, 1719, 1718,  470, 1741, 1717, 1716,   18,  710,
+ /*  2530 */   340, 1898,  477,   78,  718, 1897,  341, 2035,  266,  480,
+ /*  2540 */    16,  557, 2034, 1672,  481,  487,  558,  560, 1850,   90,
+ /*  2550 */   289, 1851,  392,  390,  492,  391,  762,  579,  522, 2049,
+ /*  2560 */   235,  523,  398,  406, 1963,  219, 1964, 1962, 1961,  220,
+ /*  2570 */   202,  380,  221,  279, 2156,   42,  280, 2155,   43, 1468,
+ /*  2580 */    57,  571,  521,  347, 2153,  574,   58,  290,  270,  394,
+ /*  2590 */   498,  580,  581, 1547, 1548,  584,  585,  268, 1544,  395,
+ /*  2600 */   292, 1629,  591,  396,  361,  630,  594,  600,  269,  502,
+ /*  2610 */   187,  599,  362,   38,   22,   13,  118,  298,  223,   21,
+ /*  2620 */   300,  609,  237,   14,   59,  238,  302,  191,  307,   20,
+ /*  2630 */   304,  241,  407,  262,  281,  410,  634,  636, 1536,  627,
+ /*  2640 */   628, 1535,  631,  632, 1530,  635,  518,  637, 1540, 1528,
+ /*  2650 */  1466, 1441, 1439,  313,  319,   23,  422,   39,  242, 1337,
+ /*  2660 */   316,  426,  197,  314, 1373,  544,  244,  546,  321, 1427,
+ /*  2670 */    67,  226,  440,   68,  432,  245,   69,   70, 1432,  323,
+ /*  2680 */  1426,  210,  324,   47,  227, 1417,  251,  443,  228, 1423,
+ /*  2690 */   247,  339,  687,  200,  229,  125, 1473,  252,  691,  695,
+ /*  2700 */   472,   72,  328,  700, 1199,   25,  703,   26,  464, 1212,
+ /*  2710 */   381,  231,   74,  338, 1411,  467,  188,  352,  232,   27,
+ /*  2720 */   354,   86,  253,   82, 1406, 1498,  114,   83,  720,  725,
+ /*  2730 */   255,  211,  726,  287,  727,  729,   28,   29,   30, 1524,
+ /*  2740 */  1510, 1514, 1512,    7, 1518,   84,   31, 1517,   85, 1242,
+ /*  2750 */  1148, 1162, 1143, 1142,   32,   87,   36,   33,  749,   88,
+ /*  2760 */    37, 1639, 1330,  751,   92, 1236,  344,   35, 1840,   49,
+ /*  2770 */    50, 1639, 1136, 1139, 1639, 1138, 1639, 1639, 1639, 1639,
+ /*  2780 */   345, 1639, 1639, 1127, 1123,  346, 1639, 1639, 1639,  111,
+ /*  2790 */  1117, 1116,
 };
 static const YYCODETYPE yy_lookahead[] = {
  /*     0 */   227,  212,  243,  212,  212,    5,  233,  234,  249,  229,
  /*    10 */   230,  231,  382,  227,  225,   15,  225,  225,  225,  233,
  /*    20 */   234,  267,   22,   23,   24,   25,  225,   27,   28,   29,
  /*    30 */    30,   31,   32,   33,   34,   35,   36,   37,   38,    5,
- /*    40 */   286,  267,  225,  229,  230,  231,   40,  246,  247,   15,
+ /*    40 */   286,  267,    3,  229,  230,  231,    7,  246,  247,   15,
  /*    50 */   264,   35,   36,   37,   38,   39,   22,   23,   24,   25,
  /*    60 */   286,   27,   28,   29,   30,   31,   32,   33,   34,   35,
  /*    70 */    36,   37,   38,  330,  331,   40,  283,  229,  230,  231,
- /*    80 */   291,  221,  291,  291,  304,  227,   40,  307,  274,  298,
+ /*    80 */   291,  221,  291,  291,  304,  227,   47,  307,  274,  298,
  /*    90 */   299,  233,  234,   93,   94,   95,   96,   97,   98,   99,
  /*   100 */   100,  101,  102,  103,  104,  325,  326,  225,   40,   93,
  /*   110 */    94,   95,   96,   97,   98,   99,  100,  101,  102,  103,
- /*   120 */   104,  241,  264,  243,  225,  245,  218,   93,   94,   95,
+ /*   120 */   104,  241,  264,  243,   56,  245,  225,   93,   94,   95,
  /*   130 */    96,   97,   98,   99,  100,  101,  102,  103,  104,  325,
- /*   140 */   326,  324,  107,  108,  109,   99,   27,   28,   29,   30,
+ /*   140 */   326,  225,  107,  108,  109,  225,   27,   28,   29,   30,
  /*   150 */    22,   23,   24,   25,  225,   27,   28,   29,   30,   31,
- /*   160 */    32,   33,   34,   35,   36,   37,   38,   99,  133,  123,
+ /*   160 */    32,   33,   34,   35,   36,   37,   38,  104,  133,   86,
  /*   170 */   135,  136,  137,  325,  326,  107,  108,  109,  318,  319,
  /*   180 */   145,   53,   22,   23,   24,   25,  212,   27,   28,   29,
  /*   190 */    30,   31,   32,   33,   34,   35,   36,   37,   38,  225,
- /*   200 */   318,  319,  320,  104,   22,   23,   24,   25,  225,   27,
+ /*   200 */   318,  319,  320,  283,   22,   23,   24,   25,  225,   27,
  /*   210 */    28,   29,   30,   31,   32,   33,   34,   35,   36,   37,
  /*   220 */    38,   93,   94,   95,   96,   97,   98,   99,  100,  101,
  /*   230 */   102,  103,  104,   51,  260,   75,  262,   77,   99,  100,
- /*   240 */   101,  102,  103,  104,  125,   40,  118,  318,  319,  320,
- /*   250 */   225,  343,  344,   93,   94,   95,   96,   97,   98,   99,
+ /*   240 */   101,  102,  103,  104,  125,  225,  118,  318,  319,  320,
+ /*   250 */   224,  168,  169,   93,   94,   95,   96,   97,   98,   99,
  /*   260 */   100,  101,  102,  103,  104,  291,   97,   98,   99,  100,
- /*   270 */   101,  102,  103,  104,  375,   93,   94,   95,   96,   97,
+ /*   270 */   101,  102,  103,  104,  373,   93,   94,   95,   96,   97,
  /*   280 */    98,   99,  100,  101,  102,  103,  104,   22,   23,   24,
- /*   290 */    25,  266,   27,   28,   29,   30,   31,   32,   33,   34,
- /*   300 */    35,   36,   37,   38,  263,  229,  230,  231,  225,  116,
- /*   310 */   225,  118,   22,   23,   24,   25,  225,   27,   28,   29,
- /*   320 */    30,   31,   32,   33,   34,   35,   36,   37,   38,  229,
- /*   330 */   230,  231,  229,  230,  231,  141,  142,   22,   23,   24,
- /*   340 */    25,   40,   27,   28,   29,   30,   31,   32,   33,   34,
- /*   350 */    35,   36,   37,   38,   40,  263,  373,  374,   93,   94,
+ /*   290 */    25,  375,   27,   28,   29,   30,   31,   32,   33,   34,
+ /*   300 */    35,   36,   37,   38,   40,  229,  230,  231,  229,  230,
+ /*   310 */   231,  121,   22,   23,   24,   25,  126,   27,   28,   29,
+ /*   320 */    30,   31,   32,   33,   34,   35,   36,   37,   38,   40,
+ /*   330 */    89,  229,  230,  231,  229,  230,  231,   22,   23,   24,
+ /*   340 */    25,  315,   27,   28,   29,   30,   31,   32,   33,   34,
+ /*   350 */    35,   36,   37,   38,  141,  142,  373,  374,   93,   94,
  /*   360 */    95,   96,   97,   98,   99,  100,  101,  102,  103,  104,
  /*   370 */    93,   94,   95,   96,   97,   98,   99,  100,  101,  102,
  /*   380 */   103,  104,  117,   93,   94,   95,   96,   97,   98,   99,
- /*   390 */   100,  101,  102,  103,  104,  224,  168,  169,  227,   86,
- /*   400 */    99,  325,  326,  225,  233,  234,  225,  117,   93,   94,
+ /*   390 */   100,  101,  102,  103,  104,  154,  107,  108,  109,  225,
+ /*   400 */   225,  325,  326,  225,  325,  326,  386,  117,   93,   94,
  /*   410 */    95,   96,   97,   98,   99,  100,  101,  102,  103,  104,
- /*   420 */   147,  107,  108,  109,  123,  325,  326,  113,  325,  326,
- /*   430 */    22,   23,   24,   25,  161,   27,   28,   29,   30,   31,
- /*   440 */    32,   33,   34,   35,   36,   37,   38,  364,  365,  364,
- /*   450 */   365,  229,  230,  231,  371,  263,  371,  372,  367,  368,
- /*   460 */    22,   23,   24,   25,  149,   27,   28,   29,   30,   31,
- /*   470 */    32,   33,   34,   35,   36,   37,   38,   40,  229,  230,
- /*   480 */   225,  168,  169,   22,   23,   24,   25,  225,   27,   28,
- /*   490 */    29,   30,   31,   32,   33,   34,   35,   36,   37,   38,
- /*   500 */   225,   93,   94,   95,   96,   97,   98,   99,  100,  101,
- /*   510 */   102,  103,  104,  225,  333,  337,  212,  251,  214,  338,
- /*   520 */   339,  225,  333,  115,  229,  230,  231,   40,  339,  225,
- /*   530 */    40,   93,   94,   95,   96,   97,   98,   99,  100,  101,
- /*   540 */   102,  103,  104,   56,  107,  108,  109,  325,  326,  225,
- /*   550 */   113,   61,  225,  115,   93,   94,   95,   96,   97,   98,
- /*   560 */    99,  100,  101,  102,  103,  104,   76,  263,   78,  229,
- /*   570 */   230,   81,  225,  142,  325,  326,  115,   22,   23,   24,
- /*   580 */    25,  150,   27,   28,   29,   30,   31,   32,   33,   34,
- /*   590 */    35,   36,   37,   38,  107,  108,  109,  107,  108,  109,
- /*   600 */    22,   23,   24,   25,  114,   27,   28,   29,   30,   31,
- /*   610 */    32,   33,   34,   35,   36,   37,   38,  229,  230,  231,
- /*   620 */   325,  326,  360,   22,   23,   24,   25,  225,   27,   28,
- /*   630 */    29,   30,   31,   32,   33,   34,   35,   36,   37,   38,
- /*   640 */   229,  230,  231,   40,  340,  225,  342,  385,   93,   94,
- /*   650 */    95,   96,   97,   98,   99,  100,  101,  102,  103,  104,
- /*   660 */   364,  365,  306,  375,  376,  325,  326,  371,  372,  225,
- /*   670 */   115,   93,   94,   95,   96,   97,   98,   99,  100,  101,
- /*   680 */   102,  103,  104,  336,  337,  283,  229,  230,  231,   69,
- /*   690 */   225,  364,  365,  115,   93,   94,   95,   96,   97,   98,
- /*   700 */    99,  100,  101,  102,  103,  104,  379,  380,  212,  120,
- /*   710 */   214,  122,  123,  325,  326,  118,  115,   22,   23,   24,
- /*   720 */    25,  225,   27,   28,   29,   30,   31,   32,   33,   34,
- /*   730 */    35,   36,   37,   38,   40,  132,  325,  326,  225,   67,
- /*   740 */    22,   23,   24,   25,  147,   27,   28,   29,   30,   31,
- /*   750 */    32,   33,   34,   35,   36,   37,   38,   40,  161,  263,
- /*   760 */   229,  230,  231,   22,   23,   24,   25,  147,   27,   28,
- /*   770 */    29,   30,   31,   32,   33,   34,   35,   36,   37,   38,
- /*   780 */    40,  161,  325,  326,   40,  225,  225,   70,   93,   94,
- /*   790 */    95,   96,   97,   98,   99,  100,  101,  102,  103,  104,
- /*   800 */    56,  107,  108,  109,  132,   58,  386,  113,  364,  365,
- /*   810 */   115,   93,   94,   95,   96,   97,   98,   99,  100,  101,
- /*   820 */   102,  103,  104,  379,  107,  108,  109,  155,  268,  364,
- /*   830 */   225,  271,  272,  115,   93,   94,   95,   96,   97,   98,
- /*   840 */    99,  100,  101,  102,  103,  104,  174,  107,  108,  109,
- /*   850 */   225,  107,  108,  109,  227,  225,  325,  326,  362,  363,
- /*   860 */   233,  234,  225,   40,  192,  225,  225,   22,   23,   24,
- /*   870 */    25,  130,   27,   28,   29,   30,   31,   32,   33,   34,
- /*   880 */    35,   36,   37,   38,   40,  280,  373,  140,  141,  142,
- /*   890 */    22,   23,   24,   25,  212,   27,   28,   29,   30,   31,
- /*   900 */    32,   33,   34,   35,   36,   37,   38,  225,  268,  224,
- /*   910 */    40,  271,  272,   22,   23,   24,   25,  280,   27,   28,
- /*   920 */    29,   30,   31,   32,   33,   34,   35,   36,   37,   38,
- /*   930 */   107,  108,  109,   92,  230,  310,  113,   40,   93,   94,
- /*   940 */    95,   96,   97,   98,   99,  100,  101,  102,  103,  104,
- /*   950 */   323,  107,  108,  109,  113,  304,  115,  113,  307,  118,
- /*   960 */   115,   93,   94,   95,   96,   97,   98,   99,  100,  101,
- /*   970 */   102,  103,  104,  291,  102,  103,  104,  107,  108,  109,
- /*   980 */   298,  225,   61,  113,   93,   94,   95,   96,   97,   98,
- /*   990 */    99,  100,  101,  102,  103,  104,   99,   76,  130,   78,
- /*  1000 */   315,   69,   81,  221,  107,  108,  109,  366,  117,   22,
- /*  1010 */    23,   24,   25,  212,   27,   28,   29,   30,   31,   32,
- /*  1020 */    33,   34,   35,   36,   37,   38,  225,  225,   40,  325,
- /*  1030 */   326,   22,   23,   24,   25,  114,   27,   28,   29,   30,
- /*  1040 */    31,   32,   33,   34,   35,   36,   37,   38,   23,   24,
- /*  1050 */    25,  225,   27,   28,   29,   30,   31,   32,   33,   34,
- /*  1060 */    35,   36,   37,   38,   24,   25,  134,   27,   28,   29,
- /*  1070 */    30,   31,   32,   33,   34,   35,   36,   37,   38,  147,
- /*  1080 */    93,   94,   95,   96,   97,   98,   99,  100,  101,  102,
- /*  1090 */   103,  104,  291,  161,  268,  107,  108,  109,  272,  298,
- /*  1100 */   318,  319,   93,   94,   95,   96,   97,   98,   99,  100,
- /*  1110 */   101,  102,  103,  104,  218,  225,   40,  225,   93,   94,
- /*  1120 */    95,   96,   97,   98,   99,  100,  101,  102,  103,  104,
- /*  1130 */    24,  225,   89,   93,   94,   95,   96,   97,   98,   99,
- /*  1140 */   100,  101,  102,  103,  104,    0,  140,  141,  142,    4,
- /*  1150 */    40,    6,  164,    8,  212,  225,  214,  114,   97,   98,
- /*  1160 */   117,   16,  360,   18,    5,   20,    4,  225,    6,  126,
- /*  1170 */     8,  110,  111,  283,   15,   90,  212,  247,   16,  109,
- /*  1180 */    18,   40,   20,  107,  108,  109,  143,  276,  118,  225,
- /*  1190 */   212,  148,  214,  108,  225,  110,  111,  154,  287,   54,
- /*  1200 */    90,  225,   57,  225,  161,  263,  225,   62,   63,   40,
- /*  1210 */   125,   66,  106,  107,   69,  225,   54,  107,  108,   57,
- /*  1220 */   110,  111,  146,  225,   62,   63,  262,  225,   66,  224,
- /*  1230 */   212,   69,  214,   88,  164,  125,  151,  152,  195,  343,
- /*  1240 */   344,  263,  199,  225,   10,  202,  212,  204,   27,  108,
- /*  1250 */    88,  212,  258,  214,  113,  291,    3,  112,  117,  225,
- /*  1260 */     7,  151,  152,  225,  225,  208,  209,  210,  211,  212,
- /*  1270 */   213,  165,  127,  283,  112,   64,   24,  108,  212,   68,
- /*  1280 */   214,  263,   48,  341,  342,  225,  229,  230,  231,  127,
- /*  1290 */   212,  225,  147,   59,  212,  212,  214,  214,  216,  154,
- /*  1300 */    47,  156,  263,  225,  159,  311,  161,  225,  225,  147,
- /*  1310 */    92,  166,  255,   11,  257,  321,  154,  312,  156,  225,
- /*  1320 */   315,  159,   65,  161,   67,  291,   24,  106,  166,  263,
- /*  1330 */   273,  113,  298,  115,  189,  366,  212,  225,  214,  194,
- /*  1340 */   216,  360,   40,  367,  199,  263,  263,  136,  288,  225,
- /*  1350 */    61,  189,  212,   58,  214,  212,  194,   55,  340,  107,
- /*  1360 */   342,  199,  360,  225,   69,  225,  155,   78,  225,  291,
- /*  1370 */    81,   69,  290,   11,  280,  225,  298,  143,  211,  322,
- /*  1380 */   213,   22,  325,  326,  327,   24,   24,  263,  212,  132,
- /*  1390 */   214,   29,   90,  225,  251,  252,  229,  230,  231,   97,
- /*  1400 */    98,  225,   40,  263,  266,  262,  212,  105,  214,  107,
- /*  1410 */   108,  109,  110,  111,  290,  113,  377,   55,  212,  225,
- /*  1420 */    14,  225,  255,  106,  257,   19,  124,  125,  362,  363,
- /*  1430 */   128,  225,  225,   18,  291,  140,   74,  225,  288,  263,
- /*  1440 */   273,   79,  147,   40,  387,  362,  363,  225,  212,  147,
- /*  1450 */   214,   45,   90,  151,  152,  153,  161,  263,  287,   97,
- /*  1460 */    98,  225,  133,  161,  135,  136,  137,  105,  107,  107,
- /*  1470 */   108,  109,  110,  111,  145,  113,  305,    4,  310,    6,
- /*  1480 */   225,    8,  165,  212,  290,  214,  124,  125,  217,   16,
- /*  1490 */   128,   18,  325,  326,  327,  288,  225,  291,  106,  263,
- /*  1500 */   210,  211,  212,  213,  298,  225,  225,   35,   36,   37,
- /*  1510 */    38,  108,  225,  151,  152,  153,  113,  377,  378,  229,
- /*  1520 */   230,  231,  310,  109,  212,  225,  290,   54,  281,  115,
- /*  1530 */    57,   65,  118,   67,  263,   62,   63,  225,  362,   66,
- /*  1540 */     1,  149,   69,  288,  225,  255,  127,  257,  189,  268,
- /*  1550 */   303,   11,  271,  272,  387,  268,  141,  142,  271,  272,
- /*  1560 */    21,   88,  225,  273,   24,   93,   94,   95,   96,   97,
- /*  1570 */    98,   99,  100,  101,  102,  103,  104,  212,  164,  214,
- /*  1580 */    40,   92,  217,   44,   24,   92,  242,   27,  288,  129,
- /*  1590 */   225,  131,  212,  333,  214,   55,  216,   58,  132,  339,
- /*  1600 */   127,   62,  113,  291,  115,  225,  113,  118,  115,  229,
- /*  1610 */   230,  231,  322,  218,   74,  325,  326,  327,  199,   79,
- /*  1620 */   147,  155,  212,  212,  214,  214,  216,  154,  263,  156,
- /*  1630 */    90,   11,  159,  118,  161,  225,  225,   97,   98,  166,
- /*  1640 */   229,  230,  231,  263,   24,  105,   40,  107,  108,  109,
- /*  1650 */   110,  111,  333,  113,  139,  189,  121,  338,  339,  356,
- /*  1660 */    40,  126,  189,  212,  124,  125,  106,  194,  128,   61,
- /*  1670 */   290,  225,  199,  263,  263,   55,  225,  387,  140,  141,
- /*  1680 */   142,  333,   40,  212,   40,  214,   78,  339,  217,   81,
- /*  1690 */   387,  151,  152,  153,   74,  225,  225,   99,  218,   79,
- /*  1700 */   290,  290,  333,   11,  144,  325,  326,  212,  339,  214,
- /*  1710 */    90,  276,  217,  107,  108,  109,   24,   97,   98,  121,
- /*  1720 */   225,  225,  287,  114,  126,  105,  118,  107,  108,  109,
- /*  1730 */   110,  111,   40,  113,  263,   41,  325,  326,  343,  344,
- /*  1740 */    11,   99,  291,    1,  124,  125,  142,   55,  128,  107,
- /*  1750 */   108,  109,  108,   24,  150,  212,  333,  214,  263,  225,
- /*  1760 */   217,  117,  339,   21,  212,  117,  214,  119,  225,   40,
- /*  1770 */   164,  151,  152,  153,  219,  220,  167,  225,  212,  212,
- /*  1780 */   214,  214,   90,  217,   55,  115,   44,  235,  118,   97,
- /*  1790 */    98,  225,  225,   34,  212,  219,  220,  105,  118,  107,
- /*  1800 */   108,  109,  110,  111,   62,  113,  263,  225,  212,  212,
- /*  1810 */   214,  214,   11,  217,  225,  263,  124,  125,  126,   90,
- /*  1820 */   128,  225,  225,  343,  344,   24,   97,   98,  148,  263,
- /*  1830 */   263,   97,   98,  212,  105,  214,  107,  108,  109,  110,
- /*  1840 */   111,   40,  113,  151,  152,  153,  225,  113,   11,  118,
- /*  1850 */    48,  157,  212,  124,  125,  126,   55,  128,  127,  263,
- /*  1860 */   263,   24,  212,   24,  214,  225,  212,  203,  214,  205,
- /*  1870 */   212,  217,  113,  291,  113,  225,   74,   40,  117,  225,
- /*  1880 */   151,  152,  153,  225,  263,   83,  225,  290,  212,  114,
- /*  1890 */   212,   90,   55,  118,  353,  354,  328,  329,   97,   98,
- /*  1900 */    99,  225,  212,  225,  347,  348,  105,  118,  107,  108,
- /*  1910 */   109,  110,  111,  263,  113,  225,  127,  263,  116,  212,
- /*  1920 */   212,  214,  214,   84,  225,  124,  125,   90,  117,  128,
- /*  1930 */   119,  291,  225,  225,   97,   98,  222,  223,  115,   40,
- /*  1940 */   290,  118,  105,  104,  107,  108,  109,  110,  111,  291,
- /*  1950 */   113,  225,  151,  152,  153,   89,  117,  222,  223,  222,
- /*  1960 */   223,  124,  125,  225,  125,  128,  212,  291,  214,  291,
- /*  1970 */   263,  263,  133,  134,  135,  136,  137,  138,  117,  225,
- /*  1980 */   119,  291,   40,  144,  222,  223,  222,  223,  151,  152,
- /*  1990 */   153,  212,  117,  214,  197,  198,   97,   98,  290,  225,
- /*  2000 */   212,  225,  214,   92,  225,  106,  107,  108,  109,  110,
- /*  2010 */   111,   42,  212,  225,  214,  225,  212,  263,  214,  212,
- /*  2020 */   154,  214,  212,  112,  214,  225,  212,  274,  214,  225,
- /*  2030 */   148,  149,  225,  134,  212,  225,  214,  225,  115,  225,
- /*  2040 */   141,  118,  263,  212,  290,  214,  212,  225,  214,  225,
- /*  2050 */   108,  263,  212,  212,  214,  214,  225,  225,  212,  225,
- /*  2060 */   214,  225,  117,  263,  119,  225,  225,  263,  193,  115,
- /*  2070 */   263,  225,  118,  263,  212,  115,  214,  263,  118,  212,
- /*  2080 */   115,  214,  113,  118,  225,  263,  115,  225,  212,  118,
- /*  2090 */   214,  125,  225,  212,  263,  214,  115,  263,  225,  118,
- /*  2100 */   212,  225,  214,  263,  263,  212,  225,  214,  115,  263,
- /*  2110 */   144,  118,  115,  225,   14,  118,  225,  125,  225,  212,
- /*  2120 */   115,  214,  212,  118,  214,  263,  134,  212,  115,  214,
- /*  2130 */   263,  118,  225,  225,  212,  225,  214,   72,   73,  263,
- /*  2140 */   225,  225,   40,  225,  263,   45,  212,  225,  214,  110,
- /*  2150 */   111,  263,  212,  212,  214,  214,  263,  225,  212,  225,
- /*  2160 */   214,  212,   24,  214,   40,  225,  225,  212,  225,  214,
- /*  2170 */   263,  225,  225,  263,  225,  212,  113,  214,  263,  212,
- /*  2180 */   225,  214,  119,  115,  225,  263,  118,  212,  225,  214,
- /*  2190 */   242,  115,  225,  115,  118,  225,  118,  263,  115,  115,
- /*  2200 */   225,  118,  118,  263,  263,  225,  212,  225,  214,  263,
- /*  2210 */   108,  212,  263,  214,  225,  212,  225,  214,  263,  225,
- /*  2220 */   212,  212,  214,  214,  225,   87,  263,  212,  225,  214,
- /*  2230 */   263,  225,  108,  225,  225,  212,  225,  214,  263,  212,
- /*  2240 */   225,  214,  212,  115,  214,  212,  118,  214,  225,  242,
- /*  2250 */   115,  115,  225,  118,  118,  225,  225,  263,  225,  110,
- /*  2260 */   111,  212,  263,  214,  114,  115,  263,  212,  212,  214,
- /*  2270 */   214,  263,  263,  225,  225,  225,  115,  225,  263,  118,
- /*  2280 */   225,  225,  115,  300,  225,  118,  263,  212,  335,  214,
- /*  2290 */   263,  225,  212,  263,  214,  225,  263,  313,  286,  355,
- /*  2300 */   225,  212,  238,  214,  294,  225,  308,  212,  212,  214,
- /*  2310 */   214,  226,  263,  212,  225,  214,  300,  300,  263,  263,
- /*  2320 */   225,  225,  212,  215,  214,  300,  225,  351,  300,  361,
- /*  2330 */   345,  381,  297,  289,  277,  225,  278,  284,  263,  277,
- /*  2340 */   316,  253,  316,  263,  239,  278,  264,  278,  241,  289,
- /*  2350 */   278,  305,  263,  256,  264,  284,  305,  264,  263,  263,
- /*  2360 */   281,  284,  281,  237,  263,   92,  305,  215,  389,   40,
- /*  2370 */   352,  113,  207,  263,  201,   58,  122,  348,  305,  358,
- /*  2380 */   117,  349,  228,  383,  383,  383,  119,   40,  346,  370,
- /*  2390 */   370,  369,  349,  346,  165,  359,  359,  146,   13,  228,
- /*  2400 */   228,   63,  348,  369,  317,  228,  160,  296,  317,  296,
- /*  2410 */   324,  295,  295,  295,   41,   91,  297,  297,  293,  149,
- /*  2420 */   293,  279,  293,  293,  350,  113,  285,  163,  282,  114,
- /*  2430 */    22,  275,  281,  228,   91,  282,  281,  259,  148,  228,
- /*  2440 */   259,  279,  279,  275,  275,  285,  289,  289,  289,  113,
- /*  2450 */   265,  228,  259,  289,  129,   43,  309,  314,  228,  259,
- /*  2460 */   228,  259,  265,  106,  248,  248,  248,   46,  244,  113,
- /*  2470 */   248,  265,  139,  254,  254,  239,  248,  244,  118,  248,
- /*  2480 */   228,  282,  248,  282,  281,  162,  261,  116,  302,  301,
- /*  2490 */    80,   71,  113,  289,  232,  104,  228,  270,  129,  292,
- /*  2500 */   334,  292,  236,  117,  334,  270,  269,  265,  168,  388,
- /*  2510 */   250,  332,  332,  329,  240,  384,  384,  224,  344,  224,
- /*  2520 */   224,  224,  250,  240,  238,  238,  250,  224,   49,  190,
- /*  2530 */    50,  189,  357,  357,  119,   34,   54,  113,  356,  356,
- /*  2540 */   117,  191,   40,  115,  357,   40,   40,   40,  118,  113,
- /*  2550 */    40,  113,  106,   40,  157,  113,  191,  118,  115,  200,
- /*  2560 */   113,  117,  113,   52,  196,    9,  118,    9,  118,  118,
- /*  2570 */   206,  118,   69,  118,  204,  119,   34,  118,  117,  113,
- /*  2580 */   118,  118,  117,  113,  117,  117,  115,   40,  119,   40,
- /*  2590 */    40,  119,  119,  119,  119,  119,  115,  119,  113,   40,
- /*  2600 */   189,   58,  112,  115,  115,  106,  165,  147,  124,  157,
- /*  2610 */   146,  117,  158,  155,  157,  132,  118,  113,  127,  132,
- /*  2620 */   143,  106,  127,   42,  112,   12,   34,   34,   34,   34,
- /*  2630 */   107,    9,  112,  119,    8,  143,  143,   52,  117,   52,
- /*  2640 */   143,  155,  146,  118,   60,   17,  119,  106,  124,   24,
- /*  2650 */   113,   51,  144,  113,  138,   51,   40,  113,   85,  113,
- /*  2660 */   115,    2,   51,   12,  113,  117,    9,  107,  115,  115,
- /*  2670 */   118,    9,  115,  164,  113,    9,  148,  113,  115,    9,
- /*  2680 */   118,    9,  117,  115,  118,  114,  119,  113,  116,  113,
- /*  2690 */   115,    9,   77,   60,   75,   60,   23,  118,    9,   82,
- /*  2700 */   118,  115,  119,  115,  115,   87,   18,  127,  118,  113,
- /*  2710 */   113,    9,    9,  390,  113,  113,  118,  118,  127,  390,
- /*  2720 */   115,  115,  113,  115,  121,  113,  119,  390,  390,  115,
- /*  2730 */   390,  390,  390,  390,  390,  390,  115,  113,  115,  119,
- /*  2740 */   390,  112,  112,  390,  390,  390,  390,  390,  390,  390,
- /*  2750 */   390,  390,  390,  390,  390,  390,  390,  390,  390,  390,
- /*  2760 */   390,  390,  390,  390,  390,  390,  390,  390,  390,  390,
- /*  2770 */   390,  390,  390,  390,  390,  390,  390,  390,  390,  390,
- /*  2780 */   390,  390,  390,  390,  390,  390,  390,  390,  390,  390,
- /*  2790 */   390,  390,  390,  390,  390,  390,  390,  390,  390,  390,
+ /*   420 */    35,   36,   37,   38,  212,  247,  214,  325,  326,   40,
+ /*   430 */   325,  326,  117,   22,   23,   24,   25,  225,   27,   28,
+ /*   440 */    29,   30,   31,   32,   33,   34,   35,   36,   37,   38,
+ /*   450 */   229,  230,  231,  164,   40,   22,   23,   24,   25,   70,
+ /*   460 */    27,   28,   29,   30,   31,   32,   33,   34,   35,   36,
+ /*   470 */    37,   38,   40,  225,  120,  263,  122,  123,   93,   94,
+ /*   480 */    95,   96,   97,   98,   99,  100,  101,  102,  103,  104,
+ /*   490 */   212,  225,  214,  102,  103,  104,  107,  108,  109,  324,
+ /*   500 */   229,  230,  231,  225,   93,   94,   95,   96,   97,   98,
+ /*   510 */    99,  100,  101,  102,  103,  104,  268,   58,  225,  271,
+ /*   520 */   272,  107,  108,  109,  168,  169,   93,   94,   95,   96,
+ /*   530 */    97,   98,   99,  100,  101,  102,  103,  104,  364,  365,
+ /*   540 */    18,  263,  263,  229,  230,  231,  325,  326,  115,  229,
+ /*   550 */   230,  231,  340,  379,  342,   40,   22,   23,   24,   25,
+ /*   560 */   149,   27,   28,   29,   30,   31,   32,   33,   34,   35,
+ /*   570 */    36,   37,   38,  229,  230,  231,  283,  225,  164,   22,
+ /*   580 */    23,   24,   25,   27,   27,   28,   29,   30,   31,   32,
+ /*   590 */    33,   34,   35,   36,   37,   38,  325,  326,   40,  140,
+ /*   600 */   141,  142,   22,   23,   24,   25,  225,   27,   28,   29,
+ /*   610 */    30,   31,   32,   33,   34,   35,   36,   37,   38,  341,
+ /*   620 */   342,   92,  107,  108,  109,   40,  360,   93,   94,   95,
+ /*   630 */    96,   97,   98,   99,  100,  101,  102,  103,  104,  325,
+ /*   640 */   326,   56,  113,  221,  115,  325,  326,  118,  225,  115,
+ /*   650 */    93,   94,   95,   96,   97,   98,   99,  100,  101,  102,
+ /*   660 */   103,  104,  106,  141,  142,  107,  108,  109,   69,  325,
+ /*   670 */   326,  113,  115,   93,   94,   95,   96,   97,   98,   99,
+ /*   680 */   100,  101,  102,  103,  104,  333,  225,  229,  230,  263,
+ /*   690 */   338,  339,  107,  108,  109,  115,   22,   23,   24,   25,
+ /*   700 */   218,   27,   28,   29,   30,   31,   32,   33,   34,   35,
+ /*   710 */    36,   37,   38,   40,  230,  225,   92,  336,  337,   22,
+ /*   720 */    23,   24,   25,  263,   27,   28,   29,   30,   31,   32,
+ /*   730 */    33,   34,   35,   36,   37,   38,  225,  113,   40,  115,
+ /*   740 */   318,  319,   22,   23,   24,   25,  147,   27,   28,   29,
+ /*   750 */    30,   31,   32,   33,   34,   35,   36,   37,   38,  227,
+ /*   760 */   161,  225,  140,  141,  142,  233,  234,   93,   94,   95,
+ /*   770 */    96,   97,   98,   99,  100,  101,  102,  103,  104,  333,
+ /*   780 */   107,  108,  109,  325,  326,  339,  113,  364,  365,  115,
+ /*   790 */    93,   94,   95,   96,   97,   98,   99,  100,  101,  102,
+ /*   800 */   103,  104,  379,  380,  268,  107,  108,  109,  272,  325,
+ /*   810 */   326,  113,  115,   93,   94,   95,   96,   97,   98,   99,
+ /*   820 */   100,  101,  102,  103,  104,  343,  344,  212,  367,  214,
+ /*   830 */   225,  216,  281,   40,  225,  115,   22,   23,   24,   25,
+ /*   840 */   225,   27,   28,   29,   30,   31,   32,   33,   34,   35,
+ /*   850 */    36,   37,   38,   40,  303,  323,  366,  225,  225,   22,
+ /*   860 */    23,   24,   25,  225,   27,   28,   29,   30,   31,   32,
+ /*   870 */    33,   34,   35,   36,   37,   38,  304,  268,  263,  307,
+ /*   880 */   271,  272,   22,   23,   24,   25,   24,   27,   28,   29,
+ /*   890 */    30,   31,   32,   33,   34,   35,   36,   37,   38,  251,
+ /*   900 */   107,  108,  109,  225,  266,  290,  113,   93,   94,   95,
+ /*   910 */    96,   97,   98,   99,  100,  101,  102,  103,  104,  109,
+ /*   920 */   107,  108,  109,  229,  230,   92,  113,   61,  118,  115,
+ /*   930 */    93,   94,   95,   96,   97,   98,   99,  100,  101,  102,
+ /*   940 */   103,  104,   76,  114,   78,  112,  268,   81,   40,  271,
+ /*   950 */   272,  225,  147,   93,   94,   95,   96,   97,   98,   99,
+ /*   960 */   100,  101,  102,  103,  104,  333,  161,  130,  106,  107,
+ /*   970 */   338,  339,  367,  368,  164,  115,   22,   23,   24,   25,
+ /*   980 */   114,   27,   28,   29,   30,   31,   32,   33,   34,   35,
+ /*   990 */    36,   37,   38,  360,  224,   40,  167,  225,   22,   23,
+ /*  1000 */    24,   25,  225,   27,   28,   29,   30,   31,   32,   33,
+ /*  1010 */    34,   35,   36,   37,   38,  107,  108,  109,  385,  325,
+ /*  1020 */   326,  113,   40,   22,   23,   24,   25,  165,   27,   28,
+ /*  1030 */    29,   30,   31,   32,   33,   34,   35,   36,   37,   38,
+ /*  1040 */   268,   92,  225,  271,  272,    1,  225,   93,   94,   95,
+ /*  1050 */    96,   97,   98,   99,  100,  101,  102,  103,  104,  140,
+ /*  1060 */   141,  142,  113,  108,  115,   21,  218,  118,  113,   93,
+ /*  1070 */    94,   95,   96,   97,   98,   99,  100,  101,  102,  103,
+ /*  1080 */   104,   99,  312,  225,  130,  315,  360,  310,   44,  107,
+ /*  1090 */   108,  109,  225,  117,   93,   94,   95,   96,   97,   98,
+ /*  1100 */    99,  100,  101,  102,  103,  104,   62,   22,   23,   24,
+ /*  1110 */    25,  225,   27,   28,   29,   30,   31,   32,   33,   34,
+ /*  1120 */    35,   36,   37,   38,   23,   24,   25,  310,   27,   28,
+ /*  1130 */    29,   30,   31,   32,   33,   34,   35,   36,   37,   38,
+ /*  1140 */    24,   25,  225,   27,   28,   29,   30,   31,   32,   33,
+ /*  1150 */    34,   35,   36,   37,   38,  288,  133,   61,  135,  136,
+ /*  1160 */   137,  224,   64,   40,  227,  225,   68,   22,  145,   40,
+ /*  1170 */   233,  234,  225,   65,   78,   67,  225,   81,   93,   94,
+ /*  1180 */    95,   96,   97,   98,   99,  100,  101,  102,  103,  104,
+ /*  1190 */   225,  343,  344,  212,   93,   94,   95,   96,   97,   98,
+ /*  1200 */    99,  100,  101,  102,  103,  104,  225,  274,   89,   93,
+ /*  1210 */    94,   95,   96,   97,   98,   99,  100,  101,  102,  103,
+ /*  1220 */   104,    0,   99,  283,  366,    4,   40,    6,   99,    8,
+ /*  1230 */   107,  108,  109,  114,  136,  288,  117,   16,   69,   18,
+ /*  1240 */   132,   20,    4,  262,    6,  126,    8,  212,  212,  214,
+ /*  1250 */   214,  216,  123,  155,   16,  225,   18,  225,   20,   40,
+ /*  1260 */   225,  225,  143,  225,  229,  230,  231,  148,  225,  212,
+ /*  1270 */    58,  214,  291,  154,   14,   54,   90,  360,   57,   19,
+ /*  1280 */   161,   69,  225,   62,   63,  225,  258,   66,  337,  212,
+ /*  1290 */    69,  214,   54,  107,  108,   57,  110,  111,  263,  263,
+ /*  1300 */    62,   63,  225,  134,   66,   45,  212,   69,  214,   88,
+ /*  1310 */   280,  125,  280,  225,  195,  212,  147,  214,  199,  225,
+ /*  1320 */   263,  202,  356,  204,  225,  290,   88,  108,  225,  287,
+ /*  1330 */   161,  288,  113,  112,  189,  225,  117,  151,  152,  311,
+ /*  1340 */   263,  208,  209,  210,  211,  212,  213,  305,  127,  321,
+ /*  1350 */   112,   90,  140,  387,  212,   40,  214,  263,  306,  147,
+ /*  1360 */   325,  326,  229,  230,  231,  127,  263,  225,  147,  108,
+ /*  1370 */   310,  110,  111,  161,   48,  154,   61,  156,   24,  280,
+ /*  1380 */   159,   24,  161,  225,   27,  147,  125,  166,  255,   11,
+ /*  1390 */   257,   76,  154,   78,  156,  225,   81,  159,  288,  161,
+ /*  1400 */    74,  212,   24,   99,  166,  263,  273,  371,  372,   83,
+ /*  1410 */   189,   41,  151,  152,  225,  194,  218,  340,   40,  342,
+ /*  1420 */   199,  118,  107,  108,  109,  121,  212,  189,  214,  114,
+ /*  1430 */   126,  217,  194,   55,  377,  378,  266,  199,  225,  225,
+ /*  1440 */   251,  252,  116,  225,  212,  115,  288,   69,  118,   11,
+ /*  1450 */   147,  262,  219,  220,  211,  322,  213,  225,  325,  326,
+ /*  1460 */   327,  107,   24,  106,  161,  371,  372,   29,   90,   10,
+ /*  1470 */   276,  106,  229,  230,  231,   97,   98,  263,   40,  212,
+ /*  1480 */   291,  287,  212,  105,  214,  107,  108,  109,  110,  111,
+ /*  1490 */   333,  113,  225,   55,  225,  225,  339,   40,  255,  218,
+ /*  1500 */   257,  144,  124,  125,  362,  363,  128,   48,  212,  212,
+ /*  1510 */   214,  214,   74,  216,  149,   40,  273,   79,   59,  225,
+ /*  1520 */   387,  225,  225,  291,  212,  147,  214,  157,   90,  151,
+ /*  1530 */   152,  153,   40,  263,   40,   97,   98,  225,   65,  161,
+ /*  1540 */    67,  343,  344,  105,  333,  107,  108,  109,  110,  111,
+ /*  1550 */   339,  113,   40,    4,   24,    6,   99,    8,  291,  263,
+ /*  1560 */   263,   24,  124,  125,  127,   16,  128,   18,  325,  326,
+ /*  1570 */   327,  115,   97,   98,  118,  263,  210,  211,  212,  213,
+ /*  1580 */   123,  106,  107,  108,  109,  110,  111,  290,    1,  151,
+ /*  1590 */   152,  153,  118,  375,  376,  229,  230,  231,  109,  107,
+ /*  1600 */   108,  109,  143,   54,  115,  132,   57,  118,   21,  134,
+ /*  1610 */   225,   62,   63,  225,   84,   66,  141,   40,   69,  212,
+ /*  1620 */   108,  255,  148,  257,  343,  344,  132,   11,  155,  117,
+ /*  1630 */   387,   44,  225,  212,  104,  214,  199,   88,  146,  273,
+ /*  1640 */    24,  371,  333,  276,  107,   58,  225,  117,  339,   62,
+ /*  1650 */   229,  230,  231,  164,  287,  125,   40,  113,  362,  363,
+ /*  1660 */   212,  117,  189,  133,  134,  135,  136,  137,  138,  333,
+ /*  1670 */   116,   55,  118,  225,  144,  339,  127,  219,  220,  117,
+ /*  1680 */    61,  212,  242,  214,  263,  108,   97,   98,  322,  377,
+ /*  1690 */    74,  325,  326,  327,  225,   79,  147,   78,  291,  212,
+ /*  1700 */    81,  214,  113,  154,  217,  156,   90,   11,  159,  118,
+ /*  1710 */   161,  290,  225,   97,   98,  166,  353,  354,  212,  118,
+ /*  1720 */    24,  105,  225,  107,  108,  109,  110,  111,  127,  113,
+ /*  1730 */   139,  225,  263,   92,  347,  348,   40,  118,  189,  291,
+ /*  1740 */   124,  125,    5,  194,  128,  114,  325,  326,  199,  118,
+ /*  1750 */   263,   55,   15,  387,  113,  193,  115,  328,  329,  212,
+ /*  1760 */   212,  214,  214,  216,  212,  222,  223,  151,  152,  153,
+ /*  1770 */    74,  106,  225,  225,  242,   79,  212,  225,  214,   11,
+ /*  1780 */   142,  217,  212,  212,  214,  214,   90,  217,  150,  225,
+ /*  1790 */   222,  223,   24,   97,   98,  225,  225,  291,  222,  223,
+ /*  1800 */   212,  105,  214,  107,  108,  109,  110,  111,   40,  113,
+ /*  1810 */   263,  263,  212,  225,  214,   11,  212,  222,  223,  115,
+ /*  1820 */   124,  125,  118,   55,  128,  225,  242,  263,   24,  225,
+ /*  1830 */   165,  362,  363,  263,  263,  222,  223,  290,   67,  129,
+ /*  1840 */   212,  131,  214,  291,   40,  217,  113,  151,  152,  153,
+ /*  1850 */   298,  263,  119,  225,  197,  198,  148,  149,   90,   55,
+ /*  1860 */   118,  290,  117,  263,  119,   97,   98,   99,  115,  127,
+ /*  1870 */   225,  118,  212,  105,  214,  107,  108,  109,  110,  111,
+ /*  1880 */   115,  113,   34,  118,  212,  225,  214,   11,  203,  217,
+ /*  1890 */   205,  263,  124,  125,   90,  291,  128,  225,  225,  142,
+ /*  1900 */    24,   97,   98,  132,  117,  115,  119,  150,  118,  105,
+ /*  1910 */   362,  107,  108,  109,  110,  111,   40,  113,  225,  151,
+ /*  1920 */   152,  153,   42,  263,   11,  212,  155,  214,  124,  125,
+ /*  1930 */   126,   55,  128,  125,  225,  263,  212,   24,  225,  212,
+ /*  1940 */   115,  214,  134,  118,  217,  174,   97,   98,  235,  225,
+ /*  1950 */   290,  212,  225,   40,  225,  151,  152,  153,  300,  110,
+ /*  1960 */   111,  113,  335,  192,  225,   40,   90,  115,   55,  115,
+ /*  1970 */   118,  225,  118,   97,   98,  212,  263,  117,  286,  119,
+ /*  1980 */   125,  105,   24,  107,  108,  109,  110,  111,  225,  113,
+ /*  1990 */   263,  225,  212,  113,  214,  212,   11,  214,  225,  144,
+ /*  2000 */   124,  125,  126,   90,  128,  225,   72,   73,  225,   24,
+ /*  2010 */    97,   98,   99,  115,  225,  291,  118,   14,  105,  225,
+ /*  2020 */   107,  108,  109,  110,  111,   40,  113,  151,  152,  153,
+ /*  2030 */   291,  225,  115,  108,  212,  118,  214,  124,  125,  115,
+ /*  2040 */    55,  128,  118,  263,  225,   87,  263,  225,   45,   40,
+ /*  2050 */   212,   40,  214,  115,  291,  212,  118,  214,  225,  115,
+ /*  2060 */   217,  298,  118,  225,  151,  152,  153,  225,  225,  225,
+ /*  2070 */   290,  110,  111,  290,  212,   90,  214,  355,  212,  294,
+ /*  2080 */   214,  115,   97,   98,  118,  263,  115,  225,  225,  118,
+ /*  2090 */   105,  225,  107,  108,  109,  110,  111,  115,  113,  225,
+ /*  2100 */   118,  263,  212,  225,  214,  212,  263,  214,  115,  124,
+ /*  2110 */   125,  118,  290,  128,  212,  225,  214,  108,  225,  108,
+ /*  2120 */   115,  225,  212,  118,  214,  263,  225,  225,  290,  263,
+ /*  2130 */   212,  115,  214,  225,  118,  225,  151,  152,  153,  212,
+ /*  2140 */   225,  214,  212,  225,  214,  212,  115,  214,  212,  118,
+ /*  2150 */   214,  115,  225,  263,  118,  225,  263,  212,  225,  214,
+ /*  2160 */   225,  225,  110,  111,  225,  263,  212,  225,  214,  212,
+ /*  2170 */   225,  214,  225,  263,  114,  115,  212,  225,  214,  225,
+ /*  2180 */   225,  263,  225,  313,  225,  225,  238,  225,  212,  225,
+ /*  2190 */   263,  308,  225,  263,  225,  225,  263,  225,  212,  263,
+ /*  2200 */   214,  225,  212,  212,  214,  214,  225,  300,  263,  225,
+ /*  2210 */   212,  225,  214,  212,  225,  225,  225,  263,  226,  225,
+ /*  2220 */   263,  225,  212,  225,  214,  225,  225,  263,  300,  225,
+ /*  2230 */   215,  212,  225,  214,  212,  225,  214,  212,  212,  214,
+ /*  2240 */   214,  300,  351,  300,  225,  361,  381,  225,  345,  263,
+ /*  2250 */   225,  225,  278,  263,  263,  277,  212,  284,  214,  284,
+ /*  2260 */   297,  263,  316,  212,  277,  214,  289,  291,  212,  225,
+ /*  2270 */   214,  239,  289,  263,  298,  278,  225,  212,  212,  214,
+ /*  2280 */   214,  225,  263,  253,  278,  263,  278,  241,  263,  263,
+ /*  2290 */   225,  225,  291,  212,  256,  214,  212,  264,  214,  298,
+ /*  2300 */   212,  284,  214,  212,  316,  214,  225,  263,  212,  225,
+ /*  2310 */   214,  264,  264,  225,  263,  281,  225,  305,  212,  263,
+ /*  2320 */   214,  225,  212,  212,  214,  214,  305,  237,  263,  263,
+ /*  2330 */   281,  225,  305,  305,  215,  225,  225,  212,   92,  214,
+ /*  2340 */   212,   40,  214,  212,  263,  214,  113,  263,  212,  207,
+ /*  2350 */   225,  263,   58,  225,  263,  212,  225,  214,  212,  263,
+ /*  2360 */   214,  225,  349,  212,  201,  214,  352,  122,  225,  263,
+ /*  2370 */   212,  225,  214,  263,  263,  117,  225,  348,  358,  212,
+ /*  2380 */   119,  214,  212,  225,  214,  383,   40,  228,  263,  165,
+ /*  2390 */   146,  263,  225,  370,  263,  225,  359,  324,   13,  359,
+ /*  2400 */   346,  346,  212,  212,  214,  214,  263,  389,  349,  263,
+ /*  2410 */   369,  212,  370,  214,  263,  225,  225,  348,  212,  369,
+ /*  2420 */   214,  263,  383,  212,  225,  214,  383,  291,  350,  317,
+ /*  2430 */   263,  225,  317,  263,  298,  212,  225,  214,  228,   63,
+ /*  2440 */   228,  228,  160,  296,  212,  296,  214,  212,  225,  214,
+ /*  2450 */   295,  295,  295,  263,  263,   41,   91,  225,  297,  297,
+ /*  2460 */   225,  293,  263,  149,  293,  293,  293,  279,  113,  263,
+ /*  2470 */   285,  163,  114,  281,  263,  282,   22,  275,  282,  281,
+ /*  2480 */   228,   91,  148,  289,  259,  228,  263,  259,  279,  289,
+ /*  2490 */   289,  275,  285,  279,  289,  263,  275,  113,  263,  265,
+ /*  2500 */   228,  259,  129,  314,   43,  228,  309,  259,  228,  259,
+ /*  2510 */   106,  248,  265,  248,  248,   46,  113,  244,  254,  265,
+ /*  2520 */   139,  254,  248,  239,  248,  244,  248,  248,  118,  261,
+ /*  2530 */   228,  282,  281,  162,  116,  282,   80,  334,  302,  301,
+ /*  2540 */   113,   71,  334,  232,  289,  228,  104,  117,  292,  129,
+ /*  2550 */   168,  292,  236,  270,  265,  270,  269,  388,  332,  344,
+ /*  2560 */   329,  332,  384,  384,  224,  250,  224,  224,  224,  250,
+ /*  2570 */   240,  240,  250,  238,  357,  356,  238,  357,  356,   49,
+ /*  2580 */   224,   50,  119,  190,  357,  189,   34,   54,  113,  117,
+ /*  2590 */    40,  191,  115,   40,   40,   40,  118,  113,   40,  113,
+ /*  2600 */   106,   40,  157,  113,  191,  118,  115,  200,  113,  117,
+ /*  2610 */   113,   52,  196,    9,  118,    9,  118,  117,   69,  118,
+ /*  2620 */   118,  206,  118,  204,   34,  118,  117,  113,  118,  118,
+ /*  2630 */   117,  113,  115,  117,  119,   40,   40,   40,  119,  119,
+ /*  2640 */   119,  119,  119,  119,  115,  119,  189,  113,   40,   58,
+ /*  2650 */   112,  115,  115,  106,  165,  113,  157,  132,  146,  124,
+ /*  2660 */   117,  158,  157,  155,  118,   42,  127,   12,  106,  112,
+ /*  2670 */    34,  143,  132,   34,  147,  127,   34,   34,  107,    9,
+ /*  2680 */   112,    8,  119,  117,  143,   52,   52,  155,  143,   60,
+ /*  2690 */   146,  118,   17,  119,  143,  106,  124,  113,   24,   51,
+ /*  2700 */   144,  113,  138,   51,   40,  113,   85,  113,  115,    2,
+ /*  2710 */    51,   12,  113,    9,  107,  117,  115,  115,  118,    9,
+ /*  2720 */   115,  118,  113,    9,  164,  115,  113,  148,  117,  114,
+ /*  2730 */   118,  115,  113,  119,  116,  113,    9,    9,    9,  115,
+ /*  2740 */    77,   60,   75,   23,   60,  118,    9,   82,  118,   87,
+ /*  2750 */   115,   18,  115,  115,  113,  127,    9,  113,  118,  127,
+ /*  2760 */     9,  390,  115,  118,  118,  115,  113,  113,  119,  113,
+ /*  2770 */   113,  390,  121,  115,  390,  115,  390,  390,  390,  390,
+ /*  2780 */   119,  390,  390,  115,  115,  119,  390,  390,  390,  113,
+ /*  2790 */   112,  112,  390,  390,  390,  390,  390,  390,  390,  390,
  /*  2800 */   390,  390,  390,  390,  390,  390,  390,  390,  390,  390,
  /*  2810 */   390,  390,  390,  390,  390,  390,  390,  390,  390,  390,
  /*  2820 */   390,  390,  390,  390,  390,  390,  390,  390,  390,  390,
@@ -14360,227 +14400,231 @@
  /*  2920 */   390,  390,  390,  390,  390,  390,  390,  390,  390,  390,
  /*  2930 */   390,  390,  390,  390,  390,  390,  390,  390,  390,  390,
  /*  2940 */   390,  390,  390,  390,  390,  390,  390,  390,  390,  390,
- /*  2950 */   390,
+ /*  2950 */   390,  390,  390,  390,  390,  390,  390,  390,  390,  390,
+ /*  2960 */   390,  390,  390,  390,  390,  390,  390,  390,  390,  390,
+ /*  2970 */   390,  390,  390,  390,  390,  390,  390,  390,  390,  390,
+ /*  2980 */   390,  390,  390,  390,  390,  390,  390,  390,  390,  390,
+ /*  2990 */   390,  390,  390,  390,  390,  390,  390,  390,  390,  390,
 };
-#define YY_SHIFT_COUNT    (774)
+#define YY_SHIFT_COUNT    (775)
 #define YY_SHIFT_MIN      (0)
-#define YY_SHIFT_MAX      (2703)
+#define YY_SHIFT_MAX      (2751)
 static const unsigned short int yy_shift_ofst[] = {
- /*     0 */  1162, 1145, 1473, 1302, 1302,  620, 1362, 1540, 1620, 1837,
- /*    10 */  1837, 1837, 1837, 1837, 1837, 1837,   35, 1295, 1837, 1837,
- /*    20 */  1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837,
- /*    30 */  1837, 1837, 1837, 1837, 1837,   68,   68,  740,  740,  932,
- /*    40 */   740,  620,  620,  620,  620,  620,  620,  620,  620,  620,
- /*    50 */     0,    0,  182,  987, 1692, 1729, 1801, 1837, 1837, 1837,
- /*    60 */  1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837,
- /*    70 */  1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837,
- /*    80 */  1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837,
- /*    90 */  1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837,
- /*   100 */  1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837, 1837,
- /*   110 */  1899, 1899,  490,  490,   68,  487,  744,  740,  740,  740,
- /*   120 */   740,  740,  740,  740,  740,  740,  597,  597,  597,  597,
- /*   130 */    34,  128,  160,  265,  290,  315,  408,  438,  461,  555,
- /*   140 */   578,  601,  695,  718,  741,  845,  868,  891,  987,  987,
- /*   150 */   987,  987,  987,  987,  987,  987,  987,  987,  987,  987,
- /*   160 */   987,  987,  987,  987,  987,  987,  987,  987, 1009,  987,
- /*   170 */  1025, 1040, 1040,   16, 1472, 1472, 1472, 1472, 1472, 1472,
- /*   180 */  1472,  277,  169,  139,  314,  717,  740,  740,  740,  740,
- /*   190 */   740,  740,  740,  740,  740,  740,  740,  740, 1211, 1560,
- /*   200 */   740,  740,  740, 1061, 1061,  313,  872,  194,  228,  228,
- /*   210 */   228,  273,   99,   99, 2743, 2743, 1839, 1839, 1839,  314,
- /*   220 */   314,  314, 1076,  437,  437,  437,  437, 1539, 1539,  717,
- /*   230 */   921,  841, 1489,  740,  740,  740,  740,  740,  740,  740,
- /*   240 */   740,  740,  740,  740,  740,  740,  740,  740,  740,  740,
- /*   250 */   740,  740, 1106,  740, 1608, 1608,  740, 1415, 1289, 1289,
- /*   260 */  1419, 1252, 1252, 1169, 1609, 1169,    6,  205, 2743, 2743,
- /*   270 */  2743, 2743, 2743, 2743, 2743, 1043, 1110, 1085, 1085,  897,
- /*   280 */   694, 1329,  823,  988, 1606, 1642,  844,  870,  740,  740,
- /*   290 */   740,  740,  740,  740,  740,  740,  740,  740,  740,  740,
- /*   300 */   740,  740,  740,  740,  740,  740,  740,  740,  740,  740,
- /*   310 */   740,  740,  740,  740,  740,  740,  747,  740,  740,  740,
- /*   320 */   740,  740,  740,  740,  740,  740,  740,  740, 1234, 1234,
- /*   330 */  1234,  740,  740,  740,  740, 1414,  740,  740, 1141, 1802,
- /*   340 */   740,  740, 1742,  740,  740,   46, 1406, 1006, 1253, 1734,
- /*   350 */  1644, 1644, 1644, 1070, 1644,  589,  589, 1598,  589,  603,
- /*   360 */  1797,  193, 1359, 1694, 1392, 1882, 1731, 1882, 1361, 1680,
- /*   370 */  1392, 1392, 1680, 1392, 1731, 1361, 1515, 1670, 1221, 1159,
- /*   380 */  1761, 1317, 1317, 1317, 1317, 1789, 1775, 1775, 1159, 1159,
- /*   390 */  1460, 1535, 2273, 2329,  205, 2258, 2165, 2173, 2173, 2173,
- /*   400 */  2317, 2254, 2317, 2254, 2165, 2263, 2263, 2267, 2347, 2347,
- /*   410 */   205, 2258, 2229, 2251, 2385, 2385, 2267, 2267, 2267, 2338,
- /*   420 */  2338, 2246, 2246, 2246, 2373, 2373, 2324, 2324, 2324, 2324,
- /*   430 */  2270, 2312, 2264, 2315, 2408, 2264, 2315, 2267, 2343, 2290,
- /*   440 */  2267, 2343, 2290, 2270, 2270, 2290, 2312, 2408, 2290, 2408,
- /*   450 */  2336, 2267, 2343, 2325, 2412, 2267, 2343, 2267, 2343, 2336,
- /*   460 */  2357, 2357, 2357, 2421, 2356, 2356, 2336, 2357, 2333, 2357,
- /*   470 */  2421, 2357, 2357, 2360, 2267, 2264, 2315, 2264, 2323, 2371,
- /*   480 */  2290, 2410, 2410, 2420, 2420, 2379, 2267, 2391, 2391, 2369,
- /*   490 */  2386, 2336, 2340, 2743, 2743, 2743, 2743, 2743, 2743, 2743,
- /*   500 */  2743, 2743, 2743, 2743, 2743, 2743, 2743, 2743, 2743, 2743,
- /*   510 */  2743, 2743, 2743, 2743, 2743, 2743,  672, 1466,  119,  301,
- /*   520 */  1218, 1493, 1257, 1538, 1403, 1823, 1911, 1923, 1875, 1954,
- /*   530 */  1960, 1648, 1664, 1965, 1811, 1971, 1861, 1981, 1759, 1866,
- /*   540 */  1945, 1993,  431, 1604, 1997, 1969, 2005, 2013, 2068, 2076,
- /*   550 */  2078, 1942, 1992, 2100, 1966, 2083, 2065, 2102, 2084, 2138,
- /*   560 */  2128, 2135, 2136, 2124, 2039, 2149, 2161, 2167, 2150, 2063,
- /*   570 */  2479, 2480, 2415, 2339, 2342, 2501, 2482, 2424, 2423, 2502,
- /*   580 */  2350, 2428, 2505, 2506, 2507, 2430, 2436, 2510, 2438, 2446,
- /*   590 */  2513, 2397, 2442, 2365, 2443, 2439, 2447, 2444, 2449, 2511,
- /*   600 */  2359, 2448, 2368, 2450, 2556, 2451, 2558, 2503, 2364, 2453,
- /*   610 */  2448, 2370, 2455, 2456, 2542, 2459, 2461, 2462, 2463, 2463,
- /*   620 */  2465, 2466, 2470, 2467, 2471, 2468, 2469, 2472, 2473, 2547,
- /*   630 */  2474, 2475, 2476, 2481, 2549, 2478, 2550, 2485, 2559, 2411,
- /*   640 */  2543, 2490, 2488, 2489, 2452, 2454, 2457, 2483, 2499, 2458,
- /*   650 */  2484, 2460, 2464, 2477, 2494, 2498, 2498, 2491, 2441, 2487,
- /*   660 */  2504, 2515, 2486, 2512, 2495, 2492, 2498, 2493, 2581, 2613,
- /*   670 */  2498, 2496, 2592, 2593, 2594, 2595, 2497, 2523, 2622, 2514,
- /*   680 */  2520, 2626, 2521, 2585, 2525, 2587, 2584, 2628, 2527, 2541,
- /*   690 */  2524, 2625, 2508, 2516, 2537, 2600, 2540, 2544, 2545, 2546,
- /*   700 */  2604, 2616, 2548, 2573, 2659, 2551, 2611, 2651, 2552, 2553,
- /*   710 */  2554, 2557, 2560, 2657, 2561, 2509, 2562, 2662, 2563, 2564,
- /*   720 */  2565, 2566, 2567, 2568, 2666, 2571, 2574, 2572, 2528, 2576,
- /*   730 */  2575, 2670, 2672, 2682, 2615, 2633, 2619, 2673, 2635, 2617,
- /*   740 */  2579, 2689, 2586, 2562, 2588, 2589, 2582, 2618, 2596, 2590,
- /*   750 */  2597, 2598, 2580, 2591, 2599, 2605, 2601, 2583, 2688, 2602,
- /*   760 */  2606, 2609, 2603, 2608, 2612, 2614, 2607, 2620, 2621, 2623,
- /*   770 */  2624, 2702, 2703, 2629, 2630,
+ /*     0 */  1238, 1221, 1549, 1378, 1378,  599, 1438, 1616, 1696, 1768,
+ /*    10 */  1768, 1985, 1985, 1985, 1985, 1985, 1985, 1985,   35, 1212,
+ /*    20 */  1768, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985,
+ /*    30 */  1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985,  515,  515,
+ /*    40 */  1169,  515,  599,  599,  599,  599,  599,  599,  599,  599,
+ /*    50 */   599,    0,    0,  182, 1001, 1804, 1876, 1913, 1985, 1985,
+ /*    60 */  1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985,
+ /*    70 */  1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985,
+ /*    80 */  1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985,
+ /*    90 */  1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985,
+ /*   100 */  1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985, 1985,
+ /*   110 */  1985, 1985, 1475, 1475, 1315, 1315,   68,  585,  515,  515,
+ /*   120 */   515,  515,  515,  515,  515,  515,  515, 1303, 1303, 1303,
+ /*   130 */  1303,   34,  128,  160,  265,  290,  315,  411,  433,  534,
+ /*   140 */   557,  580,  674,  697,  720,  814,  837,  860,  954,  976,
+ /*   150 */  1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001,
+ /*   160 */  1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001,
+ /*   170 */  1001, 1085, 1001, 1101, 1116, 1116,   16,  385,  385,  385,
+ /*   180 */   385,  385,  385,  385,  277,  169,  139,  558,  389,  515,
+ /*   190 */   515,  515,  515,  515,  515,  515,  515,  515,  515,  515,
+ /*   200 */   515, 1098, 1357,  515,  515,  515, 1849, 1849,   83,  391,
+ /*   210 */   213,  356,  356,  356,  805,   63,   63, 2792, 2792, 1530,
+ /*   220 */  1530, 1530,  558,  558,  558, 1492,  673,  673,  673,  673,
+ /*   230 */  1587, 1587,  389,  866,  529,  949,  515,  515,  515,  515,
+ /*   240 */   515,  515,  515,  515,  515,  515,  515,  515,  515,  515,
+ /*   250 */   515,  515,  515,  515,  862,  515, 1619, 1619,  515,  522,
+ /*   260 */  1096, 1096, 1437, 1354, 1354, 1577,  829, 1577,  264,  432,
+ /*   270 */  2792, 2792, 2792, 2792, 2792, 2792, 2792, 1119, 1186, 1261,
+ /*   280 */  1261,  982,  698, 1023,  793,  289,  414, 1123,  813,  908,
+ /*   290 */   515,  515,  515,  515,  515,  515,  515,  515,  515,  515,
+ /*   300 */   515,  515,  515,  515,  515,  515,  515,  515,  515,  515,
+ /*   310 */   515,  515,  515,  515,  515,  515,  515,  515,  459,  515,
+ /*   320 */   515,  515,  515,  515,  515,  515,  515,  515,  515,  515,
+ /*   330 */  1459, 1459, 1459,  515,  515,  515,  515, 1489,  515,  515,
+ /*   340 */  1219, 1326,  515,  515, 1044,  515,  515, 1129, 1260,  622,
+ /*   350 */    39, 1589, 1512, 1512, 1512,  810, 1512,  354,  354, 1304,
+ /*   360 */   354, 1494, 1657, 1554, 1145, 1370, 1365, 1708, 1601, 1708,
+ /*   370 */  1537, 1474, 1365, 1365, 1474, 1365, 1601, 1537, 1591, 1330,
+ /*   380 */   556, 1737, 1544, 1665, 1665, 1665, 1665, 1742, 1631, 1631,
+ /*   390 */  1737, 1737, 1710,  190, 2246, 2301,  432, 2233, 2142, 2163,
+ /*   400 */  2163, 2163, 2294, 2245, 2294, 2245, 2142, 2258, 2258, 2261,
+ /*   410 */  2346, 2346,  432, 2233, 2224, 2244, 2385, 2385, 2261, 2261,
+ /*   420 */  2261, 2376, 2376, 2282, 2282, 2282, 2414, 2414, 2365, 2365,
+ /*   430 */  2365, 2365, 2314, 2355, 2308, 2358, 2454, 2308, 2358, 2261,
+ /*   440 */  2390, 2334, 2261, 2390, 2334, 2314, 2314, 2334, 2355, 2454,
+ /*   450 */  2334, 2454, 2384, 2261, 2390, 2373, 2461, 2261, 2390, 2261,
+ /*   460 */  2390, 2384, 2404, 2404, 2404, 2469, 2403, 2403, 2384, 2404,
+ /*   470 */  2381, 2404, 2469, 2404, 2404, 2410, 2261, 2308, 2358, 2308,
+ /*   480 */  2371, 2418, 2334, 2456, 2456, 2470, 2470, 2427, 2261, 2442,
+ /*   490 */  2442, 2420, 2430, 2384, 2382, 2792, 2792, 2792, 2792, 2792,
+ /*   500 */  2792, 2792, 2792, 2792, 2792, 2792, 2792, 2792, 2792, 2792,
+ /*   510 */  2792, 2792, 2792, 2792, 2792, 2792, 2792, 2792, 1771, 1473,
+ /*   520 */   119, 1457,  624, 1641, 1108,  919,  955, 1456,  833, 1704,
+ /*   530 */  1562, 1753, 1765, 1745, 1685, 1790, 1787, 1825, 1852, 1848,
+ /*   540 */   241, 1860, 1854, 1638, 1757, 1898, 1880, 1917, 1924, 1938,
+ /*   550 */  1944, 1971, 1925, 1808, 2003, 1855, 1966, 1934, 2009, 1982,
+ /*   560 */  1958, 1993, 2005, 2016, 2011, 1961, 2052, 2031, 2036, 2060,
+ /*   570 */  1733, 2530, 2531, 2463, 2393, 2396, 2552, 2533, 2475, 2472,
+ /*   580 */  2550, 2400, 2477, 2553, 2554, 2555, 2478, 2484, 2558, 2486,
+ /*   590 */  2494, 2561, 2445, 2490, 2413, 2491, 2487, 2495, 2492, 2497,
+ /*   600 */  2559, 2407, 2496, 2416, 2498, 2500, 2604, 2501, 2606, 2549,
+ /*   610 */  2415, 2502, 2496, 2419, 2504, 2590, 2507, 2509, 2510, 2511,
+ /*   620 */  2511, 2513, 2514, 2518, 2515, 2517, 2516, 2519, 2520, 2521,
+ /*   630 */  2595, 2522, 2523, 2524, 2529, 2596, 2526, 2597, 2534, 2608,
+ /*   640 */  2457, 2591, 2538, 2536, 2537, 2499, 2503, 2505, 2525, 2547,
+ /*   650 */  2508, 2535, 2527, 2512, 2528, 2543, 2546, 2546, 2539, 2489,
+ /*   660 */  2540, 2542, 2562, 2532, 2557, 2548, 2541, 2546, 2545, 2623,
+ /*   670 */  2655, 2546, 2544, 2636, 2639, 2642, 2643, 2551, 2571, 2670,
+ /*   680 */  2563, 2568, 2673, 2566, 2633, 2573, 2634, 2629, 2675, 2574,
+ /*   690 */  2589, 2572, 2674, 2556, 2564, 2584, 2648, 2588, 2592, 2593,
+ /*   700 */  2594, 2652, 2664, 2598, 2621, 2707, 2599, 2659, 2699, 2600,
+ /*   710 */  2601, 2602, 2605, 2607, 2704, 2609, 2560, 2603, 2710, 2610,
+ /*   720 */  2613, 2611, 2612, 2614, 2616, 2714, 2615, 2619, 2618, 2579,
+ /*   730 */  2622, 2624, 2727, 2728, 2729, 2663, 2681, 2667, 2720, 2684,
+ /*   740 */  2665, 2627, 2737, 2635, 2603, 2637, 2638, 2630, 2662, 2641,
+ /*   750 */  2640, 2644, 2645, 2628, 2632, 2646, 2647, 2653, 2649, 2733,
+ /*   760 */  2654, 2650, 2656, 2651, 2658, 2657, 2660, 2661, 2666, 2668,
+ /*   770 */  2669, 2676, 2747, 2751, 2678, 2679,
 };
-#define YY_REDUCE_COUNT (515)
+#define YY_REDUCE_COUNT (517)
 #define YY_REDUCE_MIN   (-370)
-#define YY_REDUCE_MAX   (2303)
+#define YY_REDUCE_MAX   (2356)
 static const short yy_reduce_ofst[] = {
- /*     0 */  1057, 1290, 1167, 1380, 1411, -220,  304,  942, 1018,  496,
- /*    10 */  1066, 1140, 1083, 1082, 1124, 1410, 1143, -186, 1039, 1176,
- /*    20 */  1271, 1365, 1471, 1495, 1194, 1543, 1566, 1236, 1596, 1597,
- /*    30 */  1650, 1552, 1708, 1754, 1654,   85,  296,  327, -209, -152,
- /*    40 */   -26,   76,  100,  103,  222,  295,  388,  411,  457,  531,
- /*    50 */  -214, -142,  627,  171,  978, 1567, 1621, 1707, 1779, 1788,
- /*    60 */  1800, 1804, 1807, 1810, 1814, 1822, 1831, 1834, 1840, 1841,
- /*    70 */  1846, 1862, 1867, 1876, 1881, 1888, 1893, 1907, 1910, 1915,
- /*    80 */  1922, 1934, 1940, 1941, 1946, 1949, 1955, 1963, 1967, 1975,
- /*    90 */  1994, 1999, 2003, 2008, 2009, 2015, 2023, 2027, 2030, 2033,
- /*   100 */  2049, 2055, 2056, 2075, 2080, 2089, 2095, 2096, 2101, 2110,
- /*   110 */  -118,  -71,  181, 1319,   83,  560,  640,  444,  964,  682,
- /*   120 */   801, 1034, 1078, 1281, 1206, 1287,  249,  340,  249,  340,
- /*   130 */  -227, -227, -227, -227, -227, -227, -227, -227, -227, -227,
+ /*     0 */  1133, 1366, 1243, 1035, 1421, -220,  212,  278, 1077, 1036,
+ /*    10 */  1094, 1142, 1296, 1057, 1469,  615, 1297, 1547, 1189, -186,
+ /*    20 */  1270, 1312, 1548, 1214, 1487, 1564, 1570, 1571, 1628, 1672,
+ /*    30 */  1660, 1727, 1780, 1783, 1713, 1822, 1838, 1843,  423, -209,
+ /*    40 */  -152,  -26,   76,   79,  102,  105,  221,  271,  314,  320,
+ /*    50 */   344, -214, -142,  532,  937, 1103, 1588, 1600, 1862, 1866,
+ /*    60 */  1890, 1893, 1902, 1910, 1918, 1927, 1930, 1933, 1936, 1945,
+ /*    70 */  1954, 1957, 1964, 1986, 1990, 1991, 1998, 2010, 2019, 2022,
+ /*    80 */  2025, 2026, 2044, 2051, 2056, 2065, 2066, 2081, 2084, 2088,
+ /*    90 */  2091, 2096, 2106, 2110, 2111, 2125, 2128, 2131, 2143, 2146,
+ /*   100 */  2151, 2158, 2167, 2170, 2190, 2191, 2199, 2206, 2211, 2223,
+ /*   110 */  2232, 2235, -118,  -71,  352,  632,  248,  609,  174,  981,
+ /*   120 */  1552, 1763, 1976, 2001,  678, 2136,  772,  458,  694,  458,
+ /*   130 */   694, -227, -227, -227, -227, -227, -227, -227, -227, -227,
  /*   140 */  -227, -227, -227, -227, -227, -227, -227, -227, -227, -227,
  /*   150 */  -227, -227, -227, -227, -227, -227, -227, -227, -227, -227,
  /*   160 */  -227, -227, -227, -227, -227, -227, -227, -227, -227, -227,
  /*   170 */  -227, -227, -227, -227, -227, -227, -227, -227, -227, -227,
- /*   180 */  -227, -227, -227, -227,  262, -199,  288,  -17,   91, -211,
- /*   190 */  -208, 1312, 1451, 1582, 1640, 1658, 1676, 1678,  994, -120,
- /*   200 */   347, 1690,  826, -140,  782,  -92, -227, 1005,  896, 1395,
- /*   210 */  1480,  704, -227, -227, -227, -227, -241, -241, -241,  802,
- /*   220 */   981, 1002, -183, -207,  402,  890,  990, -246, -226,  930,
- /*   230 */   189, -257, -257,  420, -101,  465,  513,  641,  976,  969,
- /*   240 */   605,  637, 1094,  625, 1060, 1168, 1150, 1207, 1212, 1255,
- /*   250 */    25, 1300, 1171,  178, 1260, 1348, 1138,  685, 1369, 1423,
- /*   260 */  1303,  911, 1435, 1555, 1247, 1576, 1541, 1557, 1568, 1714,
- /*   270 */  1735, 1737, 1762,  651, 1764, -370,   41,   92,  192,  255,
- /*   280 */   275,  266,  324,  561,  630,  756,  892,  906,  998, 1038,
- /*   290 */  1112, 1196, 1222, 1280, 1337,  255, 1446, 1470, 1496, 1534,
- /*   300 */  1589, 1661, 1699, 1726, 1738, 1774, 1776, 1790, 1812, 1824,
- /*   310 */  1832, 1836, 1859, 1873, 1891, 1908, 1753, 1916, 1918, 1932,
- /*   320 */  1943, 1947, 1959, 1970, 1980, 1982, 1989, 1991, 1344, 1948,
- /*   330 */  2007, 2006, 2011, 2031, 2048,  356, 2050, 2052, 1983, 1953,
- /*   340 */  2059, 2066, 2012, 2070,  756, 1944, 2010, 1984, 1998, 2064,
- /*   350 */  2016, 2017, 2025,  356, 2028, 2085, 2085, 2108, 2085, 1976,
- /*   360 */  1968, 1950, 1985, 2035, 2058, 2057, 2053, 2062, 2024, 2044,
- /*   370 */  2067, 2069, 2060, 2072, 2071, 2026, 2105, 2088, 2107, 2082,
- /*   380 */  2097, 2046, 2051, 2061, 2073, 2077, 2079, 2081, 2090, 2093,
- /*   390 */  2126, 2152, 1979, 2018, 2029, 2032, 2021, 2000, 2001, 2002,
- /*   400 */  2019, 2022, 2020, 2034, 2021, 2036, 2037, 2154, 2042, 2047,
- /*   410 */  2054, 2043, 2074, 2086, 2087, 2091, 2171, 2172, 2177, 2111,
- /*   420 */  2113, 2116, 2117, 2118, 2119, 2120, 2125, 2127, 2129, 2130,
- /*   430 */  2142, 2141, 2146, 2151, 2156, 2153, 2155, 2205, 2178, 2157,
- /*   440 */  2211, 2181, 2158, 2162, 2163, 2159, 2160, 2168, 2164, 2169,
- /*   450 */  2185, 2223, 2193, 2143, 2147, 2230, 2200, 2232, 2202, 2197,
- /*   460 */  2216, 2217, 2218, 2224, 2219, 2220, 2206, 2222, 2236, 2228,
- /*   470 */  2233, 2231, 2234, 2225, 2252, 2199, 2203, 2201, 2186, 2188,
- /*   480 */  2204, 2166, 2170, 2207, 2209, 2262, 2268, 2227, 2235, 2266,
- /*   490 */  2237, 2242, 2174, 2179, 2180, 2184, 2121, 2175, 2182, 2176,
- /*   500 */  2183, 2187, 2131, 2132, 2260, 2293, 2295, 2296, 2297, 2272,
- /*   510 */  2274, 2283, 2286, 2287, 2276, 2303,
+ /*   180 */  -227, -227, -227, -227, -227, -227, -227,  633, -199, 1218,
+ /*   190 */   -17,  605, -211, -208, 1232, 1267, 1407, 1448, 1506, 1604,
+ /*   200 */  1724, 1028, -120,  381, 1739,  536, -140,  422,  482, -227,
+ /*   210 */   770,  848, 1198, 1281,  484, -227, -227, -227, -227, -241,
+ /*   220 */  -241, -241,  266,  726,  917,  175, -207,  -80,  293,  940,
+ /*   230 */  -246, -226,  178,  446, -257, -257,   20,  -84,  -99,  490,
+ /*   240 */   461,  858, 1030, 1032, 1099,  777,  867,  817,  947, 1043,
+ /*   250 */  1060, 1110,  638, 1158, 1042,  951, 1157, 1211, 1170,   26,
+ /*   260 */  1309, 1336,  966, 1194, 1367, 1233,  551, 1458, 1363, 1387,
+ /*   270 */  1429, 1543, 1568, 1576, 1595,  572, 1613, -370,  279,  426,
+ /*   280 */   460,  511,  821,  648,  886,  965, 1038,  511, 1088, 1213,
+ /*   290 */  1269, 1294, 1385, 1388, 1497, 1645, 1673, 1693, 1709, 1729,
+ /*   300 */  1746, 1766, 1773, 1789, 1794, 1806, 1819, 1833, 1842, 1844,
+ /*   310 */  1863, 1874, 1878, 1896, 1901, 1908, 1915, 1935,  933, 1939,
+ /*   320 */  1942, 1947, 1952, 1955, 1960, 1962, 1967, 1969, 1970, 1972,
+ /*   330 */  1440, 1532, 1584, 1981, 1984, 1989, 1994, 1052, 1996, 2000,
+ /*   340 */  1658, 1627, 1959, 2004, 1692, 2007,  511, 1722, 1785, 1870,
+ /*   350 */  1883, 1948, 1907, 1928, 1941, 1052, 1943, 1992, 1992, 2015,
+ /*   360 */  1992, 1891, 1884, 1865, 1903, 1963, 1974, 1978, 1973, 1987,
+ /*   370 */  1946, 1977, 1997, 2006, 1983, 2008, 1975, 1988, 2032, 2030,
+ /*   380 */  2046, 2033, 2038, 2012, 2021, 2027, 2028, 2017, 2034, 2049,
+ /*   390 */  2047, 2048, 2090, 2119, 2018, 2014, 2029, 2013, 2020, 2002,
+ /*   400 */  2039, 2043, 2023, 2041, 2042, 2050, 2020, 2037, 2040, 2159,
+ /*   410 */  2054, 2055, 2069, 2059, 2078, 2073, 2112, 2115, 2210, 2212,
+ /*   420 */  2213, 2147, 2149, 2155, 2156, 2157, 2161, 2162, 2168, 2171,
+ /*   430 */  2172, 2173, 2188, 2185, 2193, 2192, 2202, 2196, 2198, 2252,
+ /*   440 */  2225, 2194, 2257, 2228, 2200, 2209, 2214, 2201, 2207, 2216,
+ /*   450 */  2205, 2221, 2234, 2272, 2242, 2189, 2197, 2277, 2248, 2280,
+ /*   460 */  2250, 2247, 2263, 2265, 2266, 2273, 2264, 2267, 2254, 2274,
+ /*   470 */  2284, 2276, 2281, 2278, 2279, 2268, 2302, 2249, 2251, 2253,
+ /*   480 */  2236, 2238, 2255, 2203, 2208, 2256, 2259, 2311, 2317, 2283,
+ /*   490 */  2285, 2316, 2287, 2289, 2215, 2226, 2229, 2231, 2169, 2217,
+ /*   500 */  2219, 2220, 2222, 2227, 2178, 2179, 2315, 2340, 2342, 2343,
+ /*   510 */  2344, 2319, 2330, 2331, 2335, 2338, 2322, 2356,
 };
 static const YYACTIONTYPE yy_default[] = {
- /*     0 */  1779, 1779, 1779, 1833, 1639, 1927, 1639, 1639, 1639, 1639,
- /*    10 */  1639, 1639, 1639, 1833, 1833, 1833, 1639, 1639, 1639, 1639,
- /*    20 */  1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639,
- /*    30 */  1639, 1698, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639,
- /*    40 */  1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639,
- /*    50 */  1856, 1856, 1990, 1905, 1639, 1639, 1639, 1639, 1639, 1639,
- /*    60 */  1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639,
- /*    70 */  1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639,
- /*    80 */  1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639,
- /*    90 */  1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639,
- /*   100 */  1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639,
- /*   110 */  1639, 1639, 2035, 2035, 1639, 1639, 1639, 1639, 1639, 1639,
- /*   120 */  1639, 1639, 1639, 1639, 1639, 1639, 1781, 1780, 1639, 1639,
- /*   130 */  2119, 1923, 1639, 1639, 1639, 1800, 1639, 1639, 1639, 1639,
- /*   140 */  1639, 1639, 1834, 1835, 1639, 1639, 1639, 1639, 2154, 2130,
- /*   150 */  1994, 1987, 1991, 1806, 1805, 1804, 1803, 1955, 1937, 1915,
- /*   160 */  1919, 1925, 1924, 1834, 1694, 1695, 1693, 1697, 1639, 1835,
- /*   170 */  1825, 1831, 1824, 1690, 1684, 1683, 1682, 1823, 1691, 1687,
- /*   180 */  1681, 1822, 1826, 1820, 1639, 1703, 1639, 1639, 1639, 1639,
- /*   190 */  1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 2007, 1759,
- /*   200 */  1639, 1639, 1639, 1639, 1639, 1837, 1821, 1905, 1838, 1651,
- /*   210 */  1649, 1639, 1828, 1827, 1830, 1829, 1876, 1709, 1708, 1639,
- /*   220 */  1639, 1639, 1995, 1639, 1639, 1639, 1639, 1639, 1639, 1639,
- /*   230 */  2035, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639,
- /*   240 */  1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639,
- /*   250 */  1639, 1639, 1939, 1639, 2035, 2035, 1639, 1905, 2035, 2035,
- /*   260 */  2081, 1797, 1797, 1654, 1920, 1654, 2075, 2061, 2018, 1904,
- /*   270 */  1904, 1904, 1904, 1927, 1904, 1639, 1639, 1639, 1639, 1639,
- /*   280 */  1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639,
- /*   290 */  1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639,
- /*   300 */  1639, 1639, 1639, 1639, 1639, 1639, 1639, 1984, 1982, 1639,
- /*   310 */  1889, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639,
- /*   320 */  1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639,
- /*   330 */  1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1908, 1639,
- /*   340 */  1639, 1639, 1639, 1639, 1639, 1639, 1884, 1639, 1948, 1763,
- /*   350 */  1908, 1908, 1908, 1913, 1908, 1765, 1764, 1911, 1897, 1639,
- /*   360 */  1639, 2128, 2005, 1878, 1809, 1799, 1912, 1799, 1960, 1914,
- /*   370 */  1809, 1809, 1914, 1809, 1912, 1960, 1730, 1753, 1723, 1856,
- /*   380 */  1639, 1939, 1939, 1939, 1939, 1912, 1920, 1920, 1856, 1856,
- /*   390 */  1696, 1911, 1639, 1639, 1639, 2067, 2152, 2149, 2149, 2149,
- /*   400 */  2105, 2103, 2105, 2103, 2151, 2084, 2084, 1675, 1639, 1639,
- /*   410 */  1639, 2067, 2069, 1995, 1989, 1989, 1675, 1675, 1675, 1892,
- /*   420 */  1892, 1888, 1888, 1888, 1878, 1878, 1868, 1868, 1868, 1868,
- /*   430 */  1816, 1807, 1922, 1920, 1788, 1922, 1920, 1675, 2002, 1914,
- /*   440 */  1675, 2002, 1914, 1816, 1816, 1914, 1807, 1788, 1914, 1788,
- /*   450 */  1773, 1675, 2002, 1954, 1952, 1675, 2002, 1675, 2002, 1773,
- /*   460 */  1761, 1761, 1761, 1745, 1639, 1639, 1773, 1761, 1730, 1761,
- /*   470 */  1745, 1761, 1761, 1748, 1675, 1922, 1920, 1922, 1918, 1916,
- /*   480 */  1914, 2045, 2045, 1859, 1859, 1677, 1675, 1777, 1777, 1639,
- /*   490 */  1639, 1773, 2053, 2023, 2023, 2018, 2161, 2082, 2081, 2082,
- /*   500 */  2081, 2082, 2143, 2143, 1711, 1905, 1905, 1905, 1905, 1711,
- /*   510 */  1732, 1732, 1763, 1763, 1711, 1905, 1639, 1639, 1639, 1639,
- /*   520 */  1639, 1639, 1639, 1639, 1655, 1639, 1639, 1639, 1639, 1639,
- /*   530 */  1639, 2093, 1639, 1639, 1639, 1639, 2093, 1639, 1967, 1877,
- /*   540 */  1793, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639,
- /*   550 */  1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1770,
- /*   560 */  1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1661,
- /*   570 */  1639, 1997, 2165, 1639, 1639, 1639, 1639, 2013, 1639, 1639,
- /*   580 */  1639, 1639, 1639, 1639, 1639, 2076, 1639, 1639, 1639, 1639,
- /*   590 */  1639, 1639, 1639, 1639, 1639, 2062, 1639, 1639, 1639, 1639,
- /*   600 */  1639, 2142, 1639, 2129, 1639, 2139, 1639, 1639, 1639, 2150,
- /*   610 */  2137, 1639, 2136, 2093, 1639, 2135, 1639, 2134, 2133, 2132,
- /*   620 */  1639, 1639, 1639, 2094, 1639, 1639, 1639, 1639, 2064, 1639,
- /*   630 */  1639, 1639, 2063, 1639, 1639, 1639, 1639, 2059, 1639, 1639,
- /*   640 */  1639, 1639, 1639, 1639, 1883, 1639, 1639, 1639, 1639, 1639,
- /*   650 */  1639, 1639, 1639, 1639, 1794, 1801, 1802, 1639, 1639, 1639,
- /*   660 */  1639, 1639, 1639, 1639, 1639, 1639, 1815, 1639, 1639, 1639,
- /*   670 */  1810, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1958,
- /*   680 */  1639, 1639, 1639, 1639, 1951, 1950, 1639, 1639, 1865, 1639,
- /*   690 */  1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639,
- /*   700 */  1639, 1728, 1639, 1639, 1639, 1639, 1639, 1639, 1701, 1639,
- /*   710 */  1639, 1639, 1639, 1639, 1639, 1639, 1917, 1639, 1639, 1639,
- /*   720 */  1639, 2050, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639,
- /*   730 */  1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639, 1639,
- /*   740 */  1921, 1639, 1639, 1832, 1639, 1639, 1639, 1639, 1639, 2012,
- /*   750 */  1639, 2011, 1639, 1639, 1639, 1639, 1639, 1846, 1639, 1639,
- /*   760 */  1639, 1639, 1665, 1639, 1639, 1639, 1662, 1639, 1639, 1639,
- /*   770 */  1639, 1639, 1639, 1639, 1639,
+ /*     0 */  1777, 1777, 1777, 1831, 1637, 1925, 1637, 1637, 1637, 1637,
+ /*    10 */  1637, 1637, 1637, 1637, 1637, 1831, 1831, 1831, 1637, 1637,
+ /*    20 */  1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637,
+ /*    30 */  1637, 1637, 1637, 1637, 1696, 1637, 1637, 1637, 1637, 1637,
+ /*    40 */  1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637,
+ /*    50 */  1637, 1854, 1854, 1988, 1903, 1637, 1637, 1637, 1637, 1637,
+ /*    60 */  1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637,
+ /*    70 */  1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637,
+ /*    80 */  1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637,
+ /*    90 */  1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637,
+ /*   100 */  1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637,
+ /*   110 */  1637, 1637, 1637, 1637, 2033, 2033, 1637, 1637, 1637, 1637,
+ /*   120 */  1637, 1637, 1637, 1637, 1637, 1637, 1637, 1779, 1778, 1637,
+ /*   130 */  1637, 2117, 1921, 1637, 1637, 2105, 1637, 1798, 1637, 1637,
+ /*   140 */  1637, 1637, 1637, 1637, 1832, 1833, 1637, 1637, 1637, 1637,
+ /*   150 */  2152, 2114, 2128, 1992, 1985, 1989, 1804, 1803, 1802, 1801,
+ /*   160 */  1953, 1935, 1913, 1917, 1923, 1922, 1832, 1692, 1693, 1691,
+ /*   170 */  1695, 1637, 1833, 1823, 1829, 1822, 1688, 1682, 1681, 1680,
+ /*   180 */  1821, 1689, 1685, 1679, 1820, 1824, 1818, 1637, 1701, 1637,
+ /*   190 */  1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637,
+ /*   200 */  1637, 2005, 1757, 1637, 1637, 1637, 1637, 1637, 1835, 1819,
+ /*   210 */  1903, 1836, 1649, 1647, 1637, 1826, 1825, 1828, 1827, 1874,
+ /*   220 */  1707, 1706, 1637, 1637, 1637, 1993, 1637, 1637, 1637, 1637,
+ /*   230 */  1637, 1637, 1637, 2033, 1637, 1637, 1637, 1637, 1637, 1637,
+ /*   240 */  1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637,
+ /*   250 */  1637, 1637, 1637, 1637, 1937, 1637, 2033, 2033, 1637, 1903,
+ /*   260 */  2033, 2033, 2079, 1795, 1795, 1652, 1918, 1652, 2073, 2059,
+ /*   270 */  2016, 1902, 1902, 1902, 1902, 1925, 1902, 1637, 1637, 1637,
+ /*   280 */  1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637,
+ /*   290 */  1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637,
+ /*   300 */  1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1982,
+ /*   310 */  1980, 1637, 1887, 1637, 1637, 1637, 1637, 1637, 1637, 1637,
+ /*   320 */  1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637,
+ /*   330 */  1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637,
+ /*   340 */  1906, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1882, 1637,
+ /*   350 */  1946, 1761, 1906, 1906, 1906, 1911, 1906, 1763, 1762, 1909,
+ /*   360 */  1895, 1637, 1637, 2126, 2003, 1876, 1807, 1797, 1910, 1797,
+ /*   370 */  1958, 1912, 1807, 1807, 1912, 1807, 1910, 1958, 1728, 1751,
+ /*   380 */  1721, 1854, 1637, 1937, 1937, 1937, 1937, 1910, 1918, 1918,
+ /*   390 */  1854, 1854, 1694, 1909, 1637, 1637, 1637, 2065, 2150, 2147,
+ /*   400 */  2147, 2147, 2103, 2101, 2103, 2101, 2149, 2082, 2082, 1673,
+ /*   410 */  1637, 1637, 1637, 2065, 2067, 1993, 1987, 1987, 1673, 1673,
+ /*   420 */  1673, 1890, 1890, 1886, 1886, 1886, 1876, 1876, 1866, 1866,
+ /*   430 */  1866, 1866, 1814, 1805, 1920, 1918, 1786, 1920, 1918, 1673,
+ /*   440 */  2000, 1912, 1673, 2000, 1912, 1814, 1814, 1912, 1805, 1786,
+ /*   450 */  1912, 1786, 1771, 1673, 2000, 1952, 1950, 1673, 2000, 1673,
+ /*   460 */  2000, 1771, 1759, 1759, 1759, 1743, 1637, 1637, 1771, 1759,
+ /*   470 */  1728, 1759, 1743, 1759, 1759, 1746, 1673, 1920, 1918, 1920,
+ /*   480 */  1916, 1914, 1912, 2043, 2043, 1857, 1857, 1675, 1673, 1775,
+ /*   490 */  1775, 1637, 1637, 1771, 2051, 2021, 2021, 2016, 2159, 2080,
+ /*   500 */  2079, 2080, 2079, 2080, 2141, 2141, 1709, 1903, 1903, 1903,
+ /*   510 */  1903, 1709, 1730, 1730, 1761, 1761, 1709, 1903, 1637, 1637,
+ /*   520 */  1637, 1637, 1637, 1637, 1637, 1637, 1653, 1637, 1637, 1637,
+ /*   530 */  1637, 1637, 1637, 2091, 1637, 1637, 1637, 1637, 1637, 1965,
+ /*   540 */  1875, 1791, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637,
+ /*   550 */  1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637,
+ /*   560 */  1768, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637,
+ /*   570 */  1659, 1637, 1995, 2163, 1637, 1637, 1637, 1637, 2011, 1637,
+ /*   580 */  1637, 1637, 1637, 1637, 1637, 1637, 2074, 1637, 1637, 1637,
+ /*   590 */  1637, 1637, 1637, 1637, 1637, 1637, 2060, 1637, 1637, 1637,
+ /*   600 */  1637, 1637, 2140, 1637, 2127, 2092, 1637, 2137, 1637, 1637,
+ /*   610 */  1637, 2148, 2135, 1637, 2134, 1637, 2133, 1637, 2132, 2131,
+ /*   620 */  2130, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 2062,
+ /*   630 */  1637, 1637, 1637, 2061, 1637, 1637, 1637, 1637, 2057, 1637,
+ /*   640 */  1637, 1637, 1637, 1637, 1637, 1881, 1637, 1637, 1637, 1637,
+ /*   650 */  1637, 1637, 1637, 1637, 1637, 1792, 1799, 1800, 1637, 1637,
+ /*   660 */  1637, 1637, 1637, 1637, 1637, 1637, 1637, 1813, 1637, 1637,
+ /*   670 */  1637, 1808, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637,
+ /*   680 */  1956, 1637, 1637, 1637, 1637, 1949, 1948, 1637, 1637, 1863,
+ /*   690 */  1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637,
+ /*   700 */  1637, 1637, 1726, 1637, 1637, 1637, 1637, 1637, 1637, 1699,
+ /*   710 */  1637, 1637, 1637, 1637, 1637, 1637, 1637, 1915, 1637, 1637,
+ /*   720 */  1637, 1637, 2048, 1637, 1637, 1637, 1637, 1637, 1637, 1637,
+ /*   730 */  1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637, 1637,
+ /*   740 */  1637, 1919, 1637, 1637, 1830, 1637, 1637, 1637, 1637, 1637,
+ /*   750 */  2010, 1637, 2009, 1637, 1637, 1637, 1637, 1637, 1844, 1637,
+ /*   760 */  1637, 1637, 1637, 1663, 1637, 1637, 1637, 1660, 1637, 1637,
+ /*   770 */  1637, 1637, 1637, 1637, 1637, 1637,
 };
 /********** End of lemon-generated parsing tables *****************************/
 
@@ -15756,8 +15800,8 @@
  /* 462 */ "perfetto_pipe_except ::= EXCEPT LP perfetto_pipe_name_list RP",
  /* 463 */ "perfetto_pipe_replace ::=",
  /* 464 */ "perfetto_pipe_replace ::= REPLACE LP perfetto_pipe_replace_list RP",
- /* 465 */ "perfetto_pipe_select_item ::= perfetto_pipe_column",
- /* 466 */ "perfetto_pipe_select_item ::= perfetto_pipe_named_column",
+ /* 465 */ "perfetto_pipe_select_item ::= expr",
+ /* 466 */ "perfetto_pipe_select_item ::= expr AS nm",
  /* 467 */ "perfetto_pipe_select_item ::= STAR perfetto_pipe_except perfetto_pipe_replace",
  /* 468 */ "perfetto_pipe_select_item ::= nm DOT STAR perfetto_pipe_except perfetto_pipe_replace",
  /* 469 */ "perfetto_pipe_select_list ::= perfetto_pipe_select_item",
@@ -15765,7 +15809,7 @@
  /* 471 */ "perfetto_pipe_rename_item ::= nm AS nm",
  /* 472 */ "perfetto_pipe_rename_list ::= perfetto_pipe_rename_item",
  /* 473 */ "perfetto_pipe_rename_list ::= perfetto_pipe_rename_list COMMA perfetto_pipe_rename_item",
- /* 474 */ "perfetto_pipe_set_item ::= nm EQ perfetto_pipe_column",
+ /* 474 */ "perfetto_pipe_set_item ::= nm EQ expr",
  /* 475 */ "perfetto_pipe_set_list ::= perfetto_pipe_set_item",
  /* 476 */ "perfetto_pipe_set_list ::= perfetto_pipe_set_list COMMA perfetto_pipe_set_item",
  /* 477 */ "perfetto_pipe_order_term ::= expr",
@@ -16706,8 +16750,8 @@
    369,  /* (462) perfetto_pipe_except ::= EXCEPT LP perfetto_pipe_name_list RP */
    370,  /* (463) perfetto_pipe_replace ::= */
    370,  /* (464) perfetto_pipe_replace ::= REPLACE LP perfetto_pipe_replace_list RP */
-   371,  /* (465) perfetto_pipe_select_item ::= perfetto_pipe_column */
-   371,  /* (466) perfetto_pipe_select_item ::= perfetto_pipe_named_column */
+   371,  /* (465) perfetto_pipe_select_item ::= expr */
+   371,  /* (466) perfetto_pipe_select_item ::= expr AS nm */
    371,  /* (467) perfetto_pipe_select_item ::= STAR perfetto_pipe_except perfetto_pipe_replace */
    371,  /* (468) perfetto_pipe_select_item ::= nm DOT STAR perfetto_pipe_except perfetto_pipe_replace */
    372,  /* (469) perfetto_pipe_select_list ::= perfetto_pipe_select_item */
@@ -16715,7 +16759,7 @@
    373,  /* (471) perfetto_pipe_rename_item ::= nm AS nm */
    374,  /* (472) perfetto_pipe_rename_list ::= perfetto_pipe_rename_item */
    374,  /* (473) perfetto_pipe_rename_list ::= perfetto_pipe_rename_list COMMA perfetto_pipe_rename_item */
-   375,  /* (474) perfetto_pipe_set_item ::= nm EQ perfetto_pipe_column */
+   375,  /* (474) perfetto_pipe_set_item ::= nm EQ expr */
    376,  /* (475) perfetto_pipe_set_list ::= perfetto_pipe_set_item */
    376,  /* (476) perfetto_pipe_set_list ::= perfetto_pipe_set_list COMMA perfetto_pipe_set_item */
    377,  /* (477) perfetto_pipe_order_term ::= expr */
@@ -17236,8 +17280,8 @@
    -4,  /* (462) perfetto_pipe_except ::= EXCEPT LP perfetto_pipe_name_list RP */
     0,  /* (463) perfetto_pipe_replace ::= */
    -4,  /* (464) perfetto_pipe_replace ::= REPLACE LP perfetto_pipe_replace_list RP */
-   -1,  /* (465) perfetto_pipe_select_item ::= perfetto_pipe_column */
-   -1,  /* (466) perfetto_pipe_select_item ::= perfetto_pipe_named_column */
+   -1,  /* (465) perfetto_pipe_select_item ::= expr */
+   -3,  /* (466) perfetto_pipe_select_item ::= expr AS nm */
    -3,  /* (467) perfetto_pipe_select_item ::= STAR perfetto_pipe_except perfetto_pipe_replace */
    -5,  /* (468) perfetto_pipe_select_item ::= nm DOT STAR perfetto_pipe_except perfetto_pipe_replace */
    -1,  /* (469) perfetto_pipe_select_list ::= perfetto_pipe_select_item */
@@ -17245,7 +17289,7 @@
    -3,  /* (471) perfetto_pipe_rename_item ::= nm AS nm */
    -1,  /* (472) perfetto_pipe_rename_list ::= perfetto_pipe_rename_item */
    -3,  /* (473) perfetto_pipe_rename_list ::= perfetto_pipe_rename_list COMMA perfetto_pipe_rename_item */
-   -3,  /* (474) perfetto_pipe_set_item ::= nm EQ perfetto_pipe_column */
+   -3,  /* (474) perfetto_pipe_set_item ::= nm EQ expr */
    -1,  /* (475) perfetto_pipe_set_list ::= perfetto_pipe_set_item */
    -3,  /* (476) perfetto_pipe_set_list ::= perfetto_pipe_set_list COMMA perfetto_pipe_set_item */
    -1,  /* (477) perfetto_pipe_order_term ::= expr */
@@ -20032,8 +20076,6 @@
         break;
       case 420: /* perfetto_arg_def_list ::= perfetto_arg_def_list_ne */
       case 434: /* perfetto_macro_arg_list ::= perfetto_macro_arg_list_ne */ yytestcase(yyruleno==434);
-      case 465: /* perfetto_pipe_select_item ::= perfetto_pipe_column */ yytestcase(yyruleno==465);
-      case 466: /* perfetto_pipe_select_item ::= perfetto_pipe_named_column */ yytestcase(yyruleno==466);
       case 482: /* perfetto_pipe_group_item ::= perfetto_pipe_column */ yytestcase(yyruleno==482);
       case 483: /* perfetto_pipe_group_item ::= perfetto_pipe_named_column */ yytestcase(yyruleno==483);
       case 511: /* cmd ::= perfetto_pipeline */ yytestcase(yyruleno==511);
@@ -20275,6 +20317,18 @@
     yymsp[-3].minor.yy141 = yymsp[-1].minor.yy141;
 }
         break;
+      case 465: /* perfetto_pipe_select_item ::= expr */
+{
+    yylhsminor.yy141 = synq_parse_perfetto_pipe_expr_item(pCtx, yymsp[0].minor.yy141, SYNQ_NO_SPAN);
+}
+  yymsp[0].minor.yy141 = yylhsminor.yy141;
+        break;
+      case 466: /* perfetto_pipe_select_item ::= expr AS nm */
+{
+    yylhsminor.yy141 = synq_parse_perfetto_pipe_expr_item(pCtx, yymsp[-2].minor.yy141, synq_span_dequote(pCtx, yymsp[0].minor.yy0));
+}
+  yymsp[-2].minor.yy141 = yylhsminor.yy141;
+        break;
       case 467: /* perfetto_pipe_select_item ::= STAR perfetto_pipe_except perfetto_pipe_replace */
 {
     yymsp[-2].minor.yy141 = synq_parse_perfetto_pipe_star(pCtx, SYNQ_NO_SPAN, yymsp[-1].minor.yy141, yymsp[0].minor.yy141);
@@ -20299,7 +20353,7 @@
 }
   yymsp[-2].minor.yy141 = yylhsminor.yy141;
         break;
-      case 474: /* perfetto_pipe_set_item ::= nm EQ perfetto_pipe_column */
+      case 474: /* perfetto_pipe_set_item ::= nm EQ expr */
 {
     yylhsminor.yy141 = synq_parse_perfetto_pipe_set_item(pCtx, synq_span_dequote(pCtx, yymsp[-2].minor.yy0), yymsp[0].minor.yy141);
 }
diff --git a/src/perfetto_sql/syntaqlite/syntaqlite_perfetto.h b/src/perfetto_sql/syntaqlite/syntaqlite_perfetto.h
index 11130c1..47908f7 100644
--- a/src/perfetto_sql/syntaqlite/syntaqlite_perfetto.h
+++ b/src/perfetto_sql/syntaqlite/syntaqlite_perfetto.h
@@ -2398,29 +2398,30 @@
     SYNTAQLITE_NODE_PERFETTO_PIPE_NAME = 111,
     SYNTAQLITE_NODE_PERFETTO_PIPE_NAME_LIST = 112,
     SYNTAQLITE_NODE_PERFETTO_PIPE_STAR = 113,
-    SYNTAQLITE_NODE_PERFETTO_PIPE_SELECT_ITEM_LIST = 114,
-    SYNTAQLITE_NODE_PERFETTO_PIPE_SELECT = 115,
-    SYNTAQLITE_NODE_PERFETTO_PIPE_EXTEND = 116,
-    SYNTAQLITE_NODE_PERFETTO_PIPE_DROP = 117,
-    SYNTAQLITE_NODE_PERFETTO_PIPE_RENAME = 118,
-    SYNTAQLITE_NODE_PERFETTO_PIPE_SET_ITEM = 119,
-    SYNTAQLITE_NODE_PERFETTO_PIPE_SET_ITEM_LIST = 120,
-    SYNTAQLITE_NODE_PERFETTO_PIPE_SET = 121,
-    SYNTAQLITE_NODE_PERFETTO_PIPE_AS = 122,
-    SYNTAQLITE_NODE_PERFETTO_PIPE_ORDER_TERM = 123,
-    SYNTAQLITE_NODE_PERFETTO_PIPE_ORDER_TERM_LIST = 124,
-    SYNTAQLITE_NODE_PERFETTO_PIPE_ORDER_BY = 125,
-    SYNTAQLITE_NODE_PERFETTO_PIPE_AGGREGATE = 126,
-    SYNTAQLITE_NODE_PERFETTO_PIPE_WHERE = 127,
-    SYNTAQLITE_NODE_PERFETTO_PIPE_DISTINCT = 128,
-    SYNTAQLITE_NODE_PERFETTO_PIPE_STAGE_LIST = 129,
-    SYNTAQLITE_NODE_PERFETTO_PIPE_SOURCE_LIST = 130,
-    SYNTAQLITE_NODE_PERFETTO_PER_COLUMN = 131,
-    SYNTAQLITE_NODE_PERFETTO_PER_COLUMN_LIST = 132,
-    SYNTAQLITE_NODE_PERFETTO_INTERVAL_FLATTEN = 133,
-    SYNTAQLITE_NODE_PERFETTO_INTERVAL_FILL_GAPS = 134,
-    SYNTAQLITE_NODE_PERFETTO_INTERVAL_INTERSECTION = 135,
-    SYNTAQLITE_NODE_PERFETTO_PIPELINE = 136,
+    SYNTAQLITE_NODE_PERFETTO_PIPE_EXPR_ITEM = 114,
+    SYNTAQLITE_NODE_PERFETTO_PIPE_SELECT_ITEM_LIST = 115,
+    SYNTAQLITE_NODE_PERFETTO_PIPE_SELECT = 116,
+    SYNTAQLITE_NODE_PERFETTO_PIPE_EXTEND = 117,
+    SYNTAQLITE_NODE_PERFETTO_PIPE_DROP = 118,
+    SYNTAQLITE_NODE_PERFETTO_PIPE_RENAME = 119,
+    SYNTAQLITE_NODE_PERFETTO_PIPE_SET_ITEM = 120,
+    SYNTAQLITE_NODE_PERFETTO_PIPE_SET_ITEM_LIST = 121,
+    SYNTAQLITE_NODE_PERFETTO_PIPE_SET = 122,
+    SYNTAQLITE_NODE_PERFETTO_PIPE_AS = 123,
+    SYNTAQLITE_NODE_PERFETTO_PIPE_ORDER_TERM = 124,
+    SYNTAQLITE_NODE_PERFETTO_PIPE_ORDER_TERM_LIST = 125,
+    SYNTAQLITE_NODE_PERFETTO_PIPE_ORDER_BY = 126,
+    SYNTAQLITE_NODE_PERFETTO_PIPE_AGGREGATE = 127,
+    SYNTAQLITE_NODE_PERFETTO_PIPE_WHERE = 128,
+    SYNTAQLITE_NODE_PERFETTO_PIPE_DISTINCT = 129,
+    SYNTAQLITE_NODE_PERFETTO_PIPE_STAGE_LIST = 130,
+    SYNTAQLITE_NODE_PERFETTO_PIPE_SOURCE_LIST = 131,
+    SYNTAQLITE_NODE_PERFETTO_PER_COLUMN = 132,
+    SYNTAQLITE_NODE_PERFETTO_PER_COLUMN_LIST = 133,
+    SYNTAQLITE_NODE_PERFETTO_INTERVAL_FLATTEN = 134,
+    SYNTAQLITE_NODE_PERFETTO_INTERVAL_FILL_GAPS = 135,
+    SYNTAQLITE_NODE_PERFETTO_INTERVAL_INTERSECTION = 136,
+    SYNTAQLITE_NODE_PERFETTO_PIPELINE = 137,
     SYNTAQLITE_NODE_COUNT
 } SyntaqliteNodeTag;
 SYNQ_STATIC_ASSERT(sizeof(SyntaqliteNodeTag) == sizeof(uint32_t),
@@ -3291,6 +3292,12 @@
     uint32_t replace;
 } SyntaqlitePerfettoPipeStar;
 
+typedef struct SyntaqlitePerfettoPipeExprItem {
+    SyntaqliteNodeTag tag;
+    uint32_t expr;
+    SyntaqliteTextSpan alias;
+} SyntaqlitePerfettoPipeExprItem;
+
 // List of PerfettoPipeSelectItem
 typedef struct SyntaqlitePerfettoPipeSelectItemList {
     uint32_t tag;
@@ -3542,6 +3549,7 @@
     SyntaqlitePerfettoPipeName perfetto_pipe_name;
     SyntaqlitePerfettoPipeNameList perfetto_pipe_name_list;
     SyntaqlitePerfettoPipeStar perfetto_pipe_star;
+    SyntaqlitePerfettoPipeExprItem perfetto_pipe_expr_item;
     SyntaqlitePerfettoPipeSelectItemList perfetto_pipe_select_item_list;
     SyntaqlitePerfettoPipeSelect perfetto_pipe_select;
     SyntaqlitePerfettoPipeExtend perfetto_pipe_extend;
@@ -4057,20 +4065,20 @@
 
 typedef union SyntaqlitePerfettoPipeSelectItem {
     SyntaqliteNodeTag tag;
-    SyntaqlitePerfettoPipeColumn perfetto_pipe_column;
+    SyntaqlitePerfettoPipeExprItem perfetto_pipe_expr_item;
     SyntaqlitePerfettoPipeStar perfetto_pipe_star;
 } SyntaqlitePerfettoPipeSelectItem;
 
 static inline int syntaqlite_is_perfetto_pipe_select_item(SyntaqliteNodeTag tag) {
     switch (tag) {
-        case SYNTAQLITE_NODE_PERFETTO_PIPE_COLUMN: return 1;
+        case SYNTAQLITE_NODE_PERFETTO_PIPE_EXPR_ITEM: return 1;
         case SYNTAQLITE_NODE_PERFETTO_PIPE_STAR: return 1;
         default: return 0;
     }
 }
 
-static inline const SyntaqlitePerfettoPipeColumn* syntaqlite_perfetto_pipe_select_item_as_perfetto_pipe_column(const SyntaqlitePerfettoPipeSelectItem* node) {
-    return node->tag == SYNTAQLITE_NODE_PERFETTO_PIPE_COLUMN ? &node->perfetto_pipe_column : NULL;
+static inline const SyntaqlitePerfettoPipeExprItem* syntaqlite_perfetto_pipe_select_item_as_perfetto_pipe_expr_item(const SyntaqlitePerfettoPipeSelectItem* node) {
+    return node->tag == SYNTAQLITE_NODE_PERFETTO_PIPE_EXPR_ITEM ? &node->perfetto_pipe_expr_item : NULL;
 }
 
 static inline const SyntaqlitePerfettoPipeStar* syntaqlite_perfetto_pipe_select_item_as_perfetto_pipe_star(const SyntaqlitePerfettoPipeSelectItem* node) {
@@ -4629,6 +4637,10 @@
   static constexpr bool kHasTag = true;
   static constexpr uint32_t kValue = SYNTAQLITE_NODE_PERFETTO_PIPE_STAR;
 };
+template <> struct NodeTag<SyntaqlitePerfettoPipeExprItem> {
+  static constexpr bool kHasTag = true;
+  static constexpr uint32_t kValue = SYNTAQLITE_NODE_PERFETTO_PIPE_EXPR_ITEM;
+};
 template <> struct NodeTag<SyntaqlitePerfettoPipeSelectItemList> {
   static constexpr bool kHasTag = true;
   static constexpr uint32_t kValue = SYNTAQLITE_NODE_PERFETTO_PIPE_SELECT_ITEM_LIST;
diff --git a/src/tools/proto_merger/allowlist.cc b/src/tools/proto_merger/allowlist.cc
index 295e7bb..bccbdef 100644
--- a/src/tools/proto_merger/allowlist.cc
+++ b/src/tools/proto_merger/allowlist.cc
@@ -16,6 +16,8 @@
 
 #include "src/tools/proto_merger/allowlist.h"
 
+#include <set>
+
 #include <google/protobuf/descriptor.pb.h>
 
 #include "perfetto/ext/base/string_utils.h"
@@ -68,6 +70,19 @@
   containing.enums.emplace(name);
 }
 
+void AllowlistFieldAndContainingMessage(
+    const google::protobuf::FieldDescriptor& desc,
+    Allowlist& allowlist) {
+  auto& containing =
+      ResolveMessageForDescriptor(*desc.containing_type(), allowlist);
+  if (desc.containing_oneof()) {
+    containing.oneofs[std::string(desc.containing_oneof()->name())].emplace(
+        desc.number());
+  } else {
+    containing.fields.emplace(desc.number());
+  }
+}
+
 void AllowlistField(const google::protobuf::FieldDescriptor& desc,
                     Allowlist& allowlist) {
   auto& containing =
@@ -90,6 +105,8 @@
   if (desc.is_map()) {
     const auto* val_field = desc.message_type()->field(1);
     if (val_field->type() == google::protobuf::FieldDescriptor::TYPE_MESSAGE) {
+      // Make sure the value type is allowed even if it has no fields.
+      ResolveMessageForDescriptor(*val_field->message_type(), allowlist);
       for (int i = 0; i < val_field->message_type()->field_count(); ++i) {
         AllowlistField(*val_field->message_type()->field(i), allowlist);
       }
@@ -102,8 +119,10 @@
 
   switch (desc.type()) {
     case google::protobuf::FieldDescriptor::TYPE_MESSAGE:
-      // For message types, we recursively allow all fields under it including
-      // any types those fields may depend on.
+      // For message types, we allow the message type itself (even if it has
+      // no fields, e.g. an empty marker message) and recursively allow all
+      // fields under it including any types those fields may depend on.
+      ResolveMessageForDescriptor(*desc.message_type(), allowlist);
       for (int i = 0; i < desc.message_type()->field_count(); ++i) {
         AllowlistField(*desc.message_type()->field(i), allowlist);
       }
@@ -149,6 +168,12 @@
     const google::protobuf::Descriptor& desc,
     const std::vector<std::string>& allowed_fields,
     Allowlist& allowlist) {
+  // Fields on the path to an approved field (but not the approved field
+  // itself), without duplicates. These are added after all the approved
+  // fields: AllowlistField() stops early for fields which are already allowed,
+  // so adding a parent first would stop a later approved field with the same
+  // descriptor (e.g. {"a.b", "a"}) from allowing everything inside it.
+  std::set<const google::protobuf::FieldDescriptor*> path_fields;
   for (const auto& field_path : allowed_fields) {
     std::vector<std::string> pieces = SplitFieldPath(field_path);
     const auto* current = &desc;
@@ -170,11 +195,21 @@
       if (field->type() != google::protobuf::FieldDescriptor::TYPE_MESSAGE) {
         return base::ErrStatus("Field %s in message %s has a non-message type",
                                std::string(field->name()).c_str(),
-                               std::string(desc.name()).c_str());
+                               std::string(current->name()).c_str());
       }
+      path_fields.insert(field);
       current = field->message_type();
     }
   }
+
+  // Allow the fields on the path and their message types so that the approved
+  // fields are actually reachable from the root, but *not* everything inside
+  // those messages: only the fields on the path are approved.
+  for (const auto* field : path_fields) {
+    AllowlistFieldAndContainingMessage(*field, allowlist);
+    if (!field->is_map())
+      ResolveMessageForDescriptor(*field->message_type(), allowlist);
+  }
   return base::OkStatus();
 }
 
diff --git a/src/tools/proto_merger/allowlist.h b/src/tools/proto_merger/allowlist.h
index fdb8180..3010215 100644
--- a/src/tools/proto_merger/allowlist.h
+++ b/src/tools/proto_merger/allowlist.h
@@ -48,7 +48,10 @@
 };
 
 // Creates a Allowlist struct from a list of allowed fields rooted at the given
-// descriptor.
+// descriptor. Each entry is a dot-separated path of field names (e.g.
+// "foo.bar.baz"): the last field is allowed together with everything inside
+// it, while the fields before it (and their message types) are allowed on
+// their own, without the other fields of those messages.
 base::Status AllowlistFromFieldList(
     const google::protobuf::Descriptor&,
     const std::vector<std::string>& allowed_fields,
diff --git a/src/tools/proto_merger/proto_file_serializer_unittest.cc b/src/tools/proto_merger/proto_file_serializer_unittest.cc
index 55f3d4c..5b928a3 100644
--- a/src/tools/proto_merger/proto_file_serializer_unittest.cc
+++ b/src/tools/proto_merger/proto_file_serializer_unittest.cc
@@ -1676,6 +1676,249 @@
               HasSubstr("extensions 100 to 199;\n"));
 }
 
+// Imports |input_name| and |upstream_name| from |dir|, allowlists
+// |allowed_fields| rooted at |root| in upstream, merges and returns the
+// serialized result. Also checks that the result is a valid proto.
+std::string MergeWithFieldList(const std::string& dir,
+                               const std::string& input_name,
+                               const std::string& upstream_name,
+                               const std::string& root,
+                               const std::vector<std::string>& allowed_fields) {
+  protozero::MultiFileErrorCollectorImpl mfe;
+  google::protobuf::compiler::DiskSourceTree dst;
+  dst.MapPath("", dir);
+  dst.MapPath("", "buildtools/protobuf/src");
+
+  google::protobuf::compiler::Importer importer_input(&dst, &mfe);
+  const auto* input_desc = importer_input.Import(input_name);
+  google::protobuf::compiler::Importer importer_upstream(&dst, &mfe);
+  const auto* upstream_desc = importer_upstream.Import(upstream_name);
+  EXPECT_NE(input_desc, nullptr);
+  EXPECT_NE(upstream_desc, nullptr);
+  if (!input_desc || !upstream_desc)
+    return "";
+
+  const auto* root_desc = upstream_desc->FindMessageTypeByName(root);
+  EXPECT_NE(root_desc, nullptr);
+  if (!root_desc)
+    return "";
+
+  Allowlist allowed;
+  base::Status status =
+      AllowlistFromFieldList(*root_desc, allowed_fields, allowed);
+  EXPECT_TRUE(status.ok()) << status.message();
+
+  ProtoFile input_file = ProtoFileFromDescriptor("", *input_desc);
+  ProtoFile upstream_file = ProtoFileFromDescriptor("", *upstream_desc);
+  ProtoFile merged;
+  status = MergeProtoFiles(input_file, upstream_file, allowed, merged);
+  EXPECT_TRUE(status.ok()) << status.message();
+  std::string out = ProtoFileToDotProto(merged);
+
+  // The merged output must be a self-contained, valid proto.
+  TempProtoFile merged_file(dir, "merged.proto",
+                            "syntax = \"proto3\";\n"
+                            "package perfetto.protos;\n" +
+                                out);
+  protozero::MultiFileErrorCollectorImpl mfe_merged;
+  google::protobuf::compiler::Importer importer_merged(&dst, &mfe_merged);
+  EXPECT_NE(importer_merged.Import("merged.proto"), nullptr) << out;
+  return out;
+}
+
+// Approving a deep field whose parents are missing downstream must also add
+// the parent fields and messages on the path (but nothing else inside them),
+// otherwise the approved field is unreachable from the root.
+TEST(AllowlistFromFieldListTest, AddsMissingParentFieldsOnPath) {
+  base::TempDir temp_dir = base::TempDir::Create();
+  TempProtoFile input(temp_dir.path(), "input.proto", R"(
+    syntax = "proto2";
+    package perfetto.protos;
+
+    message Root {
+      optional int32 existing = 1;
+    }
+  )");
+  TempProtoFile upstream(temp_dir.path(), "upstream.proto", R"(
+    syntax = "proto2";
+    package perfetto.protos;
+
+    message Leaf {
+      optional int32 leaf_value = 1;
+    }
+    message Patch {
+      optional int32 not_approved = 1;
+      optional Leaf approved = 11;
+    }
+    message Other {
+      optional int32 other_value = 1;
+    }
+    message Ext {
+      optional Patch patch = 7;
+      optional Other other = 8;
+    }
+    message Root {
+      optional int32 existing = 1;
+      optional Ext ext = 112;
+      optional int32 not_on_path = 113;
+    }
+  )");
+
+  std::string out =
+      MergeWithFieldList(temp_dir.path(), "input.proto", "upstream.proto",
+                         "Root", {"ext.patch.approved"});
+
+  // Path fields and messages.
+  EXPECT_THAT(FindMessageText(out, "Root"), HasSubstr("Ext ext = 112;"));
+  EXPECT_THAT(FindMessageText(out, "Ext"), HasSubstr("Patch patch = 7;"));
+  EXPECT_THAT(FindMessageText(out, "Patch"), HasSubstr("Leaf approved = 11;"));
+
+  // The approved field's type, with everything inside it.
+  EXPECT_THAT(FindMessageText(out, "Leaf"), HasSubstr("int32 leaf_value = 1;"));
+
+  // Nothing else inside the path messages.
+  EXPECT_THAT(out, Not(HasSubstr("not_on_path")));
+  EXPECT_THAT(out, Not(HasSubstr("not_approved")));
+  EXPECT_THAT(out, Not(HasSubstr("Other other")));
+  EXPECT_THAT(out, Not(HasSubstr("message Other")));
+}
+
+// A field whose type is a message with no fields must still bring that
+// message definition along, otherwise the merged proto doesn't compile.
+TEST(AllowlistFromFieldListTest, AddsEmptyMessageType) {
+  base::TempDir temp_dir = base::TempDir::Create();
+  TempProtoFile input(temp_dir.path(), "input.proto", R"(
+    syntax = "proto2";
+    package perfetto.protos;
+
+    message Root {
+      optional int32 existing = 1;
+    }
+  )");
+  TempProtoFile upstream(temp_dir.path(), "upstream.proto", R"(
+    syntax = "proto2";
+    package perfetto.protos;
+
+    message EmptyMessage {}
+    message Root {
+      optional int32 existing = 1;
+      optional EmptyMessage clear = 2;
+      map<string, EmptyMessage> clear_map = 3;
+    }
+  )");
+
+  std::string out =
+      MergeWithFieldList(temp_dir.path(), "input.proto", "upstream.proto",
+                         "Root", {"clear", "clear_map"});
+
+  EXPECT_THAT(out, HasSubstr("message EmptyMessage {"));
+  EXPECT_THAT(FindMessageText(out, "Root"),
+              HasSubstr("EmptyMessage clear = 2;"));
+  EXPECT_THAT(FindMessageText(out, "Root"),
+              HasSubstr("map<string,EmptyMessage> clear_map = 3;"));
+}
+
+// Path a.b.c.d where only d is approved: a and c are missing downstream, b
+// (and its message types) already exist. Missing path fields are added once,
+// existing ones are kept as they are, and no other sibling field is added.
+TEST(AllowlistFromFieldListTest, MixedExistingAndMissingParents) {
+  base::TempDir temp_dir = base::TempDir::Create();
+  TempProtoFile input(temp_dir.path(), "input.proto", R"(
+    syntax = "proto2";
+    package perfetto.protos;
+
+    message B {
+      optional int32 b_existing = 5;
+    }
+    message A {
+      optional B b = 1;
+    }
+    message Root {
+      optional int32 existing = 1;
+    }
+  )");
+  TempProtoFile upstream(temp_dir.path(), "upstream.proto", R"(
+    syntax = "proto2";
+    package perfetto.protos;
+
+    message D {
+      optional int32 d_value = 1;
+    }
+    message C {
+      optional D d = 1;
+      optional int32 c_sibling = 2;
+    }
+    message B {
+      optional C c = 3;
+      optional int32 b_sibling = 4;
+      optional int32 b_existing = 5;
+    }
+    message A {
+      optional B b = 1;
+      optional int32 a_sibling = 2;
+    }
+    message Root {
+      optional int32 existing = 1;
+      optional A a = 2;
+      optional int32 root_sibling = 3;
+    }
+  )");
+
+  std::string out = MergeWithFieldList(temp_dir.path(), "input.proto",
+                                       "upstream.proto", "Root", {"a.b.c.d"});
+
+  // Missing path fields are added; the existing one (b) is kept, not doubled.
+  EXPECT_THAT(FindMessageText(out, "Root"), HasSubstr("A a = 2;"));
+  std::string a_text = FindMessageText(out, "A");
+  EXPECT_THAT(a_text, HasSubstr("B b = 1;"));
+  EXPECT_EQ(a_text.find("B b = 1;"), a_text.rfind("B b = 1;"));
+  EXPECT_THAT(FindMessageText(out, "B"), HasSubstr("C c = 3;"));
+  EXPECT_THAT(FindMessageText(out, "B"), HasSubstr("int32 b_existing = 5;"));
+  EXPECT_THAT(FindMessageText(out, "C"), HasSubstr("D d = 1;"));
+  EXPECT_THAT(FindMessageText(out, "D"), HasSubstr("int32 d_value = 1;"));
+
+  // No sibling field at any level of the path is added.
+  EXPECT_THAT(out, Not(HasSubstr("root_sibling")));
+  EXPECT_THAT(out, Not(HasSubstr("a_sibling")));
+  EXPECT_THAT(out, Not(HasSubstr("b_sibling")));
+  EXPECT_THAT(out, Not(HasSubstr("c_sibling")));
+}
+
+// Approving both a parent and a field inside it must allow everything inside
+// the parent, regardless of the order of the entries.
+TEST(AllowlistFromFieldListTest, ParentApprovedAfterChildIsRecursive) {
+  base::TempDir temp_dir = base::TempDir::Create();
+  TempProtoFile input(temp_dir.path(), "input.proto", R"(
+    syntax = "proto2";
+    package perfetto.protos;
+
+    message Root {
+      optional int32 existing = 1;
+    }
+  )");
+  TempProtoFile upstream(temp_dir.path(), "upstream.proto", R"(
+    syntax = "proto2";
+    package perfetto.protos;
+
+    message Ext {
+      optional int32 a = 1;
+      optional int32 b = 2;
+    }
+    message Root {
+      optional int32 existing = 1;
+      optional Ext ext = 2;
+    }
+  )");
+
+  std::string out =
+      MergeWithFieldList(temp_dir.path(), "input.proto", "upstream.proto",
+                         "Root", {"ext.a", "ext"});
+
+  EXPECT_THAT(FindMessageText(out, "Root"), HasSubstr("Ext ext = 2;"));
+  EXPECT_THAT(FindMessageText(out, "Ext"), HasSubstr("int32 a = 1;"));
+  EXPECT_THAT(FindMessageText(out, "Ext"), HasSubstr("int32 b = 2;"));
+}
+
 }  // namespace
 }  // namespace proto_merger
 }  // namespace perfetto
diff --git a/src/trace_processor/containers/interval_intersector.h b/src/trace_processor/containers/interval_intersector.h
index 524c529..f48c33a 100644
--- a/src/trace_processor/containers/interval_intersector.h
+++ b/src/trace_processor/containers/interval_intersector.h
@@ -61,13 +61,18 @@
   // copies the vector of intervals.
   explicit IntervalIntersector(const std::vector<Interval>& sorted_intervals,
                                Mode mode)
-      : intervals_(sorted_intervals), mode_(mode) {
-    if (sorted_intervals.empty()) {
+      : IntervalIntersector(sorted_intervals.data(),
+                            sorted_intervals.size(),
+                            mode) {}
+
+  IntervalIntersector(const Interval* sorted_intervals, size_t size, Mode mode)
+      : begin_(sorted_intervals), end_(sorted_intervals + size), mode_(mode) {
+    if (size == 0) {
       mode_ = kBinarySearch;
       return;
     }
     if (mode_ == kIntervalTree) {
-      tree = std::make_unique<IntervalTree>(intervals_);
+      tree = std::make_unique<IntervalTree>(sorted_intervals, size);
     }
   }
 
@@ -107,12 +112,12 @@
 
     if (mode_ == kBinarySearch) {
       // Find the first interval that ends at or after |s|.
-      auto it = std::lower_bound(intervals_.begin(), intervals_.end(), s,
+      auto it = std::lower_bound(begin_, end_, s,
                                  [](const Interval& interval, uint64_t start) {
                                    return interval.end < start;
                                  });
       // The previous interval could also overlap.
-      if (it != intervals_.begin()) {
+      if (it != begin_) {
         --it;
       }
 
@@ -120,7 +125,7 @@
         // For instant queries, we are interested in intervals that contain
         // |s|, so we can stop once we are past |s|. For range queries, we can
         // stop once the interval starts after the end of the query.
-        for (; it != intervals_.end(); ++it) {
+        for (; it != end_; ++it) {
           if (it->start > s) {
             break;
           }
@@ -129,7 +134,7 @@
         return;
       }
 
-      for (; it != intervals_.end(); ++it) {
+      for (; it != end_; ++it) {
         if (it->start >= e) {
           break;
         }
@@ -139,8 +144,8 @@
     }
 
     PERFETTO_CHECK(mode_ == kLinearScan);
-    for (const auto& interval : intervals_) {
-      handle_overlap(interval);
+    for (const Interval* it = begin_; it != end_; ++it) {
+      handle_overlap(*it);
     }
   }
 
@@ -225,7 +230,8 @@
   }
 
  private:
-  const std::vector<Interval>& intervals_;
+  const Interval* begin_;
+  const Interval* end_;
   Mode mode_;
 
   // If |use_interval_tree_|.
diff --git a/src/trace_processor/containers/interval_tree.h b/src/trace_processor/containers/interval_tree.h
index 7ea3b7e..13cf47f 100644
--- a/src/trace_processor/containers/interval_tree.h
+++ b/src/trace_processor/containers/interval_tree.h
@@ -68,10 +68,13 @@
  public:
   // Creates an interval tree from the vector of intervals if needed. Otherwise
   // copies the vector of intervals.
-  explicit IntervalTree(const std::vector<Interval>& sorted_intervals) {
-    PERFETTO_CHECK(!sorted_intervals.empty());
-    nodes_.reserve(sorted_intervals.size());
-    Node root_node(sorted_intervals.data(), sorted_intervals.size(), nodes_);
+  explicit IntervalTree(const std::vector<Interval>& sorted_intervals)
+      : IntervalTree(sorted_intervals.data(), sorted_intervals.size()) {}
+
+  IntervalTree(const Interval* sorted_intervals, size_t size) {
+    PERFETTO_CHECK(size > 0);
+    nodes_.reserve(size);
+    Node root_node(sorted_intervals, size, nodes_);
     nodes_.emplace_back(std::move(root_node));
     root_ = nodes_.size() - 1;
   }
diff --git a/src/trace_processor/core/common/BUILD.gn b/src/trace_processor/core/common/BUILD.gn
index 724770c..3e5840f 100644
--- a/src/trace_processor/core/common/BUILD.gn
+++ b/src/trace_processor/core/common/BUILD.gn
@@ -12,6 +12,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+import("../../../../gn/perfetto.gni")
 import("../../../../gn/test.gni")
 
 source_set("common") {
@@ -35,6 +36,7 @@
     "../../../../gn:default_deps",
     "../../../base",
     "../../containers",
+    "../../util:galloping_search",
     "../util",
   ]
 }
@@ -53,3 +55,16 @@
     "../../containers",
   ]
 }
+
+if (enable_perfetto_benchmarks) {
+  source_set("benchmarks") {
+    testonly = true
+    sources = [ "filter_kernels_benchmark.cc" ]
+    deps = [
+      ":common",
+      "../../../../gn:benchmark",
+      "../../../../gn:default_deps",
+      "../util",
+    ]
+  }
+}
diff --git a/src/trace_processor/core/common/filter_kernels.h b/src/trace_processor/core/common/filter_kernels.h
index 559a758..bb8c8b8 100644
--- a/src/trace_processor/core/common/filter_kernels.h
+++ b/src/trace_processor/core/common/filter_kernels.h
@@ -17,10 +17,14 @@
 #ifndef SRC_TRACE_PROCESSOR_CORE_COMMON_FILTER_KERNELS_H_
 #define SRC_TRACE_PROCESSOR_CORE_COMMON_FILTER_KERNELS_H_
 
+#include <algorithm>
 #include <cstdint>
+#include <cstring>
 #include <functional>
+#include <limits>
 #include <optional>
 #include <type_traits>
+#include <utility>
 
 #include "perfetto/base/compiler.h"
 #include "perfetto/base/logging.h"
@@ -31,15 +35,19 @@
 #include "src/trace_processor/containers/null_term_string_view.h"
 #include "src/trace_processor/containers/string_pool.h"
 #include "src/trace_processor/core/common/filter_value_cast.h"
+#include "src/trace_processor/core/common/null_types.h"
 #include "src/trace_processor/core/common/op_types.h"
 #include "src/trace_processor/core/common/storage_types.h"
 #include "src/trace_processor/core/util/bit_vector.h"
 #include "src/trace_processor/core/util/flex_vector.h"
+#include "src/trace_processor/core/util/range.h"
 #include "src/trace_processor/core/util/span.h"
+#include "src/trace_processor/util/galloping_search.h"
 
 // Keeping the rows of a column which compare true with a value already cast
-// to the column's type (see filter_value_cast.h). Shared by everything which
-// filters columns.
+// to the column's type (see filter_value_cast.h), by testing each row or by
+// searching a sorted column or index. Shared by everything which filters
+// columns.
 namespace perfetto::trace_processor::core::filter {
 
 namespace comparators {
@@ -347,6 +355,305 @@
   dest.e = FilterInHashMap<T>(data, source.b, source.e, dest.b, hm);
 }
 
+// -----------------------------------------------------------------------------
+// Searches of sorted columns and indexes
+// -----------------------------------------------------------------------------
+//
+// A sorted column, or an index listing a column's rows in the order of their
+// values, keeps the rows equal to or beyond a value together, so they are
+// found by searching rather than testing every row. Each search narrows
+// `range`, rows of the column or entries of the index, to those it keeps.
+
+template <typename DataType>
+inline auto SortedLowerBoundComparator(const StringPool* string_pool) {
+  if constexpr (std::is_same_v<DataType, StringPool::Id>) {
+    return comparators::StringComparator<Lt>{string_pool};
+  } else {
+    base::ignore_result(string_pool);
+    return std::less<>();
+  }
+}
+
+template <typename DataType>
+inline auto SortedUpperBoundComparator(const StringPool* string_pool) {
+  if constexpr (std::is_same_v<DataType, StringPool::Id>) {
+    return comparators::StringLessInvert{string_pool};
+  } else {
+    base::ignore_result(string_pool);
+    return std::less<>();
+  }
+}
+
+// The first row of `range` whose value is not less than `val`, in a column
+// sorted ascending.
+template <typename DataType, typename ValueType>
+[[nodiscard]] inline PERFETTO_ALWAYS_INLINE uint32_t
+SortedLowerBound(const DataType* data,
+                 ValueType val,
+                 const StringPool* string_pool,
+                 Range range) {
+  return static_cast<uint32_t>(
+      std::lower_bound(data + range.b, data + range.e, val,
+                       SortedLowerBoundComparator<DataType>(string_pool)) -
+      data);
+}
+
+// The first row of `range` whose value is greater than `val`, in a column
+// sorted ascending.
+template <typename DataType, typename ValueType>
+[[nodiscard]] inline PERFETTO_ALWAYS_INLINE uint32_t
+SortedUpperBound(const DataType* data,
+                 ValueType val,
+                 const StringPool* string_pool,
+                 Range range) {
+  return static_cast<uint32_t>(
+      std::upper_bound(data + range.b, data + range.e, val,
+                       SortedUpperBoundComparator<DataType>(string_pool)) -
+      data);
+}
+
+// Narrows `range` to the rows whose value equals `val`, in a column sorted
+// ascending.
+template <typename DataType, typename ValueType>
+inline PERFETTO_ALWAYS_INLINE void SortedEqualRange(
+    const DataType* data,
+    ValueType val,
+    const StringPool* string_pool,
+    Range& range) {
+  auto* begin = data + range.b;
+  auto* end = data + range.e;
+  DataType cmp_value;
+  if constexpr (std::is_same_v<DataType, StringPool::Id>) {
+    std::optional<StringPool::Id> id =
+        string_pool->GetId(base::StringView(val));
+    if (!id) {
+      range.e = range.b;
+      return;
+    }
+    cmp_value = *id;
+  } else {
+    cmp_value = val;
+  }
+  const DataType* eq_start = std::lower_bound(
+      begin, end, val, SortedLowerBoundComparator<DataType>(string_pool));
+  // Equal rows are usually few, so search from the first of them outwards.
+  const DataType* eq_end =
+      GallopingPartitionPoint(eq_start, end, [cmp_value](const DataType& v) {
+        return std::equal_to<>()(v, cmp_value);
+      });
+  range.b = static_cast<uint32_t>(eq_start - data);
+  range.e = static_cast<uint32_t>(eq_end - data);
+}
+
+// Narrows `range` to the row of an Id column whose value is `val`: an Id's
+// value is its row.
+inline PERFETTO_ALWAYS_INLINE void IdEqualRange(uint32_t val, Range& range) {
+  bool in_bounds = val >= range.b && val < range.e;
+  range.b = val;
+  range.e = val + in_bounds;
+}
+
+// Narrows `range` to the rows of an Id column from `val` on, if `begin`, or
+// before it otherwise.
+inline PERFETTO_ALWAYS_INLINE void IdBound(uint32_t val,
+                                           bool begin,
+                                           Range& range) {
+  uint32_t new_b = begin ? std::max(range.b, val) : range.b;
+  uint32_t new_e = !begin ? std::min(range.e, val) : range.e;
+  range.b = new_b;
+  range.e = std::max(new_b, new_e);
+}
+
+// Narrows `range` to the rows whose value equals `val`, in a Uint32 column
+// sorted by SetId: the rows of a value start at the row of that number.
+inline PERFETTO_ALWAYS_INLINE void
+SetIdSortedEqualRange(const uint32_t* storage, uint32_t val, Range& range) {
+  const auto* start =
+      std::clamp(storage + val, storage + range.b, storage + range.e);
+  range.b = static_cast<uint32_t>(start - storage);
+  const uint32_t* it = GallopingPartitionPoint(
+      start, storage + range.e, [val](uint32_t v) { return v == val; });
+  range.e = static_cast<uint32_t>(it - storage);
+}
+
+// Narrows `range` to the row whose value is `val`, in a column whose values
+// are distinct and small, stored as the set bits of `bv`: the row of a value
+// is the number of values below it. `popcount` holds the count of set bits
+// before each word of `bv`.
+inline PERFETTO_ALWAYS_INLINE void SmallValueEqualRange(
+    const BitVector& bv,
+    const uint32_t* popcount,
+    uint32_t val,
+    Range& range) {
+  uint32_t k = val < bv.size() && bv.is_set(val)
+                   ? static_cast<uint32_t>(popcount[val / 64] +
+                                           bv.count_set_bits_until_in_word(val))
+                   : range.e;
+  bool in_bounds = range.b <= k && k < range.e;
+  range.b = in_bounds ? k : range.e;
+  range.e = in_bounds ? k + 1 : range.b;
+}
+
+// Where the value of row `index` is stored in a column of nullability N, or
+// UINT32_MAX if it is null. `bv` marks the rows with values; `popcount`, the
+// count of set bits before each of its words, is read for SparseNull only.
+template <typename N>
+[[nodiscard]] inline PERFETTO_ALWAYS_INLINE uint32_t
+IndexToStorageIndex(uint32_t index,
+                    const BitVector* bv,
+                    const uint32_t* popcount) {
+  if constexpr (std::is_same_v<N, NonNull>) {
+    base::ignore_result(bv, popcount);
+    return index;
+  } else if constexpr (std::is_same_v<N, SparseNull>) {
+    if (!bv->is_set(index)) {
+      // Null values are always less than non-null values.
+      return std::numeric_limits<uint32_t>::max();
+    }
+    return static_cast<uint32_t>(popcount[index / 64] +
+                                 bv->count_set_bits_until_in_word(index));
+  } else if constexpr (std::is_same_v<N, DenseNull>) {
+    base::ignore_result(popcount);
+    return bv->is_set(index) ? index : std::numeric_limits<uint32_t>::max();
+  } else {
+    static_assert(std::is_same_v<N, NonNull>, "Unsupported type");
+  }
+}
+
+// Binary-searches a sorted index for all entries whose resolved storage
+// value equals |target|. Returns the [lb, ub) range of matching index
+// entries.
+//
+// |target| should be a NullTermStringView for String columns (i.e. a
+// pre-resolved string_pool->Get result) or the raw value for other types.
+// This avoids repeated string_pool->Get calls inside the comparators.
+template <typename T, typename N, typename Resolved>
+inline PERFETTO_ALWAYS_INLINE std::pair<uint32_t*, uint32_t*> IndexEqualRange(
+    uint32_t* begin,
+    uint32_t* end,
+    const Resolved& target,
+    const typename T::cpp_type* data,
+    const BitVector* bv,
+    const uint32_t* popcount,
+    const StringPool* string_pool) {
+  auto* lb =
+      std::lower_bound(begin, end, target, [&](uint32_t idx, const Resolved&) {
+        uint32_t si = IndexToStorageIndex<N>(idx, bv, popcount);
+        if (si == std::numeric_limits<uint32_t>::max())
+          return true;
+        if constexpr (std::is_same_v<T, String>) {
+          return string_pool->Get(data[si]) < target;
+        } else {
+          return data[si] < target;
+        }
+      });
+  auto* ub =
+      std::upper_bound(lb, end, target, [&](const Resolved&, uint32_t idx) {
+        uint32_t si = IndexToStorageIndex<N>(idx, bv, popcount);
+        if (si == std::numeric_limits<uint32_t>::max())
+          return false;
+        if constexpr (std::is_same_v<T, String>) {
+          return target < string_pool->Get(data[si]);
+        } else {
+          return target < data[si];
+        }
+      });
+  return {lb, ub};
+}
+
+// The rows of an IN found by binary-searching a sorted index for each of its
+// values, written to `dest` in increasing order. Returns false, writing
+// nothing, if the list is empty or too long for searching to beat a scan.
+//
+// TODO(lalitm): since the index is sorted, galloping search could replace
+// repeated std::lower_bound for better locality.
+template <typename T, typename N>
+[[nodiscard]] inline PERFETTO_ALWAYS_INLINE bool IndexedFilterInBinarySearch(
+    const CastFilterValueListResult& cast_result,
+    Span<uint32_t> index,
+    const typename T::cpp_type* data,
+    const BitVector* bv,
+    const uint32_t* popcount,
+    const StringPool* string_pool,
+    Span<uint32_t>& dest) {
+  using VL =
+      StorageType::VariantTypeAtIndex<T, CastFilterValueListResult::ValueList>;
+  const VL& vl = base::unchecked_get<VL>(cast_result.value_list);
+  if (vl.empty() || vl.size() > kFilterInIndexedBinarySearchThreshold) {
+    return false;
+  }
+  uint32_t* write = dest.b;
+  for (const auto& cmp_val : vl) {
+    // For String columns, resolve StringPool::Id to NullTermStringView
+    // once per value to avoid repeated lookups in the comparators.
+    std::pair<uint32_t*, uint32_t*> range;
+    if constexpr (std::is_same_v<T, String>) {
+      auto target = string_pool->Get(cmp_val);
+      range = IndexEqualRange<T, N>(index.b, index.e, target, data, bv,
+                                    popcount, string_pool);
+    } else {
+      range = IndexEqualRange<T, N>(index.b, index.e, cmp_val, data, bv,
+                                    popcount, string_pool);
+    }
+    auto n = static_cast<size_t>(range.second - range.first);
+    memcpy(write, range.first, n * sizeof(uint32_t));
+    write += n;
+  }
+  dest.e = write;
+
+  // Binary search produces output in key order. Sort by raw index.
+  std::sort(dest.b, dest.e);
+  return true;
+}
+
+// The rows of `range` whose value is in an IN's list, written to `dest`,
+// testing each against the list's hash map.
+template <typename T, typename N>
+inline PERFETTO_ALWAYS_INLINE void FilterInRangeScan(
+    const CastFilterValueListResult& cast_result,
+    Range range,
+    const typename T::cpp_type* data,
+    const BitVector* bv,
+    const uint32_t* popcount,
+    Span<uint32_t>& dest) {
+  using HM =
+      StorageType::VariantTypeAtIndex<T,
+                                      CastFilterValueListResult::ValueHashMap>;
+  // |data| is unused for Id columns (the storage index IS the value).
+  base::ignore_result(data);
+  const auto& hm = base::unchecked_get<HM>(cast_result.hash_map);
+  uint32_t* write = dest.b;
+  for (uint32_t i = range.b; i < range.e; ++i) {
+    uint32_t si = IndexToStorageIndex<N>(i, bv, popcount);
+    if (si == std::numeric_limits<uint32_t>::max()) {
+      continue;
+    }
+    if constexpr (std::is_same_v<T, Id>) {
+      if (hm.Find(CastFilterValueResult::Id{si}) != nullptr) {
+        *write++ = i;
+      }
+    } else {
+      if (hm.Find(data[si]) != nullptr) {
+        *write++ = i;
+      }
+    }
+  }
+  dest.e = write;
+}
+
+// Copies the rows of `source` which lie in `range` to `out`, in order,
+// returning the end of those written. `out` may be `source.b`.
+inline PERFETTO_ALWAYS_INLINE uint32_t* CopySpanIntersectingRange(
+    Span<const uint32_t> source,
+    Range range,
+    uint32_t* out) {
+  for (const uint32_t* it = source.b; it != source.e; ++it) {
+    *out = *it;
+    out += (*it >= range.b && *it < range.e);
+  }
+  return out;
+}
+
 }  // namespace perfetto::trace_processor::core::filter
 
 #endif  // SRC_TRACE_PROCESSOR_CORE_COMMON_FILTER_KERNELS_H_
diff --git a/src/trace_processor/core/common/filter_kernels_benchmark.cc b/src/trace_processor/core/common/filter_kernels_benchmark.cc
new file mode 100644
index 0000000..798e2c2
--- /dev/null
+++ b/src/trace_processor/core/common/filter_kernels_benchmark.cc
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2026 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.
+ */
+
+#include <benchmark/benchmark.h>
+
+#include <cstdint>
+#include <random>
+#include <vector>
+
+#include "src/trace_processor/core/common/filter_kernels.h"
+#include "src/trace_processor/core/util/range.h"
+
+namespace perfetto::trace_processor::core {
+namespace {
+
+constexpr uint32_t kRows = 1 << 20;
+constexpr uint32_t kLookups = 1024;
+
+// Each value repeats `run` times, so equal ranges have that length.
+std::vector<uint32_t> SortedRuns(uint32_t run) {
+  std::vector<uint32_t> data(kRows);
+  for (uint32_t i = 0; i < kRows; ++i) {
+    data[i] = i / run;
+  }
+  return data;
+}
+
+std::vector<uint32_t> RandomValues(uint32_t max) {
+  std::mt19937 rng(1);
+  std::uniform_int_distribution<uint32_t> dist(0, max);
+  std::vector<uint32_t> values(kLookups);
+  for (uint32_t& v : values) {
+    v = dist(rng);
+  }
+  return values;
+}
+
+// Argument: the length of each equal range.
+void BM_SortedEqualRange(benchmark::State& state) {
+  auto run = static_cast<uint32_t>(state.range(0));
+  std::vector<uint32_t> data = SortedRuns(run);
+  std::vector<uint32_t> values = RandomValues(kRows / run - 1);
+  for (auto _ : state) {
+    for (uint32_t v : values) {
+      Range range{0, kRows};
+      filter::SortedEqualRange(data.data(), v, nullptr, range);
+      benchmark::DoNotOptimize(range);
+    }
+  }
+  state.SetItemsProcessed(static_cast<int64_t>(state.iterations()) * kLookups);
+}
+BENCHMARK(BM_SortedEqualRange)->RangeMultiplier(4)->Range(1, 1 << 16);
+
+// Argument: the length of each set. A SetId column holds, at each row, the
+// row its set starts at.
+void BM_SetIdSortedEqualRange(benchmark::State& state) {
+  auto run = static_cast<uint32_t>(state.range(0));
+  std::vector<uint32_t> data(kRows);
+  for (uint32_t i = 0; i < kRows; ++i) {
+    data[i] = i / run * run;
+  }
+  std::vector<uint32_t> values = RandomValues(kRows / run - 1);
+  for (uint32_t& v : values) {
+    v *= run;
+  }
+  for (auto _ : state) {
+    for (uint32_t v : values) {
+      Range range{0, kRows};
+      filter::SetIdSortedEqualRange(data.data(), v, range);
+      benchmark::DoNotOptimize(range);
+    }
+  }
+  state.SetItemsProcessed(static_cast<int64_t>(state.iterations()) * kLookups);
+}
+BENCHMARK(BM_SetIdSortedEqualRange)->RangeMultiplier(4)->Range(1, 1 << 16);
+
+}  // namespace
+}  // namespace perfetto::trace_processor::core
diff --git a/src/trace_processor/core/common/filter_value_cast.h b/src/trace_processor/core/common/filter_value_cast.h
index ea5b9ea..8c1e003 100644
--- a/src/trace_processor/core/common/filter_value_cast.h
+++ b/src/trace_processor/core/common/filter_value_cast.h
@@ -302,22 +302,24 @@
   if (PERFETTO_LIKELY(filter_value_type == FilterValueFetcherImpl::kInt64)) {
     int64_t i = fetcher.GetInt64Value(index);
     auto iad = static_cast<double>(i);
-    auto iad_int = static_cast<int64_t>(iad);
 
-    // If the integer value can be converted to a double while preserving
-    // the exact integer value, then we can use the double value for
-    // comparison.
-    if (PERFETTO_LIKELY(i == iad_int)) {
-      out = iad;
-      return CastFilterValueResult::kValid;
+    // Rounding can take `i` up to 2^63, which int64_t cannot hold: casting
+    // that back would be undefined behaviour.
+    bool iad_greater_than_i = iad >= 9223372036854775808.0;
+    bool iad_less_than_i = false;
+    if (PERFETTO_LIKELY(!iad_greater_than_i)) {
+      auto iad_int = static_cast<int64_t>(iad);
+
+      // If the integer value can be converted to a double while preserving
+      // the exact integer value, then we can use the double value for
+      // comparison.
+      if (PERFETTO_LIKELY(i == iad_int)) {
+        out = iad;
+        return CastFilterValueResult::kValid;
+      }
+      iad_greater_than_i = iad_int > i;
+      iad_less_than_i = iad_int < i;
     }
-
-    // This can happen in cases where we round `i` up above
-    // numeric_limits::max(). In that case, still consider the double
-    // larger.
-    bool overflow_positive_to_negative = i > 0 && iad_int < 0;
-    bool iad_greater_than_i = iad_int > i || overflow_positive_to_negative;
-    bool iad_less_than_i = iad_int < i && !overflow_positive_to_negative;
     switch (op.index()) {
       case NonStringOp::GetTypeIndex<Lt>():
         out =
@@ -412,6 +414,50 @@
   PERFETTO_FATAL("Invalid filter spec value");
 }
 
+// Casts the filter value at `index` to the type of a column of storage type
+// T, for comparing with `op`: a value which cannot be cast exactly says
+// whether every row or none matches instead.
+template <typename T, typename FilterValueFetcherImpl>
+[[nodiscard]] inline PERFETTO_ALWAYS_INLINE CastFilterValueResult
+CastFilterValue(uint32_t index, FilterValueFetcherImpl& fetcher, NonNullOp op) {
+  typename FilterValueFetcherImpl::Type filter_value_type =
+      fetcher.GetValueType(index);
+  using ValueType =
+      StorageType::VariantTypeAtIndex<T, CastFilterValueResult::Value>;
+  CastFilterValueResult result;
+  if constexpr (std::is_same_v<T, Id>) {
+    uint32_t result_value;
+    result.validity =
+        CastFilterValueToInteger<uint32_t, FilterValueFetcherImpl>(
+            index, filter_value_type, fetcher, *op.TryDowncast<NonStringOp>(),
+            result_value);
+    if (PERFETTO_LIKELY(result.validity == CastFilterValueResult::kValid)) {
+      result.value = CastFilterValueResult::Id{result_value};
+    }
+  } else if constexpr (IntegerOrDoubleType::Contains<T>()) {
+    ValueType result_value;
+    result.validity =
+        CastFilterValueToIntegerOrDouble<ValueType, FilterValueFetcherImpl>(
+            index, filter_value_type, fetcher, *op.TryDowncast<NonStringOp>(),
+            result_value);
+    if (PERFETTO_LIKELY(result.validity == CastFilterValueResult::kValid)) {
+      result.value = result_value;
+    }
+  } else if constexpr (std::is_same_v<T, String>) {
+    static_assert(std::is_same_v<ValueType, const char*>);
+    const char* result_value;
+    result.validity = CastFilterValueToString<FilterValueFetcherImpl>(
+        index, filter_value_type, fetcher, *op.TryDowncast<StringOp>(),
+        result_value);
+    if (PERFETTO_LIKELY(result.validity == CastFilterValueResult::kValid)) {
+      result.value = result_value;
+    }
+  } else {
+    static_assert(std::is_same_v<T, Id>, "Unsupported type");
+  }
+  return result;
+}
+
 // Below this threshold, the non-indexed FilterIn path does a linear scan
 // over the value list instead of a HashMap lookup (avoids hashing overhead).
 inline constexpr uint32_t kFilterInKeyScanThreshold = 16;
diff --git a/src/trace_processor/core/dataframe/arrow_serializer_unittest.cc b/src/trace_processor/core/dataframe/arrow_serializer_unittest.cc
index acc9b5d..eea6fdf 100644
--- a/src/trace_processor/core/dataframe/arrow_serializer_unittest.cc
+++ b/src/trace_processor/core/dataframe/arrow_serializer_unittest.cc
@@ -21,6 +21,7 @@
 #include <cstring>
 #include <optional>
 #include <string_view>
+#include <utility>
 #include <variant>
 #include <vector>
 
@@ -381,6 +382,31 @@
   EXPECT_OK(serializer.Write(source, pool, sink));
 }
 
+TEST(ArrowSerializerTest, RejectsReplacementAfterPrepare) {
+  StringPool pool;
+  auto short_value = pool.InternString(base::StringView("a"));
+  auto long_value = pool.InternString(base::StringView("a longer value"));
+  auto source = MakeDataframe(kStringNonNull, &pool, short_value);
+  auto replacement = MakeDataframe(kStringNonNull, &pool, long_value);
+  source.Finalize();
+  replacement.Finalize();
+  ASSERT_EQ(source.mutations(), replacement.mutations());
+  uint64_t previous_mutations = source.mutations();
+  ArrowSerializer serializer;
+  ASSERT_OK(serializer.Prepare(source, pool));
+
+  source = std::move(replacement);
+  EXPECT_GT(source.mutations(), previous_mutations);
+  bool wrote = false;
+  EXPECT_THAT(serializer.Write(source, pool,
+                               [&](const uint8_t*, size_t) {
+                                 wrote = true;
+                                 return base::OkStatus();
+                               }),
+              IsError());
+  EXPECT_FALSE(wrote);
+}
+
 TEST(ArrowSerializerTest, CanBeReused) {
   StringPool pool;
   auto first = MakeDataframe(kUint32NonNull, &pool, uint32_t{1});
diff --git a/src/trace_processor/core/dataframe/dataframe.cc b/src/trace_processor/core/dataframe/dataframe.cc
index f8f2896..5a1eb1a 100644
--- a/src/trace_processor/core/dataframe/dataframe.cc
+++ b/src/trace_processor/core/dataframe/dataframe.cc
@@ -105,6 +105,30 @@
   }
 }
 
+Dataframe& Dataframe::operator=(Dataframe&& other) noexcept {
+  if (this == &other) {
+    return *this;
+  }
+  const uint64_t previous_mutations = mutations();
+  column_names_ = std::move(other.column_names_);
+  columns_ = std::move(other.columns_);
+  column_ptrs_ = std::move(other.column_ptrs_);
+  indexes_ = std::move(other.indexes_);
+  row_count_ = other.row_count_;
+  string_pool_ = other.string_pool_;
+  non_column_mutations_ = previous_mutations + 1;
+  finalized_ = other.finalized_;
+  ++replacement_generation_;
+  return *this;
+}
+
+Dataframe& Dataframe::operator=(const Dataframe& other) {
+  if (this != &other) {
+    *this = Dataframe(other);
+  }
+  return *this;
+}
+
 base::StatusOr<Dataframe::QueryPlan> Dataframe::PlanQuery(
     std::vector<FilterSpec>& filter_specs,
     const std::vector<DistinctSpec>& distinct_specs,
diff --git a/src/trace_processor/core/dataframe/dataframe.h b/src/trace_processor/core/dataframe/dataframe.h
index 1d7d8ed..d96904b 100644
--- a/src/trace_processor/core/dataframe/dataframe.h
+++ b/src/trace_processor/core/dataframe/dataframe.h
@@ -121,7 +121,9 @@
 
   // Movable
   Dataframe(Dataframe&&) = default;
-  Dataframe& operator=(Dataframe&&) = default;
+  // Assignment invalidates any current cursor iteration. Typed cursors can
+  // start a new query after a replacement with the same schema.
+  Dataframe& operator=(Dataframe&&) noexcept;
 
   // Adds a new row to the dataframe with the specified values.
   //
@@ -164,6 +166,9 @@
       const LimitSpec& limit_spec,
       uint64_t cols_used_bitmap) const;
 
+  // The indexes added to the dataframe (see AddIndex).
+  const std::vector<Index>& indexes() const { return indexes_; }
+
   // Returns the logical plan PlanQuery would lower, for tests which assert on
   // the planner's choices rather than on the bytecode they produce.
   base::StatusOr<LogicalPlan> PlanQueryLogicalForTesting(
@@ -310,9 +315,9 @@
     return static_cast<uint32_t>(column_ptrs_.size());
   }
 
-  // Returns the total number of mutations to the dataframe. This includes
-  // both non-column mutations (e.g. adding rows, adding indexes) and
-  // column mutations (e.g. setting cell values).
+  // Returns a mutation stamp for cache invalidation. This includes structural
+  // and column changes and advances when the contents are replaced. It is not
+  // an exact operation count.
   uint64_t mutations() const {
     uint64_t total = non_column_mutations_;
     for (const auto& col : columns_) {
@@ -728,7 +733,7 @@
 
   // Private copy constructor for special methods.
   Dataframe(const Dataframe&) = default;
-  Dataframe& operator=(const Dataframe&) = default;
+  Dataframe& operator=(const Dataframe&);
 
   // The names of all columns.
   std::vector<std::string> column_names_;
@@ -750,14 +755,14 @@
   // String pool for efficient string storage and interning.
   StringPool* string_pool_;
 
-  // A count of the number of mutations to the dataframe (e.g. adding rows,
-  // adding indexes). This does *not* include changes to values of the columns,
-  // there is a separate mutation count for that.
-  //
-  // This is used to determine if the dataframe has changed since the
-  // last time an external caller looked at it. This can allow invalidation of
-  // external caches of things inside this dataframe.
-  uint32_t non_column_mutations_ = 0;
+  // Base of the mutation stamp for structural changes. Replacement advances
+  // it past the old total, so caches cannot mistake a different dataframe
+  // payload with the same column mutation counts for an unchanged one.
+  uint64_t non_column_mutations_ = 0;
+
+  // Belongs to this dataframe object, not its columns: replacing the payload
+  // invalidates cached cursor state even if column mutation counts match.
+  uint64_t replacement_generation_ = 0;
 
   // Whether the dataframe is "finalized". See `Finalize()`.
   bool finalized_ = false;
diff --git a/src/trace_processor/core/dataframe/dataframe_unittest.cc b/src/trace_processor/core/dataframe/dataframe_unittest.cc
index d8779d3..e340484 100644
--- a/src/trace_processor/core/dataframe/dataframe_unittest.cc
+++ b/src/trace_processor/core/dataframe/dataframe_unittest.cc
@@ -1586,6 +1586,131 @@
   }
 }
 
+TEST(DataframeTest, TypedCursorCreatedBeforeDataframeReplacement) {
+  static constexpr auto kSpec = CreateTypedDataframeSpec(
+      {"value"}, CreateTypedColumnSpec(Int64(), NonNull(), Unsorted()));
+  StringPool pool;
+  Dataframe df = Dataframe::CreateFromTypedSpec(kSpec, &pool);
+  TypedCursor cursor(&df, {FilterSpec{0, 0, Eq{}, {}}}, {});
+
+  Dataframe replacement = Dataframe::CreateFromTypedSpec(kSpec, &pool);
+  replacement.InsertUnchecked(kSpec, int64_t{7});
+  replacement.Finalize();
+  df = std::move(replacement);
+
+  cursor.SetFilterValueUnchecked(0, int64_t{7});
+  cursor.ExecuteUnchecked();
+  ASSERT_FALSE(cursor.Eof());
+  EXPECT_EQ(cursor.GetCellUnchecked<0>(kSpec), int64_t{7});
+  cursor.Next();
+  EXPECT_TRUE(cursor.Eof());
+}
+
+TEST(DataframeTest, TypedCursorReplansAfterDataframeReplacement) {
+  static constexpr auto kSpec = CreateTypedDataframeSpec(
+      {"value"}, CreateTypedColumnSpec(Int64(), NonNull(), Unsorted()));
+  StringPool pool;
+  Dataframe df = Dataframe::CreateFromTypedSpec(kSpec, &pool);
+  df.InsertUnchecked(kSpec, int64_t{10});
+  df.InsertUnchecked(kSpec, int64_t{20});
+  df.Finalize();
+  TypedCursor filtered(&df, {FilterSpec{0, 0, Eq{}, {}}}, {});
+  TypedCursor sorted(&df, {}, {{0, SortDirection::kAscending}});
+  filtered.SetFilterValueUnchecked(0, int64_t{10});
+  filtered.ExecuteUnchecked();
+  ASSERT_FALSE(filtered.Eof());
+  EXPECT_EQ(filtered.GetCellUnchecked<0>(kSpec), int64_t{10});
+  sorted.ExecuteUnchecked();
+  ASSERT_FALSE(sorted.Eof());
+  EXPECT_EQ(sorted.GetCellUnchecked<0>(kSpec), int64_t{10});
+
+  // Same row count and mutation history, but different values and sort order.
+  Dataframe replacement = Dataframe::CreateFromTypedSpec(kSpec, &pool);
+  replacement.InsertUnchecked(kSpec, int64_t{40});
+  replacement.InsertUnchecked(kSpec, int64_t{30});
+  replacement.Finalize();
+  df = std::move(replacement);
+
+  filtered.SetFilterValueUnchecked(0, int64_t{30});
+  filtered.ExecuteUnchecked();
+  ASSERT_FALSE(filtered.Eof());
+  EXPECT_EQ(filtered.GetCellUnchecked<0>(kSpec), int64_t{30});
+  filtered.Next();
+  EXPECT_TRUE(filtered.Eof());
+  sorted.ExecuteUnchecked();
+  ASSERT_FALSE(sorted.Eof());
+  EXPECT_EQ(sorted.GetCellUnchecked<0>(kSpec), int64_t{30});
+  sorted.Next();
+  ASSERT_FALSE(sorted.Eof());
+  EXPECT_EQ(sorted.GetCellUnchecked<0>(kSpec), int64_t{40});
+  sorted.Next();
+  EXPECT_TRUE(sorted.Eof());
+}
+
+TEST(DataframeTest, TypedCursorReplacementWithRepeatedFilterColumn) {
+  static constexpr auto kSpec = CreateTypedDataframeSpec(
+      {"value"}, CreateTypedColumnSpec(Int64(), NonNull(), Unsorted()));
+  StringPool pool;
+  Dataframe df = Dataframe::CreateFromTypedSpec(kSpec, &pool);
+  df.InsertUnchecked(kSpec, int64_t{10});
+  df.SetCellUnchecked<0>(kSpec, 0, int64_t{20});
+  ASSERT_EQ(df.mutations(), uint64_t{2});
+  TypedCursor cursor(
+      &df, {FilterSpec{0, 0, Eq{}, {}}, FilterSpec{0, 1, Eq{}, {}}}, {});
+  cursor.SetFilterValueUnchecked(0, int64_t{20});
+  cursor.SetFilterValueUnchecked(1, int64_t{20});
+  cursor.ExecuteUnchecked();
+  ASSERT_FALSE(cursor.Eof());
+
+  Dataframe replacement = Dataframe::CreateFromTypedSpec(kSpec, &pool);
+  replacement.InsertUnchecked(kSpec, int64_t{30});
+  ASSERT_EQ(replacement.mutations(), uint64_t{1});
+  df = std::move(replacement);
+  // Both watched sums are 3: the independent generation must force a replan.
+  ASSERT_EQ(df.mutations(), uint64_t{3});
+  cursor.SetFilterValueUnchecked(0, int64_t{30});
+  cursor.SetFilterValueUnchecked(1, int64_t{30});
+  cursor.ExecuteUnchecked();
+  ASSERT_FALSE(cursor.Eof());
+  EXPECT_EQ(cursor.GetCellUnchecked<0>(kSpec), int64_t{30});
+}
+
+TEST(DataframeTest, TypedCursorFilterListAndResetAfterDataframeReplacement) {
+  static constexpr auto kSpec = CreateTypedDataframeSpec(
+      {"value"}, CreateTypedColumnSpec(Int64(), NonNull(), Unsorted()));
+  StringPool pool;
+  Dataframe df = Dataframe::CreateFromTypedSpec(kSpec, &pool);
+  df.InsertUnchecked(kSpec, int64_t{10});
+  df.Finalize();
+  TypedCursor cursor(&df, {FilterSpec{0, 0, In{}, {}}}, {});
+  TypedCursor::FilterValue value = int64_t{10};
+  cursor.SetFilterValueListUnchecked(0, &value, 1);
+  cursor.ExecuteUnchecked();
+  ASSERT_FALSE(cursor.Eof());
+  EXPECT_EQ(cursor.GetCellUnchecked<0>(kSpec), int64_t{10});
+
+  Dataframe replacement = Dataframe::CreateFromTypedSpec(kSpec, &pool);
+  replacement.InsertUnchecked(kSpec, int64_t{30});
+  replacement.Finalize();
+  df = std::move(replacement);
+  value = int64_t{30};
+  cursor.SetFilterValueListUnchecked(0, &value, 1);
+  cursor.ExecuteUnchecked();
+  ASSERT_FALSE(cursor.Eof());
+  EXPECT_EQ(cursor.GetCellUnchecked<0>(kSpec), int64_t{30});
+
+  Dataframe next = Dataframe::CreateFromTypedSpec(kSpec, &pool);
+  next.InsertUnchecked(kSpec, int64_t{50});
+  next.Finalize();
+  df = std::move(next);
+  cursor.Reset();
+  value = int64_t{50};
+  cursor.SetFilterValueListUnchecked(0, &value, 1);
+  cursor.ExecuteUnchecked();
+  ASSERT_FALSE(cursor.Eof());
+  EXPECT_EQ(cursor.GetCellUnchecked<0>(kSpec), int64_t{50});
+}
+
 TEST(DataframeTest, TypedCursorSetMultipleTimes) {
   static constexpr auto kSpec = CreateTypedDataframeSpec(
       {"id", "col2", "col3", "col4"},
diff --git a/src/trace_processor/core/dataframe/logical_plan.cc b/src/trace_processor/core/dataframe/logical_plan.cc
index 917403f..7e446b5 100644
--- a/src/trace_processor/core/dataframe/logical_plan.cc
+++ b/src/trace_processor/core/dataframe/logical_plan.cc
@@ -88,59 +88,6 @@
   return kLeastPreferred;
 }
 
-struct BestIndex {
-  uint32_t best_index_idx;
-  std::vector<uint32_t> best_index_specs;
-};
-std::optional<BestIndex> GetBestIndexForFilterSpecs(
-    uint32_t max_row_count,
-    const std::vector<FilterSpec>& all_specs,
-    const std::vector<uint8_t>& spec_already_handled,
-    const std::vector<Index>& indexes) {
-  // If we have very few rows, there's no point in using an index.
-  if (max_row_count <= 1) {
-    return std::nullopt;
-  }
-  uint32_t best_index_idx = std::numeric_limits<uint32_t>::max();
-  std::vector<uint32_t> best_index_specs;
-  for (uint32_t i = 0; i < indexes.size(); ++i) {
-    const Index& index = indexes[i];
-    std::vector<uint32_t> current_specs_for_this_index;
-    for (uint32_t column : index.columns()) {
-      bool found_spec_for_column = false;
-      for (uint32_t spec_idx = 0; spec_idx < all_specs.size(); ++spec_idx) {
-        if (spec_already_handled[spec_idx]) {
-          continue;
-        }
-        const FilterSpec& current_spec = all_specs[spec_idx];
-        if (current_spec.col == column &&
-            (current_spec.op.Is<Eq>() || current_spec.op.Is<In>())) {
-          current_specs_for_this_index.push_back(spec_idx);
-          found_spec_for_column = true;
-          break;
-        }
-      }
-      if (!found_spec_for_column) {
-        break;
-      }
-      // An In filter produces non-contiguous output, breaking the sort
-      // invariant needed by subsequent columns' binary searches. So In
-      // must be terminal: stop matching further index columns.
-      if (all_specs[current_specs_for_this_index.back()].op.Is<In>()) {
-        break;
-      }
-    }
-    if (current_specs_for_this_index.size() > best_index_specs.size()) {
-      best_index_idx = i;
-      best_index_specs = std::move(current_specs_for_this_index);
-    }
-  }
-  if (best_index_idx == std::numeric_limits<uint32_t>::max()) {
-    return std::nullopt;
-  }
-  return BestIndex{best_index_idx, std::move(best_index_specs)};
-}
-
 // Builds the logical plan for one query.
 class Planner {
  public:
@@ -288,35 +235,16 @@
 }
 
 bool Planner::TrySortedFilter(FilterSpec& spec) {
-  auto non_null_op = spec.op.TryDowncast<NonNullOp>();
-  if (!non_null_op) {
-    return false;
-  }
-  const Column& col = GetColumn(spec.col);
-  const auto& nullability = col.null_storage.nullability();
-  if (!nullability.Is<NonNull>() || col.sort_state.Is<Unsorted>()) {
-    return false;
-  }
-  if (!non_null_op->TryDowncast<RangeOp>()) {
+  std::optional<logical::FilterStrategy> strategy =
+      SortedFilterStrategy(GetColumn(spec.col), spec.op);
+  if (!strategy) {
     return false;
   }
 
   // We should have ordered the constraints such that we only reach this
   // point with range indices.
   PERFETTO_CHECK(rows_are_range_);
-
-  StorageType ct = col.storage.type();
-  if (ct.Is<Uint32>() && col.sort_state.Is<SetIdSorted>() &&
-      non_null_op->Is<Eq>()) {
-    AddFilter(spec, logical::SetIdSortedSearch{});
-    return true;
-  }
-  if (col.specialized_storage.Is<SpecializedStorage::SmallValueEq>() &&
-      non_null_op->Is<Eq>()) {
-    AddFilter(spec, logical::SmallValueLookup{});
-    return true;
-  }
-  AddFilter(spec, logical::BinarySearch{});
+  AddFilter(spec, *strategy);
   return true;
 }
 
@@ -694,6 +622,80 @@
   return res;
 }
 
+std::optional<BestIndex> GetBestIndexForFilterSpecs(
+    uint32_t max_row_count,
+    const std::vector<FilterSpec>& all_specs,
+    const std::vector<uint8_t>& spec_already_handled,
+    const std::vector<Index>& indexes) {
+  // If we have very few rows, there's no point in using an index.
+  if (max_row_count <= 1) {
+    return std::nullopt;
+  }
+  uint32_t best_index_idx = std::numeric_limits<uint32_t>::max();
+  std::vector<uint32_t> best_index_specs;
+  for (uint32_t i = 0; i < indexes.size(); ++i) {
+    const Index& index = indexes[i];
+    std::vector<uint32_t> current_specs_for_this_index;
+    for (uint32_t column : index.columns()) {
+      bool found_spec_for_column = false;
+      for (uint32_t spec_idx = 0; spec_idx < all_specs.size(); ++spec_idx) {
+        if (spec_already_handled[spec_idx]) {
+          continue;
+        }
+        const FilterSpec& current_spec = all_specs[spec_idx];
+        if (current_spec.col == column &&
+            (current_spec.op.Is<Eq>() || current_spec.op.Is<In>())) {
+          current_specs_for_this_index.push_back(spec_idx);
+          found_spec_for_column = true;
+          break;
+        }
+      }
+      if (!found_spec_for_column) {
+        break;
+      }
+      // An In filter produces non-contiguous output, breaking the sort
+      // invariant needed by subsequent columns' binary searches. So In
+      // must be terminal: stop matching further index columns.
+      if (all_specs[current_specs_for_this_index.back()].op.Is<In>()) {
+        break;
+      }
+    }
+    if (current_specs_for_this_index.size() > best_index_specs.size()) {
+      best_index_idx = i;
+      best_index_specs = std::move(current_specs_for_this_index);
+    }
+  }
+  if (best_index_idx == std::numeric_limits<uint32_t>::max()) {
+    return std::nullopt;
+  }
+  return BestIndex{best_index_idx, std::move(best_index_specs)};
+}
+
+std::optional<logical::FilterStrategy> SortedFilterStrategy(const Column& col,
+                                                            const Op& op) {
+  auto non_null_op = op.TryDowncast<NonNullOp>();
+  if (!non_null_op) {
+    return std::nullopt;
+  }
+  const auto& nullability = col.null_storage.nullability();
+  if (!nullability.Is<NonNull>() || col.sort_state.Is<Unsorted>()) {
+    return std::nullopt;
+  }
+  if (!non_null_op->TryDowncast<RangeOp>()) {
+    return std::nullopt;
+  }
+  StorageType ct = col.storage.type();
+  if (ct.Is<Uint32>() && col.sort_state.Is<SetIdSorted>() &&
+      non_null_op->Is<Eq>()) {
+    return logical::SetIdSortedSearch{};
+  }
+  if (col.specialized_storage.Is<SpecializedStorage::SmallValueEq>() &&
+      non_null_op->Is<Eq>()) {
+    return logical::SmallValueLookup{};
+  }
+  return logical::BinarySearch{};
+}
+
 base::StatusOr<LogicalPlan> LogicalPlanner::Plan(
     uint32_t row_count,
     const std::vector<std::shared_ptr<Column>>& columns,
diff --git a/src/trace_processor/core/dataframe/logical_plan.h b/src/trace_processor/core/dataframe/logical_plan.h
index bf8962f..8eda5c0 100644
--- a/src/trace_processor/core/dataframe/logical_plan.h
+++ b/src/trace_processor/core/dataframe/logical_plan.h
@@ -190,6 +190,27 @@
   std::string ToString() const;
 };
 
+// The index serving the most of `all_specs` not already handled, and those
+// specs in the index's column order: an equality or IN on each of its
+// leading columns, ending at the first IN. Null if no index serves any, or
+// there are too few rows for one to help.
+struct BestIndex {
+  uint32_t best_index_idx;
+  std::vector<uint32_t> best_index_specs;
+};
+std::optional<BestIndex> GetBestIndexForFilterSpecs(
+    uint32_t max_row_count,
+    const std::vector<FilterSpec>& all_specs,
+    const std::vector<uint8_t>& spec_already_handled,
+    const std::vector<Index>& indexes);
+
+// How `op` on `col` is answered by searching the column rather than testing
+// its rows, if it can be: the column must be sorted and hold no nulls, and
+// `op` one which keeps a contiguous run of its rows. Each strategy narrows a
+// range of rows; see filter_kernels.h for the searches.
+std::optional<logical::FilterStrategy> SortedFilterStrategy(const Column& col,
+                                                            const Op& op);
+
 // Chooses how a query should be run and records that as a LogicalPlan.
 //
 // Everything this class decides -- the order filters are applied in, which
diff --git a/src/trace_processor/core/dataframe/typed_cursor.cc b/src/trace_processor/core/dataframe/typed_cursor.cc
index e6e595b..ee6647f 100644
--- a/src/trace_processor/core/dataframe/typed_cursor.cc
+++ b/src/trace_processor/core/dataframe/typed_cursor.cc
@@ -28,7 +28,7 @@
 namespace perfetto::trace_processor::core::dataframe {
 
 void TypedCursor::ExecuteUnchecked() {
-  if (PERFETTO_UNLIKELY(last_execution_mutation_count_ != GetMutations())) {
+  if (PERFETTO_UNLIKELY(NeedsPrepareCursor())) {
     PrepareCursorInternal();
   }
   Fetcher fetcher{{}, filter_values_.data(), filter_value_list_states_.data()};
@@ -39,6 +39,7 @@
   auto plan = dataframe_->PlanQuery(filter_specs_, {}, sort_specs_, {}, 0);
   PERFETTO_CHECK(plan.ok());
   dataframe_->PrepareCursor(*plan, cursor_);
+  last_execution_generation_ = dataframe_->replacement_generation_;
   last_execution_mutation_count_ = GetMutations();
   for (const auto& spec : filter_specs_) {
     filter_value_mapping_[spec.source_index] =
diff --git a/src/trace_processor/core/dataframe/typed_cursor.h b/src/trace_processor/core/dataframe/typed_cursor.h
index c48bde9..23aaacc 100644
--- a/src/trace_processor/core/dataframe/typed_cursor.h
+++ b/src/trace_processor/core/dataframe/typed_cursor.h
@@ -140,7 +140,7 @@
       uint32_t index,
       const FilterValue* values,
       uint32_t count) {
-    if (PERFETTO_UNLIKELY(last_execution_mutation_count_ != GetMutations())) {
+    if (PERFETTO_UNLIKELY(NeedsPrepareCursor())) {
       PrepareCursorInternal();
     }
     uint32_t mapped = filter_value_mapping_[index];
@@ -198,25 +198,23 @@
         filter_specs_(std::move(filter_specs)),
         sort_specs_(std::move(sort_specs)),
         mutable_(mut),
-        column_mutation_count_(core::Slab<uint32_t*>::Alloc(
-            filter_specs_.size() + sort_specs_.size())) {
+        mutation_columns_(core::Slab<uint32_t>::Alloc(filter_specs_.size() +
+                                                      sort_specs_.size())) {
     filter_values_.resize(filter_specs_.size());
     filter_value_list_states_.resize(filter_specs_.size());
     filter_value_mapping_.resize(filter_specs_.size(),
                                  std::numeric_limits<uint32_t>::max());
     uint32_t i = 0;
     for (const auto& spec : filter_specs_) {
-      column_mutation_count_[i++] =
-          &dataframe->column_ptrs_[spec.col]->mutations;
+      mutation_columns_[i++] = spec.col;
     }
     for (const auto& spec : sort_specs_) {
-      column_mutation_count_[i++] =
-          &dataframe->column_ptrs_[spec.col]->mutations;
+      mutation_columns_[i++] = spec.col;
     }
   }
   template <typename C>
   PERFETTO_ALWAYS_INLINE void SetFilterValueInternal(uint32_t index, C value) {
-    if (PERFETTO_UNLIKELY(last_execution_mutation_count_ != GetMutations())) {
+    if (PERFETTO_UNLIKELY(NeedsPrepareCursor())) {
       PrepareCursorInternal();
     }
     uint32_t mapped = filter_value_mapping_[index];
@@ -227,10 +225,15 @@
 
   PERFETTO_NO_INLINE void PrepareCursorInternal();
 
-  uint32_t GetMutations() const {
-    uint32_t mutations = dataframe_->non_column_mutations_;
-    for (uint32_t* m : column_mutation_count_) {
-      mutations += *m;
+  bool NeedsPrepareCursor() const {
+    return last_execution_generation_ != dataframe_->replacement_generation_ ||
+           last_execution_mutation_count_ != GetMutations();
+  }
+
+  uint64_t GetMutations() const {
+    uint64_t mutations = dataframe_->non_column_mutations_;
+    for (uint32_t col : mutation_columns_) {
+      mutations += dataframe_->column_ptrs_[col]->mutations;
     }
     return mutations;
   }
@@ -244,9 +247,10 @@
   bool mutable_;
   Cursor<Fetcher> cursor_;
 
-  core::Slab<uint32_t*> column_mutation_count_;
-  uint32_t last_execution_mutation_count_ =
-      std::numeric_limits<uint32_t>::max();
+  core::Slab<uint32_t> mutation_columns_;
+  uint64_t last_execution_generation_ = std::numeric_limits<uint64_t>::max();
+  uint64_t last_execution_mutation_count_ =
+      std::numeric_limits<uint64_t>::max();
 };
 
 }  // namespace perfetto::trace_processor::core::dataframe
diff --git a/src/trace_processor/core/exec/BUILD.gn b/src/trace_processor/core/exec/BUILD.gn
index 4b342bc..66a3cb9 100644
--- a/src/trace_processor/core/exec/BUILD.gn
+++ b/src/trace_processor/core/exec/BUILD.gn
@@ -34,16 +34,25 @@
     "context.h",
     "dataframe_scan.cc",
     "dataframe_scan.h",
+    "distinct.cc",
+    "distinct.h",
+    "filter.cc",
+    "filter.h",
+    "filter_value.h",
     "group_table.cc",
     "group_table.h",
     "grouped_sort.cc",
     "grouped_sort.h",
     "hash_aggregate.cc",
     "hash_aggregate.h",
+    "interval_fill_gaps.cc",
+    "interval_fill_gaps.h",
     "interval_flatten.cc",
     "interval_flatten.h",
     "interval_intersect.cc",
     "interval_intersect.h",
+    "interval_lanes.cc",
+    "interval_lanes.h",
     "layout_column.h",
     "operator.cc",
     "operator.h",
@@ -101,12 +110,16 @@
     "assert_type_unittest.cc",
     "breaker_unittest.cc",
     "dataframe_scan_unittest.cc",
+    "distinct_unittest.cc",
     "executor_contract_unittest.cc",
+    "filter_unittest.cc",
     "group_table_unittest.cc",
     "grouped_sort_unittest.cc",
     "hash_aggregate_unittest.cc",
+    "interval_fill_gaps_unittest.cc",
     "interval_flatten_unittest.cc",
     "interval_intersect_unittest.cc",
+    "interval_lanes_unittest.cc",
     "operator_unittest.cc",
     "row_batch_unittest.cc",
     "row_store_unittest.cc",
@@ -133,6 +146,8 @@
     testonly = true
     sources = [
       "breaker_benchmark.cc",
+      "distinct_benchmark.cc",
+      "filter_benchmark.cc",
       "grouping_benchmark.cc",
       "hash_aggregate_benchmark.cc",
       "interval_flatten_benchmark.cc",
@@ -147,6 +162,7 @@
       ":exec",
       "../../../../gn:benchmark",
       "../../../../gn:default_deps",
+      "../../../base",
       "../../containers",
       "../common",
       "../dataframe",
diff --git a/src/trace_processor/core/exec/aggregate_function.cc b/src/trace_processor/core/exec/aggregate_function.cc
index ddcb083..77a896d 100644
--- a/src/trace_processor/core/exec/aggregate_function.cc
+++ b/src/trace_processor/core/exec/aggregate_function.cc
@@ -20,6 +20,7 @@
 #include <cstdint>
 #include <memory>
 
+#include "perfetto/base/compiler.h"
 #include "perfetto/base/logging.h"
 #include "perfetto/ext/base/utils.h"
 #include "src/trace_processor/core/common/storage_types.h"
@@ -105,6 +106,21 @@
 
 namespace {
 
+// How many rows of `in` hold a value.
+uint32_t CountValid(const AggregateInput& in) {
+  if (!in.valid) {
+    return in.rows;
+  }
+  uint32_t count = 0;
+  for (uint32_t row = 0; row < in.rows; row += 64) {
+    uint32_t n = std::min(64u, in.rows - row);
+    uint64_t mask = n == 64 ? ~uint64_t{0} : (uint64_t{1} << n) - 1;
+    count +=
+        static_cast<uint32_t>(PERFETTO_POPCOUNT(in.valid[row / 64] & mask));
+  }
+  return count;
+}
+
 // COUNT(*): how many rows a group holds.
 class CountStar : public AggregateFunction {
  public:
@@ -119,6 +135,12 @@
       ++states.words[groups[row] * states.stride];
     }
   }
+  void UpdateGroup(const AggregateInput& in,
+                   uint32_t group,
+                   GroupStates states,
+                   bool*) const override {
+    states.words[group * states.stride] += in.rows;
+  }
   void Combine(const GroupMerge* merges,
                uint32_t count,
                GroupStates states,
@@ -172,6 +194,12 @@
       states.words[groups[row] * states.stride] += valid;
     }
   }
+  void UpdateGroup(const AggregateInput& in,
+                   uint32_t group,
+                   GroupStates states,
+                   bool*) const override {
+    states.words[group * states.stride] += CountValid(in);
+  }
 };
 
 // SUM: the total of a group's values, null if it holds none. State: the
@@ -198,6 +226,45 @@
     }
     *overflow |= ovf;
   }
+  void UpdateGroup(const AggregateInput& in,
+                   uint32_t group,
+                   GroupStates states,
+                   bool* overflow) const override {
+    // The high and low 32 bits of the values are summed apart, which can't
+    // overflow for a batch and vectorizes, unlike checking each addition.
+    PERFETTO_DCHECK(in.rows <= kMaxBatchRows);
+    int64_t high = 0;
+    uint64_t low = 0;
+    if (!in.valid) {
+      for (uint32_t row = 0; row < in.rows; ++row) {
+        high += in.values[row] >> 32;
+        low += static_cast<uint32_t>(in.values[row]);
+      }
+    } else {
+      // A word of validity at a time, rather than a bit for each row.
+      for (uint32_t row = 0; row < in.rows; row += 64) {
+        uint32_t n = std::min(64u, in.rows - row);
+        uint64_t valid = in.valid[row / 64];
+        for (uint32_t i = 0; i < n; ++i) {
+          int64_t value =
+              in.values[row + i] & -static_cast<int64_t>((valid >> i) & 1);
+          high += value >> 32;
+          low += static_cast<uint32_t>(value);
+        }
+      }
+    }
+    // The sum is high * 2^32 + low, which fits in 64 bits if, once low's
+    // carry is in high, high fits in 32.
+    high += static_cast<int64_t>(low >> 32);
+    bool fits = high >= INT32_MIN && high <= INT32_MAX;
+    auto sum = static_cast<int64_t>(static_cast<uint64_t>(high) << 32 |
+                                    (low & 0xffffffff));
+    int64_t& total = states.words[group * states.stride];
+    *overflow |= !fits || !base::CheckedAdd(total, sum, &total);
+    if (states.seen) {
+      states.seen[group] |= CountValid(in) != 0;
+    }
+  }
   void Combine(const GroupMerge* merges,
                uint32_t count,
                GroupStates states,
@@ -283,6 +350,24 @@
       }
     }
   }
+  void UpdateGroup(const AggregateInput& in,
+                   uint32_t group,
+                   GroupStates states,
+                   bool*) const override {
+    auto& state =
+        reinterpret_cast<uint64_t&>(states.words[group * states.stride]);
+    uint64_t best = state;
+    for (uint32_t row = 0; row < in.rows; ++row) {
+      bool valid = !in.valid || ((in.valid[row / 64] >> (row % 64)) & 1);
+      uint64_t value =
+          (static_cast<uint64_t>(in.values[row]) ^ mask_) & -uint64_t{valid};
+      best = std::max(best, value);
+    }
+    state = best;
+    if (states.seen) {
+      states.seen[group] |= CountValid(in) != 0;
+    }
+  }
   void Combine(const GroupMerge* merges,
                uint32_t count,
                GroupStates states,
diff --git a/src/trace_processor/core/exec/aggregate_function.h b/src/trace_processor/core/exec/aggregate_function.h
index 0ec56e1..35ded9a 100644
--- a/src/trace_processor/core/exec/aggregate_function.h
+++ b/src/trace_processor/core/exec/aggregate_function.h
@@ -117,6 +117,12 @@
                       const uint32_t* groups,
                       GroupStates states,
                       bool* overflow) const = 0;
+  // As Update, with every row of `in` in group `group`, as without keys. A
+  // function can then fold the batch before touching the state.
+  virtual void UpdateGroup(const AggregateInput& in,
+                           uint32_t group,
+                           GroupStates states,
+                           bool* overflow) const = 0;
   // In order, for each of the `count` merges, adds the state of group
   // `from` into that of group `into`.
   virtual void Combine(const GroupMerge* merges,
diff --git a/src/trace_processor/core/exec/batch_buffer.cc b/src/trace_processor/core/exec/batch_buffer.cc
index b048c88..a3fb353 100644
--- a/src/trace_processor/core/exec/batch_buffer.cc
+++ b/src/trace_processor/core/exec/batch_buffer.cc
@@ -31,7 +31,8 @@
     PERFETTO_DCHECK(in.column_count() == columns_.size());
 #if PERFETTO_DCHECK_IS_ON()
     for (uint32_t c = 0; c < in.column_count(); ++c) {
-      PERFETTO_DCHECK(SameLogicalType(columns_[c].view, in.column(c)));
+      PERFETTO_DCHECK(SameLogicalType(ColumnShape::Of(columns_[c].view),
+                                      ColumnShape::Of(in.column(c))));
     }
 #endif
   } else {
diff --git a/src/trace_processor/core/exec/column_view.h b/src/trace_processor/core/exec/column_view.h
index e2e9d57..bf2ae40 100644
--- a/src/trace_processor/core/exec/column_view.h
+++ b/src/trace_processor/core/exec/column_view.h
@@ -119,18 +119,30 @@
   return column.kind() == ColumnView::Kind::kFlat && column.type().Is<Tag>();
 }
 
+// The kind and storage type of a column view. These decide whether views from
+// different batches can be combined. Kept apart from the view so columns can
+// be compared after their batches are gone.
+struct ColumnShape {
+  static ColumnShape Of(const ColumnView& view) {
+    return {view.kind(), view.type()};
+  }
+
+  ColumnView::Kind kind;
+  StorageType type;
+};
+
 // Whether two batches' views of a column can be combined. An implicit Id and
 // a stored Uint32 hold the same values: gathering turns one into the other.
-inline bool SameLogicalType(const ColumnView& a, const ColumnView& b) {
-  auto is_uint32 = [](const ColumnView& view) {
-    return view.kind() != ColumnView::Kind::kVariant &&
-           (view.type().Is<Id>() || view.type().Is<Uint32>());
+inline bool SameLogicalType(const ColumnShape& a, const ColumnShape& b) {
+  auto is_uint32 = [](const ColumnShape& shape) {
+    return shape.kind != ColumnView::Kind::kVariant &&
+           (shape.type.Is<Id>() || shape.type.Is<Uint32>());
   };
   if (is_uint32(a) && is_uint32(b)) {
     return true;
   }
-  return a.kind() == b.kind() &&
-         (a.kind() == ColumnView::Kind::kVariant || a.type() == b.type());
+  return a.kind == b.kind &&
+         (a.kind == ColumnView::Kind::kVariant || a.type == b.type);
 }
 
 }  // namespace perfetto::trace_processor::core::exec
diff --git a/src/trace_processor/core/exec/context.h b/src/trace_processor/core/exec/context.h
index b2001f7..c69bdad 100644
--- a/src/trace_processor/core/exec/context.h
+++ b/src/trace_processor/core/exec/context.h
@@ -24,10 +24,12 @@
 
 #include "perfetto/base/compiler.h"
 #include "src/trace_processor/core/exec/column_chunk.h"
+#include "src/trace_processor/core/util/span.h"
 
 namespace perfetto::trace_processor::core::exec {
 
 class Context;
+struct FilterValue;
 
 // The storage one column of a batch is in, if the batch owns it rather than
 // borrowing storage which outlives the run: up to kMaxBatchRows values and
@@ -109,6 +111,14 @@
   // value is zero.
   const ColumnBuffer& NullBuffer();
 
+  // The values the next run's filters compare with, by parameter, already
+  // cast (see FilterValue). Nothing is copied: the caller keeps them alive and
+  // unchanged until the run ends.
+  void SetFilterValues(Span<const FilterValue> values) {
+    filter_values_ = values;
+  }
+  Span<const FilterValue> filter_values() const { return filter_values_; }
+
  private:
   friend class ColumnBuffer;
 
@@ -121,6 +131,7 @@
   std::vector<std::unique_ptr<ColumnBuffer::Block>> blocks_;
   ColumnBuffer::Block* free_ = nullptr;
   ColumnBuffer nulls_;
+  Span<const FilterValue> filter_values_;
 };
 
 inline void ColumnBuffer::Release() {
diff --git a/src/trace_processor/core/exec/distinct.cc b/src/trace_processor/core/exec/distinct.cc
new file mode 100644
index 0000000..f96c7a3
--- /dev/null
+++ b/src/trace_processor/core/exec/distinct.cc
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2026 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.
+ */
+
+#include "src/trace_processor/core/exec/distinct.h"
+
+#include <cstdint>
+#include <memory>
+#include <optional>
+#include <utility>
+#include <vector>
+
+#include "perfetto/base/logging.h"
+#include "perfetto/base/status.h"
+#include "src/trace_processor/core/exec/operator.h"
+#include "src/trace_processor/core/exec/row_batch.h"
+#include "src/trace_processor/core/util/span.h"
+
+namespace perfetto::trace_processor::core::exec {
+
+Distinct::Distinct(std::vector<uint32_t> columns)
+    : columns_(std::move(columns)) {
+  PERFETTO_CHECK(!columns_.empty() && columns_.size() <= kMaxColumns);
+}
+
+Distinct::~Distinct() = default;
+
+Distinct::State::~State() = default;
+
+void Distinct::State::Reset() {
+  keys.Clear();
+  status = base::OkStatus();
+}
+
+std::unique_ptr<OperatorState> Distinct::MakeState(Context&) const {
+  return std::make_unique<State>();
+}
+
+base::Status Distinct::status(const OperatorState& state) const {
+  return state.Cast<const State>().status;
+}
+
+bool Distinct::Process(RowBatch& batch, OperatorState& state) const {
+  State& s = state.Cast<State>();
+  uint32_t count = batch.size();
+  if (count == 0) {
+    return true;
+  }
+  s.row_keys.resize(count);
+  uint32_t next = s.keys.size();
+  if (std::optional<uint32_t> bad =
+          s.keys.FindOrCreate(batch, columns_, s.row_keys.data())) {
+    s.status = base::ErrStatus(
+        "DISTINCT: key %u must be a column holding one type", *bad + 1);
+    return false;
+  }
+  if (s.keys.size() == next + count) {
+    return true;
+  }
+  // Keys are numbered in the order first seen, so a row is the first with
+  // its key exactly when it got the next number.
+  s.kept.resize(count);
+  uint32_t* kept = s.kept.data();
+  uint32_t n = 0;
+  for (uint32_t i = 0; i < count; ++i) {
+    kept[n] = i;
+    bool first = s.row_keys[i] == next;
+    n += first;
+    next += first;
+  }
+  batch.mutable_selection().Keep(Span<const uint32_t>(kept, kept + n));
+  return true;
+}
+
+}  // namespace perfetto::trace_processor::core::exec
diff --git a/src/trace_processor/core/exec/distinct.h b/src/trace_processor/core/exec/distinct.h
new file mode 100644
index 0000000..db6b30b
--- /dev/null
+++ b/src/trace_processor/core/exec/distinct.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2026 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.
+ */
+
+#ifndef SRC_TRACE_PROCESSOR_CORE_EXEC_DISTINCT_H_
+#define SRC_TRACE_PROCESSOR_CORE_EXEC_DISTINCT_H_
+
+#include <cstdint>
+#include <memory>
+#include <vector>
+
+#include "perfetto/base/status.h"
+#include "src/trace_processor/core/exec/group_table.h"
+#include "src/trace_processor/core/exec/operator.h"
+#include "src/trace_processor/core/exec/row_batch.h"
+#include "src/trace_processor/core/util/flex_vector.h"
+
+namespace perfetto::trace_processor::core::exec {
+
+class Context;
+
+// Keeps the first row of each set of rows equal in `columns` and drops the
+// rest. Rows are compared as in GroupTable, and the rows kept stay in order.
+//
+// Rows are dropped by narrowing the selection, so nothing is copied. Only
+// the keys of the rows kept are stored, so memory grows with the number of
+// distinct rows, not the number of input rows. There can be at most
+// kMaxColumns columns.
+class Distinct final : public Transform {
+ public:
+  static constexpr char kType = 0;
+  const void* type() const override { return &kType; }
+
+  static constexpr uint32_t kMaxColumns = 64;
+
+  explicit Distinct(std::vector<uint32_t> columns);
+  ~Distinct() override;
+
+  std::unique_ptr<OperatorState> MakeState(Context&) const override;
+  bool Process(RowBatch&, OperatorState&) const override;
+  base::Status status(const OperatorState&) const override;
+
+ private:
+  friend class PipelineFormatter;
+
+  struct State : OperatorState {
+    State() : OperatorState(ResetEachRun{}) {}
+    ~State() override;
+    void Reset() override;
+
+    // Every key seen so far, numbered in the order first seen.
+    GroupTable keys;
+
+    // Scratch for the current batch: the key number of each row, and the
+    // positions of the rows kept.
+    FlexVector<uint32_t> row_keys;
+    FlexVector<uint32_t> kept;
+
+    base::Status status = base::OkStatus();
+  };
+
+  std::vector<uint32_t> columns_;
+};
+
+}  // namespace perfetto::trace_processor::core::exec
+
+#endif  // SRC_TRACE_PROCESSOR_CORE_EXEC_DISTINCT_H_
diff --git a/src/trace_processor/core/exec/distinct_benchmark.cc b/src/trace_processor/core/exec/distinct_benchmark.cc
new file mode 100644
index 0000000..0a65115
--- /dev/null
+++ b/src/trace_processor/core/exec/distinct_benchmark.cc
@@ -0,0 +1,124 @@
+/*
+ * Copyright (C) 2026 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.
+ */
+
+#include <benchmark/benchmark.h>
+
+#include <algorithm>
+#include <cstdint>
+#include <memory>
+#include <numeric>
+#include <random>
+#include <vector>
+
+#include "src/trace_processor/containers/string_pool.h"
+#include "src/trace_processor/core/common/storage_types.h"
+#include "src/trace_processor/core/exec/column_view.h"
+#include "src/trace_processor/core/exec/context.h"
+#include "src/trace_processor/core/exec/distinct.h"
+#include "src/trace_processor/core/exec/operator.h"
+#include "src/trace_processor/core/exec/row_batch.h"
+
+// Drops duplicate rows for each kind of key. The number of distinct rows
+// ranges from a few to nearly one per row. Rows are either shuffled or
+// clustered in runs, as when the input is sorted.
+
+namespace perfetto::trace_processor::core::exec {
+namespace {
+
+enum Shape : int64_t {
+  kInt64 = 0,
+  kTwoInt64 = 1,
+  kString = 2,
+};
+
+// Arguments: key kind, number of distinct rows, 1 if rows are clustered in
+// runs and 0 if shuffled, and number of full input batches.
+void BM_Distinct(benchmark::State& state) {
+  auto shape = static_cast<Shape>(state.range(0));
+  auto distinct = static_cast<uint32_t>(state.range(1));
+  bool clustered = state.range(2) != 0;
+  auto rows = static_cast<uint32_t>(state.range(3)) * kMaxBatchRows;
+
+  std::vector<int64_t> ints;
+  std::vector<int64_t> seconds;
+  std::vector<StringPool::Id> strings;
+  // Shuffle the rows so keys do not repeat in a fixed order. A fixed order
+  // would let the hardware prefetcher hide the cost of random access.
+  std::vector<uint32_t> order(rows);
+  std::iota(order.begin(), order.end(), 0);
+  std::shuffle(order.begin(), order.end(), std::mt19937(1));
+  for (uint32_t i = 0; i < rows; ++i) {
+    uint32_t key = clustered
+                       ? static_cast<uint32_t>(uint64_t{i} * distinct / rows)
+                       : (order[i] * 2654435761u) % distinct;
+    // Spread keys out like ids and timestamps, instead of 0..distinct.
+    ints.push_back(int64_t{key} * 1000003);
+    seconds.push_back(int64_t{key} % 7);
+    strings.push_back(StringPool::Id::Raw(key + 1));
+  }
+  std::vector<RowBatch> batches;
+  for (uint32_t at = 0; at < rows; at += kMaxBatchRows) {
+    RowBatch& batch = batches.emplace_back();
+    switch (shape) {
+      case kInt64:
+        batch.AddBorrowedColumn(ColumnView::Reference(
+            StorageType{Int64{}}, ints.data(), nullptr, at));
+        break;
+      case kTwoInt64:
+        batch.AddBorrowedColumn(ColumnView::Reference(
+            StorageType{Int64{}}, ints.data(), nullptr, at));
+        batch.AddBorrowedColumn(ColumnView::Reference(
+            StorageType{Int64{}}, seconds.data(), nullptr, at));
+        break;
+      case kString:
+        batch.AddBorrowedColumn(ColumnView::Reference(
+            StorageType{String{}}, strings.data(), nullptr, at));
+        break;
+    }
+    batch.SetRowCount(kMaxBatchRows);
+  }
+  std::vector<uint32_t> columns = shape == kTwoInt64
+                                      ? std::vector<uint32_t>{0, 1}
+                                      : std::vector<uint32_t>{0};
+
+  Distinct op(columns);
+  Context context;
+  std::unique_ptr<OperatorState> op_state = op.MakeState(context);
+  RowBatch out;
+  for (auto _ : state) {
+    for (const RowBatch& batch : batches) {
+      out.CopyFrom(batch);
+      op.Process(out, *op_state);
+      benchmark::DoNotOptimize(out.size());
+    }
+    op_state->Reset();
+  }
+  state.SetItemsProcessed(static_cast<int64_t>(state.iterations()) * rows);
+}
+BENCHMARK(BM_Distinct)
+    // One Int64 key, from a few distinct rows to one per row.
+    ->Args({kInt64, 8, 0, 16})
+    ->Args({kInt64, 512, 0, 16})
+    ->Args({kInt64, 32768, 0, 16})
+    ->Args({kInt64, 512, 1, 16})
+    // Mostly distinct rows over a larger input, so the table exceeds caches.
+    ->Args({kInt64, 1 << 18, 0, 128})
+    // Other key kinds, with a moderate number of distinct rows.
+    ->Args({kTwoInt64, 512, 0, 16})
+    ->Args({kString, 512, 0, 16});
+
+}  // namespace
+}  // namespace perfetto::trace_processor::core::exec
diff --git a/src/trace_processor/core/exec/distinct_unittest.cc b/src/trace_processor/core/exec/distinct_unittest.cc
new file mode 100644
index 0000000..50b8add
--- /dev/null
+++ b/src/trace_processor/core/exec/distinct_unittest.cc
@@ -0,0 +1,168 @@
+/*
+ * Copyright (C) 2026 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.
+ */
+
+#include "src/trace_processor/core/exec/distinct.h"
+
+#include <cstdint>
+#include <memory>
+#include <optional>
+#include <vector>
+
+#include "src/trace_processor/containers/string_pool.h"
+#include "src/trace_processor/core/common/storage_types.h"
+#include "src/trace_processor/core/exec/column_view.h"
+#include "src/trace_processor/core/exec/operator.h"
+#include "src/trace_processor/core/exec/row_batch.h"
+#include "src/trace_processor/core/exec/test_utils.h"
+#include "src/trace_processor/core/util/bit_vector.h"
+#include "src/trace_processor/core/util/span.h"
+#include "test/gtest_and_gmock.h"
+
+namespace perfetto::trace_processor::core::exec {
+namespace {
+
+using ::testing::ElementsAre;
+using ::testing::HasSubstr;
+using ::testing::IsEmpty;
+
+// Runs batches of one Int64 column through a Distinct over it.
+struct Batches {
+  Batches() : op({0}), state(op.MakeState(test::TestContext())) {}
+
+  // The values kept from `values`, in order.
+  std::vector<int64_t> Process(std::vector<int64_t> values) {
+    batches.push_back(std::move(values));
+    RowBatch in;
+    in.AddBorrowedColumn(
+        ColumnView::Reference(StorageType{Int64{}}, batches.back().data()));
+    in.SetRowCount(static_cast<uint32_t>(batches.back().size()));
+    EXPECT_TRUE(test::ProcessCopy(op, in, out, *state))
+        << op.status(*state).message();
+    return test::ReadColumn<int64_t>(out, 0);
+  }
+
+  Distinct op;
+  std::unique_ptr<OperatorState> state;
+  // Kept alive, as the batches borrow them.
+  std::vector<std::vector<int64_t>> batches;
+  RowBatch out;
+};
+
+TEST(DistinctTest, KeepsTheFirstOfEachValueInOrder) {
+  Batches run;
+  EXPECT_THAT(run.Process({3, 1, 3, 2, 1, 2}), ElementsAre(3, 1, 2));
+}
+
+TEST(DistinctTest, ValuesSeenInEarlierBatchesAreDropped) {
+  Batches run;
+  EXPECT_THAT(run.Process({1, 2}), ElementsAre(1, 2));
+  EXPECT_THAT(run.Process({2, 3, 1, 3}), ElementsAre(3));
+  EXPECT_THAT(run.Process({1, 2, 3}), IsEmpty());
+}
+
+TEST(DistinctTest, RowsAreEqualOnlyIfEveryColumnIs) {
+  StringPool pool;
+  StringPool::Id a = pool.InternString("a");
+  StringPool::Id b = pool.InternString("b");
+  std::vector<int64_t> ints = {1, 1, 1, 2, 2};
+  std::vector<StringPool::Id> strings = {a, b, a, a, a};
+  RowBatch in;
+  in.AddBorrowedColumn(
+      ColumnView::Reference(StorageType{Int64{}}, ints.data()));
+  in.AddBorrowedColumn(
+      ColumnView::Reference(StorageType{String{}}, strings.data()));
+  in.SetRowCount(5);
+
+  Distinct op({0, 1});
+  std::unique_ptr<OperatorState> state = op.MakeState(test::TestContext());
+  RowBatch out;
+  ASSERT_TRUE(test::ProcessCopy(op, in, out, *state));
+  EXPECT_THAT(test::ReadColumn<int64_t>(out, 0), ElementsAre(1, 1, 2));
+  EXPECT_THAT(test::ReadColumn<StringPool::Id>(out, 1), ElementsAre(a, b, a));
+}
+
+// As in SQL's DISTINCT, nulls equal each other but not zero, and 0.0 equals
+// -0.0.
+TEST(DistinctTest, NullsAreOneValueAndZeroesAreEqual) {
+  std::vector<double> values = {0.0, 0.0, -0.0, 1.5, 0.0};
+  BitVector valid = BitVector::CreateWithSize(5);
+  valid.set(1);
+  valid.set(2);
+  valid.set(3);
+  RowBatch in;
+  in.AddBorrowedColumn(
+      ColumnView::Reference(StorageType{Double{}}, values.data(), &valid));
+  in.SetRowCount(5);
+
+  Distinct op({0});
+  std::unique_ptr<OperatorState> state = op.MakeState(test::TestContext());
+  RowBatch out;
+  ASSERT_TRUE(test::ProcessCopy(op, in, out, *state));
+  EXPECT_THAT(test::ReadNullableColumn<double>(out, 0),
+              ElementsAre(std::nullopt, 0.0, 1.5));
+}
+
+// A batch whose earlier steps dropped rows is read through its selection.
+TEST(DistinctTest, OnlyTheRowsKeptAreRead) {
+  std::vector<int64_t> values = {7, 1, 7, 2, 1};
+  RowBatch in;
+  in.AddBorrowedColumn(
+      ColumnView::Reference(StorageType{Int64{}}, values.data()));
+  in.SetRowCount(5);
+  std::vector<uint32_t> kept = {1, 3, 4};
+  in.mutable_selection().Keep(
+      Span<const uint32_t>(kept.data(), kept.data() + kept.size()));
+
+  Distinct op({0});
+  std::unique_ptr<OperatorState> state = op.MakeState(test::TestContext());
+  RowBatch out;
+  ASSERT_TRUE(test::ProcessCopy(op, in, out, *state));
+  EXPECT_THAT(test::ReadColumn<int64_t>(out, 0), ElementsAre(1, 2));
+}
+
+TEST(DistinctTest, AColumnChangingKindFailsUntilReset) {
+  std::vector<int64_t> ints = {1};
+  std::vector<double> doubles = {1.0};
+  RowBatch of_ints;
+  of_ints.AddBorrowedColumn(
+      ColumnView::Reference(StorageType{Int64{}}, ints.data()));
+  of_ints.SetRowCount(1);
+  RowBatch of_doubles;
+  of_doubles.AddBorrowedColumn(
+      ColumnView::Reference(StorageType{Double{}}, doubles.data()));
+  of_doubles.SetRowCount(1);
+
+  Distinct op({0});
+  std::unique_ptr<OperatorState> state = op.MakeState(test::TestContext());
+  RowBatch out;
+  ASSERT_TRUE(test::ProcessCopy(op, of_ints, out, *state));
+  EXPECT_FALSE(test::ProcessCopy(op, of_doubles, out, *state));
+  EXPECT_THAT(op.status(*state).message(),
+              HasSubstr("DISTINCT: key 1 must be a column holding one type"));
+
+  // A new run starts with nothing seen.
+  state->Reset();
+  EXPECT_TRUE(op.status(*state).ok());
+  ASSERT_TRUE(test::ProcessCopy(op, of_doubles, out, *state));
+  ASSERT_TRUE(test::ProcessCopy(op, of_doubles, out, *state));
+  EXPECT_EQ(out.size(), 0u);
+  state->Reset();
+  ASSERT_TRUE(test::ProcessCopy(op, of_doubles, out, *state));
+  EXPECT_EQ(out.size(), 1u);
+}
+
+}  // namespace
+}  // namespace perfetto::trace_processor::core::exec
diff --git a/src/trace_processor/core/exec/executor_contract_unittest.cc b/src/trace_processor/core/exec/executor_contract_unittest.cc
index 1d91d00..8e224cb 100644
--- a/src/trace_processor/core/exec/executor_contract_unittest.cc
+++ b/src/trace_processor/core/exec/executor_contract_unittest.cc
@@ -134,7 +134,8 @@
   RowStore store;
   ASSERT_TRUE(store.Append(input).ok());
   ASSERT_EQ(
-      store.View(&output, Span<const uint32_t>(rows), test::TestContext()), 4u);
+      store.Gather(&output, Span<const uint32_t>(rows), test::TestContext()),
+      4u);
   for (uint32_t i = 0; i < 4; ++i) {
     double value = output.Value<double>(0, i);
     uint64_t actual;
@@ -193,9 +194,9 @@
     }
     RowBatch out;
     ASSERT_EQ(
-        store.View(&out,
-                   Span<const uint32_t>(order.data(), order.data() + count),
-                   context),
+        store.Gather(&out,
+                     Span<const uint32_t>(order.data(), order.data() + count),
+                     context),
         count);
     EXPECT_NE(out.column(0).data(), stable.data());
     EXPECT_TRUE(out.selection().prefix());
diff --git a/src/trace_processor/core/exec/filter.cc b/src/trace_processor/core/exec/filter.cc
new file mode 100644
index 0000000..9ad2ae6
--- /dev/null
+++ b/src/trace_processor/core/exec/filter.cc
@@ -0,0 +1,223 @@
+/*
+ * Copyright (C) 2026 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.
+ */
+
+#include "src/trace_processor/core/exec/filter.h"
+
+#include <cstdint>
+#include <functional>
+#include <memory>
+#include <type_traits>
+#include <utility>
+#include <vector>
+
+#include "perfetto/base/logging.h"
+#include "perfetto/ext/base/variant.h"
+#include "src/trace_processor/containers/string_pool.h"
+#include "src/trace_processor/core/common/filter_kernels.h"
+#include "src/trace_processor/core/common/filter_value_cast.h"
+#include "src/trace_processor/core/common/op_types.h"
+#include "src/trace_processor/core/common/storage_types.h"
+#include "src/trace_processor/core/exec/column_view.h"
+#include "src/trace_processor/core/exec/context.h"
+#include "src/trace_processor/core/exec/filter_value.h"
+#include "src/trace_processor/core/exec/operator.h"
+#include "src/trace_processor/core/exec/row_batch.h"
+#include "src/trace_processor/core/exec/selection.h"
+#include "src/trace_processor/core/util/bit_vector.h"
+#include "src/trace_processor/core/util/span.h"
+
+namespace perfetto::trace_processor::core::exec {
+namespace {
+
+using filter::CastFilterValueResult;
+
+// The batch rows kept so far: `count` of them from `rows`, increasing. Each
+// condition narrows them in place.
+struct Rows {
+  uint32_t* rows;
+  uint32_t count;
+};
+
+// Keeps the rows which are null if `nulls`, or which are not otherwise.
+void KeepNulls(const ColumnView& column, bool nulls, Rows& r) {
+  const BitVector* validity = column.validity();
+  if (!validity) {
+    r.count = nulls ? 0 : r.count;
+    return;
+  }
+  uint32_t start = column.start();
+  uint32_t kept = 0;
+  for (uint32_t i = 0; i < r.count; ++i) {
+    uint32_t row = r.rows[i];
+    if (validity->is_set(start + row) != nulls) {
+      r.rows[kept++] = row;
+    }
+  }
+  r.count = kept;
+}
+
+// Keeps the rows of a column of storage type T which compare true by O with
+// the filter value. The kernels read each row's value at the column's data
+// plus the row, so the data passed starts where the window does.
+template <typename T, typename O>
+void Compare(const ColumnView& column,
+             const FilterValue& cast,
+             const StringPool& pool,
+             Rows& r) {
+  uint32_t* begin = r.rows;
+  uint32_t* end = r.rows + r.count;
+  uint32_t* kept;
+  if constexpr (std::is_same_v<T, Id>) {
+    // An Id's value is where it would be stored.
+    uint32_t start = column.start();
+    auto cmp = filter::comparators::IntegerOrDoubleComparator<uint32_t, O>();
+    kept = filter::IdentityFilter(
+        begin, end, begin,
+        base::unchecked_get<CastFilterValueResult::Id>(cast.value.value).value,
+        [start, cmp](uint32_t row, uint32_t v) { return cmp(start + row, v); });
+  } else if constexpr (std::is_same_v<T, String>) {
+    const auto* data =
+        static_cast<const StringPool::Id*>(column.data()) + column.start();
+    if constexpr (std::is_same_v<O, Eq> || std::is_same_v<O, Ne>) {
+      // Equal strings are the same string in the pool.
+      static_assert(sizeof(StringPool::Id) == sizeof(uint32_t));
+      using Cmp = std::conditional_t<std::is_same_v<O, Eq>, std::equal_to<>,
+                                     std::not_equal_to<>>;
+      kept = filter::Filter(reinterpret_cast<const uint32_t*>(data), begin, end,
+                            begin, cast.string_id.raw_id(), Cmp());
+    } else {
+      kept = filter::FilterStringCompare<O>(&pool, data, begin, end, begin,
+                                            cast.text.c_str());
+    }
+  } else {
+    using M = StorageType::VariantTypeAtIndex<T, CastFilterValueResult::Value>;
+    const auto* data = static_cast<const M*>(column.data()) + column.start();
+    kept = filter::Filter(
+        data, begin, end, begin, base::unchecked_get<M>(cast.value.value),
+        filter::comparators::IntegerOrDoubleComparator<M, O>());
+  }
+  r.count = static_cast<uint32_t>(kept - begin);
+}
+
+template <typename T>
+void CompareByOp(const Op& op,
+                 const ColumnView& column,
+                 const FilterValue& cast,
+                 const StringPool& pool,
+                 Rows& r) {
+  switch (op.index()) {
+    case Op::GetTypeIndex<Eq>():
+      return Compare<T, Eq>(column, cast, pool, r);
+    case Op::GetTypeIndex<Ne>():
+      return Compare<T, Ne>(column, cast, pool, r);
+    case Op::GetTypeIndex<Lt>():
+      return Compare<T, Lt>(column, cast, pool, r);
+    case Op::GetTypeIndex<Le>():
+      return Compare<T, Le>(column, cast, pool, r);
+    case Op::GetTypeIndex<Gt>():
+      return Compare<T, Gt>(column, cast, pool, r);
+    case Op::GetTypeIndex<Ge>():
+      return Compare<T, Ge>(column, cast, pool, r);
+    default:
+      PERFETTO_FATAL("Unsupported filter operator");
+  }
+}
+
+// Applies a comparison to the rows kept so far. As the interpreter does, it
+// first drops the nulls, which it can never be true of, and only then looks at
+// whether its value cast.
+void ApplyComparison(const Op& op,
+                     const FilterValue& cast,
+                     const ColumnView& column,
+                     const StringPool& pool,
+                     Rows& r) {
+  switch (cast.value.validity) {
+    case CastFilterValueResult::kNoneMatch:
+      r.count = 0;
+      return;
+    case CastFilterValueResult::kAllMatch:
+      KeepNulls(column, /*nulls=*/false, r);
+      return;
+    case CastFilterValueResult::kValid:
+      KeepNulls(column, /*nulls=*/false, r);
+      break;
+  }
+  if (r.count == 0) {
+    return;
+  }
+  // The value was cast for the column's storage type, which picks its
+  // alternative.
+  PERFETTO_DCHECK(cast.value.value.index() == column.type().index());
+  switch (column.type().index()) {
+    case StorageType::GetTypeIndex<Id>():
+      PERFETTO_DCHECK(column.kind() == ColumnView::Kind::kSequence);
+      return CompareByOp<Id>(op, column, cast, pool, r);
+    case StorageType::GetTypeIndex<Uint32>():
+      return CompareByOp<Uint32>(op, column, cast, pool, r);
+    case StorageType::GetTypeIndex<Int32>():
+      return CompareByOp<Int32>(op, column, cast, pool, r);
+    case StorageType::GetTypeIndex<Int64>():
+      return CompareByOp<Int64>(op, column, cast, pool, r);
+    case StorageType::GetTypeIndex<Double>():
+      return CompareByOp<Double>(op, column, cast, pool, r);
+    case StorageType::GetTypeIndex<String>():
+      return CompareByOp<String>(op, column, cast, pool, r);
+    default:
+      PERFETTO_FATAL("Unsupported storage type");
+  }
+}
+
+}  // namespace
+
+Filter::Filter(std::vector<Condition> conditions, const StringPool* pool)
+    : conditions_(std::move(conditions)), pool_(pool) {
+  for (const Condition& c : conditions_) {
+    PERFETTO_CHECK(c.op.IsAnyOf<NonStringOp>() || c.op.IsAnyOf<NullOp>());
+  }
+}
+
+Filter::~Filter() = default;
+Filter::State::~State() = default;
+
+std::unique_ptr<OperatorState> Filter::MakeState(Context& context) const {
+  return std::make_unique<State>(context);
+}
+
+bool Filter::Process(RowBatch& batch, OperatorState& state) const {
+  State& s = state.Cast<State>();
+  const FilterValue* values = s.context->filter_values().b;
+  const Selection& selection = batch.selection();
+  Rows r{s.rows.data(), selection.size()};
+  for (uint32_t i = 0; i < r.count; ++i) {
+    r.rows[i] = selection[i];
+  }
+  for (uint32_t i = 0; i < conditions_.size() && r.count != 0; ++i) {
+    const Condition& c = conditions_[i];
+    const ColumnView& column = batch.column(c.column);
+    PERFETTO_DCHECK(column.kind() != ColumnView::Kind::kVariant);
+    if (c.op.IsAnyOf<NullOp>()) {
+      KeepNulls(column, c.op.Is<IsNull>(), r);
+      continue;
+    }
+    PERFETTO_DCHECK(c.value < s.context->filter_values().size());
+    ApplyComparison(c.op, values[c.value], column, *pool_, r);
+  }
+  batch.mutable_selection().KeepRows(
+      Span<const uint32_t>(r.rows, r.rows + r.count));
+  return true;
+}
+
+}  // namespace perfetto::trace_processor::core::exec
diff --git a/src/trace_processor/core/exec/filter.h b/src/trace_processor/core/exec/filter.h
new file mode 100644
index 0000000..d7aa69e
--- /dev/null
+++ b/src/trace_processor/core/exec/filter.h
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2026 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.
+ */
+
+#ifndef SRC_TRACE_PROCESSOR_CORE_EXEC_FILTER_H_
+#define SRC_TRACE_PROCESSOR_CORE_EXEC_FILTER_H_
+
+#include <array>
+#include <cstdint>
+#include <memory>
+#include <vector>
+
+#include "src/trace_processor/containers/string_pool.h"
+#include "src/trace_processor/core/common/op_types.h"
+#include "src/trace_processor/core/exec/context.h"
+#include "src/trace_processor/core/exec/operator.h"
+#include "src/trace_processor/core/exec/row_batch.h"
+#include "src/trace_processor/core/exec/selection.h"
+
+namespace perfetto::trace_processor::core::exec {
+
+// Keeps the rows of each batch for which every condition holds. Nothing is
+// copied: the batch's selection is narrowed.
+//
+// A condition compares a column with one of the run's filter values (see
+// Context::SetFilterValues) by =, !=, <, <=, >, >=, or tests it with IS [NOT]
+// NULL. The values come already cast for the column and comparison, so a
+// Filter only compares.
+//
+// A condition means exactly what the same filter on a dataframe means: no
+// comparison is true of a null, and an integer column compared with 2.5 keeps
+// the rows SQL would.
+//
+// Columns must be flat or Id sequences, of the storage type their values were
+// cast for.
+class Filter final : public Transform {
+ public:
+  static constexpr char kType = 0;
+  const void* type() const override { return &kType; }
+
+  struct Condition {
+    uint32_t column = 0;
+    Op op{Eq{}};
+    // The filter value compared with. Unused by IS [NOT] NULL.
+    uint32_t value = 0;
+  };
+
+  // `pool` holds the strings of the columns, and must outlive the filter.
+  Filter(std::vector<Condition> conditions, const StringPool* pool);
+  ~Filter() override;
+
+  std::unique_ptr<OperatorState> MakeState(Context&) const override;
+  bool Process(RowBatch& batch, OperatorState& state) const override;
+
+ private:
+  friend class PipelineFormatter;
+
+  struct State : OperatorState {
+    explicit State(const Context& c) : context(&c) {}
+    ~State() override;
+    // Where the run's filter values are.
+    const Context* context;
+    // The batch rows still kept, increasing.
+    std::array<uint32_t, kMaxBatchRows> rows;
+  };
+
+  std::vector<Condition> conditions_;
+  const StringPool* pool_;
+};
+
+}  // namespace perfetto::trace_processor::core::exec
+
+#endif  // SRC_TRACE_PROCESSOR_CORE_EXEC_FILTER_H_
diff --git a/src/trace_processor/core/exec/filter_benchmark.cc b/src/trace_processor/core/exec/filter_benchmark.cc
new file mode 100644
index 0000000..058d5ba
--- /dev/null
+++ b/src/trace_processor/core/exec/filter_benchmark.cc
@@ -0,0 +1,222 @@
+/*
+ * Copyright (C) 2026 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.
+ */
+
+#include "src/trace_processor/core/exec/filter.h"
+
+#include <benchmark/benchmark.h>
+
+#include <cstddef>
+#include <cstdint>
+#include <memory>
+#include <optional>
+#include <string>
+#include <utility>
+#include <variant>
+#include <vector>
+
+#include "perfetto/base/logging.h"
+#include "perfetto/ext/base/variant.h"
+#include "src/trace_processor/containers/string_pool.h"
+#include "src/trace_processor/core/common/op_types.h"
+#include "src/trace_processor/core/common/storage_types.h"
+#include "src/trace_processor/core/common/value_fetcher.h"
+#include "src/trace_processor/core/dataframe/cursor.h"
+#include "src/trace_processor/core/dataframe/cursor_impl.h"
+#include "src/trace_processor/core/dataframe/dataframe.h"
+#include "src/trace_processor/core/dataframe/specs.h"
+#include "src/trace_processor/core/exec/context.h"
+#include "src/trace_processor/core/exec/dataframe_scan.h"
+#include "src/trace_processor/core/exec/filter_value.h"
+#include "src/trace_processor/core/exec/operator.h"
+#include "src/trace_processor/core/exec/row_batch.h"
+#include "src/trace_processor/core/util/span.h"
+
+namespace perfetto::trace_processor::core::exec {
+namespace {
+
+// Shaped like a trace's slices, with none of the filtered columns sorted, so
+// both the executor and the interpreter test every row.
+inline constexpr auto kSlices = dataframe::CreateTypedDataframeSpec(
+    {"id", "dur", "cpu", "depth", "name"},
+    dataframe::CreateTypedColumnSpec(Id{}, NonNull{}, IdSorted{}),
+    dataframe::CreateTypedColumnSpec(Int64{}, NonNull{}, Unsorted{}),
+    dataframe::CreateTypedColumnSpec(Uint32{}, NonNull{}, Unsorted{}),
+    dataframe::CreateTypedColumnSpec(Uint32{}, DenseNull{}, Unsorted{}),
+    dataframe::CreateTypedColumnSpec(String{}, NonNull{}, Unsorted{}));
+
+constexpr uint32_t kRows = 1u << 20;
+constexpr uint32_t kCpus = 8;
+constexpr uint32_t kNames = 64;
+
+enum Column : uint32_t { kId, kDur, kCpu, kDepth, kName };
+
+class Slices {
+ public:
+  Slices() : df_(dataframe::Dataframe::CreateFromTypedSpec(kSlices, &pool_)) {
+    std::vector<StringPool::Id> names;
+    for (uint32_t i = 0; i < kNames; ++i) {
+      names.push_back(pool_.InternString(("name" + std::to_string(i)).c_str()));
+    }
+    for (uint32_t i = 0; i < kRows; ++i) {
+      // A multiplicative hash spreads the values over the rows.
+      uint32_t hash = i * 2654435761u;
+      std::optional<uint32_t> depth;
+      if (hash % 5 != 0) {
+        depth = (hash >> 4) % 16;
+      }
+      df_.InsertUnchecked(kSlices, std::monostate{},
+                          int64_t{(hash >> 12) % 1000}, (hash >> 8) % kCpus,
+                          depth, names[(hash >> 16) % kNames]);
+    }
+    df_.Finalize();
+  }
+
+  const dataframe::Dataframe& df() const { return df_; }
+  const StringPool& pool() const { return pool_; }
+
+ private:
+  StringPool pool_;
+  dataframe::Dataframe df_;
+};
+
+const Slices& GetSlices() {
+  static const Slices* slices = new Slices();
+  return *slices;
+}
+
+using Value = std::variant<int64_t, std::string>;
+
+struct OneValue : ValueFetcher {
+  using Type = size_t;
+  static constexpr Type kInt64 = base::variant_index<Value, int64_t>();
+  static constexpr Type kString = base::variant_index<Value, std::string>();
+  static constexpr Type kDouble = kString + 1;
+  static constexpr Type kNull = kString + 2;
+
+  explicit OneValue(const Value& v) : value(v) {}
+
+  int64_t GetInt64Value(uint32_t) const { return std::get<int64_t>(value); }
+  double GetDoubleValue(uint32_t) const { PERFETTO_FATAL("No doubles"); }
+  const char* GetStringValue(uint32_t) const {
+    return std::get<std::string>(value).c_str();
+  }
+  Type GetValueType(uint32_t) const { return value.index(); }
+  bool IteratorInit(uint32_t) { return false; }
+  bool IteratorNext(uint32_t) { return false; }
+
+  const Value& value;
+};
+
+// Scans every row and filters each batch, the filter's value cast as each run
+// starts.
+void RunExecutor(benchmark::State& state,
+                 uint32_t column,
+                 Op op,
+                 const Value& value) {
+  const Slices& s = GetSlices();
+  const dataframe::Dataframe& df = s.df();
+  Filter filter({{1, op, 0}}, &s.pool());
+  DataframeScan scan({df.shared_column(kId), df.shared_column(column)},
+                     df.row_count());
+  FilterValueCaster<OneValue> caster =
+      GetFilterValueCaster<OneValue>(df.column_type(column), op);
+  OneValue fetcher(value);
+  FilterValue cast[1];
+
+  Context context;
+  context.SetFilterValues(Span<const FilterValue>(cast));
+  std::unique_ptr<OperatorState> scan_state = scan.MakeState(context);
+  std::unique_ptr<OperatorState> filter_state = filter.MakeState(context);
+  RowBatch batch;
+  for (auto _ : state) {
+    caster(fetcher, 0, s.pool(), &cast[0]);
+    scan.Rewind(*scan_state);
+    uint32_t rows = 0;
+    while (scan.GetData(batch, *scan_state)) {
+      filter.Process(batch, *filter_state);
+      rows += batch.size();
+    }
+    benchmark::DoNotOptimize(rows);
+  }
+  state.SetItemsProcessed(static_cast<int64_t>(state.iterations()) * kRows);
+}
+
+// The same filter, run by the dataframe interpreter.
+void RunInterpreter(benchmark::State& state,
+                    uint32_t column,
+                    Op op,
+                    const Value& value) {
+  const Slices& s = GetSlices();
+  const dataframe::Dataframe& df = s.df();
+  std::vector<dataframe::FilterSpec> specs = {{column, 0, op, std::nullopt}};
+  auto plan = df.PlanQuery(specs, {}, {}, {}, uint64_t{1} << kId);
+  PERFETTO_CHECK(plan.ok());
+  dataframe::Cursor<OneValue> cursor;
+  df.PrepareCursor(*plan, cursor);
+  OneValue fetcher(value);
+  for (auto _ : state) {
+    cursor.Execute(fetcher);
+    uint32_t rows = 0;
+    for (; !cursor.Eof(); cursor.Next()) {
+      ++rows;
+    }
+    benchmark::DoNotOptimize(rows);
+  }
+  state.SetItemsProcessed(static_cast<int64_t>(state.iterations()) * kRows);
+}
+
+// An eighth of the rows, spread throughout.
+void BM_ExecFilterEqUint32(benchmark::State& state) {
+  RunExecutor(state, kCpu, Eq{}, int64_t{3});
+}
+BENCHMARK(BM_ExecFilterEqUint32);
+void BM_InterpreterFilterEqUint32(benchmark::State& state) {
+  RunInterpreter(state, kCpu, Eq{}, int64_t{3});
+}
+BENCHMARK(BM_InterpreterFilterEqUint32);
+
+// Half the rows.
+void BM_ExecFilterLtInt64(benchmark::State& state) {
+  RunExecutor(state, kDur, Lt{}, int64_t{500});
+}
+BENCHMARK(BM_ExecFilterLtInt64);
+void BM_InterpreterFilterLtInt64(benchmark::State& state) {
+  RunInterpreter(state, kDur, Lt{}, int64_t{500});
+}
+BENCHMARK(BM_InterpreterFilterLtInt64);
+
+// A sixteenth of the rows which are not null.
+void BM_ExecFilterEqNullable(benchmark::State& state) {
+  RunExecutor(state, kDepth, Eq{}, int64_t{3});
+}
+BENCHMARK(BM_ExecFilterEqNullable);
+void BM_InterpreterFilterEqNullable(benchmark::State& state) {
+  RunInterpreter(state, kDepth, Eq{}, int64_t{3});
+}
+BENCHMARK(BM_InterpreterFilterEqNullable);
+
+// A sixty-fourth of the rows, by string.
+void BM_ExecFilterEqString(benchmark::State& state) {
+  RunExecutor(state, kName, Eq{}, std::string("name7"));
+}
+BENCHMARK(BM_ExecFilterEqString);
+void BM_InterpreterFilterEqString(benchmark::State& state) {
+  RunInterpreter(state, kName, Eq{}, std::string("name7"));
+}
+BENCHMARK(BM_InterpreterFilterEqString);
+
+}  // namespace
+}  // namespace perfetto::trace_processor::core::exec
diff --git a/src/trace_processor/core/exec/filter_unittest.cc b/src/trace_processor/core/exec/filter_unittest.cc
new file mode 100644
index 0000000..d110a29
--- /dev/null
+++ b/src/trace_processor/core/exec/filter_unittest.cc
@@ -0,0 +1,230 @@
+/*
+ * Copyright (C) 2026 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.
+ */
+
+#include "src/trace_processor/core/exec/filter.h"
+
+#include <cstddef>
+#include <cstdint>
+#include <memory>
+#include <utility>
+#include <variant>
+#include <vector>
+
+#include "perfetto/ext/base/variant.h"
+#include "src/trace_processor/containers/string_pool.h"
+#include "src/trace_processor/core/common/op_types.h"
+#include "src/trace_processor/core/common/storage_types.h"
+#include "src/trace_processor/core/common/value_fetcher.h"
+#include "src/trace_processor/core/exec/column_view.h"
+#include "src/trace_processor/core/exec/context.h"
+#include "src/trace_processor/core/exec/filter_value.h"
+#include "src/trace_processor/core/exec/operator.h"
+#include "src/trace_processor/core/exec/row_batch.h"
+#include "src/trace_processor/core/exec/test_utils.h"
+#include "src/trace_processor/core/util/bit_vector.h"
+#include "src/trace_processor/core/util/span.h"
+#include "test/gtest_and_gmock.h"
+
+namespace perfetto::trace_processor::core::exec {
+namespace {
+
+using testing::ElementsAre;
+
+// A value as SQLite would pass it.
+using Value = std::variant<std::nullptr_t, int64_t, double, const char*>;
+
+// Hands values to the casters, as the SQLite layer hands them sqlite3_values.
+struct Values : ValueFetcher {
+  using Type = size_t;
+  static constexpr Type kNull = base::variant_index<Value, std::nullptr_t>();
+  static constexpr Type kInt64 = base::variant_index<Value, int64_t>();
+  static constexpr Type kDouble = base::variant_index<Value, double>();
+  static constexpr Type kString = base::variant_index<Value, const char*>();
+
+  int64_t GetInt64Value(uint32_t i) const { return std::get<int64_t>(v[i]); }
+  double GetDoubleValue(uint32_t i) const { return std::get<double>(v[i]); }
+  const char* GetStringValue(uint32_t i) const {
+    return std::get<const char*>(v[i]);
+  }
+  Type GetValueType(uint32_t i) const { return v[i].index(); }
+
+  std::vector<Value> v;
+};
+
+// Most of Filter's meaning is the interpreter's casts and kernels, checked end
+// to end by diff tests. These cover what those can't easily reach: batches
+// whose rows are already narrowed or windowed, and a plan run again with new
+// parameters.
+//
+// A batch of five rows: `n` holds 10, 20, null, 40, 50 and `s` holds "b",
+// "a", "c", "a", "d".
+class FilterTest : public ::testing::Test {
+ protected:
+  FilterTest() {
+    for (uint32_t i = 0; i < 5; ++i) {
+      if (i != 2) {
+        validity_.set(i);
+      }
+    }
+    for (const char* s : {"b", "a", "c", "a", "d"}) {
+      strings_.push_back(pool_.InternString(s));
+    }
+    batch_.AddBorrowedColumn(
+        ColumnView::Reference(StorageType{Int64{}}, numbers_, &validity_));
+    batch_.AddBorrowedColumn(
+        ColumnView::Reference(StorageType{String{}}, strings_.data(), nullptr));
+    batch_.SetRowCount(5);
+  }
+
+  // A condition on `n` or `s`, compared with value `index`.
+  struct On {
+    uint32_t column;
+    Op op;
+    uint32_t index = 0;
+  };
+
+  // Casts `values` for `on` into `cast`, as the SQLite layer would with the
+  // casters it picked for each condition.
+  void CastAll(const std::vector<On>& on,
+               const std::vector<Value>& values,
+               std::vector<FilterValue>* cast) {
+    Values fetcher;
+    fetcher.v = values;
+    cast->resize(values.size());
+    for (const On& c : on) {
+      if (c.op.IsAnyOf<NullOp>()) {
+        continue;
+      }
+      StorageType type =
+          c.column == 0 ? StorageType{Int64{}} : StorageType{String{}};
+      GetFilterValueCaster<Values>(type, c.op)(fetcher, c.index, pool_,
+                                               &(*cast)[c.index]);
+    }
+  }
+
+  static std::vector<Filter::Condition> Conditions(const std::vector<On>& on) {
+    std::vector<Filter::Condition> conditions;
+    for (const On& c : on) {
+      conditions.push_back({c.column, c.op, c.index});
+    }
+    return conditions;
+  }
+
+  // The values of `n` in the rows of `in` every condition keeps.
+  std::vector<int64_t> Kept(const std::vector<On>& on,
+                            const std::vector<Value>& values,
+                            const RowBatch* in = nullptr) {
+    Filter filter(Conditions(on), &pool_);
+    Context context;
+    std::unique_ptr<OperatorState> state = filter.MakeState(context);
+    std::vector<FilterValue> cast;
+    CastAll(on, values, &cast);
+    context.SetFilterValues(Span<const FilterValue>(cast));
+    RowBatch batch;
+    batch.CopyFrom(in ? *in : batch_);
+    EXPECT_TRUE(filter.Process(batch, *state));
+    return test::ReadColumn<int64_t>(batch, 0);
+  }
+
+  StringPool pool_;
+  int64_t numbers_[5] = {10, 20, 0, 40, 50};
+  BitVector validity_ = BitVector::CreateWithSize(5);
+  std::vector<StringPool::Id> strings_;
+  RowBatch batch_;
+};
+
+// As in SQL, no comparison is true of a null: only IS NULL keeps one.
+TEST_F(FilterTest, KeepsTheRowsEveryConditionHoldsFor) {
+  std::vector<Value> twenty = {int64_t{20}};
+  EXPECT_THAT(Kept({{0, Eq{}}}, twenty), ElementsAre(20));
+  EXPECT_THAT(Kept({{0, Ne{}}}, twenty), ElementsAre(10, 40, 50));
+  EXPECT_THAT(Kept({{0, Le{}}}, twenty), ElementsAre(10, 20));
+  EXPECT_THAT(Kept({{0, Gt{}}}, twenty), ElementsAre(40, 50));
+  EXPECT_THAT(Kept({{0, IsNotNull{}}}, {}), ElementsAre(10, 20, 40, 50));
+  EXPECT_EQ(Kept({{0, IsNull{}}}, {}).size(), 1u);
+
+  std::vector<Value> a = {"a"};
+  EXPECT_THAT(Kept({{1, Eq{}}}, a), ElementsAre(20, 40));
+  EXPECT_THAT(Kept({{1, Ne{}}}, a), ElementsAre(10, 0, 50));
+  EXPECT_THAT(Kept({{1, Gt{}}}, {"b"}), ElementsAre(0, 50));
+
+  // Every condition must hold, each with its own value.
+  EXPECT_THAT(Kept({{1, Eq{}, 0}, {0, Gt{}, 1}}, {"a", int64_t{20}}),
+              ElementsAre(40));
+}
+
+// A batch whose rows are already narrowed keeps only rows among them, and
+// rows of a window are read where the window starts.
+TEST_F(FilterTest, NarrowsTheRowsKeptOfAWindow) {
+  std::vector<Value> ten = {int64_t{10}};
+
+  RowBatch narrowed;
+  narrowed.CopyFrom(batch_);
+  uint32_t positions[] = {0, 3, 4};
+  narrowed.mutable_selection().Keep(Span<const uint32_t>(positions));
+  EXPECT_THAT(Kept({{0, Gt{}}}, ten, &narrowed), ElementsAre(40, 50));
+
+  // Rows 1 to 4: 20, null, 40, 50.
+  RowBatch window;
+  window.CopyFrom(batch_);
+  test::Window(&window, 1, 4);
+  EXPECT_THAT(Kept({{0, Gt{}}}, ten, &window), ElementsAre(20, 40, 50));
+}
+
+// A plan runs again with new values cast into the same ones, so strings of
+// any length, and ones the pool does not hold, keep the right rows.
+TEST_F(FilterTest, RunsAgainWithNewValues) {
+  std::vector<On> on = {{1, Lt{}, 0}, {1, Ne{}, 1}};
+  Filter filter(Conditions(on), &pool_);
+  Context context;
+  std::unique_ptr<OperatorState> state = filter.MakeState(context);
+  std::vector<FilterValue> cast;
+  auto run = [&](const char* lt, const char* ne) {
+    CastAll(on, {lt, ne}, &cast);
+    context.SetFilterValues(Span<const FilterValue>(cast));
+    RowBatch batch;
+    batch.CopyFrom(batch_);
+    EXPECT_TRUE(filter.Process(batch, *state));
+    return test::ReadColumn<int64_t>(batch, 0);
+  };
+  EXPECT_THAT(run("c", "a"), ElementsAre(10));
+  EXPECT_THAT(run("a long string sorting after a", "z"), ElementsAre(20, 40));
+  EXPECT_THAT(run("d", "b"), ElementsAre(20, 0, 40));
+}
+
+// An Id column holds the row each value is stored at, from where the window
+// starts.
+TEST(FilterIdTest, ComparesIdsByWhereTheyAre) {
+  StringPool pool;
+  Filter filter({{0, Ge{}, 0}}, &pool);
+  Context context;
+  std::unique_ptr<OperatorState> state = filter.MakeState(context);
+  Values fetcher;
+  fetcher.v = {int64_t{12}};
+  FilterValue cast[1];
+  GetFilterValueCaster<Values>(StorageType{Id{}}, Ge{})(fetcher, 0, pool,
+                                                        &cast[0]);
+  context.SetFilterValues(Span<const FilterValue>(cast));
+  RowBatch batch;
+  batch.AddBorrowedColumn(
+      ColumnView::Reference(StorageType{Id{}}, nullptr, nullptr, 10));
+  batch.SetRowCount(4);
+  ASSERT_TRUE(filter.Process(batch, *state));
+  EXPECT_THAT(test::ReadColumn<uint32_t>(batch, 0), ElementsAre(12u, 13u));
+}
+
+}  // namespace
+}  // namespace perfetto::trace_processor::core::exec
diff --git a/src/trace_processor/core/exec/filter_value.h b/src/trace_processor/core/exec/filter_value.h
new file mode 100644
index 0000000..f6bba99
--- /dev/null
+++ b/src/trace_processor/core/exec/filter_value.h
@@ -0,0 +1,144 @@
+/*
+ * Copyright (C) 2026 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.
+ */
+
+#ifndef SRC_TRACE_PROCESSOR_CORE_EXEC_FILTER_VALUE_H_
+#define SRC_TRACE_PROCESSOR_CORE_EXEC_FILTER_VALUE_H_
+
+#include <cstdint>
+#include <optional>
+#include <string>
+#include <type_traits>
+
+#include "perfetto/base/compiler.h"
+#include "perfetto/base/logging.h"
+#include "perfetto/ext/base/string_view.h"
+#include "perfetto/ext/base/utils.h"
+#include "perfetto/ext/base/variant.h"
+#include "src/trace_processor/containers/string_pool.h"
+#include "src/trace_processor/core/common/filter_value_cast.h"
+#include "src/trace_processor/core/common/op_types.h"
+#include "src/trace_processor/core/common/storage_types.h"
+
+namespace perfetto::trace_processor::core::exec {
+
+// A value a run of a plan compares a column with, already cast to the column's
+// storage type for one comparison, exactly as the dataframe interpreter casts
+// it (see filter_value_cast.h): a value, or that every or no row matches.
+//
+// Whoever runs a plan keeps one per condition from run to run, and casts each
+// run's values into them with casters it picked when the plan was built (see
+// GetFilterValueCaster). Everything after only reads them: nothing is
+// allocated, and nothing dispatches on the column's type or the comparison,
+// which matters when each run looks up one row.
+struct FilterValue {
+  filter::CastFilterValueResult value =
+      filter::CastFilterValueResult::NoneMatch();
+  // For a string compared by = or !=: the string's id in the pool.
+  StringPool::Id string_id = StringPool::Id::Null();
+  // For a string compared by order: its text, which `value` points to. Its
+  // buffer is reused, so only a string longer than any before allocates.
+  std::string text;
+};
+
+// Casts a value for one storage type and comparison.
+template <typename Fetcher>
+using FilterValueCaster =
+    void (*)(Fetcher&, uint32_t, const StringPool&, FilterValue*);
+
+namespace internal {
+
+// Casts the value `fetcher` has at `index` into `out`, for a column of
+// storage type T compared by O. `pool` holds the column's strings.
+template <typename T, typename O, typename Fetcher>
+PERFETTO_ALWAYS_INLINE void CastFilterValueFor(Fetcher& fetcher,
+                                               uint32_t index,
+                                               const StringPool& pool,
+                                               FilterValue* out) {
+  out->value = filter::CastFilterValue<T>(index, fetcher, NonNullOp(O{}));
+  if constexpr (std::is_same_v<T, String>) {
+    if (out->value.validity != filter::CastFilterValueResult::kValid) {
+      return;
+    }
+    const char* text = base::unchecked_get<const char*>(out->value.value);
+    if constexpr (std::is_same_v<O, Eq> || std::is_same_v<O, Ne>) {
+      // A string no row holds equals none of them, and differs from all.
+      std::optional<StringPool::Id> id = pool.GetId(base::StringView(text));
+      if (!id) {
+        out->value = std::is_same_v<O, Eq>
+                         ? filter::CastFilterValueResult::NoneMatch()
+                         : filter::CastFilterValueResult::AllMatch();
+        return;
+      }
+      out->string_id = *id;
+      // Whatever `text` points to need not outlive the cast.
+      out->value.value = static_cast<const char*>(nullptr);
+    } else {
+      out->text.assign(text);
+      out->value.value = out->text.c_str();
+    }
+  } else {
+    base::ignore_result(pool);
+  }
+}
+
+template <typename T, typename Fetcher>
+FilterValueCaster<Fetcher> FilterValueCasterFor(const Op& op) {
+  switch (op.index()) {
+    case Op::GetTypeIndex<Eq>():
+      return &CastFilterValueFor<T, Eq, Fetcher>;
+    case Op::GetTypeIndex<Ne>():
+      return &CastFilterValueFor<T, Ne, Fetcher>;
+    case Op::GetTypeIndex<Lt>():
+      return &CastFilterValueFor<T, Lt, Fetcher>;
+    case Op::GetTypeIndex<Le>():
+      return &CastFilterValueFor<T, Le, Fetcher>;
+    case Op::GetTypeIndex<Gt>():
+      return &CastFilterValueFor<T, Gt, Fetcher>;
+    case Op::GetTypeIndex<Ge>():
+      return &CastFilterValueFor<T, Ge, Fetcher>;
+    default:
+      PERFETTO_FATAL("Unsupported filter operator");
+  }
+}
+
+}  // namespace internal
+
+// The caster for a column of storage type `type` compared by `op`, one of =,
+// !=, <, <=, >, >=. Picked once, when a plan is built.
+template <typename Fetcher>
+FilterValueCaster<Fetcher> GetFilterValueCaster(StorageType type,
+                                                const Op& op) {
+  switch (type.index()) {
+    case StorageType::GetTypeIndex<Id>():
+      return internal::FilterValueCasterFor<Id, Fetcher>(op);
+    case StorageType::GetTypeIndex<Uint32>():
+      return internal::FilterValueCasterFor<Uint32, Fetcher>(op);
+    case StorageType::GetTypeIndex<Int32>():
+      return internal::FilterValueCasterFor<Int32, Fetcher>(op);
+    case StorageType::GetTypeIndex<Int64>():
+      return internal::FilterValueCasterFor<Int64, Fetcher>(op);
+    case StorageType::GetTypeIndex<Double>():
+      return internal::FilterValueCasterFor<Double, Fetcher>(op);
+    case StorageType::GetTypeIndex<String>():
+      return internal::FilterValueCasterFor<String, Fetcher>(op);
+    default:
+      PERFETTO_FATAL("Unsupported storage type");
+  }
+}
+
+}  // namespace perfetto::trace_processor::core::exec
+
+#endif  // SRC_TRACE_PROCESSOR_CORE_EXEC_FILTER_VALUE_H_
diff --git a/src/trace_processor/core/exec/group_table.cc b/src/trace_processor/core/exec/group_table.cc
index 52005fd..66886c7 100644
--- a/src/trace_processor/core/exec/group_table.cc
+++ b/src/trace_processor/core/exec/group_table.cc
@@ -111,10 +111,18 @@
     const RowBatch& batch,
     const std::vector<uint32_t>& columns,
     uint32_t* groups) {
+  return FindOrCreate(batch, batch.selection(), columns, groups);
+}
+
+std::optional<uint32_t> GroupTable::FindOrCreate(
+    const RowBatch& batch,
+    const Selection& rows,
+    const std::vector<uint32_t>& columns,
+    uint32_t* groups) {
   // Nulls are stored as one bit per column in a 64-bit word.
   PERFETTO_CHECK(columns.size() <= 64);
   PERFETTO_DCHECK(kinds_.empty() || kinds_.size() == columns.size());
-  uint32_t count = batch.size();
+  uint32_t count = rows.size();
   keys_.resize(columns.size());
   nulls_.resize(count);
   memset(nulls_.data(), 0, count * sizeof(uint64_t));
@@ -123,8 +131,7 @@
   for (uint32_t k = 0; k < columns.size(); ++k) {
     keys_[k].resize(count);
     may_be_null |= batch.column(columns[k]).validity() != nullptr;
-    std::optional<Kind> kind =
-        Load(batch.column(columns[k]), batch.selection(), k, count);
+    std::optional<Kind> kind = Load(batch.column(columns[k]), rows, k, count);
     if (!kind || (!first && kinds_[k] != *kind)) {
       // Only keep the first batch's kinds if every column is a valid key.
       if (first) {
diff --git a/src/trace_processor/core/exec/group_table.h b/src/trace_processor/core/exec/group_table.h
index 593ca4e..5861fc4 100644
--- a/src/trace_processor/core/exec/group_table.h
+++ b/src/trace_processor/core/exec/group_table.h
@@ -46,6 +46,12 @@
   std::optional<uint32_t> FindOrCreate(const RowBatch& batch,
                                        const std::vector<uint32_t>& columns,
                                        uint32_t* groups);
+  // As above, for the rows of `batch` which `rows` keeps rather than those
+  // its own selection does.
+  std::optional<uint32_t> FindOrCreate(const RowBatch& batch,
+                                       const Selection& rows,
+                                       const std::vector<uint32_t>& columns,
+                                       uint32_t* groups);
 
   uint32_t size() const { return static_cast<uint32_t>(hashes_.size()); }
   void Clear();
diff --git a/src/trace_processor/core/exec/grouped_sort.cc b/src/trace_processor/core/exec/grouped_sort.cc
index 3de9e04..f506237 100644
--- a/src/trace_processor/core/exec/grouped_sort.cc
+++ b/src/trace_processor/core/exec/grouped_sort.cc
@@ -112,7 +112,7 @@
   if (s.emitted == s.rows.size()) {
     return false;
   }
-  uint32_t count = s.rows.View(&out, s.emitted, *s.context);
+  uint32_t count = s.rows.Gather(&out, s.emitted, *s.context);
   out.AddBorrowedColumn(ColumnView::Reference(
       StorageType{Uint32{}}, s.ordered_groups.data(), nullptr, s.emitted));
   s.emitted += count;
diff --git a/src/trace_processor/core/exec/hash_aggregate.cc b/src/trace_processor/core/exec/hash_aggregate.cc
index eb35350..147eb2d 100644
--- a/src/trace_processor/core/exec/hash_aggregate.cc
+++ b/src/trace_processor/core/exec/hash_aggregate.cc
@@ -123,13 +123,13 @@
     return true;
   }
   // Find each row's group. Groups are numbered in the order first seen, so a
-  // row starts a new group when its number equals the group count.
+  // row starts a new group when its number equals the group count. With no
+  // keys, every row is in the one group.
   s.consumed = true;
-  s.row_groups.resize(rows);
-  uint32_t* row_groups = s.row_groups.data();
-  if (spec_.key_columns.empty()) {
-    std::fill(row_groups, row_groups + rows, 0u);
-  } else {
+  uint32_t* row_groups = nullptr;
+  if (!spec_.key_columns.empty()) {
+    s.row_groups.resize(rows);
+    row_groups = s.row_groups.data();
     if (std::optional<uint32_t> bad =
             s.groups.FindOrCreate(in, spec_.key_columns, row_groups)) {
       s.status = base::ErrStatus(
@@ -158,7 +158,11 @@
     if (function.tracks_seen()) {
       states.seen = s.seen[a].For(GroupCount(s), input.valid != nullptr);
     }
-    function.Update(input, row_groups, states, &overflow);
+    if (row_groups) {
+      function.Update(input, row_groups, states, &overflow);
+    } else {
+      function.UpdateGroup(input, 0, states, &overflow);
+    }
   }
   if (overflow) {
     s.status = base::ErrStatus("AGGREGATE: integer overflow");
diff --git a/src/trace_processor/core/exec/hash_aggregate_benchmark.cc b/src/trace_processor/core/exec/hash_aggregate_benchmark.cc
index 0b5aaa6..3cd4dd0 100644
--- a/src/trace_processor/core/exec/hash_aggregate_benchmark.cc
+++ b/src/trace_processor/core/exec/hash_aggregate_benchmark.cc
@@ -21,6 +21,7 @@
 #include <memory>
 #include <numeric>
 #include <random>
+#include <utility>
 #include <vector>
 
 #include "src/trace_processor/core/common/storage_types.h"
@@ -44,10 +45,21 @@
 namespace perfetto::trace_processor::core::exec {
 namespace {
 
+using F = AggregateCall::Function;
+
+// The first `count` of the aggregates listed at the top.
+std::vector<AggregateCall> FirstCalls(uint32_t count) {
+  std::vector<AggregateCall> calls = {
+      {F::kCountStar, 0}, {F::kSum, 1}, {F::kSum, 2}, {F::kSum, 3}};
+  calls.resize(count);
+  return calls;
+}
+
 void Run(benchmark::State& state,
+         bool keyed,
          uint32_t distinct,
          uint32_t batch_count,
-         uint32_t aggregates) {
+         std::vector<AggregateCall> calls) {
   uint32_t rows = batch_count * kMaxBatchRows;
   std::vector<uint32_t> order(rows);
   std::iota(order.begin(), order.end(), 0);
@@ -73,11 +85,9 @@
     }
     batch.SetRowCount(kMaxBatchRows);
   }
-  using F = AggregateCall::Function;
-  std::vector<AggregateCall> calls = {
-      {F::kCountStar, 0}, {F::kSum, 1}, {F::kSum, 2}, {F::kSum, 3}};
-  calls.resize(aggregates);
-  HashAggregate op(HashAggregateSpec{{0}, calls});
+  HashAggregate op(HashAggregateSpec{
+      keyed ? std::vector<uint32_t>{0} : std::vector<uint32_t>{},
+      std::move(calls)});
   Context context;
   std::unique_ptr<OperatorState> op_state = op.MakeState(context);
   RowBatch out;
@@ -96,15 +106,30 @@
 // Arguments: number of distinct keys across 16 batches, and number of
 // aggregates.
 void BM_HashAggregate(benchmark::State& state) {
-  Run(state, static_cast<uint32_t>(state.range(0)), 16,
-      static_cast<uint32_t>(state.range(1)));
+  Run(state, true, static_cast<uint32_t>(state.range(0)), 16,
+      FirstCalls(static_cast<uint32_t>(state.range(1))));
 }
 BENCHMARK(BM_HashAggregate)->ArgsProduct({{8, 512, 8192, 32768}, {1, 3}});
 
+// Like BM_HashAggregate with no keys, so every row is in one group. Argument:
+// number of aggregates.
+void BM_HashAggregateNoKeys(benchmark::State& state) {
+  Run(state, false, 1, 16, FirstCalls(static_cast<uint32_t>(state.range(0))));
+}
+BENCHMARK(BM_HashAggregateNoKeys)->DenseRange(1, 4);
+
+// MIN and MAX with no keys. Argument: 0 for a column with no nulls, 1 for one
+// where a quarter of the rows are null.
+void BM_HashAggregateNoKeysMinMax(benchmark::State& state) {
+  uint32_t column = state.range(0) ? 2 : 1;
+  Run(state, false, 1, 16, {{F::kMin, column}, {F::kMax, column}});
+}
+BENCHMARK(BM_HashAggregateNoKeysMinMax)->DenseRange(0, 1);
+
 // Like BM_HashAggregate but over 10M rows, to compare with other engines.
 void BM_HashAggregateLarge(benchmark::State& state) {
-  Run(state, static_cast<uint32_t>(state.range(0)), 4883,
-      static_cast<uint32_t>(state.range(1)));
+  Run(state, true, static_cast<uint32_t>(state.range(0)), 4883,
+      FirstCalls(static_cast<uint32_t>(state.range(1))));
 }
 BENCHMARK(BM_HashAggregateLarge)
     ->ArgsProduct({{8, 512, 8192, 1 << 20}, {1, 2, 3, 4}})
diff --git a/src/trace_processor/core/exec/hash_aggregate_unittest.cc b/src/trace_processor/core/exec/hash_aggregate_unittest.cc
index f540bf0..d878de3 100644
--- a/src/trace_processor/core/exec/hash_aggregate_unittest.cc
+++ b/src/trace_processor/core/exec/hash_aggregate_unittest.cc
@@ -17,6 +17,7 @@
 #include "src/trace_processor/core/exec/hash_aggregate.h"
 
 #include <cstdint>
+#include <limits>
 #include <memory>
 #include <optional>
 #include <vector>
@@ -94,5 +95,56 @@
   EXPECT_THAT(ReadNullableColumn<int64_t>(out, 1), ElementsAre(15));
 }
 
+TEST(HashAggregateTest, NoKeysFoldsEachBatchAtOnce) {
+  // Two batches of one nullable column, with rows 1 and 5 null.
+  constexpr int64_t kHalf = std::numeric_limits<int64_t>::max() / 2;
+  std::vector<int64_t> values = {-7, 5, kHalf, 0, -kHalf, 9, 3};
+  BitVector valid = BitVector::CreateWithSize(7, true);
+  valid.clear(1);
+  valid.clear(5);
+
+  using F = AggregateCall::Function;
+  HashAggregate op(HashAggregateSpec{{},
+                                     {{F::kCountStar, 0},
+                                      {F::kCount, 0},
+                                      {F::kSum, 0},
+                                      {F::kMin, 0},
+                                      {F::kMax, 0}}});
+  std::unique_ptr<OperatorState> state = op.MakeState(test::TestContext());
+  RowBatch out;
+  for (uint32_t at : {0u, 4u}) {
+    RowBatch in;
+    in.AddBorrowedColumn(
+        ColumnView::Reference(StorageType{Int64{}}, values.data(), &valid, at));
+    in.SetRowCount(at == 0 ? 4 : 3);
+    ASSERT_EQ(op.Execute(in, out, *state), OpResult::kNeedMoreInput);
+  }
+  ASSERT_EQ(op.Finish(out, *state), OpResult::kHaveMoreOutput);
+  EXPECT_THAT(ReadColumn<int64_t>(out, 0), ElementsAre(7));
+  EXPECT_THAT(ReadColumn<int64_t>(out, 1), ElementsAre(5));
+  EXPECT_THAT(ReadNullableColumn<int64_t>(out, 2), ElementsAre(-4));
+  EXPECT_THAT(ReadNullableColumn<int64_t>(out, 3), ElementsAre(-kHalf));
+  EXPECT_THAT(ReadNullableColumn<int64_t>(out, 4), ElementsAre(kHalf));
+}
+
+TEST(HashAggregateTest, NoKeysSumFailsPastInt64) {
+  using F = AggregateCall::Function;
+  HashAggregate op(HashAggregateSpec{{}, {{F::kSum, 0}}});
+  std::unique_ptr<OperatorState> state = op.MakeState(test::TestContext());
+  RowBatch out;
+  // The least Int64 fits; one less doesn't.
+  std::vector<int64_t> least = {std::numeric_limits<int64_t>::min(), 0};
+  std::vector<int64_t> one = {-1};
+  for (std::vector<int64_t>* values : {&least, &one}) {
+    RowBatch in;
+    in.AddBorrowedColumn(
+        ColumnView::Reference(StorageType{Int64{}}, values->data()));
+    in.SetRowCount(static_cast<uint32_t>(values->size()));
+    OpResult expected =
+        values == &least ? OpResult::kNeedMoreInput : OpResult::kError;
+    ASSERT_EQ(op.Execute(in, out, *state), expected);
+  }
+}
+
 }  // namespace
 }  // namespace perfetto::trace_processor::core::exec
diff --git a/src/trace_processor/core/exec/interval_fill_gaps.cc b/src/trace_processor/core/exec/interval_fill_gaps.cc
new file mode 100644
index 0000000..d9b84b2
--- /dev/null
+++ b/src/trace_processor/core/exec/interval_fill_gaps.cc
@@ -0,0 +1,362 @@
+/*
+ * Copyright (C) 2026 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.
+ */
+
+#include "src/trace_processor/core/exec/interval_fill_gaps.h"
+
+#include <algorithm>
+#include <cstdint>
+#include <memory>
+#include <optional>
+#include <utility>
+#include <vector>
+
+#include "perfetto/base/logging.h"
+#include "perfetto/base/status.h"
+#include "perfetto/ext/base/status_macros.h"
+#include "src/trace_processor/containers/interval_tree.h"
+#include "src/trace_processor/core/common/storage_types.h"
+#include "src/trace_processor/core/exec/column_view.h"
+#include "src/trace_processor/core/exec/context.h"
+#include "src/trace_processor/core/exec/group_table.h"
+#include "src/trace_processor/core/exec/interval_lanes.h"
+#include "src/trace_processor/core/exec/variant.h"
+#include "src/trace_processor/core/util/interval_gaps.h"
+#include "src/trace_processor/core/util/span.h"
+
+namespace perfetto::trace_processor::core::exec {
+namespace {
+
+constexpr char kName[] = "INTERVAL FILL GAPS";
+
+// Adds a null column of the same kind and type as `like`, or of `fallback` if
+// `like` is not known.
+void AddNulls(const std::optional<ColumnShape>& like,
+              StorageType fallback,
+              Context& context,
+              RowBatch* out) {
+  if (like && like->kind == ColumnView::Kind::kVariant) {
+    // Zeroed, the null buffer's values are null Variants.
+    const ColumnBuffer& nulls = context.NullBuffer();
+    out->AddColumn(ColumnView::Variants(nulls.chunk().Values<Variant>()),
+                   nulls);
+    return;
+  }
+  out->AddNullColumn(like ? like->type : fallback, context);
+}
+
+}  // namespace
+
+struct IntervalFillGaps::State : OperatorState {
+  State(const IntervalFillGapsSpec& spec, Context& c)
+      : OperatorState(ResetEachRun{}),
+        context(&c),
+        background(spec.background, {kName, "the background"}),
+        input(spec.input, {kName, "the input"}),
+        keys(spec.input.key_columns) {}
+  ~State() override;
+  void Reset() override;
+
+  Context* context;
+  std::unique_ptr<OperatorState> background_state;
+  base::Status status = base::OkStatus();
+  bool background_read = false;
+  bool finished = false;
+
+  // Numbers lanes by key on both sides, if both have PER columns.
+  GroupTable lanes;
+  CollectedLanes background;
+  LaneReader input;
+
+  // Whether each background lane had any input.
+  std::vector<bool> visited;
+
+  // If broadcasting, the PER values of the input batch's lanes, and the
+  // handle of the current lane's.
+  LaneKeys keys;
+  uint32_t lane_key = 0;
+
+  // The current input lane.
+  uint32_t lane = 0;
+  IntervalGaps gaps;
+
+  // The shape of each output's input column, from the first input batch.
+  std::vector<std::optional<ColumnShape>> shapes;
+
+  // How many gaps have been output, and whether the current input batch has
+  // been output but its gaps have not.
+  size_t served = 0;
+  bool serving = false;
+
+  // Scratch for serving fillers.
+  std::vector<uint32_t> rows;
+  RowBatch gathered;
+  RowBatch gathered_keys;
+};
+
+IntervalFillGaps::State::~State() = default;
+
+void IntervalFillGaps::State::Reset() {
+  status = base::OkStatus();
+  background_read = false;
+  finished = false;
+  lanes.Clear();
+  background.Clear();
+  input.Reset();
+  visited.clear();
+  keys.Clear();
+  gaps.Clear();
+  std::fill(shapes.begin(), shapes.end(), std::nullopt);
+  served = 0;
+  serving = false;
+}
+
+IntervalFillGaps::IntervalFillGaps(IntervalFillGapsSpec spec)
+    : spec_(std::move(spec)) {
+  const auto& keys = spec_.input.key_columns;
+  const auto& background_keys = spec_.background.lanes.key_columns;
+  PERFETTO_CHECK(background_keys.empty() ||
+                 background_keys.size() == keys.size());
+  broadcast_ = !keys.empty() && background_keys.empty();
+  shared_ = !keys.empty() && !broadcast_;
+  for (const IntervalFillGapsSpec::Output& output : spec_.outputs) {
+    input_columns_.push_back(output.input);
+    // ts and dur always come from the filler, not the background.
+    auto key = std::find(keys.begin(), keys.end(), output.input);
+    if (output.input == spec_.input.ts_column) {
+      filler_columns_.push_back({FillerSource::kTs, 0});
+    } else if (output.input == spec_.input.dur_column) {
+      filler_columns_.push_back({FillerSource::kDur, 0});
+    } else if (output.background) {
+      filler_columns_.push_back(
+          {FillerSource::kBackground, *output.background});
+    } else if (broadcast_ && key != keys.end()) {
+      filler_columns_.push_back(
+          {FillerSource::kLaneKey, static_cast<uint32_t>(key - keys.begin())});
+    } else {
+      filler_columns_.push_back({FillerSource::kNull, 0});
+    }
+  }
+}
+
+IntervalFillGaps::~IntervalFillGaps() = default;
+
+std::unique_ptr<OperatorState> IntervalFillGaps::MakeState(
+    Context& context) const {
+  auto state = std::make_unique<State>(spec_, context);
+  state->background_state = spec_.background.source->MakeState(context);
+  state->shapes.resize(spec_.outputs.size());
+  return state;
+}
+
+base::Status IntervalFillGaps::status(const OperatorState& state) const {
+  return state.Cast<const State>().status;
+}
+
+bool IntervalFillGaps::EnsureBackgroundRead(State& s) const {
+  if (!s.background_read) {
+    spec_.background.source->Rewind(*s.background_state);
+    s.status = ReadBackground(s);
+    s.background_read = true;
+  }
+  return s.status.ok();
+}
+
+base::Status IntervalFillGaps::ReadBackground(State& s) const {
+  RETURN_IF_ERROR(
+      s.background.Collect(*s.background_state, shared_ ? &s.lanes : nullptr));
+  for (uint32_t i = 0; i < s.background.size(); ++i) {
+    // Intervals are sorted by start, so only the previous one with width can
+    // overlap. Zero-width intervals cover nothing.
+    std::optional<Ts> end;
+    for (const Interval& interval : s.background.lane(i).intervals) {
+      if (interval.start == interval.end) {
+        continue;
+      }
+      if (end && interval.start < *end) {
+        return base::ErrStatus("%s: background rows overlap within a lane",
+                               kName);
+      }
+      end = interval.end;
+    }
+  }
+  s.visited.assign(s.background.size(), false);
+  return base::OkStatus();
+}
+
+void IntervalFillGaps::StartLane(uint32_t lane, uint32_t row, State& s) const {
+  s.lane = lane;
+  uint32_t tag = lane;
+  if (broadcast_) {
+    s.lane_key = s.keys.Of(row);
+    tag = s.lane_key;
+  }
+  const uint32_t background_lane = broadcast_ ? 0 : lane;
+  Span<const Interval> background;
+  if (std::optional<uint32_t> i = s.background.Find(background_lane)) {
+    s.visited[*i] = true;
+    background = s.background.lane(*i).intervals;
+  }
+  s.gaps.StartLane(tag, background);
+}
+
+base::Status IntervalFillGaps::Cover(const RowBatch& in, State& s) const {
+  RETURN_IF_ERROR(s.input.Start(in, shared_ ? &s.lanes : nullptr));
+  LaneBatch lanes = s.input.batch();
+  if (broadcast_) {
+    RETURN_IF_ERROR(s.keys.Hold(in));
+    // The open lane's keys are now carried.
+    s.lane_key = LaneKeys::kCarried;
+    s.gaps.set_lane(s.lane_key);
+  }
+  for (uint32_t row = 0; row < in.size(); ++row) {
+    uint32_t lane = lanes.lane(row);
+    if (!s.gaps.in_lane() || lane != s.lane) {
+      StartLane(lane, row, s);
+    }
+    int64_t start;
+    int64_t end;
+    LaneBatch::Result result = lanes.Read(row, &start, &end);
+    if (result != LaneBatch::Result::kOk) {
+      if (result == LaneBatch::Result::kSkip) {
+        continue;
+      }
+      return lanes.Error(result, {kName, "the input"});
+    }
+    s.gaps.Cover(static_cast<Ts>(start), static_cast<Ts>(end));
+  }
+  if (broadcast_ && s.gaps.in_lane()) {
+    s.keys.Carry(s.lane_key);
+  }
+  return base::OkStatus();
+}
+
+OpResult IntervalFillGaps::Execute(const RowBatch& in,
+                                   RowBatch& out,
+                                   OperatorState& state) const {
+  auto& s = state.Cast<State>();
+  out.Reset();
+  if (s.serving) {
+    return ServeFillers(out, s);
+  }
+  // Background lanes must be known before reading input.
+  if (!EnsureBackgroundRead(s)) {
+    return OpResult::kError;
+  }
+  s.status = Cover(in, s);
+  if (!s.status.ok()) {
+    return OpResult::kError;
+  }
+  for (size_t i = 0; i < spec_.outputs.size(); ++i) {
+    if (!s.shapes[i]) {
+      s.shapes[i] = ColumnShape::Of(in.column(spec_.outputs[i].input));
+    }
+  }
+  out.Project(in, input_columns_);
+  s.serving = !s.gaps.gaps().empty();
+  return s.serving ? OpResult::kHaveMoreOutput : OpResult::kNeedMoreInput;
+}
+
+OpResult IntervalFillGaps::Finish(RowBatch& out, OperatorState& state) const {
+  auto& s = state.Cast<State>();
+  out.Reset();
+  if (!EnsureBackgroundRead(s)) {
+    return OpResult::kError;
+  }
+  if (!s.finished) {
+    s.gaps.EndLane();
+    // Background lanes with no input are filled completely.
+    for (uint32_t i = 0; i < s.visited.size() && !broadcast_; ++i) {
+      if (!s.visited[i]) {
+        s.gaps.StartLane(0, s.background.lane(i).intervals);
+        s.gaps.EndLane();
+      }
+    }
+    s.finished = true;
+  }
+  if (s.gaps.gaps().empty()) {
+    return OpResult::kNeedMoreInput;
+  }
+  return ServeFillers(out, s);
+}
+
+OpResult IntervalFillGaps::ServeFillers(RowBatch& out, State& s) const {
+  std::vector<IntervalGaps::Gap>& gaps = s.gaps.gaps();
+  auto count = static_cast<uint32_t>(
+      std::min<size_t>(gaps.size() - s.served, kMaxBatchRows));
+  const IntervalGaps::Gap* fillers = gaps.data() + s.served;
+
+  BoundsColumns bounds;
+  bounds.Take(*s.context);
+  s.rows.resize(count);
+  for (uint32_t i = 0; i < count; ++i) {
+    bounds.ts[i] = static_cast<int64_t>(fillers[i].start);
+    bounds.dur[i] = static_cast<int64_t>(fillers[i].end - fillers[i].start);
+    s.rows[i] = fillers[i].id;
+  }
+  const uint32_t* rows = s.rows.data();
+  s.background.rows().Gather(&s.gathered, {rows, rows + count}, *s.context);
+  if (broadcast_) {
+    for (uint32_t i = 0; i < count; ++i) {
+      s.rows[i] = fillers[i].lane;
+    }
+    s.keys.Gather(&s.gathered_keys, {rows, rows + count}, *s.context);
+  }
+
+  for (size_t i = 0; i < spec_.outputs.size(); ++i) {
+    const FillerColumn& filler = filler_columns_[i];
+    switch (filler.source) {
+      case FillerSource::kTs:
+        bounds.AddTsTo(&out);
+        break;
+      case FillerSource::kDur:
+        bounds.AddDurTo(&out);
+        break;
+      case FillerSource::kBackground: {
+        const ColumnView& column = s.gathered.column(filler.index);
+        // Lowering only converts typed columns, so untyped ones can still
+        // differ between the input and the background.
+        if (s.shapes[i] &&
+            !SameLogicalType(ColumnShape::Of(column), *s.shapes[i])) {
+          s.status = base::ErrStatus(
+              "%s: column '%s' holds a different type in the background than "
+              "in the input",
+              kName, spec_.outputs[i].name.c_str());
+          return OpResult::kError;
+        }
+        out.AddColumn(column, s.gathered.buffer(filler.index));
+        break;
+      }
+      case FillerSource::kLaneKey:
+        out.AddColumn(s.gathered_keys.column(filler.index),
+                      s.gathered_keys.buffer(filler.index));
+        break;
+      case FillerSource::kNull:
+        AddNulls(s.shapes[i], spec_.outputs[i].fallback, *s.context, &out);
+        break;
+    }
+  }
+  out.SetRowCount(count);
+  s.served += count;
+  if (s.served < gaps.size()) {
+    return OpResult::kHaveMoreOutput;
+  }
+  gaps.clear();
+  s.served = 0;
+  s.serving = false;
+  return OpResult::kNeedMoreInput;
+}
+
+}  // namespace perfetto::trace_processor::core::exec
diff --git a/src/trace_processor/core/exec/interval_fill_gaps.h b/src/trace_processor/core/exec/interval_fill_gaps.h
new file mode 100644
index 0000000..b662e93
--- /dev/null
+++ b/src/trace_processor/core/exec/interval_fill_gaps.h
@@ -0,0 +1,131 @@
+/*
+ * Copyright (C) 2026 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.
+ */
+
+#ifndef SRC_TRACE_PROCESSOR_CORE_EXEC_INTERVAL_FILL_GAPS_H_
+#define SRC_TRACE_PROCESSOR_CORE_EXEC_INTERVAL_FILL_GAPS_H_
+
+#include <cstdint>
+#include <memory>
+#include <optional>
+#include <string>
+#include <vector>
+
+#include "perfetto/base/status.h"
+#include "src/trace_processor/core/common/storage_types.h"
+#include "src/trace_processor/core/exec/interval_lanes.h"
+#include "src/trace_processor/core/exec/operator.h"
+#include "src/trace_processor/core/exec/row_batch.h"
+
+namespace perfetto::trace_processor::core::exec {
+
+struct IntervalFillGapsSpec {
+  // An output column. Input rows take its value from the input. Filler rows
+  // take it from the first of these that applies:
+  //  - the background column with the same name;
+  //  - the lane's PER value, if it is a PER column;
+  //  - null.
+  struct Output {
+    // Column index in the input.
+    uint32_t input = 0;
+    // Index in the background's retained columns, if it has this column.
+    std::optional<uint32_t> background;
+    // Type of the null column used if no input batch was seen.
+    StorageType fallback{Int64{}};
+    // Column name, used in error messages.
+    std::string name;
+  };
+
+  // The input. A dur of -1 lasts forever.
+  IntervalLaneSpec input;
+
+  // The background, read whole before the input. Its key columns are either
+  // none or those matching the input's, in the same order.
+  CollectedInputSpec background;
+
+  std::vector<Output> outputs;
+};
+
+// INTERVAL FILL GAPS. Outputs every input row unchanged. Also outputs a
+// filler row for each part of the background that no input row in the same
+// lane covers.
+//
+// A lane is the set of rows with the same PER values. There are two modes:
+//  - The background has the PER columns, or there are no PER columns. Each
+//    background row belongs to one lane. A lane with no input is filled
+//    completely. Input in a lane the background does not have gets no
+//    fillers.
+//  - The background has no PER columns but the input does. Every input lane
+//    is filled against the whole background. Fillers get the lane's PER
+//    values.
+//
+// Background rows in the same lane may not overlap. Fillers never have zero
+// duration. Output rows are in no particular order.
+class IntervalFillGaps : public Operator {
+ public:
+  static constexpr char kType = 0;
+  const void* type() const override { return &kType; }
+
+  explicit IntervalFillGaps(IntervalFillGapsSpec);
+  ~IntervalFillGaps() override;
+
+  std::unique_ptr<OperatorState> MakeState(Context&) const override;
+  OpResult Execute(const RowBatch&, RowBatch&, OperatorState&) const override;
+  OpResult Finish(RowBatch&, OperatorState&) const override;
+  base::Status status(const OperatorState&) const override;
+
+ private:
+  friend class PipelineFormatter;
+
+  struct State;
+
+  // Where a filler takes an output column from.
+  enum class FillerSource : uint8_t { kTs, kDur, kBackground, kLaneKey, kNull };
+  struct FillerColumn {
+    FillerSource source;
+    // The background's retained column, or the index of the PER column.
+    uint32_t index;
+  };
+
+  // Reads the background on first call. Returns false on error.
+  bool EnsureBackgroundRead(State&) const;
+  base::Status ReadBackground(State&) const;
+
+  // Finds the gaps left by the rows of one input batch.
+  base::Status Cover(const RowBatch&, State&) const;
+
+  // Starts lane `lane`, whose first row is row `row` of the input batch.
+  void StartLane(uint32_t lane, uint32_t row, State&) const;
+
+  // Writes the next batch of filler rows to `out`.
+  OpResult ServeFillers(RowBatch& out, State&) const;
+
+  IntervalFillGapsSpec spec_;
+
+  // Whether the input's lanes are filled against the whole background, and
+  // so fillers take their PER values from the input.
+  bool broadcast_;
+
+  // Whether lanes are matched across the input and background by key.
+  bool shared_;
+
+  // The input column of each output, and where fillers take it from.
+  std::vector<uint32_t> input_columns_;
+  std::vector<FillerColumn> filler_columns_;
+};
+
+}  // namespace perfetto::trace_processor::core::exec
+
+#endif  // SRC_TRACE_PROCESSOR_CORE_EXEC_INTERVAL_FILL_GAPS_H_
diff --git a/src/trace_processor/core/exec/interval_fill_gaps_unittest.cc b/src/trace_processor/core/exec/interval_fill_gaps_unittest.cc
new file mode 100644
index 0000000..ab4295b
--- /dev/null
+++ b/src/trace_processor/core/exec/interval_fill_gaps_unittest.cc
@@ -0,0 +1,234 @@
+/*
+ * Copyright (C) 2026 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.
+ */
+
+#include "src/trace_processor/core/exec/interval_fill_gaps.h"
+
+#include <algorithm>
+#include <cstdint>
+#include <memory>
+#include <optional>
+#include <tuple>
+#include <utility>
+#include <vector>
+
+#include "src/trace_processor/core/common/storage_types.h"
+#include "src/trace_processor/core/exec/column_view.h"
+#include "src/trace_processor/core/exec/context.h"
+#include "src/trace_processor/core/exec/operator.h"
+#include "src/trace_processor/core/exec/row_batch.h"
+#include "src/trace_processor/core/exec/test_utils.h"
+#include "src/trace_processor/core/util/bit_vector.h"
+#include "test/gtest_and_gmock.h"
+
+namespace perfetto::trace_processor::core::exec {
+namespace {
+
+// Rows of Int64 columns, served in batches of at most kMaxBatchRows.
+class RowsSource final : public Source {
+ public:
+  static constexpr char kType = 0;
+  const void* type() const override { return &kType; }
+
+  explicit RowsSource(std::vector<std::vector<int64_t>> rows)
+      : rows_(std::move(rows)) {
+    columns_.resize(rows_.empty() ? 0 : rows_[0].size());
+    for (const auto& row : rows_) {
+      for (size_t c = 0; c < row.size(); ++c) {
+        columns_[c].push_back(row[c]);
+      }
+    }
+  }
+
+  std::unique_ptr<OperatorState> MakeState(Context&) const override {
+    return std::make_unique<State>();
+  }
+  void Rewind(OperatorState& state) const override {
+    state.Cast<State>().emitted = 0;
+  }
+  bool GetData(RowBatch& out, OperatorState& state) const override {
+    State& s = state.Cast<State>();
+    auto total = static_cast<uint32_t>(rows_.size());
+    if (s.emitted == total) {
+      return false;
+    }
+    uint32_t count = std::min(kMaxBatchRows, total - s.emitted);
+    out.Reset();
+    for (const auto& column : columns_) {
+      out.AddBorrowedColumn(ColumnView::Reference(
+          StorageType{Int64{}}, column.data(), nullptr, s.emitted));
+    }
+    out.SetRowCount(count);
+    s.emitted += count;
+    return true;
+  }
+
+ private:
+  struct State : OperatorState {
+    uint32_t emitted = 0;
+  };
+  std::vector<std::vector<int64_t>> rows_;
+  std::vector<std::vector<int64_t>> columns_;
+};
+
+// ts, dur, key, value.
+using Row = std::
+    tuple<int64_t, int64_t, std::optional<int64_t>, std::optional<int64_t>>;
+
+// Input columns: ts, dur, key, value, group number. Background columns: ts,
+// dur, value.
+IntervalFillGapsSpec MakeSpec(const Source* background, bool keyed) {
+  IntervalFillGapsSpec spec;
+  spec.input.ts_column = 0;
+  spec.input.dur_column = 1;
+  spec.input.forever = true;
+  if (keyed) {
+    spec.input.key_columns = {2};
+    spec.input.group_column = 4;
+  }
+  spec.background.source = background;
+  spec.background.lanes.ts_column = 0;
+  spec.background.lanes.dur_column = 1;
+  spec.background.retained_columns = {2};
+  spec.outputs = {{0, std::nullopt, StorageType{Int64{}}, "ts"},
+                  {1, std::nullopt, StorageType{Int64{}}, "dur"},
+                  {2, std::nullopt, StorageType{Int64{}}, "key"},
+                  {3, 0, StorageType{Int64{}}, "value"}};
+  return spec;
+}
+
+// Runs `op` over `input` split into batches of `chunk` rows, and returns every
+// output row. Each batch is copied into its own buffers. The input must be
+// grouped by key and sorted by ts within each key.
+std::vector<Row> RunFill(
+    const IntervalFillGaps& op,
+    OperatorState& state,
+    const std::vector<std::vector<std::optional<int64_t>>>& input,
+    uint32_t chunk) {
+  Context& context = test::TestContext();
+  RowBatch in, out;
+  std::vector<Row> rows;
+  uint32_t groups = 0;
+  std::optional<int64_t> last_key;
+  auto collect = [&] {
+    EXPECT_LE(out.size(), kMaxBatchRows);
+    auto keys = test::ReadNullableColumn<int64_t>(out, 2);
+    auto values = test::ReadNullableColumn<int64_t>(out, 3);
+    auto starts = test::ReadNullableColumn<int64_t>(out, 0);
+    for (uint32_t row = 0; row < out.size(); ++row) {
+      rows.emplace_back(starts[row].value_or(-100), out.Value<int64_t>(1, row),
+                        keys[row], values[row]);
+    }
+  };
+  for (size_t at = 0; at < input.size(); at += chunk) {
+    auto count =
+        static_cast<uint32_t>(std::min<size_t>(chunk, input.size() - at));
+    std::vector<int64_t> ts(count), dur(count), key(count), value(count);
+    std::vector<uint32_t> group(count);
+    auto ts_valid = BitVector::CreateWithSize(count);
+    for (uint32_t row = 0; row < count; ++row) {
+      const auto& r = input[at + row];
+      ts_valid.change(row, r[0].has_value());
+      ts[row] = r[0].value_or(0);
+      dur[row] = *r[1];
+      key[row] = *r[2];
+      value[row] = *r[3];
+      if (key[row] != last_key) {
+        last_key = key[row];
+        ++groups;
+      }
+      group[row] = groups - 1;
+    }
+    in.Reset();
+    test::AddCopy(context, ts, &ts_valid, &in);
+    test::AddCopy(context, dur, nullptr, &in);
+    test::AddCopy(context, key, nullptr, &in);
+    test::AddCopy(context, value, nullptr, &in);
+    test::AddCopy(context, group, nullptr, &in);
+    in.SetRowCount(count);
+    OpResult result;
+    do {
+      result = op.Execute(in, out, state);
+      EXPECT_NE(result, OpResult::kError) << op.status(state).message();
+      collect();
+    } while (result == OpResult::kHaveMoreOutput);
+  }
+  OpResult result;
+  do {
+    result = op.Finish(out, state);
+    EXPECT_NE(result, OpResult::kError) << op.status(state).message();
+    collect();
+  } while (result == OpResult::kHaveMoreOutput);
+  std::sort(rows.begin(), rows.end(), [](const Row& a, const Row& b) {
+    return std::tie(std::get<0>(a), std::get<2>(a), std::get<1>(a)) <
+           std::tie(std::get<0>(b), std::get<2>(b), std::get<1>(b));
+  });
+  return rows;
+}
+
+TEST(IntervalFillGapsTest, FillsEveryLaneAcrossBatches) {
+  // More gaps per lane than fit in one output batch, so the operator has to
+  // output them over several calls. Lane keys must survive the input buffers
+  // being refilled.
+  constexpr int64_t kSpans = kMaxBatchRows + 3;
+  RowsSource background({{0, 4 * kSpans, 7}});
+  IntervalFillGaps op(MakeSpec(&background, /*keyed=*/true));
+
+  std::vector<std::vector<std::optional<int64_t>>> input;
+  std::vector<Row> expected;
+  for (int64_t lane : {10, 11}) {
+    for (int64_t i = 0; i < kSpans; ++i) {
+      input.push_back({4 * i, 1, lane, i});
+      expected.emplace_back(4 * i, 1, lane, i);
+      expected.emplace_back(4 * i + 1, 3, lane, 7);
+    }
+  }
+  // A lane whose only row has no bounds covers nothing, so it is filled whole.
+  input.push_back({std::nullopt, 5, 12, 0});
+  expected.emplace_back(-100, 5, 12, 0);
+  expected.emplace_back(0, 4 * kSpans, 12, 7);
+  std::sort(expected.begin(), expected.end(), [](const Row& a, const Row& b) {
+    return std::tie(std::get<0>(a), std::get<2>(a), std::get<1>(a)) <
+           std::tie(std::get<0>(b), std::get<2>(b), std::get<1>(b));
+  });
+
+  auto state = op.MakeState(test::TestContext());
+  for (uint32_t chunk : {1u, 17u, kMaxBatchRows}) {
+    SCOPED_TRACE(chunk);
+    state->Reset();
+    EXPECT_EQ(RunFill(op, *state, input, chunk), expected);
+  }
+}
+
+TEST(IntervalFillGapsTest, OverlappingRowsCoverTheirUnion) {
+  RowsSource background({{0, 100, 7}});
+  IntervalFillGaps op(MakeSpec(&background, /*keyed=*/false));
+  auto state = op.MakeState(test::TestContext());
+  // Some rows overlap and some touch. Together they cover [10, 30) and
+  // [50, 60).
+  std::vector<Row> rows = RunFill(
+      op, *state,
+      {{10, 10, 0, 3}, {12, 3, 0, 4}, {20, 10, 0, 2}, {50, 10, 0, 1}}, 2);
+  EXPECT_EQ(rows, (std::vector<Row>{{0, 10, std::nullopt, 7},
+                                    {10, 10, 0, 3},
+                                    {12, 3, 0, 4},
+                                    {20, 10, 0, 2},
+                                    {30, 20, std::nullopt, 7},
+                                    {50, 10, 0, 1},
+                                    {60, 40, std::nullopt, 7}}));
+}
+
+}  // namespace
+}  // namespace perfetto::trace_processor::core::exec
diff --git a/src/trace_processor/core/exec/interval_flatten.cc b/src/trace_processor/core/exec/interval_flatten.cc
index 23511ed..da9289f 100644
--- a/src/trace_processor/core/exec/interval_flatten.cc
+++ b/src/trace_processor/core/exec/interval_flatten.cc
@@ -34,6 +34,7 @@
 #include "src/trace_processor/core/exec/column_chunk.h"
 #include "src/trace_processor/core/exec/column_view.h"
 #include "src/trace_processor/core/exec/context.h"
+#include "src/trace_processor/core/exec/interval_lanes.h"
 #include "src/trace_processor/core/util/heap.h"
 
 namespace perfetto::trace_processor::core::exec {
@@ -89,7 +90,7 @@
 }  // namespace
 
 IntervalFlatten::IntervalFlatten(IntervalFlattenSpec spec)
-    : spec_(std::move(spec)) {
+    : spec_(std::move(spec)), keyed_(!spec_.lanes.key_columns.empty()) {
   subtract_ = true;
   for (const AggregateCall& call : spec_.aggregates) {
     functions_.push_back(MakeAggregateFunction(call.function));
@@ -104,7 +105,7 @@
 
 std::unique_ptr<OperatorState> IntervalFlatten::MakeState(
     Context& context) const {
-  auto state = std::make_unique<State>();
+  auto state = std::make_unique<State>(spec_.lanes);
   state->context = &context;
   state->seen_bytes.resize(functions_.size());
   state->outputs.resize(functions_.size());
@@ -122,33 +123,33 @@
   if (!s.status.ok()) {
     return OpResult::kError;
   }
-  PERFETTO_DCHECK(IsFlat<Int64>(in.column(spec_.ts_column)));
-  PERFETTO_DCHECK(IsFlat<Int64>(in.column(spec_.dur_column)));
-  FlatColumnReader<int64_t> ts(in, spec_.ts_column);
-  FlatColumnReader<int64_t> dur(in, spec_.dur_column);
+  LaneBatch lanes(in, spec_.lanes);
   // A full output batch can interrupt consumption of the same input. Keep its
   // keys in place until all rows have been consumed.
   if (!s.input_pending) {
-    if (!RetainKeys(in, s)) {
-      return OpResult::kError;
+    if (keyed_) {
+      s.status = s.keys.Hold(in);
+      s.key_row = LaneKeys::kCarried;
     }
     s.input_pending = true;
   }
+  if (!s.status.ok()) {
+    return OpResult::kError;
+  }
   uint32_t rows = in.size();
-  bool keyed = !spec_.key_columns.empty();
   for (; s.input_row < rows; ++s.input_row) {
     uint32_t row = s.input_row;
     int64_t start;
-    int64_t length;
-    if (!ts.Read(row, &start) || !dur.Read(row, &length)) {
-      continue;
-    }
-    if (start < 0 || length < 0) {
-      s.status =
-          base::ErrStatus("INTERVAL FLATTEN: a row's ts or dur is below zero");
+    int64_t end;
+    LaneBatch::Result result = lanes.Read(row, &start, &end);
+    if (result != LaneBatch::Result::kOk) {
+      if (result == LaneBatch::Result::kSkip) {
+        continue;
+      }
+      s.status = lanes.Error(result, {"INTERVAL FLATTEN", "the input"});
       return OpResult::kError;
     }
-    uint32_t group = keyed ? in.Value<uint32_t>(spec_.group_column, row) : 0;
+    uint32_t group = lanes.lane(row);
     if (!s.in_group || group != s.input_group) {
       if (s.in_group) {
         // Finish the old group before accepting any rows from the new one.
@@ -160,7 +161,7 @@
       }
       s.in_group = true;
       s.input_group = group;
-      s.key_row = s.first_key + row;
+      s.key_row = s.keys.Of(row);
       s.input_ts = std::numeric_limits<int64_t>::min();
     }
     if (start != s.input_ts) {
@@ -171,40 +172,32 @@
       }
       s.input_ts = start;
     }
-    if (!AddInterval(s, row, start, length)) {
-      return OpResult::kError;
-    }
+    AddInterval(s, row, start, end);
   }
   s.input_row = 0;
   s.input_pending = false;
   // Only the current group's key must survive reuse of the input buffers.
-  if (keyed && s.in_group) {
-    s.key_rows.View(&s.saved_key, s.key_row, 1);
+  if (keyed_ && s.in_group) {
+    s.keys.Carry(s.key_row);
   }
   return Yield(out, s, OpResult::kNeedMoreInput, &in);
 }
 
 // The interval's state goes into a slot of its own, kept until it ends.
-PERFETTO_ALWAYS_INLINE bool IntervalFlatten::AddInterval(State& s,
+PERFETTO_ALWAYS_INLINE void IntervalFlatten::AddInterval(State& s,
                                                          uint32_t row,
                                                          int64_t start,
-                                                         int64_t length) const {
+                                                         int64_t end) const {
   uint32_t slot = TakeSlot(s);
   s.rows.push_back(row);
   s.row_slots.push_back(slot);
-  if (length == 0) {
+  if (end == start) {
     // Counted only by the point at its time, emitted when the time is done.
     s.instants.push_back(Live{start, slot, s.segments});
-    return true;
-  }
-  int64_t end;
-  if (!base::CheckedAdd(start, length, &end)) {
-    s.status = base::ErrStatus("INTERVAL FLATTEN: integer overflow");
-    return false;
+    return;
   }
   PushEnd(s.ends, Live{end, slot, s.segments});
   ++s.live;
-  return true;
 }
 
 PERFETTO_ALWAYS_INLINE uint32_t IntervalFlatten::TakeSlot(State& s) const {
@@ -217,26 +210,6 @@
   return slot;
 }
 
-bool IntervalFlatten::RetainKeys(const RowBatch& in, State& s) const {
-  if (spec_.key_columns.empty()) {
-    return true;
-  }
-  s.key_rows.Clear();
-  // The sweep may still emit rows for the group from the previous input, even
-  // after that input's borrowed buffers have been reused.
-  if (s.saved_key.size()) {
-    s.status = s.key_rows.Append(s.saved_key);
-    if (!s.status.ok()) {
-      return false;
-    }
-  }
-  s.key_row = 0;
-  s.first_key = s.key_rows.size();
-  s.retained.Project(in, spec_.key_columns);
-  s.status = s.key_rows.Append(s.retained);
-  return s.status.ok();
-}
-
 bool IntervalFlatten::Advance(State& s, int64_t time) const {
   // Points at the last input timestamp include all rows starting there, so
   // emit them only once that timestamp is complete.
@@ -296,11 +269,11 @@
   if (PERFETTO_UNLIKELY(n == s.segment_capacity)) {
     GrowSegments(s);
   }
-  if (PERFETTO_UNLIKELY(!s.ts_buffer)) {
+  if (PERFETTO_UNLIKELY(!s.bounds.taken())) {
     TakeSegmentBuffers(s);
   }
-  s.segment_ts[n] = ts;
-  s.segment_dur[n] = dur;
+  s.bounds.ts[n] = ts;
+  s.bounds.dur[n] = dur;
   s.segment_groups[n] = s.output_group;
   s.segment_key_rows[n] = s.key_row;
   s.segments = n + 1;
@@ -313,11 +286,8 @@
 }
 
 PERFETTO_NO_INLINE void IntervalFlatten::TakeSegmentBuffers(State& s) const {
-  s.ts_buffer = s.context->TakeBuffer();
-  s.dur_buffer = s.context->TakeBuffer();
+  s.bounds.Take(*s.context);
   s.group_buffer = s.context->TakeBuffer();
-  s.segment_ts = s.ts_buffer.chunk().Values<int64_t>();
-  s.segment_dur = s.dur_buffer.chunk().Values<int64_t>();
   s.segment_groups = s.group_buffer.chunk().Values<uint32_t>();
 }
 
@@ -499,13 +469,10 @@
   }
   // The batch takes the segments' buffers; the next batch's first segment
   // takes new ones.
-  out.AddColumn(ColumnView::Reference(StorageType{Int64{}}, s.segment_ts),
-                std::move(s.ts_buffer));
-  out.AddColumn(ColumnView::Reference(StorageType{Int64{}}, s.segment_dur),
-                std::move(s.dur_buffer));
-  if (!spec_.key_columns.empty()) {
+  s.bounds.AddTo(&out);
+  if (keyed_) {
     const uint32_t* rows = s.segment_key_rows.data();
-    s.key_rows.View(&s.served_keys, {rows, rows + count}, *s.context);
+    s.keys.Gather(&s.served_keys, {rows, rows + count}, *s.context);
     for (uint32_t k = 0; k < s.served_keys.column_count(); ++k) {
       out.AddColumn(s.served_keys.column(k), s.served_keys.buffer(k));
     }
@@ -527,7 +494,6 @@
   s.status = base::OkStatus();
   s.input_row = 0;
   s.input_pending = false;
-  s.first_key = 0;
   s.input_group = 0;
   s.output_group = 0;
   s.in_group = false;
@@ -547,14 +513,11 @@
   for (SeenBytes& bytes : s.seen_bytes) {
     bytes.Clear();
   }
-  s.key_rows.Clear();
+  s.keys.Clear();
   s.segments = 0;
-  s.retained.Reset();
-  s.saved_key.Reset();
   s.key_row = 0;
   s.served_keys.Reset();
-  s.ts_buffer = ColumnBuffer();
-  s.dur_buffer = ColumnBuffer();
+  s.bounds.Clear();
   s.group_buffer = ColumnBuffer();
 }
 
diff --git a/src/trace_processor/core/exec/interval_flatten.h b/src/trace_processor/core/exec/interval_flatten.h
index 142e6ce..d7a96d7 100644
--- a/src/trace_processor/core/exec/interval_flatten.h
+++ b/src/trace_processor/core/exec/interval_flatten.h
@@ -24,6 +24,7 @@
 #include "perfetto/base/status.h"
 #include "src/trace_processor/core/exec/aggregate_function.h"
 #include "src/trace_processor/core/exec/context.h"
+#include "src/trace_processor/core/exec/interval_lanes.h"
 #include "src/trace_processor/core/exec/operator.h"
 #include "src/trace_processor/core/exec/row_batch.h"
 #include "src/trace_processor/core/exec/row_store.h"
@@ -33,11 +34,7 @@
 namespace perfetto::trace_processor::core::exec {
 
 struct IntervalFlattenSpec {
-  uint32_t ts_column = 0;
-  uint32_t dur_column = 0;
-  std::vector<uint32_t> key_columns;
-  // The group number column appended by GroupedSort. Unused without keys.
-  uint32_t group_column = 0;
+  IntervalLaneSpec lanes;
   std::vector<AggregateCall> aggregates;
 };
 
@@ -81,7 +78,8 @@
   };
 
   struct State : OperatorState {
-    State() : OperatorState(ResetEachRun{}) {}
+    explicit State(const IntervalLaneSpec& lanes)
+        : OperatorState(ResetEachRun{}), keys(lanes.key_columns) {}
     ~State() override;
     void Reset() override;
 
@@ -126,14 +124,9 @@
     std::vector<SeenBytes> seen_bytes;
     AggregateInputLoader input;
 
-    // Keys for the current input batch plus one carried key from the previous
-    // input batch. Groups can share an output batch without retaining earlier
-    // input.
-    RowStore key_rows;
-    RowBatch retained;
-    RowBatch saved_key;
+    // The keys of the input batch's lanes, and the current lane's handle.
+    LaneKeys keys;
     uint32_t key_row = 0;
-    uint32_t first_key = 0;
 
     // At most kMaxBatchRows completed segments, reused after each yield.
     // Active intervals remain in the heap until their ends are reached.
@@ -141,11 +134,8 @@
     uint32_t segment_capacity = 0;
     // The segments' columns, written straight into the buffers the batch
     // served holds: taken as its first segment is emitted.
-    ColumnBuffer ts_buffer;
-    ColumnBuffer dur_buffer;
+    BoundsColumns bounds;
     ColumnBuffer group_buffer;
-    int64_t* segment_ts = nullptr;
-    int64_t* segment_dur = nullptr;
     uint32_t* segment_groups = nullptr;
     FlexVector<uint32_t> segment_key_rows;
     // By aggregate, the buffer the batch being served has its values in.
@@ -153,8 +143,7 @@
     RowBatch served_keys;
   };
 
-  bool RetainKeys(const RowBatch&, State&) const;
-  bool AddInterval(State&, uint32_t row, int64_t start, int64_t length) const;
+  void AddInterval(State&, uint32_t row, int64_t start, int64_t end) const;
   uint32_t TakeSlot(State&) const;
   // Aggregates the batch, publishes any completed segments, or
   // propagates an error. `in` is the input batch, if any.
@@ -175,6 +164,8 @@
   void TakeSegmentBuffers(State&) const;
 
   IntervalFlattenSpec spec_;
+  // Whether the input has PER columns.
+  bool keyed_;
   // By aggregate of the spec.
   std::vector<std::unique_ptr<AggregateFunction>> functions_;
   std::vector<uint32_t> offsets_;
diff --git a/src/trace_processor/core/exec/interval_flatten_benchmark.cc b/src/trace_processor/core/exec/interval_flatten_benchmark.cc
index 2428222..7e27189 100644
--- a/src/trace_processor/core/exec/interval_flatten_benchmark.cc
+++ b/src/trace_processor/core/exec/interval_flatten_benchmark.cc
@@ -66,13 +66,13 @@
     batch.SetRowCount(count);
   }
   IntervalFlattenSpec spec;
-  spec.ts_column = 0;
-  spec.dur_column = 1;
+  spec.lanes.ts_column = 0;
+  spec.lanes.dur_column = 1;
   spec.aggregates = {{AggregateCall::Function::kCountStar, 0},
                      {AggregateCall::Function::kSum, 2}};
   if (rows_per_group) {
-    spec.key_columns = {3};
-    spec.group_column = 3;
+    spec.lanes.key_columns = {3};
+    spec.lanes.group_column = 3;
   }
   IntervalFlatten op(spec);
   std::unique_ptr<OperatorState> op_state = op.MakeState(context);
diff --git a/src/trace_processor/core/exec/interval_flatten_unittest.cc b/src/trace_processor/core/exec/interval_flatten_unittest.cc
index a2436a1..1810807 100644
--- a/src/trace_processor/core/exec/interval_flatten_unittest.cc
+++ b/src/trace_processor/core/exec/interval_flatten_unittest.cc
@@ -75,10 +75,10 @@
   }
 
   IntervalFlattenSpec spec;
-  spec.ts_column = 0;
-  spec.dur_column = 1;
-  spec.key_columns = {2};
-  spec.group_column = 4;
+  spec.lanes.ts_column = 0;
+  spec.lanes.dur_column = 1;
+  spec.lanes.key_columns = {2};
+  spec.lanes.group_column = 4;
   spec.aggregates = {{AggregateCall::Function::kCountStar, 0},
                      {AggregateCall::Function::kSum, 3}};
   IntervalFlatten op(spec);
@@ -166,8 +166,8 @@
   }
   auto run = [&](std::vector<AggregateCall> aggregates) {
     IntervalFlattenSpec spec;
-    spec.ts_column = 0;
-    spec.dur_column = 1;
+    spec.lanes.ts_column = 0;
+    spec.lanes.dur_column = 1;
     spec.aggregates = std::move(aggregates);
     IntervalFlatten op(spec);
     auto state = op.MakeState(test::TestContext());
@@ -232,8 +232,8 @@
                                              weight.data(), &weight_valid));
   in.SetRowCount(2 * kPairs);
   IntervalFlattenSpec spec;
-  spec.ts_column = 0;
-  spec.dur_column = 1;
+  spec.lanes.ts_column = 0;
+  spec.lanes.dur_column = 1;
   spec.aggregates = {{AggregateCall::Function::kSum, 2}};
   IntervalFlatten op(spec);
   auto state = op.MakeState(test::TestContext());
diff --git a/src/trace_processor/core/exec/interval_intersect.cc b/src/trace_processor/core/exec/interval_intersect.cc
index 6e407f87..448057b 100644
--- a/src/trace_processor/core/exec/interval_intersect.cc
+++ b/src/trace_processor/core/exec/interval_intersect.cc
@@ -19,6 +19,7 @@
 #include <algorithm>
 #include <cstdint>
 #include <cstring>
+#include <limits>
 #include <memory>
 #include <numeric>
 #include <optional>
@@ -37,6 +38,7 @@
 #include "src/trace_processor/core/exec/column_view.h"
 #include "src/trace_processor/core/exec/context.h"
 #include "src/trace_processor/core/exec/group_table.h"
+#include "src/trace_processor/core/exec/interval_lanes.h"
 #include "src/trace_processor/core/exec/operator.h"
 #include "src/trace_processor/core/exec/row_batch.h"
 #include "src/trace_processor/core/exec/row_store.h"
@@ -81,64 +83,17 @@
   }
 };
 
-// The intervals of one key in one operand.
-struct Group {
-  std::vector<Interval> intervals;
-
-  // Whether no two intervals overlap. If so, they can be searched without
-  // building a tree.
-  bool nonoverlapping = true;
-};
-
-// The groups of one operand, indexed by group number from the shared group
-// table. Kept across runs to reuse memory.
-struct Groups {
-  std::vector<Group> by_number;
-  // The groups that have at least one interval, in the order first seen.
-  std::vector<uint32_t> seen;
-  // The operand's group number of the last row read.
-  std::optional<uint32_t> last_group;
-
-  // The shared group number of that row's key.
-  uint32_t last_number = 0;
-
-  Group& Get(uint32_t number) {
-    if (number >= by_number.size()) {
-      by_number.resize(number + 1);
-    }
-    Group& group = by_number[number];
-    if (group.intervals.empty()) {
-      seen.push_back(number);
-      group.nonoverlapping = true;
-    }
-    return group;
-  }
-  const Group* Find(uint32_t number) const {
-    return number < by_number.size() && !by_number[number].intervals.empty()
-               ? &by_number[number]
-               : nullptr;
-  }
-  void Clear() {
-    for (uint32_t number : seen) {
-      by_number[number].intervals.clear();
-    }
-    seen.clear();
-    last_group.reset();
-  }
-};
-
 class IntersectState : public OperatorState {
  public:
   ~IntersectState() override;
 
   std::vector<std::unique_ptr<OperatorState>> operand_states;
-  std::vector<std::unique_ptr<RowStore>> stores;
   // Shared by all operands, so a key has the same number in each of them.
   // This only works if their key types match.
   GroupTable group_table;
-  // Per operand, its rows by key. A key with no entry in some operand covers
-  // nothing, so only keys every operand has produce regions.
-  std::vector<Groups> groups;
+  // Per operand, its intervals by lane. A key with no lane in some operand
+  // covers nothing, so only keys every operand has produce regions.
+  std::vector<std::unique_ptr<CollectedLanes>> lanes;
 
   bool computed = false;
   Regions regions;
@@ -163,126 +118,25 @@
     std::vector<Interval> overlaps;
     // Per operand, the row indices a gather reads.
     std::vector<std::vector<uint32_t>> gather_rows;
-    // The current batch of an operand.
-    RowBatch batch;
-
-    // The part of the current batch that is kept.
-    RowBatch retained;
-
-    // The first row of each group in the current batch.
-    RowBatch firsts;
-    std::vector<uint32_t> first_rows;
-
-    // Per operand, its group of the key being narrowed.
-    std::vector<const Group*> key_groups;
-    // The shared group number of each row of the current batch.
-    std::vector<uint32_t> row_groups;
-
-    // The shared group number of each first row.
-    std::vector<uint32_t> first_numbers;
+    // Per operand, its lane of the key being narrowed.
+    std::vector<CollectedLanes::Lane> key_lanes;
   } scratch;
 };
 
 IntersectState::~IntersectState() = default;
 
-// Reads every row of `operand` into `store` and groups them by key.
-base::Status Collect(const IntervalIntersectOperand& operand,
-                     uint32_t which,
-                     OperatorState& state,
-                     RowStore& store,
-                     GroupTable& group_table,
-                     Groups& groups,
-                     IntersectState::Scratch& scratch) {
-  RowBatch& batch = scratch.batch;
-  RowBatch& retained = scratch.retained;
-  while (operand.source->GetData(batch, state)) {
-    PERFETTO_DCHECK(IsFlat<Int64>(batch.column(operand.ts_column)));
-    PERFETTO_DCHECK(IsFlat<Int64>(batch.column(operand.dur_column)));
-    FlatColumnReader<int64_t> ts(batch, operand.ts_column);
-    FlatColumnReader<int64_t> dur(batch, operand.dur_column);
-    // A group's rows arrive together, so only the first row of each group is
-    // looked up in the shared group table.
-    scratch.row_groups.assign(batch.size(), 0);
-    if (!operand.key_columns.empty()) {
-      scratch.first_rows.clear();
-      std::optional<uint32_t> last = groups.last_group;
-      for (uint32_t row = 0; row < batch.size(); ++row) {
-        uint32_t group = batch.Value<uint32_t>(operand.group_column, row);
-        if (group != last) {
-          scratch.first_rows.push_back(row);
-          last = group;
-        }
-      }
-      scratch.firsts.CopyFrom(batch);
-      const uint32_t* firsts = scratch.first_rows.data();
-      scratch.firsts.mutable_selection().Keep(
-          {firsts, firsts + scratch.first_rows.size()});
-      std::vector<uint32_t>& numbers = scratch.first_numbers;
-      numbers.resize(scratch.first_rows.size());
-      if (std::optional<uint32_t> bad = group_table.FindOrCreate(
-              scratch.firsts, operand.key_columns, numbers.data())) {
-        return base::ErrStatus(
-            "INTERVAL INTERSECTION: operand %u's PER column %u must hold one "
-            "type, the same in every operand",
-            which + 1, *bad + 1);
-      }
-      size_t next = 0;
-      for (uint32_t row = 0; row < batch.size(); ++row) {
-        if (next < scratch.first_rows.size() &&
-            scratch.first_rows[next] == row) {
-          groups.last_number = numbers[next++];
-        }
-        scratch.row_groups[row] = groups.last_number;
-      }
-      groups.last_group = last;
-    }
-    for (uint32_t row = 0; row < batch.size(); ++row) {
-      int64_t start;
-      int64_t length;
-      if (!ts.Read(row, &start) || !dur.Read(row, &length)) {
-        continue;
-      }
-      if (start < 0 || length < 0) {
-        return base::ErrStatus(
-            "INTERVAL INTERSECTION: operand %u has a row whose ts or dur is "
-            "below zero",
-            which + 1);
-      }
-      int64_t end;
-      if (!base::CheckedAdd(start, length, &end)) {
-        return base::ErrStatus("INTERVAL INTERSECTION: integer overflow");
-      }
-      Group& group = groups.Get(scratch.row_groups[row]);
-      Interval interval{static_cast<Ts>(start), static_cast<Ts>(end),
-                        store.size() + row};
-      // Groups with no overlapping intervals use a faster path. Intervals
-      // arrive sorted by start, so comparing with the previous one is enough
-      // to detect overlap.
-      if (!group.intervals.empty() &&
-          IsOverlapping(group.intervals.back(), interval)) {
-        group.nonoverlapping = false;
-      }
-      group.intervals.push_back(interval);
-    }
-    retained.Project(batch, operand.retained_columns);
-    RETURN_IF_ERROR(store.Append(retained));
-  }
-  RETURN_IF_ERROR(operand.source->status(state));
-
-  return base::OkStatus();
-}
-
 // Narrows the regions of one key. If every operand is non-overlapping, runs a
 // fast k-pointer sweep. Otherwise, narrows through operands pairwise, smallest
 // first so the running set starts as small as it can.
-void NarrowKey(const std::vector<const Group*>& groups,
+void NarrowKey(const std::vector<CollectedLanes::Lane>& groups,
                IntersectState::Scratch& scratch,
                Regions& out) {
-  if (std::all_of(groups.begin(), groups.end(),
-                  [](const Group* g) { return g->nonoverlapping; })) {
-    base::SmallVector<const std::vector<Interval>*, 16> tables;
-    for (const Group* group : groups) {
-      tables.emplace_back(&group->intervals);
+  if (std::all_of(
+          groups.begin(), groups.end(),
+          [](const CollectedLanes::Lane& g) { return g.nonoverlapping; })) {
+    base::SmallVector<const Span<const Interval>*, 16> tables;
+    for (const CollectedLanes::Lane& group : groups) {
+      tables.emplace_back(&group.intervals);
     }
     IntervalIntersector::IntersectNonOverlapping(
         tables, [&](uint64_t start, uint64_t end, const uint32_t* ids) {
@@ -300,19 +154,19 @@
   order.resize(count);
   std::iota(order.begin(), order.end(), 0u);
   ColdSortByKey(order.begin(), order.end(),
-                [&](uint32_t i) { return groups[i]->intervals.size(); });
+                [&](uint32_t i) { return groups[i].intervals.size(); });
 
   running.Clear();
-  for (const Interval& interval : groups[order.front()]->intervals) {
+  for (const Interval& interval : groups[order.front()].intervals) {
     running.Push(interval.start, interval.end, nullptr)[order.front()] =
         interval.id;
   }
 
   for (uint32_t i = 1; i < count && running.size() > 0; ++i) {
     uint32_t which = order[i];
-    const Group& group = *groups[which];
+    const CollectedLanes::Lane& group = groups[which];
     IntervalIntersector intersector(
-        group.intervals,
+        group.intervals.data(), group.intervals.size(),
         IntervalIntersector::DecideMode(group.nonoverlapping, running.size()));
     narrowed.Clear();
     for (uint32_t r = 0; r < running.size(); ++r) {
@@ -332,8 +186,7 @@
 
 }  // namespace
 
-IntervalIntersect::IntervalIntersect(
-    std::vector<IntervalIntersectOperand> operands)
+IntervalIntersect::IntervalIntersect(std::vector<CollectedInputSpec> operands)
     : operands_(std::move(operands)) {
   PERFETTO_CHECK(operands_.size() >= 2);
 }
@@ -346,12 +199,13 @@
   state->context = &context;
   auto count = static_cast<uint32_t>(operands_.size());
   for (uint32_t i = 0; i < count; ++i) {
-    state->stores.push_back(std::make_unique<RowStore>());
+    state->lanes.push_back(std::make_unique<CollectedLanes>(
+        operands_[i],
+        IntervalInputName{"INTERVAL INTERSECTION", "operand", i + 1}));
   }
-  state->groups.resize(count);
   state->gathered.resize(count);
   state->scratch.gather_rows.resize(count);
-  for (const IntervalIntersectOperand& operand : operands_) {
+  for (const CollectedInputSpec& operand : operands_) {
     state->operand_states.push_back(operand.source->MakeState(context));
   }
   return state;
@@ -365,8 +219,7 @@
   IntersectState& s = state.Cast<IntersectState>();
   for (uint32_t i = 0; i < operands_.size(); ++i) {
     operands_[i].source->Rewind(*s.operand_states[i]);
-    s.stores[i]->Clear();
-    s.groups[i].Clear();
+    s.lanes[i]->Clear();
   }
   s.group_table.Clear();
   s.computed = false;
@@ -383,8 +236,12 @@
     s.scratch.running.operands = count;
     s.scratch.narrowed.operands = count;
     for (uint32_t i = 0; i < count; ++i) {
-      s.status = Collect(operands_[i], i, *s.operand_states[i], *s.stores[i],
-                         s.group_table, s.groups[i], s.scratch);
+      // A key no earlier operand has can produce no region, so is skipped.
+      uint32_t limit = i == 0 || operands_[i].lanes.key_columns.empty()
+                           ? std::numeric_limits<uint32_t>::max()
+                           : s.group_table.size();
+      s.status =
+          s.lanes[i]->Collect(*s.operand_states[i], &s.group_table, limit);
       if (!s.status.ok()) {
         return false;
       }
@@ -393,21 +250,28 @@
     // fewest of them can start one.
     uint32_t fewest = 0;
     for (uint32_t i = 1; i < count; ++i) {
-      if (s.groups[i].seen.size() < s.groups[fewest].seen.size()) {
+      if (s.lanes[i]->size() < s.lanes[fewest]->size()) {
         fewest = i;
       }
     }
-    std::vector<const Group*>& groups = s.scratch.key_groups;
-    groups.resize(count);
-    for (uint32_t number : s.groups[fewest].seen) {
+    std::vector<CollectedLanes::Lane>& lanes = s.scratch.key_lanes;
+    lanes.resize(count);
+    for (uint32_t l = 0; l < s.lanes[fewest]->size(); ++l) {
+      uint32_t number = s.lanes[fewest]->lane(l).number;
       bool everywhere = true;
       for (uint32_t i = 0; i < count && everywhere; ++i) {
-        const Group* group = s.groups[i].Find(number);
-        groups[i] = group;
-        everywhere = group != nullptr;
+        if (i == fewest) {
+          lanes[i] = s.lanes[i]->lane(l);
+          continue;
+        }
+        std::optional<uint32_t> found = s.lanes[i]->Find(number);
+        everywhere = found.has_value();
+        if (everywhere) {
+          lanes[i] = s.lanes[i]->lane(*found);
+        }
       }
       if (everywhere) {
-        NarrowKey(groups, s.scratch, s.regions);
+        NarrowKey(lanes, s.scratch, s.regions);
       }
     }
     s.computed = true;
@@ -420,17 +284,16 @@
     return false;
   }
 
-  ColumnBuffer ts_buffer = s.context->TakeBuffer();
-  ColumnBuffer dur_buffer = s.context->TakeBuffer();
-  int64_t* ts = ts_buffer.chunk().Values<int64_t>();
-  int64_t* dur = dur_buffer.chunk().Values<int64_t>();
+  BoundsColumns bounds;
+  bounds.Take(*s.context);
   for (uint32_t i = 0; i < count; ++i) {
     s.scratch.gather_rows[i].resize(serving);
   }
   for (uint32_t row = 0; row < serving; ++row) {
     uint32_t at = s.served + row;
-    ts[row] = static_cast<int64_t>(s.regions.starts[at]);
-    dur[row] = static_cast<int64_t>(s.regions.ends[at] - s.regions.starts[at]);
+    bounds.ts[row] = static_cast<int64_t>(s.regions.starts[at]);
+    bounds.dur[row] =
+        static_cast<int64_t>(s.regions.ends[at] - s.regions.starts[at]);
     const uint32_t* from = s.regions.RowsOf(at);
     for (uint32_t i = 0; i < count; ++i) {
       s.scratch.gather_rows[i][row] = from[i];
@@ -439,13 +302,11 @@
   s.served += serving;
 
   out.Reset();
-  out.AddColumn(ColumnView::Reference(StorageType{Int64{}}, ts),
-                std::move(ts_buffer));
-  out.AddColumn(ColumnView::Reference(StorageType{Int64{}}, dur),
-                std::move(dur_buffer));
+  bounds.AddTo(&out);
   for (uint32_t i = 0; i < count; ++i) {
     const uint32_t* rows = s.scratch.gather_rows[i].data();
-    s.stores[i]->View(&s.gathered[i], {rows, rows + serving}, *s.context);
+    s.lanes[i]->rows().Gather(&s.gathered[i], {rows, rows + serving},
+                              *s.context);
     for (uint32_t c = 0; c < s.gathered[i].column_count(); ++c) {
       out.AddColumn(s.gathered[i].column(c), s.gathered[i].buffer(c));
     }
diff --git a/src/trace_processor/core/exec/interval_intersect.h b/src/trace_processor/core/exec/interval_intersect.h
index c516246..55e4634 100644
--- a/src/trace_processor/core/exec/interval_intersect.h
+++ b/src/trace_processor/core/exec/interval_intersect.h
@@ -22,29 +22,12 @@
 #include <vector>
 
 #include "perfetto/base/status.h"
+#include "src/trace_processor/core/exec/interval_lanes.h"
 #include "src/trace_processor/core/exec/operator.h"
 #include "src/trace_processor/core/exec/row_batch.h"
 
 namespace perfetto::trace_processor::core::exec {
 
-// One operand of an intersection: where its rows come from and which of its
-// columns carry the interval and the key.
-struct IntervalIntersectOperand {
-  // Read in full before any region is found.
-  const Source* source = nullptr;
-  // Flat Int64 columns of `source`'s batches.
-  uint32_t ts_column = 0;
-  uint32_t dur_column = 0;
-  // Compared pairwise across the operands, in this order.
-  std::vector<uint32_t> key_columns;
-  // The column holding each row's group number. Only used if there are keys.
-  // A group's rows arrive together, sorted by ts.
-  uint32_t group_column = 0;
-  // The columns kept for output, in this order. Any others are read only to
-  // find the regions and are never buffered.
-  std::vector<uint32_t> retained_columns;
-};
-
 // Emits a row over each region every operand covers.
 //
 // An interval is [ts, ts + dur) and a region is the part two or more of them
@@ -65,9 +48,10 @@
   static constexpr char kType = 0;
   const void* type() const override { return &kType; }
 
-  // Every operand's source must outlive this. Two are the fewest which can
-  // have a region in common.
-  explicit IntervalIntersect(std::vector<IntervalIntersectOperand>);
+  // Each operand is read in full before any region is found, and their keys
+  // are compared pairwise, in order. Every operand's source must outlive
+  // this. Two are the fewest which can have a region in common.
+  explicit IntervalIntersect(std::vector<CollectedInputSpec>);
   ~IntervalIntersect() override;
 
   std::unique_ptr<OperatorState> MakeState(Context&) const override;
@@ -78,7 +62,7 @@
  private:
   friend class PipelineFormatter;
 
-  std::vector<IntervalIntersectOperand> operands_;
+  std::vector<CollectedInputSpec> operands_;
 };
 
 }  // namespace perfetto::trace_processor::core::exec
diff --git a/src/trace_processor/core/exec/interval_intersect_benchmark.cc b/src/trace_processor/core/exec/interval_intersect_benchmark.cc
index 254b8cb..df713ab 100644
--- a/src/trace_processor/core/exec/interval_intersect_benchmark.cc
+++ b/src/trace_processor/core/exec/interval_intersect_benchmark.cc
@@ -16,6 +16,7 @@
 
 #include "src/trace_processor/core/exec/context.h"
 #include "src/trace_processor/core/exec/interval_intersect.h"
+#include "src/trace_processor/core/exec/interval_lanes.h"
 
 #include <benchmark/benchmark.h>
 
@@ -81,12 +82,12 @@
   std::vector<int64_t> key_;
 };
 
-IntervalIntersectOperand Operand(const Intervals& source) {
-  IntervalIntersectOperand operand;
+CollectedInputSpec Operand(const Intervals& source) {
+  CollectedInputSpec operand;
   operand.source = &source;
-  operand.ts_column = 0;
-  operand.dur_column = 1;
-  operand.key_columns = {2};
+  operand.lanes.ts_column = 0;
+  operand.lanes.dur_column = 1;
+  operand.lanes.key_columns = {2};
   operand.retained_columns = {2};
   return operand;
 }
diff --git a/src/trace_processor/core/exec/interval_intersect_unittest.cc b/src/trace_processor/core/exec/interval_intersect_unittest.cc
index f7a5dd3..61f6856 100644
--- a/src/trace_processor/core/exec/interval_intersect_unittest.cc
+++ b/src/trace_processor/core/exec/interval_intersect_unittest.cc
@@ -15,6 +15,7 @@
  */
 
 #include "src/trace_processor/core/exec/interval_intersect.h"
+#include "src/trace_processor/core/exec/interval_lanes.h"
 
 #include <algorithm>
 #include <cstdint>
@@ -101,11 +102,11 @@
 
 // An operand whose ts and dur are its first two columns, the rest being
 // whatever the table carries along. Every column is retained.
-IntervalIntersectOperand Operand(const TableSource& source) {
-  IntervalIntersectOperand operand;
+CollectedInputSpec Operand(const TableSource& source) {
+  CollectedInputSpec operand;
   operand.source = &source;
-  operand.ts_column = 0;
-  operand.dur_column = 1;
+  operand.lanes.ts_column = 0;
+  operand.lanes.dur_column = 1;
   for (uint32_t c = 0; c < source.columns(); ++c) {
     operand.retained_columns.push_back(c);
   }
@@ -138,7 +139,7 @@
   return rows;
 }
 
-Table Intersect(std::vector<IntervalIntersectOperand> operands,
+Table Intersect(std::vector<CollectedInputSpec> operands,
                 base::Status* status = nullptr) {
   IntervalIntersect intersect(std::move(operands));
   std::unique_ptr<OperatorState> state =
diff --git a/src/trace_processor/core/exec/interval_lanes.cc b/src/trace_processor/core/exec/interval_lanes.cc
new file mode 100644
index 0000000..fd12254
--- /dev/null
+++ b/src/trace_processor/core/exec/interval_lanes.cc
@@ -0,0 +1,242 @@
+/*
+ * Copyright (C) 2026 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.
+ */
+
+#include "src/trace_processor/core/exec/interval_lanes.h"
+
+#include <algorithm>
+#include <cstdint>
+#include <optional>
+#include <utility>
+#include <vector>
+
+#include "perfetto/base/logging.h"
+#include "perfetto/base/status.h"
+#include "perfetto/ext/base/status_macros.h"
+#include "perfetto/ext/base/string_utils.h"
+#include "src/trace_processor/containers/interval_tree.h"
+#include "src/trace_processor/core/exec/context.h"
+#include "src/trace_processor/core/exec/group_table.h"
+#include "src/trace_processor/core/exec/operator.h"
+#include "src/trace_processor/core/exec/row_batch.h"
+#include "src/trace_processor/core/exec/selection.h"
+#include "src/trace_processor/core/util/span.h"
+
+namespace perfetto::trace_processor::core::exec {
+
+namespace {
+
+// "<op>: <input>", with the input's number if it has one.
+base::StackString<128> Prefix(const IntervalInputName& name) {
+  auto op = static_cast<int>(name.op.size());
+  auto input = static_cast<int>(name.input.size());
+  if (name.number) {
+    return base::StackString<128>("%.*s: %.*s %u", op, name.op.data(), input,
+                                  name.input.data(), name.number);
+  }
+  return base::StackString<128>("%.*s: %.*s", op, name.op.data(), input,
+                                name.input.data());
+}
+
+}  // namespace
+
+base::Status LaneBatch::Error(Result result,
+                              const IntervalInputName& name) const {
+  if (result == Result::kOverflow) {
+    return base::ErrStatus("%.*s: integer overflow",
+                           static_cast<int>(name.op.size()), name.op.data());
+  }
+  PERFETTO_DCHECK(result == Result::kNegative);
+  if (forever_) {
+    return base::ErrStatus(
+        "%s has a row whose ts is below zero, or whose dur is below zero and "
+        "not -1",
+        Prefix(name).c_str());
+  }
+  return base::ErrStatus("%s has a row whose ts or dur is below zero",
+                         Prefix(name).c_str());
+}
+
+base::Status LaneReader::Start(const RowBatch& in, GroupTable* shared) {
+  PERFETTO_DCHECK(IsFlat<Int64>(in.column(spec_->ts_column)));
+  PERFETTO_DCHECK(IsFlat<Int64>(in.column(spec_->dur_column)));
+  batch_ = &in;
+  shared_ = shared && !spec_->key_columns.empty();
+  if (!shared_) {
+    return base::OkStatus();
+  }
+  // A lane's rows arrive together, so only the first row of each lane is
+  // looked up in the shared table.
+  first_rows_.clear();
+  std::optional<uint32_t> last = last_group_;
+  for (uint32_t row = 0; row < in.size(); ++row) {
+    uint32_t group = in.Value<uint32_t>(spec_->group_column, row);
+    if (group != last) {
+      first_rows_.push_back(row);
+      last = group;
+    }
+  }
+  if (!first_rows_.empty()) {
+    firsts_.CopyFrom(in.selection());
+    const uint32_t* firsts = first_rows_.data();
+    firsts_.Keep({firsts, firsts + first_rows_.size()});
+    first_lanes_.resize(first_rows_.size());
+    if (std::optional<uint32_t> bad = shared->FindOrCreate(
+            in, firsts_, spec_->key_columns, first_lanes_.data())) {
+      return base::ErrStatus(
+          "%s's PER column %u must hold one type, the same in every input",
+          Prefix(name_).c_str(), *bad + 1);
+    }
+  }
+  lanes_.resize(in.size());
+  size_t next = 0;
+  for (uint32_t row = 0; row < in.size(); ++row) {
+    if (next < first_rows_.size() && first_rows_[next] == row) {
+      last_lane_ = first_lanes_[next++];
+    }
+    lanes_[row] = last_lane_;
+  }
+  last_group_ = last;
+  return base::OkStatus();
+}
+
+base::Status CollectedLanes::Collect(OperatorState& state,
+                                     GroupTable* shared,
+                                     uint32_t limit) {
+  const Source& source = *input_->source;
+  while (source.GetData(batch_, state)) {
+    RETURN_IF_ERROR(reader_.Start(batch_, shared));
+    LaneBatch lanes = reader_.batch();
+    uint32_t first_row = rows_.size();
+    for (uint32_t row = 0; row < batch_.size(); ++row) {
+      int64_t start;
+      int64_t end;
+      LaneBatch::Result result = lanes.Read(row, &start, &end);
+      if (result != LaneBatch::Result::kOk) {
+        if (result == LaneBatch::Result::kSkip) {
+          continue;
+        }
+        return lanes.Error(result, reader_.name());
+      }
+      uint32_t number = lanes.lane(row);
+      if (number >= limit) {
+        continue;
+      }
+      Add(number, Interval{static_cast<Ts>(start), static_cast<Ts>(end),
+                           first_row + row});
+    }
+    retained_.Project(batch_, input_->retained_columns);
+    RETURN_IF_ERROR(rows_.Append(retained_));
+  }
+  RETURN_IF_ERROR(source.status(state));
+  by_number_.clear();
+  by_number_.reserve(ranges_.size());
+  for (uint32_t i = 0; i < ranges_.size(); ++i) {
+    by_number_.emplace_back(ranges_[i].number, i);
+  }
+  if (!std::is_sorted(by_number_.begin(), by_number_.end())) {
+    std::sort(by_number_.begin(), by_number_.end());
+  }
+  // Find() returns one range per number, so each lane must arrive whole.
+  PERFETTO_DCHECK(std::adjacent_find(by_number_.begin(), by_number_.end(),
+                                     [](const auto& a, const auto& b) {
+                                       return a.first == b.first;
+                                     }) == by_number_.end());
+  return base::OkStatus();
+}
+
+PERFETTO_ALWAYS_INLINE void CollectedLanes::Add(uint32_t number,
+                                                const Interval& interval) {
+  if (ranges_.empty() || ranges_.back().number != number) {
+    auto at = static_cast<uint32_t>(intervals_.size());
+    ranges_.push_back({number, at, at, true});
+  }
+  Range& range = ranges_.back();
+  // Intervals arrive sorted by start, so comparing with the previous one is
+  // enough to detect overlap.
+  if (range.end > range.begin && IsOverlapping(intervals_.back(), interval)) {
+    range.nonoverlapping = false;
+  }
+  intervals_.push_back(interval);
+  range.end++;
+}
+
+void CollectedLanes::Clear() {
+  reader_.Reset();
+  intervals_.clear();
+  ranges_.clear();
+  by_number_.clear();
+  rows_.Clear();
+}
+
+base::Status LaneKeys::Hold(const RowBatch& in) {
+  rows_.Clear();
+  // The open lane's keys may be in buffers the previous batch has since
+  // given back for reuse, so they were kept by Carry().
+  if (carried_.size()) {
+    RETURN_IF_ERROR(rows_.Append(carried_));
+  }
+  first_ = rows_.size();
+  retained_.Project(in, *key_columns_);
+  return rows_.Append(retained_);
+}
+
+void LaneKeys::Carry(uint32_t handle) {
+  rows_.View(&carried_, handle, 1);
+}
+
+void LaneKeys::Gather(RowBatch* out, Span<const uint32_t> handles, Context& c) {
+  rows_.Gather(out, handles, c);
+}
+
+void LaneKeys::Clear() {
+  rows_.Clear();
+  retained_.Reset();
+  carried_.Reset();
+  first_ = 0;
+}
+
+void BoundsColumns::Take(Context& context) {
+  ts_buffer_ = context.TakeBuffer();
+  dur_buffer_ = context.TakeBuffer();
+  ts = ts_buffer_.chunk().Values<int64_t>();
+  dur = dur_buffer_.chunk().Values<int64_t>();
+}
+
+void BoundsColumns::AddTo(RowBatch* out) {
+  out->AddColumn(ColumnView::Reference(StorageType{Int64{}}, ts),
+                 std::move(ts_buffer_));
+  out->AddColumn(ColumnView::Reference(StorageType{Int64{}}, dur),
+                 std::move(dur_buffer_));
+  ts = nullptr;
+  dur = nullptr;
+}
+
+void BoundsColumns::AddTsTo(RowBatch* out) const {
+  out->AddColumn(ColumnView::Reference(StorageType{Int64{}}, ts), ts_buffer_);
+}
+
+void BoundsColumns::AddDurTo(RowBatch* out) const {
+  out->AddColumn(ColumnView::Reference(StorageType{Int64{}}, dur), dur_buffer_);
+}
+
+void BoundsColumns::Clear() {
+  ts_buffer_ = ColumnBuffer();
+  dur_buffer_ = ColumnBuffer();
+  ts = nullptr;
+  dur = nullptr;
+}
+
+}  // namespace perfetto::trace_processor::core::exec
diff --git a/src/trace_processor/core/exec/interval_lanes.h b/src/trace_processor/core/exec/interval_lanes.h
new file mode 100644
index 0000000..4caadea
--- /dev/null
+++ b/src/trace_processor/core/exec/interval_lanes.h
@@ -0,0 +1,309 @@
+/*
+ * Copyright (C) 2026 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.
+ */
+
+#ifndef SRC_TRACE_PROCESSOR_CORE_EXEC_INTERVAL_LANES_H_
+#define SRC_TRACE_PROCESSOR_CORE_EXEC_INTERVAL_LANES_H_
+
+#include <algorithm>
+#include <cstdint>
+#include <limits>
+#include <optional>
+#include <string_view>
+#include <utility>
+#include <vector>
+
+#include "perfetto/base/compiler.h"
+#include "perfetto/base/status.h"
+#include "perfetto/ext/base/utils.h"
+#include "src/trace_processor/containers/interval_tree.h"
+#include "src/trace_processor/core/common/storage_types.h"
+#include "src/trace_processor/core/exec/column_view.h"
+#include "src/trace_processor/core/exec/context.h"
+#include "src/trace_processor/core/exec/row_batch.h"
+#include "src/trace_processor/core/exec/row_store.h"
+#include "src/trace_processor/core/exec/selection.h"
+#include "src/trace_processor/core/util/span.h"
+
+// The input stage shared by the interval operators. Each reads one or more
+// interval inputs: rows with a ts and dur, grouped into lanes by PER columns
+// and sorted by ts within each lane.
+
+namespace perfetto::trace_processor::core::exec {
+
+class GroupTable;
+class OperatorState;
+class Source;
+
+// Where an interval input's columns are. ts and dur are flat Int64. Rows are
+// grouped by `key_columns`, numbered by `group_column` if there are any, and
+// sorted by ts within each group.
+struct IntervalLaneSpec {
+  uint32_t ts_column = 0;
+  uint32_t dur_column = 0;
+  std::vector<uint32_t> key_columns;
+  uint32_t group_column = 0;
+  // Whether a dur of -1 is an interval which never ends.
+  bool forever = false;
+};
+
+// An interval input read whole from its own source, keeping
+// `retained_columns` of each row, in this order. Any other column is read
+// only for the intervals and is never buffered.
+struct CollectedInputSpec {
+  const Source* source = nullptr;
+  IntervalLaneSpec lanes;
+  std::vector<uint32_t> retained_columns;
+};
+
+// An interval input, as named in error messages: "<op>: <input> has ...".
+// A non-zero `number` follows the input's name, as in "operand 2".
+struct IntervalInputName {
+  std::string_view op;
+  std::string_view input;
+  uint32_t number = 0;
+};
+
+// One batch of an interval input: each row's lane and interval. Small, so
+// callers keep it in a local while they loop over the rows. Without a
+// LaneReader, lanes are numbered by `group_column`.
+class LaneBatch {
+ public:
+  enum class Result { kOk, kSkip, kNegative, kOverflow };
+
+  LaneBatch(const RowBatch& batch, const IntervalLaneSpec& spec)
+      : ts_(batch, spec.ts_column),
+        dur_(batch, spec.dur_column),
+        batch_(&batch),
+        group_column_(spec.group_column),
+        keyed_(!spec.key_columns.empty()),
+        forever_(spec.forever) {}
+
+  // The lane of row `row`. Rows without keys are all in lane 0.
+  PERFETTO_ALWAYS_INLINE uint32_t lane(uint32_t row) const {
+    if (!keyed_) {
+      return 0;
+    }
+    return lanes_ ? lanes_[row] : batch_->Value<uint32_t>(group_column_, row);
+  }
+
+  // Reads row `row`'s interval [start, end). A row without a ts or dur is
+  // kSkip. Error() describes the other failures.
+  PERFETTO_ALWAYS_INLINE Result Read(uint32_t row,
+                                     int64_t* start,
+                                     int64_t* end) const {
+    int64_t length;
+    if (!ts_.Read(row, start) || !dur_.Read(row, &length)) {
+      return Result::kSkip;
+    }
+    if (PERFETTO_UNLIKELY(*start < 0 || length < 0)) {
+      if (forever_ && length == -1 && *start >= 0) {
+        *end = std::numeric_limits<int64_t>::max();
+        return Result::kOk;
+      }
+      return Result::kNegative;
+    }
+    if (PERFETTO_UNLIKELY(!base::CheckedAdd(*start, length, end))) {
+      return Result::kOverflow;
+    }
+    return Result::kOk;
+  }
+
+  // Why a row of input `name` could not be read.
+  base::Status Error(Result, const IntervalInputName& name) const;
+
+ private:
+  friend class LaneReader;
+
+  FlatColumnReader<int64_t> ts_;
+  FlatColumnReader<int64_t> dur_;
+  const RowBatch* batch_;
+  // The shared number of each row's lane, if a LaneReader numbered them.
+  const uint32_t* lanes_ = nullptr;
+  uint32_t group_column_;
+  bool keyed_;
+  bool forever_;
+};
+
+// Numbers the lanes of an interval input's batches in a GroupTable, which
+// several inputs can share so that they agree on each key's number.
+class LaneReader {
+ public:
+  LaneReader(const IntervalLaneSpec& spec, IntervalInputName name)
+      : spec_(&spec), name_(name) {}
+
+  // Reads `in`, numbering its lanes in `shared` if given, and by group number
+  // otherwise.
+  base::Status Start(const RowBatch& in, GroupTable* shared);
+
+  // The batch Start() was last given.
+  LaneBatch batch() const {
+    LaneBatch batch(*batch_, *spec_);
+    batch.lanes_ = shared_ ? lanes_.data() : nullptr;
+    return batch;
+  }
+
+  const IntervalInputName& name() const { return name_; }
+
+  // Forgets the last lane read, for a new run.
+  void Reset() { last_group_.reset(); }
+
+ private:
+  const IntervalLaneSpec* spec_;
+  IntervalInputName name_;
+
+  const RowBatch* batch_ = nullptr;
+  bool shared_ = false;
+  std::vector<uint32_t> lanes_;
+  // The input's group number of the last row read, and its shared number.
+  std::optional<uint32_t> last_group_;
+  uint32_t last_lane_ = 0;
+
+  // Scratch: the first row of each group in the batch, and their numbers.
+  Selection firsts_;
+  std::vector<uint32_t> first_rows_;
+  std::vector<uint32_t> first_lanes_;
+};
+
+// An interval input read whole: its intervals in one vector, grouped by lane
+// and sorted by start within each, and the rows they came from. Each
+// interval's id is its row in rows(). Kept across runs to reuse memory.
+class CollectedLanes {
+ public:
+  struct Lane {
+    uint32_t number;
+    Span<const Interval> intervals;
+    // Whether no two intervals overlap. If so, they can be searched without
+    // building a tree.
+    bool nonoverlapping;
+  };
+
+  CollectedLanes(const CollectedInputSpec& input, IntervalInputName name)
+      : input_(&input), reader_(input.lanes, name) {}
+
+  // Reads every batch of the input's source. Lanes are numbered in `shared`
+  // if given, as LaneReader::Start() does, and by group number otherwise.
+  // Lanes numbered at or above `limit` are dropped.
+  base::Status Collect(OperatorState& state,
+                       GroupTable* shared,
+                       uint32_t limit = std::numeric_limits<uint32_t>::max());
+
+  uint32_t size() const { return static_cast<uint32_t>(ranges_.size()); }
+  Lane lane(uint32_t i) const {
+    const Range& range = ranges_[i];
+    const Interval* data = intervals_.data();
+    return {range.number,
+            {data + range.begin, data + range.end},
+            range.nonoverlapping};
+  }
+  // The index of the lane numbered `number`, if there is one.
+  std::optional<uint32_t> Find(uint32_t number) const {
+    auto it = std::lower_bound(by_number_.begin(), by_number_.end(), number,
+                               [](const std::pair<uint32_t, uint32_t>& p,
+                                  uint32_t n) { return p.first < n; });
+    if (it == by_number_.end() || it->first != number) {
+      return std::nullopt;
+    }
+    return it->second;
+  }
+
+  RowStore& rows() { return rows_; }
+  const LaneReader& reader() const { return reader_; }
+
+  void Clear();
+
+ private:
+  struct Range {
+    uint32_t number;
+    uint32_t begin;
+    uint32_t end;
+    bool nonoverlapping;
+  };
+
+  void Add(uint32_t number, const Interval& interval);
+
+  const CollectedInputSpec* input_;
+  LaneReader reader_;
+  std::vector<Interval> intervals_;
+  std::vector<Range> ranges_;
+  // Each range's number and index, sorted by number.
+  std::vector<std::pair<uint32_t, uint32_t>> by_number_;
+  RowStore rows_;
+
+  // Scratch: the current batch, and the part of it kept.
+  RowBatch batch_;
+  RowBatch retained_;
+};
+
+// The PER values of the lanes of one input batch, for rows an operator makes
+// for those lanes. Only one batch's keys are held, plus those of a lane still
+// open from the batch before, so memory does not grow with the input.
+class LaneKeys {
+ public:
+  // The handle of the open lane's keys after Hold().
+  static constexpr uint32_t kCarried = 0;
+
+  // `key_columns` must outlive this.
+  explicit LaneKeys(const std::vector<uint32_t>& key_columns)
+      : key_columns_(&key_columns) {}
+
+  // Holds the keys of every row of `in`, after those carried by Carry().
+  // Handles from before are invalid.
+  base::Status Hold(const RowBatch& in);
+
+  // The handle of the keys of row `row` of the batch held.
+  uint32_t Of(uint32_t row) const { return first_ + row; }
+
+  // Keeps the keys of `handle` through the next Hold(), as kCarried: a lane
+  // still open at the end of a batch continues into the next.
+  void Carry(uint32_t handle);
+
+  // Copies the keys of `handles`, in order, into `out`.
+  void Gather(RowBatch* out, Span<const uint32_t> handles, Context&);
+
+  void Clear();
+
+ private:
+  const std::vector<uint32_t>* key_columns_;
+  RowStore rows_;
+  RowBatch retained_;
+  RowBatch carried_;
+  uint32_t first_ = 0;
+};
+
+// The ts and dur columns of rows an interval operator makes, written straight
+// into buffers taken from a Context.
+class BoundsColumns {
+ public:
+  bool taken() const { return ts != nullptr; }
+  void Take(Context&);
+  // Adds the columns to `out` and gives it the buffers.
+  void AddTo(RowBatch* out);
+  // Adds one column to `out`, sharing its buffer, so it can be added again.
+  void AddTsTo(RowBatch* out) const;
+  void AddDurTo(RowBatch* out) const;
+  void Clear();
+
+  int64_t* ts = nullptr;
+  int64_t* dur = nullptr;
+
+ private:
+  ColumnBuffer ts_buffer_;
+  ColumnBuffer dur_buffer_;
+};
+
+}  // namespace perfetto::trace_processor::core::exec
+
+#endif  // SRC_TRACE_PROCESSOR_CORE_EXEC_INTERVAL_LANES_H_
diff --git a/src/trace_processor/core/exec/interval_lanes_unittest.cc b/src/trace_processor/core/exec/interval_lanes_unittest.cc
new file mode 100644
index 0000000..ca8c174
--- /dev/null
+++ b/src/trace_processor/core/exec/interval_lanes_unittest.cc
@@ -0,0 +1,149 @@
+/*
+ * Copyright (C) 2026 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.
+ */
+
+#include "src/trace_processor/core/exec/interval_lanes.h"
+
+#include <cstdint>
+#include <limits>
+#include <vector>
+
+#include "src/trace_processor/core/exec/group_table.h"
+#include "src/trace_processor/core/exec/row_batch.h"
+#include "src/trace_processor/core/exec/test_utils.h"
+#include "src/trace_processor/core/util/bit_vector.h"
+#include "test/gtest_and_gmock.h"
+
+namespace perfetto::trace_processor::core::exec {
+namespace {
+
+using testing::ElementsAre;
+using testing::HasSubstr;
+using Result = LaneBatch::Result;
+
+// A batch of ts, dur, key and group number columns. A dur of `kNull` is null.
+constexpr int64_t kNull = std::numeric_limits<int64_t>::min();
+RowBatch Batch(const std::vector<int64_t>& ts,
+               const std::vector<int64_t>& dur,
+               const std::vector<int64_t>& keys,
+               const std::vector<uint32_t>& groups) {
+  BitVector valid = BitVector::CreateWithSize(dur.size(), true);
+  for (uint32_t i = 0; i < dur.size(); ++i) {
+    if (dur[i] == kNull) {
+      valid.clear(i);
+    }
+  }
+  RowBatch batch;
+  Context& context = test::TestContext();
+  test::AddCopy(context, ts, nullptr, &batch);
+  test::AddCopy(context, dur, &valid, &batch);
+  test::AddCopy(context, keys, nullptr, &batch);
+  test::AddCopy(context, groups, nullptr, &batch);
+  batch.SetRowCount(static_cast<uint32_t>(ts.size()));
+  return batch;
+}
+
+IntervalLaneSpec Spec() {
+  IntervalLaneSpec spec;
+  spec.ts_column = 0;
+  spec.dur_column = 1;
+  spec.key_columns = {2};
+  spec.group_column = 3;
+  return spec;
+}
+
+TEST(LaneBatchTest, ReadsEachKindOfRow) {
+  IntervalLaneSpec spec = Spec();
+  RowBatch batch =
+      Batch({10, 0, 5, 10, std::numeric_limits<int64_t>::max()},
+            {5, 0, kNull, -1, 1}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0});
+  IntervalInputName name{"OP", "operand", 2};
+  LaneBatch lanes(batch, spec);
+  int64_t start;
+  int64_t end;
+  ASSERT_EQ(lanes.Read(0, &start, &end), Result::kOk);
+  EXPECT_EQ(start, 10);
+  EXPECT_EQ(end, 15);
+  ASSERT_EQ(lanes.Read(1, &start, &end), Result::kOk);
+  EXPECT_EQ(end, 0);
+  EXPECT_EQ(lanes.Read(2, &start, &end), Result::kSkip);
+  EXPECT_EQ(lanes.Read(3, &start, &end), Result::kNegative);
+  EXPECT_THAT(lanes.Error(Result::kNegative, name).message(),
+              HasSubstr("OP: operand 2 has a row whose ts or dur"));
+  EXPECT_EQ(lanes.Read(4, &start, &end), Result::kOverflow);
+  EXPECT_THAT(lanes.Error(Result::kOverflow, name).message(),
+              HasSubstr("integer overflow"));
+
+  // With `forever`, a dur of -1 never ends.
+  spec.forever = true;
+  LaneBatch forever(batch, spec);
+  ASSERT_EQ(forever.Read(3, &start, &end), Result::kOk);
+  EXPECT_EQ(end, std::numeric_limits<int64_t>::max());
+}
+
+std::vector<uint32_t> Lanes(LaneReader& reader,
+                            const RowBatch& batch,
+                            GroupTable* shared) {
+  EXPECT_TRUE(reader.Start(batch, shared).ok());
+  LaneBatch lanes = reader.batch();
+  std::vector<uint32_t> out;
+  for (uint32_t row = 0; row < batch.size(); ++row) {
+    out.push_back(lanes.lane(row));
+  }
+  return out;
+}
+
+// Without a LaneReader, lanes are the input's group numbers. With one,
+// inputs sharing a table agree on each key's number, also for a lane spanning
+// two batches.
+TEST(LaneReaderTest, NumbersLanes) {
+  IntervalLaneSpec spec = Spec();
+  RowBatch own = Batch({0, 0}, {1, 1}, {7, 3}, {0, 1});
+  LaneBatch lanes(own, spec);
+  EXPECT_EQ(lanes.lane(0), 0u);
+  EXPECT_EQ(lanes.lane(1), 1u);
+
+  GroupTable table;
+  LaneReader a(spec, {"OP", "a"});
+  LaneReader b(spec, {"OP", "b"});
+  EXPECT_THAT(
+      Lanes(a, Batch({0, 0, 0}, {1, 1, 1}, {7, 7, 3}, {0, 0, 1}), &table),
+      ElementsAre(0, 0, 1));
+  EXPECT_THAT(Lanes(a, Batch({0, 0}, {1, 1}, {3, 9}, {1, 2}), &table),
+              ElementsAre(1, 2));
+  EXPECT_THAT(
+      Lanes(b, Batch({0, 0, 0}, {1, 1, 1}, {9, 4, 7}, {0, 1, 2}), &table),
+      ElementsAre(2, 3, 0));
+}
+
+// A lane's keys stay readable after the next batch is held if carried.
+TEST(LaneKeysTest, CarriesTheOpenLane) {
+  Context& context = test::TestContext();
+  std::vector<uint32_t> key_columns = {2};
+  LaneKeys keys(key_columns);
+  RowBatch first = Batch({0, 0}, {1, 1}, {7, 3}, {0, 1});
+  ASSERT_TRUE(keys.Hold(first).ok());
+  uint32_t open = keys.Of(1);
+  keys.Carry(open);
+  RowBatch second = Batch({0}, {1}, {9}, {2});
+  ASSERT_TRUE(keys.Hold(second).ok());
+  std::vector<uint32_t> handles = {LaneKeys::kCarried, keys.Of(0)};
+  RowBatch out;
+  keys.Gather(&out, handles, context);
+  EXPECT_THAT(test::ReadColumn<int64_t>(out, 0), ElementsAre(3, 9));
+}
+
+}  // namespace
+}  // namespace perfetto::trace_processor::core::exec
diff --git a/src/trace_processor/core/exec/pipeline_formatter.cc b/src/trace_processor/core/exec/pipeline_formatter.cc
index 965602a..7df0488 100644
--- a/src/trace_processor/core/exec/pipeline_formatter.cc
+++ b/src/trace_processor/core/exec/pipeline_formatter.cc
@@ -22,15 +22,20 @@
 #include <variant>
 #include <vector>
 
+#include "src/trace_processor/core/common/op_types.h"
 #include "src/trace_processor/core/common/storage_types.h"
 #include "src/trace_processor/core/exec/aggregate_function.h"
 #include "src/trace_processor/core/exec/assert_type.h"
 #include "src/trace_processor/core/exec/combine_batches.h"
 #include "src/trace_processor/core/exec/dataframe_scan.h"
+#include "src/trace_processor/core/exec/distinct.h"
+#include "src/trace_processor/core/exec/filter.h"
 #include "src/trace_processor/core/exec/grouped_sort.h"
 #include "src/trace_processor/core/exec/hash_aggregate.h"
+#include "src/trace_processor/core/exec/interval_fill_gaps.h"
 #include "src/trace_processor/core/exec/interval_flatten.h"
 #include "src/trace_processor/core/exec/interval_intersect.h"
+#include "src/trace_processor/core/exec/interval_lanes.h"
 #include "src/trace_processor/core/exec/operator.h"
 #include "src/trace_processor/core/exec/pipeline.h"
 #include "src/trace_processor/core/exec/sort.h"
@@ -42,6 +47,29 @@
 namespace perfetto::trace_processor::core::exec {
 namespace {
 
+std::string OpName(const Op& op) {
+  switch (op.index()) {
+    case Op::GetTypeIndex<Eq>():
+      return "=";
+    case Op::GetTypeIndex<Ne>():
+      return "!=";
+    case Op::GetTypeIndex<Lt>():
+      return "<";
+    case Op::GetTypeIndex<Le>():
+      return "<=";
+    case Op::GetTypeIndex<Gt>():
+      return ">";
+    case Op::GetTypeIndex<Ge>():
+      return ">=";
+    case Op::GetTypeIndex<IsNull>():
+      return "IS NULL";
+    case Op::GetTypeIndex<IsNotNull>():
+      return "IS NOT NULL";
+    default:
+      return "?";
+  }
+}
+
 std::string Column(uint32_t position) {
   return "#" + std::to_string(position);
 }
@@ -54,6 +82,15 @@
   return out;
 }
 
+std::string Lanes(const IntervalLaneSpec& lanes) {
+  std::string out = Column(lanes.ts_column) + ", " + Column(lanes.dur_column);
+  if (!lanes.key_columns.empty()) {
+    out += ", keys: " + Columns(lanes.key_columns) +
+           ", groups: " + Column(lanes.group_column);
+  }
+  return out;
+}
+
 std::string Keys(const std::vector<SortKey>& keys) {
   std::string out;
   for (const SortKey& key : keys) {
@@ -133,13 +170,7 @@
     const auto& isect = static_cast<const IntervalIntersect&>(source);
     std::string out = "IntervalIntersect(";
     for (size_t i = 0; i < isect.operands_.size(); ++i) {
-      const IntervalIntersectOperand& operand = isect.operands_[i];
-      out += (i == 0 ? "" : "; ") + Column(operand.ts_column) + ", " +
-             Column(operand.dur_column);
-      if (!operand.key_columns.empty()) {
-        out += ", keys: " + Columns(operand.key_columns) +
-               ", groups: " + Column(operand.group_column);
-      }
+      out += (i == 0 ? "" : "; ") + Lanes(isect.operands_[i].lanes);
     }
     return out + ")";
   }
@@ -157,6 +188,21 @@
                                                        : "String";
     return "AssertType(" + Column(assert.column_) + " to " + target + ")";
   }
+  if (transform.Is<Distinct>()) {
+    return "Distinct(" +
+           Columns(static_cast<const Distinct&>(transform).columns_) + ")";
+  }
+  if (transform.Is<Filter>()) {
+    const auto& filter = static_cast<const Filter&>(transform);
+    std::string out;
+    for (const Filter::Condition& c : filter.conditions_) {
+      out += (out.empty() ? "" : ", ") + Column(c.column) + " " + OpName(c.op);
+      if (!c.op.IsAnyOf<NullOp>()) {
+        out += " ?" + std::to_string(c.value);
+      }
+    }
+    return "Filter(" + out + ")";
+  }
   if (transform.Is<NullColumn>()) {
     const auto& null = static_cast<const NullColumn&>(transform);
     return "NullColumn(" + Column(null.column_) + " as " +
@@ -202,15 +248,16 @@
     return "HashAggregate(keys: " + Columns(spec.key_columns) + "; " +
            Aggregates(spec.aggregates) + ")";
   }
+  if (op.Is<IntervalFillGaps>()) {
+    const IntervalFillGapsSpec& spec =
+        static_cast<const IntervalFillGaps&>(op).spec_;
+    return "IntervalFillGaps(" + Lanes(spec.input) +
+           "; background: " + Lanes(spec.background.lanes) + ")";
+  }
   if (op.Is<IntervalFlatten>()) {
     const IntervalFlattenSpec& spec =
         static_cast<const IntervalFlatten&>(op).spec_;
-    std::string out = "IntervalFlatten(" + Column(spec.ts_column) + ", " +
-                      Column(spec.dur_column);
-    if (!spec.key_columns.empty()) {
-      out += ", keys: " + Columns(spec.key_columns) +
-             ", groups: " + Column(spec.group_column);
-    }
+    std::string out = "IntervalFlatten(" + Lanes(spec.lanes);
     if (!spec.aggregates.empty()) {
       out += "; " + Aggregates(spec.aggregates);
     }
diff --git a/src/trace_processor/core/exec/row_cursor.h b/src/trace_processor/core/exec/row_cursor.h
index 66b4aa8..fc2883e 100644
--- a/src/trace_processor/core/exec/row_cursor.h
+++ b/src/trace_processor/core/exec/row_cursor.h
@@ -24,8 +24,10 @@
 #include "perfetto/base/logging.h"
 #include "perfetto/base/status.h"
 #include "src/trace_processor/core/exec/context.h"
+#include "src/trace_processor/core/exec/filter_value.h"
 #include "src/trace_processor/core/exec/operator.h"
 #include "src/trace_processor/core/exec/row_batch.h"
+#include "src/trace_processor/core/util/span.h"
 
 namespace perfetto::trace_processor::core::exec {
 
@@ -41,8 +43,10 @@
   RowCursor(Source&&) = delete;
   ~RowCursor();
 
-  // Rewinds and moves to the first row.
-  bool Open() {
+  // Rewinds and moves to the first row, the run's filters comparing with
+  // `filter_values` (see Context::SetFilterValues).
+  bool Open(Span<const FilterValue> filter_values = {}) {
+    context_.SetFilterValues(filter_values);
     source_.Rewind(*state_);
     batch_ = nullptr;
     index_ = 0;
diff --git a/src/trace_processor/core/exec/row_store.cc b/src/trace_processor/core/exec/row_store.cc
index 5bc92b5..2a6facc 100644
--- a/src/trace_processor/core/exec/row_store.cc
+++ b/src/trace_processor/core/exec/row_store.cc
@@ -50,7 +50,8 @@
     PERFETTO_DCHECK(first.column_count() == in.column_count());
 #if PERFETTO_DCHECK_IS_ON()
     for (uint32_t c = 0; c < in.column_count(); ++c) {
-      PERFETTO_DCHECK(SameLogicalType(first.column(c), in.column(c)));
+      PERFETTO_DCHECK(SameLogicalType(ColumnShape::Of(first.column(c)),
+                                      ColumnShape::Of(in.column(c))));
     }
 #endif
   } else {
@@ -100,9 +101,9 @@
   return count;
 }
 
-uint32_t RowStore::View(RowBatch* out,
-                        Span<const uint32_t> rows,
-                        Context& context) {
+uint32_t RowStore::Gather(RowBatch* out,
+                          Span<const uint32_t> rows,
+                          Context& context) {
   out->Reset();
   auto count =
       static_cast<uint32_t>(std::min<size_t>(rows.size(), kMaxBatchRows));
diff --git a/src/trace_processor/core/exec/row_store.h b/src/trace_processor/core/exec/row_store.h
index 6b45c3e..af8a2a3 100644
--- a/src/trace_processor/core/exec/row_store.h
+++ b/src/trace_processor/core/exec/row_store.h
@@ -52,7 +52,7 @@
 
   // Copies up to kMaxBatchRows of `rows`, in that order and repeats included,
   // into buffers taken from `context`. Returns how many.
-  uint32_t View(RowBatch* out, Span<const uint32_t> rows, Context& context);
+  uint32_t Gather(RowBatch* out, Span<const uint32_t> rows, Context& context);
 
   // Lets go of every row held.
   void Clear();
diff --git a/src/trace_processor/core/exec/row_store_benchmark.cc b/src/trace_processor/core/exec/row_store_benchmark.cc
index 9b45f52..aa44477 100644
--- a/src/trace_processor/core/exec/row_store_benchmark.cc
+++ b/src/trace_processor/core/exec/row_store_benchmark.cc
@@ -66,7 +66,7 @@
     for (uint32_t at = 0; at < rows; at += kMaxBatchRows) {
       const uint32_t* begin = order.data() + at;
       uint32_t count = std::min(kMaxBatchRows, rows - at);
-      store.View(&out, Span<const uint32_t>(begin, begin + count), context);
+      store.Gather(&out, Span<const uint32_t>(begin, begin + count), context);
       benchmark::DoNotOptimize(out.size());
     }
     store.Clear();
diff --git a/src/trace_processor/core/exec/row_store_unittest.cc b/src/trace_processor/core/exec/row_store_unittest.cc
index 9f56a63..46738ab 100644
--- a/src/trace_processor/core/exec/row_store_unittest.cc
+++ b/src/trace_processor/core/exec/row_store_unittest.cc
@@ -61,7 +61,7 @@
 
 // Gathers `rows` of the store.
 uint32_t Gather(RowStore& store, RowBatch* out, std::vector<uint32_t> rows) {
-  return store.View(
+  return store.Gather(
       out, Span<const uint32_t>(rows.data(), rows.data() + rows.size()),
       test::TestContext());
 }
diff --git a/src/trace_processor/core/exec/selection.h b/src/trace_processor/core/exec/selection.h
index 7b0e4bb..32b440a 100644
--- a/src/trace_processor/core/exec/selection.h
+++ b/src/trace_processor/core/exec/selection.h
@@ -85,6 +85,28 @@
     prefix_ = false;
   }
 
+  // Keeps the batch rows `rows`, which are increasing and all kept already.
+  void KeepRows(Span<const uint32_t> rows) {
+    auto count = static_cast<uint32_t>(rows.size());
+    PERFETTO_DCHECK(count <= size_);
+    if (count == size_) {
+      // Kept already, they can only be every row kept.
+      return;
+    }
+    size_ = count;
+    if (count == 0 || rows.b[count - 1] == count - 1) {
+      // Increasing and ending at count - 1, they are the first `count`.
+      prefix_ = true;
+      return;
+    }
+    for (uint32_t i = 0; i < count; ++i) {
+      PERFETTO_DCHECK(rows.b[i] < rows_ &&
+                      (i == 0 || rows.b[i - 1] < rows.b[i]));
+      indices_[i] = static_cast<uint16_t>(rows.b[i]);
+    }
+    prefix_ = false;
+  }
+
   // Keeps `count` of the rows kept, from the `first`.
   void KeepRange(uint32_t first, uint32_t count) {
     PERFETTO_DCHECK(first + count <= size_);
diff --git a/src/trace_processor/core/exec/sort.cc b/src/trace_processor/core/exec/sort.cc
index 13b1bfd..7f81a2a 100644
--- a/src/trace_processor/core/exec/sort.cc
+++ b/src/trace_processor/core/exec/sort.cc
@@ -53,7 +53,7 @@
   if (s.emitted == s.rows.size()) {
     return false;
   }
-  s.emitted += s.rows.View(&out, s.emitted, *s.context);
+  s.emitted += s.rows.Gather(&out, s.emitted, *s.context);
   return true;
 }
 
diff --git a/src/trace_processor/core/exec/sorted_rows.cc b/src/trace_processor/core/exec/sorted_rows.cc
index 3739072..7e50829 100644
--- a/src/trace_processor/core/exec/sorted_rows.cc
+++ b/src/trace_processor/core/exec/sorted_rows.cc
@@ -143,10 +143,10 @@
   }
 }
 
-uint32_t SortedRows::View(RowBatch* out, uint32_t at, Context& context) {
+uint32_t SortedRows::Gather(RowBatch* out, uint32_t at, Context& context) {
   uint32_t count = std::min(kMaxBatchRows, rows_.size() - at);
   const uint32_t* begin = order_.data() + at;
-  return rows_.View(out, Span<const uint32_t>(begin, begin + count), context);
+  return rows_.Gather(out, Span<const uint32_t>(begin, begin + count), context);
 }
 
 void SortedRows::Clear() {
diff --git a/src/trace_processor/core/exec/sorted_rows.h b/src/trace_processor/core/exec/sorted_rows.h
index eaa01ea..60227df 100644
--- a/src/trace_processor/core/exec/sorted_rows.h
+++ b/src/trace_processor/core/exec/sorted_rows.h
@@ -58,7 +58,7 @@
 
   // Copies up to kMaxBatchRows rows into `out`, starting at position `at` in
   // the order. Returns the number of rows copied.
-  uint32_t View(RowBatch* out, uint32_t at, Context& context);
+  uint32_t Gather(RowBatch* out, uint32_t at, Context& context);
   void Clear();
 
  private:
diff --git a/src/trace_processor/core/exec/tree_order.cc b/src/trace_processor/core/exec/tree_order.cc
index 8fe1702..1921a55 100644
--- a/src/trace_processor/core/exec/tree_order.cc
+++ b/src/trace_processor/core/exec/tree_order.cc
@@ -188,8 +188,8 @@
     count = s.rows.View(&out, s.emitted, count);
   } else {
     const uint32_t* begin = s.order.data() + s.emitted;
-    count = s.rows.View(&out, Span<const uint32_t>(begin, begin + count),
-                        *s.context);
+    count = s.rows.Gather(&out, Span<const uint32_t>(begin, begin + count),
+                          *s.context);
   }
   s.emitted += count;
   return true;
@@ -264,8 +264,8 @@
   auto total = static_cast<uint32_t>(s.letting_go.size());
   uint32_t count = std::min(kMaxBatchRows, total - s.served);
   const uint32_t* begin = s.letting_go.data() + s.served;
-  count = s.held.rows.View(&out, Span<const uint32_t>(begin, begin + count),
-                           *s.context);
+  count = s.held.rows.Gather(&out, Span<const uint32_t>(begin, begin + count),
+                             *s.context);
   s.served += count;
   if (s.served < total) {
     return OpResult::kHaveMoreOutput;
diff --git a/src/trace_processor/core/interpreter/bytecode_interpreter_impl.cc b/src/trace_processor/core/interpreter/bytecode_interpreter_impl.cc
index 3af97bc..ca82573 100644
--- a/src/trace_processor/core/interpreter/bytecode_interpreter_impl.cc
+++ b/src/trace_processor/core/interpreter/bytecode_interpreter_impl.cc
@@ -151,12 +151,8 @@
       state.ReadFromRegister(bytecode.arg<B::source_range_register>());
   auto& update = state.ReadFromRegister(bytecode.arg<B::update_register>());
   PERFETTO_DCHECK(source.size() <= update.size());
-  uint32_t* write_ptr = update.b;
-  for (const uint32_t* it = source.b; it != source.e; ++it) {
-    *write_ptr = *it;
-    write_ptr += (*it >= source_range.b && *it < source_range.e);
-  }
-  update.e = write_ptr;
+  update.e = filter::CopySpanIntersectingRange(
+      Span<const uint32_t>(source.b, source.e), source_range, update.b);
 }
 
 void InitRankMap(InterpreterState& state, const struct InitRankMap& bytecode) {
diff --git a/src/trace_processor/core/interpreter/bytecode_interpreter_impl.h b/src/trace_processor/core/interpreter/bytecode_interpreter_impl.h
index 642995b..d8e5347 100644
--- a/src/trace_processor/core/interpreter/bytecode_interpreter_impl.h
+++ b/src/trace_processor/core/interpreter/bytecode_interpreter_impl.h
@@ -219,56 +219,17 @@
   update.e = nbv.bv->template PackLeft<kInvert>(update.b, update.e, update.b);
 }
 
-// Attempts to cast a filter value to the specified type and stores the
-// result. Currently only supports casting to Id type.
+// Casts a filter value to the column's type and stores the result.
 template <typename T, typename FilterValueFetcherImpl>
 inline PERFETTO_ALWAYS_INLINE void CastFilterValue(
     InterpreterState& state,
     FilterValueFetcherImpl& fetcher,
     const CastFilterValueBase& f) {
   using B = CastFilterValueBase;
-  FilterValueHandle handle = f.arg<B::fval_handle>();
-  typename FilterValueFetcherImpl::Type filter_value_type =
-      fetcher.GetValueType(handle.index);
-
-  using ValueType =
-      StorageType::VariantTypeAtIndex<T, filter::CastFilterValueResult::Value>;
-  filter::CastFilterValueResult result;
-  if constexpr (std::is_same_v<T, Id>) {
-    auto op = *f.arg<B::op>().TryDowncast<NonStringOp>();
-    uint32_t result_value;
-    result.validity =
-        filter::CastFilterValueToInteger<uint32_t, FilterValueFetcherImpl>(
-            handle.index, filter_value_type, fetcher, op, result_value);
-    if (PERFETTO_LIKELY(result.validity ==
-                        filter::CastFilterValueResult::kValid)) {
-      result.value = filter::CastFilterValueResult::Id{result_value};
-    }
-  } else if constexpr (IntegerOrDoubleType::Contains<T>()) {
-    auto op = *f.arg<B::op>().TryDowncast<NonStringOp>();
-    ValueType result_value;
-    result.validity =
-        filter::CastFilterValueToIntegerOrDouble<ValueType,
-                                                 FilterValueFetcherImpl>(
-            handle.index, filter_value_type, fetcher, op, result_value);
-    if (PERFETTO_LIKELY(result.validity ==
-                        filter::CastFilterValueResult::kValid)) {
-      result.value = result_value;
-    }
-  } else if constexpr (std::is_same_v<T, String>) {
-    static_assert(std::is_same_v<ValueType, const char*>);
-    auto op = *f.arg<B::op>().TryDowncast<StringOp>();
-    const char* result_value;
-    result.validity = filter::CastFilterValueToString<FilterValueFetcherImpl>(
-        handle.index, filter_value_type, fetcher, op, result_value);
-    if (PERFETTO_LIKELY(result.validity ==
-                        filter::CastFilterValueResult::kValid)) {
-      result.value = result_value;
-    }
-  } else {
-    static_assert(std::is_same_v<T, Id>, "Unsupported type");
-  }
-  state.WriteToRegister(f.arg<B::write_register>(), result);
+  state.WriteToRegister(
+      f.arg<B::write_register>(),
+      filter::CastFilterValue<T>(f.arg<B::fval_handle>().index, fetcher,
+                                 f.arg<B::op>()));
 }
 
 template <typename T, typename Op>
@@ -339,24 +300,6 @@
                                 update.b, val);
 }
 
-template <typename DataType>
-inline auto GetLbComprarator(const InterpreterState& state) {
-  if constexpr (std::is_same_v<DataType, StringPool::Id>) {
-    return filter::comparators::StringComparator<Lt>{state.string_pool};
-  } else {
-    return std::less<>();
-  }
-}
-
-template <typename DataType>
-inline auto GetUbComparator(const InterpreterState& state) {
-  if constexpr (std::is_same_v<DataType, StringPool::Id>) {
-    return filter::comparators::StringLessInvert{state.string_pool};
-  } else {
-    return std::less<>();
-  }
-}
-
 template <typename RangeOp, typename DataType, typename ValueType>
 inline PERFETTO_ALWAYS_INLINE void NonIdSortedFilter(
     const InterpreterState& state,
@@ -364,54 +307,15 @@
     ValueType val,
     BoundModifier bound_modifier,
     Range& update) {
-  auto* begin = data + update.b;
-  auto* end = data + update.e;
   if constexpr (std::is_same_v<RangeOp, EqualRange>) {
     PERFETTO_DCHECK(bound_modifier.Is<BothBounds>());
-    DataType cmp_value;
-    if constexpr (std::is_same_v<DataType, StringPool::Id>) {
-      std::optional<StringPool::Id> id =
-          state.string_pool->GetId(base::StringView(val));
-      if (!id) {
-        update.e = update.b;
-        return;
-      }
-      cmp_value = *id;
-    } else {
-      cmp_value = val;
-    }
-    const DataType* eq_start =
-        std::lower_bound(begin, end, val, GetLbComprarator<DataType>(state));
-    const DataType* eq_end = eq_start;
-
-    // Scan 16 rows: it's often the case that we have just a very small number
-    // of equal rows, so we can avoid a binary search.
-    const DataType* eq_end_limit = eq_start + 16;
-    for (;; ++eq_end) {
-      if (eq_end == end) {
-        break;
-      }
-      if (eq_end == eq_end_limit) {
-        eq_end = std::upper_bound(eq_start, end, val,
-                                  GetUbComparator<DataType>(state));
-        break;
-      }
-      if (std::not_equal_to<>()(*eq_end, cmp_value)) {
-        break;
-      }
-    }
-    update.b = static_cast<uint32_t>(eq_start - data);
-    update.e = static_cast<uint32_t>(eq_end - data);
+    filter::SortedEqualRange(data, val, state.string_pool, update);
   } else if constexpr (std::is_same_v<RangeOp, LowerBound>) {
     auto& res = bound_modifier.Is<BeginBound>() ? update.b : update.e;
-    res = static_cast<uint32_t>(
-        std::lower_bound(begin, end, val, GetLbComprarator<DataType>(state)) -
-        data);
+    res = filter::SortedLowerBound(data, val, state.string_pool, update);
   } else if constexpr (std::is_same_v<RangeOp, UpperBound>) {
     auto& res = bound_modifier.Is<BeginBound>() ? update.b : update.e;
-    res = static_cast<uint32_t>(
-        std::upper_bound(begin, end, val, GetUbComparator<DataType>(state)) -
-        data);
+    res = filter::SortedUpperBound(data, val, state.string_pool, update);
   } else {
     static_assert(std::is_same_v<RangeOp, EqualRange>, "Unsupported op");
   }
@@ -437,23 +341,12 @@
   if constexpr (std::is_same_v<T, Id>) {
     uint32_t inner_val = val.value;
     if constexpr (std::is_same_v<RangeOp, EqualRange>) {
-      bool in_bounds = inner_val >= update.b && inner_val < update.e;
-      update.b = inner_val;
-      update.e = inner_val + in_bounds;
+      filter::IdEqualRange(inner_val, update);
     } else if constexpr (std::is_same_v<RangeOp, LowerBound> ||
                          std::is_same_v<RangeOp, UpperBound>) {
       BoundModifier bound_to_modify = f.template arg<B::write_result_to>();
-
-      uint32_t effective_val = inner_val + std::is_same_v<RangeOp, UpperBound>;
-      bool is_begin_bound = bound_to_modify.template Is<BeginBound>();
-
-      uint32_t new_b =
-          is_begin_bound ? std::max(update.b, effective_val) : update.b;
-      uint32_t new_e =
-          !is_begin_bound ? std::min(update.e, effective_val) : update.e;
-
-      update.b = new_b;
-      update.e = std::max(new_b, new_e);
+      filter::IdBound(inner_val + std::is_same_v<RangeOp, UpperBound>,
+                      bound_to_modify.template Is<BeginBound>(), update);
     } else {
       static_assert(std::is_same_v<RangeOp, EqualRange>, "Unsupported op");
     }
@@ -516,65 +409,12 @@
   span.e = o_write;
 }
 
-template <typename N>
-inline PERFETTO_ALWAYS_INLINE uint32_t
-IndexToStorageIndex(uint32_t index, const NullBitvector* nbv) {
-  if constexpr (std::is_same_v<N, NonNull>) {
-    base::ignore_result(nbv);
-    return index;
-  } else if constexpr (std::is_same_v<N, SparseNull>) {
-    if (!nbv->bv->is_set(index)) {
-      // Null values are always less than non-null values.
-      return std::numeric_limits<uint32_t>::max();
-    }
-    return static_cast<uint32_t>(nbv->popcount[index / 64] +
-                                 nbv->bv->count_set_bits_until_in_word(index));
-  } else if constexpr (std::is_same_v<N, DenseNull>) {
-    return nbv->bv->is_set(index) ? index
-                                  : std::numeric_limits<uint32_t>::max();
-  } else {
-    static_assert(std::is_same_v<N, NonNull>, "Unsupported type");
-  }
-}
-
-// Binary-searches a sorted index for all entries whose resolved storage
-// value equals |target|. Returns the [lb, ub) range of matching index
-// entries.
-//
-// |target| should be a NullTermStringView for String columns (i.e. a
-// pre-resolved string_pool->Get result) or the raw value for other types.
-// This avoids repeated string_pool->Get calls inside the comparators.
-template <typename T, typename N, typename Resolved>
-inline PERFETTO_ALWAYS_INLINE std::pair<uint32_t*, uint32_t*> IndexEqualRange(
-    uint32_t* begin,
-    uint32_t* end,
-    const Resolved& target,
-    const typename T::cpp_type* data,
-    const NullBitvector* nbv,
-    const StringPool* string_pool) {
-  auto* lb =
-      std::lower_bound(begin, end, target, [&](uint32_t idx, const Resolved&) {
-        uint32_t si = IndexToStorageIndex<N>(idx, nbv);
-        if (si == std::numeric_limits<uint32_t>::max())
-          return true;
-        if constexpr (std::is_same_v<T, String>) {
-          return string_pool->Get(data[si]) < target;
-        } else {
-          return data[si] < target;
-        }
-      });
-  auto* ub =
-      std::upper_bound(lb, end, target, [&](const Resolved&, uint32_t idx) {
-        uint32_t si = IndexToStorageIndex<N>(idx, nbv);
-        if (si == std::numeric_limits<uint32_t>::max())
-          return false;
-        if constexpr (std::is_same_v<T, String>) {
-          return target < string_pool->Get(data[si]);
-        } else {
-          return target < data[si];
-        }
-      });
-  return {lb, ub};
+// The null bitvector and popcount an index search reads, or nulls for a
+// column without one.
+inline std::pair<const BitVector*, const uint32_t*> NullsFor(
+    const NullBitvector* nbv) {
+  return nbv ? std::make_pair(nbv->bv, nbv->popcount.data())
+             : std::make_pair(nullptr, nullptr);
 }
 
 template <typename T, typename N>
@@ -599,8 +439,9 @@
   const NullBitvector* nbv =
       state.MaybeReadFromRegister(bytecode.arg<B::null_bv_register>());
 
-  std::tie(dest.b, dest.e) = IndexEqualRange<T, N>(
-      source.b, source.e, value, data, nbv, state.string_pool);
+  auto [bv, popcount] = NullsFor(nbv);
+  std::tie(dest.b, dest.e) = filter::IndexEqualRange<T, N>(
+      source.b, source.e, value, data, bv, popcount, state.string_pool);
   state.WriteToRegister(bytecode.arg<B::dest_register>(), dest);
 }
 
@@ -656,9 +497,6 @@
 // searches the sorted index for each value and populates dest. Returns
 // true if binary search was performed, false if the caller should use
 // a different strategy.
-//
-// TODO(lalitm): since the index is sorted, galloping search could replace
-// repeated std::lower_bound for better locality.
 template <typename T, typename N>
 inline PERFETTO_ALWAYS_INLINE bool TryIndexedFilterInBinarySearch(
     InterpreterState& state,
@@ -677,42 +515,12 @@
       return false;
     }
 
-    using VL = StorageType::VariantTypeAtIndex<
-        T, filter::CastFilterValueListResult::ValueList>;
-    const VL& vl = base::unchecked_get<VL>(cast_result.value_list);
-    if (vl.empty() ||
-        vl.size() > filter::kFilterInIndexedBinarySearchThreshold) {
-      return false;
-    }
-
     const auto* data =
         state.ReadStorageFromRegister<T>(bytecode.arg<B::storage_register>());
-    const NullBitvector* nbv =
-        state.MaybeReadFromRegister(bytecode.arg<B::null_bv_register>());
-    const StringPool* string_pool = state.string_pool;
-
-    uint32_t* write = dest.b;
-    for (const auto& cmp_val : vl) {
-      // For String columns, resolve StringPool::Id to NullTermStringView
-      // once per value to avoid repeated lookups in the comparators.
-      std::pair<uint32_t*, uint32_t*> range;
-      if constexpr (std::is_same_v<T, String>) {
-        auto target = string_pool->Get(cmp_val);
-        range = IndexEqualRange<T, N>(index->b, index->e, target, data, nbv,
-                                      string_pool);
-      } else {
-        range = IndexEqualRange<T, N>(index->b, index->e, cmp_val, data, nbv,
-                                      string_pool);
-      }
-      auto n = static_cast<size_t>(range.second - range.first);
-      memcpy(write, range.first, n * sizeof(uint32_t));
-      write += n;
-    }
-    dest.e = write;
-
-    // Binary search produces output in key order. Sort by raw index.
-    std::sort(dest.b, dest.e);
-    return true;
+    auto [bv, popcount] = NullsFor(
+        state.MaybeReadFromRegister(bytecode.arg<B::null_bv_register>()));
+    return filter::IndexedFilterInBinarySearch<T, N>(
+        cast_result, *index, data, bv, popcount, state.string_pool, dest);
   }
 }
 
@@ -727,35 +535,13 @@
     const filter::CastFilterValueListResult& cast_result,
     Span<uint32_t>& dest) {
   using B = FilterInBase;
-  using HM = StorageType::VariantTypeAtIndex<
-      T, filter::CastFilterValueListResult::ValueHashMap>;
   const auto* data =
       state.ReadStorageFromRegister<T>(bytecode.arg<B::storage_register>());
-  // |data| is unused for Id columns (the storage index IS the value).
-  base::ignore_result(data);
-  const NullBitvector* nbv =
-      state.MaybeReadFromRegister(bytecode.arg<B::null_bv_register>());
-  const auto& hm = base::unchecked_get<HM>(cast_result.hash_map);
+  auto [bv, popcount] = NullsFor(
+      state.MaybeReadFromRegister(bytecode.arg<B::null_bv_register>()));
   const Range& range =
       state.ReadFromRegister(bytecode.arg<B::source_range_register>());
-
-  uint32_t* write = dest.b;
-  for (uint32_t i = range.b; i < range.e; ++i) {
-    uint32_t si = IndexToStorageIndex<N>(i, nbv);
-    if (si == std::numeric_limits<uint32_t>::max()) {
-      continue;
-    }
-    if constexpr (std::is_same_v<T, Id>) {
-      if (hm.Find(filter::CastFilterValueResult::Id{si}) != nullptr) {
-        *write++ = i;
-      }
-    } else {
-      if (hm.Find(data[si]) != nullptr) {
-        *write++ = i;
-      }
-    }
-  }
-  dest.e = write;
+  filter::FilterInRangeScan<T, N>(cast_result, range, data, bv, popcount, dest);
 }
 
 // Unified filter-in bytecode entry point.
@@ -815,17 +601,7 @@
   auto val = base::unchecked_get<ValueType>(cast_result.value);
   const auto* storage = state.ReadStorageFromRegister<Uint32>(
       bytecode.arg<B::storage_register>());
-  const auto* start =
-      std::clamp(storage + val, storage + update.b, storage + update.e);
-
-  update.b = static_cast<uint32_t>(start - storage);
-  const auto* it = start;
-  for (; it != storage + update.e; ++it) {
-    if (*it != val) {
-      break;
-    }
-  }
-  update.e = static_cast<uint32_t>(it - storage);
+  filter::SetIdSortedEqualRange(storage, val, update);
 }
 
 inline PERFETTO_ALWAYS_INLINE void SpecializedStorageSmallValueEq(
@@ -848,14 +624,7 @@
   const Span<const uint32_t>& popcount =
       state.ReadFromRegister(bytecode.arg<B::small_value_popcount_register>());
 
-  uint32_t k =
-      val < bv->size() && bv->is_set(val)
-          ? static_cast<uint32_t>(popcount.b[val / 64] +
-                                  bv->count_set_bits_until_in_word(val))
-          : update.e;
-  bool in_bounds = update.b <= k && k < update.e;
-  update.b = in_bounds ? k : update.e;
-  update.e = in_bounds ? k + 1 : update.b;
+  filter::SmallValueEqualRange(*bv, popcount.b, val, update);
 }
 
 template <typename T, typename Nullability>
diff --git a/src/trace_processor/core/util/BUILD.gn b/src/trace_processor/core/util/BUILD.gn
index cd0adfd..5b0245b 100644
--- a/src/trace_processor/core/util/BUILD.gn
+++ b/src/trace_processor/core/util/BUILD.gn
@@ -19,6 +19,7 @@
     "bit_vector.h",
     "flex_vector.h",
     "heap.h",
+    "interval_gaps.h",
     "ops.cc",
     "ops.h",
     "range.h",
@@ -40,6 +41,7 @@
     "bit_vector_unittest.cc",
     "flex_vector_unittest.cc",
     "heap_unittest.cc",
+    "interval_gaps_unittest.cc",
     "ops_unittest.cc",
     "slab_unittest.cc",
     "sort_unittest.cc",
diff --git a/src/trace_processor/core/util/interval_gaps.h b/src/trace_processor/core/util/interval_gaps.h
new file mode 100644
index 0000000..d50fca4
--- /dev/null
+++ b/src/trace_processor/core/util/interval_gaps.h
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2026 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.
+ */
+
+#ifndef SRC_TRACE_PROCESSOR_CORE_UTIL_INTERVAL_GAPS_H_
+#define SRC_TRACE_PROCESSOR_CORE_UTIL_INTERVAL_GAPS_H_
+
+#include <algorithm>
+#include <cstdint>
+#include <limits>
+#include <vector>
+
+#include "perfetto/base/logging.h"
+#include "src/trace_processor/containers/interval_tree.h"
+#include "src/trace_processor/core/util/span.h"
+
+namespace perfetto::trace_processor::core {
+
+// Finds the parts of each lane's background that the lane's covering
+// intervals leave uncovered. A lane's covering intervals arrive sorted by
+// start, so each gap is found as soon as an interval starts beyond all
+// earlier ones.
+class IntervalGaps {
+ public:
+  // An uncovered part of background interval `id`, in lane `lane`.
+  struct Gap {
+    Ts start;
+    Ts end;
+    uint32_t id;
+    uint32_t lane;
+  };
+
+  // Starts lane `lane`, whose background is sorted by start, with no two
+  // intervals of width overlapping. Ends the current lane first.
+  void StartLane(uint32_t lane, Span<const Interval> background) {
+    EndLane();
+    in_lane_ = true;
+    lane_ = lane;
+    covered_ = 0;
+    next_ = background.b;
+    end_ = background.e;
+  }
+
+  // Covers [start, end) in the current lane. Starts must not decrease.
+  void Cover(Ts start, Ts end) {
+    PERFETTO_DCHECK(in_lane_);
+    if (start == end) {
+      return;
+    }
+    FillTo(start);
+    covered_ = std::max(covered_, end);
+  }
+
+  // Ends the current lane, if any. The rest of its background is a gap.
+  void EndLane() {
+    if (in_lane_) {
+      FillTo(std::numeric_limits<Ts>::max());
+      in_lane_ = false;
+    }
+  }
+
+  // Changes the number the current lane's later gaps are given.
+  void set_lane(uint32_t lane) { lane_ = lane; }
+
+  void Clear() {
+    in_lane_ = false;
+    gaps_.clear();
+  }
+
+  bool in_lane() const { return in_lane_; }
+
+  // The gaps found, in the order found. The caller removes those it uses.
+  std::vector<Gap>& gaps() { return gaps_; }
+
+ private:
+  // Adds the gaps before `to`. Everything between `covered_` and `to` is
+  // uncovered, since covering intervals arrive sorted by start.
+  void FillTo(Ts to) {
+    for (; next_ != end_; ++next_) {
+      if (next_->start >= to) {
+        return;
+      }
+      Ts start = std::max(next_->start, covered_);
+      Ts end = std::min(next_->end, to);
+      if (start < end) {
+        gaps_.push_back({start, end, next_->id, lane_});
+      }
+      if (next_->end > to) {
+        return;
+      }
+    }
+  }
+
+  bool in_lane_ = false;
+  uint32_t lane_ = 0;
+  // The end of the current lane's covering intervals so far.
+  Ts covered_ = 0;
+  // The current lane's background not yet passed.
+  const Interval* next_ = nullptr;
+  const Interval* end_ = nullptr;
+  std::vector<Gap> gaps_;
+};
+
+}  // namespace perfetto::trace_processor::core
+
+#endif  // SRC_TRACE_PROCESSOR_CORE_UTIL_INTERVAL_GAPS_H_
diff --git a/src/trace_processor/core/util/interval_gaps_unittest.cc b/src/trace_processor/core/util/interval_gaps_unittest.cc
new file mode 100644
index 0000000..03e277d
--- /dev/null
+++ b/src/trace_processor/core/util/interval_gaps_unittest.cc
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2026 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.
+ */
+
+#include "src/trace_processor/core/util/interval_gaps.h"
+
+#include <cstdint>
+#include <limits>
+#include <tuple>
+#include <vector>
+
+#include "test/gtest_and_gmock.h"
+
+namespace perfetto::trace_processor::core {
+namespace {
+
+using testing::ElementsAre;
+using testing::IsEmpty;
+
+constexpr Ts kForever = std::numeric_limits<int64_t>::max();
+
+// Each gap as (start, end, id, lane), and clears them.
+std::vector<std::tuple<Ts, Ts, uint32_t, uint32_t>> Take(IntervalGaps& gaps) {
+  std::vector<std::tuple<Ts, Ts, uint32_t, uint32_t>> out;
+  for (const IntervalGaps::Gap& gap : gaps.gaps()) {
+    out.emplace_back(gap.start, gap.end, gap.id, gap.lane);
+  }
+  gaps.gaps().clear();
+  return out;
+}
+
+TEST(IntervalGapsTest, FillsAroundCoveringIntervals) {
+  std::vector<Interval> background = {{0, 100, 7}};
+  IntervalGaps gaps;
+  gaps.StartLane(0, background);
+  gaps.Cover(10, 20);
+  gaps.Cover(50, 60);
+  gaps.EndLane();
+  EXPECT_THAT(Take(gaps),
+              ElementsAre(std::make_tuple(Ts{0}, Ts{10}, 7u, 0u),
+                          std::make_tuple(Ts{20}, Ts{50}, 7u, 0u),
+                          std::make_tuple(Ts{60}, Ts{100}, 7u, 0u)));
+}
+
+// Overlapping and nested covering intervals leave no gap between them.
+TEST(IntervalGapsTest, OverlappingCoverLeavesNoGap) {
+  std::vector<Interval> background = {{0, 100, 0}};
+  IntervalGaps gaps;
+  gaps.StartLane(0, background);
+  gaps.Cover(10, 40);
+  gaps.Cover(15, 20);
+  gaps.Cover(30, 50);
+  gaps.EndLane();
+  EXPECT_THAT(Take(gaps),
+              ElementsAre(std::make_tuple(Ts{0}, Ts{10}, 0u, 0u),
+                          std::make_tuple(Ts{50}, Ts{100}, 0u, 0u)));
+}
+
+// A gap never crosses from one background interval into the next.
+TEST(IntervalGapsTest, GapsStayWithinBackgroundIntervals) {
+  std::vector<Interval> background = {{0, 10, 0}, {20, 30, 1}, {40, 50, 2}};
+  IntervalGaps gaps;
+  gaps.StartLane(0, background);
+  gaps.Cover(5, 25);
+  gaps.EndLane();
+  EXPECT_THAT(Take(gaps), ElementsAre(std::make_tuple(Ts{0}, Ts{5}, 0u, 0u),
+                                      std::make_tuple(Ts{25}, Ts{30}, 1u, 0u),
+                                      std::make_tuple(Ts{40}, Ts{50}, 2u, 0u)));
+}
+
+// A zero-width interval covers nothing, and one which never ends covers the
+// rest of the lane.
+TEST(IntervalGapsTest, PointsAndForever) {
+  std::vector<Interval> background = {{0, 100, 0}};
+  IntervalGaps gaps;
+  gaps.StartLane(0, background);
+  gaps.Cover(30, 30);
+  gaps.Cover(60, kForever);
+  gaps.EndLane();
+  EXPECT_THAT(Take(gaps), ElementsAre(std::make_tuple(Ts{0}, Ts{60}, 0u, 0u)));
+}
+
+// Starting a lane ends the previous one, and a lane with no covering
+// intervals is one gap.
+TEST(IntervalGapsTest, LanesAreIndependent) {
+  std::vector<Interval> first = {{0, 10, 0}};
+  std::vector<Interval> second = {{5, 15, 1}};
+  IntervalGaps gaps;
+  gaps.StartLane(3, first);
+  gaps.Cover(0, 4);
+  gaps.StartLane(4, second);
+  gaps.EndLane();
+  gaps.StartLane(5, {});
+  gaps.Cover(0, 10);
+  gaps.EndLane();
+  EXPECT_THAT(Take(gaps), ElementsAre(std::make_tuple(Ts{4}, Ts{10}, 0u, 3u),
+                                      std::make_tuple(Ts{5}, Ts{15}, 1u, 4u)));
+  EXPECT_THAT(Take(gaps), IsEmpty());
+}
+
+}  // namespace
+}  // namespace perfetto::trace_processor::core
diff --git a/src/trace_processor/importers/proto/track_event_tokenizer.cc b/src/trace_processor/importers/proto/track_event_tokenizer.cc
index 020ef8a..00b7fce 100644
--- a/src/trace_processor/importers/proto/track_event_tokenizer.cc
+++ b/src/trace_processor/importers/proto/track_event_tokenizer.cc
@@ -15,6 +15,7 @@
  */
 
 #include "src/trace_processor/importers/proto/track_event_tokenizer.h"
+#include "src/trace_processor/util/cold_sort.h"
 
 #include <cstddef>
 #include <cstdint>
@@ -23,6 +24,7 @@
 #include <string>
 #include <string_view>
 #include <utility>
+#include <vector>
 
 #include "perfetto/base/compiler.h"
 #include "perfetto/base/status.h"
@@ -64,6 +66,7 @@
 #include "protos/perfetto/trace/track_event/range_of_interest.pbzero.h"
 #include "protos/perfetto/trace/track_event/thread_descriptor.pbzero.h"
 #include "protos/perfetto/trace/track_event/track_descriptor.pbzero.h"
+#include "protos/perfetto/trace/track_event/track_dimension.pbzero.h"
 #include "protos/perfetto/trace/track_event/track_event.pbzero.h"
 
 namespace perfetto::trace_processor {
@@ -86,6 +89,112 @@
               "mask must fit one presence word");
 using protos::pbzero::CounterDescriptor;
 
+// Dimensions which trace processor recognizes and synthesizes itself, and
+// whose canonical value means the same thing across data sources. Producers
+// cannot declare a custom dimension with one of these names. Keep in sync with
+// the list of reserved names documented in track_dimension.proto.
+bool IsWellKnownDimensionName(base::StringView name) {
+  return name == "machine" || name == "gpu" || name == "cpu" ||
+         name == "process" || name == "thread";
+}
+
+// Parses `TrackDescriptor.dimensions` into |reservation|. Dimensions without a
+// name or value, or with a reserved (well known) name, are dropped and their
+// errors appended to |errors|. Returns false if a name or value iid is not in
+// the interned data of the sequence (e.g. because that data was lost): the
+// whole descriptor must then be ignored rather than reserved with a partial
+// set of dimensions, which would make a later re-emission with the interned
+// data a conflicting reservation.
+bool ParseTrackDimensions(
+    TraceProcessorContext* context,
+    PacketSequenceStateGeneration* state,
+    const protos::pbzero::TrackDescriptor::Decoder& track,
+    TrackEventTracker::DescriptorTrackReservation* reservation,
+    std::vector<size_t>* errors) {
+  using Reservation = TrackEventTracker::DescriptorTrackReservation;
+  for (auto it = track.dimensions(); it; ++it) {
+    protos::pbzero::TrackDimension::Decoder dim(*it);
+
+    StringId name_id = kNullStringId;
+    base::StringView name = dim.name();
+    if (dim.has_name_iid()) {
+      std::optional<StringId> interned = state->InternedStringId(
+          protos::pbzero::InternedData::kTrackDimensionStringsFieldNumber,
+          dim.name_iid());
+      if (!interned) {
+        return false;
+      }
+      name_id = *interned;
+      name = context->storage->GetString(name_id);
+    }
+    if (name.empty()) {
+      errors->push_back(stats::track_descriptor_invalid_dimension);
+      continue;
+    }
+    if (IsWellKnownDimensionName(name)) {
+      errors->push_back(stats::track_descriptor_reserved_dimension_name);
+      continue;
+    }
+
+    Reservation::Dimension out;
+    out.name =
+        name_id.is_null() ? context->storage->InternString(name) : name_id;
+    if (dim.has_int_value()) {
+      out.int_value = dim.int_value();
+    } else if (dim.has_string_value()) {
+      out.string_value = context->storage->InternString(dim.string_value());
+    } else if (dim.has_string_value_iid()) {
+      out.string_value = state->InternedStringId(
+          protos::pbzero::InternedData::kTrackDimensionStringsFieldNumber,
+          dim.string_value_iid());
+      if (!out.string_value) {
+        return false;
+      }
+    } else {
+      errors->push_back(stats::track_descriptor_invalid_dimension);
+      continue;
+    }
+    if (dim.has_display_name()) {
+      out.display_name = context->storage->InternString(dim.display_name());
+    } else if (dim.has_display_name_iid()) {
+      // The display name only affects presentation: an unknown iid drops it
+      // but keeps the dimension.
+      out.display_name = state->InternedStringId(
+          protos::pbzero::InternedData::kTrackDimensionStringsFieldNumber,
+          dim.display_name_iid());
+      if (!out.display_name) {
+        errors->push_back(stats::track_descriptor_invalid_dimension);
+      }
+    }
+    reservation->dimensions.push_back(out);
+  }
+  if (reservation->dimensions.empty()) {
+    return true;
+  }
+
+  // Dimensions are part of the track identity, so they are normalized: sorted
+  // by name, so that the declaration order doesn't matter, and without
+  // repeated names. A name declared more than once keeps its first value.
+  auto& dims = reservation->dimensions;
+  ColdStableSortByKey(
+      dims.begin(), dims.end(),
+      [](const Reservation::Dimension& d) { return d.name.raw_id(); });
+  size_t kept = 0;
+  for (size_t i = 0; i < dims.size(); ++i) {
+    if (kept > 0 && dims[kept - 1].name == dims[i].name) {
+      if (dims[kept - 1].int_value != dims[i].int_value ||
+          dims[kept - 1].string_value != dims[i].string_value) {
+        errors->push_back(stats::track_dimension_conflicting_value);
+      }
+      continue;
+    }
+    dims[kept++] = dims[i];
+  }
+  dims.resize(kept);
+  reservation->dimensions_hash = Reservation::HashDimensions(dims);
+  return true;
+}
+
 class V8Sink : public TraceSorter::Sink<LegacyV8CpuProfileEvent, V8Sink> {
  public:
   explicit V8Sink(LegacyV8CpuProfileTracker* tracker) : tracker_(tracker) {}
@@ -253,6 +362,26 @@
         context_->storage->InternString(track.description());
   }
 
+  std::vector<size_t> dimension_errors;
+  if (track.has_dimensions() &&
+      !ParseTrackDimensions(context_, args.state.get(), track, &reservation,
+                            &dimension_errors)) {
+    RecordTokenizationErrorWithTrackUuid(
+        stats::track_descriptor_invalid_dimension, track.uuid(), args.packet);
+    return ModuleResult::Handled();
+  }
+  // Producers re-emit their descriptors (e.g. on every incremental state
+  // clear), so the errors of the dimensions are only recorded for the first
+  // reservation of a uuid.
+  auto reserve = [&]() {
+    if (track_event_tracker_->ReserveDescriptorTrack(track.uuid(),
+                                                     reservation)) {
+      for (size_t stat : dimension_errors) {
+        RecordTokenizationErrorWithTrackUuid(stat, track.uuid(), args.packet);
+      }
+    }
+  };
+
   if (args.decoder.has_trusted_pid()) {
     context_->process_tracker->UpdateTrustedPid(
         static_cast<uint32_t>(args.decoder.trusted_pid()), track.uuid());
@@ -286,7 +415,7 @@
         reservation.use_synthetic_tid = chrome_thread.is_sandboxed_tid();
       }
     }
-    track_event_tracker_->ReserveDescriptorTrack(track.uuid(), reservation);
+    reserve();
 
     if (args.state->IsIncrementalStateValid()) {
       TokenizeThreadDescriptor(*args.state, thread,
@@ -311,7 +440,7 @@
 
     reservation.pid = static_cast<uint32_t>(process.pid());
     reservation.min_timestamp = args.ts;
-    track_event_tracker_->ReserveDescriptorTrack(track.uuid(), reservation);
+    reserve();
 
     return ModuleResult::Ignored();
   }
@@ -384,7 +513,7 @@
     }
 
     // Incrementally encoded counters are only valid on a single sequence.
-    track_event_tracker_->ReserveDescriptorTrack(track.uuid(), reservation);
+    reserve();
 
     return ModuleResult::Ignored();
   }
@@ -393,7 +522,7 @@
     reservation.is_state = true;
   }
 
-  track_event_tracker_->ReserveDescriptorTrack(track.uuid(), reservation);
+  reserve();
 
   // Let ProtoTraceReader forward the packet to the parser.
   return ModuleResult::Ignored();
diff --git a/src/trace_processor/importers/proto/track_event_tracker.cc b/src/trace_processor/importers/proto/track_event_tracker.cc
index c4377ec..415d90e 100644
--- a/src/trace_processor/importers/proto/track_event_tracker.cc
+++ b/src/trace_processor/importers/proto/track_event_tracker.cc
@@ -26,8 +26,10 @@
 #include <unordered_set>
 #include <utility>
 #include <variant>
+#include <vector>
 
 #include "perfetto/base/logging.h"
+#include "perfetto/ext/base/murmur_hash.h"
 #include "src/trace_processor/importers/common/args_tracker.h"
 #include "src/trace_processor/importers/common/import_logs_tracker.h"
 #include "src/trace_processor/importers/common/process_track_translation_table.h"
@@ -42,6 +44,7 @@
 #include "src/trace_processor/importers/proto/track_event_sequence_state.h"
 #include "src/trace_processor/storage/stats.h"
 #include "src/trace_processor/storage/trace_storage.h"
+#include "src/trace_processor/tables/track_tables_py.h"
 #include "src/trace_processor/types/trace_processor_context.h"
 #include "src/trace_processor/types/variadic.h"
 
@@ -129,6 +132,78 @@
         tracks::StringIdDimensionBlueprint("merge_key_value")),
     tracks::DynamicNameBlueprint());
 
+// Variants of the merged blueprints above for tracks with custom dimensions,
+// declared or inherited: siblings are only merged if they have the same
+// dimensions, so the hash of their dimensions is part of the merge key. Only
+// these tracks carry the extra dimension, so the dimensions of every other
+// merged track are left untouched.
+constexpr auto kCustomDimensionsHashBlueprint =
+    tracks::LongDimensionBlueprint("custom_dimensions_hash");
+
+constexpr auto kThreadTrackMergedWithDimensionsBlueprint =
+    TrackCompressor::SliceBlueprint(
+        "thread_merged_track_event",
+        tracks::DimensionBlueprints(
+            tracks::kThreadDimensionBlueprint,
+            tracks::LongDimensionBlueprint("parent_track_uuid"),
+            tracks::UintDimensionBlueprint("merge_key_type"),
+            tracks::StringIdDimensionBlueprint("merge_key_value"),
+            kCustomDimensionsHashBlueprint),
+        tracks::DynamicNameBlueprint());
+
+constexpr auto kProcessTrackMergedWithDimensionsBlueprint =
+    TrackCompressor::SliceBlueprint(
+        "process_merged_track_event",
+        tracks::DimensionBlueprints(
+            tracks::kProcessDimensionBlueprint,
+            tracks::LongDimensionBlueprint("parent_track_uuid"),
+            tracks::UintDimensionBlueprint("merge_key_type"),
+            tracks::StringIdDimensionBlueprint("merge_key_value"),
+            kCustomDimensionsHashBlueprint),
+        tracks::DynamicNameBlueprint());
+
+constexpr auto kGlobalTrackMergedWithDimensionsBlueprint =
+    TrackCompressor::SliceBlueprint(
+        "global_merged_track_event",
+        tracks::DimensionBlueprints(
+            tracks::LongDimensionBlueprint("parent_track_uuid"),
+            tracks::UintDimensionBlueprint("merge_key_type"),
+            tracks::StringIdDimensionBlueprint("merge_key_value"),
+            kCustomDimensionsHashBlueprint),
+        tracks::DynamicNameBlueprint());
+
+// Creates the factory of a merged track using |bp|, or |bp_with_dimensions|
+// with |dimensions_hash| appended to |dims| if the track has custom dimensions.
+template <typename Blueprint,
+          typename BlueprintWithDimensions,
+          typename... Dims>
+TrackCompressor::TrackFactory CreateMergedTrackFactory(
+    TrackCompressor* compressor,
+    const Blueprint& bp,
+    const BlueprintWithDimensions& bp_with_dimensions,
+    std::optional<uint64_t> dimensions_hash,
+    StringId name,
+    TrackTracker::SetArgsCallback args,
+    std::function<void(TrackId)> on_new_track,
+    Dims... dims) {
+  if (!dimensions_hash) {
+    return compressor->CreateTrackFactory(
+        bp, tracks::Dimensions(dims...), tracks::DynamicName(name),
+        std::move(args), std::move(on_new_track));
+  }
+  return compressor->CreateTrackFactory(
+      bp_with_dimensions,
+      tracks::Dimensions(dims..., static_cast<int64_t>(*dimensions_hash)),
+      tracks::DynamicName(name), std::move(args), std::move(on_new_track));
+}
+
+// Part of the hash of a dimension, so that e.g. the integer 5 doesn't collide
+// with the string interned with id 5.
+enum class DimensionValueType : uint8_t {
+  kInt = 0,
+  kString = 1,
+};
+
 std::pair<uint32_t, StringId> GetMergeKey(
     const TrackEventTracker::DescriptorTrackReservation& reservation,
     StringId name) {
@@ -173,7 +248,25 @@
       parent_uuid_key_id_(context->storage->InternString("parent_uuid")),
       context_(context) {}
 
-void TrackEventTracker::ReserveDescriptorTrack(
+// static
+uint64_t TrackEventTracker::DescriptorTrackReservation::HashDimensions(
+    const std::vector<Dimension>& dims) {
+  base::MurmurHashCombiner hasher;
+  for (const auto& dim : dims) {
+    if (dim.int_value) {
+      hasher.Combine(dim.name.raw_id(),
+                     static_cast<uint8_t>(DimensionValueType::kInt),
+                     *dim.int_value);
+    } else {
+      hasher.Combine(dim.name.raw_id(),
+                     static_cast<uint8_t>(DimensionValueType::kString),
+                     dim.string_value->raw_id());
+    }
+  }
+  return hasher.digest();
+}
+
+bool TrackEventTracker::ReserveDescriptorTrack(
     uint64_t uuid,
     const DescriptorTrackReservation& reservation) {
   if (uuid == kDefaultDescriptorTrackUuid && reservation.parent_uuid) {
@@ -183,16 +276,17 @@
           inserter.AddArg(parent_uuid_key_id_,
                           Variadic::UnsignedInteger(reservation.parent_uuid));
         });
-    return;
+    return false;
   }
 
   auto [it, inserted] = descriptor_tracks_state_.Insert(uuid, {reservation});
   if (inserted) {
-    return;
+    has_dimensions_ |= !reservation.dimensions.empty();
+    return true;
   }
   if (!it->reservation.IsForSameTrack(reservation)) {
     RecordTrackError(stats::track_descriptor_conflicting_reservation, uuid);
-    return;
+    return false;
   }
 
   if (!reservation.name.is_null()) {
@@ -218,6 +312,7 @@
   }
   it->reservation.min_timestamp =
       std::min(it->reservation.min_timestamp, reservation.min_timestamp);
+  return false;
 }
 
 std::optional<TrackEventTracker::ResolvedDescriptorTrack>
@@ -475,6 +570,28 @@
       rr.set_parent_id(parent_track_id);
     }
   };
+  // Merged tracks are created lazily and there can be more than one of them
+  // for a single descriptor, so dimensions are recorded from the track
+  // creation callback. Only descriptors with the same dimensions are merged
+  // together (they are part of the merge key), so the dimensions of the
+  // descriptor creating the track apply to the whole merged track. Every other
+  // track is handled by |EnsureDescriptorTrackInterned|.
+  auto on_new_merged_track = [this, uuid, set_parent_id](bool set_parent) {
+    return [this, uuid, set_parent_id, set_parent](TrackId id) {
+      if (set_parent) {
+        set_parent_id(id);
+      }
+      RecordTrackDimensions(uuid, id);
+    };
+  };
+  // Siblings are only merged if they have the same dimensions, including the
+  // ones they inherit, so the merge key uses the effective dimensions.
+  std::optional<uint64_t> merge_dimensions_hash;
+  if (has_dimensions_) {
+    if (const DimensionVec& dims = ResolveDimensions(uuid); !dims.empty()) {
+      merge_dimensions_hash = DescriptorTrackReservation::HashDimensions(dims);
+    }
+  }
   using M = TrackEventTracker::DescriptorTrackReservation::SiblingMergeBehavior;
   if (parent_track_id) {
     // If we have the track id, we should also always have the resolved track
@@ -517,14 +634,13 @@
           return id;
         }
         auto [type, key] = GetMergeKey(*reservation, name);
-        return context_->track_compressor->CreateTrackFactory(
-            kThreadTrackMergedBlueprint,
-            tracks::Dimensions(parent_resolved_track->utid(),
-                               static_cast<int64_t>(reservation->parent_uuid),
-                               type, key),
-            tracks::DynamicName(name), args_fn_non_root,
-            parent_resolved_track->is_root() ? std::function<void(TrackId)>()
-                                             : set_parent_id);
+        return CreateMergedTrackFactory(
+            context_->track_compressor.get(), kThreadTrackMergedBlueprint,
+            kThreadTrackMergedWithDimensionsBlueprint, merge_dimensions_hash,
+            name, args_fn_non_root,
+            on_new_merged_track(!parent_resolved_track->is_root()),
+            parent_resolved_track->utid(),
+            static_cast<int64_t>(reservation->parent_uuid), type, key);
       }
       case ResolvedDescriptorTrack::Scope::kProcess: {
         // If parent is a process track, create another process-associated
@@ -568,14 +684,13 @@
           return id;
         }
         auto [type, key] = GetMergeKey(*reservation, translated_name);
-        return context_->track_compressor->CreateTrackFactory(
-            kProcessTrackMergedBlueprint,
-            tracks::Dimensions(parent_resolved_track->upid(),
-                               static_cast<int64_t>(reservation->parent_uuid),
-                               type, key),
-            tracks::DynamicName(translated_name), args_fn_non_root,
-            parent_resolved_track->is_root() ? std::function<void(TrackId)>()
-                                             : set_parent_id);
+        return CreateMergedTrackFactory(
+            context_->track_compressor.get(), kProcessTrackMergedBlueprint,
+            kProcessTrackMergedWithDimensionsBlueprint, merge_dimensions_hash,
+            translated_name, args_fn_non_root,
+            on_new_merged_track(!parent_resolved_track->is_root()),
+            parent_resolved_track->upid(),
+            static_cast<int64_t>(reservation->parent_uuid), type, key);
       }
       case ResolvedDescriptorTrack::Scope::kGlobal:
         break;
@@ -607,12 +722,12 @@
     return id;
   }
   auto [type, key] = GetMergeKey(*reservation, name);
-  return context_->track_compressor->CreateTrackFactory(
-      kGlobalTrackMergedBlueprint,
-      tracks::Dimensions(static_cast<int64_t>(reservation->parent_uuid), type,
-                         key),
-      tracks::DynamicName(name),
-      is_root_in_scope ? args_fn_root : args_fn_non_root, set_parent_id);
+  return CreateMergedTrackFactory(
+      context_->track_compressor.get(), kGlobalTrackMergedBlueprint,
+      kGlobalTrackMergedWithDimensionsBlueprint, merge_dimensions_hash, name,
+      is_root_in_scope ? args_fn_root : args_fn_non_root,
+      on_new_merged_track(true), static_cast<int64_t>(reservation->parent_uuid),
+      type, key);
 }
 
 std::optional<double> TrackEventTracker::ConvertToAbsoluteCounterValue(
@@ -707,6 +822,62 @@
   }
 }
 
+void TrackEventTracker::RecordTrackDimensions(uint64_t uuid, TrackId track_id) {
+  // The overwhelmingly common case: no producer declared any dimension.
+  if (!has_dimensions_) {
+    return;
+  }
+  // Every track gets its dimensions from a single descriptor, so they never
+  // need reconciling: the siblings sharing a merged track have the same
+  // dimensions (they are part of the merge key), and the thread track of a
+  // root thread descriptor is not shared with another descriptor (one for the
+  // same tid is a tid reuse and gets a new thread) but only with tracks of
+  // other data sources, which have no custom dimensions.
+  const DimensionVec& dims = ResolveDimensions(uuid);
+  auto* table = context_->storage->mutable_track_dimension_table();
+  for (const auto& dim : dims) {
+    tables::TrackDimensionTable::Row row;
+    row.track_id = track_id;
+    row.name = dim.name;
+    row.int_value = dim.int_value;
+    row.string_value = dim.string_value;
+    row.display_name = dim.display_name;
+    table->Insert(row);
+  }
+}
+
+const TrackEventTracker::DimensionVec& TrackEventTracker::ResolveDimensions(
+    uint64_t uuid) {
+  State* state = descriptor_tracks_state_.Find(uuid);
+  PERFETTO_CHECK(state);
+  if (state->dimensions) {
+    return *state->dimensions;
+  }
+  DimensionVec dims;
+  if (uint64_t parent = state->reservation.parent_uuid;
+      parent != kDefaultDescriptorTrackUuid) {
+    dims = ResolveDimensions(parent);
+  }
+  for (const auto& dim : state->reservation.dimensions) {
+    auto existing =
+        std::find_if(dims.begin(), dims.end(),
+                     [&dim](const auto& d) { return d.name == dim.name; });
+    if (existing == dims.end()) {
+      dims.push_back(dim);
+    } else if (existing->int_value != dim.int_value ||
+               existing->string_value != dim.string_value) {
+      // The value which is already there, i.e. the inherited one or the first
+      // one declared, wins.
+      RecordTrackError(stats::track_dimension_conflicting_value, uuid);
+    }
+  }
+  std::sort(dims.begin(), dims.end(), [](const auto& a, const auto& b) {
+    return a.name.raw_id() < b.name.raw_id();
+  });
+  state->dimensions = std::move(dims);
+  return *state->dimensions;
+}
+
 bool TrackEventTracker::IsTrackHierarchyValid(uint64_t uuid) {
   // Do a basic tree walking algorithm to find if there are duplicate ids or
   // the path to the root is longer than kMaxAncestors.
diff --git a/src/trace_processor/importers/proto/track_event_tracker.h b/src/trace_processor/importers/proto/track_event_tracker.h
index 7b2ea74..45d19c1 100644
--- a/src/trace_processor/importers/proto/track_event_tracker.h
+++ b/src/trace_processor/importers/proto/track_event_tracker.h
@@ -23,6 +23,7 @@
 #include <unordered_set>
 #include <utility>
 #include <variant>
+#include <vector>
 
 #include "perfetto/base/logging.h"
 #include "perfetto/ext/base/flat_hash_map.h"
@@ -79,6 +80,15 @@
       kByKey = 2,
     };
 
+    // A producer-declared custom dimension (see TrackDescriptor.dimensions).
+    // Exactly one of |int_value| / |string_value| is set.
+    struct Dimension {
+      StringId name = kNullStringId;
+      std::optional<int64_t> int_value;
+      std::optional<StringId> string_value;
+      std::optional<StringId> display_name;
+    };
+
     uint64_t parent_uuid = 0;
     std::optional<int64_t> pid;
     std::optional<int64_t> tid;
@@ -103,6 +113,14 @@
     SiblingMergeBehavior sibling_merge_behavior = SiblingMergeBehavior::kByName;
     StringId sibling_merge_key = kNullStringId;
 
+    // Producer-declared custom dimensions, sorted by name and without repeated
+    // names. Dimensions are part of the track's identity, so they are compared
+    // by |IsForSameTrack|.
+    std::vector<Dimension> dimensions;
+
+    // HashDimensions() of |dimensions|.
+    uint64_t dimensions_hash = 0;
+
     // Whether |other| is a valid descriptor for this track reservation. A track
     // should always remain nested underneath its original parent.
     bool IsForSameTrack(const DescriptorTrackReservation& other) {
@@ -113,12 +131,37 @@
           !counter_details->IsForSameTrack(*other.counter_details)) {
         return false;
       }
+      if (!HasSameDimensions(other)) {
+        return false;
+      }
       return std::tie(parent_uuid, pid, tid, is_counter, is_state,
                       sibling_merge_behavior, sibling_merge_key) ==
              std::tie(other.parent_uuid, other.pid, other.tid, other.is_counter,
                       other.is_state, other.sibling_merge_behavior,
                       other.sibling_merge_key);
     }
+
+    // Whether |other| declares the same dimension names and values (display
+    // names only affect presentation and are ignored).
+    bool HasSameDimensions(const DescriptorTrackReservation& other) const {
+      if (dimensions_hash != other.dimensions_hash ||
+          dimensions.size() != other.dimensions.size()) {
+        return false;
+      }
+      for (size_t i = 0; i < dimensions.size(); ++i) {
+        const Dimension& a = dimensions[i];
+        const Dimension& b = other.dimensions[i];
+        if (std::tie(a.name, a.int_value, a.string_value) !=
+            std::tie(b.name, b.int_value, b.string_value)) {
+          return false;
+        }
+      }
+      return true;
+    }
+
+    // Hash of the names and typed values of |dims|, sorted by name. Display
+    // names only affect presentation and are not part of it.
+    static uint64_t HashDimensions(const std::vector<Dimension>& dims);
   };
 
   // A descriptor track which has been resolved to a concrete track in the
@@ -199,8 +242,9 @@
   // Associate a TrackDescriptor track identified by the given |uuid| with a
   // given track description. This is called during tokenization. If a
   // reservation for the same |uuid| already exists, verifies that the present
-  // reservation matches the new one.
-  void ReserveDescriptorTrack(uint64_t uuid, const DescriptorTrackReservation&);
+  // reservation matches the new one. Returns whether this is the first
+  // reservation for |uuid|.
+  bool ReserveDescriptorTrack(uint64_t uuid, const DescriptorTrackReservation&);
 
   // Resolves a descriptor track UUID to a `ResolvedDescriptorTrack` object.
   // This object contains information about the track's scope (global, process,
@@ -348,11 +392,17 @@
   }
 
  private:
+  using DimensionVec = std::vector<DescriptorTrackReservation::Dimension>;
+
   struct State {
     DescriptorTrackReservation reservation;
     std::optional<ResolvedDescriptorTrack> resolved = std::nullopt;
     std::optional<std::variant<TrackId, TrackCompressor::TrackFactory>>
         track_id_or_factory = std::nullopt;
+    // The custom dimensions of the tracks of this descriptor, i.e. the ones of
+    // its parent plus the ones it declares, sorted by name. Computed by
+    // |ResolveDimensions| when the first track of the descriptor is created.
+    std::optional<DimensionVec> dimensions = std::nullopt;
   };
 
   std::optional<TrackId> InternDescriptorTrackForParent(
@@ -389,6 +439,10 @@
       s = descriptor_tracks_state_.Find(uuid);
       PERFETTO_CHECK(s);
       s->track_id_or_factory = std::move(res);
+      // Merged tracks record their dimensions as they are created instead.
+      if (auto* track_id = std::get_if<TrackId>(&*s->track_id_or_factory)) {
+        RecordTrackDimensions(uuid, *track_id);
+      }
     }
     return s;
   }
@@ -411,6 +465,20 @@
                     bool,
                     ArgsTracker::BoundInserter&);
 
+  // Writes the custom dimensions of the descriptor |uuid| (see
+  // |ResolveDimensions|) to the track dimension table for |track_id|, a track
+  // created for that descriptor.
+  void RecordTrackDimensions(uint64_t uuid, TrackId track_id);
+
+  // Returns the custom dimensions of the descriptor |uuid|: the ones of its
+  // parent plus the ones it declares itself. A declared value conflicting with
+  // an inherited one, or with one declared earlier on the same descriptor, is
+  // ignored and recorded as `track_dimension_conflicting_value`. This is
+  // computed once per descriptor, when its first track is created, so each bad
+  // declaration is only recorded once. The parent of a descriptor is always
+  // interned, and so resolved, before its children.
+  const DimensionVec& ResolveDimensions(uint64_t uuid);
+
   // Helper to record analysis errors with track_uuid arg
   void RecordTrackError(size_t stat_key, uint64_t track_uuid);
 
@@ -423,6 +491,10 @@
 
   std::unordered_set<uint32_t> sequences_with_first_packet_;
 
+  // Whether any descriptor declared custom dimensions: if none did, no track
+  // has any and |RecordTrackDimensions| has nothing to do.
+  bool has_dimensions_ = false;
+
   const StringId source_key_;
   const StringId source_id_key_;
   const StringId is_root_in_scope_key_;
diff --git a/src/trace_processor/perfetto_sql/engine/perfetto_sql_connection.cc b/src/trace_processor/perfetto_sql/engine/perfetto_sql_connection.cc
index 786d44c..0f34ccf 100644
--- a/src/trace_processor/perfetto_sql/engine/perfetto_sql_connection.cc
+++ b/src/trace_processor/perfetto_sql/engine/perfetto_sql_connection.cc
@@ -1073,7 +1073,9 @@
   ASSIGN_OR_RETURN(pipeline::LogicalPlan plan,
                    pipeline::DeserializePlan(serialized, *catalog_));
   RETURN_IF_ERROR(pipeline::BindDataframeArgs(plan, args, pool_));
-  return pipeline::Lower(plan);
+  pipeline::LoweringContext context;
+  context.pool = pool_;
+  return pipeline::Lower(plan, context);
 }
 
 base::Status PerfettoSqlConnection::ExecuteCreateView(
diff --git a/src/trace_processor/perfetto_sql/engine/perfetto_sql_connection_unittest.cc b/src/trace_processor/perfetto_sql/engine/perfetto_sql_connection_unittest.cc
index 2e96f6b..f524bee 100644
--- a/src/trace_processor/perfetto_sql/engine/perfetto_sql_connection_unittest.cc
+++ b/src/trace_processor/perfetto_sql/engine/perfetto_sql_connection_unittest.cc
@@ -699,6 +699,35 @@
   ASSERT_TRUE(rows.ok()) << rows.status().message();
   EXPECT_THAT(*rows, testing::ElementsAre("5,5,NULL", "5,5,x"));
 
+  // A bare ts, dur or key is the region's, and an operand's other columns
+  // are found by their bare names too. So a star, or no stage at all, gives
+  // the region and what each operand carries, without the operands' own ts
+  // and dur.
+  const std::string kIntersection =
+      "INTERVAL INTERSECTION OF ("
+      "(SELECT ts, dur, name, n AS a_n FROM a) AS a, b AS b) PER name ";
+  for (const char* stage : {"", "|> SELECT *"}) {
+    SCOPED_TRACE(stage);
+    EXPECT_THAT(ColumnNames(kIntersection + stage),
+                testing::ElementsAre("ts", "dur", "name", "a_n", "n"));
+    rows = Rows(kIntersection + stage);
+    ASSERT_TRUE(rows.ok()) << rows.status().message();
+    EXPECT_THAT(*rows, testing::ElementsAre("5,5,NULL,3,2", "5,5,x,1,1"));
+  }
+  rows = Rows(kIntersection + "|> SELECT a_n, n, a.ts, b.ts AS b_ts");
+  ASSERT_TRUE(rows.ok()) << rows.status().message();
+  EXPECT_THAT(*rows, testing::ElementsAre("1,1,0,5", "3,2,0,5"));
+  // A new alias covers those same columns, so its ts is the region's.
+  rows = Rows(kIntersection + "|> AS u |> SELECT u.ts, u.a_n");
+  ASSERT_TRUE(rows.ok()) << rows.status().message();
+  EXPECT_THAT(*rows, testing::ElementsAre("5,1", "5,3"));
+  // Two operands with a column of one name make that name ambiguous.
+  EXPECT_THAT(Rows("INTERVAL INTERSECTION OF (a AS a, b AS b) PER name "
+                   "|> SELECT n")
+                  .status()
+                  .message(),
+              testing::HasSubstr("column 'n' is ambiguous"));
+
   // A key that holds strings in one operand and numbers in another is an
   // error when the plan is lowered.
   EXPECT_THAT(Rows(R"(
@@ -851,10 +880,21 @@
                   .status()
                   .message(),
               testing::HasSubstr("overflow"));
-  EXPECT_THAT(Rows("FROM spans |> AGGREGATE COUNT(*) AS cpu GROUP BY cpu")
+  // As in any row, two columns can share a name, which is then ambiguous to
+  // refer to.
+  rows = Rows("FROM spans |> AGGREGATE COUNT(*) AS cpu GROUP BY cpu");
+  ASSERT_TRUE(rows.ok()) << rows.status().message();
+  EXPECT_THAT(*rows, testing::ElementsAre("1,2", "2,2", "NULL,2"));
+  EXPECT_THAT(Rows("FROM spans |> AGGREGATE COUNT(*) AS cpu GROUP BY cpu "
+                   "|> SELECT cpu")
                   .status()
                   .message(),
-              testing::HasSubstr("listed only once"));
+              testing::HasSubstr("column 'cpu' is ambiguous"));
+  // A key listed again groups nothing new, but is another output column.
+  rows = Rows(
+      "FROM spans AS s |> AGGREGATE COUNT(*) AS n GROUP BY cpu, s.cpu AS c");
+  ASSERT_TRUE(rows.ok()) << rows.status().message();
+  EXPECT_THAT(*rows, testing::ElementsAre("1,1,2", "2,2,2", "NULL,NULL,2"));
 }
 
 // Every alias in pipe syntax needs AS, so a keyword after a relation, like
diff --git a/src/trace_processor/perfetto_sql/engine/pipeline_module.cc b/src/trace_processor/perfetto_sql/engine/pipeline_module.cc
index 2c0d090..6146cb8 100644
--- a/src/trace_processor/perfetto_sql/engine/pipeline_module.cc
+++ b/src/trace_processor/perfetto_sql/engine/pipeline_module.cc
@@ -394,7 +394,7 @@
       return rc;
     }
   }
-  c->eof = !c->rows->Open();
+  c->eof = !c->rows->Open(c->plan->filter_values());
   if (c->eof)
     return CheckStatus(c);
   CacheColumnReaders(c);
diff --git a/src/trace_processor/perfetto_sql/pipeline/compiler.cc b/src/trace_processor/perfetto_sql/pipeline/compiler.cc
index f78ca15..325785e 100644
--- a/src/trace_processor/perfetto_sql/pipeline/compiler.cc
+++ b/src/trace_processor/perfetto_sql/pipeline/compiler.cc
@@ -131,6 +131,23 @@
   scope_.aliases.push_back(std::move(alias));
 }
 
+void Compiler::ReplaceAliasColumns(
+    const std::vector<std::pair<ColumnId, ColumnId>>& replaced) {
+  for (Alias& alias : scope_.aliases) {
+    std::vector<RowColumn> columns;
+    for (RowColumn column : alias.columns) {
+      auto it = std::find_if(
+          replaced.begin(), replaced.end(),
+          [&](const auto& pair) { return pair.first == column.column.id; });
+      if (it != replaced.end()) {
+        column.column.id = it->second;
+        columns.push_back(std::move(column));
+      }
+    }
+    alias.columns = std::move(columns);
+  }
+}
+
 ColumnId Compiler::AddColumn(std::string name, PlanType type) {
   return plan_.AddColumn(std::move(name), type);
 }
@@ -138,18 +155,7 @@
 base::Status Compiler::BuildOperation(uint32_t stage) {
   uint32_t tag = Node<SyntaqliteNode>(p_, stage)->tag;
   const auto* registration = FindOperationBySyntax(tag);
-  if (!registration) {
-    switch (tag) {
-      case SYNTAQLITE_NODE_PERFETTO_INTERVAL_FILL_GAPS:
-        return Unsupported(stage, "INTERVAL FILL GAPS");
-      case SYNTAQLITE_NODE_PERFETTO_PIPE_WHERE:
-        return Unsupported(stage, "WHERE");
-      case SYNTAQLITE_NODE_PERFETTO_PIPE_DISTINCT:
-        return Unsupported(stage, "DISTINCT");
-      default:
-        PERFETTO_FATAL("Unknown pipeline stage");
-    }
-  }
+  PERFETTO_CHECK(registration);
   return registration->BuildPlan(this, stage);
 }
 
@@ -373,9 +379,13 @@
 }
 
 LogicalPlan Compiler::Finish() {
+  // The result is the row as a bare name sees it. Columns only an alias
+  // finds, as an intersection's operand columns are, stay behind.
   plan_.output().clear();
   for (const RowColumn& column : scope_.row) {
-    plan_.output().push_back(column.column);
+    if (!column.qualified_only) {
+      plan_.output().push_back(column.column);
+    }
   }
   return std::move(plan_);
 }
diff --git a/src/trace_processor/perfetto_sql/pipeline/compiler.h b/src/trace_processor/perfetto_sql/pipeline/compiler.h
index e1dc9b1..40b7d09 100644
--- a/src/trace_processor/perfetto_sql/pipeline/compiler.h
+++ b/src/trace_processor/perfetto_sql/pipeline/compiler.h
@@ -211,6 +211,12 @@
   void ClearAliases();
   void AddAlias(Alias alias);
 
+  // Updates each alias to point at new columns, for a stage that replaces
+  // every column. `replaced` holds (`from`, `to`) pairs. Columns with no
+  // replacement are removed from the alias.
+  void ReplaceAliasColumns(
+      const std::vector<std::pair<ColumnId, ColumnId>>& replaced);
+
   // Forgets the table alias `name`, if there is one.
   void RemoveAlias(const std::string& name);
 
diff --git a/src/trace_processor/perfetto_sql/pipeline/logical_plan_test_utils.cc b/src/trace_processor/perfetto_sql/pipeline/logical_plan_test_utils.cc
index a96d980..046e3c8 100644
--- a/src/trace_processor/perfetto_sql/pipeline/logical_plan_test_utils.cc
+++ b/src/trace_processor/perfetto_sql/pipeline/logical_plan_test_utils.cc
@@ -23,13 +23,17 @@
 
 #include "perfetto/base/logging.h"
 #include "perfetto/ext/base/variant.h"
+#include "src/trace_processor/core/common/op_types.h"
 #include "src/trace_processor/core/common/storage_types.h"
 #include "src/trace_processor/perfetto_sql/pipeline/operations/aggregate_stage.h"
+#include "src/trace_processor/perfetto_sql/pipeline/operations/distinct.h"
+#include "src/trace_processor/perfetto_sql/pipeline/operations/interval_fill_gaps.h"
 #include "src/trace_processor/perfetto_sql/pipeline/operations/interval_flatten.h"
 #include "src/trace_processor/perfetto_sql/pipeline/operations/interval_intersect.h"
 #include "src/trace_processor/perfetto_sql/pipeline/operations/order_by.h"
 #include "src/trace_processor/perfetto_sql/pipeline/operations/scan.h"
 #include "src/trace_processor/perfetto_sql/pipeline/operations/tree_accumulate.h"
+#include "src/trace_processor/perfetto_sql/pipeline/operations/where.h"
 
 namespace perfetto::trace_processor::pipeline {
 namespace {
@@ -82,6 +86,27 @@
   return out;
 }
 
+// A WHERE predicate's operator, e.g. `=` in `#2 = 5`.
+std::string OpString(const WherePredicate::Op& op) {
+  if (op.Is<core::Eq>()) {
+    return "=";
+  }
+  if (op.Is<core::Ne>()) {
+    return "!=";
+  }
+  if (op.Is<core::Lt>()) {
+    return "<";
+  }
+  if (op.Is<core::Le>()) {
+    return "<=";
+  }
+  if (op.Is<core::Gt>()) {
+    return ">";
+  }
+  PERFETTO_CHECK(op.Is<core::Ge>());
+  return ">=";
+}
+
 }  // namespace
 
 // Kept in the test-only target: formatting must not add production binary size.
@@ -97,7 +122,11 @@
                                            const IntervalFlatten&);
   static std::string IntervalIntersectString(const LogicalPlan&,
                                              const PlanNode&);
+  static std::string IntervalFillGapsString(const LogicalPlan&,
+                                            const PlanNode&);
   static std::string OrderByString(const OrderBy&);
+  static std::string DistinctString(const Distinct&);
+  static std::string WhereString(const Where&);
   static std::string AggregateStageString(const LogicalPlan&,
                                           const AggregateStage&);
   static std::string SubtreeString(const LogicalPlan&, PlanNodeId);
@@ -186,6 +215,32 @@
   return out;
 }
 
+std::string LogicalPlanFormatter::IntervalFillGapsString(
+    const LogicalPlan& plan,
+    const PlanNode& node) {
+  const auto& fill = node.Cast<IntervalFillGaps>();
+  std::string out = "IntervalFillGaps(ts=#" + std::to_string(fill.ts_) +
+                    ", dur=#" + std::to_string(fill.dur_);
+  for (ColumnId key : fill.keys_) {
+    out += ", key=#" + std::to_string(key);
+  }
+  out += ")";
+  for (const auto& output : fill.outputs_) {
+    out += "\n  " + ColumnString(plan, output.column) + " <- ";
+    out += "#" + std::to_string(output.input);
+    out += " | ";
+    out +=
+        output.background ? "#" + std::to_string(*output.background) : "null";
+  }
+  out += "\n  background(ts=#" + std::to_string(fill.background_ts_) +
+         ", dur=#" + std::to_string(fill.background_dur_);
+  for (ColumnId key : fill.background_keys_) {
+    out += ", key=#" + std::to_string(key);
+  }
+  return out + ")\n    " +
+         ScanString(plan, plan.nodes()[node.children()[1]].Cast<Scan>());
+}
+
 std::string LogicalPlanFormatter::OrderByString(const OrderBy& order) {
   std::string out = "OrderBy(";
   for (size_t i = 0; i < order.keys_.size(); ++i) {
@@ -195,6 +250,26 @@
   return out + ")";
 }
 
+std::string LogicalPlanFormatter::DistinctString(const Distinct& distinct) {
+  std::string out = "Distinct(";
+  for (size_t i = 0; i < distinct.columns_.size(); ++i) {
+    out += (i ? ", #" : "#") + std::to_string(distinct.columns_[i]);
+  }
+  return out + ")";
+}
+
+std::string LogicalPlanFormatter::WhereString(const Where& where) {
+  std::string out = "Where(";
+  for (size_t i = 0; i < where.predicates_.size(); ++i) {
+    const WherePredicate& p = where.predicates_[i];
+    out += (i ? ", #" : "#") + std::to_string(p.column) + " " + OpString(p.op) +
+           " " +
+           (p.is_double ? std::to_string(p.double_value)
+                        : std::to_string(p.int_value));
+  }
+  return out + ")";
+}
+
 std::string LogicalPlanFormatter::AggregateStageString(
     const LogicalPlan& plan,
     const AggregateStage& aggregate) {
@@ -227,6 +302,10 @@
   if (node.Is<IntervalIntersect>()) {
     return IntervalIntersectString(plan, node) + "\n";
   }
+  if (node.Is<IntervalFillGaps>()) {
+    return SubtreeString(plan, node.children()[0]) +
+           IntervalFillGapsString(plan, node) + "\n";
+  }
   if (node.Is<IntervalFlatten>()) {
     return SubtreeString(plan, node.children()[0]) +
            IntervalFlattenString(plan, node.Cast<IntervalFlatten>()) + "\n";
@@ -239,6 +318,14 @@
     return SubtreeString(plan, node.children()[0]) +
            OrderByString(node.Cast<OrderBy>()) + "\n";
   }
+  if (node.Is<Distinct>()) {
+    return SubtreeString(plan, node.children()[0]) +
+           DistinctString(node.Cast<Distinct>()) + "\n";
+  }
+  if (node.Is<Where>()) {
+    return SubtreeString(plan, node.children()[0]) +
+           WhereString(node.Cast<Where>()) + "\n";
+  }
   PERFETTO_FATAL("Unknown plan operation");
 }
 
diff --git a/src/trace_processor/perfetto_sql/pipeline/operation_registry.cc b/src/trace_processor/perfetto_sql/pipeline/operation_registry.cc
index 960ea42..3e754ac 100644
--- a/src/trace_processor/perfetto_sql/pipeline/operation_registry.cc
+++ b/src/trace_processor/perfetto_sql/pipeline/operation_registry.cc
@@ -17,12 +17,15 @@
 #include "src/trace_processor/perfetto_sql/pipeline/operation_registry.h"
 
 #include "src/trace_processor/perfetto_sql/pipeline/operations/aggregate_stage.h"
+#include "src/trace_processor/perfetto_sql/pipeline/operations/distinct.h"
+#include "src/trace_processor/perfetto_sql/pipeline/operations/interval_fill_gaps.h"
 #include "src/trace_processor/perfetto_sql/pipeline/operations/interval_flatten.h"
 #include "src/trace_processor/perfetto_sql/pipeline/operations/interval_intersect.h"
 #include "src/trace_processor/perfetto_sql/pipeline/operations/order_by.h"
 #include "src/trace_processor/perfetto_sql/pipeline/operations/projection.h"
 #include "src/trace_processor/perfetto_sql/pipeline/operations/scan.h"
 #include "src/trace_processor/perfetto_sql/pipeline/operations/tree_accumulate.h"
+#include "src/trace_processor/perfetto_sql/pipeline/operations/where.h"
 
 namespace perfetto::trace_processor::pipeline {
 
@@ -33,8 +36,11 @@
     &TreeAccumulate::kRegistration,
     &IntervalIntersect::kRegistration,
     &IntervalFlatten::kRegistration,
+    &IntervalFillGaps::kRegistration,
     &OrderBy::kRegistration,
     &AggregateStage::kRegistration,
+    &Distinct::kRegistration,
+    &Where::kRegistration,
     &projection::kSelect,
     &projection::kExtend,
     &projection::kDrop,
diff --git a/src/trace_processor/perfetto_sql/pipeline/operations/BUILD.gn b/src/trace_processor/perfetto_sql/pipeline/operations/BUILD.gn
index d2604b9..ef48184 100644
--- a/src/trace_processor/perfetto_sql/pipeline/operations/BUILD.gn
+++ b/src/trace_processor/perfetto_sql/pipeline/operations/BUILD.gn
@@ -20,6 +20,10 @@
   sources = [
     "aggregate_stage.cc",
     "aggregate_stage.h",
+    "distinct.cc",
+    "distinct.h",
+    "interval_fill_gaps.cc",
+    "interval_fill_gaps.h",
     "interval_flatten.cc",
     "interval_flatten.h",
     "interval_intersect.cc",
@@ -32,6 +36,8 @@
     "scan.h",
     "tree_accumulate.cc",
     "tree_accumulate.h",
+    "where.cc",
+    "where.h",
   ]
   deps = [
     "..:plan",
diff --git a/src/trace_processor/perfetto_sql/pipeline/operations/aggregate_stage.cc b/src/trace_processor/perfetto_sql/pipeline/operations/aggregate_stage.cc
index 7bdff40..8ef5116 100644
--- a/src/trace_processor/perfetto_sql/pipeline/operations/aggregate_stage.cc
+++ b/src/trace_processor/perfetto_sql/pipeline/operations/aggregate_stage.cc
@@ -16,6 +16,7 @@
 
 #include "src/trace_processor/perfetto_sql/pipeline/operations/aggregate_stage.h"
 
+#include <algorithm>
 #include <cstdint>
 #include <memory>
 #include <optional>
@@ -45,8 +46,6 @@
   const auto* n = Node<SyntaqlitePerfettoPipeAggregate>(c->parser(), stage);
 
   AggregateStage aggregate;
-  // Output column names, keys then aggregates. Each name must be unique.
-  std::vector<std::string> names;
   std::vector<std::pair<NamedColumn, uint32_t>> keys;
   if (syntaqlite_node_is_present(n->group_by)) {
     const auto* list =
@@ -63,8 +62,11 @@
       if (IsSpanPresent(item->alias)) {
         name = SpanText(c->parser(), item->alias);
       }
-      RETURN_IF_ERROR(c->CheckListedOnce(names, name, item_id));
-      aggregate.keys_.push_back(key);
+      // Groups once by each column, but outputs one column per item listed.
+      if (std::find(aggregate.keys_.begin(), aggregate.keys_.end(), key) ==
+          aggregate.keys_.end()) {
+        aggregate.keys_.push_back(key);
+      }
       keys.push_back({NamedColumn{std::move(name), key}, item_id});
     }
   }
@@ -77,7 +79,6 @@
     const auto* agg = Node<SyntaqlitePerfettoAggregate>(c->parser(), agg_id);
     ASSIGN_OR_RETURN(Aggregate resolved, c->ResolveAggregate(agg->expr));
     std::string name = SpanText(c->parser(), agg->name);
-    RETURN_IF_ERROR(c->CheckListedOnce(names, name, agg_id));
     resolved.output = c->AddColumn(name, core::Int64{});
     aggregate.aggregates_.push_back(resolved);
     aggregates.push_back(
diff --git a/src/trace_processor/perfetto_sql/pipeline/operations/distinct.cc b/src/trace_processor/perfetto_sql/pipeline/operations/distinct.cc
new file mode 100644
index 0000000..6121b59
--- /dev/null
+++ b/src/trace_processor/perfetto_sql/pipeline/operations/distinct.cc
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2026 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.
+ */
+
+#include "src/trace_processor/perfetto_sql/pipeline/operations/distinct.h"
+
+#include <cstdint>
+#include <memory>
+#include <optional>
+#include <utility>
+#include <vector>
+
+#include "perfetto/base/status.h"
+#include "src/perfetto_sql/syntaqlite/syntaqlite_perfetto.h"
+#include "src/trace_processor/core/exec/distinct.h"
+#include "src/trace_processor/perfetto_sql/pipeline/compiler.h"
+#include "src/trace_processor/perfetto_sql/pipeline/physical_plan.h"
+#include "src/trace_processor/perfetto_sql/pipeline/plan_serialization.h"
+
+namespace perfetto::trace_processor::pipeline {
+namespace ex = core::exec;
+
+const OperationRegistration Distinct::kRegistration{
+    SYNTAQLITE_NODE_PERFETTO_PIPE_DISTINCT, &BuildPlan,
+    OperationRegistration::Encoding{7, false, &DecodePlan}};
+
+base::Status Distinct::BuildPlan(Compiler* c, uint32_t stage) {
+  c->SetOperation("DISTINCT");
+  // Other columns have no single value per output row, so they are dropped.
+  Distinct distinct;
+  std::vector<Compiler::RowColumn> row;
+  std::vector<std::pair<ColumnId, ColumnId>> kept;
+  for (const Compiler::RowColumn& column : c->row()) {
+    if (!column.qualified_only) {
+      distinct.columns_.push_back(column.column.id);
+      row.push_back(column);
+      kept.emplace_back(column.column.id, column.column.id);
+    }
+  }
+  if (distinct.columns_.size() > ex::Distinct::kMaxColumns) {
+    return c->Unsupported(stage, "a row of more than 64 columns");
+  }
+  c->ReplaceRow(std::move(row));
+  c->ReplaceAliasColumns(kept);
+  c->AddNode(std::move(distinct), {c->plan().root()});
+  return base::OkStatus();
+}
+
+std::optional<uint32_t> Distinct::Prune(std::vector<bool>* needed) {
+  for (ColumnId column : columns_) {
+    (*needed)[column] = true;
+  }
+  return std::nullopt;
+}
+
+void Distinct::Lower(Lowering* c, const PlanNode& node) const {
+  c->LowerNode(node.children()[0]);
+  std::vector<uint32_t> positions;
+  positions.reserve(columns_.size());
+  for (ColumnId column : columns_) {
+    positions.push_back(c->QueryPosition(column));
+  }
+  // Rows kept stay in their input order, so any known arrangement survives.
+  c->AddOperator(std::make_unique<ex::Distinct>(std::move(positions)));
+  c->DeclareSmallBatches();
+  c->DeclareRowsDropped();
+}
+
+const OperationRegistration& Distinct::registration() const {
+  return kRegistration;
+}
+
+std::unique_ptr<PlanOperation> Distinct::Clone() const {
+  return std::make_unique<Distinct>(*this);
+}
+
+void Distinct::Write(PlanWriter* c,
+                     const PlanNode&,
+                     Available* available) const {
+  c->writer().Size(columns_.size());
+  for (ColumnId column : columns_) {
+    c->writer().Position(*available, column);
+  }
+}
+
+void Distinct::DecodePlan(PlanReader* c, Available* available) {
+  Distinct distinct;
+  distinct.columns_.resize(c->reader().Count());
+  if (distinct.columns_.empty() ||
+      distinct.columns_.size() > ex::Distinct::kMaxColumns) {
+    c->reader().Fail();
+  }
+  for (ColumnId& column : distinct.columns_) {
+    column = c->reader().Position(*available);
+  }
+  c->AddNode(std::move(distinct), {c->plan().root()});
+}
+
+}  // namespace perfetto::trace_processor::pipeline
diff --git a/src/trace_processor/perfetto_sql/pipeline/operations/distinct.h b/src/trace_processor/perfetto_sql/pipeline/operations/distinct.h
new file mode 100644
index 0000000..5ef756e
--- /dev/null
+++ b/src/trace_processor/perfetto_sql/pipeline/operations/distinct.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2026 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.
+ */
+
+#ifndef SRC_TRACE_PROCESSOR_PERFETTO_SQL_PIPELINE_OPERATIONS_DISTINCT_H_
+#define SRC_TRACE_PROCESSOR_PERFETTO_SQL_PIPELINE_OPERATIONS_DISTINCT_H_
+
+#include <memory>
+#include <optional>
+#include <vector>
+
+#include "perfetto/base/status.h"
+#include "src/trace_processor/perfetto_sql/pipeline/logical_plan.h"
+#include "src/trace_processor/perfetto_sql/pipeline/operation_registry.h"
+#include "src/trace_processor/perfetto_sql/pipeline/plan_types.h"
+
+namespace perfetto::trace_processor::pipeline {
+
+class Lowering;
+class PlanNode;
+
+// `|> DISTINCT`. Keeps one row of each set of rows equal in every column of
+// the row, in the order they are first seen.
+class Distinct : public PlanOperation {
+ public:
+  static const OperationRegistration kRegistration;
+
+ private:
+  // Test-only formatting; keep payload details out of the public interface.
+  friend class LogicalPlanFormatter;
+
+  // PlanOperation implementation. Dispatch goes through the base interface.
+  std::unique_ptr<PlanOperation> Clone() const override;
+  std::optional<uint32_t> Prune(std::vector<bool>* needed) override;
+  void Lower(Lowering*, const PlanNode&) const override;
+  void Write(PlanWriter*, const PlanNode&, Available*) const override;
+
+  static base::Status BuildPlan(Compiler*, uint32_t);
+  static void DecodePlan(PlanReader*, Available*);
+
+  const OperationRegistration& registration() const override;
+
+  std::vector<ColumnId> columns_;
+};
+
+}  // namespace perfetto::trace_processor::pipeline
+
+#endif  // SRC_TRACE_PROCESSOR_PERFETTO_SQL_PIPELINE_OPERATIONS_DISTINCT_H_
diff --git a/src/trace_processor/perfetto_sql/pipeline/operations/interval_fill_gaps.cc b/src/trace_processor/perfetto_sql/pipeline/operations/interval_fill_gaps.cc
new file mode 100644
index 0000000..215aef2
--- /dev/null
+++ b/src/trace_processor/perfetto_sql/pipeline/operations/interval_fill_gaps.cc
@@ -0,0 +1,361 @@
+/*
+ * Copyright (C) 2026 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.
+ */
+
+#include "src/trace_processor/perfetto_sql/pipeline/operations/interval_fill_gaps.h"
+
+#include <algorithm>
+#include <cstdint>
+#include <memory>
+#include <optional>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include "perfetto/base/logging.h"
+#include "perfetto/base/status.h"
+#include "perfetto/ext/base/status_macros.h"
+#include "perfetto/ext/base/status_or.h"
+#include "perfetto/ext/base/string_utils.h"
+#include "src/perfetto_sql/syntaqlite/syntaqlite_perfetto.h"
+#include "src/trace_processor/core/common/storage_types.h"
+#include "src/trace_processor/core/exec/interval_fill_gaps.h"
+#include "src/trace_processor/core/exec/pipeline.h"
+#include "src/trace_processor/perfetto_sql/pipeline/compiler.h"
+#include "src/trace_processor/perfetto_sql/pipeline/operations/scan.h"
+#include "src/trace_processor/perfetto_sql/pipeline/physical_plan.h"
+#include "src/trace_processor/perfetto_sql/pipeline/plan_serialization.h"
+
+namespace perfetto::trace_processor::pipeline {
+namespace ex = core::exec;
+
+const OperationRegistration IntervalFillGaps::kRegistration{
+    SYNTAQLITE_NODE_PERFETTO_INTERVAL_FILL_GAPS, &BuildPlan,
+    OperationRegistration::Encoding{6, false, &DecodePlan}};
+
+namespace {
+
+// The column named `name`, or nullopt if there is none.
+std::optional<ColumnId> FindColumn(const std::vector<NamedColumn>& columns,
+                                   const std::string& name) {
+  for (const NamedColumn& column : columns) {
+    if (base::CaseInsensitiveEqual(column.name, name)) {
+      return column.id;
+    }
+  }
+  return std::nullopt;
+}
+
+bool IsBounds(const std::string& name) {
+  return base::CaseInsensitiveEqual(name, "ts") ||
+         base::CaseInsensitiveEqual(name, "dur");
+}
+
+// The type of an output column. ts and dur are Int64, since lowering converts
+// them. Other columns get the type both sides convert to. Fillers can make
+// any column null, and Id columns cannot hold nulls, so Id becomes Uint32.
+// Returns nullopt if one side is a string and the other a number.
+std::optional<PlanType> OutputType(const PlanType& input,
+                                   const PlanType* background,
+                                   bool bounds) {
+  if (bounds) {
+    return PlanType(core::Int64{});
+  }
+  std::optional<PlanType> type =
+      background ? CommonType(input, *background) : input;
+  if (type && type->Is<core::Id>()) {
+    return PlanType(core::Uint32{});
+  }
+  return type;
+}
+
+}  // namespace
+
+base::Status IntervalFillGaps::BuildPlan(Compiler* c, uint32_t stage) {
+  c->SetOperation("INTERVAL FILL GAPS");
+  const auto* n = Node<SyntaqlitePerfettoIntervalFillGaps>(c->parser(), stage);
+
+  IntervalFillGaps fill;
+  ASSIGN_OR_RETURN(fill.ts_, c->Resolve("ts", stage));
+  ASSIGN_OR_RETURN(fill.dur_, c->Resolve("dur", stage));
+  std::vector<std::string> per;
+  if (syntaqlite_node_is_present(n->per)) {
+    const auto* list =
+        Node<SyntaqlitePerfettoPerColumnList>(c->parser(), n->per);
+    for (uint32_t i = 0; i < syntaqlite_list_count(list); ++i) {
+      uint32_t col_id = syntaqlite_list_child_id(list, i);
+      std::string name = SpanText(
+          c->parser(),
+          Node<SyntaqlitePerfettoPerColumn>(c->parser(), col_id)->name);
+      ASSIGN_OR_RETURN(ColumnId key, c->Resolve(name, col_id));
+      // A PER column listed again adds nothing to the grouping.
+      if (std::find(fill.keys_.begin(), fill.keys_.end(), key) !=
+          fill.keys_.end()) {
+        continue;
+      }
+      fill.keys_.push_back(key);
+      per.push_back(name);
+    }
+  }
+
+  // The input is the plan so far. The background is added as a new scan.
+  PlanNodeId input = c->plan().root();
+  ASSIGN_OR_RETURN(SourceRelation background,
+                   Scan::BuildRelation(c, n->background));
+  std::optional<ColumnId> ts = FindColumn(background.columns, "ts");
+  std::optional<ColumnId> dur = FindColumn(background.columns, "dur");
+  if (!ts || !dur) {
+    return c->Expected(n->background, std::string("the background to have a ") +
+                                          (ts ? "dur" : "ts") + " column");
+  }
+  fill.background_ts_ = *ts;
+  fill.background_dur_ = *dur;
+  for (const std::string& name : per) {
+    if (std::optional<ColumnId> key = FindColumn(background.columns, name)) {
+      fill.background_keys_.push_back(*key);
+    }
+  }
+  if (!fill.background_keys_.empty() &&
+      fill.background_keys_.size() != fill.keys_.size()) {
+    return c->Expected(n->background,
+                       "the background to have every PER column or none");
+  }
+
+  // Fillers take each column from the background column with the same name.
+  // Columns only reachable through an alias are not matched.
+  const auto& types = c->plan().columns();
+  std::vector<Compiler::RowColumn> row;
+  std::vector<std::pair<ColumnId, ColumnId>> replaced;
+  std::vector<ColumnId> matched;
+  for (const Compiler::RowColumn& column : c->row()) {
+    Output output;
+    output.input = column.column.id;
+    bool bounds = column.column.id == fill.ts_ || column.column.id == fill.dur_;
+    if (!column.qualified_only && !bounds && !IsBounds(column.column.name)) {
+      output.background = FindColumn(background.columns, column.column.name);
+    }
+    std::optional<PlanType> type = OutputType(
+        types[output.input].type,
+        output.background ? &types[*output.background].type : nullptr, bounds);
+    if (!type) {
+      return c->Expected(n->background,
+                         "the background's '" + column.column.name +
+                             "' to hold the same kind of values as the "
+                             "input's");
+    }
+    if (output.background) {
+      matched.push_back(*output.background);
+    }
+    output.column = c->AddColumn(column.column.name, *type);
+    fill.outputs_.push_back(output);
+    replaced.emplace_back(column.column.id, output.column);
+    Compiler::RowColumn out = column;
+    out.column.id = output.column;
+    row.push_back(std::move(out));
+  }
+  for (const NamedColumn& column : background.columns) {
+    if (!IsBounds(column.name) &&
+        std::find(matched.begin(), matched.end(), column.id) == matched.end()) {
+      return c->Expected(n->background, "the input to have the background's '" +
+                                            column.name + "'");
+    }
+  }
+  // Aliases still refer to their columns.
+  c->ReplaceRow(std::move(row));
+  c->ReplaceAliasColumns(replaced);
+  c->AddNode(std::move(fill), {input, background.node});
+  return base::OkStatus();
+}
+
+std::optional<uint32_t> IntervalFillGaps::Prune(std::vector<bool>* needed) {
+  outputs_.erase(std::remove_if(outputs_.begin(), outputs_.end(),
+                                [&](const Output& output) {
+                                  return !(*needed)[output.column];
+                                }),
+                 outputs_.end());
+  // ts, dur and the PER columns on both sides decide where the fillers go.
+  for (ColumnId id : {ts_, dur_, background_ts_, background_dur_}) {
+    (*needed)[id] = true;
+  }
+  for (ColumnId key : keys_) {
+    (*needed)[key] = true;
+  }
+  for (ColumnId key : background_keys_) {
+    (*needed)[key] = true;
+  }
+  for (const Output& output : outputs_) {
+    (*needed)[output.input] = true;
+    if (output.background) {
+      (*needed)[*output.background] = true;
+    }
+  }
+  return std::nullopt;
+}
+
+void IntervalFillGaps::Lower(Lowering* c, const PlanNode& node) const {
+  const auto& fill = *this;
+  c->LowerNode(node.children()[0]);
+  // The background is read from its own side pipeline.
+  Lowering& background = c->AddSidePipeline();
+  background.LowerNode(node.children()[1]);
+
+  // Columns present on both sides are converted to a common type.
+  for (const Output& output : fill.outputs_) {
+    if (output.background) {
+      c->RequireCommonType(
+          {{c, output.input}, {&background, *output.background}});
+    }
+  }
+
+  // PER columns are numbered in one table, so both sides need one type even
+  // if they are not output.
+  for (size_t k = 0; k < fill.background_keys_.size(); ++k) {
+    c->RequireCommonType(
+        {{c, fill.keys_[k]}, {&background, fill.background_keys_[k]}});
+  }
+
+  ex::IntervalFillGapsSpec spec;
+  spec.input = c->RequireIntervalLanes(fill.ts_, fill.dur_, fill.keys_);
+  spec.input.forever = true;
+  spec.background.lanes = background.RequireIntervalLanes(
+      fill.background_ts_, fill.background_dur_, fill.background_keys_);
+  for (const Output& output : fill.outputs_) {
+    ex::IntervalFillGapsSpec::Output lowered;
+    lowered.input = c->QueryPosition(output.input);
+    if (output.background) {
+      // Only the background columns fillers take are kept.
+      lowered.background =
+          static_cast<uint32_t>(spec.background.retained_columns.size());
+      spec.background.retained_columns.push_back(
+          background.QueryPosition(*output.background));
+    }
+    const auto& column = c->plan().columns()[output.column];
+    lowered.fallback =
+        column.type.storage().value_or(core::StorageType{core::Int64{}});
+    lowered.name = column.name;
+    spec.outputs.push_back(std::move(lowered));
+  }
+  spec.background.source = background.FinishSide();
+  c->AddOperator(std::make_unique<ex::IntervalFillGaps>(std::move(spec)));
+
+  // The output has a new layout and no known order. Filler batches can be
+  // small.
+  c->ResetLayout();
+  for (const Output& output : fill.outputs_) {
+    c->DeclareColumn(output.column);
+  }
+  c->DeclareSmallBatches();
+}
+
+const OperationRegistration& IntervalFillGaps::registration() const {
+  return kRegistration;
+}
+
+std::unique_ptr<PlanOperation> IntervalFillGaps::Clone() const {
+  return std::make_unique<IntervalFillGaps>(*this);
+}
+
+// Writes the background's scan inline, then replaces `available` with the
+// output columns.
+void IntervalFillGaps::Write(PlanWriter* c,
+                             const PlanNode& node,
+                             Available* available_columns) const {
+  auto& available = *available_columns;
+  const auto& fill = *this;
+  c->writer().Position(available, fill.ts_);
+  c->writer().Position(available, fill.dur_);
+  c->writer().Size(fill.keys_.size());
+  for (ColumnId key : fill.keys_) {
+    c->writer().Position(available, key);
+  }
+  const PlanNode& child = c->plan().nodes()[node.children()[1]];
+  PERFETTO_CHECK(child.Is<Scan>());
+  Available in;
+  child.operation().Write(c, child, &in);
+  c->writer().Position(in, fill.background_ts_);
+  c->writer().Position(in, fill.background_dur_);
+  c->writer().Size(fill.background_keys_.size());
+  for (ColumnId key : fill.background_keys_) {
+    c->writer().Position(in, key);
+  }
+  // An output's type is derived from its inputs, so only its name is written.
+  c->writer().Size(fill.outputs_.size());
+  for (const Output& output : fill.outputs_) {
+    c->writer().Str(c->plan().columns()[output.column].name);
+    c->writer().Position(available, output.input);
+    c->writer().U8(output.background ? 1 : 0);
+    if (output.background) {
+      c->writer().Position(in, *output.background);
+    }
+  }
+  available.clear();
+  for (const Output& output : fill.outputs_) {
+    available.push_back(output.column);
+  }
+}
+
+void IntervalFillGaps::DecodePlan(PlanReader* c, Available* available_columns) {
+  auto& available = *available_columns;
+  PlanNodeId input = c->plan().root();
+  IntervalFillGaps fill;
+  fill.ts_ = c->reader().Position(available);
+  fill.dur_ = c->reader().Position(available);
+  fill.keys_.resize(c->reader().Count());
+  for (ColumnId& key : fill.keys_) {
+    key = c->reader().Position(available);
+  }
+  Scan scan;
+  Available in = Scan::ReadPayload(c, &scan);
+  if (!c->reader().ok()) {
+    return;
+  }
+  PlanNodeId background = c->AddNode(std::move(scan));
+  fill.background_ts_ = c->reader().Position(in);
+  fill.background_dur_ = c->reader().Position(in);
+  fill.background_keys_.resize(c->reader().Count());
+  if (!fill.background_keys_.empty() &&
+      fill.background_keys_.size() != fill.keys_.size()) {
+    c->reader().Fail();
+    return;
+  }
+  for (ColumnId& key : fill.background_keys_) {
+    key = c->reader().Position(in);
+  }
+  const auto& types = c->plan().columns();
+  fill.outputs_.resize(c->reader().Count());
+  for (Output& output : fill.outputs_) {
+    std::string name = c->reader().Str();
+    output.input = c->reader().Position(available);
+    if (c->reader().U8()) {
+      output.background = c->reader().Position(in);
+    }
+    std::optional<PlanType> type = OutputType(
+        types[output.input].type,
+        output.background ? &types[*output.background].type : nullptr,
+        output.input == fill.ts_ || output.input == fill.dur_);
+    if (!c->reader().ok() || !type) {
+      c->reader().Fail();
+      return;
+    }
+    output.column = c->AddColumn(std::move(name), *type);
+  }
+  available.clear();
+  for (const Output& output : fill.outputs_) {
+    available.push_back(output.column);
+  }
+  c->AddNode(std::move(fill), {input, background});
+}
+
+}  // namespace perfetto::trace_processor::pipeline
diff --git a/src/trace_processor/perfetto_sql/pipeline/operations/interval_fill_gaps.h b/src/trace_processor/perfetto_sql/pipeline/operations/interval_fill_gaps.h
new file mode 100644
index 0000000..d471aeb
--- /dev/null
+++ b/src/trace_processor/perfetto_sql/pipeline/operations/interval_fill_gaps.h
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2026 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.
+ */
+
+#ifndef SRC_TRACE_PROCESSOR_PERFETTO_SQL_PIPELINE_OPERATIONS_INTERVAL_FILL_GAPS_H_
+#define SRC_TRACE_PROCESSOR_PERFETTO_SQL_PIPELINE_OPERATIONS_INTERVAL_FILL_GAPS_H_
+
+#include <cstdint>
+#include <memory>
+#include <optional>
+#include <vector>
+
+#include "src/trace_processor/perfetto_sql/pipeline/logical_plan.h"
+#include "src/trace_processor/perfetto_sql/pipeline/plan_types.h"
+
+namespace perfetto::trace_processor::pipeline {
+
+class Lowering;
+class PlanNode;
+
+// `|> INTERVAL FILL GAPS WITH rel [PER cols]`. Outputs every input row. Also
+// outputs a row for each part of `rel` that input in the same lane does not
+// cover. These rows take their values from `rel` by column name.
+//
+// The node has two children: the input, then a scan of the background.
+class IntervalFillGaps : public PlanOperation {
+ public:
+  static const OperationRegistration kRegistration;
+
+ private:
+  // An output column. Fillers always use their own ts and dur.
+  struct Output {
+    ColumnId column = 0;
+
+    // The input column, used by input rows.
+    ColumnId input = 0;
+
+    // The background column with the same name, used by fillers. Empty if
+    // the background has no such column.
+    std::optional<ColumnId> background;
+  };
+
+  // Test-only formatting; keep payload details out of the public interface.
+  friend class LogicalPlanFormatter;
+
+  // PlanOperation implementation. Dispatch goes through the base interface.
+  std::unique_ptr<PlanOperation> Clone() const override;
+  std::optional<uint32_t> Prune(std::vector<bool>* needed) override;
+  void Lower(Lowering*, const PlanNode&) const override;
+  void Write(PlanWriter*, const PlanNode&, Available*) const override;
+
+  static base::Status BuildPlan(Compiler*, uint32_t);
+  static void DecodePlan(PlanReader*, Available*);
+
+  const OperationRegistration& registration() const override;
+
+  ColumnId ts_ = 0;
+  ColumnId dur_ = 0;
+  std::vector<ColumnId> keys_;
+  ColumnId background_ts_ = 0;
+  ColumnId background_dur_ = 0;
+  // The background columns matching keys_, in the same order, or empty.
+  std::vector<ColumnId> background_keys_;
+  std::vector<Output> outputs_;
+};
+
+}  // namespace perfetto::trace_processor::pipeline
+
+#endif  // SRC_TRACE_PROCESSOR_PERFETTO_SQL_PIPELINE_OPERATIONS_INTERVAL_FILL_GAPS_H_
diff --git a/src/trace_processor/perfetto_sql/pipeline/operations/interval_flatten.cc b/src/trace_processor/perfetto_sql/pipeline/operations/interval_flatten.cc
index cc2dffe..d4ce2fa 100644
--- a/src/trace_processor/perfetto_sql/pipeline/operations/interval_flatten.cc
+++ b/src/trace_processor/perfetto_sql/pipeline/operations/interval_flatten.cc
@@ -54,15 +54,17 @@
   if (syntaqlite_node_is_present(n->per)) {
     const auto* per =
         Node<SyntaqlitePerfettoPerColumnList>(c->parser(), n->per);
-    std::vector<std::string> seen;
     for (uint32_t i = 0; i < syntaqlite_list_count(per); ++i) {
       uint32_t col_id = syntaqlite_list_child_id(per, i);
       std::string name = SpanText(
           c->parser(),
           Node<SyntaqlitePerfettoPerColumn>(c->parser(), col_id)->name);
-      RETURN_IF_ERROR(c->CheckListedOnce(seen, name, col_id));
       ASSIGN_OR_RETURN(ColumnId key, c->Resolve(name, col_id));
-      flatten.keys_.push_back(key);
+      // Groups once by each column, but outputs one column per item listed.
+      if (std::find(flatten.keys_.begin(), flatten.keys_.end(), key) ==
+          flatten.keys_.end()) {
+        flatten.keys_.push_back(key);
+      }
       keys.push_back({NamedColumn{std::move(name), key}, col_id});
     }
   }
@@ -114,18 +116,9 @@
   const auto& flatten = *this;
   c->LowerNode(node.children()[0]);
 
-  c->RequireType(flatten.ts_, core::Int64{});
-  c->RequireType(flatten.dur_, core::Int64{});
-  c->RequireSortedWithinGroups(flatten.keys_, {{flatten.ts_, false}});
   ex::IntervalFlattenSpec spec;
-  spec.ts_column = c->QueryPosition(flatten.ts_);
-  spec.dur_column = c->QueryPosition(flatten.dur_);
-  for (ColumnId key : flatten.keys_) {
-    spec.key_columns.push_back(c->QueryPosition(key));
-  }
-  if (!flatten.keys_.empty()) {
-    spec.group_column = c->RequireGroupNumbers(flatten.keys_);
-  }
+  spec.lanes =
+      c->RequireIntervalLanes(flatten.ts_, flatten.dur_, flatten.keys_);
   for (const Aggregate& agg : flatten.aggregates_) {
     spec.aggregates.push_back(LowerAggregate(c, agg));
   }
diff --git a/src/trace_processor/perfetto_sql/pipeline/operations/interval_intersect.cc b/src/trace_processor/perfetto_sql/pipeline/operations/interval_intersect.cc
index f4cf269..711cbf2 100644
--- a/src/trace_processor/perfetto_sql/pipeline/operations/interval_intersect.cc
+++ b/src/trace_processor/perfetto_sql/pipeline/operations/interval_intersect.cc
@@ -32,6 +32,7 @@
 #include "src/perfetto_sql/syntaqlite/syntaqlite_perfetto.h"
 #include "src/trace_processor/core/common/storage_types.h"
 #include "src/trace_processor/core/exec/interval_intersect.h"
+#include "src/trace_processor/core/exec/interval_lanes.h"
 #include "src/trace_processor/core/exec/pipeline.h"
 #include "src/trace_processor/perfetto_sql/pipeline/compiler.h"
 #include "src/trace_processor/perfetto_sql/pipeline/operations/scan.h"
@@ -74,7 +75,20 @@
       syntaqlite_node_is_present(n->per)
           ? Node<SyntaqlitePerfettoPerColumnList>(c->parser(), n->per)
           : nullptr;
-  uint32_t key_count = per ? syntaqlite_list_count(per) : 0;
+  // A PER column listed again adds nothing to the grouping.
+  std::vector<std::pair<std::string, uint32_t>> per_columns;
+  for (uint32_t k = 0; per && k < syntaqlite_list_count(per); k++) {
+    uint32_t col_id = syntaqlite_list_child_id(per, k);
+    std::string name =
+        SpanText(c->parser(),
+                 Node<SyntaqlitePerfettoPerColumn>(c->parser(), col_id)->name);
+    if (std::none_of(per_columns.begin(), per_columns.end(),
+                     [&](const auto& p) {
+                       return base::CaseInsensitiveEqual(p.first, name);
+                     })) {
+      per_columns.emplace_back(std::move(name), col_id);
+    }
+  }
 
   IntervalIntersect isect;
   // The region's bounds are the operation's own, so they are named before an
@@ -108,24 +122,25 @@
     IntervalIntersect::Operand operand;
     operand.ts = *ts;
     operand.dur = *dur;
-    for (uint32_t k = 0; k < key_count; k++) {
-      uint32_t col_id = syntaqlite_list_child_id(per, k);
-      const auto* col = Node<SyntaqlitePerfettoPerColumn>(c->parser(), col_id);
-      std::string name = SpanText(c->parser(), col->name);
+    for (const auto& [name, col_id] : per_columns) {
       std::optional<ColumnId> key = FindColumn(relation.columns, name);
       if (!key) {
         return c->Expected(col_id, *alias + " to have a " + name + " column");
       }
       operand.keys.push_back(*key);
     }
-    // Every operand column is carried, reachable through the operand's alias.
-    // A PER column holds the same value in every operand, so the first
-    // operand's is also the one a bare name finds.
+    // Every operand column is carried, reachable through the operand's alias
+    // and, for most, by its bare name too. The region's ts and dur are what
+    // a bare ts and dur mean, so an operand's own are found only through its
+    // alias. A PER column holds the same value in every operand, so only the
+    // first operand's is found by its bare name.
     Compiler::Alias operand_alias{*alias, {}};
     for (const NamedColumn& column : relation.columns) {
       bool is_key = std::find(operand.keys.begin(), operand.keys.end(),
                               column.id) != operand.keys.end();
-      c->Append(column, source_id, /*qualified_only=*/!(is_key && i == 0));
+      bool is_bound = column.id == operand.ts || column.id == operand.dur;
+      c->Append(column, source_id,
+                /*qualified_only=*/is_bound || (is_key && i != 0));
       operand_alias.columns.push_back(c->row().back());
       operand.carried.push_back(column.id);
     }
@@ -170,15 +185,11 @@
   c->DeclareColumn(isect.ts_);
   c->DeclareColumn(isect.dur_);
 
-  // Each operand is read from its own side pipeline, which converts ts and
-  // dur to Int64 if needed.
+  // Each operand is read from its own side pipeline.
   std::vector<Lowering*> sides;
   for (uint32_t i = 0; i < isect.operands_.size(); i++) {
-    const IntervalIntersect::Operand& operand = isect.operands_[i];
     Lowering& side = c->AddSidePipeline();
     side.LowerNode(children[i]);
-    side.RequireType(operand.ts, core::Int64{});
-    side.RequireType(operand.dur, core::Int64{});
     sides.push_back(&side);
   }
 
@@ -194,22 +205,13 @@
     c->RequireCommonType(same);
   }
 
-  std::vector<ex::IntervalIntersectOperand> inputs;
+  std::vector<ex::CollectedInputSpec> inputs;
   for (uint32_t i = 0; i < isect.operands_.size(); i++) {
     const IntervalIntersect::Operand& operand = isect.operands_[i];
     Lowering& side = *sides[i];
-    ex::IntervalIntersectOperand lowered;
-    // The operator reads each key's intervals sorted by start.
-    std::vector<SortKey> by_start = {{operand.ts, false}};
-    side.RequireSortedWithinGroups(operand.keys, by_start);
-    if (!operand.keys.empty()) {
-      lowered.group_column = side.RequireGroupNumbers(operand.keys);
-    }
-    lowered.ts_column = side.QueryPosition(operand.ts);
-    lowered.dur_column = side.QueryPosition(operand.dur);
-    for (ColumnId key : operand.keys) {
-      lowered.key_columns.push_back(side.QueryPosition(key));
-    }
+    ex::CollectedInputSpec lowered;
+    lowered.lanes =
+        side.RequireIntervalLanes(operand.ts, operand.dur, operand.keys);
     for (ColumnId id : operand.carried) {
       lowered.retained_columns.push_back(side.QueryPosition(id));
     }
diff --git a/src/trace_processor/perfetto_sql/pipeline/operations/projection.cc b/src/trace_processor/perfetto_sql/pipeline/operations/projection.cc
index d146d00..419906a 100644
--- a/src/trace_processor/perfetto_sql/pipeline/operations/projection.cc
+++ b/src/trace_processor/perfetto_sql/pipeline/operations/projection.cc
@@ -44,6 +44,15 @@
 base::StatusOr<std::vector<Compiler::RowColumn>>
 ExpandStar(Compiler*, uint32_t star_id, bool allow_unqualified_star);
 
+// Resolves an item's expression, which must be a column reference.
+base::StatusOr<ColumnId> ResolveColumnItem(Compiler* c, uint32_t expr) {
+  if (Node<SyntaqliteNode>(c->parser(), expr)->tag !=
+      SYNTAQLITE_NODE_COLUMN_REF) {
+    return c->Unsupported(expr, "a computed column");
+  }
+  return c->ResolveColumnExpr(expr);
+}
+
 // Replaces the row. What it leaves is a new table: no alias reaches into it.
 base::Status BuildSelectPlan(Compiler* c, uint32_t stage) {
   c->SetOperation("SELECT");
@@ -146,14 +155,7 @@
     std::string name = SpanText(c->parser(), item->name);
     RETURN_IF_ERROR(c->CheckListedOnce(seen, name, item_id));
     ASSIGN_OR_RETURN(size_t at, c->FindInRow(name, item_id));
-    const auto* value =
-        Node<SyntaqlitePerfettoPipeColumn>(c->parser(), item->value);
-    std::string qualifier = IsSpanPresent(value->qualifier)
-                                ? SpanText(c->parser(), value->qualifier)
-                                : "";
-    ASSIGN_OR_RETURN(
-        ColumnId id,
-        c->Resolve(qualifier, SpanText(c->parser(), value->name), item->value));
+    ASSIGN_OR_RETURN(ColumnId id, ResolveColumnItem(c, item->value));
     assignments.push_back({at, id, item_id});
   }
   for (const Assignment& assignment : assignments) {
@@ -162,12 +164,20 @@
   return base::OkStatus();
 }
 
-// Replaces every alias with one covering the whole row as it is now.
+// Replaces every alias with one covering the row as a bare name sees it now.
+// Columns which only an earlier alias found go with that alias.
 base::Status BuildAsPlan(Compiler* c, uint32_t stage) {
   c->SetOperation("AS");
   const auto* n = Node<SyntaqlitePerfettoPipeAs>(c->parser(), stage);
+  std::vector<Compiler::RowColumn> row;
+  for (const Compiler::RowColumn& column : c->row()) {
+    if (!column.qualified_only) {
+      row.push_back(column);
+    }
+  }
   c->ClearAliases();
-  c->AddAlias({SpanText(c->parser(), n->alias), c->row()});
+  c->AddAlias({SpanText(c->parser(), n->alias), row});
+  c->ReplaceRow(std::move(row));
   return base::OkStatus();
 }
 
@@ -185,15 +195,14 @@
       columns.insert(columns.end(), expanded.begin(), expanded.end());
       continue;
     }
-    const auto* item = Node<SyntaqlitePerfettoPipeColumn>(c->parser(), item_id);
-    std::string qualifier = IsSpanPresent(item->qualifier)
-                                ? SpanText(c->parser(), item->qualifier)
-                                : "";
-    std::string name = SpanText(c->parser(), item->name);
-    ASSIGN_OR_RETURN(ColumnId id, c->Resolve(qualifier, name, item_id));
-    if (IsSpanPresent(item->alias)) {
-      name = SpanText(c->parser(), item->alias);
-    }
+    const auto* item =
+        Node<SyntaqlitePerfettoPipeExprItem>(c->parser(), item_id);
+    ASSIGN_OR_RETURN(ColumnId id, ResolveColumnItem(c, item->expr));
+    std::string name = IsSpanPresent(item->alias)
+                           ? SpanText(c->parser(), item->alias)
+                           : SpanText(c->parser(), Node<SyntaqliteNode>(
+                                                       c->parser(), item->expr)
+                                                       ->column_ref.column);
     columns.push_back({{std::move(name), id}, c->operation(), item_id});
   }
   return columns;
@@ -215,7 +224,13 @@
     if (!allow_unqualified_star) {
       return c->Expected(star_id, "a table alias before the star, as in `t.*`");
     }
-    columns = c->row();
+    // A bare star is the columns a bare name finds. Others, as an
+    // intersection's operand columns are, come through their alias.
+    for (const Compiler::RowColumn& column : c->row()) {
+      if (!column.qualified_only) {
+        columns.push_back(column);
+      }
+    }
   }
 
   if (syntaqlite_node_is_present(star->except)) {
diff --git a/src/trace_processor/perfetto_sql/pipeline/operations/where.cc b/src/trace_processor/perfetto_sql/pipeline/operations/where.cc
new file mode 100644
index 0000000..b455128
--- /dev/null
+++ b/src/trace_processor/perfetto_sql/pipeline/operations/where.cc
@@ -0,0 +1,243 @@
+/*
+ * Copyright (C) 2026 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.
+ */
+
+#include "src/trace_processor/perfetto_sql/pipeline/operations/where.h"
+
+#include <cstdint>
+#include <memory>
+#include <optional>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include "perfetto/base/logging.h"
+#include "perfetto/base/status.h"
+#include "perfetto/ext/base/status_macros.h"
+#include "perfetto/ext/base/status_or.h"
+#include "perfetto/ext/base/string_utils.h"
+#include "src/perfetto_sql/syntaqlite/syntaqlite_perfetto.h"
+#include "src/trace_processor/core/common/op_types.h"
+#include "src/trace_processor/core/common/storage_types.h"
+#include "src/trace_processor/core/common/value_fetcher.h"
+#include "src/trace_processor/core/exec/filter.h"
+#include "src/trace_processor/core/exec/filter_value.h"
+#include "src/trace_processor/perfetto_sql/pipeline/compiler.h"
+#include "src/trace_processor/perfetto_sql/pipeline/physical_plan.h"
+#include "src/trace_processor/perfetto_sql/pipeline/plan_serialization.h"
+
+namespace perfetto::trace_processor::pipeline {
+namespace ex = core::exec;
+namespace {
+
+// Hands a WHERE literal to the shared filter value casts, so it means for
+// each column type what any other filter value means.
+struct LiteralFetcher : core::ValueFetcher {
+  static constexpr Type kInt64 = 0;
+  static constexpr Type kDouble = 1;
+  static constexpr Type kString = 2;
+  static constexpr Type kNull = 3;
+
+  explicit LiteralFetcher(const WherePredicate& p) : predicate(p) {}
+
+  Type GetValueType(uint32_t) const {
+    return predicate.is_double ? kDouble : kInt64;
+  }
+  int64_t GetInt64Value(uint32_t) const { return predicate.int_value; }
+  double GetDoubleValue(uint32_t) const { return predicate.double_value; }
+  const char* GetStringValue(uint32_t) const {
+    PERFETTO_FATAL("WHERE literals are numbers");
+  }
+
+  const WherePredicate& predicate;
+};
+
+// Reads a number literal, optionally negated, into `out`.
+base::Status ParseLiteral(Compiler* c, uint32_t expr, WherePredicate* out) {
+  SyntaqliteParser* p = c->parser();
+  const auto* node = Node<SyntaqliteNode>(p, expr);
+  bool negate = false;
+  if (node->tag == SYNTAQLITE_NODE_UNARY_EXPR &&
+      node->unary_expr.op == SYNTAQLITE_UNARY_OP_MINUS) {
+    negate = true;
+    node = Node<SyntaqliteNode>(p, node->unary_expr.operand);
+  }
+  if (node->tag != SYNTAQLITE_NODE_LITERAL) {
+    return c->Unsupported(expr, "a value other than a number literal");
+  }
+  const SyntaqliteLiteral& literal = node->literal;
+  std::string text = SpanText(p, literal.source);
+  if (literal.literal_type == SYNTAQLITE_LITERAL_TYPE_INTEGER) {
+    std::optional<int64_t> value = base::StringToInt64(text);
+    if (!value) {
+      return c->Unsupported(expr, "a number which does not fit an integer");
+    }
+    out->is_double = false;
+    out->int_value = negate ? -*value : *value;
+    return base::OkStatus();
+  }
+  if (literal.literal_type == SYNTAQLITE_LITERAL_TYPE_FLOAT) {
+    std::optional<double> value = base::StringToDouble(text);
+    if (!value) {
+      return c->Unsupported(expr, "a malformed number");
+    }
+    out->is_double = true;
+    out->double_value = negate ? -*value : *value;
+    return base::OkStatus();
+  }
+  return c->Unsupported(expr, "a literal other than a number");
+}
+
+base::StatusOr<WherePredicate> ParsePredicate(Compiler* c, uint32_t expr) {
+  const auto* node = Node<SyntaqliteNode>(c->parser(), expr);
+  if (node->tag != SYNTAQLITE_NODE_BINARY_EXPR) {
+    return c->Unsupported(expr, "a condition other than column OP value");
+  }
+  WherePredicate predicate;
+  SyntaqliteBinaryOp op = node->binary_expr.op;
+  if (op == SYNTAQLITE_BINARY_OP_EQ) {
+    predicate.op = core::Eq{};
+  } else if (op == SYNTAQLITE_BINARY_OP_NE) {
+    predicate.op = core::Ne{};
+  } else if (op == SYNTAQLITE_BINARY_OP_LT) {
+    predicate.op = core::Lt{};
+  } else if (op == SYNTAQLITE_BINARY_OP_LE) {
+    predicate.op = core::Le{};
+  } else if (op == SYNTAQLITE_BINARY_OP_GT) {
+    predicate.op = core::Gt{};
+  } else if (op == SYNTAQLITE_BINARY_OP_GE) {
+    predicate.op = core::Ge{};
+  } else {
+    return c->Unsupported(expr, "an operator other than =, !=, <, <=, >, >=");
+  }
+  ASSIGN_OR_RETURN(predicate.column,
+                   c->ResolveColumnExpr(node->binary_expr.left));
+  RETURN_IF_ERROR(ParseLiteral(c, node->binary_expr.right, &predicate));
+  return predicate;
+}
+
+base::Status ParseCondition(Compiler* c,
+                            uint32_t expr,
+                            std::vector<WherePredicate>* out) {
+  const auto* node = Node<SyntaqliteNode>(c->parser(), expr);
+  if (node->tag == SYNTAQLITE_NODE_BINARY_EXPR &&
+      node->binary_expr.op == SYNTAQLITE_BINARY_OP_AND) {
+    RETURN_IF_ERROR(ParseCondition(c, node->binary_expr.left, out));
+    return ParseCondition(c, node->binary_expr.right, out);
+  }
+  ASSIGN_OR_RETURN(WherePredicate predicate, ParsePredicate(c, expr));
+  out->push_back(predicate);
+  return base::OkStatus();
+}
+
+}  // namespace
+
+const OperationRegistration Where::kRegistration{
+    SYNTAQLITE_NODE_PERFETTO_PIPE_WHERE, &BuildPlan,
+    OperationRegistration::Encoding{8, false, &DecodePlan}};
+
+base::Status Where::BuildPlan(Compiler* c, uint32_t stage) {
+  c->SetOperation("WHERE");
+  const auto* n = Node<SyntaqlitePerfettoPipeWhere>(c->parser(), stage);
+  Where where;
+  RETURN_IF_ERROR(ParseCondition(c, n->condition, &where.predicates_));
+  c->AddNode(std::move(where), {c->plan().root()});
+  return base::OkStatus();
+}
+
+std::optional<uint32_t> Where::Prune(std::vector<bool>* needed) {
+  for (const WherePredicate& p : predicates_) {
+    (*needed)[p.column] = true;
+  }
+  return std::nullopt;
+}
+
+void Where::Lower(Lowering* c, const PlanNode& node) const {
+  c->LowerNode(node.children()[0]);
+  std::vector<ex::Filter::Condition> conditions;
+  for (const WherePredicate& p : predicates_) {
+    // Filter reads only columns of one type. A column of no known type
+    // carries a type per row, so it is converted to the literal's.
+    std::optional<core::StorageType> type = c->QueryType(p.column).storage();
+    if (!type) {
+      type = p.is_double ? core::StorageType(core::Double{})
+                         : core::StorageType(core::Int64{});
+      c->RequireType(p.column, *type);
+    }
+    LiteralFetcher fetcher(p);
+    ex::FilterValue value;
+    ex::GetFilterValueCaster<LiteralFetcher>(*type, p.op)(
+        fetcher, 0, *c->context().pool, &value);
+
+    ex::Filter::Condition condition;
+    condition.column = c->QueryPosition(p.column);
+    condition.op = p.op;
+    condition.value = c->AddFilterValue(std::move(value));
+    conditions.push_back(condition);
+  }
+  c->AddOperator(
+      std::make_unique<ex::Filter>(std::move(conditions), c->context().pool));
+  c->DeclareSmallBatches();
+  c->DeclareRowsDropped();
+}
+
+const OperationRegistration& Where::registration() const {
+  return kRegistration;
+}
+
+std::unique_ptr<PlanOperation> Where::Clone() const {
+  return std::make_unique<Where>(*this);
+}
+
+void Where::Write(PlanWriter* c, const PlanNode&, Available* available) const {
+  c->writer().Size(predicates_.size());
+  for (const WherePredicate& p : predicates_) {
+    c->writer().Position(*available, p.column);
+    c->writer().U8(static_cast<uint8_t>(p.op.index()));
+    c->writer().U8(p.is_double ? 1 : 0);
+    if (p.is_double) {
+      c->writer().F64(p.double_value);
+    } else {
+      c->writer().U64(static_cast<uint64_t>(p.int_value));
+    }
+  }
+}
+
+void Where::DecodePlan(PlanReader* c, Available* available) {
+  Where where;
+  where.predicates_.resize(c->reader().Count());
+  if (where.predicates_.empty()) {
+    c->reader().Fail();
+  }
+  for (WherePredicate& p : where.predicates_) {
+    p.column = c->reader().Position(*available);
+    // Only comparisons are written; anything else is corrupt.
+    std::optional<core::Op> op = core::Op::FromIndex(c->reader().U8());
+    if (!op || !op->IsAnyOf<core::NonStringOp>()) {
+      c->reader().Fail();
+      continue;
+    }
+    p.op = *op;
+    p.is_double = c->reader().U8() != 0;
+    if (p.is_double) {
+      p.double_value = c->reader().F64();
+    } else {
+      p.int_value = static_cast<int64_t>(c->reader().U64());
+    }
+  }
+  c->AddNode(std::move(where), {c->plan().root()});
+}
+
+}  // namespace perfetto::trace_processor::pipeline
diff --git a/src/trace_processor/perfetto_sql/pipeline/operations/where.h b/src/trace_processor/perfetto_sql/pipeline/operations/where.h
new file mode 100644
index 0000000..b8fe5af
--- /dev/null
+++ b/src/trace_processor/perfetto_sql/pipeline/operations/where.h
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2026 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.
+ */
+
+#ifndef SRC_TRACE_PROCESSOR_PERFETTO_SQL_PIPELINE_OPERATIONS_WHERE_H_
+#define SRC_TRACE_PROCESSOR_PERFETTO_SQL_PIPELINE_OPERATIONS_WHERE_H_
+
+#include <cstdint>
+#include <memory>
+#include <optional>
+#include <vector>
+
+#include "perfetto/base/status.h"
+#include "src/trace_processor/core/common/op_types.h"
+#include "src/trace_processor/perfetto_sql/pipeline/logical_plan.h"
+#include "src/trace_processor/perfetto_sql/pipeline/operation_registry.h"
+#include "src/trace_processor/perfetto_sql/pipeline/plan_types.h"
+
+namespace perfetto::trace_processor::pipeline {
+
+class Lowering;
+class PlanNode;
+
+// A `column OP literal` test, where OP is one of =, !=, <, <=, >, >= and the
+// literal is a number. A WHERE condition is the AND of these. The literal is
+// compared as SQL compares it with the column's type, whatever that is.
+struct WherePredicate {
+  using Op = core::Op;
+
+  ColumnId column = 0;
+  Op op{core::Eq{}};
+  // The literal is `double_value` if set, `int_value` otherwise.
+  bool is_double = false;
+  int64_t int_value = 0;
+  double double_value = 0;
+};
+
+// `|> WHERE condition`. The condition must be a conjunction (AND) of
+// `column OP literal` comparisons; anything else is unsupported.
+class Where : public PlanOperation {
+ public:
+  static const OperationRegistration kRegistration;
+
+ private:
+  // Test-only formatting; keep payload details out of the public interface.
+  friend class LogicalPlanFormatter;
+
+  // PlanOperation implementation. Dispatch goes through the base interface.
+  std::unique_ptr<PlanOperation> Clone() const override;
+  std::optional<uint32_t> Prune(std::vector<bool>* needed) override;
+  void Lower(Lowering*, const PlanNode&) const override;
+  void Write(PlanWriter*, const PlanNode&, Available*) const override;
+
+  static base::Status BuildPlan(Compiler*, uint32_t);
+  static void DecodePlan(PlanReader*, Available*);
+
+  const OperationRegistration& registration() const override;
+
+  std::vector<WherePredicate> predicates_;
+};
+
+}  // namespace perfetto::trace_processor::pipeline
+
+#endif  // SRC_TRACE_PROCESSOR_PERFETTO_SQL_PIPELINE_OPERATIONS_WHERE_H_
diff --git a/src/trace_processor/perfetto_sql/pipeline/physical_plan.cc b/src/trace_processor/perfetto_sql/pipeline/physical_plan.cc
index 15b3ae8..3d741bb 100644
--- a/src/trace_processor/perfetto_sql/pipeline/physical_plan.cc
+++ b/src/trace_processor/perfetto_sql/pipeline/physical_plan.cc
@@ -57,11 +57,8 @@
   return kept;
 }
 
-// Returns the type that both `a` and `b` convert to without loss. Returns
-// nullopt if one is a string and the other a number.
-//
-// A column of unknown type is checked at runtime to hold the other side's
-// type. For integers the check uses Int64, so it accepts any integer.
+}  // namespace
+
 std::optional<PlanType> CommonType(const PlanType& a, const PlanType& b) {
   if (a.is_null()) {
     return b;
@@ -93,8 +90,6 @@
   return PlanType(core::Int64{});
 }
 
-}  // namespace
-
 Lowering::Lowering(PlanLowering* plan)
     : plan_(plan),
       positions_(plan->plan().columns().size(),
@@ -134,6 +129,16 @@
   return out.side_pipelines_.back().get();
 }
 
+uint32_t Lowering::AddFilterValue(core::exec::FilterValue value) {
+  std::vector<core::exec::FilterValue>& values = plan_->out_->filter_values_;
+  values.push_back(std::move(value));
+  return static_cast<uint32_t>(values.size() - 1);
+}
+
+const LoweringContext& Lowering::context() const {
+  return plan_->context_;
+}
+
 void Lowering::RequireType(ColumnId column, core::StorageType type) {
   std::optional<PlanType> common =
       CommonType(plan_->TypeOf(column), PlanType(type));
@@ -235,19 +240,42 @@
   }
 }
 
+core::exec::IntervalLaneSpec Lowering::RequireIntervalLanes(
+    ColumnId ts,
+    ColumnId dur,
+    const std::vector<ColumnId>& keys) {
+  RequireType(ts, core::Int64{});
+  RequireType(dur, core::Int64{});
+  RequireSortedWithinGroups(keys, {{ts, false}});
+  core::exec::IntervalLaneSpec spec;
+  if (!keys.empty()) {
+    spec.group_column = RequireGroupNumbers(keys);
+  }
+  spec.ts_column = QueryPosition(ts);
+  spec.dur_column = QueryPosition(dur);
+  for (ColumnId key : keys) {
+    spec.key_columns.push_back(QueryPosition(key));
+  }
+  return spec;
+}
+
 Lowering::TreeColumns Lowering::RequireTreeWalk(ColumnId node,
                                                 ColumnId parent,
                                                 TreeDirection direction) {
-  if (!tree_columns_) {
+  bool same_tree =
+      tree_columns_ && tree_node_ == node && tree_parent_ == parent;
+  if (same_tree && tree_walk_ == direction) {
+    return *tree_columns_;
+  }
+  if (same_tree && DropOpenSort() && tree_walk_ == direction) {
+    return *tree_columns_;
+  }
+  if (!same_tree) {
     AddOrderIndependent(std::make_unique<ex::TreeNumberNodes>(
         QueryPosition(node), QueryPosition(parent)));
     tree_columns_ = TreeColumns{column_count_++, column_count_++};
-  }
-  if (tree_walk_ == direction) {
-    return *tree_columns_;
-  }
-  if (DropOpenSort() && tree_walk_ == direction) {
-    return *tree_columns_;
+    tree_node_ = node;
+    tree_parent_ = parent;
   }
   if (direction == TreeDirection::kUp) {
     AddBreaker(std::make_unique<ex::TreeChildFirst>(tree_columns_->node,
@@ -289,6 +317,11 @@
   full_batches_ = false;
 }
 
+void Lowering::DeclareRowsDropped() {
+  tree_walk_.reset();
+  tree_columns_.reset();
+}
+
 void Lowering::DeclareGroupNumbers(const std::vector<ColumnId>& keys,
                                    uint32_t position) {
   group_numbers_.push_back({keys, position});
@@ -309,6 +342,10 @@
   return positions_[id];
 }
 
+PlanType Lowering::QueryType(ColumnId id) const {
+  return plan_->TypeOf(id);
+}
+
 std::vector<SortKey> Lowering::QuerySortedBy(
     const std::vector<ColumnId>& columns) const {
   std::vector<SortKey> longest;
@@ -472,8 +509,10 @@
   return std::make_unique<ex::Pipeline>(*input_, std::move(operators_));
 }
 
-PlanLowering::PlanLowering(const LogicalPlan& plan)
+PlanLowering::PlanLowering(const LogicalPlan& plan,
+                           const LoweringContext& context)
     : plan_(plan),
+      context_(context),
       converted_(plan.columns().size()),
       out_(std::make_unique<PhysicalPlan>()) {
   pipelines_.push_back(std::make_unique<Lowering>(this));
@@ -508,8 +547,10 @@
 PhysicalPlan::PhysicalPlan() = default;
 PhysicalPlan::~PhysicalPlan() = default;
 
-base::StatusOr<std::unique_ptr<PhysicalPlan>> Lower(const LogicalPlan& plan) {
-  PlanLowering lowering(plan);
+base::StatusOr<std::unique_ptr<PhysicalPlan>> Lower(
+    const LogicalPlan& plan,
+    const LoweringContext& context) {
+  PlanLowering lowering(plan, context);
   lowering.main().LowerNode(plan.root());
   return lowering.Finish();
 }
diff --git a/src/trace_processor/perfetto_sql/pipeline/physical_plan.h b/src/trace_processor/perfetto_sql/pipeline/physical_plan.h
index 60246c5..9df8069 100644
--- a/src/trace_processor/perfetto_sql/pipeline/physical_plan.h
+++ b/src/trace_processor/perfetto_sql/pipeline/physical_plan.h
@@ -25,6 +25,8 @@
 
 #include "perfetto/base/status.h"
 #include "perfetto/ext/base/status_or.h"
+#include "src/trace_processor/core/exec/filter_value.h"
+#include "src/trace_processor/core/exec/interval_lanes.h"
 #include "src/trace_processor/core/exec/operator.h"
 #include "src/trace_processor/core/exec/pipeline.h"
 #include "src/trace_processor/perfetto_sql/pipeline/logical_plan.h"
@@ -64,6 +66,13 @@
     return side_pipelines_;
   }
 
+  // The values a Filter compares columns with, known when the plan was
+  // built, e.g. a WHERE literal. Passed to Context::SetFilterValues (see
+  // core::exec::RowCursor::Open) before each run.
+  const std::vector<core::exec::FilterValue>& filter_values() const {
+    return filter_values_;
+  }
+
  private:
   friend class Lowering;
   friend class PlanLowering;
@@ -75,17 +84,33 @@
   std::unique_ptr<core::exec::Source> input_;
   std::unique_ptr<core::exec::Pipeline> pipeline_;
   std::vector<Column> columns_;
+  std::vector<core::exec::FilterValue> filter_values_;
+};
+
+// What lowering needs from whoever runs the plan. Everything here must outlive
+// every run of the plan.
+struct LoweringContext {
+  // Holds the strings of the columns a Filter reads.
+  const StringPool* pool = nullptr;
 };
 
 // Builds executor nodes from a logical plan. Establishes tree numbering, row
 // ordering, and column types as needed, reusing them across consecutive folds.
 // Every dataframe the plan reads must already be resolved.
-base::StatusOr<std::unique_ptr<PhysicalPlan>> Lower(const LogicalPlan&);
+base::StatusOr<std::unique_ptr<PhysicalPlan>> Lower(const LogicalPlan&,
+                                                    const LoweringContext&);
 
 // -----------------------------------------------------------------------------
 // Lowering
 // -----------------------------------------------------------------------------
 
+// Returns the type that both `a` and `b` convert to without loss. Returns
+// nullopt if one is a string and the other a number.
+//
+// A column of unknown type is checked at runtime to hold the other side's
+// type. For integers the check uses Int64, so it accepts any integer.
+std::optional<PlanType> CommonType(const PlanType& a, const PlanType& b);
+
 class PlanLowering;
 
 // Builds one pipeline. It is either the main pipeline or a side pipeline. A
@@ -150,6 +175,13 @@
   // from. Nothing can be added to the pipeline afterwards.
   const core::exec::Source* FinishSide();
 
+  // Adds a filter value known when the plan was built, e.g. a WHERE literal,
+  // and returns its index into the run's filter values (see
+  // PhysicalPlan::filter_values).
+  uint32_t AddFilterValue(core::exec::FilterValue value);
+
+  const LoweringContext& context() const;
+
   // ---------------------------------------------------------------------------
   // Requirements: add operators only if needed
   // ---------------------------------------------------------------------------
@@ -179,12 +211,21 @@
   // row's group number.
   uint32_t RequireGroupNumbers(const std::vector<ColumnId>& keys);
 
+  // Prepares the rows as an interval input: Int64 `ts` and `dur`, grouped by
+  // `keys` with group numbers, and sorted by `ts` within each group. Returns
+  // where the operator finds them.
+  core::exec::IntervalLaneSpec RequireIntervalLanes(
+      ColumnId ts,
+      ColumnId dur,
+      const std::vector<ColumnId>& keys);
+
   // Use before an operator that works best on full batches. Adds a
   // CombineBatches only if an earlier step may have made small batches.
   void RequireFullBatches();
 
   // Orders rows as a tree walk in `direction`, and returns the positions of
-  // the node number columns. The numbering is reused until ResetLayout.
+  // the node number columns. The numbering is reused while `node` and
+  // `parent` are the columns it was made from, until ResetLayout.
   TreeColumns RequireTreeWalk(ColumnId node, ColumnId parent, TreeDirection);
 
   // ---------------------------------------------------------------------------
@@ -213,6 +254,10 @@
   // because it drops rows. Batches are assumed to be full otherwise.
   void DeclareSmallBatches();
 
+  // Records that an added operator drops rows. A tree numbered before may
+  // now name parents which are gone, so the next tree walk numbers it again.
+  void DeclareRowsDropped();
+
   // Records that the column at `position` holds group numbers for `keys`.
   void DeclareGroupNumbers(const std::vector<ColumnId>& keys,
                            uint32_t position);
@@ -228,6 +273,9 @@
   // The batch position of a column declared with DeclareColumn.
   uint32_t QueryPosition(ColumnId id) const;
 
+  // The type of a column, after any conversion added so far.
+  PlanType QueryType(ColumnId id) const;
+
   // The longest prefix of the known sort order that uses only `columns`.
   std::vector<SortKey> QuerySortedBy(
       const std::vector<ColumnId>& columns) const;
@@ -339,8 +387,12 @@
   bool full_batches_ = true;
 
   // The tree node number columns, if the tree is numbered. They stay valid
-  // when rows are reordered, until ResetLayout.
+  // when rows are reordered, until ResetLayout, DeclareRowsDropped or a walk
+  // of another tree.
   std::optional<TreeColumns> tree_columns_;
+  // The id and parent columns `tree_columns_` were numbered from.
+  ColumnId tree_node_ = 0;
+  ColumnId tree_parent_ = 0;
 
   // The group number columns. They stay valid when rows are reordered, until
   // ResetLayout.
@@ -360,7 +412,7 @@
 // State shared by all pipelines while lowering a plan.
 class PlanLowering {
  public:
-  explicit PlanLowering(const LogicalPlan& plan);
+  PlanLowering(const LogicalPlan& plan, const LoweringContext& context);
   PlanLowering(const PlanLowering&) = delete;
   PlanLowering& operator=(const PlanLowering&) = delete;
   ~PlanLowering();
@@ -385,6 +437,7 @@
 
   // Borrowed for the duration of lowering.
   const LogicalPlan& plan_;
+  LoweringContext context_;
 
   // For each logical column, the type it was converted to, if any. Kept here
   // because column ids are unique across pipelines.
diff --git a/src/trace_processor/perfetto_sql/pipeline/physical_plan_unittest.cc b/src/trace_processor/perfetto_sql/pipeline/physical_plan_unittest.cc
index 81f8ac5..c024b38 100644
--- a/src/trace_processor/perfetto_sql/pipeline/physical_plan_unittest.cc
+++ b/src/trace_processor/perfetto_sql/pipeline/physical_plan_unittest.cc
@@ -139,7 +139,7 @@
     LogicalPlan moved = MoveSqlSourcesToDataframeArgs(std::move(plan)).plan;
     RETURN_IF_ERROR(
         BindDataframeArgs(moved, DataframeArgs(dataframes), &pool_));
-    return Lower(moved);
+    return Lower(moved, {&pool_});
   }
 
   std::vector<std::string> Names(const PhysicalPlan& plan) {
@@ -163,7 +163,8 @@
     }
     Rows out;
     RowCursor cursor(plan.source());
-    for (bool row = cursor.Open(); row; row = cursor.Next()) {
+    for (bool row = cursor.Open(plan.filter_values()); row;
+         row = cursor.Next()) {
       out.emplace_back(*IntAt(cursor, id_column), IntAt(cursor, value_column));
     }
     if (!cursor.status().ok()) {
@@ -195,7 +196,7 @@
   copy.output().resize(1);
   PruneColumns(copy);
 
-  auto physical = Lower(*original);
+  auto physical = Lower(*original, {&pool_});
   ASSERT_TRUE(physical.ok()) << physical.status().message();
   auto rows = Run(**physical, "total");
   ASSERT_TRUE(rows.ok()) << rows.status().message();
@@ -289,6 +290,46 @@
             "IntervalFlatten(#0, #1; COUNT(*)) | CombineBatches | Sort(#2)");
 }
 
+// DISTINCT compares only the columns of the row at that stage: `id`, dropped
+// before it, does not make rows differ.
+TEST_F(PhysicalPlanTest, DistinctComparesTheRowAtItsStage) {
+  Exec("CREATE TABLE t(id INTEGER, cpu INTEGER)");
+  Exec("INSERT INTO t VALUES (0, 1), (1, 2), (2, 1), (3, 3), (4, 2)");
+  auto plan = Plan("FROM t |> SELECT cpu |> DISTINCT");
+  ASSERT_TRUE(plan.ok()) << plan.status().message();
+
+  uint32_t cpu_column = (*plan)->columns()[0].index;
+  std::vector<int64_t> values;
+  RowCursor cursor((*plan)->source());
+  for (bool row = cursor.Open(); row; row = cursor.Next()) {
+    values.push_back(*IntAt(cursor, cpu_column));
+  }
+  ASSERT_TRUE(cursor.status().ok()) << cursor.status().message();
+  EXPECT_THAT(values, ElementsAre(1, 2, 3));
+}
+
+// WHERE keeps the rows matching every comparison. A literal is compared as
+// SQL compares it with the column, whatever their types: an integer column
+// with a fraction and a double column with an integer. The columns keep their
+// types. Each comparison drops at least one row.
+TEST_F(PhysicalPlanTest, WhereKeepsRowsMatchingEveryComparison) {
+  Exec("CREATE TABLE t(cpu INTEGER, value REAL)");
+  Exec("INSERT INTO t VALUES (1, 3.5), (5, 2.5), (3, 1.5), (9, 3.5), (7, 2.5)");
+  auto plan = Plan(
+      "FROM t |> WHERE cpu > 2.5 AND cpu < 9 AND value >= 2 |> SELECT cpu");
+  ASSERT_TRUE(plan.ok()) << plan.status().message();
+
+  uint32_t cpu_column = (*plan)->columns()[0].index;
+  std::vector<int64_t> values;
+  RowCursor cursor((*plan)->source());
+  for (bool row = cursor.Open((*plan)->filter_values()); row;
+       row = cursor.Next()) {
+    values.push_back(*IntAt(cursor, cpu_column));
+  }
+  ASSERT_TRUE(cursor.status().ok()) << cursor.status().message();
+  EXPECT_THAT(values, ElementsAre(5, 7));
+}
+
 // Each operand is grouped by its PER keys and sorted by ts within each group,
 // unless it already is.
 TEST_F(PhysicalPlanTest, IntersectionOrdersItsOperands) {
@@ -303,16 +344,35 @@
   // ts and dur are converted to Int64. So is cpu, because it has a different
   // integer type in each dataframe.
   EXPECT_EQ(PhysicalPlanToString(**plan),
-            "side: DataframeScan | AssertType(#0 to Int64) | "
-            "AssertType(#1 to Int64) | AssertType(#2 to Int64) | "
+            "side: DataframeScan | AssertType(#2 to Int64) | "
+            "AssertType(#0 to Int64) | AssertType(#1 to Int64) | "
             "GroupedSort(#2; #0)\n"
-            "side: DataframeScan | AssertType(#0 to Int64) | "
-            "AssertType(#1 to Int64) | AssertType(#2 to Int64) | "
+            "side: DataframeScan | AssertType(#2 to Int64) | "
+            "AssertType(#0 to Int64) | AssertType(#1 to Int64) | "
             "GroupedSort(#2; #0)\n"
             "main: IntervalIntersect(#0, #1, keys: #2, groups: #3; #0, #1, "
             "keys: #2, groups: #3)");
 }
 
+// The input is grouped by its PER columns and sorted by ts within each group.
+// The background is read from a side pipeline and sorted by ts within each of
+// its lanes.
+TEST_F(PhysicalPlanTest, FillGapsOrdersBothSides) {
+  Exec("CREATE TABLE spans(ts INTEGER, dur INTEGER, cpu INTEGER)");
+  Exec("INSERT INTO spans VALUES (5, 1, 1), (0, 1, 0)");
+  Exec("CREATE TABLE windows(ts INTEGER, dur INTEGER, cpu INTEGER)");
+  Exec("INSERT INTO windows VALUES (9, 10, 1), (0, 10, 0)");
+  auto plan = Plan("FROM spans |> INTERVAL FILL GAPS WITH windows PER cpu");
+  ASSERT_TRUE(plan.ok()) << plan.status().message();
+  EXPECT_EQ(PhysicalPlanToString(**plan),
+            "side: DataframeScan | AssertType(#0 to Int64) | "
+            "AssertType(#1 to Int64) | GroupedSort(#2; #0)\n"
+            "main: DataframeScan | AssertType(#0 to Int64) | "
+            "AssertType(#1 to Int64) | GroupedSort(#2; #0) | "
+            "IntervalFillGaps(#0, #1, keys: #2, groups: #3; "
+            "background: #0, #1, keys: #2, groups: #3)");
+}
+
 // An intersection needs its operands' bounds and PER columns, but only passes
 // on the columns something after it reads: it neither buffers nor gathers
 // the rest.
@@ -437,7 +497,7 @@
   EXPECT_TRUE(moved.args.empty());
   auto read = DeserializePlan(SerializePlan(moved.plan), catalog_);
   ASSERT_TRUE(read.ok()) << read.status().message();
-  auto lowered = Lower(*read);
+  auto lowered = Lower(*read, {&pool_});
   ASSERT_TRUE(lowered.ok()) << lowered.status().message();
   EXPECT_THAT(Names(**lowered),
               ElementsAre("id", "parent_id", "own", "copy", "total"));
diff --git a/src/trace_processor/perfetto_sql/pipeline/plan_serialization.cc b/src/trace_processor/perfetto_sql/pipeline/plan_serialization.cc
index 369cfa2..8cf2d0c 100644
--- a/src/trace_processor/perfetto_sql/pipeline/plan_serialization.cc
+++ b/src/trace_processor/perfetto_sql/pipeline/plan_serialization.cc
@@ -41,6 +41,14 @@
   Append(&value, sizeof(value));
 }
 
+void Writer::U64(uint64_t value) {
+  Append(&value, sizeof(value));
+}
+
+void Writer::F64(double value) {
+  Append(&value, sizeof(value));
+}
+
 void Writer::Size(size_t value) {
   U32(static_cast<uint32_t>(value));
 }
@@ -79,6 +87,18 @@
   return value;
 }
 
+uint64_t Reader::U64() {
+  uint64_t value = 0;
+  Read(&value, sizeof(value));
+  return value;
+}
+
+double Reader::F64() {
+  double value = 0;
+  Read(&value, sizeof(value));
+  return value;
+}
+
 uint32_t Reader::Count() {
   uint32_t count = U32();
   if (count > in_.size() - at_) {
@@ -182,7 +202,9 @@
   while (
       !plan_.nodes()[id].operation().registration().encoding()->is_source()) {
     stages.push_back(&plan_.nodes()[id]);
-    PERFETTO_CHECK(plan_.nodes()[id].children().size() == 1);
+    // A stage's input is its first child. The stage writes any other children
+    // itself, like FILL GAPS writes its background.
+    PERFETTO_CHECK(!plan_.nodes()[id].children().empty());
     id = plan_.nodes()[id].children()[0];
   }
   const PlanNode& source = plan_.nodes()[id];
diff --git a/src/trace_processor/perfetto_sql/pipeline/plan_serialization.h b/src/trace_processor/perfetto_sql/pipeline/plan_serialization.h
index 4dff47e..8116644 100644
--- a/src/trace_processor/perfetto_sql/pipeline/plan_serialization.h
+++ b/src/trace_processor/perfetto_sql/pipeline/plan_serialization.h
@@ -70,6 +70,8 @@
  public:
   void U8(uint8_t value);
   void U32(uint32_t value);
+  void U64(uint64_t value);
+  void F64(double value);
   void Size(size_t value);
   void Str(std::string_view value);
 
@@ -92,6 +94,8 @@
 
   uint8_t U8();
   uint32_t U32();
+  uint64_t U64();
+  double F64();
 
   // At most the bytes left, so a corrupt count cannot allocate much.
   uint32_t Count();
diff --git a/src/trace_processor/perfetto_sql/pipeline/plan_serialization_unittest.cc b/src/trace_processor/perfetto_sql/pipeline/plan_serialization_unittest.cc
index c5db6e7..bb40cfd 100644
--- a/src/trace_processor/perfetto_sql/pipeline/plan_serialization_unittest.cc
+++ b/src/trace_processor/perfetto_sql/pipeline/plan_serialization_unittest.cc
@@ -97,8 +97,12 @@
     "INTERVAL INTERSECTION OF (spans AS a, spans AS b) PER cpu",
     "FROM spans |> INTERVAL FLATTEN PER cpu AGGREGATE SUM(dur) AS d",
     "FROM spans |> INTERVAL FLATTEN AGGREGATE COUNT(*) AS n |> SELECT ts, n",
+    "FROM spans |> INTERVAL FILL GAPS WITH spans PER cpu",
+    "FROM spans |> INTERVAL FILL GAPS WITH (SELECT ts, dur FROM spans)",
     "FROM df |> ORDER BY self DESC, id |> SELECT id",
     "FROM spans |> INTERVAL FLATTEN AGGREGATE COUNT(*) AS n |> ORDER BY n",
+    "FROM df |> SELECT parent_id |> DISTINCT",
+    "FROM df |> WHERE self > 0 AND id < 10",
     "FROM spans |> AGGREGATE COUNT(*) AS n, SUM(dur) AS d GROUP BY cpu AS c",
     "FROM spans |> AGGREGATE MAX(dur) AS m |> SELECT m",
     // Pruning removes the fold, whose node is left behind unread.
@@ -138,12 +142,13 @@
                  .ok()) {
           continue;
         }
-        auto physical = Lower(*read);
+        auto physical = Lower(*read, {&pool_});
         if (!physical.ok()) {
           continue;
         }
         core::exec::RowCursor cursor((*physical)->source());
-        for (bool row = cursor.Open(); row; row = cursor.Next()) {
+        for (bool row = cursor.Open((*physical)->filter_values()); row;
+             row = cursor.Next()) {
         }
       }
     }
diff --git a/src/trace_processor/perfetto_sql/stdlib/android/battery/charging_states.sql b/src/trace_processor/perfetto_sql/stdlib/android/battery/charging_states.sql
index cf92a09..1f0d027 100644
--- a/src/trace_processor/perfetto_sql/stdlib/android/battery/charging_states.sql
+++ b/src/trace_processor/perfetto_sql/stdlib/android/battery/charging_states.sql
@@ -15,7 +15,56 @@
 
 INCLUDE PERFETTO MODULE counters.intervals;
 
-INCLUDE PERFETTO MODULE intervals.fill_gaps;
+-- Charging state intervals per machine, NULL where the state is unknown: every
+-- machine with data is filled between its rows, and the primary machine is
+-- filled even without data, since the trace says it was there. Other machines
+-- without data may not have emitted any, which is not the same as their state
+-- being unknown.
+CREATE PERFETTO TABLE _android_charging_states_filled AS
+FROM (
+  WITH
+    _counter AS (
+      SELECT counter.id, ts, counter.track_id, value
+      FROM counter
+      JOIN counter_track
+        ON counter_track.id = counter.track_id
+      WHERE
+        counter_track.name = 'BatteryStatus'
+    ),
+    _intervals AS (
+      SELECT
+        intervals.id,
+        intervals.ts,
+        intervals.dur,
+        counter_track.machine_id,
+        CASE intervals.value
+          WHEN 2 THEN 'charging'
+          WHEN 3 THEN 'discharging'
+          WHEN 4 THEN 'not_charging'
+          WHEN 5 THEN 'full'
+        END AS short_charging_state,
+        CASE intervals.value
+          -- 0 and 1 are both 'Unknown'
+          WHEN 2 THEN 'Charging'
+          WHEN 3 THEN 'Discharging'
+          -- special case when charger is present but battery isn't charging
+          WHEN 4 THEN 'Not charging'
+          WHEN 5 THEN 'Full'
+        END AS charging_state
+      FROM counter_leading_intervals!(_counter) AS intervals
+      JOIN counter_track
+        ON counter_track.id = intervals.track_id
+      WHERE
+        dur > 0
+    )
+  -- A charging state value which is not a valid enum value is unknown.
+  SELECT ts, dur, machine_id, short_charging_state, charging_state
+  FROM _intervals
+)
+|> INTERVAL FILL GAPS WITH (SELECT trace_start() AS ts, trace_dur() AS dur) PER machine_id
+|> INTERVAL FILL GAPS WITH (
+  SELECT trace_start() AS ts, trace_dur() AS dur, 0 AS machine_id
+) PER machine_id;
 
 -- Device charging states.
 CREATE PERFETTO TABLE android_charging_states(
@@ -35,56 +84,16 @@
   charging_state STRING
 )
 AS
--- Either the first statement is populated or the select statement after the
--- union is populated but not both.
-WITH
-  _counter AS (
-    SELECT counter.id, ts, counter.track_id, value
-    FROM counter
-    JOIN counter_track
-      ON counter_track.id = counter.track_id
-    WHERE
-      counter_track.name = 'BatteryStatus'
-  ),
-  _intervals AS (
-    SELECT
-      intervals.id,
-      intervals.ts,
-      intervals.dur,
-      counter_track.machine_id,
-      CASE intervals.value
-        WHEN 2 THEN 'charging'
-        WHEN 3 THEN 'discharging'
-        WHEN 4 THEN 'not_charging'
-        WHEN 5 THEN 'full'
-      END AS short_charging_state,
-      CASE intervals.value
-        -- 0 and 1 are both 'Unknown'
-        WHEN 2 THEN 'Charging'
-        WHEN 3 THEN 'Discharging'
-        -- special case when charger is present but battery isn't charging
-        WHEN 4 THEN 'Not charging'
-        WHEN 5 THEN 'Full'
-      END AS charging_state
-    FROM counter_leading_intervals!(_counter) AS intervals
-    JOIN counter_track
-      ON counter_track.id = intervals.track_id
-    WHERE
-      dur > 0
-  )
--- When the trace does not have a slice in the charging state track or when
--- the charging state value is not a valid enum value, assume the charging
--- state for the entire trace is unknown. The use of _intervals_fill_gaps
--- ensures we still have data for the entirety of the trace.
+-- Where the charging state is not known, it is 'unknown' for the entirety of
+-- the trace.
 SELECT
-  ROW_NUMBER() OVER () AS id,
+  ROW_NUMBER() OVER (ORDER BY ts, machine_id) AS id,
   ts,
   dur,
   machine_id,
   COALESCE(short_charging_state, 'unknown') AS short_charging_state,
   COALESCE(charging_state, 'Unknown') AS charging_state
-FROM _intervals_fill_gaps!(
-  (machine_id),
-  (short_charging_state, charging_state),
-  _intervals
-);
+FROM _android_charging_states_filled
+ORDER BY
+  ts,
+  machine_id;
diff --git a/src/trace_processor/perfetto_sql/stdlib/android/cujs/cuj_frame_counters.sql b/src/trace_processor/perfetto_sql/stdlib/android/cujs/cuj_frame_counters.sql
index 9c7ca53..f89ac89 100644
--- a/src/trace_processor/perfetto_sql/stdlib/android/cujs/cuj_frame_counters.sql
+++ b/src/trace_processor/perfetto_sql/stdlib/android/cujs/cuj_frame_counters.sql
@@ -60,24 +60,25 @@
 
 -- Extract all counters for Jank CUJ tracks.
 CREATE PERFETTO TABLE _android_jank_cuj_counter AS
-WITH
-  cuj_counter_track AS (
-    SELECT DISTINCT
-      upid,
-      track.id AS track_id,
-      -- extract the CUJ name inside <>
-      str_split(str_split(track.name, '>#', 0), '<', 1) AS cuj_name,
-      -- take the name of the counter after #
-      str_split(track.name, '#', 1) AS counter_name
-    FROM process_counter_track AS track
-    JOIN android_jank_cuj USING (upid)
-    WHERE
-      track.name GLOB 'J<*>#*'
-  )
-SELECT ts, upid, cuj_name, counter_name, CAST(value AS INTEGER) AS value
+SELECT
+  ts,
+  upid,
+  -- extract the CUJ name inside <>
+  str_split(str_split(track.name, '>#', 0), '<', 1) AS cuj_name,
+  -- take the name of the counter after #
+  str_split(track.name, '#', 1) AS counter_name,
+  CAST(value AS INTEGER) AS value
 FROM counter
-JOIN cuj_counter_track
-  ON counter.track_id = cuj_counter_track.track_id;
+JOIN process_counter_track AS track
+  ON counter.track_id = track.id
+WHERE
+  counter.track_id IN (
+    SELECT id
+    FROM process_counter_track
+    WHERE
+      name GLOB 'J<*>#*'
+      AND upid IN (SELECT upid FROM android_jank_cuj)
+  );
 
 -- Returns the counter value for the given CUJ name and counter name.
 CREATE PERFETTO FUNCTION _android_jank_cuj_counter_value(
diff --git a/src/trace_processor/perfetto_sql/stdlib/android/freezer.sql b/src/trace_processor/perfetto_sql/stdlib/android/freezer.sql
index a5988cc..b5c5456 100644
--- a/src/trace_processor/perfetto_sql/stdlib/android/freezer.sql
+++ b/src/trace_processor/perfetto_sql/stdlib/android/freezer.sql
@@ -13,6 +13,8 @@
 -- limitations under the License.
 --
 
+INCLUDE PERFETTO MODULE android.process_metadata;
+
 CREATE PERFETTO FUNCTION _extract_freezer_pid(name STRING)
 RETURNS LONG
 AS
@@ -217,3 +219,83 @@
   time_unfrozen_millis,
   unfreeze_reason
 FROM app_freeze_changes;
+
+-- FROZEN/UNFROZEN spans of each process over its lifetime. Freezer events and
+-- the trace-stop snapshot rows carry an unfreeze_reason only when the process
+-- is unfrozen, which is what tells the two states apart.
+CREATE PERFETTO TABLE _android_freezer_intervals AS
+WITH
+  -- A frozen process that gets killed emits no unfreeze, so spans stop at its
+  -- death. death is NULL while the process lives on at trace end.
+  lifetimes AS (
+    SELECT
+      p.upid,
+      coalesce(fw.fw_start_ts, p.start_ts, trace_start()) AS birth,
+      p.end_ts AS death
+    FROM process AS p
+    LEFT JOIN __intrinsic_android_track_event_process AS fw USING (upid)
+  ),
+  events AS (
+    SELECT
+      upid,
+      ts,
+      iif(unfreeze_reason IS NULL, 'FROZEN', 'UNFROZEN') AS state,
+      lag(ts) OVER (PARTITION BY upid ORDER BY ts) AS prev_ts,
+      lead(ts) OVER (PARTITION BY upid ORDER BY ts) AS next_ts
+    FROM __intrinsic_android_freezer_state
+    WHERE
+      is_initial = 0
+  ),
+  -- Spans still open at trace end have dur = -1, like unfinished slices.
+  spans AS (
+    SELECT
+      e.upid,
+      e.ts,
+      iif(
+        e.next_ts IS NULL
+        AND l.death IS NULL,
+        -1,
+        min(coalesce(e.next_ts, trace_end()), coalesce(l.death, trace_end()))
+        - e.ts
+      ) AS dur,
+      e.state
+    FROM events AS e
+    JOIN lifetimes AS l USING (upid)
+    UNION ALL
+    -- Before its first event a process was in the opposite state.
+    SELECT
+      e.upid,
+      l.birth AS ts,
+      e.ts - l.birth AS dur,
+      iif(e.state = 'FROZEN', 'UNFROZEN', 'FROZEN') AS state
+    FROM events AS e
+    JOIN lifetimes AS l USING (upid)
+    WHERE
+      e.prev_ts IS NULL
+    UNION ALL
+    -- Processes without events kept their trace-stop state throughout.
+    SELECT
+      s.upid,
+      l.birth AS ts,
+      iif(l.death IS NULL, -1, l.death - l.birth) AS dur,
+      iif(s.unfreeze_reason IS NULL, 'FROZEN', 'UNFROZEN') AS state
+    FROM __intrinsic_android_freezer_state AS s
+    JOIN lifetimes AS l USING (upid)
+    WHERE
+      s.is_initial = 1
+      AND NOT EXISTS (SELECT 1 FROM events AS e WHERE e.upid = s.upid)
+  )
+SELECT
+  row_number() OVER (ORDER BY s.ts, s.upid) AS id,
+  s.ts,
+  s.dur,
+  s.upid,
+  p.pid,
+  m.process_name,
+  s.state
+FROM spans AS s
+JOIN process AS p USING (upid)
+LEFT JOIN android_process_metadata AS m USING (upid)
+WHERE
+  s.dur > 0
+  OR s.dur = -1;
diff --git a/src/trace_processor/perfetto_sql/stdlib/android/input.sql b/src/trace_processor/perfetto_sql/stdlib/android/input.sql
index b2e26ac..391d0a5 100644
--- a/src/trace_processor/perfetto_sql/stdlib/android/input.sql
+++ b/src/trace_processor/perfetto_sql/stdlib/android/input.sql
@@ -539,6 +539,38 @@
   frame_id
 );
 
+CREATE PERFETTO TABLE _android_input_lifecycle AS
+SELECT
+  e.input_event_id AS input_id,
+  e.event_channel AS channel,
+  e.end_to_end_latency_dur AS total_latency,
+  e.read_time AS ts_reader,
+  e.dispatch_ts AS ts_dispatch,
+  e.receive_ts AS ts_receive,
+  s_cons.ts AS ts_consume,
+  s_read.id AS id_reader,
+  s_read.track_id AS track_reader,
+  s_read.dur AS dur_reader,
+  s_disp.id AS id_dispatch,
+  e.dispatch_track_id AS track_dispatch,
+  s_disp.dur AS dur_dispatch,
+  s_recv.id AS id_receive,
+  e.receive_track_id AS track_receive,
+  s_recv.dur AS dur_receive,
+  s_cons.id AS id_consume,
+  s_cons.track_id AS track_consume,
+  s_cons.dur AS dur_consume,
+  e.is_speculative_frame
+FROM android_input_events AS e
+LEFT JOIN slice AS s_read ON s_read.ts = e.read_time AND s_read.track_id != 0
+LEFT JOIN slice AS s_disp
+  ON s_disp.ts = e.dispatch_ts
+  AND s_disp.track_id = e.dispatch_track_id
+LEFT JOIN slice AS s_recv
+  ON s_recv.ts = e.receive_ts
+  AND s_recv.track_id = e.receive_track_id
+LEFT JOIN _input_consumers_lookup AS s_cons ON s_cons.cookie = e.event_seq;
+
 -- Retrieves the full lifecycle of an Android input event (Read -> Dispatch -> Receive -> Consume -> Frame)
 -- by matching a given slice ID from any stage of the pipeline.
 CREATE PERFETTO FUNCTION _android_input_lifecycle_by_slice_id(
@@ -576,41 +608,10 @@
   is_speculative_frame BOOL
 )
 AS
-SELECT
-  e.input_event_id AS input_id,
-  e.event_channel AS channel,
-  e.end_to_end_latency_dur AS total_latency,
-  e.read_time AS ts_reader,
-  e.dispatch_ts AS ts_dispatch,
-  e.receive_ts AS ts_receive,
-  s_cons.ts AS ts_consume,
-  s_read.id AS id_reader,
-  s_read.track_id AS track_reader,
-  s_read.dur AS dur_reader,
-  s_disp.id AS id_dispatch,
-  e.dispatch_track_id AS track_dispatch,
-  s_disp.dur AS dur_dispatch,
-  s_recv.id AS id_receive,
-  e.receive_track_id AS track_receive,
-  s_recv.dur AS dur_receive,
-  s_cons.id AS id_consume,
-  s_cons.track_id AS track_consume,
-  s_cons.dur AS dur_consume,
-  e.is_speculative_frame
-FROM android_input_events AS e
-LEFT JOIN slice AS s_read
-  ON s_read.ts = e.read_time
-  AND s_read.track_id != 0
-LEFT JOIN slice AS s_disp
-  ON s_disp.ts = e.dispatch_ts
-  AND s_disp.track_id = e.dispatch_track_id
-LEFT JOIN slice AS s_recv
-  ON s_recv.ts = e.receive_ts
-  AND s_recv.track_id = e.receive_track_id
-LEFT JOIN _input_consumers_lookup AS s_cons
-  ON s_cons.cookie = e.event_seq
+SELECT *
+FROM _android_input_lifecycle
 WHERE
-  $slice_id IN (s_read.id, s_disp.id, s_recv.id, s_cons.id);
+  $slice_id IN (id_reader, id_dispatch, id_receive, id_consume);
 
 CREATE PERFETTO TABLE _input_sf_composite AS
 SELECT
diff --git a/src/trace_processor/perfetto_sql/stdlib/android/memory/heap_graph/excluded_refs.sql b/src/trace_processor/perfetto_sql/stdlib/android/memory/heap_graph/excluded_refs.sql
index 5a30bae..b0114a2 100644
--- a/src/trace_processor/perfetto_sql/stdlib/android/memory/heap_graph/excluded_refs.sql
+++ b/src/trace_processor/perfetto_sql/stdlib/android/memory/heap_graph/excluded_refs.sql
@@ -26,10 +26,17 @@
   type_id;
 
 CREATE PERFETTO TABLE _excluded_refs AS
+WITH
+  ref_objects AS (
+    SELECT reference_set_id
+    FROM heap_graph_object
+    WHERE
+      reference_set_id IS NOT NULL
+      AND type_id IN _ref_type_ids
+  )
 SELECT ref.id
-FROM heap_graph_object AS robj
+FROM ref_objects
 CROSS JOIN heap_graph_reference AS ref USING (reference_set_id)
-CROSS JOIN _ref_type_ids USING (type_id)
 WHERE
   ref.field_name = 'java.lang.ref.Reference.referent'
 ORDER BY
diff --git a/src/trace_processor/perfetto_sql/stdlib/android/memory/heap_graph/helpers.sql b/src/trace_processor/perfetto_sql/stdlib/android/memory/heap_graph/helpers.sql
index b89cc37..1696d19 100644
--- a/src/trace_processor/perfetto_sql/stdlib/android/memory/heap_graph/helpers.sql
+++ b/src/trace_processor/perfetto_sql/stdlib/android/memory/heap_graph/helpers.sql
@@ -94,15 +94,17 @@
 RETURNS TableOrSubquery
 AS (
   WITH
-    x AS (
+    -- Pre-aggregate integer columns by path_hash first. CROSS JOIN keeps $tab
+    -- as the outer table so Dataframe consumes GROUP BY path_hash in C++ and
+    -- probes heap_graph_object.id via O(1) IdSorted lookup.
+    agg_by_hash AS (
       SELECT
-        o.graph_sample_ts,
-        o.upid,
+        -- All objects sharing a path_hash have the same (upid, graph_sample_ts,
+        -- root_type, heap_type) and class display name, so MIN(id) picks a
+        -- deterministic representative object to resolve those columns below.
+        MIN(id) AS sample_id,
         path_hash,
         parent_path_hash,
-        coalesce(c.deobfuscated_name, c.name, '') AS name,
-        o.root_type,
-        o.heap_type,
         count() AS self_count,
         -- -1 is a placeholder sentinel (see HeapGraphTracker::GetOrInsertObject
         -- in heap_graph_tracker.cc) for forward-referenced objects in
@@ -111,40 +113,44 @@
         sum(o.native_size > 0) AS self_native_count,
         sum(o.native_size) AS self_native_size
       FROM $tab
-      JOIN heap_graph_object AS o
+      CROSS JOIN heap_graph_object AS o
         USING (id)
-      JOIN heap_graph_class AS c
-        ON o.type_id = c.id
       GROUP BY
         path_hash
     )
   SELECT
-    graph_sample_ts,
-    upid,
-    hash(path_hash, 'native', '') AS path_hash,
-    path_hash AS parent_path_hash,
-    '[native] ' || x.name AS name,
-    root_type,
+    o.graph_sample_ts,
+    o.upid,
+    hash(a.path_hash, 'native', '') AS path_hash,
+    a.path_hash AS parent_path_hash,
+    '[native] ' || coalesce(c.deobfuscated_name, c.name, '') AS name,
+    o.root_type,
     'HEAP_TYPE_NATIVE' AS heap_type,
-    sum(x.self_native_count) AS self_count,
-    sum(x.self_native_size) AS self_size
-  FROM x
+    a.self_native_count AS self_count,
+    a.self_native_size AS self_size
+  FROM agg_by_hash AS a
+  JOIN heap_graph_object AS o
+    ON a.sample_id = o.id
+  JOIN heap_graph_class AS c
+    ON o.type_id = c.id
   WHERE
-    x.self_native_size > 0
-  GROUP BY
-    path_hash
+    a.self_native_size > 0
   UNION ALL
   SELECT
-    graph_sample_ts,
-    upid,
-    path_hash,
-    parent_path_hash,
-    name,
-    root_type,
-    heap_type,
-    self_count,
-    self_size
-  FROM x
+    o.graph_sample_ts,
+    o.upid,
+    a.path_hash,
+    a.parent_path_hash,
+    coalesce(c.deobfuscated_name, c.name, '') AS name,
+    o.root_type,
+    o.heap_type,
+    a.self_count,
+    a.self_size
+  FROM agg_by_hash AS a
+  JOIN heap_graph_object AS o
+    ON a.sample_id = o.id
+  JOIN heap_graph_class AS c
+    ON o.type_id = c.id
   ORDER BY
     path_hash
 );
diff --git a/src/trace_processor/perfetto_sql/stdlib/android/screen_state.sql b/src/trace_processor/perfetto_sql/stdlib/android/screen_state.sql
index 0cef8dc..2195c8e 100644
--- a/src/trace_processor/perfetto_sql/stdlib/android/screen_state.sql
+++ b/src/trace_processor/perfetto_sql/stdlib/android/screen_state.sql
@@ -14,7 +14,94 @@
 
 INCLUDE PERFETTO MODULE counters.intervals;
 
-INCLUDE PERFETTO MODULE intervals.fill_gaps;
+-- Screen state intervals per machine, NULL where the state is unknown: every
+-- machine with data is filled between its rows, and the primary machine is
+-- filled even without data, since the trace says it was there. Other machines
+-- without data may not have emitted any, which is not the same as their state
+-- being unknown.
+CREATE PERFETTO TABLE _android_screen_state_filled AS
+FROM (
+  WITH
+    screen_state_span AS (
+      SELECT *
+      FROM counter_leading_intervals!(
+        (
+          SELECT counter.id, ts, counter.track_id, value
+          FROM counter
+          JOIN counter_track ON counter_track.id = counter.track_id
+          WHERE
+            name = 'ScreenState'
+        )
+      )
+    ),
+    mapped_names AS (
+      SELECT
+        screen_state_span.id,
+        screen_state_span.ts,
+        screen_state_span.dur,
+        counter_track.machine_id,
+        -- Should be kept in sync with the enums in Display.java
+        CASE screen_state_span.value
+          -- Display.STATE_OFF
+          WHEN 1 THEN 'off'
+          -- Display.STATE_ON
+          WHEN 2 THEN 'on'
+          -- Display.STATE_DOZE
+          WHEN 3 THEN 'doze'
+          -- Display.STATE_DOZE_SUSPEND
+          WHEN 4 THEN 'doze'
+          -- Display.STATE_VR
+          WHEN 5 THEN 'on'
+          -- Display.STATE_ON_SUSPEND
+          WHEN 6 THEN 'on'
+        END AS simple_screen_state,
+        CASE screen_state_span.value
+          -- Display.STATE_OFF
+          WHEN 1 THEN 'off'
+          -- Display.STATE_ON
+          WHEN 2 THEN 'on'
+          -- Display.STATE_DOZE
+          WHEN 3 THEN 'doze'
+          -- Display.STATE_DOZE_SUSPEND
+          WHEN 4 THEN 'doze-suspend'
+          -- Display.STATE_VR
+          WHEN 5 THEN 'on-vr'
+          -- Display.STATE_ON_SUSPEND
+          WHEN 6 THEN 'on-suspend'
+        END AS short_screen_state,
+        CASE screen_state_span.value
+          -- Display.STATE_OFF
+          WHEN 1 THEN 'Screen off'
+          -- Display.STATE_ON
+          WHEN 2 THEN 'Screen on'
+          -- Display.STATE_DOZE
+          WHEN 3 THEN 'Always-on display (doze)'
+          -- Display.STATE_DOZE_SUSPEND
+          WHEN 4 THEN 'Always-on display (doze-suspend)'
+          -- Display.STATE_VR
+          WHEN 5 THEN 'Screen on (VR)'
+          -- Display.STATE_ON_SUSPEND
+          WHEN 6 THEN 'Screen on (suspend)'
+        END AS screen_state
+      FROM screen_state_span
+      JOIN counter_track
+        ON counter_track.id = screen_state_span.track_id
+      WHERE
+        dur > 0
+    )
+  SELECT
+    ts,
+    dur,
+    machine_id,
+    simple_screen_state,
+    short_screen_state,
+    screen_state
+  FROM mapped_names
+)
+|> INTERVAL FILL GAPS WITH (SELECT trace_start() AS ts, trace_dur() AS dur) PER machine_id
+|> INTERVAL FILL GAPS WITH (
+  SELECT trace_start() AS ts, trace_dur() AS dur, 0 AS machine_id
+) PER machine_id;
 
 -- Table of the screen state - on, off or doze (always on display).
 CREATE PERFETTO TABLE android_screen_state(
@@ -34,84 +121,15 @@
   screen_state STRING
 )
 AS
-WITH
-  screen_state_span AS (
-    SELECT *
-    FROM counter_leading_intervals!(
-      (
-        SELECT counter.id, ts, counter.track_id, value
-        FROM counter
-        JOIN counter_track ON counter_track.id = counter.track_id
-        WHERE
-          name = 'ScreenState'
-      )
-    )
-  ),
-  mapped_names AS (
-    SELECT
-      screen_state_span.id,
-      screen_state_span.ts,
-      screen_state_span.dur,
-      counter_track.machine_id,
-      -- Should be kept in sync with the enums in Display.java
-      CASE screen_state_span.value
-        -- Display.STATE_OFF
-        WHEN 1 THEN 'off'
-        -- Display.STATE_ON
-        WHEN 2 THEN 'on'
-        -- Display.STATE_DOZE
-        WHEN 3 THEN 'doze'
-        -- Display.STATE_DOZE_SUSPEND
-        WHEN 4 THEN 'doze'
-        -- Display.STATE_VR
-        WHEN 5 THEN 'on'
-        -- Display.STATE_ON_SUSPEND
-        WHEN 6 THEN 'on'
-      END AS simple_screen_state,
-      CASE screen_state_span.value
-        -- Display.STATE_OFF
-        WHEN 1 THEN 'off'
-        -- Display.STATE_ON
-        WHEN 2 THEN 'on'
-        -- Display.STATE_DOZE
-        WHEN 3 THEN 'doze'
-        -- Display.STATE_DOZE_SUSPEND
-        WHEN 4 THEN 'doze-suspend'
-        -- Display.STATE_VR
-        WHEN 5 THEN 'on-vr'
-        -- Display.STATE_ON_SUSPEND
-        WHEN 6 THEN 'on-suspend'
-      END AS short_screen_state,
-      CASE screen_state_span.value
-        -- Display.STATE_OFF
-        WHEN 1 THEN 'Screen off'
-        -- Display.STATE_ON
-        WHEN 2 THEN 'Screen on'
-        -- Display.STATE_DOZE
-        WHEN 3 THEN 'Always-on display (doze)'
-        -- Display.STATE_DOZE_SUSPEND
-        WHEN 4 THEN 'Always-on display (doze-suspend)'
-        -- Display.STATE_VR
-        WHEN 5 THEN 'Screen on (VR)'
-        -- Display.STATE_ON_SUSPEND
-        WHEN 6 THEN 'Screen on (suspend)'
-      END AS screen_state
-    FROM screen_state_span
-    JOIN counter_track
-      ON counter_track.id = screen_state_span.track_id
-    WHERE
-      dur > 0
-  )
 SELECT
-  ROW_NUMBER() OVER () AS id,
+  ROW_NUMBER() OVER (ORDER BY ts, machine_id) AS id,
   ts,
   dur,
   machine_id,
   COALESCE(simple_screen_state, 'unknown') AS simple_screen_state,
   COALESCE(short_screen_state, 'unknown') AS short_screen_state,
   COALESCE(screen_state, 'Unknown') AS screen_state
-FROM _intervals_fill_gaps!(
-  (machine_id),
-  (simple_screen_state, short_screen_state, screen_state),
-  mapped_names
-);
+FROM _android_screen_state_filled
+ORDER BY
+  ts,
+  machine_id;
diff --git a/src/trace_processor/perfetto_sql/stdlib/android/suspend.sql b/src/trace_processor/perfetto_sql/stdlib/android/suspend.sql
index 6fe9c96..f5fbf21 100644
--- a/src/trace_processor/perfetto_sql/stdlib/android/suspend.sql
+++ b/src/trace_processor/perfetto_sql/stdlib/android/suspend.sql
@@ -14,13 +14,14 @@
 -- limitations under the License.
 --
 
-INCLUDE PERFETTO MODULE intervals.fill_gaps;
-
 -- Table of suspended and awake slices.
 --
 -- Selects either the minimal or full ftrace source depending on what's
 -- available, marks suspended periods, and complements them to give awake
--- periods.
+-- periods: every machine with suspend slices is awake between them. The
+-- primary machine is awake throughout if it never suspended, since the trace
+-- starting and ending at all says it was awake. Other machines may have been
+-- asleep throughout, so nothing is known of them without suspend slices.
 CREATE PERFETTO TABLE android_suspend_state(
   -- Timestamp
   ts TIMESTAMP,
@@ -32,79 +33,74 @@
   machine_id JOINID(machine.id)
 )
 AS
-WITH
-  suspend_slice_from_minimal AS (
-    SELECT
-      ts,
-      dur,
-      coalesce(
-        lead(ts) OVER (PARTITION BY t.machine_id ORDER BY ts),
-        trace_end()
-      )
-      - ts
-      - dur AS duration_gap,
-      t.machine_id
-    FROM track AS t
-    JOIN slice AS s
-      ON s.track_id = t.id
-    WHERE
-      t.name = 'Suspend/Resume Minimal'
-  ),
-  suspend_slice_latency AS (
-    SELECT
-      ts,
-      dur,
-      coalesce(
-        lead(ts) OVER (PARTITION BY track.machine_id ORDER BY ts),
-        trace_end()
-      )
-      - ts
-      - dur AS duration_gap,
-      track.machine_id
-    FROM slice
-    JOIN track
-      ON slice.track_id = track.id
-    WHERE
-      track.name = 'Suspend/Resume Latency'
-      AND (slice.name = 'syscore_resume(0)'
-      OR slice.name = 'timekeeping_freeze(0)')
-      AND dur != -1
-      AND NOT EXISTS (
-        SELECT *
-        FROM suspend_slice_from_minimal
-        WHERE
-          suspend_slice_from_minimal.machine_id = track.machine_id
-      )
-  ),
-  suspend_slice_pre_filter AS (
-    SELECT ts, dur, duration_gap, machine_id FROM suspend_slice_from_minimal
-    UNION ALL
-    SELECT ts, dur, duration_gap, machine_id FROM suspend_slice_latency
-  ),
-  suspend_slice AS (
-    -- Filter out all the slices that overlapped with the following slices.
-    -- This happens with data loss where we lose start and end slices for suspends.
-    SELECT ts, dur, machine_id, 'suspended' AS power_state
-    FROM suspend_slice_pre_filter
-    WHERE
-      duration_gap >= 0
-    UNION ALL
-    -- This guarantees that if machine 0 has no suspend slices in the trace,
-    -- that _intervals_fill_gaps will add an awake slice for the trace bounds.
-    -- This only works for the primary machine because we know from the trace
-    -- starting and ending at all that the device was awake. However, for other
-    -- machines, we don't actually know the suspend state as it's very possible
-    -- they were just asleep throughout the trace.
-    SELECT NULL, NULL, 0, NULL
-  )
-SELECT
-  ts,
-  dur,
-  COALESCE(machine_id, 0) AS machine_id,
-  COALESCE(power_state, 'awake') AS power_state
-FROM _intervals_fill_gaps!((machine_id), (power_state), suspend_slice)
-ORDER BY
-  ts;
+FROM (
+  WITH
+    suspend_slice_from_minimal AS (
+      SELECT
+        ts,
+        dur,
+        coalesce(
+          lead(ts) OVER (PARTITION BY t.machine_id ORDER BY ts),
+          trace_end()
+        )
+        - ts
+        - dur AS duration_gap,
+        t.machine_id
+      FROM track AS t
+      JOIN slice AS s
+        ON s.track_id = t.id
+      WHERE
+        t.name = 'Suspend/Resume Minimal'
+    ),
+    suspend_slice_latency AS (
+      SELECT
+        ts,
+        dur,
+        coalesce(
+          lead(ts) OVER (PARTITION BY track.machine_id ORDER BY ts),
+          trace_end()
+        )
+        - ts
+        - dur AS duration_gap,
+        track.machine_id
+      FROM slice
+      JOIN track
+        ON slice.track_id = track.id
+      WHERE
+        track.name = 'Suspend/Resume Latency'
+        AND (slice.name = 'syscore_resume(0)'
+        OR slice.name = 'timekeeping_freeze(0)')
+        AND dur != -1
+        AND NOT EXISTS (
+          SELECT *
+          FROM suspend_slice_from_minimal
+          WHERE
+            suspend_slice_from_minimal.machine_id = track.machine_id
+        )
+    ),
+    suspend_slice_pre_filter AS (
+      SELECT ts, dur, duration_gap, machine_id FROM suspend_slice_from_minimal
+      UNION ALL
+      SELECT ts, dur, duration_gap, machine_id FROM suspend_slice_latency
+    )
+  -- Filter out all the slices that overlapped with the following slices.
+  -- This happens with data loss where we lose start and end slices for suspends.
+  SELECT ts, dur, machine_id, 'suspended' AS power_state
+  FROM suspend_slice_pre_filter
+  WHERE
+    duration_gap >= 0
+)
+|> INTERVAL FILL GAPS WITH (
+  SELECT trace_start() AS ts, trace_dur() AS dur, 'awake' AS power_state
+) PER machine_id
+|> INTERVAL FILL GAPS WITH (
+  SELECT
+    trace_start() AS ts,
+    trace_dur() AS dur,
+    0 AS machine_id,
+    'awake' AS power_state
+) PER machine_id
+|> ORDER BY ts;
 
 -- Order by will cause Perfetto table to index by ts.;
 
diff --git a/src/trace_processor/perfetto_sql/stdlib/intervals/BUILD.gn b/src/trace_processor/perfetto_sql/stdlib/intervals/BUILD.gn
index b6ecfb9..065d5f1 100644
--- a/src/trace_processor/perfetto_sql/stdlib/intervals/BUILD.gn
+++ b/src/trace_processor/perfetto_sql/stdlib/intervals/BUILD.gn
@@ -17,7 +17,6 @@
 perfetto_sql_source_set("intervals") {
   sources = [
     "create_intervals.sql",
-    "fill_gaps.sql",
     "intersect.sql",
     "mipmap.sql",
     "overlap.sql",
diff --git a/src/trace_processor/perfetto_sql/stdlib/intervals/fill_gaps.sql b/src/trace_processor/perfetto_sql/stdlib/intervals/fill_gaps.sql
deleted file mode 100644
index a288c0c..0000000
--- a/src/trace_processor/perfetto_sql/stdlib/intervals/fill_gaps.sql
+++ /dev/null
@@ -1,118 +0,0 @@
---
--- Copyright 2026 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 std.metasql.unparenthesize;
-
--- Helper for __intrinsic_token_apply to fill in NULLs for a ColumnNameList.
-CREATE PERFETTO MACRO __ifg_null(x Expr)
-RETURNS Expr
-AS NULL;
-
--- Fills in gaps within a table of slices, so data is present from trace_start
--- to trace_end for each group of columns.
---
--- Given a table of slices (`ts`, `dur`, `group_cols`, `data_cols`), this macro
--- returns a table where every distinct `group_cols` has contiguous data from
--- trace_start to trace_end. The `data_cols` are carried through from the source
--- and filled with nulls when gaps are found. The input must not have overlaps
--- within a set of `group_cols`
---
--- Notes:
--- * If grouping is not required, you may pass `(NULL)` for group_cols.
--- * To guarantee a group is present, it is safe to `UNION` a row with the
---   correct `group_cols` and all other columns as NULL.
---
--- Example:
--- ```
--- _intervals_fill_gaps!(
---   (uid, package_name),
---   (process_state),
---   process_state_table
--- )
--- ```
-CREATE PERFETTO MACRO _intervals_fill_gaps(
-  -- A parenthesized list of column names to group by, or (NULL) to not group.
-  group_cols ColumnNameList,
-  -- A parethensizes list of column names to carry through.
-  data_cols ColumnNameList,
-  -- The source data, with columns ts, dur, group_cols, and data_cols.
-  data TableOrSubquery
-)
-RETURNS TableOrSubquery
-AS (
-  WITH SourceData AS (
-    SELECT
-      ts, dur,
-      metasql_unparenthesize_exprlist!($group_cols),
-      metasql_unparenthesize_exprlist!($data_cols)
-    FROM $data
-  ),
-  Bounds AS (
-    SELECT
-      metasql_unparenthesize_exprlist!($group_cols),
-      MIN(ts) AS min_ts,
-      MAX(ts+dur) AS max_ts
-    FROM SourceData
-    GROUP BY metasql_unparenthesize_exprlist!($group_cols)
-  ),
-  Parts AS (
-    -- Part 1: the base data from the table.
-    SELECT
-      ts, dur,
-      metasql_unparenthesize_exprlist!($group_cols),
-      metasql_unparenthesize_exprlist!($data_cols)
-    FROM SourceData
-    UNION ALL
-    -- Part 2: the time from the trace start, to first slice.
-    SELECT
-      trace_start(), min_ts - trace_start(),
-      metasql_unparenthesize_exprlist!($group_cols),
-      __intrinsic_token_apply!(__ifg_null, $data_cols)
-    FROM Bounds
-    UNION ALL
-    -- Part 3: the time from the last slice, to trace end.
-    SELECT
-      max_ts, trace_end() - max_ts,
-      metasql_unparenthesize_exprlist!($group_cols),
-      __intrinsic_token_apply!(__ifg_null, $data_cols)
-    FROM Bounds
-    UNION ALL
-    -- Part 4.a: when there is no data for a group, return one row for the whole trace.
-    SELECT
-      trace_start(), trace_dur(),
-      metasql_unparenthesize_exprlist!($group_cols),
-      __intrinsic_token_apply!(__ifg_null, $data_cols)
-    FROM Bounds
-    WHERE min_ts IS NULL AND max_ts IS NULL
-    UNION ALL
-    -- Part 4.b: when there is no data at all, return null group_cols for the whole trace.
-    SELECT
-      trace_start(), trace_dur(),
-      __intrinsic_token_apply!(__ifg_null, $group_cols),
-      __intrinsic_token_apply!(__ifg_null, $data_cols)
-    WHERE NOT EXISTS(SELECT * FROM SourceData)
-    UNION ALL
-    -- Part 5: the time between slices (from when one ends, to next start).
-    SELECT
-      ts+dur, LEAD(ts) OVER (PARTITION BY metasql_unparenthesize_exprlist!($group_cols) ORDER BY ts) - (ts+dur),
-      metasql_unparenthesize_exprlist!($group_cols),
-      __intrinsic_token_apply!(__ifg_null, $data_cols)
-    FROM SourceData
-  )
-  SELECT *
-  FROM Parts
-  WHERE IFNULL(dur, 0) > 0
-  ORDER BY ts
-);
diff --git a/src/trace_processor/perfetto_sql/stdlib/prelude/after_eof/tracks.sql b/src/trace_processor/perfetto_sql/stdlib/prelude/after_eof/tracks.sql
index 504597f..889c1b3 100644
--- a/src/trace_processor/perfetto_sql/stdlib/prelude/after_eof/tracks.sql
+++ b/src/trace_processor/perfetto_sql/stdlib/prelude/after_eof/tracks.sql
@@ -21,6 +21,10 @@
 
 INCLUDE PERFETTO MODULE prelude.after_eof.views;
 
+INCLUDE PERFETTO MODULE prelude.after_eof.cpu_scheduling;
+
+INCLUDE PERFETTO MODULE prelude.after_eof.gpu;
+
 -- Tracks are a fundamental concept in trace processor and represent a
 -- "timeline" for events of the same type and with the same context. See
 -- https://perfetto.dev/docs/analysis/trace-processor#tracks for a more
@@ -261,3 +265,147 @@
     'gpu_log',
     'graphics_frame_event'
   );
+
+CREATE PERFETTO TABLE _track_dimension_data(
+  track_id JOINID(track.id),
+  name STRING,
+  int_value LONG,
+  string_value STRING,
+  display_name STRING,
+  is_well_known BOOL,
+  display_value STRING
+)
+AS
+-- Custom dimensions come from imported declarations; well known values come
+-- from track columns and entity metadata.
+SELECT
+  track_id,
+  name,
+  int_value,
+  string_value,
+  display_name,
+  0 AS is_well_known,
+  coalesce(cast_string!(int_value), string_value) AS display_value
+FROM __intrinsic_track_dimension
+UNION ALL
+SELECT
+  t.id AS track_id,
+  'machine' AS name,
+  t.machine_id AS int_value,
+  NULL AS string_value,
+  m.name AS display_name,
+  1 AS is_well_known,
+  cast_string!(m.label_index) AS display_value
+FROM __intrinsic_track AS t
+LEFT JOIN machine AS m
+  ON m.id = t.machine_id
+UNION ALL
+SELECT
+  t.id AS track_id,
+  'process' AS name,
+  t.upid AS int_value,
+  NULL AS string_value,
+  p.name AS display_name,
+  1 AS is_well_known,
+  cast_string!(p.pid) AS display_value
+FROM __intrinsic_track AS t
+LEFT JOIN process AS p
+  ON p.upid = t.upid
+WHERE
+  t.upid IS NOT NULL
+UNION ALL
+SELECT
+  t.id AS track_id,
+  'thread' AS name,
+  t.utid AS int_value,
+  NULL AS string_value,
+  th.name AS display_name,
+  1 AS is_well_known,
+  cast_string!(th.tid) AS display_value
+FROM __intrinsic_track AS t
+LEFT JOIN thread AS th
+  ON th.utid = t.utid
+WHERE
+  t.utid IS NOT NULL
+UNION ALL
+-- Tracks only have the per machine CPU number: the machine aware id is the one
+-- of the CPU with that number on the machine of the track.
+SELECT
+  t.id AS track_id,
+  'cpu' AS name,
+  c.id AS int_value,
+  NULL AS string_value,
+  NULL AS display_name,
+  1 AS is_well_known,
+  cast_string!(c.cpu) AS display_value
+FROM __intrinsic_track AS t
+JOIN cpu AS c
+  ON c.machine_id = t.machine_id
+  AND c.cpu = extract_arg(t.dimension_arg_set_id, 'cpu')
+UNION ALL
+SELECT
+  t.id AS track_id,
+  'gpu' AS name,
+  extract_arg(t.dimension_arg_set_id, 'ugpu') AS int_value,
+  NULL AS string_value,
+  g.name AS display_name,
+  1 AS is_well_known,
+  cast_string!(g.gpu) AS display_value
+FROM __intrinsic_track AS t
+LEFT JOIN gpu AS g
+  ON g.id = extract_arg(t.dimension_arg_set_id, 'ugpu')
+WHERE
+  extract_arg(t.dimension_arg_set_id, 'ugpu') IS NOT NULL;
+
+CREATE PERFETTO INDEX _track_dimension_data_track_id ON _track_dimension_data(
+  track_id
+);
+
+-- The dimensions of every track.
+--
+-- A dimension is a named, typed key/value which is part of a track's identity.
+-- There is one vocabulary for all of them:
+--  * *well known* dimensions (`machine`, `process`, `thread`, `cpu`, `gpu`)
+--    are derived by trace processor for every track. Their values are trace
+--    processor identities (`machine.id`, `upid`, `utid`, `cpu.id`, `gpu.id`).
+--    Note that tracks only associated with a thread don't have a `process`
+--    dimension: use `thread.upid` for those.
+--  * *custom* dimensions are declared by producers with
+--    `TrackDescriptor.dimensions` (e.g. `rank` for a distributed training
+--    job). They apply to the declaring track and its `parent_uuid`
+--    descendants, nothing else: e.g. a dimension declared on a process track
+--    only reaches the tracks of its threads if they are `parent_uuid` children
+--    of the process track. Use `thread.upid` to join the tracks of a thread to
+--    the tracks of its process otherwise.
+CREATE PERFETTO VIEW track_dimension(
+  -- The track this dimension applies to.
+  track_id JOINID(track.id),
+  -- The canonical dimension name, e.g. 'rank' or 'machine'.
+  name STRING,
+  -- The value, for integer valued dimensions.
+  int_value LONG,
+  -- The value, for string valued dimensions. Exactly one of `int_value` and
+  -- `string_value` is non-null.
+  string_value STRING,
+  -- Optional human readable label for this *value*: producer-supplied for
+  -- custom dimensions, or the corresponding entity name for well known ones
+  -- (e.g. `process.name`). Presentation only, not part of the identity.
+  display_name STRING,
+  -- Whether this is a well known dimension, i.e. one which trace processor
+  -- understands and whose value means the same thing across data sources.
+  is_well_known BOOL,
+  -- Human readable value: the producer's value for custom dimensions, or the
+  -- CPU/GPU number, pid/tid or machine label index for well known ones. Joins
+  -- and identity use `int_value` / `string_value`, not this presentation text.
+  display_value STRING
+)
+AS
+SELECT
+  track_id,
+  name,
+  int_value,
+  string_value,
+  display_name,
+  is_well_known,
+  display_value
+FROM _track_dimension_data;
diff --git a/src/trace_processor/perfetto_sql/stdlib/slices/cpu_time.sql b/src/trace_processor/perfetto_sql/stdlib/slices/cpu_time.sql
index fafb2f2..50b0a4c2 100644
--- a/src/trace_processor/perfetto_sql/stdlib/slices/cpu_time.sql
+++ b/src/trace_processor/perfetto_sql/stdlib/slices/cpu_time.sql
@@ -13,8 +13,6 @@
 -- See the License for the specific language governing permissions and
 -- limitations under the License.
 
-INCLUDE PERFETTO MODULE intervals.intersect;
-
 INCLUDE PERFETTO MODULE linux.cpu.utilization.slice;
 
 INCLUDE PERFETTO MODULE slices.with_context;
@@ -38,24 +36,26 @@
   cpu_time LONG
 )
 AS
-SELECT
-  id_0 AS id,
-  name,
-  ts.utid,
-  thread_name,
-  upid,
-  process_name,
-  sum(ii.dur) AS cpu_time
-FROM _interval_intersect!((
-  (SELECT * FROM thread_slice WHERE utid > 0 AND dur > 0),
-  (SELECT * FROM sched WHERE dur > 0)
-  ), (utid)) AS ii
-JOIN thread_slice AS ts
-  ON ts.id = ii.id_0
+INTERVAL INTERSECTION OF (
+  (
+    SELECT id, ts, dur, name, utid, thread_name, upid, process_name
+    FROM thread_slice
+    WHERE
+      utid > 0
+      AND dur > 0
+  ) AS s,
+  (SELECT ts, dur, utid FROM sched WHERE dur > 0) AS running
+) PER utid
+|> AGGREGATE
+  SUM(dur) AS cpu_time
 GROUP BY
-  id
-ORDER BY
-  id;
+  s.id,
+  s.name,
+  utid,
+  s.thread_name,
+  s.upid,
+  s.process_name
+|> ORDER BY id;
 
 -- CPU cycles per each slice.
 CREATE PERFETTO VIEW thread_slice_cpu_cycles(
diff --git a/src/trace_processor/perfetto_sql/stdlib/slices/time_in_state.sql b/src/trace_processor/perfetto_sql/stdlib/slices/time_in_state.sql
index 12b2a63..0b9f8e8 100644
--- a/src/trace_processor/perfetto_sql/stdlib/slices/time_in_state.sql
+++ b/src/trace_processor/perfetto_sql/stdlib/slices/time_in_state.sql
@@ -13,8 +13,6 @@
 -- See the License for the specific language governing permissions and
 -- limitations under the License.
 
-INCLUDE PERFETTO MODULE intervals.intersect;
-
 INCLUDE PERFETTO MODULE slices.with_context;
 
 -- For each thread slice, returns the sum of the time it spent in various
@@ -55,32 +53,31 @@
   dur DURATION
 )
 AS
-SELECT
-  ii.id_0 AS id,
-  ts.name,
-  ts.utid,
-  ts.thread_name,
-  ts.upid,
-  ts.process_name,
-  tstate.state,
-  tstate.io_wait,
-  tstate.blocked_function,
-  sum(ii.dur) AS dur
-FROM _interval_intersect!(
+INTERVAL INTERSECTION OF (
   (
-    (SELECT * FROM thread_slice WHERE utid > 0 AND dur > 0),
-    (SELECT * FROM thread_state WHERE dur > 0)
-  ),
-  (utid)
-) AS ii
-JOIN thread_slice AS ts
-  ON ts.id = ii.id_0
-JOIN thread_state AS tstate
-  ON tstate.id = ii.id_1
+    SELECT id, ts, dur, name, utid, thread_name, upid, process_name
+    FROM thread_slice
+    WHERE
+      utid > 0
+      AND dur > 0
+  ) AS s,
+  (
+    SELECT ts, dur, utid, state, io_wait, blocked_function
+    FROM thread_state
+    WHERE
+      dur > 0
+  ) AS st
+) PER utid
+|> AGGREGATE
+  SUM(dur) AS dur
 GROUP BY
-  ii.id_0,
-  tstate.state,
-  tstate.io_wait,
-  tstate.blocked_function
-ORDER BY
-  ii.id_0;
+  s.id,
+  s.name,
+  utid,
+  s.thread_name,
+  s.upid,
+  s.process_name,
+  st.state,
+  st.io_wait,
+  st.blocked_function
+|> ORDER BY id;
diff --git a/src/trace_processor/perfetto_sql/stdlib/wattson/cpu/freq.sql b/src/trace_processor/perfetto_sql/stdlib/wattson/cpu/freq.sql
index 4afcbae..6002494 100644
--- a/src/trace_processor/perfetto_sql/stdlib/wattson/cpu/freq.sql
+++ b/src/trace_processor/perfetto_sql/stdlib/wattson/cpu/freq.sql
@@ -17,41 +17,17 @@
 
 INCLUDE PERFETTO MODULE wattson.device_infos;
 
+-- Every physically present CPU's frequency from trace start to trace end, NULL
+-- where no freq event defines it, so that interval_intersect doesn't remove the
+-- undefined time region.
 CREATE PERFETTO TABLE _adjusted_cpu_freq AS
-WITH
-  _cpu_freq AS (
-    SELECT ts, dur, freq, cf.ucpu AS cpu, d_map.policy
-    FROM cpu_frequency_counters AS cf
-    JOIN _dev_cpu_policy_map AS d_map
-      ON cf.ucpu = d_map.cpu
-  ),
-  -- Get first freq transition per CPU
-  first_cpu_freq_slices AS (
-    SELECT min(ts) AS ts, cpu FROM _cpu_freq GROUP BY cpu
-  )
--- Prepend NULL slices up to first freq events on a per CPU basis
-SELECT
-  -- Construct slices from first cpu ts up to first freq event for each cpu
-  trace_start() AS ts,
-  first_slices.ts - trace_start() AS dur,
-  NULL AS freq,
-  first_slices.cpu,
-  d_map.policy
-FROM first_cpu_freq_slices AS first_slices
-JOIN _dev_cpu_policy_map AS d_map
-  ON first_slices.cpu = d_map.cpu
-UNION ALL
-SELECT ts, dur, freq, cpu, policy FROM _cpu_freq
-UNION ALL
--- Add empty cpu freq counters for CPUs that are physically present, but did not
--- have a single freq event register. The time region needs to be defined so
--- that interval_intersect doesn't remove the undefined time region.
-SELECT
-  trace_start() AS ts,
-  trace_dur() AS dur,
-  NULL AS freq,
-  cpu,
-  NULL AS policy
-FROM _dev_cpu_policy_map
-WHERE
-  NOT (cpu IN (SELECT cpu FROM first_cpu_freq_slices));
+FROM (
+  SELECT ts, dur, freq, cf.ucpu AS cpu, d_map.policy
+  FROM cpu_frequency_counters AS cf
+  JOIN _dev_cpu_policy_map AS d_map
+    ON cf.ucpu = d_map.cpu
+)
+|> INTERVAL FILL GAPS WITH (
+  SELECT trace_start() AS ts, trace_dur() AS dur, cpu, policy
+  FROM _dev_cpu_policy_map
+) PER cpu;
diff --git a/src/trace_processor/perfetto_sql/stdlib/wattson/cpu/hotplug.sql b/src/trace_processor/perfetto_sql/stdlib/wattson/cpu/hotplug.sql
index a0478fb..0257b1f 100644
--- a/src/trace_processor/perfetto_sql/stdlib/wattson/cpu/hotplug.sql
+++ b/src/trace_processor/perfetto_sql/stdlib/wattson/cpu/hotplug.sql
@@ -69,34 +69,18 @@
   iif(is_different_cpu AND dur < time_from_us(100), FALSE, is_different_cpu) AS is_different_cpu
 FROM transitions_dur;
 
--- Fill gaps from beginning of trace to end of trace so that this table can be
--- used by interval_intersect().
+-- Every CPU's hotplug state from trace start to trace end, online wherever
+-- cpuhp says nothing, so that this table can be used by interval_intersect():
+-- a CPU which is never offline is online throughout.
 CREATE PERFETTO TABLE _gapless_hotplug_slices AS
-WITH
-  filled_gaps AS (
-    -- First slice from trace_start() to first offline slice per CPU
-    SELECT
-      cpu,
-      trace_start() AS ts,
-      min(ts) - trace_start() AS dur,
-      FALSE AS offline
-    FROM _cpu_hotplug_offline
-    GROUP BY
-      cpu
-    UNION ALL
-    -- All online and offline regions as defined by cpuhp. This will have
-    -- continuous slices from somewhere in the middle to the end of the trace.
-    SELECT cpu, ts, dur, is_different_cpu AS offline FROM _cpu_hotplug_offline
-    UNION ALL
-    -- Creates a single online slice spanning the entire trace for CPUs that are
-    -- never offline. This is needed for interval_intersect() to not delete
-    -- undefined time periods
-    SELECT cpu, trace_start() AS ts, trace_dur() AS dur, FALSE AS offline
-    FROM _dev_cpu_policy_map
-    WHERE
-      NOT (cpu IN (SELECT cpu FROM _cpu_hotplug_offline))
-  )
-SELECT ts, dur, cpu, offline FROM filled_gaps ORDER BY cpu, ts;
+FROM (
+  SELECT ts, dur, cpu, is_different_cpu AS offline FROM _cpu_hotplug_offline
+)
+|> INTERVAL FILL GAPS WITH (
+  SELECT trace_start() AS ts, trace_dur() AS dur, cpu, FALSE AS offline
+  FROM _dev_cpu_policy_map
+) PER cpu
+|> ORDER BY cpu, ts;
 
 -- Nominal suspend table with gapless suspended state.
 CREATE PERFETTO TABLE _gapless_suspend_slices AS
diff --git a/src/trace_processor/perfetto_sql/stdlib/wattson/gpu/freq_idle.sql b/src/trace_processor/perfetto_sql/stdlib/wattson/gpu/freq_idle.sql
index 46b8656..2d9286c 100644
--- a/src/trace_processor/perfetto_sql/stdlib/wattson/gpu/freq_idle.sql
+++ b/src/trace_processor/perfetto_sql/stdlib/wattson/gpu/freq_idle.sql
@@ -40,46 +40,28 @@
 WHERE
   t.name = 'powervr_gpu_power_state';
 
--- Gapless time slices of GPU freq from trace_start() to trace_end()
+-- Gapless time slices of GPU freq from trace_start() to trace_end(), NULL where
+-- no freq event defines it.
 CREATE PERFETTO TABLE _gapless_gpu_freq AS
-WITH
-  nominal_freqs AS (
-    -- Prepend NULL slices up to first freq events
-    SELECT
-      trace_start() AS ts,
-      min(ts) - trace_start() AS dur,
-      NULL AS freq,
-      NULL AS prev_freq,
-      next_gpu_freq AS next_freq,
-      gpu_id
-    FROM android_gpu_frequency
-    WHERE
-      gpu_id
-      = (
-        SELECT gpu_id
-        FROM _gpuid_map
-        JOIN _wattson_device
-          ON _gpuid_map.device = _wattson_device.name
-      )
-    UNION ALL
-    SELECT
-      ts,
-      dur,
-      gpu_freq AS freq,
-      prev_gpu_freq AS prev_freq,
-      next_gpu_freq AS next_freq,
-      gpu_id
-    FROM android_gpu_frequency
-    WHERE
-      gpu_id
-      = (
-        SELECT gpu_id
-        FROM _gpuid_map
-        JOIN _wattson_device
-          ON _gpuid_map.device = _wattson_device.name
-      )
-  )
-SELECT * FROM nominal_freqs;
+FROM (
+  SELECT
+    ts,
+    dur,
+    gpu_freq AS freq,
+    prev_gpu_freq AS prev_freq,
+    next_gpu_freq AS next_freq,
+    gpu_id
+  FROM android_gpu_frequency
+  WHERE
+    gpu_id
+    = (
+      SELECT gpu_id
+      FROM _gpuid_map
+      JOIN _wattson_device
+        ON _gpuid_map.device = _wattson_device.name
+    )
+)
+|> INTERVAL FILL GAPS WITH (SELECT trace_start() AS ts, trace_dur() AS dur);
 
 -- A single source for GPU power state information
 -- from either mali or pvr which are mutually exclusive
@@ -88,20 +70,11 @@
 UNION ALL
 SELECT ts, dur, power_state FROM _pvr_gpu_power_state;
 
--- Gapless time slices of GPU idle from trace_start() to trace_end()
+-- Gapless time slices of GPU idle from trace_start() to trace_end(), NULL where
+-- no power state event defines it.
 CREATE PERFETTO TABLE _gapless_gpu_power_state AS
--- Prepend NULL slices up to first idle events
-WITH
-  nominal_power_states AS (
-    SELECT
-      trace_start() AS ts,
-      min(ts) - trace_start() AS dur,
-      NULL AS power_state
-    FROM _gpu_power_state
-    UNION ALL
-    SELECT ts, dur, power_state FROM _gpu_power_state
-  )
-SELECT * FROM nominal_power_states;
+FROM _gpu_power_state
+|> INTERVAL FILL GAPS WITH (SELECT trace_start() AS ts, trace_dur() AS dur);
 
 -- GPU frequency and power state over the regions where both are defined.
 CREATE PERFETTO TABLE _gpu_freq_idle_raw AS
diff --git a/src/trace_processor/perfetto_sql/stdlib/wattson/tpu/freq_idle.sql b/src/trace_processor/perfetto_sql/stdlib/wattson/tpu/freq_idle.sql
index 14abee9..900d2bc 100644
--- a/src/trace_processor/perfetto_sql/stdlib/wattson/tpu/freq_idle.sql
+++ b/src/trace_processor/perfetto_sql/stdlib/wattson/tpu/freq_idle.sql
@@ -14,47 +14,41 @@
 -- limitations under the License.
 
 -- Creates TPU freq counter and cluster based off of slices
--- (gapless from trace_start to trace_end)
+-- (gapless from trace_start to trace_end, 0 where no DVFS event defines it)
+-- A device without a TPU has no DVFS events, and so no TPU frequency at all.
 CREATE PERFETTO TABLE _tpu_freq AS
-WITH
-  raw_freqs AS (
-    SELECT
-      s.ts,
-      iif(s.dur = -1, trace_end() - s.ts, s.dur) AS dur,
-      CAST(s.name AS INTEGER) AS freq,
-      CASE
-        WHEN s.name GLOB '*Cluster Both*' THEN 2
-        WHEN s.name GLOB '*Cluster 0*' THEN 0
-        WHEN s.name GLOB '*Cluster 1*' THEN 1
-        ELSE 2
-      END AS cluster
-    FROM slice AS s
-    JOIN track AS t
-      ON t.id = s.track_id
-    WHERE
-      t.name = 'DVFS'
-  ),
-  all_slices AS (
-    -- Initial gap before first DVFS event
-    SELECT
-      trace_start() AS ts,
-      min(ts) - trace_start() AS dur,
-      0 AS freq,
-      0 AS cluster
-    FROM raw_freqs
-    UNION ALL
-    -- Active DVFS events
-    SELECT ts, dur, freq, cluster FROM raw_freqs
-    UNION ALL
-    -- Gaps between consecutive DVFS events and after the last DVFS event
-    SELECT
-      ts + dur AS ts,
-      lead(ts, 1, trace_end()) OVER (ORDER BY ts) - (ts + dur) AS dur,
-      0 AS freq,
-      0 AS cluster
-    FROM raw_freqs
-  )
-SELECT * FROM all_slices WHERE dur > 0 ORDER BY ts;
+FROM (
+  SELECT
+    s.ts,
+    iif(s.dur = -1, trace_end() - s.ts, s.dur) AS dur,
+    CAST(s.name AS INTEGER) AS freq,
+    CASE
+      WHEN s.name GLOB '*Cluster Both*' THEN 2
+      WHEN s.name GLOB '*Cluster 0*' THEN 0
+      WHEN s.name GLOB '*Cluster 1*' THEN 1
+      ELSE 2
+    END AS cluster
+  FROM slice AS s
+  JOIN track AS t
+    ON t.id = s.track_id
+  WHERE
+    t.name = 'DVFS'
+    AND s.dur != 0
+)
+|> INTERVAL FILL GAPS WITH (
+  SELECT trace_start() AS ts, trace_dur() AS dur, 0 AS freq, 0 AS cluster
+  WHERE
+    EXISTS (
+      SELECT 1
+      FROM slice AS s
+      JOIN track AS t
+        ON t.id = s.track_id
+      WHERE
+        t.name = 'DVFS'
+        AND s.dur != 0
+    )
+)
+|> ORDER BY ts;
 
 -- Number of parallel TPU requests at any point in time. The weight 0
 -- background row spanning the whole trace makes INTERVAL FLATTEN also emit
diff --git a/src/trace_processor/plugins/android_process_state/android_process_state_tracker.cc b/src/trace_processor/plugins/android_process_state/android_process_state_tracker.cc
index 92b2bf1..214febb 100644
--- a/src/trace_processor/plugins/android_process_state/android_process_state_tracker.cc
+++ b/src/trace_processor/plugins/android_process_state/android_process_state_tracker.cc
@@ -216,12 +216,17 @@
     }
     FreezerStateValues v;
     v.upid = *opt_upid;
-    // Note: android.util.proto.ProtoOutputStream ignores/omits 0 data points
-    // during serialization on Android, so unset fields represent UFR_NONE (0).
-    v.unfreeze_reason =
-        rec.has_unfreeze_reason()
-            ? static_cast<int32_t>(rec.unfreeze_reason())
-            : static_cast<int32_t>(fb::UnfreezeReason::UFR_NONE);
+    // If the process is unfrozen in the dump, has_unfrozen_dur_ms() is true.
+    // Note: android.util.proto.ProtoOutputStream omits 0 values during
+    // serialization, so an unset unfreeze_reason on an unfrozen process
+    // represents UFR_NONE (0). When the process is frozen, unfreeze_reason is
+    // left as std::nullopt so the initial row has NULL.
+    if (rec.has_unfrozen_dur_ms()) {
+      v.unfreeze_reason =
+          rec.has_unfreeze_reason()
+              ? static_cast<int32_t>(rec.unfreeze_reason())
+              : static_cast<int32_t>(fb::UnfreezeReason::UFR_NONE);
+    }
     freezer_dump_[v.upid] = v;
   }
 }
diff --git a/src/trace_processor/plugins/storage_tables/storage_tables.cc b/src/trace_processor/plugins/storage_tables/storage_tables.cc
index f9b16a2d..1f2b8f6 100644
--- a/src/trace_processor/plugins/storage_tables/storage_tables.cc
+++ b/src/trace_processor/plugins/storage_tables/storage_tables.cc
@@ -208,6 +208,7 @@
     AddDataframe(out, s->mutable_sched_slice_table(), {{"utid"}});
     AddDataframe(out, s->mutable_thread_state_table());
     AddDataframe(out, s->mutable_track_table());
+    AddDataframe(out, s->mutable_track_dimension_table(), {{"track_id"}});
     AddDataframe(out, s->mutable_counter_table());
     AddDataframe(out, s->mutable_android_network_packets_table());
     AddDataframe(out, s->mutable_metadata_table());
diff --git a/src/trace_processor/plugins/wattson/data/Tensor_G6/cpu_1d.csv b/src/trace_processor/plugins/wattson/data/Tensor_G6/cpu_1d.csv
index cd290ae..fef855a 100644
--- a/src/trace_processor/plugins/wattson/data/Tensor_G6/cpu_1d.csv
+++ b/src/trace_processor/plugins/wattson/data/Tensor_G6/cpu_1d.csv
@@ -1,86 +1,86 @@
-device,policy,freq_khz,static,active,idle0,idle1

-Tensor G6,0,394000,0.23,20.19,2.33,0.00

-Tensor G6,0,533000,0.36,26.62,2.46,0.00

-Tensor G6,0,614000,1.03,29.38,2.38,0.00

-Tensor G6,0,691000,0.97,31.56,2.7,0.00

-Tensor G6,0,787000,1.33,35.77,2.66,0.00

-Tensor G6,0,883000,1.4,38.93,2.79,0.00

-Tensor G6,0,960000,1.36,43.64,2.92,0.00

-Tensor G6,0,1036000,1.62,49.5,3.03,0.00

-Tensor G6,0,1152000,1.98,50.15,2.95,0.00

-Tensor G6,0,1248000,2.1,55.8,3.2,0.00

-Tensor G6,0,1344000,2.08,60.31,3.65,0.00

-Tensor G6,0,1440000,2.61,64.38,3.51,0.00

-Tensor G6,0,1536000,3.09,71.62,3.66,0.00

-Tensor G6,0,1632000,3.38,73.76,3.93,0.00

-Tensor G6,0,1728000,3.72,83.43,4.08,0.00

-Tensor G6,0,1824000,4.37,91.3,4.14,0.00

-Tensor G6,0,1920000,4.13,97.12,4.51,0.00

-Tensor G6,0,2073000,6,106.83,4.53,0.00

-Tensor G6,0,2150000,5.93,114.07,4.92,0.00

-Tensor G6,0,2227000,6.13,129.38,5.47,0.00

-Tensor G6,0,2342000,6.42,140.32,6.28,0.00

-Tensor G6,0,2496000,8.98,160.73,6.88,0.00

-Tensor G6,0,2649000,9.71,186.1,8.51,0.00

-Tensor G6,2,394000,3.6,44.50,2.97,0.00

-Tensor G6,2,533000,3,50.52,3.57,0.0

-Tensor G6,2,614000,3.33,55.59,3.7,0.00

-Tensor G6,2,691000,3.87,57.93,3.85,0.00

-Tensor G6,2,768000,2.74,65.50,4.20,0.00

-Tensor G6,2,844000,1.61,72.00,4.40,0.00

-Tensor G6,2,921000,4.44,78.00,4.55,0.00

-Tensor G6,2,1036000,5,83.04,3.92,0.00

-Tensor G6,2,1171000,5.22,101.96,4.61,0.00

-Tensor G6,2,1305000,5.57,104.06,4.77,0.00

-Tensor G6,2,1440000,6.24,109.85,5.07,0.00

-Tensor G6,2,1574000,6.9,132,5.37,0.00

-Tensor G6,2,1689000,7.87,145.47,5.4,0.00

-Tensor G6,2,1804000,7.11,160.55,6.19,0.00

-Tensor G6,2,1920000,9.88,176.89,5.61,0.00

-Tensor G6,2,2035000,9.81,187.98,5.97,0.00

-Tensor G6,2,2169000,11.5,201.71,6.54,0.00

-Tensor G6,2,2304000,12.07,219.8,7.62,0.00

-Tensor G6,2,2476000,15.06,290.32,8.34,0.00

-Tensor G6,2,2649000,19.3,302.61,9.41,0.00

-Tensor G6,2,2899000,22.23,400.29,10.99,0.00

-Tensor G6,2,3148000,25.22,497.95,17.53,0.00

-Tensor G6,2,3379000,36.75,599.38,26.39,0.00

-Tensor G6,6,788000,0.00,224.67,38.22,0.00

-Tensor G6,6,921000,0.00,286.72,40.43,0.00

-Tensor G6,6,1056000,0.00,340.74,42.26,0.00

-Tensor G6,6,1190000,0.00,394.75,43.82,0.00

-Tensor G6,6,1305000,0.00,441.85,45.77,0.00

-Tensor G6,6,1420000,0.00,488.95,47.15,0.00

-Tensor G6,6,1555000,0.00,544.24,50.52,0.00

-Tensor G6,6,1689000,0.00,623.94,52.94,0.00

-Tensor G6,6,1843000,0.00,703.65,57.00,0.00

-Tensor G6,6,1996000,0.00,706.12,59.56,0.00

-Tensor G6,6,2150000,0.00,708.58,63.23,0.00

-Tensor G6,6,2323000,0.00,923.93,68.98,0.00

-Tensor G6,6,2496000,0.00,1134.83,72.56,0.00

-Tensor G6,6,2649000,0.00,1316.40,83.26,0.00

-Tensor G6,6,2803000,0.00,1499.15,86.51,0.00

-Tensor G6,6,3033000,0.00,1772.10,91.49,0.00

-Tensor G6,6,3340000,0.00,2147.35,96.99,0.00

-Tensor G6,6,3571000,0.00,2429.71,97.50,0.00

-Tensor G6,6,3782000,0.00,4985.61,98.20,0.00

-Tensor G6,6,3898000,0.00,5565.42,99.31,0.00

-Tensor G6,6,4013000,0.00,5677.65,101.13,0.00

-Tensor G6,6,4109000,0.00,5905.11,101.02,0.00

-Tensor G6,255,394000000,0.0,56.97,0.0,0.0

-Tensor G6,255,533000000,0.0,60.31,0.0,0.0

-Tensor G6,255,691000000,0.0,60.92,0.0,0.0

-Tensor G6,255,768000000,0.0,65.87,0.0,0.0

-Tensor G6,255,883000000,0.0,69.78,0.0,0.0

-Tensor G6,255,960000000,0.0,73.26,0.0,0.0

-Tensor G6,255,1036000000,0.0,77.38,0.0,0.0

-Tensor G6,255,1113000000,0.0,78.83,0.0,0.0

-Tensor G6,255,1190000000,0.0,86.69,0.0,0.0

-Tensor G6,255,1305000000,0.0,90.65,0.0,0.0

-Tensor G6,255,1382000000,0.0,94.52,0.0,0.0

-Tensor G6,255,1459000000,0.0,98.66,0.0,0.0

-Tensor G6,255,1536000000,0.0,103.76,0.0,0.0

-Tensor G6,255,1612000000,0.0,112.86,0.0,0.0

-Tensor G6,255,1728000000,0.0,126.21,0.0,0.0

-Tensor G6,255,1843000000,0.0,137.24,0.0,0.0

-Tensor G6,255,1920000000,0.0,141.83,0.0,0.0

+device,policy,freq_khz,static,active,idle0,idle1
+Tensor G6,0,394000,0.50,20.19,2.33,0.00
+Tensor G6,0,533000,15.93,26.62,2.46,0.00
+Tensor G6,0,614000,18.54,29.38,2.38,0.00
+Tensor G6,0,691000,20.85,31.56,2.7,0.00
+Tensor G6,0,787000,23.59,35.77,2.66,0.00
+Tensor G6,0,883000,26.20,38.93,2.79,0.00
+Tensor G6,0,960000,28.23,43.64,2.92,0.00
+Tensor G6,0,1036000,30.19,49.5,3.03,0.00
+Tensor G6,0,1152000,33.09,50.15,2.95,0.00
+Tensor G6,0,1248000,35.44,55.8,3.2,0.00
+Tensor G6,0,1344000,37.73,60.31,3.65,0.00
+Tensor G6,0,1440000,39.98,64.38,3.51,0.00
+Tensor G6,0,1536000,42.19,71.62,3.66,0.00
+Tensor G6,0,1632000,44.36,73.76,3.93,0.00
+Tensor G6,0,1728000,46.51,83.43,4.08,0.00
+Tensor G6,0,1824000,48.62,91.3,4.14,0.00
+Tensor G6,0,1920000,50.70,97.12,4.51,0.00
+Tensor G6,0,2073000,53.97,106.83,4.53,0.00
+Tensor G6,0,2150000,55.59,114.07,4.92,0.00
+Tensor G6,0,2227000,57.20,129.38,5.47,0.00
+Tensor G6,0,2342000,59.58,140.32,6.28,0.00
+Tensor G6,0,2496000,62.72,160.73,6.88,0.00
+Tensor G6,0,2649000,65.00,186.1,8.51,0.00
+Tensor G6,2,394000,20.00,44.50,2.97,0.00
+Tensor G6,2,533000,43.67,50.52,3.57,0.0
+Tensor G6,2,614000,47.14,55.59,3.7,0.00
+Tensor G6,2,691000,50.14,57.93,3.85,0.00
+Tensor G6,2,768000,52.95,65.50,4.20,0.00
+Tensor G6,2,844000,55.58,72.00,4.40,0.00
+Tensor G6,2,921000,58.13,78.00,4.55,0.00
+Tensor G6,2,1036000,61.78,83.04,3.92,0.00
+Tensor G6,2,1171000,65.85,101.96,4.61,0.00
+Tensor G6,2,1305000,69.71,104.06,4.77,0.00
+Tensor G6,2,1440000,73.44,109.85,5.07,0.00
+Tensor G6,2,1574000,77.01,132,5.37,0.00
+Tensor G6,2,1689000,79.98,145.47,5.4,0.00
+Tensor G6,2,1804000,82.89,160.55,6.19,0.00
+Tensor G6,2,1920000,85.75,176.89,5.61,0.00
+Tensor G6,2,2035000,87.50,187.98,5.97,0.00
+Tensor G6,2,2169000,88.65,201.71,6.54,0.00
+Tensor G6,2,2304000,89.87,219.8,7.62,0.00
+Tensor G6,2,2476000,93.30,290.32,8.34,0.00
+Tensor G6,2,2649000,96.65,302.61,9.41,0.00
+Tensor G6,2,2899000,101.41,400.29,10.99,0.00
+Tensor G6,2,3148000,105.97,497.95,17.53,0.00
+Tensor G6,2,3379000,110.00,599.38,26.39,0.00
+Tensor G6,6,788000,10.00,224.67,38.22,0.00
+Tensor G6,6,921000,53.68,286.72,40.43,0.00
+Tensor G6,6,1056000,64.15,340.74,42.26,0.00
+Tensor G6,6,1190000,73.48,394.75,43.82,0.00
+Tensor G6,6,1305000,80.96,441.85,45.77,0.00
+Tensor G6,6,1420000,88.09,488.95,47.15,0.00
+Tensor G6,6,1555000,96.14,544.24,50.52,0.00
+Tensor G6,6,1689000,103.85,623.94,52.94,0.00
+Tensor G6,6,1843000,112.44,703.65,57.00,0.00
+Tensor G6,6,1996000,120.73,706.12,59.56,0.00
+Tensor G6,6,2150000,128.86,708.58,63.23,0.00
+Tensor G6,6,2323000,137.78,923.93,68.98,0.00
+Tensor G6,6,2496000,146.50,1134.83,72.56,0.00
+Tensor G6,6,2649000,154.05,1316.40,83.26,0.00
+Tensor G6,6,2803000,161.51,1499.15,86.51,0.00
+Tensor G6,6,3033000,172.43,1772.10,91.49,0.00
+Tensor G6,6,3340000,186.65,2147.35,96.99,0.00
+Tensor G6,6,3571000,197.09,2429.71,97.50,0.00
+Tensor G6,6,3782000,206.45,4985.61,98.20,0.00
+Tensor G6,6,3898000,211.53,5565.42,99.31,0.00
+Tensor G6,6,4013000,216.52,5677.65,101.13,0.00
+Tensor G6,6,4109000,220.00,5905.11,101.02,0.00
+Tensor G6,255,394000000,0.0,21.50,0.0,0.0
+Tensor G6,255,533000000,0.0,29.06,0.0,0.0
+Tensor G6,255,691000000,0.0,30.76,0.0,0.0
+Tensor G6,255,768000000,0.0,36.32,0.0,0.0
+Tensor G6,255,883000000,0.0,42.20,0.0,0.0
+Tensor G6,255,960000000,0.0,45.67,0.0,0.0
+Tensor G6,255,1036000000,0.0,51.65,0.0,0.0
+Tensor G6,255,1113000000,0.0,55.69,0.0,0.0
+Tensor G6,255,1190000000,0.0,63.69,0.0,0.0
+Tensor G6,255,1305000000,0.0,82.10,0.0,0.0
+Tensor G6,255,1382000000,0.0,88.00,0.0,0.0
+Tensor G6,255,1459000000,0.0,95.20,0.0,0.0
+Tensor G6,255,1536000000,0.0,101.70,0.0,0.0
+Tensor G6,255,1612000000,0.0,111.40,0.0,0.0
+Tensor G6,255,1728000000,0.0,127.00,0.0,0.0
+Tensor G6,255,1843000000,0.0,140.70,0.0,0.0
+Tensor G6,255,1920000000,0.0,149.00,0.0,0.0
diff --git a/src/trace_processor/plugins/winscope_importer/winscope_proto_mapping.h b/src/trace_processor/plugins/winscope_importer/winscope_proto_mapping.h
index 024b06e..e9493c8 100644
--- a/src/trace_processor/plugins/winscope_importer/winscope_proto_mapping.h
+++ b/src/trace_processor/plugins/winscope_importer/winscope_proto_mapping.h
@@ -74,8 +74,7 @@
 }
 }  // namespace
 
-inline base::StatusOr<const char* const> GetProtoName(
-    const std::string& table_name) {
+inline base::StatusOr<const char*> GetProtoName(const std::string& table_name) {
   if (table_name == tables::SurfaceFlingerLayerTable::Name()) {
     return ".com.android.internal.LayerProto";
   }
diff --git a/src/trace_processor/plugins/winscope_proto_to_args_with_defaults/winscope_proto_to_args_with_defaults.cc b/src/trace_processor/plugins/winscope_proto_to_args_with_defaults/winscope_proto_to_args_with_defaults.cc
index cdd6c9f..becf927 100644
--- a/src/trace_processor/plugins/winscope_proto_to_args_with_defaults/winscope_proto_to_args_with_defaults.cc
+++ b/src/trace_processor/plugins/winscope_proto_to_args_with_defaults/winscope_proto_to_args_with_defaults.cc
@@ -416,7 +416,7 @@
         base::ErrStatus("Failed to find %s table.", table_name_str.c_str()));
   }
 
-  base::StatusOr<const char* const> proto_name =
+  base::StatusOr<const char*> proto_name =
       util::winscope_proto_mapping::GetProtoName(table_name_str);
   if (!proto_name.ok()) {
     return OnFailure(proto_name.status());
diff --git a/src/trace_processor/sorter/BUILD.gn b/src/trace_processor/sorter/BUILD.gn
index 67d6e1f..f1de486 100644
--- a/src/trace_processor/sorter/BUILD.gn
+++ b/src/trace_processor/sorter/BUILD.gn
@@ -29,6 +29,7 @@
     "../../../gn:default_deps",
     "../../../include/perfetto/trace_processor:storage",
     "../../base",
+    "../core/util",
     "../importers/common:parser_types",
     "../importers/common:stats_tracker",
     "../importers/proto:packet_sequence_state_generation_hdr",
diff --git a/src/trace_processor/sorter/trace_sorter.cc b/src/trace_processor/sorter/trace_sorter.cc
index 692add7..c66bfe2 100644
--- a/src/trace_processor/sorter/trace_sorter.cc
+++ b/src/trace_processor/sorter/trace_sorter.cc
@@ -21,9 +21,11 @@
 #include <cstring>
 #include <limits>
 #include <memory>
+#include <vector>
 
 #include "perfetto/base/logging.h"
 #include "perfetto/public/compiler.h"
+#include "src/trace_processor/core/util/heap.h"
 #include "src/trace_processor/sorter/trace_sorter.h"
 #include "src/trace_processor/sorter/trace_token_buffer.h"
 #include "src/trace_processor/storage/stats.h"
@@ -123,46 +125,32 @@
 //  q2              {min_ts: 12    max_ts: 40}
 //
 // We know that we can extract all events from q1 until we hit ts=10 without
-// looking at any other queue. After hitting ts=10, we need to re-look to all of
-// them to figure out the next min-event.
-// There are more suitable data structures to do this (e.g. keeping a min-heap
-// to avoid re-scanning all the queues all the times) but doesn't seem worth it.
-// With Android traces (that have 8 CPUs) this function accounts for ~1-3% cpu
-// time in a profiler.
+// looking at any other queue. After hitting ts=10, the next min-queue comes
+// from a heap: queues interleave finely, so this repeats every event or two,
+// and re-scanning all of them each time dominated extraction.
 void TraceSorter::SortAndExtractEventsUntilAllocId(
     BumpAllocator::AllocId limit_alloc_id) {
   constexpr int64_t kTsMax = std::numeric_limits<int64_t>::max();
-  for (;;) {
-    size_t min_queue_idx = 0;  // The index of the queue with the min(ts).
-
-    // The top-2 min(ts) among all queues.
-    // queues_[min_queue_idx].events.timestamp == min_queue_ts[0].
-    int64_t min_queue_ts[2]{kTsMax, kTsMax};
-
-    // This loop identifies the queue which starts with the earliest event and
-    // also remembers the earliest event of the 2nd queue (in min_queue_ts[1]).
-    bool all_queues_empty = true;
-    for (size_t i = 0; i < queues_.size(); i++) {
-      auto& queue = queues_[i];
-      if (queue.events_.empty()) {
-        continue;
-      }
-      PERFETTO_DCHECK(queue.max_ts_ <= append_max_ts_);
-
-      // Checking for |all_queues_empty| is necessary here as in fuzzer cases
-      // we can end up with |int64::max()| as the value here.
-      // See https://crbug.com/oss-fuzz/69164 for an example.
-      if (all_queues_empty || queue.min_ts_ < min_queue_ts[0]) {
-        min_queue_ts[1] = min_queue_ts[0];
-        min_queue_ts[0] = queue.min_ts_;
-        min_queue_idx = i;
-      } else if (queue.min_ts_ < min_queue_ts[1]) {
-        min_queue_ts[1] = queue.min_ts_;
-      }
-      all_queues_empty = false;
+  // A min-heap of the non-empty queues by their earliest event, ties broken
+  // by queue index, so equal timestamps come out in queue order.
+  auto later = [](const QueueHeapEntry& a, const QueueHeapEntry& b) {
+    return a.min_ts != b.min_ts ? a.min_ts > b.min_ts : a.queue > b.queue;
+  };
+  std::vector<QueueHeapEntry>& heap = queue_heap_;
+  heap.clear();
+  for (uint32_t i = 0; i < queues_.size(); ++i) {
+    if (!queues_[i].events_.empty()) {
+      PERFETTO_DCHECK(queues_[i].max_ts_ <= append_max_ts_);
+      heap.push_back({queues_[i].min_ts_, i});
     }
-    if (all_queues_empty) {
-      break;
+  }
+  std::make_heap(heap.begin(), heap.end(), later);
+  while (!heap.empty()) {
+    uint32_t min_queue_idx = heap[0].queue;
+    // The earliest event of any other queue.
+    int64_t next_queue_ts = kTsMax;
+    for (size_t child = 1; child <= 2 && child < heap.size(); ++child) {
+      next_queue_ts = std::min(next_queue_ts, heap[child].min_ts);
     }
 
     auto& queue = queues_[min_queue_idx];
@@ -172,18 +160,19 @@
     }
     PERFETTO_DCHECK(queue.min_ts_ == events.front().ts);
 
-    // Now that we identified the min-queue, extract all events from it until
-    // we hit either: (1) the min-ts of the 2nd queue or (2) the packet index
-    // limit, whichever comes first.
+    // Extract events from the min-queue until hitting either: (1) the
+    // earliest event of another queue or (2) the alloc id limit, whichever
+    // comes first.
     size_t num_extracted = 0;
+    extracting_ = true;
     for (auto& event : events) {
       if (event.alloc_id() >= limit_alloc_id) {
         break;
       }
 
-      if (event.ts > min_queue_ts[1]) {
-        // We should never hit this condition on the first extraction as by
-        // the algorithm above (event.ts =) min_queue_ts[0] <= min_queue[1].
+      if (event.ts > next_queue_ts) {
+        // We should never hit this condition on the first extraction as the
+        // min-queue's first event is no later than any other queue's.
         PERFETTO_DCHECK(num_extracted > 0);
         break;
       }
@@ -207,6 +196,7 @@
 
       queue.sink->OnSortedEvent(this, event.ts, GetTokenBufferId(event));
     }  // for (event: events)
+    extracting_ = false;
 
     // The earliest event cannot be extracted without going past the limit.
     if (!num_extracted) {
@@ -229,7 +219,20 @@
     } else {
       queue.min_ts_ = queue.events_.front().ts;
     }
-  }  // for(;;)
+
+    // The queue's earliest event only moved later, so it moves down from the
+    // top; an empty queue is replaced there by the last.
+    if (events.empty()) {
+      QueueHeapEntry last = heap.back();
+      heap.pop_back();
+      if (!heap.empty()) {
+        core::HeapSiftDown(heap.data(), heap.size(), last, later);
+      }
+    } else {
+      core::HeapSiftDown(heap.data(), heap.size(),
+                         QueueHeapEntry{queue.min_ts_, min_queue_idx}, later);
+    }
+  }
 }
 
 TraceSorter::UntypedSink::~UntypedSink() = default;
diff --git a/src/trace_processor/sorter/trace_sorter.h b/src/trace_processor/sorter/trace_sorter.h
index 2045ee2..cedbf58 100644
--- a/src/trace_processor/sorter/trace_sorter.h
+++ b/src/trace_processor/sorter/trace_sorter.h
@@ -286,6 +286,19 @@
 
   std::vector<Queue> queues_;
 
+  // SortAndExtractEventsUntilAllocId()'s heap of queues, kept to reuse its
+  // memory. Each entry holds its queue's earliest timestamp, so the heap is
+  // ordered without reading the queues.
+  struct QueueHeapEntry {
+    int64_t min_ts;
+    uint32_t queue;
+  };
+  std::vector<QueueHeapEntry> queue_heap_;
+
+  // Whether events are being extracted: the heap of queues assumes none are
+  // pushed meanwhile.
+  bool extracting_ = false;
+
   // Whether we should ignore incremental extraction and just wait for
   // forced extractionn at the end of the trace.
   SortingMode sorting_mode_ = SortingMode::kDefault;
@@ -379,6 +392,7 @@
       sorter_->use_slow_sorting_ =
           sorter_->use_slow_sorting_ || data.phase == 'X';
     }
+    PERFETTO_DCHECK(!sorter_->extracting_);
     TraceTokenBuffer::Id id = sorter_->token_buffer_.Append(std::move(data));
     Queue& queue = sorter_->queues_[queue_idx_];
     queue.Append(ts, id, std::is_same_v<T, JsonEvent>,
diff --git a/src/trace_processor/sorter/trace_sorter_unittest.cc b/src/trace_processor/sorter/trace_sorter_unittest.cc
index 22c65c0..b622a96 100644
--- a/src/trace_processor/sorter/trace_sorter_unittest.cc
+++ b/src/trace_processor/sorter/trace_sorter_unittest.cc
@@ -272,6 +272,45 @@
       2);
 }
 
+// Sorts events which straddle the point where the queue's memory wraps around.
+TEST_F(TraceSorterTest, SortAcrossQueueWrap) {
+  CreateSorter(false);
+
+  auto sink = std::make_unique<MockSink<FtraceEventData>>();
+  auto* sink_ptr = sink.get();
+  auto stream = context_.sorter->CreateStream(std::move(sink));
+  std::vector<int64_t> parsed;
+  EXPECT_CALL(*sink_ptr, MockParse(_, _))
+      .WillRepeatedly(
+          [&parsed](int64_t ts, FtraceEventData) { parsed.push_back(ts); });
+
+  // Fill most of the queue's 1024 slots in order, then extract them all so the
+  // next events are pushed from near the end of its memory.
+  TraceBlobView tbv(TraceBlob::Allocate(1));
+  constexpr int64_t kFirst = 1000;
+  for (int64_t i = 0; i < kFirst; ++i) {
+    stream->Push(i, {tbv.slice_off(0, 1), 0});
+  }
+  for (int i = 0; i < 2; ++i) {
+    context_.sorter->NotifyFlushEvent();
+    context_.sorter->NotifyFlushEvent();
+    context_.sorter->NotifyReadBufferEvent();
+  }
+  ASSERT_EQ(parsed.size(), static_cast<size_t>(kFirst));
+
+  // Push in reverse, so all of them need sorting.
+  constexpr int64_t kSecond = 100;
+  for (int64_t i = kSecond - 1; i >= 0; --i) {
+    stream->Push(kFirst + i, {tbv.slice_off(0, 1), 0});
+  }
+  context_.sorter->ExtractEventsForced();
+
+  ASSERT_EQ(parsed.size(), static_cast<size_t>(kFirst + kSecond));
+  for (size_t i = 0; i < parsed.size(); ++i) {
+    EXPECT_EQ(parsed[i], static_cast<int64_t>(i));
+  }
+}
+
 // Simulates a random stream of ftrace events happening on random CPUs.
 // Tests that the output of the TraceSorter matches the timestamp order
 // (% events happening at the same time on different CPUs).
diff --git a/src/trace_processor/sqlite/sqlite_connection.cc b/src/trace_processor/sqlite/sqlite_connection.cc
index 44aab05..e6fbc44 100644
--- a/src/trace_processor/sqlite/sqlite_connection.cc
+++ b/src/trace_processor/sqlite/sqlite_connection.cc
@@ -113,6 +113,15 @@
 constexpr int kSqliteOpenFlags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE |
                                  SQLITE_OPEN_NOMUTEX | SQLITE_OPEN_URI;
 
+void ApplyAttachCreateWriteConfig(sqlite3* db, bool enabled) {
+  int unused = 0;
+  int val = enabled ? 1 : 0;
+  PERFETTO_CHECK(sqlite3_db_config(db, SQLITE_DBCONFIG_ENABLE_ATTACH_WRITE, val,
+                                   &unused) == SQLITE_OK);
+  PERFETTO_CHECK(sqlite3_db_config(db, SQLITE_DBCONFIG_ENABLE_ATTACH_CREATE,
+                                   val, &unused) == SQLITE_OK);
+}
+
 }  // namespace
 
 std::unique_ptr<SqliteConnection>
@@ -135,6 +144,9 @@
   // queries.
   PERFETTO_CHECK(sqlite3_db_config(db, SQLITE_DBCONFIG_LOOKASIDE, nullptr,
                                    /*sz=*/1200, /*cnt=*/1000) == SQLITE_OK);
+  // Untrusted SQL (e.g. the RPC server) must never be able to ATTACH-write
+  // OS files.
+  ApplyAttachCreateWriteConfig(db, /*enabled=*/false);
 #ifdef SQLITE_DBCONFIG_FP_DIGITS
   // SQLite 3.52 went from 15 to 17 significant digits when turning a double
   // into text. Keep the 15 older versions produce.
@@ -149,6 +161,10 @@
   return std::make_unique<SqliteConnection>(database_);
 }
 
+void SqliteConnection::SetAttachCreateWriteEnabled(bool enabled) {
+  ApplyAttachCreateWriteConfig(db_.get(), enabled);
+}
+
 SqliteConnection::~SqliteConnection() = default;
 
 SqliteConnection::PreparedStatement SqliteConnection::PrepareStatement(
diff --git a/src/trace_processor/sqlite/sqlite_connection.h b/src/trace_processor/sqlite/sqlite_connection.h
index 64b5953..e26f46f 100644
--- a/src/trace_processor/sqlite/sqlite_connection.h
+++ b/src/trace_processor/sqlite/sqlite_connection.h
@@ -103,6 +103,9 @@
   // underlying in-memory store is shared.
   std::unique_ptr<SqliteConnection> Fork();
 
+  // Disabled by default; see the constructor.
+  void SetAttachCreateWriteEnabled(bool enabled);
+
   // Prepares a SQLite statement for the given SQL.
   PreparedStatement PrepareStatement(SqlSource);
 
diff --git a/src/trace_processor/storage/stats.h b/src/trace_processor/storage/stats.h
index fe80c07..04f7697 100644
--- a/src/trace_processor/storage/stats.h
+++ b/src/trace_processor/storage/stats.h
@@ -921,6 +921,23 @@
       "A TrackEventRangeOfInterest packet was received without the required "  \
       "start_us field. The packet is ignored. This is a bug in the trace "     \
       "producer."),                                                            \
+  F(track_descriptor_invalid_dimension,         kSingle,  kError,  kAnalysis, Scope::kMachineAndTrace,  \
+      "A TrackDescriptor declared a dimension without a name or without a "    \
+      "value, which is ignored, or with an iid which is not in the interned "  \
+      "data of the sequence. A descriptor with an unknown name or value iid "  \
+      "is ignored entirely, so that a later re-emission with the interned "    \
+      "data can still be reserved; an unknown display_name_iid only drops "    \
+      "the display name."),                                                    \
+  F(track_descriptor_reserved_dimension_name,   kSingle,  kError,  kAnalysis, Scope::kMachineAndTrace,  \
+      "A TrackDescriptor declared a custom dimension using a name reserved "   \
+      "for well known dimensions (machine, gpu, cpu, process, thread). These " \
+      "are synthesized by trace processor and cannot be redefined: the "       \
+      "dimension is ignored. This is a bug in the trace producer."),           \
+  F(track_dimension_conflicting_value,          kSingle,  kError,  kAnalysis, Scope::kMachineAndTrace,  \
+      "A TrackDescriptor declared a dimension which it already inherits "      \
+      "from a parent_uuid ancestor, or declares twice, with a *different* "    \
+      "value. The inherited (or first declared) value is kept and the other "  \
+      "one is ignored. This is a bug in the trace producer."),                 \
   F(track_descriptor_invalid_child_ordering,    kSingle,  kError,  kAnalysis, Scope::kMachineAndTrace,  \
       "A TrackDescriptor specified an invalid or unrecognized value for "      \
       "child_tracks_ordering. The descriptor is ignored. This is a bug in "    \
diff --git a/src/trace_processor/storage/trace_storage.h b/src/trace_processor/storage/trace_storage.h
index 97266d2..e5ced9e 100644
--- a/src/trace_processor/storage/trace_storage.h
+++ b/src/trace_processor/storage/trace_storage.h
@@ -244,6 +244,13 @@
     return mutable_table<tables::TrackTable>();
   }
 
+  const tables::TrackDimensionTable& track_dimension_table() const {
+    return table<tables::TrackDimensionTable>();
+  }
+  tables::TrackDimensionTable* mutable_track_dimension_table() {
+    return mutable_table<tables::TrackDimensionTable>();
+  }
+
   const tables::GpuContextTable& gpu_context_table() const {
     return table<tables::GpuContextTable>();
   }
diff --git a/src/trace_processor/tables/track_tables.py b/src/trace_processor/tables/track_tables.py
index 2f77846..01ba1a7 100644
--- a/src/trace_processor/tables/track_tables.py
+++ b/src/trace_processor/tables/track_tables.py
@@ -16,6 +16,7 @@
 from python.generators.trace_processor_table.public import Column as C
 from python.generators.trace_processor_table.public import CppAccess
 from python.generators.trace_processor_table.public import CppAccessDuration
+from python.generators.trace_processor_table.public import CppInt64
 from python.generators.trace_processor_table.public import CppOptional
 from python.generators.trace_processor_table.public import CppSelfTableId
 from python.generators.trace_processor_table.public import CppString
@@ -89,7 +90,45 @@
         ),
     ])
 
+# The custom dimensions of every track, written when the track event track is
+# created: the ones declared on its own TrackDescriptor plus the ones inherited
+# from its `parent_uuid` ancestors. The well known dimensions (machine, process,
+# thread, cpu, gpu) are derived from the track table by the public
+# `track_dimension` view, which adds them on top of this table.
+TRACK_DIMENSION_TABLE = Table(
+    python_module=__file__,
+    class_name="TrackDimensionTable",
+    sql_name="__intrinsic_track_dimension",
+    columns=[
+        C(
+            "track_id",
+            CppTableId(TRACK_TABLE),
+            cpp_access=CppAccess.READ,
+        ),
+        C(
+            "name",
+            CppString(),
+            cpp_access=CppAccess.READ,
+        ),
+        C(
+            "int_value",
+            CppOptional(CppInt64()),
+            cpp_access=CppAccess.READ,
+        ),
+        C(
+            "string_value",
+            CppOptional(CppString()),
+            cpp_access=CppAccess.READ,
+        ),
+        C(
+            "display_name",
+            CppOptional(CppString()),
+            cpp_access=CppAccess.READ,
+        ),
+    ])
+
 # Keep this list sorted.
 ALL_TABLES = [
+    TRACK_DIMENSION_TABLE,
     TRACK_TABLE,
 ]
diff --git a/src/trace_processor/trace_database_integrationtest.cc b/src/trace_processor/trace_database_integrationtest.cc
index 2dea558..142c33f 100644
--- a/src/trace_processor/trace_database_integrationtest.cc
+++ b/src/trace_processor/trace_database_integrationtest.cc
@@ -1421,6 +1421,14 @@
       QuerySingleInt(Processor(), "SELECT count() FROM slice");
   int64_t slice_dur_sum =
       QuerySingleInt(Processor(), "SELECT sum(dur) FROM slice");
+  int64_t dimension_count =
+      QuerySingleInt(Processor(), "SELECT count() FROM track_dimension");
+  const std::string arg_lookup =
+      "SELECT extract_arg(a.arg_set_id, a.key) = a.int_value FROM args AS a "
+      "WHERE a.int_value IS NOT NULL "
+      "AND a.value_type IN ('int', 'uint', 'bool', 'pointer') "
+      "ORDER BY a.arg_set_id, a.key LIMIT 1";
+  ASSERT_EQ(QuerySingleInt(Processor(), arg_lookup), 1);
   std::string first_thread_name = QuerySingleString(
       Processor(),
       "SELECT name FROM thread WHERE name IS NOT NULL ORDER BY name LIMIT 1");
@@ -1431,7 +1439,17 @@
       ExportToString(Processor(), TraceProcessor::ExportFormat::kPerfetto);
 
   auto reimport = TraceProcessor::CreateInstance(Config());
+  ASSERT_EQ(QuerySingleInt(reimport.get(),
+                           "SELECT extract_arg(0, 'missing') IS NULL"),
+            1);
+  ASSERT_EQ(QuerySingleString(reimport.get(),
+                              "SELECT __intrinsic_arg_set_to_json(0)"),
+            "{}");
   ASSERT_OK(ParsePerfettoExport(reimport.get(), tar));
+  EXPECT_EQ(QuerySingleInt(reimport.get(), arg_lookup), 1);
+  EXPECT_EQ(
+      QuerySingleInt(reimport.get(), "SELECT count() FROM track_dimension"),
+      dimension_count);
 
   EXPECT_EQ(QuerySingleInt(reimport.get(), "SELECT count() FROM thread"),
             thread_count);
diff --git a/src/trace_processor/trace_processor_impl.cc b/src/trace_processor/trace_processor_impl.cc
index d0bba8f..0c1d24c 100644
--- a/src/trace_processor/trace_processor_impl.cc
+++ b/src/trace_processor/trace_processor_impl.cc
@@ -40,6 +40,7 @@
 #include "perfetto/ext/base/status_or.h"
 #include "perfetto/ext/base/string_splitter.h"
 #include "perfetto/ext/base/string_utils.h"
+#include "perfetto/ext/base/utils.h"
 #include "perfetto/protozero/scattered_heap_buffer.h"
 #include "perfetto/trace_processor/basic_types.h"
 #include "perfetto/trace_processor/io.h"
@@ -1243,6 +1244,12 @@
     if (!file_system) {
       return base::ErrStatus("SQLite export requires a file system");
     }
+    // ATTACH-write is disabled by default; re-enable it for this local-only
+    // export.
+    SqliteConnection* conn = engine_->sqlite_connection();
+    conn->SetAttachCreateWriteEnabled(true);
+    auto reset_attach =
+        base::OnScopeExit([conn] { conn->SetAttachCreateWriteEnabled(false); });
     return ExportSqliteDatabase(this, file_system, *path);
   }
   return trace_export::WriteExport(
diff --git a/src/trace_processor/util/BUILD.gn b/src/trace_processor/util/BUILD.gn
index 17b73c1..a4a0167 100644
--- a/src/trace_processor/util/BUILD.gn
+++ b/src/trace_processor/util/BUILD.gn
@@ -264,7 +264,10 @@
 
 source_set("galloping_search") {
   sources = [ "galloping_search.h" ]
-  deps = [ "../../../gn:default_deps" ]
+  deps = [
+    "../../../gn:default_deps",
+    "../../../include/perfetto/public",
+  ]
 }
 
 source_set("concurrency_stress_test_util") {
diff --git a/src/trace_processor/util/galloping_search.h b/src/trace_processor/util/galloping_search.h
index 9b9492f..e1c9b0c 100644
--- a/src/trace_processor/util/galloping_search.h
+++ b/src/trace_processor/util/galloping_search.h
@@ -17,10 +17,74 @@
 #ifndef SRC_TRACE_PROCESSOR_UTIL_GALLOPING_SEARCH_H_
 #define SRC_TRACE_PROCESSOR_UTIL_GALLOPING_SEARCH_H_
 
+#include <cstddef>
 #include <cstdint>
 
+#include "perfetto/public/compiler.h"
+
 namespace perfetto::trace_processor {
 
+// Ranges this short are scanned rather than halved: the elements share a cache
+// line or two, so comparing each is cheaper than branching on halves.
+inline constexpr size_t kGallopingLinearScan = 16;
+
+// std::partition_point over [begin, end), where `pred` holds for a prefix of
+// the range: binary search until few elements are left, then a scan.
+template <typename T, typename Pred>
+const T* PartitionPoint(const T* begin, const T* end, Pred pred) {
+  while (static_cast<size_t>(end - begin) > kGallopingLinearScan) {
+    const T* mid = begin + (end - begin) / 2;
+    if (pred(*mid)) {
+      begin = mid + 1;
+    } else {
+      end = mid;
+    }
+  }
+  while (begin != end && pred(*begin)) {
+    ++begin;
+  }
+  return begin;
+}
+
+namespace internal {
+
+// The rest of GallopingPartitionPoint, once `pred` is known to hold for the
+// first kGallopingLinearScan elements: probes at doubling distances, then
+// searches the last gap. Out of line, so callers inline only the scan.
+template <typename T, typename Pred>
+PERFETTO_NO_INLINE const T* Gallop(const T* begin, const T* end, Pred pred) {
+  auto size = static_cast<size_t>(end - begin);
+  size_t lo = kGallopingLinearScan;
+  size_t hi = size;
+  for (size_t step = kGallopingLinearScan; lo + step < size; step *= 2) {
+    if (!pred(begin[lo + step])) {
+      hi = lo + step;
+      break;
+    }
+    lo += step + 1;
+  }
+  return PartitionPoint(begin + lo, begin + hi, pred);
+}
+
+}  // namespace internal
+
+// As PartitionPoint, but in O(log d) for a point d elements from `begin`:
+// scans the first few elements, then probes at doubling distances and
+// searches only the last gap. For when the point is likely near `begin`.
+template <typename T, typename Pred>
+PERFETTO_ALWAYS_INLINE inline const T* GallopingPartitionPoint(const T* begin,
+                                                               const T* end,
+                                                               Pred pred) {
+  // A fixed trip count, not min(size, kGallopingLinearScan), so the scan
+  // unrolls with nothing to compute before it.
+  for (size_t i = 0; i < kGallopingLinearScan; ++i) {
+    if (begin + i == end || !pred(begin[i])) {
+      return begin + i;
+    }
+  }
+  return internal::Gallop(begin, end, pred);
+}
+
 // Galloping (exponential) search optimized for sorted queries.
 //
 // When searching for multiple keys that are themselves sorted, galloping search
diff --git a/src/trace_processor/util/galloping_search_unittest.cc b/src/trace_processor/util/galloping_search_unittest.cc
index 96c27c8..ebd4c3f 100644
--- a/src/trace_processor/util/galloping_search_unittest.cc
+++ b/src/trace_processor/util/galloping_search_unittest.cc
@@ -162,5 +162,26 @@
   EXPECT_EQ(results, expected);
 }
 
+// Every point of every size up to past a few doublings of the probe step, so
+// the scan, each probe and the final search all see the point at each offset.
+TEST(GallopingSearchTest, PartitionPointsMatchStd) {
+  for (uint32_t size = 0; size < 300; ++size) {
+    for (uint32_t point = 0; point <= size; ++point) {
+      std::vector<uint32_t> data(size);
+      for (uint32_t i = 0; i < size; ++i) {
+        data[i] = i < point ? 0 : 1;
+      }
+      auto pred = [](uint32_t v) { return v == 0; };
+      const uint32_t* b = data.data();
+      const uint32_t* e = b + size;
+      EXPECT_EQ(static_cast<uint32_t>(PartitionPoint(b, e, pred) - b), point)
+          << size;
+      EXPECT_EQ(static_cast<uint32_t>(GallopingPartitionPoint(b, e, pred) - b),
+                point)
+          << size;
+    }
+  }
+}
+
 }  // namespace
 }  // namespace perfetto::trace_processor
diff --git a/src/trace_processor/util/proto_to_args_parser.cc b/src/trace_processor/util/proto_to_args_parser.cc
index 7e84a1c..03a3ac1 100644
--- a/src/trace_processor/util/proto_to_args_parser.cc
+++ b/src/trace_processor/util/proto_to_args_parser.cc
@@ -277,6 +277,11 @@
   if (!idx) {
     return base::Status("Failed to find proto descriptor for " + type);
   }
+  auto reset_call_params = base::OnScopeExit([this] {
+    allowed_fields_ = nullptr;
+    unknown_extensions_ = nullptr;
+    add_defaults_ = false;
+  });
   allowed_fields_ = allowed_fields;
   unknown_extensions_ = unknown_extensions;
   add_defaults_ = add_defaults;
@@ -307,9 +312,12 @@
     RepeatedFieldIndex* repeated_field_index) {
   PERFETTO_DCHECK(work_stack_.empty());
   PERFETTO_DCHECK(descriptor_idx < pool_.descriptors().size());
-  allowed_fields_ = nullptr;
+  auto reset_call_params = base::OnScopeExit([this] {
+    allowed_fields_ = nullptr;
+    unknown_extensions_ = nullptr;
+    add_defaults_ = false;
+  });
   unknown_extensions_ = unknown_extensions;
-  add_defaults_ = false;
   uint64_t root_key = PathEdgeKey(kNoPath, descriptor_idx);
   uint32_t* slot = path_index_.Find(root_key);
   uint32_t root_path = slot ? *slot
diff --git a/src/trace_processor/util/proto_to_args_parser.h b/src/trace_processor/util/proto_to_args_parser.h
index 759b725..7df2778 100644
--- a/src/trace_processor/util/proto_to_args_parser.h
+++ b/src/trace_processor/util/proto_to_args_parser.h
@@ -468,8 +468,10 @@
   // keyed by pool descriptor index under the kNoPath parent.
   base::FlatHashMap<uint64_t, uint32_t> path_index_;
   Key key_prefix_;
-  // Parameters to ParseMessage that apply uniformly to every ProtoMessage
-  // WorkItem on the stack. Set by ParseMessage; read by StepProtoMessage.
+  // Parameters to ParseMessage/ParseMessageField that apply uniformly to
+  // every ProtoMessage WorkItem on the stack, read by StepProtoMessage /
+  // HandleField. Both setters reset these to their defaults on every exit
+  // path, so no other entry point ever sees a stale value.
   const std::vector<uint32_t>* allowed_fields_ = nullptr;
   int* unknown_extensions_ = nullptr;
   bool add_defaults_ = false;
diff --git a/src/trace_processor/util/proto_to_args_parser_unittest.cc b/src/trace_processor/util/proto_to_args_parser_unittest.cc
index b07a026..353a562 100644
--- a/src/trace_processor/util/proto_to_args_parser_unittest.cc
+++ b/src/trace_processor/util/proto_to_args_parser_unittest.cc
@@ -1197,6 +1197,48 @@
                           "root.field_string root.field_string value"));
 }
 
+// ParseDebugAnnotation takes no unknown_extensions parameter of its own, so
+// it must not act on one left behind by an earlier, unrelated
+// ParseMessageField call on the same parser instance (as
+// TrackEventEventImporter::ParseTrackEventArgs makes on every event). A
+// proto_value naming a message with undeclared fields must not touch that
+// stale pointer.
+TEST_F(DebugAnnotationParserTest, DoesNotReuseStaleUnknownExtensionsPointer) {
+  DescriptorPool pool;
+  ASSERT_TRUE(pool.AddFromFileDescriptorSet(kTestMessagesDescriptor.data(),
+                                            kTestMessagesDescriptor.size())
+                  .ok());
+  ProtoToArgsParser args_parser(pool, string_pool_);
+
+  uint32_t every_field =
+      *pool.FindDescriptorIdx(".protozero.test.protos.EveryField");
+  int unknown = 0;
+  protozero::Field unknown_field;
+  unknown_field.initialize(
+      9999,
+      static_cast<uint8_t>(protozero::proto_utils::ProtoWireType::kVarInt), 1,
+      0);
+  ASSERT_TRUE(
+      args_parser.ParseMessageField(every_field, unknown_field, *this, &unknown)
+          .ok());
+  ASSERT_EQ(unknown, 1);
+
+  protozero::HeapBuffered<protozero::Message> inner{kChunkSize, kChunkSize};
+  inner->AppendVarInt(9001, 1);
+  inner->AppendVarInt(9002, 2);
+  inner->AppendVarInt(9003, 3);
+  auto inner_bytes = inner.SerializeAsArray();
+
+  protozero::HeapBuffered<protos::pbzero::DebugAnnotation> msg;
+  msg->set_name("root");
+  msg->set_proto_type_name(".protozero.test.protos.EveryField");
+  msg->set_proto_value(inner_bytes.data(), inner_bytes.size());
+
+  base::Status status = ParseDebugAnnotation(args_parser, msg, *this);
+  EXPECT_TRUE(status.ok()) << status.message();
+  EXPECT_EQ(unknown, 1);
+}
+
 // Verifies that a DebugAnnotation whose proto_value is itself a
 // DebugAnnotation (an arbitrarily deep cycle) is parsed iteratively without
 // consuming C++ stack per level.
diff --git a/src/traced/probes/BUILD.gn b/src/traced/probes/BUILD.gn
index 341e532..e0ab459 100644
--- a/src/traced/probes/BUILD.gn
+++ b/src/traced/probes/BUILD.gn
@@ -67,6 +67,7 @@
     "../../base",
     "../../tracing/core",
     "../../tracing/ipc/producer",
+    "../../tracing/v2",
     "android_aflags",
     "android_cpu_per_uid",
     "android_game_intervention_list",
diff --git a/src/traced/probes/probes_producer.cc b/src/traced/probes/probes_producer.cc
index f9abb45..adecd5f 100644
--- a/src/traced/probes/probes_producer.cc
+++ b/src/traced/probes/probes_producer.cc
@@ -59,6 +59,7 @@
 #include "src/traced/probes/sys_stats/sys_stats_data_source.h"
 #include "src/traced/probes/system_info/system_info_data_source.h"
 #include "src/traced/probes/user_list/user_list_data_source.h"
+#include "src/tracing/v2/producer_ring_buffer_arbiter.h"
 
 #include "src/traced/probes/journald/journald_data_source.h"
 
@@ -128,6 +129,20 @@
   ConnectWithRetries(socket_name, task_runner);
 }
 
+std::unique_ptr<TraceWriter> ProbesProducer::CreateTraceWriter(
+    const DataSourceConfig& config) {
+  const auto buffer_id = static_cast<BufferID>(config.target_buffer());
+  if (!tracing_v2::ProducerRingBufferArbiter::ShouldUseTracingV2(config)) {
+    return endpoint_->CreateTraceWriter(buffer_id,
+                                        BufferExhaustedPolicy::kStall);
+  }
+  // The first instance that selects v2 sizes the ring buffer from its config.
+  // Later calls do nothing.
+  endpoint_->InitializeV2RingBuffer(config);
+  return endpoint_->CreateTraceWriterV2(buffer_id,
+                                        BufferExhaustedPolicy::kStall);
+}
+
 template <>
 std::unique_ptr<ProbesDataSource>
 ProbesProducer::CreateDSInstance<FtraceDataSource>(
@@ -153,10 +168,9 @@
   }
 
   PERFETTO_LOG("Ftrace setup (target_buf=%" PRIu32 ")", config.target_buffer());
-  const BufferID buffer_id = static_cast<BufferID>(config.target_buffer());
   std::unique_ptr<FtraceDataSource> data_source(new FtraceDataSource(
       ftrace_controller_->GetWeakPtr(), session_id, std::move(ftrace_config),
-      endpoint_->CreateTraceWriter(buffer_id, BufferExhaustedPolicy::kStall)));
+      CreateTraceWriter(config)));
   if (!ftrace_controller_->AddDataSource(data_source.get())) {
     PERFETTO_ELOG("Failed to setup ftrace");
     return nullptr;
@@ -171,12 +185,11 @@
     const DataSourceConfig& source_config) {
   PERFETTO_LOG("Inode file map setup (target_buf=%" PRIu32 ")",
                source_config.target_buffer());
-  auto buffer_id = static_cast<BufferID>(source_config.target_buffer());
   if (system_inodes_.empty())
     CreateStaticDeviceToInodeMap("/system", &system_inodes_);
   return std::make_unique<InodeFileDataSource>(
       source_config, task_runner_, session_id, &system_inodes_, &cache_,
-      endpoint_->CreateTraceWriter(buffer_id, BufferExhaustedPolicy::kStall));
+      CreateTraceWriter(source_config));
 }
 
 template <>
@@ -184,11 +197,8 @@
 ProbesProducer::CreateDSInstance<ProcessStatsDataSource>(
     TracingSessionID session_id,
     const DataSourceConfig& config) {
-  auto buffer_id = static_cast<BufferID>(config.target_buffer());
   return std::make_unique<ProcessStatsDataSource>(
-      task_runner_, session_id,
-      endpoint_->CreateTraceWriter(buffer_id, BufferExhaustedPolicy::kStall),
-      config);
+      task_runner_, session_id, CreateTraceWriter(config), config);
 }
 
 template <>
@@ -196,11 +206,8 @@
 ProbesProducer::CreateDSInstance<StatsdBinderDataSource>(
     TracingSessionID session_id,
     const DataSourceConfig& config) {
-  auto buffer_id = static_cast<BufferID>(config.target_buffer());
   return std::make_unique<StatsdBinderDataSource>(
-      task_runner_, session_id,
-      endpoint_->CreateTraceWriter(buffer_id, BufferExhaustedPolicy::kStall),
-      config);
+      task_runner_, session_id, CreateTraceWriter(config), config);
 }
 
 template <>
@@ -208,10 +215,8 @@
 ProbesProducer::CreateDSInstance<AndroidAflagsDataSource>(
     TracingSessionID session_id,
     const DataSourceConfig& config) {
-  auto buffer_id = static_cast<BufferID>(config.target_buffer());
   return std::make_unique<AndroidAflagsDataSource>(
-      config, task_runner_, session_id,
-      endpoint_->CreateTraceWriter(buffer_id, BufferExhaustedPolicy::kStall));
+      config, task_runner_, session_id, CreateTraceWriter(config));
 }
 
 template <>
@@ -219,10 +224,8 @@
 ProbesProducer::CreateDSInstance<AndroidPowerDataSource>(
     TracingSessionID session_id,
     const DataSourceConfig& config) {
-  auto buffer_id = static_cast<BufferID>(config.target_buffer());
   return std::make_unique<AndroidPowerDataSource>(
-      config, task_runner_, session_id,
-      endpoint_->CreateTraceWriter(buffer_id, BufferExhaustedPolicy::kStall));
+      config, task_runner_, session_id, CreateTraceWriter(config));
 }
 
 template <>
@@ -230,10 +233,8 @@
 ProbesProducer::CreateDSInstance<LinuxPowerSysfsDataSource>(
     TracingSessionID session_id,
     const DataSourceConfig& config) {
-  auto buffer_id = static_cast<BufferID>(config.target_buffer());
   return std::make_unique<LinuxPowerSysfsDataSource>(
-      config, task_runner_, session_id,
-      endpoint_->CreateTraceWriter(buffer_id, BufferExhaustedPolicy::kStall));
+      config, task_runner_, session_id, CreateTraceWriter(config));
 }
 
 template <>
@@ -241,10 +242,8 @@
 ProbesProducer::CreateDSInstance<AndroidCpuPerUidDataSource>(
     TracingSessionID session_id,
     const DataSourceConfig& config) {
-  auto buffer_id = static_cast<BufferID>(config.target_buffer());
   return std::make_unique<AndroidCpuPerUidDataSource>(
-      config, task_runner_, session_id,
-      endpoint_->CreateTraceWriter(buffer_id, BufferExhaustedPolicy::kStall));
+      config, task_runner_, session_id, CreateTraceWriter(config));
 }
 
 template <>
@@ -252,10 +251,8 @@
 ProbesProducer::CreateDSInstance<AndroidKernelWakelocksDataSource>(
     TracingSessionID session_id,
     const DataSourceConfig& config) {
-  auto buffer_id = static_cast<BufferID>(config.target_buffer());
   return std::make_unique<AndroidKernelWakelocksDataSource>(
-      config, task_runner_, session_id,
-      endpoint_->CreateTraceWriter(buffer_id, BufferExhaustedPolicy::kStall));
+      config, task_runner_, session_id, CreateTraceWriter(config));
 }
 
 template <>
@@ -263,10 +260,8 @@
 ProbesProducer::CreateDSInstance<AndroidLogDataSource>(
     TracingSessionID session_id,
     const DataSourceConfig& config) {
-  auto buffer_id = static_cast<BufferID>(config.target_buffer());
   return std::make_unique<AndroidLogDataSource>(
-      config, task_runner_, session_id,
-      endpoint_->CreateTraceWriter(buffer_id, BufferExhaustedPolicy::kStall));
+      config, task_runner_, session_id, CreateTraceWriter(config));
 }
 
 template <>
@@ -274,10 +269,8 @@
 ProbesProducer::CreateDSInstance<PackagesListDataSource>(
     TracingSessionID session_id,
     const DataSourceConfig& config) {
-  auto buffer_id = static_cast<BufferID>(config.target_buffer());
   return std::make_unique<PackagesListDataSource>(
-      config, task_runner_, session_id,
-      endpoint_->CreateTraceWriter(buffer_id, BufferExhaustedPolicy::kStall));
+      config, task_runner_, session_id, CreateTraceWriter(config));
 }
 
 template <>
@@ -285,10 +278,8 @@
 ProbesProducer::CreateDSInstance<AndroidGameInterventionListDataSource>(
     TracingSessionID session_id,
     const DataSourceConfig& config) {
-  auto buffer_id = static_cast<BufferID>(config.target_buffer());
   return std::make_unique<AndroidGameInterventionListDataSource>(
-      config, session_id,
-      endpoint_->CreateTraceWriter(buffer_id, BufferExhaustedPolicy::kStall));
+      config, session_id, CreateTraceWriter(config));
 }
 
 template <>
@@ -296,11 +287,9 @@
 ProbesProducer::CreateDSInstance<SysStatsDataSource>(
     TracingSessionID session_id,
     const DataSourceConfig& config) {
-  auto buffer_id = static_cast<BufferID>(config.target_buffer());
-  return std::make_unique<SysStatsDataSource>(
-      task_runner_, session_id,
-      endpoint_->CreateTraceWriter(buffer_id, BufferExhaustedPolicy::kStall),
-      config, std::make_unique<CpuFreqInfo>());
+  return std::make_unique<SysStatsDataSource>(task_runner_, session_id,
+                                              CreateTraceWriter(config), config,
+                                              std::make_unique<CpuFreqInfo>());
 }
 
 template <>
@@ -308,10 +297,8 @@
 ProbesProducer::CreateDSInstance<MetatraceDataSource>(
     TracingSessionID session_id,
     const DataSourceConfig& config) {
-  auto buffer_id = static_cast<BufferID>(config.target_buffer());
-  return std::make_unique<MetatraceDataSource>(
-      task_runner_, session_id,
-      endpoint_->CreateTraceWriter(buffer_id, BufferExhaustedPolicy::kStall));
+  return std::make_unique<MetatraceDataSource>(task_runner_, session_id,
+                                               CreateTraceWriter(config));
 }
 
 template <>
@@ -319,11 +306,9 @@
 ProbesProducer::CreateDSInstance<SystemInfoDataSource>(
     TracingSessionID session_id,
     const DataSourceConfig& config) {
-  auto buffer_id = static_cast<BufferID>(config.target_buffer());
   return std::make_unique<SystemInfoDataSource>(
-      session_id,
-      endpoint_->CreateTraceWriter(buffer_id, BufferExhaustedPolicy::kStall),
-      std::make_unique<CpuFreqInfo>(), config);
+      session_id, CreateTraceWriter(config), std::make_unique<CpuFreqInfo>(),
+      config);
 }
 
 template <>
@@ -331,11 +316,8 @@
 ProbesProducer::CreateDSInstance<UserListDataSource>(
     TracingSessionID session_id,
     const DataSourceConfig& config) {
-  auto buffer_id = static_cast<BufferID>(config.target_buffer());
-  return std::unique_ptr<ProbesDataSource>(new UserListDataSource(
-      config, session_id,
-      endpoint_->CreateTraceWriter(buffer_id,
-                                   perfetto::BufferExhaustedPolicy::kStall)));
+  return std::unique_ptr<ProbesDataSource>(
+      new UserListDataSource(config, session_id, CreateTraceWriter(config)));
 }
 
 template <>
@@ -343,10 +325,8 @@
 ProbesProducer::CreateDSInstance<InitialDisplayStateDataSource>(
     TracingSessionID session_id,
     const DataSourceConfig& config) {
-  auto buffer_id = static_cast<BufferID>(config.target_buffer());
   return std::make_unique<InitialDisplayStateDataSource>(
-      task_runner_, config, session_id,
-      endpoint_->CreateTraceWriter(buffer_id, BufferExhaustedPolicy::kStall));
+      task_runner_, config, session_id, CreateTraceWriter(config));
 }
 
 template <>
@@ -354,10 +334,8 @@
 ProbesProducer::CreateDSInstance<AndroidSystemPropertyDataSource>(
     TracingSessionID session_id,
     const DataSourceConfig& config) {
-  auto buffer_id = static_cast<BufferID>(config.target_buffer());
   return std::make_unique<AndroidSystemPropertyDataSource>(
-      task_runner_, config, session_id,
-      endpoint_->CreateTraceWriter(buffer_id, BufferExhaustedPolicy::kStall));
+      task_runner_, config, session_id, CreateTraceWriter(config));
 }
 
 template <>
@@ -365,10 +343,8 @@
 ProbesProducer::CreateDSInstance<FrozenFtraceDataSource>(
     TracingSessionID session_id,
     const DataSourceConfig& config) {
-  auto buffer_id = static_cast<BufferID>(config.target_buffer());
   return std::make_unique<FrozenFtraceDataSource>(
-      task_runner_, config, session_id,
-      endpoint_->CreateTraceWriter(buffer_id, BufferExhaustedPolicy::kStall));
+      task_runner_, config, session_id, CreateTraceWriter(config));
 }
 
 template <>
@@ -376,10 +352,8 @@
 ProbesProducer::CreateDSInstance<JournaldDataSource>(
     TracingSessionID session_id,
     const DataSourceConfig& config) {
-  auto buffer_id = static_cast<BufferID>(config.target_buffer());
-  return std::make_unique<JournaldDataSource>(
-      config, task_runner_, session_id,
-      endpoint_->CreateTraceWriter(buffer_id, BufferExhaustedPolicy::kStall));
+  return std::make_unique<JournaldDataSource>(config, task_runner_, session_id,
+                                              CreateTraceWriter(config));
 }
 
 // Another anonymous namespace. This cannot be moved into the anonymous
diff --git a/src/traced/probes/probes_producer.h b/src/traced/probes/probes_producer.h
index d6f49a6..4a04630 100644
--- a/src/traced/probes/probes_producer.h
+++ b/src/traced/probes/probes_producer.h
@@ -103,6 +103,11 @@
   void Restart();
   void ResetConnectionBackoff();
   void IncreaseConnectionBackoff();
+
+  // Creates the writer of a data source instance, and picks v1 or v2 for it.
+  // Each instance has exactly one writer, so call this once per instance.
+  std::unique_ptr<TraceWriter> CreateTraceWriter(const DataSourceConfig&);
+
   void OnDataSourceFlushComplete(FlushRequestID, DataSourceInstanceID);
   void OnFlushTimeout(FlushRequestID);
 
diff --git a/src/tracing/BUILD.gn b/src/tracing/BUILD.gn
index 577415e..e7a9caa 100644
--- a/src/tracing/BUILD.gn
+++ b/src/tracing/BUILD.gn
@@ -79,6 +79,7 @@
     "../../protos/perfetto/config/track_event:cpp",
     "../base",
     "core",
+    "v2",
   ]
   public_deps = [ "../../include/perfetto/tracing" ]
   sources = [
diff --git a/src/tracing/internal/tracing_muxer_impl.cc b/src/tracing/internal/tracing_muxer_impl.cc
index f974637..b7d1474 100644
--- a/src/tracing/internal/tracing_muxer_impl.cc
+++ b/src/tracing/internal/tracing_muxer_impl.cc
@@ -48,6 +48,7 @@
 #include "perfetto/tracing/tracing_backend.h"
 #include "src/tracing/core/null_trace_writer.h"
 #include "src/tracing/internal/tracing_muxer_fake.h"
+#include "src/tracing/v2/producer_ring_buffer_arbiter.h"
 
 #include "protos/perfetto/config/interceptor_config.gen.h"
 
@@ -1416,13 +1417,8 @@
     // An intercepted instance takes its writer from the interceptor.
     internal_state->use_tracing_v2 =
         !startup_session_id && !internal_state->interceptor_id &&
-        rds.params.supports_tracing_v2 && cfg.supports_tracing_v2();
-    const uint32_t probability =
-        cfg.experimental_tracing_v2().use_v2_probability_percent();
-    if (internal_state->use_tracing_v2 && probability < 100) {
-      internal_state->use_tracing_v2 =
-          static_cast<uint64_t>(base::Uuidv4().lsb()) % 100 < probability;
-    }
+        rds.params.supports_tracing_v2 &&
+        tracing_v2::ProducerRingBufferArbiter::ShouldUseTracingV2(cfg);
     // Complete initialization before writer threads can observe this instance.
     if (internal_state->use_tracing_v2)
       backend.producer->service_->InitializeV2RingBuffer(cfg);
diff --git a/src/tracing/service/BUILD.gn b/src/tracing/service/BUILD.gn
index 451f385..95e9733 100644
--- a/src/tracing/service/BUILD.gn
+++ b/src/tracing/service/BUILD.gn
@@ -32,6 +32,7 @@
     "../../../protos/perfetto/config/protovm:cpp",
     "../../../protos/perfetto/protovm:cpp",
     "../../../protos/perfetto/trace:zero",
+    "../../../protos/perfetto/trace/perfetto:cpp",
     "../../../protos/perfetto/trace/perfetto:zero",  # For MetatraceWriter.
     "../../android_stats",
     "../../base",
diff --git a/src/tracing/service/packet_stream_validator.cc b/src/tracing/service/packet_stream_validator.cc
index 7572b05..6cb7d50 100644
--- a/src/tracing/service/packet_stream_validator.cc
+++ b/src/tracing/service/packet_stream_validator.cc
@@ -37,6 +37,7 @@
     protos::pbzero::TracePacket::kTrustedPacketSequenceIdFieldNumber,
     protos::pbzero::TracePacket::kTraceConfigFieldNumber,
     protos::pbzero::TracePacket::kTraceStatsFieldNumber,
+    protos::pbzero::TracePacket::kExperimentalTracingV2ProducerStatsFieldNumber,
     protos::pbzero::TracePacket::kCompressedPacketsFieldNumber,
     protos::pbzero::TracePacket::kZstdCompressedPacketsFieldNumber,
     protos::pbzero::TracePacket::kSynchronizationMarkerFieldNumber,
diff --git a/src/tracing/service/packet_stream_validator_unittest.cc b/src/tracing/service/packet_stream_validator_unittest.cc
index f0b1cdb..29b08e9 100644
--- a/src/tracing/service/packet_stream_validator_unittest.cc
+++ b/src/tracing/service/packet_stream_validator_unittest.cc
@@ -23,6 +23,7 @@
 #include "protos/perfetto/trace/ftrace/sched.gen.h"
 #include "protos/perfetto/trace/perfetto/trace_provenance.gen.h"
 #include "protos/perfetto/trace/perfetto/tracing_service_event.gen.h"
+#include "protos/perfetto/trace/perfetto/tracing_v2_producer_stats.gen.h"
 #include "protos/perfetto/trace/test_event.gen.h"
 #include "protos/perfetto/trace/trace_packet.gen.h"
 #include "test/gtest_and_gmock.h"
@@ -213,6 +214,19 @@
   EXPECT_FALSE(PacketStreamValidator::Validate(seq));
 }
 
+TEST(PacketStreamValidatorTest, SimplePacketWithTracingV2ProducerStats) {
+  protos::gen::TracePacket proto;
+  proto.mutable_experimental_tracing_v2_producer_stats()->set_producer_id(1);
+  std::string ser_buf = proto.SerializeAsString();
+
+  for (size_t i = 0; i < ser_buf.size(); ++i) {
+    Slices seq;
+    seq.emplace_back(&ser_buf[0], i);
+    seq.emplace_back(&ser_buf[i], ser_buf.size() - i);
+    EXPECT_FALSE(PacketStreamValidator::Validate(seq));
+  }
+}
+
 TEST(PacketStreamValidatorTest, SimplePacketWithTraceProvenance) {
   protos::gen::TracePacket proto;
   proto.mutable_trace_provenance()->add_buffers();
diff --git a/src/tracing/service/service_ring_buffer_drainer.cc b/src/tracing/service/service_ring_buffer_drainer.cc
index ee43474..0158124 100644
--- a/src/tracing/service/service_ring_buffer_drainer.cc
+++ b/src/tracing/service/service_ring_buffer_drainer.cc
@@ -16,12 +16,16 @@
 
 #include "src/tracing/service/service_ring_buffer_drainer.h"
 
+#include <algorithm>
 #include <utility>
 
 #include "perfetto/base/compiler.h"
 #include "perfetto/base/logging.h"
+#include "perfetto/base/time.h"
 #include "src/tracing/service/trace_buffer.h"
 
+#include "protos/perfetto/trace/perfetto/tracing_v2_producer_stats.gen.h"
+
 namespace perfetto::tracing_v2 {
 
 namespace {
@@ -64,7 +68,13 @@
   // Bound each pass to num_chunks() logical positions, including positions
   // reserved during the pass.
   const SharedRingBufferReader::Stats stats_before = reader_.GetStats();
+  const base::TimeNanos time_before = base::GetWallTimeNs();
   const auto result = reader_.Drain(ring_buffer_.num_chunks());
+  const auto pass_time_ns =
+      static_cast<uint64_t>((base::GetWallTimeNs() - time_before).count());
+  ++drain_passes_;
+  drain_time_ns_ += pass_time_ns;
+  drain_max_time_ns_ = std::max(drain_max_time_ns_, pass_time_ns);
   const SharedRingBufferReader::Stats stats_after = reader_.GetStats();
 
   // The reader discards malformed chunks and chunks in an unknown format. It
@@ -96,9 +106,43 @@
   }
 }
 
+void ServiceRingBufferDrainer::FillStats(
+    protos::gen::ExperimentalTracingV2ProducerStats* stats) const {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+
+  stats->set_chunk_size_bytes(ring_buffer_.chunk_size());
+  stats->set_num_chunks(ring_buffer_.num_chunks());
+
+  // Counted by the reader.
+  const SharedRingBufferReader::Stats reader = reader_.GetStats();
+  stats->set_chunks_read(reader.chunks_read);
+  stats->set_bytes_read(reader.bytes_read);
+  stats->set_data_loss_chunks(reader.data_loss_chunks);
+  stats->set_malformed_chunks(reader.malformed_chunks);
+  stats->set_unsupported_format_chunks(reader.unsupported_format_chunks);
+  stats->set_rewrite_requests(reader.rewrite_requests);
+  stats->set_positions_skipped(reader.positions_skipped);
+
+  // Counted by this class.
+  stats->set_invalid_writer_chunks(invalid_writer_chunks_);
+  stats->set_invalid_destination_chunks(invalid_destination_chunks_);
+  stats->set_trace_buffer_rejected_chunks(trace_buffer_rejected_chunks_);
+  stats->set_drain_passes(drain_passes_);
+  stats->set_drain_time_ns(drain_time_ns_);
+  stats->set_drain_max_time_ns(drain_max_time_ns_);
+
+  // The producer controls these values, so they are reported as they are.
+  const SharedRingBuffer::RingBufferFullStats full =
+      ring_buffer_.LoadRingBufferFullStatsRelaxed();
+  stats->set_writer_dropped_packets(full.dropped_packets);
+  stats->set_writer_stalls(full.stalls);
+  stats->set_writer_stall_time_ms(full.stall_time_ms);
+}
+
 void ServiceRingBufferDrainer::OnChunkRead(
     const SharedRingBufferReader::ChunkContents& chunk) {
   if (PERFETTO_UNLIKELY(!chunk.writer_id || chunk.writer_id > kMaxWriterID)) {
+    ++invalid_writer_chunks_;
     delegate_->OnRingBufferChunksDiscarded(1);
     return;
   }
@@ -106,6 +150,7 @@
   TraceBuffer* buffer =
       delegate_->GetV2RingBufferDestination(chunk.target_buffer);
   if (PERFETTO_UNLIKELY(!buffer)) {
+    ++invalid_destination_chunks_;
     delegate_->OnRingBufferChunksDiscarded(1);
     RecordWriterLoss(chunk.writer_id);
     return;
@@ -123,10 +168,12 @@
   // the reader's scratch, then into a TBv2 chunk. The reader could pass the
   // decoded sizes and one payload range, so that TBv2 copies once. Measure
   // the drain cost in a profile first.
-  buffer->CopyChunkV2Untrusted(
+  const bool stored = buffer->CopyChunkV2Untrusted(
       sequence, chunk.fragments, chunk.num_fragments,
       chunk.payload_flags & kFlagContinuesFromPrevChunk,
       chunk.payload_flags & kFlagContinuesOnNextChunk);
+  if (PERFETTO_UNLIKELY(!stored))
+    ++trace_buffer_rejected_chunks_;
 }
 
 void ServiceRingBufferDrainer::OnDataLoss(WriterID writer_id) {
diff --git a/src/tracing/service/service_ring_buffer_drainer.h b/src/tracing/service/service_ring_buffer_drainer.h
index 967572d..f9e2eba 100644
--- a/src/tracing/service/service_ring_buffer_drainer.h
+++ b/src/tracing/service/service_ring_buffer_drainer.h
@@ -33,6 +33,9 @@
 
 namespace perfetto {
 class TraceBuffer;
+namespace protos::gen {
+class ExperimentalTracingV2ProducerStats;
+}
 namespace tracing_v2 {
 
 namespace test {
@@ -111,6 +114,12 @@
   // Mapping size for the service's memory guardrail.
   size_t size_bytes() const { return memory_->size(); }
 
+  // Sets the ring buffer fields of |stats|.
+  // These are the layout and the counters of the reader, of this class and of
+  // the producer's writers.
+  // The caller sets the producer's identity.
+  void FillStats(protos::gen::ExperimentalTracingV2ProducerStats* stats) const;
+
  private:
   friend class test::ServiceRingBufferDrainerTestPeer;
 
@@ -138,6 +147,18 @@
 
   bool retry_scheduled_ = false;
 
+  // Chunks that the reader delivered but no trace buffer stored.
+  // See ExperimentalTracingV2ProducerStats for each case.
+  uint64_t invalid_writer_chunks_ = 0;
+  uint64_t invalid_destination_chunks_ = 0;
+  uint64_t trace_buffer_rejected_chunks_ = 0;
+
+  // Calls to Drain() that ran the reader, and their total and longest time on
+  // the monotonic clock.
+  uint64_t drain_passes_ = 0;
+  uint64_t drain_time_ns_ = 0;
+  uint64_t drain_max_time_ns_ = 0;
+
   PERFETTO_THREAD_CHECKER(thread_checker_)
 
   // Declared last to cancel retry tasks before reader or mapping destruction.
diff --git a/src/tracing/service/service_ring_buffer_drainer_unittest.cc b/src/tracing/service/service_ring_buffer_drainer_unittest.cc
index ff376f2..2913091 100644
--- a/src/tracing/service/service_ring_buffer_drainer_unittest.cc
+++ b/src/tracing/service/service_ring_buffer_drainer_unittest.cc
@@ -29,12 +29,14 @@
 #include "src/base/test/test_task_runner.h"
 #include "src/tracing/core/in_process_shared_memory.h"
 #include "src/tracing/service/trace_buffer_v2.h"
+#include "src/tracing/test/fake_packet.h"
 #include "src/tracing/v2/shared_ring_buffer.h"
 #include "src/tracing/v2/shared_ring_buffer_abi.h"
 #include "src/tracing/v2/shared_ring_buffer_reader.h"
 #include "src/tracing/v2/shared_ring_buffer_test_utils.h"
 #include "test/gtest_and_gmock.h"
 
+#include "protos/perfetto/trace/perfetto/tracing_v2_producer_stats.gen.h"
 #include "protos/perfetto/trace/test_event.gen.h"
 #include "protos/perfetto/trace/trace_packet.gen.h"
 
@@ -137,6 +139,12 @@
 
   uint32_t ReadPos() { return Internals::GetReadPos(ring_buffer_.get()); }
 
+  protos::gen::ExperimentalTracingV2ProducerStats Stats() {
+    protos::gen::ExperimentalTracingV2ProducerStats stats;
+    drainer_->FillStats(&stats);
+    return stats;
+  }
+
   base::TestTaskRunner task_runner_;
   FakeDelegate delegate_;
   std::unique_ptr<SharedRingBuffer> ring_buffer_;
@@ -164,6 +172,15 @@
     EXPECT_EQ(packet.writer_id, kWriter);
     EXPECT_FALSE(packet.previous_packet_dropped);
   }
+
+  const auto stats = Stats();
+  EXPECT_EQ(stats.chunk_size_bytes(), kChunkSize);
+  EXPECT_EQ(stats.num_chunks(), kNumChunks);
+  EXPECT_EQ(stats.chunks_read(), 1u);
+  EXPECT_EQ(stats.bytes_read(),
+            Packet("first").size() + Packet("second").size());
+  EXPECT_EQ(stats.drain_passes(), 1u);
+  EXPECT_EQ(stats.drain_max_time_ns(), stats.drain_time_ns());
 }
 
 TEST_F(ServiceRingBufferDrainerTest, DiscardsInvalidWriterIds) {
@@ -182,6 +199,7 @@
 
   EXPECT_EQ(ReadPos(), 2u);
   EXPECT_EQ(delegate_.chunks_discarded, 2u);
+  EXPECT_EQ(Stats().invalid_writer_chunks(), 2u);
   EXPECT_TRUE(ReadPackets().empty());
 }
 
@@ -202,6 +220,7 @@
   // The service drops the chunk before any trace buffer sees it. The
   // writer's sequence in the allowed buffer shows the gap.
   EXPECT_EQ(delegate_.chunks_discarded, 1u);
+  EXPECT_EQ(Stats().invalid_destination_chunks(), 1u);
   const auto packets = ReadPackets();
   ASSERT_EQ(packets.size(), 2u);
   EXPECT_EQ(packets[0].str, "before");
@@ -228,6 +247,7 @@
   drainer_->Drain();
 
   EXPECT_EQ(delegate_.chunks_discarded, 0u);
+  EXPECT_EQ(Stats().data_loss_chunks(), 1u);
   const auto packets = ReadPackets();
   ASSERT_EQ(packets.size(), 2u);
   EXPECT_EQ(packets[0].str, "before");
@@ -235,6 +255,25 @@
   EXPECT_TRUE(packets[1].previous_packet_dropped);
 }
 
+// The trace buffer can refuse a chunk that the reader delivered. Here the
+// writer ID already has SMB chunks in the buffer.
+TEST_F(ServiceRingBufferDrainerTest, CountsChunksRejectedByTraceBuffer) {
+  FakeChunk(delegate_.buffer.get(), kProducer, kWriter, ChunkID(0))
+      .AddPacket(4, 'a')
+      .CopyIntoTraceBuffer();
+
+  SharedRingBufferWriter writer =
+      MakeWriter(ring_buffer_.get(), kWriter, kBuffer);
+  ASSERT_TRUE(WriteFragment(&writer, Packet("rejected")));
+  writer.FinishCurrentChunk();
+  drainer_->Drain();
+
+  const auto stats = Stats();
+  EXPECT_EQ(stats.chunks_read(), 1u);
+  EXPECT_EQ(stats.trace_buffer_rejected_chunks(), 1u);
+  EXPECT_EQ(delegate_.buffer->stats().abi_violations(), 1u);
+}
+
 TEST_F(ServiceRingBufferDrainerTest, MalformedAndUnknownChunksAreDiscards) {
   const struct {
     ChunkFormat format;
@@ -257,6 +296,10 @@
   EXPECT_EQ(ReadPos(), 2u);
   EXPECT_EQ(delegate_.chunks_discarded, 2u);
   EXPECT_EQ(delegate_.buffer->stats().abi_violations(), 0u);
+  const auto stats = Stats();
+  EXPECT_EQ(stats.malformed_chunks(), 1u);
+  EXPECT_EQ(stats.unsupported_format_chunks(), 1u);
+  EXPECT_EQ(stats.positions_skipped(), 2u);
 }
 
 TEST_F(ServiceRingBufferDrainerTest, ProtocolErrorIsAnAbiViolation) {
@@ -278,6 +321,9 @@
   EXPECT_EQ(ReadPos(), 0u);
   EXPECT_EQ(delegate_.buffer->stats().abi_violations(), 1u);
   EXPECT_TRUE(ReadPackets().empty());
+
+  // Only the first drain ran the reader.
+  EXPECT_EQ(Stats().drain_passes(), 1u);
 }
 
 TEST_F(ServiceRingBufferDrainerTest, LostRacesPostOneDelayedRetry) {
diff --git a/src/tracing/service/trace_buffer.h b/src/tracing/service/trace_buffer.h
index e75e45a..ad4193b 100644
--- a/src/tracing/service/trace_buffer.h
+++ b/src/tracing/service/trace_buffer.h
@@ -200,8 +200,13 @@
  public:
   using WriterBuckets =
       Histogram<8, 32, 128, 512, 1024, 2048, 4096, 8192, 12288, 16384>;
+  struct ChunkUsage {
+    WriterBuckets chunk_payload_histogram;
+    // ProtocolAbiVersion values that carried this writer's chunks.
+    uint32_t protocol_abi_versions = 0;
+  };
   using WriterStatsMap = base::FlatHashMap<ProducerAndWriterID,
-                                           WriterBuckets,
+                                           ChunkUsage,
                                            std::hash<ProducerAndWriterID>,
                                            base::QuadraticProbe,
                                            /*AppendOnly=*/true>;
@@ -219,8 +224,14 @@
     return *this;
   }
 
-  void Insert(ProducerAndWriterID key, HistValue val) {
-    map_.Insert(key, {}).first->Add(val);
+  // Adds one chunk of payload size |val|.
+  // |protocol_abi_version| is the ProtocolAbiVersion that carried it.
+  void Insert(ProducerAndWriterID key,
+              HistValue val,
+              uint32_t protocol_abi_version) {
+    ChunkUsage& usage = *map_.Insert(key, {}).first;
+    usage.protocol_abi_versions |= protocol_abi_version;
+    usage.chunk_payload_histogram.Add(val);
   }
 
   WriterStatsMap::Iterator GetIterator() const { return map_.GetIterator(); }
diff --git a/src/tracing/service/trace_buffer_v1.cc b/src/tracing/service/trace_buffer_v1.cc
index eb78345..a44bbd1 100644
--- a/src/tracing/service/trace_buffer_v1.cc
+++ b/src/tracing/service/trace_buffer_v1.cc
@@ -24,6 +24,7 @@
 #include "perfetto/ext/tracing/core/client_identity.h"
 #include "perfetto/ext/tracing/core/shared_memory_abi.h"
 #include "perfetto/ext/tracing/core/trace_packet.h"
+#include "perfetto/ext/tracing/core/tracing_service.h"
 #include "perfetto/protozero/proto_utils.h"
 
 #define TRACE_BUFFER_VERBOSE_LOGGING() 0  // Set to 1 when debugging unittests.
@@ -896,7 +897,7 @@
     stats_.set_chunks_read(stats_.chunks_read() + 1);
     stats_.set_bytes_read(stats_.bytes_read() + chunk_record->size);
     writer_stats_.Insert(producer_and_writer_id,
-                         chunk_meta->cur_fragment_offset);
+                         chunk_meta->cur_fragment_offset, kProtocolAbiV1);
   } else {
     // We have at least one more packet to parse. It should be within the chunk.
     if (chunk_meta->cur_fragment_offset + sizeof(ChunkRecord) >=
diff --git a/src/tracing/service/trace_buffer_v2.cc b/src/tracing/service/trace_buffer_v2.cc
index d923a5a..c6b7af2 100644
--- a/src/tracing/service/trace_buffer_v2.cc
+++ b/src/tracing/service/trace_buffer_v2.cc
@@ -26,6 +26,7 @@
 #include "perfetto/ext/tracing/core/basic_types.h"
 #include "perfetto/ext/tracing/core/client_identity.h"
 #include "perfetto/ext/tracing/core/shared_memory_abi.h"
+#include "perfetto/ext/tracing/core/tracing_service.h"
 #include "perfetto/protozero/proto_utils.h"
 
 #include "protos/perfetto/trace/trace_packet.pbzero.h"
@@ -959,7 +960,8 @@
   }
 
   auto seq_key = MkProducerAndWriterID(producer_id_trusted, writer_id);
-  writer_stats_.Insert(seq_key, static_cast<HistValue>(all_frags_size));
+  writer_stats_.Insert(seq_key, static_cast<HistValue>(all_frags_size),
+                       kProtocolAbiV1);
 
   auto [seq_it, seq_is_new] = sequences_.try_emplace(
       seq_key,
@@ -1246,7 +1248,8 @@
 
   auto seq_key =
       MkProducerAndWriterID(sequence.producer_id_trusted, sequence.writer_id);
-  writer_stats_.Insert(seq_key, static_cast<HistValue>(total_payload));
+  writer_stats_.Insert(seq_key, static_cast<HistValue>(total_payload),
+                       kProtocolAbiV2);
 
   auto [seq_it, seq_is_new] = sequences_.try_emplace(
       seq_key, SequenceState(sequence.producer_id_trusted, sequence.writer_id,
diff --git a/src/tracing/service/trace_buffer_v2_unittest.cc b/src/tracing/service/trace_buffer_v2_unittest.cc
index 13fa5c1..20a3f6a 100644
--- a/src/tracing/service/trace_buffer_v2_unittest.cc
+++ b/src/tracing/service/trace_buffer_v2_unittest.cc
@@ -29,6 +29,7 @@
 #include "perfetto/ext/tracing/core/client_identity.h"
 #include "perfetto/ext/tracing/core/shared_memory_abi.h"
 #include "perfetto/ext/tracing/core/trace_packet.h"
+#include "perfetto/ext/tracing/core/tracing_service.h"
 #include "perfetto/protozero/proto_decoder.h"
 #include "perfetto/protozero/proto_utils.h"
 #include "protos/perfetto/trace/trace_packet.pbzero.h"
@@ -4556,6 +4557,10 @@
     ++count;
     EXPECT_TRUE(it.key() == MkProducerAndWriterID(1, 0x8001) ||
                 it.key() == MkProducerAndWriterID(1, 1));
+    // Each entry has the protocol that carried the writer's chunk.
+    EXPECT_EQ(it.value().protocol_abi_versions,
+              it.key() == MkProducerAndWriterID(1, 1) ? kProtocolAbiV2
+                                                      : kProtocolAbiV1);
   }
   EXPECT_EQ(count, 2u);
   trace_buffer()->BeginRead();
diff --git a/src/tracing/service/tracing_service_endpoints_impl.cc b/src/tracing/service/tracing_service_endpoints_impl.cc
index 58a02f9..477706e 100644
--- a/src/tracing/service/tracing_service_endpoints_impl.cc
+++ b/src/tracing/service/tracing_service_endpoints_impl.cc
@@ -41,6 +41,7 @@
 #include "src/tracing/v2/shared_ring_buffer_abi.h"
 
 #include "protos/perfetto/common/builtin_clock.pbzero.h"
+#include "protos/perfetto/trace/perfetto/tracing_v2_producer_stats.gen.h"
 
 namespace perfetto::tracing_service {
 
@@ -855,6 +856,20 @@
     v2_ring_buffer_drainer_->Drain();
 }
 
+std::optional<protos::gen::ExperimentalTracingV2ProducerStats>
+ProducerEndpointImpl::GetTracingV2Stats() const {
+  PERFETTO_DCHECK_THREAD(thread_checker_);
+  if (!v2_ring_buffer_drainer_)
+    return std::nullopt;
+
+  protos::gen::ExperimentalTracingV2ProducerStats stats;
+  stats.set_producer_id(id_);
+  stats.set_pid(static_cast<int32_t>(pid()));
+  stats.set_producer_name(name_);
+  v2_ring_buffer_drainer_->FillStats(&stats);
+  return stats;
+}
+
 TraceBuffer* ProducerEndpointImpl::GetV2RingBufferDestination(BufferID id) {
   if (!is_allowed_target_buffer(id))
     return nullptr;
diff --git a/src/tracing/service/tracing_service_endpoints_impl.h b/src/tracing/service/tracing_service_endpoints_impl.h
index aea19a3..cf75dc4 100644
--- a/src/tracing/service/tracing_service_endpoints_impl.h
+++ b/src/tracing/service/tracing_service_endpoints_impl.h
@@ -49,6 +49,10 @@
 
 class SharedMemoryArbiterImpl;
 
+namespace protos::gen {
+class ExperimentalTracingV2ProducerStats;
+}
+
 namespace tracing_service {
 
 class TracingServiceImpl;
@@ -154,6 +158,11 @@
   ProducerEndpointImpl(const ProducerEndpointImpl&) = delete;
   ProducerEndpointImpl& operator=(const ProducerEndpointImpl&) = delete;
 
+  // Returns this producer's ring buffer stats, or nullopt if no ring buffer
+  // is attached.
+  std::optional<protos::gen::ExperimentalTracingV2ProducerStats>
+  GetTracingV2Stats() const;
+
   ProducerID const id_;
   ClientIdentity const client_identity_;
   TracingServiceImpl* const service_;
diff --git a/src/tracing/service/tracing_service_impl.cc b/src/tracing/service/tracing_service_impl.cc
index 8dcc44f..8a11e62 100644
--- a/src/tracing/service/tracing_service_impl.cc
+++ b/src/tracing/service/tracing_service_impl.cc
@@ -137,6 +137,8 @@
 #include "protos/perfetto/trace/perfetto/concurrent_session_event.pbzero.h"
 #include "protos/perfetto/trace/perfetto/trace_provenance.pbzero.h"
 #include "protos/perfetto/trace/perfetto/tracing_service_event.pbzero.h"
+#include "protos/perfetto/trace/perfetto/tracing_v2_producer_stats.gen.h"
+#include "protos/perfetto/trace/perfetto/tracing_v2_producer_stats.pbzero.h"
 #include "protos/perfetto/trace/remote_clock_sync.pbzero.h"
 #include "protos/perfetto/trace/trace_packet.pbzero.h"
 #include "protos/perfetto/trace/trace_uuid.pbzero.h"
@@ -2945,6 +2947,11 @@
     EmitLifecycleEvents(tracing_session, &packets);
   }
 
+  // Emit producer stats before MaybeFilterPackets to respect the session's
+  // trace filtering rules.
+  if (!*has_more && tracing_session->should_emit_stats)
+    EmitTracingV2ProducerStats(tracing_session, &packets);
+
   MaybeFilterPackets(tracing_session, &packets);
 
   // Only emit the stats when there is no more trace data is available to read.
@@ -4179,6 +4186,34 @@
   packets->back().AddSlice(&sync_marker_packet_[0], sync_marker_packet_size_);
 }
 
+void TracingServiceImpl::EmitTracingV2ProducerStats(
+    TracingSession* tracing_session,
+    std::vector<TracePacket>* packets) {
+  for (const auto& stats : GetTracingV2ProducerStats(*tracing_session)) {
+    protozero::HeapBuffered<protos::pbzero::TracePacket> packet;
+    SetServiceTracePacketHeader(packet.get());
+    stats.Serialize(packet->set_experimental_tracing_v2_producer_stats());
+    SerializeAndAppendPacket(packets, packet.SerializeAsArray());
+  }
+}
+
+std::vector<protos::gen::ExperimentalTracingV2ProducerStats>
+TracingServiceImpl::GetTracingV2ProducerStats(const TracingSession& session) {
+  // A cloned session has no data source instances.
+  // It keeps the copy that FinishCloneSession() took from its source session.
+  if (session.state == TracingSession::CLONED_READ_ONLY)
+    return session.tracing_v2_producer_stats_at_clone;
+
+  std::vector<protos::gen::ExperimentalTracingV2ProducerStats> producer_stats;
+  for (const auto& [producer_id, producer] : producers_) {
+    if (session.data_source_instances.count(producer_id) == 0)
+      continue;
+    if (auto stats = producer->GetTracingV2Stats())
+      producer_stats.emplace_back(std::move(*stats));
+  }
+  return producer_stats;
+}
+
 void TracingServiceImpl::EmitStats(TracingSession* tracing_session,
                                    std::vector<TracePacket>* packets) {
   protozero::HeapBuffered<protos::pbzero::TracePacket> packet;
@@ -4241,7 +4276,7 @@
       if (!buf)
         continue;
       for (auto it = buf->writer_stats().GetIterator(); it; ++it) {
-        const auto& hist = it.value();
+        const auto& hist = it.value().chunk_payload_histogram;
         ProducerID p;
         WriterID w;
         GetProducerAndWriterID(it.key(), &p, &w);
@@ -4258,6 +4293,7 @@
         wri_stats->set_sequence_id(
             tracing_session->GetPacketSequenceID(kDefaultMachineID, p, w));
         wri_stats->set_buffer(buf_idx);
+        wri_stats->set_protocol_abi_versions(it.value().protocol_abi_versions);
         for (size_t i = 0; i < hist.num_buckets(); ++i) {
           wri_stats->add_chunk_payload_histogram_counts(hist.GetBucketCount(i));
           wri_stats->add_chunk_payload_histogram_sum(hist.GetBucketSum(i));
@@ -5132,6 +5168,8 @@
   cloned_session->flushes_requested = src->flushes_requested;
   cloned_session->flushes_succeeded = src->flushes_succeeded;
   cloned_session->flushes_failed = src->flushes_failed;
+  cloned_session->tracing_v2_producer_stats_at_clone =
+      GetTracingV2ProducerStats(*src);
   if (src->trace_filter && !skip_trace_filter) {
     // Copy the trace filter, unless it's a clone-for-bugreport (b/317065412).
     cloned_session->trace_filter.reset(
diff --git a/src/tracing/service/tracing_service_impl.h b/src/tracing/service/tracing_service_impl.h
index 4ff5f98..d5088c3 100644
--- a/src/tracing/service/tracing_service_impl.h
+++ b/src/tracing/service/tracing_service_impl.h
@@ -53,8 +53,9 @@
 
 namespace protos {
 namespace gen {
+class ExperimentalTracingV2ProducerStats;
 enum TraceStats_FinalFlushOutcome : int;
-}
+}  // namespace gen
 namespace pbzero {
 class TracePacket;
 }
@@ -266,6 +267,12 @@
                          TracingSession::ClockSnapshotData,
                          std::vector<TracePacket>*);
   void EmitSyncMarker(std::vector<TracePacket>*);
+  void EmitTracingV2ProducerStats(TracingSession*, std::vector<TracePacket>*);
+  // Returns the tracing v2 stats of the connected producers that have a data
+  // source instance in the session.
+  // For a cloned session, returns the copy taken when it was cloned.
+  std::vector<protos::gen::ExperimentalTracingV2ProducerStats>
+  GetTracingV2ProducerStats(const TracingSession&);
   void EmitStats(TracingSession*, std::vector<TracePacket>*);
   TraceStats GetTraceStats(TracingSession*);
   void EmitLifecycleEvents(TracingSession*, std::vector<TracePacket>*);
diff --git a/src/tracing/service/tracing_service_impl_unittest.cc b/src/tracing/service/tracing_service_impl_unittest.cc
index a688d62..bbae661 100644
--- a/src/tracing/service/tracing_service_impl_unittest.cc
+++ b/src/tracing/service/tracing_service_impl_unittest.cc
@@ -80,6 +80,7 @@
 #include "protos/perfetto/trace/perfetto/concurrent_session_event.gen.h"
 #include "protos/perfetto/trace/perfetto/trace_provenance.gen.h"
 #include "protos/perfetto/trace/perfetto/tracing_service_event.gen.h"
+#include "protos/perfetto/trace/perfetto/tracing_v2_producer_stats.gen.h"
 #include "protos/perfetto/trace/test_event.gen.h"
 #include "protos/perfetto/trace/test_event.pbzero.h"
 #include "protos/perfetto/trace/trace.gen.h"
@@ -520,6 +521,19 @@
   return payloads;
 }
 
+std::vector<protos::gen::ExperimentalTracingV2ProducerStats>
+GetTracingV2ProducerStats(
+    const std::vector<protos::gen::TracePacket>& packets) {
+  std::vector<protos::gen::ExperimentalTracingV2ProducerStats> stats;
+  for (const auto& packet : packets) {
+    if (packet.has_experimental_tracing_v2_producer_stats()) {
+      EXPECT_FALSE(packet.has_trace_stats());
+      stats.push_back(packet.experimental_tracing_v2_producer_stats());
+    }
+  }
+  return stats;
+}
+
 // An in-process producer with v2 uses the same producer code as over IPC.
 // The service shares its mapping of the ring buffer.
 TEST_F(TracingServiceImplTest, InProcessWriterUsesV2) {
@@ -585,13 +599,122 @@
         endpoint->NotifyFlushComplete(id);
       });
   ASSERT_TRUE(consumer->Flush().WaitForReply());
-  EXPECT_THAT(TestPayloads(consumer->ReadBuffers()), ElementsAre(payload));
+  const auto packets = consumer->ReadBuffers();
+  EXPECT_THAT(TestPayloads(packets), ElementsAre(payload));
+
+  const auto producer_stats_entries = GetTracingV2ProducerStats(packets);
+  ASSERT_EQ(producer_stats_entries.size(), 1u);
+  const auto& producer_stats = producer_stats_entries[0];
+  EXPECT_EQ(producer_stats.pid(), 1025);
+  EXPECT_EQ(producer_stats.producer_name(), "ring_buffer");
+  EXPECT_EQ(producer_stats.chunk_size_bytes() * producer_stats.num_chunks() +
+                sizeof(tracing_v2::RingBufferHeader),
+            impl->ring_buffer_size_bytes());
+  EXPECT_GT(producer_stats.chunks_read(), 0u);
+  EXPECT_GT(producer_stats.bytes_read(), payload.size());
+  EXPECT_GT(producer_stats.drain_passes(), 0u);
+
+  // TraceStats reports the protocol of each writer.
+  consumer->GetTraceStats();
+  const TraceStats stats = consumer->WaitForTraceStats(/*success=*/true);
+  ASSERT_EQ(stats.writer_stats().size(), 1u);
+  EXPECT_EQ(stats.writer_stats()[0].protocol_abi_versions(), kProtocolAbiV2);
+
   writer.reset();
   EXPECT_CALL(producer, StopDataSource(instance));
   consumer->DisableTracing();
   consumer->WaitForTracingDisabled();
 }
 
+// Only a session with a data source of the producer lists its stats. A clone
+// keeps the stats from the time of the clone.
+TEST_F(TracingServiceImplTest, TracingV2ProducerStatsFollowSession) {
+  NiceMock<MockProducer> producer(&task_runner);
+  NiceMock<MockProducer> other_producer(&task_runner);
+  // Each producer has a data source named after it and a ring buffer of four
+  // chunks.
+  auto connect = [&](MockProducer* mock, const std::string& name) {
+    auto endpoint = svc->ConnectProducer(
+        mock, ClientIdentity(42, 1025), name,
+        /*shared_memory_size_hint_bytes=*/0, /*in_process=*/true,
+        TracingService::ProducerSMBScrapingMode::kDefault,
+        /*shared_memory_page_size_hint_bytes=*/0, /*shm=*/nullptr,
+        /*sdk_version=*/"1.2.3", /*machine_name=*/{},
+        kProtocolAbiV1 | kProtocolAbiV2);
+    DataSourceDescriptor descriptor;
+    descriptor.set_name(name);
+    endpoint->RegisterDataSource(descriptor);
+    endpoint->AttachV2RingBuffer(
+        std::make_shared<InProcessSharedMemory>(
+            sizeof(tracing_v2::RingBufferHeader) + 4 * 256),
+        /*chunk_size_bytes=*/256, [](bool accepted) { EXPECT_TRUE(accepted); });
+    return endpoint;
+  };
+  auto endpoint = connect(&producer, "in_session");
+  auto other_endpoint = connect(&other_producer, "not_in_session");
+
+  auto consumer = CreateMockConsumer();
+  consumer->Connect(svc.get());
+  consumer->EnableTracing(RingBufferConfig("in_session"));
+  task_runner.RunUntilIdle();
+  const TracingSessionID source_session_id =
+      GetLastTracingSessionId(consumer.get());
+
+  const auto stats = GetTracingV2ProducerStats(consumer->ReadBuffers());
+  ASSERT_EQ(stats.size(), 1u);
+  EXPECT_EQ(stats[0].producer_name(), "in_session");
+  EXPECT_EQ(stats[0].num_chunks(), 4u);
+
+  // A filter that only permits TraceStats must exclude producer identity.
+  auto filtered_consumer = CreateMockConsumer();
+  filtered_consumer->Connect(svc.get());
+  TraceConfig filtered_config = RingBufferConfig("in_session");
+  protozero::FilterBytecodeGenerator filter;
+  filter.AddNestedField(1, 1);
+  filter.EndMessage();
+  filter.AddSimpleField(protos::pbzero::TracePacket::kTraceStatsFieldNumber);
+  filter.EndMessage();
+  filtered_config.mutable_trace_filter()->set_bytecode(
+      filter.Serialize().bytecode);
+  filtered_consumer->EnableTracing(filtered_config);
+  task_runner.RunUntilIdle();
+  const auto filtered_packets = filtered_consumer->ReadBuffers();
+  EXPECT_TRUE(GetTracingV2ProducerStats(filtered_packets).empty());
+  EXPECT_THAT(
+      filtered_packets,
+      Contains(Property(&protos::gen::TracePacket::has_trace_stats, true)));
+  filtered_consumer->DisableTracing();
+  filtered_consumer->WaitForTracingDisabled();
+
+  // The clone flushes the session's producers first.
+  auto clone_consumer = CreateMockConsumer();
+  clone_consumer->Connect(svc.get());
+  EXPECT_CALL(producer, Flush(_, _, _, _))
+      .WillOnce([&](FlushRequestID id, const DataSourceInstanceID*, size_t,
+                    FlushFlags) { endpoint->NotifyFlushComplete(id); });
+  auto clone_done = task_runner.CreateCheckpoint("clone_done");
+  EXPECT_CALL(*clone_consumer, OnSessionCloned(_))
+      .WillOnce([&](const Consumer::OnSessionClonedArgs& args) {
+        EXPECT_TRUE(args.success);
+        clone_done();
+      });
+  clone_consumer->CloneSession(source_session_id);
+  task_runner.RunUntilCheckpoint("clone_done");
+
+  // The clone keeps its stats after the producer disconnects.
+  endpoint.reset();
+  task_runner.RunUntilIdle();
+  const auto cloned_stats =
+      GetTracingV2ProducerStats(clone_consumer->ReadBuffers());
+  ASSERT_EQ(cloned_stats.size(), 1u);
+  EXPECT_EQ(cloned_stats[0].producer_name(), "in_session");
+  // The service drained on the attach and on the clone's flush.
+  EXPECT_GE(cloned_stats[0].drain_passes(), 2u);
+
+  consumer->DisableTracing();
+  consumer->WaitForTracingDisabled();
+}
+
 // Only InitializeV2RingBuffer() allocates the ring buffer.
 // The first call attaches it, and later sessions reuse it with the first
 // instance's chunk size and drain percentage.
@@ -6043,6 +6166,8 @@
                 packet.trace_stats().chunk_payload_histogram_def()[i]),
             wri.chunk_payload_histogram_counts()[i]);
       }
+      // Both writers use the SMB.
+      EXPECT_EQ(wri.protocol_abi_versions(), kProtocolAbiV1);
 
       switch (wri.sequence_id()) {
         case 1:  // Ignore service-generated packets.
diff --git a/src/tracing/service/tracing_service_session.h b/src/tracing/service/tracing_service_session.h
index ea9efa1..392315e 100644
--- a/src/tracing/service/tracing_service_session.h
+++ b/src/tracing/service/tracing_service_session.h
@@ -33,23 +33,20 @@
 #include "perfetto/ext/base/scoped_sched_boost.h"
 #include "perfetto/ext/base/uuid.h"
 #include "perfetto/ext/tracing/core/basic_types.h"
+#include "perfetto/ext/tracing/core/trace_stats.h"
 #include "perfetto/tracing/core/data_source_config.h"
 #include "perfetto/tracing/core/trace_config.h"
 
 #include "src/tracing/service/tracing_service_structs.h"
 
+#include "protos/perfetto/trace/perfetto/tracing_v2_producer_stats.gen.h"
+
 namespace protozero {
 class MessageFilter;
 }
 
 namespace perfetto {
 
-namespace protos {
-namespace gen {
-enum TraceStats_FinalFlushOutcome : int;
-}
-}  // namespace protos
-
 namespace base {
 class TaskRunner;
 }
@@ -178,6 +175,11 @@
   // Outcome of the final Flush() done by FlushAndDisableTracing().
   protos::gen::TraceStats_FinalFlushOutcome final_flush_outcome{};
 
+  // The tracing v2 stats of the source session's producers, copied when the
+  // session was cloned.
+  std::vector<protos::gen::ExperimentalTracingV2ProducerStats>
+      tracing_v2_producer_stats_at_clone;
+
   // Set to true on the first call to MaybeNotifyAllDataSourcesStarted().
   bool did_notify_all_data_source_started = false;
 
diff --git a/src/tracing/test/BUILD.gn b/src/tracing/test/BUILD.gn
index a49ad1d..7c032b5 100644
--- a/src/tracing/test/BUILD.gn
+++ b/src/tracing/test/BUILD.gn
@@ -73,6 +73,7 @@
       "../../../gn:gtest_and_gmock",
       "../../../include/perfetto/ext/ipc",
       "../../../protos/perfetto/ipc:cpp",
+      "../../../protos/perfetto/trace/perfetto:cpp",
       "../../base",
       "../../base:test_support",
       "../ipc:common",
diff --git a/src/tracing/test/tracing_integration_test.cc b/src/tracing/test/tracing_integration_test.cc
index ef6d07c..b94d124 100644
--- a/src/tracing/test/tracing_integration_test.cc
+++ b/src/tracing/test/tracing_integration_test.cc
@@ -54,6 +54,7 @@
 #include "protos/perfetto/ipc/producer_port.gen.h"
 #include "protos/perfetto/ipc/producer_port.ipc.h"
 #include "protos/perfetto/trace/clock_snapshot.gen.h"
+#include "protos/perfetto/trace/perfetto/tracing_v2_producer_stats.gen.h"
 #include "protos/perfetto/trace/test_event.gen.h"
 #include "protos/perfetto/trace/test_event.pbzero.h"
 #include "protos/perfetto/trace/trace.gen.h"
@@ -466,7 +467,9 @@
     task_runner_->RunUntilCheckpoint(name);
   }
 
-  std::vector<protos::gen::TracePacket> Read() {
+  std::vector<protos::gen::TracePacket> Read(
+      std::vector<protos::gen::ExperimentalTracingV2ProducerStats>*
+          producer_stats = nullptr) {
     std::vector<protos::gen::TracePacket> result;
     auto read = task_runner_->CreateCheckpoint("ring_buffer_read");
     EXPECT_CALL(consumer_, OnTracePackets(_, _))
@@ -475,6 +478,12 @@
             protos::gen::TracePacket packet;
             EXPECT_TRUE(
                 packet.ParseFromString(encoded.GetRawBytesForTesting()));
+            if (producer_stats &&
+                packet.has_experimental_tracing_v2_producer_stats()) {
+              EXPECT_FALSE(packet.has_trace_stats());
+              producer_stats->push_back(
+                  packet.experimental_tracing_v2_producer_stats());
+            }
             if (packet.has_for_testing())
               result.push_back(std::move(packet));
           }
@@ -641,11 +650,29 @@
     flushed();
   });
   task_runner_->RunUntilCheckpoint("instance_flushed");
-  auto packets = Read();
+  std::vector<protos::gen::ExperimentalTracingV2ProducerStats> producer_stats;
+  auto packets = Read(&producer_stats);
   ASSERT_EQ(packets.size(), param.selected_version ? 1u : 0u);
   if (param.selected_version)
     EXPECT_EQ(packets[0].for_testing().str(), payload);
 
+  // TraceStats shows the writer's protocol. Only v2 has a producer stats
+  // packet.
+  const TraceStats stats = GetTraceStats();
+  if (param.selected_version) {
+    ASSERT_EQ(stats.writer_stats().size(), 1u);
+    EXPECT_EQ(stats.writer_stats()[0].protocol_abi_versions(),
+              *param.selected_version);
+  }
+  if (param.selected_version == kProtocolAbiV2) {
+    ASSERT_EQ(producer_stats.size(), 1u);
+    EXPECT_EQ(producer_stats[0].chunk_size_bytes(), 1024u);
+    EXPECT_GT(producer_stats[0].chunks_read(), 0u);
+    EXPECT_GT(producer_stats[0].bytes_read(), payload.size());
+  } else {
+    EXPECT_TRUE(producer_stats.empty());
+  }
+
   writer.reset();
   auto stopped = task_runner_->CreateCheckpoint("instance_stopped");
   EXPECT_CALL(producer_, StopDataSource(instance));
@@ -900,7 +927,9 @@
   first.FinishCurrentChunk();
   second.FinishCurrentChunk();
   Drain();
+  // A dropping writer marks its next chunk and counts the packet in the header.
   first.RecordDataLoss();
+  ring_buffer_->AddDroppedPackets(1);
   ASSERT_TRUE(tracing_v2::test::WriteFragment(&first, Packet("discarded")));
   first.FinishCurrentChunk();
   Drain();
@@ -909,7 +938,8 @@
   first.FinishCurrentChunk();
   second.FinishCurrentChunk();
   Drain();
-  auto packets = Read();
+  std::vector<protos::gen::ExperimentalTracingV2ProducerStats> producer_stats;
+  auto packets = Read(&producer_stats);
   ASSERT_EQ(packets.size(), 3u);
   for (const auto& packet : packets) {
     if (packet.for_testing().str() == "recovered")
@@ -919,6 +949,11 @@
     else
       EXPECT_EQ(packet.for_testing().str(), "other-before");
   }
+
+  // The service counts the marked chunk and reads the packet count.
+  ASSERT_EQ(producer_stats.size(), 1u);
+  EXPECT_EQ(producer_stats[0].data_loss_chunks(), 1u);
+  EXPECT_EQ(producer_stats[0].writer_dropped_packets(), 1u);
 }
 
 TEST_F(RingBufferTransportIntegrationTest,
diff --git a/src/tracing/v2/producer_ring_buffer_arbiter.cc b/src/tracing/v2/producer_ring_buffer_arbiter.cc
index 6db1512..00595f2 100644
--- a/src/tracing/v2/producer_ring_buffer_arbiter.cc
+++ b/src/tracing/v2/producer_ring_buffer_arbiter.cc
@@ -16,11 +16,14 @@
 
 #include "src/tracing/v2/producer_ring_buffer_arbiter.h"
 
+#include <stdint.h>
+
 #include <algorithm>
 #include <utility>
 
 #include "perfetto/base/logging.h"
 #include "perfetto/base/task_runner.h"
+#include "perfetto/ext/base/murmur_hash.h"
 #include "perfetto/ext/base/status_macros.h"
 #include "perfetto/ext/base/uuid.h"
 #include "perfetto/ext/tracing/core/shared_memory.h"
@@ -95,6 +98,27 @@
 }  // namespace
 
 // static
+bool ProducerRingBufferArbiter::ShouldUseTracingV2(
+    const DataSourceConfig& config) {
+  if (!config.supports_tracing_v2())
+    return false;
+  const uint32_t probability =
+      config.experimental_tracing_v2().use_v2_probability_percent();
+  if (probability >= 100)
+    return true;
+
+  // To ensure data sources from the same producer and session enable or
+  // disable v2 together when their probabilities match, hash the session ID
+  // with this function's address. Code ASLR provides entropy across processes,
+  // while the address stays fixed within each process.
+  const uint64_t session_sample = base::MurmurHashCombine(
+      config.tracing_session_id(),
+      reinterpret_cast<uintptr_t>(
+          &ProducerRingBufferArbiter::ShouldUseTracingV2));
+  return session_sample % 100 < probability;
+}
+
+// static
 base::StatusOr<std::unique_ptr<ProducerRingBufferArbiter>>
 ProducerRingBufferArbiter::Create(
     base::TaskRunner* task_runner,
diff --git a/src/tracing/v2/producer_ring_buffer_arbiter.h b/src/tracing/v2/producer_ring_buffer_arbiter.h
index fcb092a..51a048c 100644
--- a/src/tracing/v2/producer_ring_buffer_arbiter.h
+++ b/src/tracing/v2/producer_ring_buffer_arbiter.h
@@ -74,8 +74,9 @@
 // - Creation, state changes, posted tasks, flush callbacks and service
 //   requests run on the endpoint thread.
 //
-// The caller selects v2, then calls InitializeV2RingBuffer() on the endpoint
-// thread before it lets writers use the ring buffer.
+// The caller selects v2 with ShouldUseTracingV2(), then calls
+// InitializeV2RingBuffer() on the endpoint thread before it lets writers use
+// the ring buffer.
 // Time goes down.
 // "--->" is a direct call, and "===>" is an IPC message.
 //
@@ -202,6 +203,16 @@
   using AllocateSharedMemoryFn =
       base::StatusOr<std::shared_ptr<SharedMemory>> (*)(size_t size);
 
+  // Picks v1 or v2 from |config|.
+  // - Returns false if the service did not set supports_tracing_v2.
+  // - Otherwise returns true with probability use_v2_probability_percent.
+  // Eligible data sources with the same probability get the same result
+  // within a process and tracing session.
+  // All writers of an instance must use the same version.
+  // On true, call the endpoint's InitializeV2RingBuffer() before
+  // CreateTraceWriterV2().
+  static bool ShouldUseTracingV2(const DataSourceConfig& config);
+
   // Sizes and allocates a ring buffer from |config|, then creates its arbiter
   // in kPending.
   // - The chunk size and the drain occupancy threshold come from |config|.
diff --git a/src/tracing/v2/producer_ring_buffer_arbiter_unittest.cc b/src/tracing/v2/producer_ring_buffer_arbiter_unittest.cc
index ddae6c4..52564a0 100644
--- a/src/tracing/v2/producer_ring_buffer_arbiter_unittest.cc
+++ b/src/tracing/v2/producer_ring_buffer_arbiter_unittest.cc
@@ -16,6 +16,8 @@
 
 // Tests for ProducerRingBufferArbiter, the producer side of one tracing v2
 // ring buffer. They cover:
+// - Protocol selection: eligible data sources with the same probability
+//   agree within a process and tracing session.
 // - Creation: Create() picks the chunk size, ring buffer size and drain
 //   threshold from the config, and returns the error status of a failed
 //   allocation.
@@ -137,6 +139,45 @@
   }
 };
 
+// --- Protocol selection ---
+
+TEST_F(ProducerRingBufferArbiterTest,
+       TracingV2SelectionRespectsSupportAndProbability) {
+  DataSourceConfig config;
+  config.set_supports_tracing_v2(true);
+  EXPECT_FALSE(ProducerRingBufferArbiter::ShouldUseTracingV2(config));
+
+  config.mutable_experimental_tracing_v2()->set_use_v2_probability_percent(100);
+  EXPECT_TRUE(ProducerRingBufferArbiter::ShouldUseTracingV2(config));
+
+  config.set_supports_tracing_v2(false);
+  EXPECT_FALSE(ProducerRingBufferArbiter::ShouldUseTracingV2(config));
+}
+
+TEST_F(ProducerRingBufferArbiterTest, TracingV2SelectionIsStableWithinSession) {
+  DataSourceConfig config;
+  config.set_supports_tracing_v2(true);
+  config.set_tracing_session_id(42);
+  config.set_name("linux.ftrace");
+  config.set_target_buffer(1);
+
+  DataSourceConfig other_config = config;
+  other_config.set_name("linux.process_stats");
+  other_config.set_target_buffer(2);
+
+  for (uint32_t probability = 1; probability < 100; ++probability) {
+    SCOPED_TRACE(probability);
+    config.mutable_experimental_tracing_v2()->set_use_v2_probability_percent(
+        probability);
+    other_config.mutable_experimental_tracing_v2()
+        ->set_use_v2_probability_percent(probability);
+    const bool use_v2 = ProducerRingBufferArbiter::ShouldUseTracingV2(config);
+    EXPECT_EQ(ProducerRingBufferArbiter::ShouldUseTracingV2(other_config),
+              use_v2);
+    EXPECT_EQ(ProducerRingBufferArbiter::ShouldUseTracingV2(config), use_v2);
+  }
+}
+
 // --- The ring buffer and its attach reply ---
 
 // MockProducerEndpoint does not override InitializeV2RingBuffer() or
diff --git a/src/tracing/v2/shared_ring_buffer.cc b/src/tracing/v2/shared_ring_buffer.cc
index c579dcf..9d000e7 100644
--- a/src/tracing/v2/shared_ring_buffer.cc
+++ b/src/tracing/v2/shared_ring_buffer.cc
@@ -414,4 +414,33 @@
   base::FutexWake(ReadPosFutexAddress(&ring_header->rw_positions), INT_MAX);
 }
 
+// --- Ring buffer full stats. ---
+//
+// All accesses are relaxed because no chunk or position update depends on
+// these counters.
+// They are also independent of each other, so a reader can see them from
+// different times.
+
+SharedRingBuffer::RingBufferFullStats
+SharedRingBuffer::LoadRingBufferFullStatsRelaxed() const {
+  const RingBufferHeader* ring_header = header();
+  RingBufferFullStats stats{};
+  stats.dropped_packets =
+      ring_header->dropped_packets.load(std::memory_order_relaxed);
+  stats.stalls = ring_header->stalls.load(std::memory_order_relaxed);
+  stats.stall_time_ms =
+      ring_header->stall_time_ms.load(std::memory_order_relaxed);
+  return stats;
+}
+
+void SharedRingBuffer::AddDroppedPackets(uint64_t count) {
+  header()->dropped_packets.fetch_add(count, std::memory_order_relaxed);
+}
+
+void SharedRingBuffer::AddStall(uint64_t time_ms) {
+  RingBufferHeader* ring_header = header();
+  ring_header->stalls.fetch_add(1, std::memory_order_relaxed);
+  ring_header->stall_time_ms.fetch_add(time_ms, std::memory_order_relaxed);
+}
+
 }  // namespace perfetto::tracing_v2
diff --git a/src/tracing/v2/shared_ring_buffer.h b/src/tracing/v2/shared_ring_buffer.h
index eac8e40..6cb2b57 100644
--- a/src/tracing/v2/shared_ring_buffer.h
+++ b/src/tracing/v2/shared_ring_buffer.h
@@ -255,6 +255,31 @@
   // can lag the reader's local value. The lag only under-reports free capacity.
   void PublishReadPos(uint32_t read_pos);
 
+  // Ring buffer full stats.
+  //
+  // Writers count in the header what happens to them when the ring buffer
+  // is full.
+  // The service can't see this from the chunks, so it reads the counters and
+  // reports them in TraceStats.
+  // No writer or reader decision depends on their values.
+
+  struct RingBufferFullStats {
+    uint64_t dropped_packets = 0;
+    uint64_t stalls = 0;
+    uint64_t stall_time_ms = 0;
+  };
+
+  // Loads each counter separately, so the values can be from different times.
+  RingBufferFullStats LoadRingBufferFullStatsRelaxed() const;
+
+  // Adds |count| to |dropped_packets|.
+  // These are packets that a writer dropped because it got no chunk.
+  void AddDroppedPackets(uint64_t count);
+
+  // Increments |stalls| for a wait for space, and adds |time_ms| to
+  // |stall_time_ms|.
+  void AddStall(uint64_t time_ms);
+
  private:
   friend class test::SharedRingBufferInternalsForTest;
 
diff --git a/src/tracing/v2/shared_ring_buffer_abi.h b/src/tracing/v2/shared_ring_buffer_abi.h
index 6091a2e..c349527 100644
--- a/src/tracing/v2/shared_ring_buffer_abi.h
+++ b/src/tracing/v2/shared_ring_buffer_abi.h
@@ -103,14 +103,21 @@
 // ------------------
 //
 //   byte offset
-//   0              4              8              12               64
-//   +--------------+--------------+--------------+----------------+
-//   |   read_pos   |  write_pos   | num_writers_ |    reserved    |
-//   |              |              |   waiting    |                |
-//   +--------------+--------------+--------------+----------------+
+//   0              4              8              12             16
+//   +--------------+--------------+--------------+--------------+
+//   |   read_pos   |  write_pos   | num_writers_ |   padding    |
+//   |              |              |   waiting    |              |
+//   +--------------+--------------+--------------+--------------+
 //   |<------- rw_positions ------>|<- atomic32 ->|
 //          atomic<uint64_t>
 //
+//   16             24             32             40             64
+//   +--------------+--------------+--------------+--------------+
+//   |   dropped_   |    stalls    | stall_time_  |   reserved   |
+//   |   packets    |              |      ms      |              |
+//   +--------------+--------------+--------------+--------------+
+//   |<---------- three atomic<uint64_t> -------->|
+//
 // Writers check capacity by loading rw_positions once. In memory:
 // - The first four bytes hold read_pos.
 // - The next four bytes hold write_pos.
@@ -125,7 +132,13 @@
 // for space. It is only an optimization and never decides whether the ring
 // buffer is full or who owns a chunk.
 //
-// Bytes 12..63 pad the header to one cache line.
+// Bytes 12..15 are padding so the counters below are 8-byte aligned.
+// Writers update them in bytes 16..39 when the ring buffer is full.
+// They are dropped_packets, stalls and stall_time_ms.
+// The service reads them only to report them in TraceStats.
+// No writer or reader decision depends on their values.
+//
+// Bytes 40..63 are reserved and pad the header to one cache line.
 //
 static_assert(sizeof(std::atomic<uint32_t>) == 4 &&
                   alignof(std::atomic<uint32_t>) <= 4,
@@ -139,11 +152,18 @@
 struct alignas(64) RingBufferHeader {
   std::atomic<uint64_t> rw_positions;
   std::atomic<uint32_t> num_writers_waiting;
-  uint8_t reserved[52];
+  uint8_t padding[4];
+  std::atomic<uint64_t> dropped_packets;
+  std::atomic<uint64_t> stalls;
+  std::atomic<uint64_t> stall_time_ms;
+  uint8_t reserved[24];
 };
 
 static_assert(offsetof(RingBufferHeader, num_writers_waiting) == 8 &&
-                  offsetof(RingBufferHeader, reserved) == 12 &&
+                  offsetof(RingBufferHeader, dropped_packets) == 16 &&
+                  offsetof(RingBufferHeader, stalls) == 24 &&
+                  offsetof(RingBufferHeader, stall_time_ms) == 32 &&
+                  offsetof(RingBufferHeader, reserved) == 40 &&
                   sizeof(RingBufferHeader) == 64,
               "RingBufferHeader does not match the shared-memory ABI");
 
diff --git a/src/tracing/v2/shared_ring_buffer_reader.cc b/src/tracing/v2/shared_ring_buffer_reader.cc
index 3617ab9..2df9c20 100644
--- a/src/tracing/v2/shared_ring_buffer_reader.cc
+++ b/src/tracing/v2/shared_ring_buffer_reader.cc
@@ -217,7 +217,7 @@
       // kFlagDataLoss to the relocated fragment instead.
       if (status == CopiedChunkStatus::kNoFragments &&
           (copied_chunk_.payload_flags & kFlagDataLoss)) {
-        delegate_->OnDataLoss(copied_chunk_.writer_id);
+        return HandleCopiedChunk(CopiedChunkStatus::kDataLoss);
       }
       return HandleCopiedChunk(status);
     }
@@ -335,6 +335,7 @@
   switch (status) {
     case CopiedChunkStatus::kReady:
       ++stats_.chunks_read;
+      stats_.bytes_read += copied_payload_.size();
       delegate_->OnChunkRead(copied_chunk_);
       return ConsumeResult::kChunkRead;
     case CopiedChunkStatus::kMalformed:
@@ -346,6 +347,7 @@
       delegate_->OnDataLoss(copied_chunk_.writer_id);
       break;
     case CopiedChunkStatus::kDataLoss:
+      ++stats_.data_loss_chunks;
       delegate_->OnDataLoss(copied_chunk_.writer_id);
       break;
     case CopiedChunkStatus::kNoFragments:
diff --git a/src/tracing/v2/shared_ring_buffer_reader.h b/src/tracing/v2/shared_ring_buffer_reader.h
index fc054da..fd26b25 100644
--- a/src/tracing/v2/shared_ring_buffer_reader.h
+++ b/src/tracing/v2/shared_ring_buffer_reader.h
@@ -145,13 +145,17 @@
   bool has_protocol_error() const { return has_protocol_error_; }
   uint32_t read_pos() const { return read_pos_; }
 
-  // For diagnostics only. The protocol never reads these counters.
-  // TODO(sashwinbalaji): Wire these counters into service statistics.
+  // For diagnostics only. No writer or reader decision depends on them.
+  // The service reports them in ExperimentalTracingV2ProducerStats.
   struct Stats {
     uint64_t positions_skipped = 0;
     // Successful BeingWritten -> RewriteRequested transitions.
     uint64_t rewrite_requests = 0;
     uint64_t chunks_read = 0;
+    // Total fragment bytes of the chunks in |chunks_read|.
+    uint64_t bytes_read = 0;
+    // Chunks discarded because they carry kFlagDataLoss.
+    uint64_t data_loss_chunks = 0;
     uint64_t malformed_chunks = 0;
     uint64_t unsupported_format_chunks = 0;
   };
diff --git a/src/tracing/v2/shared_ring_buffer_reader_unittest.cc b/src/tracing/v2/shared_ring_buffer_reader_unittest.cc
index 5f4f9c4..a8937bf 100644
--- a/src/tracing/v2/shared_ring_buffer_reader_unittest.cc
+++ b/src/tracing/v2/shared_ring_buffer_reader_unittest.cc
@@ -115,6 +115,8 @@
   EXPECT_EQ(delegate.chunks[0].target_buffer, kBuffer);
   EXPECT_EQ(delegate.chunks[0].fragments,
             (std::vector<std::string>{"alpha", "beta"}));
+  EXPECT_EQ(reader.GetStats().chunks_read, 1u);
+  EXPECT_EQ(reader.GetStats().bytes_read, strlen("alpha") + strlen("beta"));
 
   // The chunk is now Free with the wrap count of its next position.
   EXPECT_EQ(ring->LoadChunkStateWordAcquire(ChunkIndex::FromIndex(0)),
@@ -947,6 +949,7 @@
     EXPECT_EQ(result.last_result, ConsumeResult::kPositionSkipped);
     EXPECT_TRUE(delegate.chunks.empty());
     EXPECT_EQ(delegate.writers_with_data_loss, std::vector<WriterID>{kWriterA});
+    EXPECT_EQ(reader.GetStats().data_loss_chunks, 1u);
 
     if (writer_is_appending) {
       const uint32_t word =
@@ -1025,6 +1028,8 @@
             ConsumeResult::kPositionSkipped);
   EXPECT_TRUE(delegate.chunks.empty());
   EXPECT_EQ(delegate.writers_with_data_loss, (std::vector<WriterID>{kWriterA}));
+  EXPECT_EQ(reader.GetStats().data_loss_chunks, 1u);
+  EXPECT_EQ(reader.GetStats().positions_skipped, 1u);
   EXPECT_EQ(ring->LoadChunkStateWordAcquire(ChunkIndex::FromIndex(0)),
             MakeFreeStateWord(1));
 
diff --git a/src/tracing/v2/trace_writer_v2_impl.cc b/src/tracing/v2/trace_writer_v2_impl.cc
index 127a8c2..88fe32f 100644
--- a/src/tracing/v2/trace_writer_v2_impl.cc
+++ b/src/tracing/v2/trace_writer_v2_impl.cc
@@ -142,6 +142,7 @@
   // reservations.
   ring_buffer_writer_.FinishCurrentChunk();
   stream_writer_.Reset({nullptr, nullptr});
+  ReportDroppedPackets();
   ring_buffer_arbiter_->Flush(std::move(callback));
 }
 
@@ -194,7 +195,10 @@
         kMinFragmentPayloadSize, continues_from_prev);
     if (range.result == SharedRingBufferWriter::BeginFragmentResult::kSuccess) {
       fragment_begin_ = range.begin;
-      in_drop_mode_ = false;
+      if (PERFETTO_UNLIKELY(in_drop_mode_)) {
+        in_drop_mode_ = false;
+        ReportDroppedPackets();
+      }
       return {range.begin, range.end};
     }
     // Every valid chunk size holds kMinFragmentPayloadSize.
@@ -282,8 +286,9 @@
   // Without an attached reader, nothing frees space. So drop, also under
   // kStall. A wait would only end at the deadline, where kStall crashes.
   uint32_t time_left_ms = 0;
+  base::TimeMillis now{};
   if (can_stall && ring_buffer_arbiter_->IsReaderAttached()) {
-    const base::TimeMillis now = get_time_ms_();
+    now = get_time_ms_();
     if (!stall_deadline->has_value())
       *stall_deadline = now + base::TimeMillis(kStallTimeoutMs);
     const base::TimeMillis deadline = **stall_deadline;
@@ -325,11 +330,18 @@
   // measured before the request above. So the wait can end slightly after the
   // deadline. The next check then drops or aborts.
   ring_buffer_writer_.WaitForReadPosChange(std::min(kMaxWaitMs, time_left_ms));
+
+  // |now| is from before the drain request, so this counts the whole time
+  // that the thread was blocked.
+  ring_buffer_arbiter_->ring_buffer()->AddStall(
+      static_cast<uint64_t>((get_time_ms_() - now).count()));
   return true;
 }
 
 void TraceWriterV2Impl::EnterDropMode() {
   fragment_begin_ = nullptr;
+  // Every dropped packet gets here once.
+  ++unreported_dropped_packets_;
   // Consecutive dropped packets count as one drop.
   if (in_drop_mode_)
     return;
@@ -338,6 +350,14 @@
   ring_buffer_writer_.RecordDataLoss();
 }
 
+void TraceWriterV2Impl::ReportDroppedPackets() {
+  if (unreported_dropped_packets_ == 0)
+    return;
+  ring_buffer_arbiter_->ring_buffer()->AddDroppedPackets(
+      unreported_dropped_packets_);
+  unreported_dropped_packets_ = 0;
+}
+
 protozero::ContiguousMemoryRange TraceWriterV2Impl::GetDropBuffer() {
   PERFETTO_DCHECK(in_drop_mode_);
   PERFETTO_ANNOTATE_BENIGN_RACE_SIZED(&g_drop_buffer, sizeof(g_drop_buffer),
diff --git a/src/tracing/v2/trace_writer_v2_impl.h b/src/tracing/v2/trace_writer_v2_impl.h
index 1731ce1..156df27 100644
--- a/src/tracing/v2/trace_writer_v2_impl.h
+++ b/src/tracing/v2/trace_writer_v2_impl.h
@@ -206,11 +206,16 @@
 
   // Drops the rest of the open packet: its bytes go to GetDropBuffer() from now
   // on.
+  // - Counts the packet in |unreported_dropped_packets_|.
   // - If drop mode is not active yet, counts one drop and records the loss
   //   for the next publication.
   // - Drop mode lasts until a later packet gets a fragment in the ring buffer.
   void EnterDropMode();
 
+  // Adds |unreported_dropped_packets_| to the ring buffer header.
+  // Does nothing if there are none.
+  void ReportDroppedPackets();
+
   // Returns the process-wide drop buffer as a writable range. Only in drop
   // mode.
   protozero::ContiguousMemoryRange GetDropBuffer();
@@ -266,6 +271,12 @@
   // Number of times this writer entered drop mode. Consecutive dropped
   // packets count once, as in TraceWriterImpl.
   uint64_t drop_count_ = 0;
+
+  // Dropped packets that are not in the ring buffer header yet which the
+  // service reads for TraceStats.
+  // We add the count when the writer leaves drop mode and on Flush() as all
+  // writers share the header's cache line, so we don't add each drop.
+  uint32_t unreported_dropped_packets_ = 0;
 };
 
 }  // namespace perfetto::tracing_v2
diff --git a/src/tracing/v2/trace_writer_v2_impl_unittest.cc b/src/tracing/v2/trace_writer_v2_impl_unittest.cc
index a65520a..c1a16c5 100644
--- a/src/tracing/v2/trace_writer_v2_impl_unittest.cc
+++ b/src/tracing/v2/trace_writer_v2_impl_unittest.cc
@@ -541,6 +541,12 @@
 
   EXPECT_EQ(writer->drop_count(), 1u);
   EXPECT_EQ(num_drain_requests_, 3u);
+
+  // The header has each wait and its fake time.
+  const SharedRingBuffer::RingBufferFullStats stats =
+      reader_ring_buffer_->LoadRingBufferFullStatsRelaxed();
+  EXPECT_EQ(stats.stalls, 3u);
+  EXPECT_EQ(stats.stall_time_ms, static_cast<uint64_t>(kStallTimeout.count()));
 }
 
 // The same holds for the replacement acquisition of a relocation.
@@ -733,6 +739,11 @@
     if (read.packet.for_testing().str() == "recovered")
       EXPECT_NE(read.previous_dropped, 0u);
   }
+
+  // The writer counted the packet that it dropped.
+  const SharedRingBuffer::RingBufferFullStats full =
+      reader_ring_buffer_->LoadRingBufferFullStatsRelaxed();
+  EXPECT_EQ(full.dropped_packets, 1u);
 }
 
 // --- Counters ---
@@ -765,6 +776,44 @@
   EXPECT_EQ(writer->drop_count(), 2u);
 }
 
+// The writer adds dropped packets to the ring buffer header when it flushes or
+// stops dropping, so a writer that drops every packet does not write to the
+// shared header each time.
+TEST_F(TraceWriterV2ImplTest, DroppedPacketsReachRingBufferHeader) {
+  // Without a reader nothing frees space, so kDrop does not wait.
+  CreateRingBufferArbiter(/*num_chunks=*/4);
+  auto writer = CreateWriter(BufferExhaustedPolicy::kDrop);
+  auto dropped_packets_in_header = [this] {
+    return reader_ring_buffer_->LoadRingBufferFullStatsRelaxed()
+        .dropped_packets;
+  };
+  // Each 200-byte packet needs its own chunk.
+  const std::string payload(200, 'd');
+  for (int i = 0; i < 4; ++i)
+    WritePacket(writer.get(), payload);
+  ASSERT_EQ(writer->drop_count(), 0u);
+
+  // The ring buffer is full, so every packet is dropped. The header does not
+  // have them yet.
+  for (int i = 0; i < 5; ++i)
+    WritePacket(writer.get(), payload);
+  EXPECT_EQ(dropped_packets_in_header(), 0u);
+
+  // Flush() adds them.
+  writer->Flush();
+  EXPECT_EQ(dropped_packets_in_header(), 5u);
+
+  // So does the next packet that fits, which ends the drop.
+  for (int i = 0; i < 2; ++i)
+    WritePacket(writer.get(), payload);
+  AttachReader();
+  Drain();
+  WritePacket(writer.get(), "fits");
+  EXPECT_EQ(dropped_packets_in_header(), 7u);
+  // All these packets are one drop for drop_count().
+  EXPECT_EQ(writer->drop_count(), 1u);
+}
+
 // written() counts the packet bytes in all fragments. It does not count
 // chunk headers or size entries.
 TEST_F(TraceWriterV2ImplTest, WrittenCountsPacketBytes) {
diff --git a/test/trace_processor/diff_tests/include_index.py b/test/trace_processor/diff_tests/include_index.py
index ad86ec7..f9aa447 100644
--- a/test/trace_processor/diff_tests/include_index.py
+++ b/test/trace_processor/diff_tests/include_index.py
@@ -163,7 +163,6 @@
 from diff_tests.stdlib.graphs.scan_tests import GraphScanTests
 from diff_tests.stdlib.graphs.search_tests import GraphSearchTests
 from diff_tests.stdlib.intervals.create_intervals_tests import CreateIntervals
-from diff_tests.stdlib.intervals.fill_gaps_tests import IntervalsFillGaps
 from diff_tests.stdlib.intervals.intersect_duration_tests import IntervalsIntersectDurations
 from diff_tests.stdlib.intervals.intersect_tests import IntervalsIntersect
 from diff_tests.stdlib.intervals.tests import StdlibIntervals
@@ -386,7 +385,6 @@
       SpanJoinSmoke,
       Stacks,
       CreateIntervals,
-      IntervalsFillGaps,
       IntervalsIntersect,
       IntervalsIntersectDurations,
       StdlibIntervals,
diff --git a/test/trace_processor/diff_tests/parser/android/android_process_state.textproto b/test/trace_processor/diff_tests/parser/android/android_process_state.textproto
index 3b71640..328a19c 100644
--- a/test/trace_processor/diff_tests/parser/android/android_process_state.textproto
+++ b/test/trace_processor/diff_tests/parser/android/android_process_state.textproto
@@ -12,6 +12,7 @@
     processes { pid: 500 ppid: 1 cmdline: "proc500" }
     processes { pid: 600 ppid: 1 cmdline: "proc600" }
     processes { pid: 700 ppid: 1 cmdline: "proc700" }
+    processes { pid: 800 ppid: 1 cmdline: "proc800" }
   }
 }
 packet {
@@ -220,7 +221,7 @@
     }
   }
 }
-# Trace-stop dump for freezer state (contains pid 100, pid 600, pid 700, and unknown pid 999).
+# Trace-stop dump for freezer state (contains pid 100, pid 600, pid 700, pid 800, and unknown pid 999).
 # PID 600 tests dump-only freezer records.
 packet {
   timestamp: 10000
@@ -229,20 +230,25 @@
       pid: 100
       uid: 10001
       unfrozen_dur_ms: 500
-      frozen_dur_ms: 1200
       unfreeze_reason: UFR_ACTIVITY
     }
     record {
       pid: 600
       uid: 10006
       unfrozen_dur_ms: 50
-      frozen_dur_ms: 600
       unfreeze_reason: UFR_PING
     }
-    # PID 700: Dump-only freezer record with omitted unfreeze_reason (testing 0/UFR_NONE fallback).
+    # PID 700: Unfrozen dump-only freezer record with omitted unfreeze_reason (testing 0/UFR_NONE fallback).
     record {
       pid: 700
       uid: 10007
+      unfrozen_dur_ms: 50
+    }
+    # PID 800: Frozen dump-only freezer record (has_unfrozen_dur_ms is false, so unfreeze_reason is NULL).
+    record {
+      pid: 800
+      uid: 10008
+      frozen_dur_ms: 600
     }
     # PID 999: Unknown process (not in process_tree), should be skipped.
     record {
diff --git a/test/trace_processor/diff_tests/parser/android/android_process_state_metadata.textproto b/test/trace_processor/diff_tests/parser/android/android_process_state_metadata.textproto
index 1dfe294..7859387 100644
--- a/test/trace_processor/diff_tests/parser/android/android_process_state_metadata.textproto
+++ b/test/trace_processor/diff_tests/parser/android/android_process_state_metadata.textproto
@@ -192,6 +192,7 @@
   [com.android.internal.FrameworksBaseTracePacket.android_freezer_state] {
     record {
       pid: 200
+      unfrozen_dur_ms: 50
       unfreeze_reason: UFR_PING
     }
   }
diff --git a/test/trace_processor/diff_tests/parser/android/tests.py b/test/trace_processor/diff_tests/parser/android/tests.py
index 632d20f..e30d393 100644
--- a/test/trace_processor/diff_tests/parser/android/tests.py
+++ b/test/trace_processor/diff_tests/parser/android/tests.py
@@ -450,6 +450,7 @@
           3000,200,100,300,"UFR_BIND_SERVICE",0
           "[NULL]",600,"[NULL]","[NULL]","UFR_PING",1
           "[NULL]",700,"[NULL]","[NULL]","UFR_NONE",1
+          "[NULL]",800,"[NULL]","[NULL]","[NULL]",1
         """))
 
   def test_android_process_state_metadata(self):
diff --git a/test/trace_processor/diff_tests/parser/track_event/tests.py b/test/trace_processor/diff_tests/parser/track_event/tests.py
index 8ca8356..cc892ce 100644
--- a/test/trace_processor/diff_tests/parser/track_event/tests.py
+++ b/test/trace_processor/diff_tests/parser/track_event/tests.py
@@ -1583,3 +1583,981 @@
         "slice_count","slice_name","slice_ts","errors"
         1,"good",1000000,1
         """))
+
+  # Producer-declared custom dimensions (TrackDescriptor.dimensions) and the
+  # well known dimensions synthesized by trace processor.
+  def test_track_event_dimensions(self):
+    return DiffTestBlueprint(
+        trace=Path('track_event_dimensions.textproto'),
+        query="""
+        SELECT
+          extract_arg(t.dimension_arg_set_id, 'track_uuid') AS track_uuid,
+          t.name AS track_name,
+          d.name,
+          d.int_value,
+          d.string_value,
+          d.display_name
+        FROM track_dimension AS d
+        JOIN track AS t ON t.id = d.track_id
+        WHERE d.is_well_known = 0
+        ORDER BY track_uuid, d.name;
+        """,
+        out=Csv("""
+        "track_uuid","track_name","name","int_value","string_value","display_name"
+        10,"[NULL]","rank",3,"[NULL]","[NULL]"
+        10,"[NULL]","stage","[NULL]","forward","[NULL]"
+        11,"async","rank",3,"[NULL]","[NULL]"
+        11,"async","stage","[NULL]","forward","[NULL]"
+        20,"[NULL]","rank",7,"[NULL]","worker-east"
+        21,"child","rank",7,"[NULL]","worker-east"
+        30,"[NULL]","chrome.process_label","[NULL]","IMDb: Ratings, Reviews","IMDb: Ratings, Reviews"
+        30,"[NULL]","chrome.process_label2","[NULL]","Subframe: https://prebid.a-mo.net/","Subframe: https://prebid.a-mo.net/"
+        """))
+
+  # Dimensions are a query axis: slices can be filtered/grouped by the
+  # dimensions of the track they are on, whatever the track type.
+  def test_track_event_dimensions_slice_join(self):
+    return DiffTestBlueprint(
+        trace=Path('track_event_dimensions.textproto'),
+        query="""
+        SELECT
+          s.name AS slice,
+          d.name AS dimension,
+          d.int_value,
+          d.string_value
+        FROM slice AS s
+        JOIN track_dimension AS d USING (track_id)
+        WHERE d.is_well_known = 0
+        ORDER BY s.ts, d.name;
+        """,
+        out=Csv("""
+        "slice","dimension","int_value","string_value"
+        "work","rank",3,"[NULL]"
+        "work","stage","[NULL]","forward"
+        "other","rank",7,"[NULL]"
+        "frame","chrome.process_label","[NULL]","IMDb: Ratings, Reviews"
+        "frame","chrome.process_label2","[NULL]","Subframe: https://prebid.a-mo.net/"
+        """))
+
+  # Invalid dimension declarations are dropped and reported as stats: a child
+  # cannot override an inherited value, cannot use a reserved well known name
+  # and must provide a value.
+  def test_track_event_dimensions_invalid(self):
+    return DiffTestBlueprint(
+        trace=Path('track_event_dimensions.textproto'),
+        query="""
+        SELECT name, value
+        FROM stats
+        WHERE name IN (
+          'track_descriptor_invalid_dimension',
+          'track_descriptor_reserved_dimension_name',
+          'track_dimension_conflicting_value')
+          AND value > 0
+        ORDER BY name;
+        """,
+        out=Csv("""
+        "name","value"
+        "track_descriptor_invalid_dimension",1
+        "track_descriptor_reserved_dimension_name",1
+        "track_dimension_conflicting_value",1
+        """))
+
+  # Producers re-emit their descriptors, e.g. on every incremental state
+  # clear: the errors of their dimensions are only recorded once per
+  # descriptor.
+  def test_track_event_dimensions_errors_once(self):
+    return DiffTestBlueprint(
+        trace=TextProto(r"""
+        packet {
+          trusted_packet_sequence_id: 1
+          timestamp: 0
+          incremental_state_cleared: true
+          track_descriptor {
+            uuid: 1
+            name: "bad"
+            dimensions { name: "cpu" int_value: 1 }
+            dimensions { name: "shard" }
+            dimensions { name: "rank" int_value: 1 }
+            dimensions { name: "rank" int_value: 2 }
+          }
+        }
+        packet {
+          trusted_packet_sequence_id: 1
+          timestamp: 10
+          incremental_state_cleared: true
+          track_descriptor {
+            uuid: 1
+            name: "bad"
+            dimensions { name: "cpu" int_value: 1 }
+            dimensions { name: "shard" }
+            dimensions { name: "rank" int_value: 1 }
+            dimensions { name: "rank" int_value: 2 }
+          }
+        }
+        packet {
+          trusted_packet_sequence_id: 1
+          timestamp: 20
+          incremental_state_cleared: true
+          track_descriptor {
+            uuid: 1
+            name: "bad"
+            dimensions { name: "cpu" int_value: 1 }
+            dimensions { name: "shard" }
+            dimensions { name: "rank" int_value: 1 }
+            dimensions { name: "rank" int_value: 2 }
+          }
+        }
+        packet { trusted_packet_sequence_id: 1 timestamp: 100
+          track_event { track_uuid: 1 type: TYPE_INSTANT name: "a" } }
+        """),
+        query="""
+        SELECT name, value
+        FROM stats
+        WHERE name IN (
+          'track_descriptor_conflicting_reservation',
+          'track_descriptor_invalid_dimension',
+          'track_descriptor_reserved_dimension_name',
+          'track_dimension_conflicting_value')
+        ORDER BY name;
+        """,
+        out=Csv("""
+        "name","value"
+        "track_descriptor_conflicting_reservation",0
+        "track_descriptor_invalid_dimension",1
+        "track_descriptor_reserved_dimension_name",1
+        "track_dimension_conflicting_value",1
+        """))
+
+  # A global track only gets the dimensions declared on itself or an explicit
+  # parent_uuid ancestor, plus synthesized well known ones. It must not pick up
+  # dimensions from unrelated trees or processes.
+  def test_track_event_dimensions_global_tracks(self):
+    return DiffTestBlueprint(
+        trace=TextProto(r"""
+        packet {
+          trusted_packet_sequence_id: 1
+          timestamp: 0
+          incremental_state_cleared: true
+          track_descriptor {
+            uuid: 1
+            name: "global parent"
+            sibling_merge_behavior: SIBLING_MERGE_BEHAVIOR_NONE
+            dimensions { name: "shard" int_value: 1 }
+          }
+        }
+        packet {
+          trusted_packet_sequence_id: 1
+          timestamp: 0
+          track_descriptor {
+            uuid: 2
+            parent_uuid: 1
+            name: "global child"
+            sibling_merge_behavior: SIBLING_MERGE_BEHAVIOR_NONE
+          }
+        }
+        packet {
+          trusted_packet_sequence_id: 1
+          timestamp: 0
+          track_descriptor {
+            uuid: 3
+            name: "unrelated global"
+            sibling_merge_behavior: SIBLING_MERGE_BEHAVIOR_NONE
+          }
+        }
+        packet {
+          trusted_packet_sequence_id: 1
+          timestamp: 0
+          track_descriptor {
+            uuid: 4
+            process { pid: 100 process_name: "p" }
+            dimensions { name: "rank" int_value: 9 }
+          }
+        }
+        packet { trusted_packet_sequence_id: 1 timestamp: 100
+          track_event { track_uuid: 1 type: TYPE_INSTANT name: "a" } }
+        packet { trusted_packet_sequence_id: 1 timestamp: 100
+          track_event { track_uuid: 2 type: TYPE_INSTANT name: "b" } }
+        packet { trusted_packet_sequence_id: 1 timestamp: 100
+          track_event { track_uuid: 3 type: TYPE_INSTANT name: "c" } }
+        packet { trusted_packet_sequence_id: 1 timestamp: 100
+          track_event { track_uuid: 4 type: TYPE_INSTANT name: "d" } }
+        """),
+        query="""
+        SELECT
+          t.name AS track,
+          (
+            SELECT group_concat(n, ',')
+            FROM (
+              SELECT
+                CASE
+                  WHEN d.is_well_known THEN d.name
+                  ELSE d.name || '=' || coalesce(d.int_value, d.string_value)
+                END AS n
+              FROM track_dimension AS d
+              WHERE d.track_id = t.id
+              ORDER BY d.name
+            )
+          ) AS dimensions
+        FROM track AS t
+        ORDER BY t.name;
+        """,
+        out=Csv("""
+        "track","dimensions"
+        "[NULL]","machine,process,rank=9"
+        "global child","machine,shard=1"
+        "global parent","machine,shard=1"
+        "unrelated global","machine"
+        """))
+
+  # Well known dimensions are synthesized by trace processor from existing
+  # columns rather than declared by producers.
+  def test_track_event_dimensions_well_known(self):
+    return DiffTestBlueprint(
+        trace=Path('track_event_dimensions.textproto'),
+        query="""
+        SELECT DISTINCT name
+        FROM track_dimension
+        WHERE is_well_known = 1
+        ORDER BY name;
+        """,
+        out=Csv("""
+        "name"
+        "machine"
+        "process"
+        "thread"
+        """))
+
+  # Dimensions are part of the track identity: a re-emitted descriptor with
+  # different dimensions (including a first descriptor without any) is a
+  # conflicting reservation and the first descriptor is kept. Order and display
+  # names don't matter.
+  def test_track_event_dimensions_identity_reservation(self):
+    return DiffTestBlueprint(
+        trace=Path('track_event_dimensions_identity.textproto'),
+        query="""
+        SELECT
+          s.name AS slice,
+          (
+            SELECT group_concat(d.name || '=' || coalesce(d.int_value, d.string_value), ',')
+            FROM (
+              SELECT * FROM track_dimension
+              WHERE track_id = s.track_id AND is_well_known = 0
+              ORDER BY name
+            ) AS d
+          ) AS dimensions,
+          (
+            SELECT value FROM stats
+            WHERE name = 'track_descriptor_conflicting_reservation'
+          ) AS conflicts
+        FROM slice AS s
+        WHERE s.name IN ('g1_event', 'g2_event')
+        ORDER BY s.name;
+        """,
+        out=Csv("""
+        "slice","dimensions","conflicts"
+        "g1_event","rank=1,stage=fwd",2
+        "g2_event","[NULL]",2
+        """))
+
+  # The declared dimensions are normalized: sorted by name and without repeated
+  # names, a name declared twice keeping its first value. Re-emitting the same
+  # dimensions in another order or with a repeated name is the same identity.
+  def test_track_event_dimensions_normalized(self):
+    return DiffTestBlueprint(
+        trace=TextProto(r"""
+        packet {
+          trusted_packet_sequence_id: 1
+          timestamp: 0
+          incremental_state_cleared: true
+          track_descriptor {
+            uuid: 1
+            name: "repeated"
+            sibling_merge_behavior: SIBLING_MERGE_BEHAVIOR_NONE
+            dimensions { name: "rank" int_value: 1 }
+            dimensions { name: "stage" string_value: "fwd" }
+            dimensions { name: "rank" int_value: 1 }
+          }
+        }
+        packet {
+          trusted_packet_sequence_id: 1
+          timestamp: 0
+          track_descriptor {
+            uuid: 1
+            name: "repeated"
+            sibling_merge_behavior: SIBLING_MERGE_BEHAVIOR_NONE
+            dimensions { name: "stage" string_value: "fwd" }
+            dimensions { name: "rank" int_value: 1 }
+          }
+        }
+        packet {
+          trusted_packet_sequence_id: 1
+          timestamp: 0
+          track_descriptor {
+            uuid: 2
+            name: "conflicting"
+            sibling_merge_behavior: SIBLING_MERGE_BEHAVIOR_NONE
+            dimensions { name: "shard" int_value: 1 }
+            dimensions { name: "shard" int_value: 2 }
+          }
+        }
+        packet { trusted_packet_sequence_id: 1 timestamp: 100
+          track_event { track_uuid: 1 type: TYPE_INSTANT name: "on_repeated" } }
+        packet { trusted_packet_sequence_id: 1 timestamp: 200
+          track_event { track_uuid: 2 type: TYPE_INSTANT name: "on_conflicting" } }
+        """),
+        query="""
+        SELECT
+          'slice' AS kind,
+          s.name,
+          (
+            SELECT group_concat(d.name || '=' || coalesce(d.int_value, d.string_value), ',')
+            FROM (
+              SELECT * FROM track_dimension
+              WHERE track_id = s.track_id AND NOT is_well_known
+              ORDER BY name
+            ) AS d
+          ) AS value
+        FROM slice AS s
+        UNION ALL
+        SELECT 'stat' AS kind, name, value
+        FROM stats
+        WHERE name IN (
+          'track_descriptor_conflicting_reservation',
+          'track_dimension_conflicting_value')
+        ORDER BY kind, name;
+        """,
+        out=Csv("""
+        "kind","name","value"
+        "slice","on_conflicting","shard=1"
+        "slice","on_repeated","rank=1,stage=fwd"
+        "stat","track_descriptor_conflicting_reservation",0
+        "stat","track_dimension_conflicting_value",1
+        """))
+
+  # Dimensions are part of the sibling merge key: siblings are only merged if
+  # they declare the same dimensions.
+  def test_track_event_dimensions_identity_merging(self):
+    return DiffTestBlueprint(
+        trace=Path('track_event_dimensions_identity.textproto'),
+        query="""
+        SELECT
+          s.name AS slice,
+          dense_rank() OVER (
+            ORDER BY (SELECT min(ts) FROM slice WHERE track_id = s.track_id)
+          ) AS track_idx,
+          (
+            SELECT int_value FROM track_dimension
+            WHERE track_id = s.track_id AND name = 'rank'
+          ) AS rank
+        FROM slice AS s
+        JOIN track AS t ON t.id = s.track_id
+        WHERE t.name = 'step'
+        ORDER BY s.ts;
+        """,
+        out=Csv("""
+        "slice","track_idx","rank"
+        "rank1_a",1,1
+        "rank2",2,2
+        "rank1_b",1,1
+        "no_rank",3,"[NULL]"
+        """))
+
+  # Siblings are merged on their effective dimensions, inherited ones
+  # included: a sibling redundantly declaring the rank of its parent is merged
+  # with one which only inherits it, but not with one which has another
+  # dimension.
+  def test_track_event_dimensions_merge_effective(self):
+    return DiffTestBlueprint(
+        trace=TextProto(r"""
+        packet {
+          trusted_packet_sequence_id: 1
+          timestamp: 0
+          incremental_state_cleared: true
+          track_descriptor {
+            uuid: 10
+            process { pid: 100 process_name: "trainer" }
+            dimensions { name: "rank" int_value: 1 }
+          }
+        }
+        packet {
+          trusted_packet_sequence_id: 1
+          timestamp: 0
+          track_descriptor {
+            uuid: 11
+            parent_uuid: 10
+            name: "step"
+            dimensions { name: "rank" int_value: 1 }
+          }
+        }
+        packet {
+          trusted_packet_sequence_id: 1
+          timestamp: 0
+          track_descriptor { uuid: 12 parent_uuid: 10 name: "step" }
+        }
+        packet {
+          trusted_packet_sequence_id: 1
+          timestamp: 0
+          track_descriptor {
+            uuid: 13
+            parent_uuid: 10
+            name: "step"
+            dimensions { name: "stage" string_value: "fwd" }
+          }
+        }
+        packet { trusted_packet_sequence_id: 1 timestamp: 100
+          track_event { track_uuid: 11 type: TYPE_INSTANT name: "redundant" } }
+        packet { trusted_packet_sequence_id: 1 timestamp: 200
+          track_event { track_uuid: 12 type: TYPE_INSTANT name: "inherited" } }
+        packet { trusted_packet_sequence_id: 1 timestamp: 300
+          track_event { track_uuid: 13 type: TYPE_INSTANT name: "other" } }
+        """),
+        query="""
+        SELECT
+          s.name AS slice,
+          dense_rank() OVER (
+            ORDER BY (SELECT min(ts) FROM slice WHERE track_id = s.track_id)
+          ) AS track_idx,
+          (
+            SELECT group_concat(d.name || '=' || coalesce(d.int_value, d.string_value), ',')
+            FROM (
+              SELECT * FROM track_dimension
+              WHERE track_id = s.track_id AND NOT is_well_known
+              ORDER BY name
+            ) AS d
+          ) AS dimensions
+        FROM slice AS s
+        ORDER BY s.ts;
+        """,
+        out=Csv("""
+        "slice","track_idx","dimensions"
+        "redundant",1,"rank=1"
+        "inherited",1,"rank=1"
+        "other",2,"rank=1,stage=fwd"
+        """))
+
+  # Dimension names, string values and display names can be interned with
+  # `name_iid` / `string_value_iid` / `display_name_iid`. The resolved strings
+  # are the name and value: they are the same identity (and merge key) as
+  # inline strings with the same contents. A descriptor with a name or value
+  # iid without interned data is ignored, so that a re-emission with the
+  # interned data (e.g. after the original was lost) is still accepted. A
+  # display name iid without interned data only drops the display name.
+  def test_track_event_dimensions_interned_string_value(self):
+    return DiffTestBlueprint(
+        trace=TextProto(r"""
+        packet {
+          trusted_packet_sequence_id: 1
+          timestamp: 0
+          incremental_state_cleared: true
+          sequence_flags: 2
+          interned_data {
+            track_dimension_strings { iid: 1 str: "fwd" }
+            track_dimension_strings { iid: 2 str: "forward pass" }
+            track_dimension_strings { iid: 3 str: "stage" }
+          }
+          track_descriptor {
+            uuid: 10
+            process { pid: 100 process_name: "trainer" }
+          }
+        }
+        packet {
+          trusted_packet_sequence_id: 1
+          timestamp: 0
+          sequence_flags: 2
+          track_descriptor {
+            uuid: 11
+            parent_uuid: 10
+            name: "step"
+            dimensions {
+              name: "stage" string_value_iid: 1 display_name_iid: 2
+            }
+          }
+        }
+        packet {
+          trusted_packet_sequence_id: 1
+          timestamp: 0
+          sequence_flags: 2
+          track_descriptor {
+            uuid: 12
+            parent_uuid: 10
+            name: "step"
+            dimensions { name: "stage" string_value: "fwd" }
+          }
+        }
+        packet {
+          trusted_packet_sequence_id: 1
+          timestamp: 0
+          sequence_flags: 2
+          track_descriptor {
+            uuid: 13
+            parent_uuid: 10
+            name: "step"
+            dimensions { name: "stage" string_value_iid: 99 }
+          }
+        }
+        packet {
+          trusted_packet_sequence_id: 1
+          timestamp: 0
+          sequence_flags: 2
+          track_descriptor {
+            uuid: 14
+            parent_uuid: 10
+            name: "other"
+            dimensions {
+              name: "stage" string_value: "bwd" display_name_iid: 98
+            }
+          }
+        }
+        packet {
+          trusted_packet_sequence_id: 1
+          timestamp: 0
+          sequence_flags: 2
+          track_descriptor {
+            uuid: 15
+            parent_uuid: 10
+            name: "step"
+            dimensions { name_iid: 3 string_value_iid: 1 }
+          }
+        }
+        packet {
+          trusted_packet_sequence_id: 1
+          timestamp: 0
+          sequence_flags: 2
+          track_descriptor {
+            uuid: 16
+            parent_uuid: 10
+            name: "step"
+            dimensions { name_iid: 97 string_value: "fwd" }
+          }
+        }
+        packet {
+          trusted_packet_sequence_id: 2
+          timestamp: 0
+          incremental_state_cleared: true
+          sequence_flags: 2
+          interned_data {
+            track_dimension_strings { iid: 99 str: "fwd" }
+          }
+          track_descriptor {
+            uuid: 13
+            parent_uuid: 10
+            name: "step"
+            dimensions { name: "stage" string_value_iid: 99 }
+          }
+        }
+        packet { trusted_packet_sequence_id: 1 timestamp: 1000
+          track_event { track_uuid: 11 type: TYPE_INSTANT name: "interned" } }
+        packet { trusted_packet_sequence_id: 1 timestamp: 2000
+          track_event { track_uuid: 12 type: TYPE_INSTANT name: "inline" } }
+        packet { trusted_packet_sequence_id: 1 timestamp: 3000
+          track_event { track_uuid: 13 type: TYPE_INSTANT name: "reemitted" } }
+        packet { trusted_packet_sequence_id: 1 timestamp: 4000
+          track_event {
+            track_uuid: 14 type: TYPE_INSTANT name: "unknown_display_iid"
+          }
+        }
+        packet { trusted_packet_sequence_id: 1 timestamp: 5000
+          track_event { track_uuid: 15 type: TYPE_INSTANT name: "interned_name" } }
+        packet { trusted_packet_sequence_id: 1 timestamp: 6000
+          track_event {
+            track_uuid: 16 type: TYPE_INSTANT name: "unknown_name_iid"
+          }
+        }
+        """),
+        query="""
+        SELECT
+          s.name AS slice,
+          dense_rank() OVER (
+            ORDER BY (SELECT min(ts) FROM slice WHERE track_id = s.track_id)
+          ) AS track_idx,
+          (
+            SELECT string_value FROM track_dimension
+            WHERE track_id = s.track_id AND name = 'stage'
+          ) AS stage,
+          (
+            SELECT display_name FROM track_dimension
+            WHERE track_id = s.track_id AND name = 'stage'
+          ) AS stage_display_name,
+          (
+            SELECT value FROM stats
+            WHERE name = 'track_descriptor_invalid_dimension'
+          ) AS invalid
+        FROM slice AS s
+        ORDER BY s.ts;
+        """,
+        out=Csv("""
+        "slice","track_idx","stage","stage_display_name","invalid"
+        "interned",1,"fwd","forward pass",3
+        "inline",1,"fwd","forward pass",3
+        "reemitted",1,"fwd","forward pass",3
+        "unknown_display_iid",2,"bwd","[NULL]",3
+        "interned_name",1,"fwd","forward pass",3
+        "unknown_name_iid",3,"[NULL]","[NULL]",3
+        """))
+
+  # Dimensions only flow down parent_uuid: a process or thread track is just a
+  # track which may declare dimensions. The threads of a process only inherit
+  # its dimensions if their descriptors are parent_uuid children of the process
+  # track. A value conflicting with an inherited one, or a name declared twice
+  # with different values, is ignored and counted once per declaration, not
+  # once per track inheriting from it.
+  def test_track_event_dimensions_parent_uuid_only(self):
+    return DiffTestBlueprint(
+        trace=TextProto(r"""
+        packet {
+          trusted_packet_sequence_id: 1
+          timestamp: 0
+          incremental_state_cleared: true
+          track_descriptor {
+            uuid: 10
+            process { pid: 100 process_name: "trainer" }
+            dimensions { name: "rank" int_value: 3 }
+          }
+        }
+        packet {
+          trusted_packet_sequence_id: 1
+          timestamp: 0
+          track_descriptor {
+            uuid: 11
+            thread { pid: 100 tid: 101 thread_name: "standalone" }
+            dimensions { name: "stage" string_value: "fwd" }
+          }
+        }
+        packet {
+          trusted_packet_sequence_id: 1
+          timestamp: 0
+          track_descriptor {
+            uuid: 12
+            parent_uuid: 10
+            thread { pid: 100 tid: 102 thread_name: "nested" }
+          }
+        }
+        packet {
+          trusted_packet_sequence_id: 1
+          timestamp: 0
+          track_descriptor {
+            uuid: 13
+            parent_uuid: 12
+            name: "child"
+            sibling_merge_behavior: SIBLING_MERGE_BEHAVIOR_NONE
+            dimensions { name: "rank" int_value: 4 }
+            dimensions { name: "shard" int_value: 1 }
+            dimensions { name: "shard" int_value: 2 }
+          }
+        }
+        packet {
+          trusted_packet_sequence_id: 1
+          timestamp: 0
+          track_descriptor {
+            uuid: 14
+            parent_uuid: 13
+            name: "grandchild"
+            sibling_merge_behavior: SIBLING_MERGE_BEHAVIOR_NONE
+          }
+        }
+        packet {
+          trusted_packet_sequence_id: 1
+          timestamp: 0
+          track_descriptor {
+            uuid: 15
+            parent_uuid: 10
+            name: "async"
+            dimensions { name: "rank" int_value: 9 }
+          }
+        }
+        packet { trusted_packet_sequence_id: 1 timestamp: 1000
+          track_event { track_uuid: 11 type: TYPE_INSTANT name: "on_standalone" } }
+        packet { trusted_packet_sequence_id: 1 timestamp: 2000
+          track_event { track_uuid: 12 type: TYPE_INSTANT name: "on_nested" } }
+        packet { trusted_packet_sequence_id: 1 timestamp: 3000
+          track_event { track_uuid: 13 type: TYPE_INSTANT name: "on_child" } }
+        packet { trusted_packet_sequence_id: 1 timestamp: 3500
+          track_event { track_uuid: 14 type: TYPE_INSTANT name: "on_grandchild" } }
+        packet { trusted_packet_sequence_id: 1 timestamp: 4000
+          track_event { track_uuid: 15 type: TYPE_INSTANT name: "on_async" } }
+        """),
+        query="""
+        SELECT
+          'slice' AS kind,
+          s.name,
+          (
+            SELECT group_concat(d.name || '=' || coalesce(d.int_value, d.string_value), ',')
+            FROM (
+              SELECT * FROM track_dimension
+              WHERE track_id = s.track_id AND NOT is_well_known
+              ORDER BY name
+            ) AS d
+          ) AS value
+        FROM slice AS s
+        UNION ALL
+        SELECT 'error' AS kind, name, extract_arg(arg_set_id, 'track_uuid')
+        FROM _trace_import_logs
+        WHERE name = 'track_dimension_conflicting_value'
+        ORDER BY kind, name, value;
+        """,
+        out=Csv("""
+        "kind","name","value"
+        "error","track_dimension_conflicting_value",13
+        "error","track_dimension_conflicting_value",13
+        "error","track_dimension_conflicting_value",15
+        "slice","on_async","rank=3"
+        "slice","on_child","rank=3,shard=1"
+        "slice","on_grandchild","rank=3,shard=1"
+        "slice","on_nested","rank=3"
+        "slice","on_standalone","stage=fwd"
+        """))
+
+  # Two thread descriptors for the same tid don't share the thread track: the
+  # second one is a tid reuse and gets a thread of its own, so each track gets
+  # the dimensions of a single descriptor whatever the order they are parsed
+  # in.
+  def test_track_event_dimensions_same_tid(self):
+    return DiffTestBlueprint(
+        trace=TextProto(r"""
+        packet { trusted_packet_sequence_id: 1 timestamp: 100
+          incremental_state_cleared: true
+          track_descriptor { uuid: 20 thread { pid: 10 tid: 11 } } }
+        packet { trusted_packet_sequence_id: 2 timestamp: 100
+          incremental_state_cleared: true
+          track_descriptor { uuid: 21 thread { pid: 10 tid: 11 }
+            dimensions { name: "rank" int_value: 3 } } }
+        packet { trusted_packet_sequence_id: 1 timestamp: 200
+          track_event { track_uuid: 20 type: TYPE_INSTANT name: "without" } }
+        packet { trusted_packet_sequence_id: 2 timestamp: 300
+          track_event { track_uuid: 21 type: TYPE_INSTANT name: "with" } }
+        """),
+        query="""
+        SELECT
+          s.name AS slice,
+          t.tid,
+          (
+            SELECT group_concat(d.name || '=' || d.int_value, ',')
+            FROM track_dimension AS d
+            WHERE d.track_id = s.track_id AND NOT d.is_well_known
+          ) AS dimensions,
+          (SELECT count(DISTINCT utid) FROM thread WHERE tid = 11) AS threads
+        FROM slice AS s
+        JOIN thread_track AS tt ON tt.id = s.track_id
+        JOIN thread AS t USING (utid)
+        ORDER BY s.ts;
+        """,
+        out=Csv("""
+        "slice","tid","dimensions","threads"
+        "without",11,"[NULL]",2
+        "with",11,"rank=3",2
+        """))
+
+  # Writing dimensions as tracks are created doesn't depend on the order in
+  # which tracks and descriptors show up: a track gets the dimensions of its own
+  # descriptor and its parent_uuid ancestors, never the ones of descriptors it
+  # is only associated with through its process or thread.
+  def test_track_event_dimensions_order_independent(self):
+    return DiffTestBlueprint(
+        trace=TextProto(r"""
+        packet { trusted_packet_sequence_id: 1 timestamp: 100 sequence_flags: 1
+          track_descriptor { uuid: 20 thread { pid: 10 tid: 11 } } }
+        packet { trusted_packet_sequence_id: 1 timestamp: 200
+          track_event { track_uuid: 20 type: TYPE_SLICE_BEGIN name: "early" } }
+        packet { trusted_packet_sequence_id: 1 timestamp: 300
+          track_event { track_uuid: 20 type: TYPE_SLICE_END } }
+        packet { trusted_packet_sequence_id: 2 timestamp: 1000 sequence_flags: 1
+          track_descriptor { uuid: 10 process { pid: 10 }
+            dimensions { name: "rank" int_value: 3 } } }
+        packet { timestamp: 1400 process_stats { processes { pid: 10 rss_anon_kb: 100 } } }
+        packet { trusted_packet_sequence_id: 2 timestamp: 1500
+          track_event { track_uuid: 10 type: TYPE_INSTANT name: "late" } }
+        """),
+        query="""
+        SELECT
+          t.name,
+          t.type,
+          (
+            SELECT group_concat(d.name || '=' || coalesce(d.int_value, d.string_value), ',')
+            FROM (
+              SELECT * FROM track_dimension
+              WHERE track_id = t.id AND NOT is_well_known
+              ORDER BY name
+            ) AS d
+          ) AS dimensions
+        FROM track AS t
+        ORDER BY t.type;
+        """,
+        out=Csv("""
+        "name","type","dimensions"
+        "mem.rss.anon","process_memory","[NULL]"
+        "[NULL]","process_track_event","rank=3"
+        "[NULL]","thread_execution","[NULL]"
+        """))
+
+  # Well known dimensions are derived by trace processor for every track, not
+  # only track event ones. Tracks only associated with a thread have no
+  # `process` dimension. The `cpu` dimension is the machine aware `ucpu`, so
+  # CPU 1 of each machine is a different CPU.
+  def test_track_event_dimensions_well_known_all_tracks(self):
+    return DiffTestBlueprint(
+        trace=TextProto(r"""
+        packet {
+          ftrace_events {
+            cpu: 0
+            event {
+              timestamp: 1000
+              pid: 0
+              cpu_frequency { state: 1000000 cpu_id: 1 }
+            }
+          }
+        }
+        packet {
+          timestamp: 1500
+          generic_kernel_cpu_freq_event { cpu: 1 freq_hz: 2500000000 }
+          machine_id: 349028234
+        }
+        packet {
+          trusted_packet_sequence_id: 1
+          timestamp: 0
+          incremental_state_cleared: true
+          track_descriptor {
+            uuid: 11
+            thread { pid: 100 tid: 101 thread_name: "worker" }
+          }
+        }
+        packet { trusted_packet_sequence_id: 1 timestamp: 2000
+          track_event { track_uuid: 11 type: TYPE_INSTANT name: "tick" } }
+        """),
+        query="""
+        SELECT type, dimensions
+        FROM (
+          SELECT
+            t.type,
+            (
+              SELECT group_concat(n, ',')
+              FROM (
+                SELECT
+                  CASE d.name
+                    WHEN 'cpu' THEN 'cpu=' || (
+                      SELECT c.cpu || '@' || m.raw_id
+                      FROM cpu AS c
+                      JOIN machine AS m ON m.id = c.machine_id
+                      WHERE c.id = d.int_value
+                    )
+                    WHEN 'machine' THEN 'machine=' || (
+                      SELECT raw_id FROM machine WHERE id = d.int_value
+                    )
+                    ELSE d.name
+                  END AS n
+                FROM track_dimension AS d
+                WHERE d.track_id = t.id AND d.is_well_known
+                ORDER BY d.name
+              )
+            ) AS dimensions
+          FROM track AS t
+        )
+        ORDER BY type, dimensions;
+        """,
+        out=Csv("""
+        "type","dimensions"
+        "cpu_frequency","cpu=1@0,machine=0"
+        "cpu_frequency","cpu=1@349028234,machine=349028234"
+        "thread_execution","machine=0,thread"
+        """))
+
+  def test_track_event_dimensions_display_values(self):
+    return DiffTestBlueprint(
+        trace=TextProto(r"""
+        packet { timestamp: 0 gpu_counter_event {
+          gpu_id: 7
+          counter_descriptor { specs { counter_id: 1 name: "GPU Frequency" } }
+        } }
+        packet { timestamp: 100 machine_id: 349028234
+          generic_kernel_cpu_freq_event { cpu: 1 freq_hz: 2500000000 } }
+        packet { timestamp: 0 machine_id: 349028234
+          gpu_counter_event {
+            gpu_id: 0
+            counter_descriptor { specs { counter_id: 1 name: "GPU Frequency" } }
+          } }
+        packet { trusted_packet_sequence_id: 1 timestamp: 0
+          incremental_state_cleared: true machine_id: 349028234
+          track_descriptor { uuid: 10 process { pid: 100 process_name: "proc" } } }
+        packet { trusted_packet_sequence_id: 1 timestamp: 200 machine_id: 349028234
+          track_event { track_uuid: 10 type: TYPE_INSTANT name: "p" } }
+        packet { trusted_packet_sequence_id: 2 timestamp: 0
+          incremental_state_cleared: true machine_id: 349028234
+          track_descriptor { uuid: 11 thread { pid: 100 tid: 101 thread_name: "worker" } } }
+        packet { trusted_packet_sequence_id: 2 timestamp: 300 machine_id: 349028234
+          track_event { track_uuid: 11 type: TYPE_INSTANT name: "t" } }
+        packet { timestamp: 400 machine_id: 349028234
+          system_info { machine_name: "training-host" } }
+        packet { timestamp: 400 machine_id: 349028234
+          gpu_info { gpus { name: "training-gpu" } } }
+        """),
+        query="""
+        SELECT DISTINCT
+          d.name,
+          d.display_value,
+          d.display_name,
+          CASE d.name
+            WHEN 'cpu' THEN EXISTS(
+              SELECT 1 FROM cpu
+              WHERE id = d.int_value AND cast_string!(cpu) = d.display_value
+            )
+            WHEN 'gpu' THEN EXISTS(
+              SELECT 1 FROM gpu
+              WHERE id = d.int_value AND cast_string!(gpu) = d.display_value
+            )
+            WHEN 'process' THEN EXISTS(
+              SELECT 1 FROM process
+              WHERE upid = d.int_value AND cast_string!(pid) = d.display_value
+            )
+            WHEN 'thread' THEN EXISTS(
+              SELECT 1 FROM thread
+              WHERE utid = d.int_value AND cast_string!(tid) = d.display_value
+            )
+            WHEN 'machine' THEN EXISTS(
+              SELECT 1 FROM machine
+              WHERE id = d.int_value AND cast_string!(label_index) = d.display_value
+            )
+          END AS canonical_identity_valid
+        FROM track_dimension AS d
+        JOIN track AS t ON t.id = d.track_id
+        JOIN machine AS m ON m.id = t.machine_id
+        WHERE d.is_well_known AND m.raw_id = 349028234
+        ORDER BY d.name;
+        """,
+        out=Csv("""
+        "name","display_value","display_name","canonical_identity_valid"
+        "cpu","1","[NULL]",1
+        "gpu","0","training-gpu",1
+        "machine","1","training-host",1
+        "process","100","proc",1
+        "thread","101","worker",1
+        """))
+
+  def test_track_event_dimensions_custom_display_values(self):
+    return DiffTestBlueprint(
+        trace=TextProto(r"""
+        packet { trusted_packet_sequence_id: 1 timestamp: 0
+          incremental_state_cleared: true
+          track_descriptor {
+            uuid: 1
+            dimensions { name: "max" int_value: 9223372036854775807 display_name: "largest" }
+            dimensions { name: "min" int_value: -9223372036854775808 }
+            dimensions { name: "stage" string_value: "forward" display_name: "forward pass" }
+            dimensions { name: "empty" string_value: "" }
+            dimensions { name: "zero" int_value: 0 }
+          } }
+        packet { trusted_packet_sequence_id: 1 timestamp: 100
+          track_event { track_uuid: 1 type: TYPE_INSTANT name: "event" } }
+        """),
+        query="""
+        SELECT name, int_value, string_value, display_value, display_name
+        FROM track_dimension
+        WHERE NOT is_well_known
+        ORDER BY name;
+        """,
+        out=Csv("""
+        "name","int_value","string_value","display_value","display_name"
+        "empty","[NULL]","","","[NULL]"
+        "max",9223372036854775807,"[NULL]","9223372036854775807","largest"
+        "min",-9223372036854775808,"[NULL]","-9223372036854775808","[NULL]"
+        "stage","[NULL]","forward","forward","forward pass"
+        "zero",0,"[NULL]","0","[NULL]"
+        """))
diff --git a/test/trace_processor/diff_tests/parser/track_event/track_event_dimensions.textproto b/test/trace_processor/diff_tests/parser/track_event/track_event_dimensions.textproto
new file mode 100644
index 0000000..4169e10
--- /dev/null
+++ b/test/trace_processor/diff_tests/parser/track_event/track_event_dimensions.textproto
@@ -0,0 +1,158 @@
+# A distributed training-like trace: two processes of the same name which are
+# only distinguishable by the producer-declared `rank` dimension.
+packet {
+  trusted_packet_sequence_id: 1
+  timestamp: 0
+  incremental_state_cleared: true
+  track_descriptor {
+    uuid: 10
+    process {
+      pid: 100
+      process_name: "trainer"
+    }
+    dimensions {
+      name: "rank"
+      int_value: 3
+    }
+    dimensions {
+      name: "stage"
+      string_value: "forward"
+    }
+  }
+}
+# A child track of the process track: inherits both dimensions.
+packet {
+  trusted_packet_sequence_id: 1
+  timestamp: 0
+  track_descriptor {
+    uuid: 11
+    parent_uuid: 10
+    name: "async"
+    sibling_merge_behavior: SIBLING_MERGE_BEHAVIOR_NONE
+  }
+}
+# A thread of the process which isn't a parent_uuid child of the process track,
+# so it doesn't inherit its dimensions.
+packet {
+  trusted_packet_sequence_id: 1
+  timestamp: 0
+  track_descriptor {
+    uuid: 12
+    thread {
+      pid: 100
+      tid: 101
+      thread_name: "main"
+    }
+  }
+}
+# A second process with a different rank and a display name for it.
+packet {
+  trusted_packet_sequence_id: 2
+  timestamp: 0
+  incremental_state_cleared: true
+  track_descriptor {
+    uuid: 20
+    process {
+      pid: 200
+      process_name: "trainer"
+    }
+    dimensions {
+      name: "rank"
+      int_value: 7
+      display_name: "worker-east"
+    }
+  }
+}
+# Invalid producer input, all of which must be ignored:
+#  * a dimension which overrides an inherited value,
+#  * a dimension using a reserved well known name,
+#  * a dimension without a value.
+packet {
+  trusted_packet_sequence_id: 2
+  timestamp: 0
+  track_descriptor {
+    uuid: 21
+    parent_uuid: 20
+    name: "child"
+    sibling_merge_behavior: SIBLING_MERGE_BEHAVIOR_NONE
+    dimensions {
+      name: "rank"
+      int_value: 4
+    }
+    dimensions {
+      name: "machine"
+      int_value: 1
+    }
+    dimensions {
+      name: "shard"
+    }
+  }
+}
+# A Chrome-shaped process: several ordered labels, one dimension each, with a
+# display name so they render as bare titles.
+packet {
+  trusted_packet_sequence_id: 3
+  timestamp: 0
+  incremental_state_cleared: true
+  track_descriptor {
+    uuid: 30
+    process {
+      pid: 300
+      process_name: "Renderer"
+    }
+    dimensions {
+      name: "chrome.process_label"
+      string_value: "IMDb: Ratings, Reviews"
+      display_name: "IMDb: Ratings, Reviews"
+    }
+    dimensions {
+      name: "chrome.process_label2"
+      string_value: "Subframe: https://prebid.a-mo.net/"
+      display_name: "Subframe: https://prebid.a-mo.net/"
+    }
+  }
+}
+packet {
+  trusted_packet_sequence_id: 3
+  timestamp: 1300
+  track_event {
+    track_uuid: 30
+    type: TYPE_INSTANT
+    name: "frame"
+  }
+}
+packet {
+  trusted_packet_sequence_id: 1
+  timestamp: 1000
+  track_event {
+    track_uuid: 11
+    type: TYPE_SLICE_BEGIN
+    name: "work"
+  }
+}
+packet {
+  trusted_packet_sequence_id: 1
+  timestamp: 2000
+  track_event {
+    track_uuid: 11
+    type: TYPE_SLICE_END
+  }
+}
+packet {
+  trusted_packet_sequence_id: 1
+  timestamp: 1500
+  track_event {
+    track_uuid: 12
+    type: TYPE_INSTANT
+    name: "tick"
+  }
+}
+packet {
+  trusted_packet_sequence_id: 2
+  timestamp: 1200
+  track_event {
+    track_uuid: 21
+    type: TYPE_INSTANT
+    name: "other"
+  }
+}
diff --git a/test/trace_processor/diff_tests/parser/track_event/track_event_dimensions_identity.textproto b/test/trace_processor/diff_tests/parser/track_event/track_event_dimensions_identity.textproto
new file mode 100644
index 0000000..23caf74
--- /dev/null
+++ b/test/trace_processor/diff_tests/parser/track_event/track_event_dimensions_identity.textproto
@@ -0,0 +1,211 @@
+# Dimensions are part of the track identity.
+#
+# A global track with a rank.
+packet {
+  trusted_packet_sequence_id: 1
+  timestamp: 0
+  incremental_state_cleared: true
+  track_descriptor {
+    uuid: 1
+    name: "g1"
+    sibling_merge_behavior: SIBLING_MERGE_BEHAVIOR_NONE
+    dimensions {
+      name: "rank"
+      int_value: 1
+    }
+    dimensions {
+      name: "stage"
+      string_value: "fwd"
+    }
+  }
+}
+# Re-emitted with the same dimensions in a different order and with a display
+# name: same identity, accepted.
+packet {
+  trusted_packet_sequence_id: 1
+  timestamp: 0
+  track_descriptor {
+    uuid: 1
+    name: "g1"
+    sibling_merge_behavior: SIBLING_MERGE_BEHAVIOR_NONE
+    dimensions {
+      name: "stage"
+      string_value: "fwd"
+    }
+    dimensions {
+      name: "rank"
+      int_value: 1
+      display_name: "one"
+    }
+  }
+}
+# Re-emitted with a different value: conflicting reservation, ignored.
+packet {
+  trusted_packet_sequence_id: 1
+  timestamp: 0
+  track_descriptor {
+    uuid: 1
+    name: "g1"
+    sibling_merge_behavior: SIBLING_MERGE_BEHAVIOR_NONE
+    dimensions {
+      name: "rank"
+      int_value: 2
+    }
+    dimensions {
+      name: "stage"
+      string_value: "fwd"
+    }
+  }
+}
+# A global track first described without dimensions.
+packet {
+  trusted_packet_sequence_id: 1
+  timestamp: 0
+  track_descriptor {
+    uuid: 2
+    name: "g2"
+    sibling_merge_behavior: SIBLING_MERGE_BEHAVIOR_NONE
+  }
+}
+# Re-emitted with dimensions: conflicting reservation, ignored.
+packet {
+  trusted_packet_sequence_id: 1
+  timestamp: 0
+  track_descriptor {
+    uuid: 2
+    name: "g2"
+    sibling_merge_behavior: SIBLING_MERGE_BEHAVIOR_NONE
+    dimensions {
+      name: "rank"
+      int_value: 5
+    }
+  }
+}
+# Sibling tracks merged by name under the same process: only the siblings
+# declaring the same dimensions are merged.
+packet {
+  trusted_packet_sequence_id: 1
+  timestamp: 0
+  track_descriptor {
+    uuid: 10
+    process {
+      pid: 100
+      process_name: "trainer"
+    }
+  }
+}
+packet {
+  trusted_packet_sequence_id: 1
+  timestamp: 0
+  track_descriptor {
+    uuid: 11
+    parent_uuid: 10
+    name: "step"
+    dimensions {
+      name: "rank"
+      int_value: 1
+    }
+    dimensions {
+      name: "stage"
+      string_value: "fwd"
+    }
+  }
+}
+packet {
+  trusted_packet_sequence_id: 1
+  timestamp: 0
+  track_descriptor {
+    uuid: 12
+    parent_uuid: 10
+    name: "step"
+    dimensions {
+      name: "rank"
+      int_value: 2
+    }
+    dimensions {
+      name: "stage"
+      string_value: "fwd"
+    }
+  }
+}
+packet {
+  trusted_packet_sequence_id: 1
+  timestamp: 0
+  track_descriptor {
+    uuid: 13
+    parent_uuid: 10
+    name: "step"
+    dimensions {
+      name: "stage"
+      string_value: "fwd"
+    }
+    dimensions {
+      name: "rank"
+      int_value: 1
+      display_name: "one"
+    }
+  }
+}
+packet {
+  trusted_packet_sequence_id: 1
+  timestamp: 0
+  track_descriptor {
+    uuid: 14
+    parent_uuid: 10
+    name: "step"
+  }
+}
+packet {
+  trusted_packet_sequence_id: 1
+  timestamp: 100
+  track_event {
+    track_uuid: 1
+    type: TYPE_INSTANT
+    name: "g1_event"
+  }
+}
+packet {
+  trusted_packet_sequence_id: 1
+  timestamp: 100
+  track_event {
+    track_uuid: 2
+    type: TYPE_INSTANT
+    name: "g2_event"
+  }
+}
+packet {
+  trusted_packet_sequence_id: 1
+  timestamp: 1000
+  track_event {
+    track_uuid: 11
+    type: TYPE_INSTANT
+    name: "rank1_a"
+  }
+}
+packet {
+  trusted_packet_sequence_id: 1
+  timestamp: 2000
+  track_event {
+    track_uuid: 12
+    type: TYPE_INSTANT
+    name: "rank2"
+  }
+}
+packet {
+  trusted_packet_sequence_id: 1
+  timestamp: 3000
+  track_event {
+    track_uuid: 13
+    type: TYPE_INSTANT
+    name: "rank1_b"
+  }
+}
+packet {
+  trusted_packet_sequence_id: 1
+  timestamp: 4000
+  track_event {
+    track_uuid: 14
+    type: TYPE_INSTANT
+    name: "no_rank"
+  }
+}
diff --git a/test/trace_processor/diff_tests/stdlib/android/freezer_intervals.textproto b/test/trace_processor/diff_tests/stdlib/android/freezer_intervals.textproto
new file mode 100644
index 0000000..5e904ff
--- /dev/null
+++ b/test/trace_processor/diff_tests/stdlib/android/freezer_intervals.textproto
@@ -0,0 +1,158 @@
+# pid 200 starts mid-trace, is frozen, unfrozen, frozen again and then killed
+# while frozen. pid 500 is frozen near the end and still alive. pids 300 and
+# 400 have no freezer events: the trace-stop snapshot says 300 (started
+# mid-trace) is frozen and 400 is not.
+packet {
+  timestamp: 500
+  process_tree {
+    processes { pid: 400 ppid: 1 cmdline: "proc400" }
+    processes { pid: 500 ppid: 1 cmdline: "proc500" }
+  }
+}
+packet {
+  timestamp: 500
+  track_descriptor {
+    uuid: 2
+    thread {
+      pid: 200
+      tid: 200
+      thread_name: "main"
+    }
+  }
+}
+packet {
+  timestamp: 500
+  trusted_packet_sequence_id: 1
+  track_event {
+    type: TYPE_INSTANT
+    track_uuid: 2
+    name: "trace_begin"
+  }
+}
+packet {
+  timestamp: 1000
+  trusted_packet_sequence_id: 1
+  track_event {
+    type: TYPE_INSTANT
+    track_uuid: 2
+    name: "process_start"
+    [com.android.internal.FrameworksBaseTrackEvent.process_start_event] {
+      pid: 200
+      package_uid: 10002
+    }
+  }
+}
+packet {
+  timestamp: 3000
+  trusted_packet_sequence_id: 1
+  track_event {
+    type: TYPE_INSTANT
+    track_uuid: 2
+    name: "freeze"
+    [com.android.internal.FrameworksBaseTrackEvent.freezer_event] {
+      pid: 200
+      uid: 10002
+      unfrozen_dur_ms: 1
+    }
+  }
+}
+packet {
+  timestamp: 5000
+  trusted_packet_sequence_id: 1
+  track_event {
+    type: TYPE_INSTANT
+    track_uuid: 2
+    name: "unfreeze"
+    [com.android.internal.FrameworksBaseTrackEvent.freezer_event] {
+      pid: 200
+      uid: 10002
+      frozen_dur_ms: 2
+      unfreeze_reason: UFR_BIND_SERVICE
+    }
+  }
+}
+packet {
+  timestamp: 6000
+  trusted_packet_sequence_id: 1
+  track_event {
+    type: TYPE_INSTANT
+    track_uuid: 2
+    name: "freeze"
+    [com.android.internal.FrameworksBaseTrackEvent.freezer_event] {
+      pid: 200
+      uid: 10002
+      unfrozen_dur_ms: 1
+    }
+  }
+}
+packet {
+  timestamp: 7000
+  trusted_packet_sequence_id: 1
+  track_event {
+    type: TYPE_INSTANT
+    track_uuid: 2
+    name: "process_start"
+    [com.android.internal.FrameworksBaseTrackEvent.process_start_event] {
+      pid: 300
+      package_uid: 10003
+    }
+  }
+}
+packet {
+  timestamp: 8000
+  trusted_packet_sequence_id: 1
+  track_event {
+    type: TYPE_INSTANT
+    track_uuid: 2
+    name: "binder_died"
+    [com.android.internal.FrameworksBaseTrackEvent.binder_died_event] {
+      uid: 10002
+      pid: 200
+      process_name: "com.example.app"
+    }
+  }
+}
+packet {
+  timestamp: 9000
+  trusted_packet_sequence_id: 1
+  track_event {
+    type: TYPE_INSTANT
+    track_uuid: 2
+    name: "freeze"
+    [com.android.internal.FrameworksBaseTrackEvent.freezer_event] {
+      pid: 500
+      uid: 10005
+      unfrozen_dur_ms: 8
+    }
+  }
+}
+packet {
+  timestamp: 10000
+  trusted_packet_sequence_id: 1
+  track_event {
+    type: TYPE_INSTANT
+    track_uuid: 2
+    name: "end"
+  }
+}
+packet {
+  timestamp: 10000
+  [com.android.internal.FrameworksBaseTracePacket.android_freezer_state] {
+    record {
+      pid: 300
+      uid: 10003
+      frozen_dur_ms: 600
+    }
+    record {
+      pid: 400
+      uid: 10004
+      unfrozen_dur_ms: 50
+      unfreeze_reason: UFR_PING
+    }
+    record {
+      pid: 500
+      uid: 10005
+      frozen_dur_ms: 1
+    }
+  }
+}
diff --git a/test/trace_processor/diff_tests/stdlib/android/freezer_tests.py b/test/trace_processor/diff_tests/stdlib/android/freezer_tests.py
index 0c6c63b..b6e5e98 100644
--- a/test/trace_processor/diff_tests/stdlib/android/freezer_tests.py
+++ b/test/trace_processor/diff_tests/stdlib/android/freezer_tests.py
@@ -30,3 +30,24 @@
             1000000000,4000000000,1234,"com.example.app","FREEZE_APP",0,"UFR_NONE"
             5000000000,0,1234,"com.example.app","UNFREEZE_APP",4,"UFR_ACTIVITY"
             """))
+
+  def test_android_freezer_intervals(self):
+    return DiffTestBlueprint(
+        trace=Path('freezer_intervals.textproto'),
+        query="""
+        INCLUDE PERFETTO MODULE android.freezer;
+        SELECT ts, dur, pid, state
+        FROM _android_freezer_intervals
+        ORDER BY ts, pid;
+        """,
+        out=Csv("""
+        "ts","dur","pid","state"
+        500,-1,400,"UNFROZEN"
+        500,8500,500,"UNFROZEN"
+        1000,2000,200,"UNFROZEN"
+        3000,2000,200,"FROZEN"
+        5000,1000,200,"UNFROZEN"
+        6000,2000,200,"FROZEN"
+        7000,-1,300,"FROZEN"
+        9000,-1,500,"FROZEN"
+        """))
diff --git a/test/trace_processor/diff_tests/stdlib/android/heap_graph_tests.py b/test/trace_processor/diff_tests/stdlib/android/heap_graph_tests.py
index 8265121..3dc49fd 100644
--- a/test/trace_processor/diff_tests/stdlib/android/heap_graph_tests.py
+++ b/test/trace_processor/diff_tests/stdlib/android/heap_graph_tests.py
@@ -103,6 +103,24 @@
           "java.lang.String",1,666,1,666
         """))
 
+  def test_heap_graph_class_tree_native_size(self):
+    return DiffTestBlueprint(
+        trace=Path('../../parser/profiling/heap_graph_native_size.textproto'),
+        query="""
+          INCLUDE PERFETTO MODULE android.memory.heap_graph.class_tree;
+
+          SELECT p.name AS parent_name, c.name, c.heap_type, c.self_count, c.self_size
+          FROM _heap_graph_class_tree c
+          LEFT JOIN _heap_graph_class_tree p ON c.parent_id = p.id
+          WHERE c.name GLOB '*Bitmap*'
+          ORDER BY c.name;
+        """,
+        out=Csv("""
+          "parent_name","name","heap_type","self_count","self_size"
+          "android.graphics.Bitmap","[native] android.graphics.Bitmap","HEAP_TYPE_NATIVE",1,123456
+          "[NULL]","android.graphics.Bitmap","[NULL]",1,46
+        """))
+
   # The same class loaded by two class loaders has the same name but distinct
   # type_ids. The class tree keys on class name, so the two instances must
   # coalesce into a single node (self_count = 2) rather than splitting.
diff --git a/test/trace_processor/diff_tests/stdlib/intervals/fill_gaps_tests.py b/test/trace_processor/diff_tests/stdlib/intervals/fill_gaps_tests.py
deleted file mode 100644
index e2175fe..0000000
--- a/test/trace_processor/diff_tests/stdlib/intervals/fill_gaps_tests.py
+++ /dev/null
@@ -1,244 +0,0 @@
-#!/usr/bin/env python3
-# Copyright (C) 2026 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 python.generators.diff_tests.testing import Path, DataPath, Metric
-from python.generators.diff_tests.testing import Csv, TextProto, DiffTestBlueprint, TestSuite
-
-
-def make_trace_bounds(start: int, end: int) -> TextProto:
-  return TextProto(f"""
-  packet {{
-    ftrace_events {{
-      cpu: 0
-      event {{
-        timestamp: {start}
-        pid: 10
-        print {{
-          buf: "B|10|Start"
-        }}
-      }}
-      event {{
-        timestamp: {end}
-        pid: 10
-        print {{
-          buf: "E|10"
-        }}
-      }}
-    }}
-  }}
-  """)
-
-
-class IntervalsFillGaps(TestSuite):
-
-  def test_fill_gaps_single_group(self):
-    return DiffTestBlueprint(
-        trace=make_trace_bounds(100, 1000),
-        query="""
-        INCLUDE PERFETTO MODULE intervals.fill_gaps;
-
-        CREATE PERFETTO TABLE data_table AS
-        WITH data(ts, dur, grp, val) AS (
-          VALUES
-            (200, 100, 'A', 42),
-            (500, 200, 'A', 43)
-        )
-        SELECT * FROM data;
-
-        SELECT ts, dur, grp, val
-        FROM _intervals_fill_gaps!((grp), (val), data_table)
-        ORDER BY ts;
-        """,
-        out=Csv("""
-        "ts","dur","grp","val"
-        100,100,"A","[NULL]"
-        200,100,"A",42
-        300,200,"A","[NULL]"
-        500,200,"A",43
-        700,300,"A","[NULL]"
-        """))
-
-  def test_fill_gaps_multiple_groups(self):
-    return DiffTestBlueprint(
-        trace=make_trace_bounds(100, 1000),
-        query="""
-        INCLUDE PERFETTO MODULE intervals.fill_gaps;
-
-        CREATE PERFETTO TABLE data_table AS
-        WITH data(ts, dur, grp, val) AS (
-          VALUES
-            (200, 100, 'A', 42),
-            (500, 200, 'A', 43),
-            (300, 150, 'B', 99)
-        )
-        SELECT * FROM data;
-
-        SELECT ts, dur, grp, val
-        FROM _intervals_fill_gaps!((grp), (val), data_table)
-        ORDER BY grp, ts;
-        """,
-        out=Csv("""
-        "ts","dur","grp","val"
-        100,100,"A","[NULL]"
-        200,100,"A",42
-        300,200,"A","[NULL]"
-        500,200,"A",43
-        700,300,"A","[NULL]"
-        100,200,"B","[NULL]"
-        300,150,"B",99
-        450,550,"B","[NULL]"
-        """))
-
-  def test_fill_gaps_empty_input(self):
-    return DiffTestBlueprint(
-        trace=make_trace_bounds(100, 1000),
-        query="""
-        INCLUDE PERFETTO MODULE intervals.fill_gaps;
-
-        CREATE PERFETTO TABLE empty_table AS
-        SELECT CAST(NULL AS INT) AS ts, CAST(NULL AS INT) AS dur, CAST(NULL AS TEXT) AS grp, CAST(NULL AS INT) AS val LIMIT 0;
-
-        SELECT ts, dur, grp, val
-        FROM _intervals_fill_gaps!((grp), (val), empty_table);
-        """,
-        out=Csv("""
-        "ts","dur","grp","val"
-        100,900,"[NULL]","[NULL]"
-        """))
-
-  def test_fill_gaps_no_valid_slices(self):
-    return DiffTestBlueprint(
-        trace=make_trace_bounds(100, 1000),
-        query="""
-        INCLUDE PERFETTO MODULE intervals.fill_gaps;
-
-        CREATE PERFETTO TABLE data_table AS
-        WITH data(ts, dur, grp, val) AS (
-          VALUES
-            (NULL, NULL, 'A', NULL)
-        )
-        SELECT * FROM data;
-
-        SELECT ts, dur, grp, val
-        FROM _intervals_fill_gaps!((grp), (val), data_table);
-        """,
-        out=Csv("""
-        "ts","dur","grp","val"
-        100,900,"A","[NULL]"
-        """))
-
-  def test_fill_gaps_multiple_group_cols(self):
-    return DiffTestBlueprint(
-        trace=make_trace_bounds(100, 1000),
-        query="""
-        INCLUDE PERFETTO MODULE intervals.fill_gaps;
-
-        CREATE PERFETTO TABLE data_table AS
-        WITH data(ts, dur, grp1, grp2, val) AS (
-          VALUES
-            (200, 100, 'A', 'X', 42),
-            (500, 200, 'A', 'Y', 43)
-        )
-        SELECT * FROM data;
-
-        SELECT ts, dur, grp1, grp2, val
-        FROM _intervals_fill_gaps!((grp1, grp2), (val), data_table)
-        ORDER BY grp1, grp2, ts;
-        """,
-        out=Csv("""
-        "ts","dur","grp1","grp2","val"
-        100,100,"A","X","[NULL]"
-        200,100,"A","X",42
-        300,700,"A","X","[NULL]"
-        100,400,"A","Y","[NULL]"
-        500,200,"A","Y",43
-        700,300,"A","Y","[NULL]"
-        """))
-
-  def test_fill_gaps_multiple_data_cols(self):
-    return DiffTestBlueprint(
-        trace=make_trace_bounds(100, 1000),
-        query="""
-        INCLUDE PERFETTO MODULE intervals.fill_gaps;
-
-        CREATE PERFETTO TABLE data_table AS
-        WITH data(ts, dur, grp, val1, val2) AS (
-          VALUES
-            (200, 100, 'A', 42, 'hello'),
-            (500, 200, 'A', 43, 'world')
-        )
-        SELECT * FROM data;
-
-        SELECT ts, dur, grp, val1, val2
-        FROM _intervals_fill_gaps!((grp), (val1, val2), data_table)
-        ORDER BY ts;
-        """,
-        out=Csv("""
-        "ts","dur","grp","val1","val2"
-        100,100,"A","[NULL]","[NULL]"
-        200,100,"A",42,"hello"
-        300,200,"A","[NULL]","[NULL]"
-        500,200,"A",43,"world"
-        700,300,"A","[NULL]","[NULL]"
-        """))
-
-  def test_fill_gaps_union_guarantees_group(self):
-    return DiffTestBlueprint(
-        trace=make_trace_bounds(100, 1000),
-        query="""
-        INCLUDE PERFETTO MODULE intervals.fill_gaps;
-
-        CREATE PERFETTO TABLE data_table AS
-        WITH data(ts, dur, uid, val) AS (
-          VALUES
-            (200, 100, 1234, 42),
-            (NULL, NULL, 1234, NULL)
-        )
-        SELECT * FROM data;
-
-        SELECT ts, dur, uid, val
-        FROM _intervals_fill_gaps!((uid), (val), data_table)
-        ORDER BY uid, ts;
-        """,
-        out=Csv("""
-        "ts","dur","uid","val"
-        100,100,1234,"[NULL]"
-        200,100,1234,42
-        300,700,1234,"[NULL]"
-        """))
-
-  def test_fill_gaps_without_partition(self):
-    return DiffTestBlueprint(
-        trace=make_trace_bounds(100, 1000),
-        query="""
-        INCLUDE PERFETTO MODULE intervals.fill_gaps;
-
-        CREATE PERFETTO TABLE data_table AS
-        WITH data(ts, dur, val) AS (
-          VALUES
-            (200, 100, 42)
-        )
-        SELECT * FROM data;
-
-        SELECT ts, dur, val
-        FROM _intervals_fill_gaps!((NULL), (val), data_table)
-        ORDER BY ts;
-        """,
-        out=Csv("""
-        "ts","dur","val"
-        100,100,"[NULL]"
-        200,100,42
-        300,700,"[NULL]"
-        """))
\ No newline at end of file
diff --git a/test/trace_processor/diff_tests/syntax/pipeline_tests.py b/test/trace_processor/diff_tests/syntax/pipeline_tests.py
index de0811e..52785ec 100644
--- a/test/trace_processor/diff_tests/syntax/pipeline_tests.py
+++ b/test/trace_processor/diff_tests/syntax/pipeline_tests.py
@@ -47,6 +47,52 @@
         "root",10,100,10
         """))
 
+  # A stage walks the tree its own id and parent_id describe, even when an
+  # earlier stage walked another.
+  def test_tree_accumulate_after_the_tree_changes(self):
+    return DiffTestBlueprint(
+        trace=TextProto(r''),
+        query="""
+        PERFETTO PRAGMA pipelines = 1;
+        CREATE PERFETTO TABLE t AS
+        SELECT 0 AS id, NULL AS parent_id, 1 AS v, 0 AS id2, 1 AS p2
+        UNION ALL SELECT 1, 0, 10, 1, 2
+        UNION ALL SELECT 2, 1, 100, 2, NULL;
+
+        FROM t
+        |> TREE ACCUMULATE UP SUM(v) AS a
+        |> SET id = id2, parent_id = p2
+        |> TREE ACCUMULATE UP SUM(v) AS b
+        |> ORDER BY v
+        |> SELECT v, a, b;
+        """,
+        out=Csv("""
+        "v","a","b"
+        1,111,1
+        10,110,11
+        100,100,111
+        """))
+
+  # Rows dropped between two stages can leave a parent missing, which the
+  # second stage finds as it would with no stage before it.
+  def test_tree_accumulate_after_rows_are_dropped(self):
+    return DiffTestBlueprint(
+        trace=TextProto(r''),
+        query="""
+        PERFETTO PRAGMA pipelines = 1;
+        CREATE PERFETTO TABLE t AS
+        SELECT 0 AS id, NULL AS parent_id, 1 AS v
+        UNION ALL SELECT 1, 0, 10
+        UNION ALL SELECT 2, 1, 100;
+
+        FROM t
+        |> TREE ACCUMULATE UP SUM(v) AS a
+        |> WHERE v > 1
+        |> TREE ACCUMULATE UP SUM(v) AS b
+        |> SELECT v, a, b;
+        """,
+        out=ExpectedError('a row names a parent which is not itself a row'))
+
   # Must match the descendant closure, which this is meant to replace.
   def test_tree_accumulate_matches_closure(self):
     return DiffTestBlueprint(
@@ -207,6 +253,45 @@
         """))
 
   # AGGREGATE ... GROUP BY gives what SQLite's GROUP BY does.
+  # A key listed again, however it is written, groups nothing new. A stage
+  # which outputs its keys outputs one column for each listed.
+  def test_a_repeated_key_groups_once(self):
+    return DiffTestBlueprint(
+        trace=TextProto(r''),
+        query="""
+        PERFETTO PRAGMA pipelines = 1;
+        CREATE PERFETTO TABLE t AS
+        SELECT 0 AS ts, 10 AS dur, 1 AS cpu
+        UNION ALL SELECT 5, 10, 1
+        UNION ALL SELECT 0, 3, 2;
+
+        CREATE PERFETTO TABLE aggregated AS
+        FROM t AS t
+        |> AGGREGATE COUNT(*) AS n GROUP BY cpu, t.cpu AS cpu2;
+        CREATE PERFETTO TABLE flattened AS
+        FROM t
+        |> INTERVAL FLATTEN PER cpu, CPU AGGREGATE COUNT(*) AS n
+        |> AGGREGATE COUNT(*) AS n;
+        CREATE PERFETTO TABLE intersected AS
+        INTERVAL INTERSECTION OF (t AS a, t AS b) PER cpu, cpu
+        |> AGGREGATE COUNT(*) AS n;
+        CREATE PERFETTO TABLE filled AS
+        FROM t
+        |> INTERVAL FILL GAPS WITH (SELECT 0 AS ts, 20 AS dur) PER cpu, cpu
+        |> AGGREGATE COUNT(*) AS n;
+
+        SELECT
+          (SELECT group_concat(cpu || ':' || cpu2 || ':' || n, ' ')
+           FROM (SELECT * FROM aggregated ORDER BY cpu)) AS aggregated,
+          (SELECT n FROM flattened) AS flattened,
+          (SELECT n FROM intersected) AS intersected,
+          (SELECT n FROM filled) AS filled;
+        """,
+        out=Csv("""
+        "aggregated","flattened","intersected","filled"
+        "1:1:2 2:2:1",4,5,5
+        """))
+
   def test_aggregate_matches_group_by(self):
     return DiffTestBlueprint(
         trace=DataPath('chrome_input_with_frame_view.pftrace'),
@@ -369,15 +454,69 @@
         """,
         out=ExpectedError('aggregate AVG is not supported yet'))
 
-  def test_distinct_is_not_supported_yet(self):
+  # Must match SQL's WHERE and DISTINCT, including comparing an integer
+  # column with a fraction.
+  def test_where_and_distinct_match_sql(self):
+    return DiffTestBlueprint(
+        trace=DataPath('chrome_input_with_frame_view.pftrace'),
+        query="""
+        PERFETTO PRAGMA pipelines = 1;
+        CREATE PERFETTO TABLE piped AS
+        FROM (SELECT track_id, depth, dur FROM slice)
+        |> WHERE dur > 999.5 AND depth <= 2
+        |> SELECT track_id, depth
+        |> DISTINCT;
+
+        CREATE PERFETTO TABLE expected AS
+        SELECT DISTINCT track_id, depth FROM slice
+        WHERE dur > 999.5 AND depth <= 2;
+
+        SELECT
+          (SELECT count(*) FROM piped) AS rows,
+          (SELECT count(*) FROM expected) AS expected_rows,
+          (SELECT count(*) FROM (
+            SELECT * FROM piped EXCEPT SELECT * FROM expected))
+          + (SELECT count(*) FROM (
+            SELECT * FROM expected EXCEPT SELECT * FROM piped)) AS mismatches;
+        """,
+        out=Csv("""
+        "rows","expected_rows","mismatches"
+        126,126,0
+        """))
+
+  # DISTINCT compares the columns a bare name finds, so two rows of `a`
+  # meeting `b` over one region give one row.
+  def test_distinct_after_intersection(self):
     return DiffTestBlueprint(
         trace=TextProto(r''),
         query="""
         PERFETTO PRAGMA pipelines = 1;
-        FROM (SELECT 1 AS id)
-        |> DISTINCT;
+        CREATE PERFETTO TABLE a AS
+        SELECT 0 AS ts, 10 AS dur, 1 AS k
+        UNION ALL SELECT 1, 10, 1;
+        CREATE PERFETTO TABLE b AS SELECT 5 AS ts, 2 AS dur;
+
+        INTERVAL INTERSECTION OF (a AS x, b AS y)
+        |> DISTINCT
+        |> SELECT ts, dur, x.k;
         """,
-        out=ExpectedError('DISTINCT is not supported yet'))
+        out=Csv("""
+        "ts","dur","k"
+        5,2,1
+        """))
+
+  # A column DISTINCT does not compare has no one value per row, so it is
+  # gone from the aliases too.
+  def test_distinct_drops_columns_it_does_not_compare(self):
+    return DiffTestBlueprint(
+        trace=TextProto(r''),
+        query="""
+        PERFETTO PRAGMA pipelines = 1;
+        CREATE PERFETTO TABLE t AS SELECT 1 AS x, 2 AS y;
+
+        FROM t AS t |> DROP x |> DISTINCT |> SELECT t.x;
+        """,
+        out=ExpectedError("no such column: 't.x'"))
 
   def test_a_pipeline_needs_the_pragma(self):
     return DiffTestBlueprint(
@@ -470,6 +609,99 @@
         10,20,0,30,10
         """))
 
+  # A star gives the region's ts and dur, not each operand's.
+  def test_interval_intersection_star_is_the_region(self):
+    return DiffTestBlueprint(
+        trace=TextProto(r''),
+        query="""
+        PERFETTO PRAGMA pipelines = 1;
+        CREATE PERFETTO TABLE a AS SELECT 0 AS ts, 30 AS dur, 7 AS freq;
+        CREATE PERFETTO TABLE b AS SELECT 10 AS ts, 100 AS dur, 1 AS state;
+
+        INTERVAL INTERSECTION OF (a AS x, b AS y) |> SELECT *;
+        """,
+        out=Csv("""
+        "ts","dur","freq","state"
+        10,20,7,1
+        """))
+
+  def test_interval_intersection_without_a_stage_is_the_region(self):
+    return DiffTestBlueprint(
+        trace=TextProto(r''),
+        query="""
+        PERFETTO PRAGMA pipelines = 1;
+        CREATE PERFETTO TABLE a AS SELECT 0 AS ts, 30 AS dur, 7 AS freq;
+        CREATE PERFETTO TABLE b AS SELECT 10 AS ts, 100 AS dur, 1 AS state;
+
+        INTERVAL INTERSECTION OF (a AS x, b AS y);
+        """,
+        out=Csv("""
+        "ts","dur","freq","state"
+        10,20,7,1
+        """))
+
+  def test_interval_intersection_operand_columns_by_bare_name(self):
+    return DiffTestBlueprint(
+        trace=TextProto(r''),
+        query="""
+        PERFETTO PRAGMA pipelines = 1;
+        CREATE PERFETTO TABLE a AS SELECT 0 AS ts, 30 AS dur, 7 AS freq;
+        CREATE PERFETTO TABLE b AS SELECT 10 AS ts, 100 AS dur, 1 AS state;
+
+        INTERVAL INTERSECTION OF (a AS x, b AS y)
+        |> SELECT ts, dur, freq, state, x.freq AS x_freq;
+        """,
+        out=Csv("""
+        "ts","dur","freq","state","x_freq"
+        10,20,7,1,7
+        """))
+
+  def test_interval_intersection_new_alias_is_the_region(self):
+    return DiffTestBlueprint(
+        trace=TextProto(r''),
+        query="""
+        PERFETTO PRAGMA pipelines = 1;
+        CREATE PERFETTO TABLE a AS SELECT 0 AS ts, 30 AS dur, 7 AS freq;
+        CREATE PERFETTO TABLE b AS SELECT 10 AS ts, 100 AS dur, 1 AS state;
+
+        INTERVAL INTERSECTION OF (a AS x, b AS y)
+        |> AS u
+        |> SELECT u.ts, u.dur, u.freq;
+        """,
+        out=Csv("""
+        "ts","dur","freq"
+        10,20,7
+        """))
+
+  # A later operand's copy of a PER column is reached through its alias.
+  def test_interval_intersection_per_column_of_a_later_operand(self):
+    return DiffTestBlueprint(
+        trace=TextProto(r''),
+        query="""
+        PERFETTO PRAGMA pipelines = 1;
+        CREATE PERFETTO TABLE a AS SELECT 0 AS ts, 30 AS dur, 2 AS cpu;
+        CREATE PERFETTO TABLE b AS SELECT 10 AS ts, 100 AS dur, 2 AS cpu;
+
+        INTERVAL INTERSECTION OF (a AS x, b AS y) PER cpu
+        |> SELECT *, y.cpu AS y_cpu;
+        """,
+        out=Csv("""
+        "ts","dur","cpu","y_cpu"
+        10,20,2,2
+        """))
+
+  def test_interval_intersection_shared_column_is_ambiguous(self):
+    return DiffTestBlueprint(
+        trace=TextProto(r''),
+        query="""
+        PERFETTO PRAGMA pipelines = 1;
+        CREATE PERFETTO TABLE a AS SELECT 0 AS ts, 30 AS dur, 7 AS n;
+        CREATE PERFETTO TABLE b AS SELECT 10 AS ts, 100 AS dur, 1 AS n;
+
+        INTERVAL INTERSECTION OF (a AS x, b AS y) |> SELECT n;
+        """,
+        out=ExpectedError("column 'n' is ambiguous"))
+
   # PER confines regions to rows which agree on the columns named, and those
   # columns come out under their bare names.
   def test_interval_intersection_per_a_key(self):
@@ -801,3 +1033,308 @@
         "start","dur","x_start","state"
         10,20,0,1
         """))
+
+  # Rows which never overlap within a cpu, filled over the trace, tile the
+  # trace exactly on every cpu.
+  def test_interval_fill_gaps_tiles_the_trace(self):
+    return DiffTestBlueprint(
+        trace=DataPath('android_boot.pftrace'),
+        query="""
+        PERFETTO PRAGMA pipelines = 1;
+
+        CREATE PERFETTO TABLE sched_rows AS
+        SELECT ts, dur, cpu, utid FROM sched WHERE dur > 0 AND utid != 0;
+
+        CREATE PERFETTO TABLE piped AS
+        FROM sched_rows
+        |> INTERVAL FILL GAPS WITH (
+             SELECT trace_start() AS ts, trace_dur() AS dur
+           ) PER cpu;
+
+        SELECT
+          (SELECT count(*) FROM piped WHERE utid IS NULL) AS fillers,
+          (
+            SELECT count(*) FROM (
+              SELECT cpu FROM piped GROUP BY cpu HAVING sum(dur) != trace_dur()
+            )
+          ) AS untiled_cpus,
+          (
+            SELECT count(*) FROM (
+              SELECT
+                ts + dur > lead(ts) OVER (PARTITION BY cpu ORDER BY ts)
+                  AS overlaps
+              FROM piped
+            )
+            WHERE overlaps
+          ) AS overlaps;
+        """,
+        out=Csv("""
+        "fillers","untiled_cpus","overlaps"
+        76331,0,0
+        """))
+
+  # Without PER, a filler takes the background's columns by name and its own
+  # bounds.
+  def test_interval_fill_gaps_takes_the_background_by_name(self):
+    return DiffTestBlueprint(
+        trace=TextProto(r''),
+        query="""
+        PERFETTO PRAGMA pipelines = 1;
+        CREATE PERFETTO TABLE spans AS
+        SELECT 2 AS ts, 3 AS dur, 'run' AS state
+        UNION ALL SELECT 6, 1, 'run';
+
+        FROM spans
+        |> INTERVAL FILL GAPS WITH (SELECT 0 AS ts, 10 AS dur, 'idle' AS state)
+        |> ORDER BY ts;
+        """,
+        out=Csv("""
+        "ts","dur","state"
+        0,2,"idle"
+        2,3,"run"
+        5,1,"idle"
+        6,1,"run"
+        7,3,"idle"
+        """))
+
+  # A background without the PER columns fills every lane of the input, and a
+  # filler takes its lane's PER values.
+  def test_interval_fill_gaps_shares_the_background_across_lanes(self):
+    return DiffTestBlueprint(
+        trace=TextProto(r''),
+        query="""
+        PERFETTO PRAGMA pipelines = 1;
+        CREATE PERFETTO TABLE spans AS
+        SELECT 2 AS ts, 3 AS dur, 0 AS cpu, 'run' AS state
+        UNION ALL SELECT 1, 2, 1, 'sleep';
+
+        FROM spans
+        |> INTERVAL FILL GAPS WITH (SELECT 0 AS ts, 10 AS dur) PER cpu
+        |> ORDER BY cpu, ts;
+        """,
+        out=Csv("""
+        "ts","dur","cpu","state"
+        0,2,0,"[NULL]"
+        2,3,0,"run"
+        5,5,0,"[NULL]"
+        0,1,1,"[NULL]"
+        1,2,1,"sleep"
+        3,7,1,"[NULL]"
+        """))
+
+  # A background with the PER columns names the lanes: one without input is
+  # filled whole, and input in a lane it does not name fills nothing.
+  def test_interval_fill_gaps_background_names_the_lanes(self):
+    return DiffTestBlueprint(
+        trace=TextProto(r''),
+        query="""
+        PERFETTO PRAGMA pipelines = 1;
+        CREATE PERFETTO TABLE spans AS
+        SELECT 2 AS ts, 3 AS dur, 0 AS cpu, 'run' AS state
+        UNION ALL SELECT 1, 2, 1, 'sleep';
+        CREATE PERFETTO TABLE lanes AS
+        SELECT 0 AS ts, 10 AS dur, 0 AS cpu, 'idle' AS state
+        UNION ALL SELECT 0, 4, 2, 'off';
+
+        FROM spans
+        |> INTERVAL FILL GAPS WITH lanes PER cpu
+        |> ORDER BY cpu, ts;
+        """,
+        out=Csv("""
+        "ts","dur","cpu","state"
+        0,2,0,"idle"
+        2,3,0,"run"
+        5,5,0,"idle"
+        1,2,1,"sleep"
+        0,4,2,"off"
+        """))
+
+  # Without input, the background is filled whole.
+  def test_interval_fill_gaps_without_input(self):
+    return DiffTestBlueprint(
+        trace=TextProto(r''),
+        query="""
+        PERFETTO PRAGMA pipelines = 1;
+        CREATE PERFETTO TABLE spans AS
+        SELECT 0 AS ts, 0 AS dur, 'run' AS state WHERE 0;
+
+        FROM spans
+        |> INTERVAL FILL GAPS WITH (SELECT 0 AS ts, 4 AS dur, 'idle' AS state);
+        """,
+        out=Csv("""
+        "ts","dur","state"
+        0,4,"idle"
+        """))
+
+  # Overlapping input covers its union, a dur of -1 covers to the end, and a
+  # row with a null ts covers nothing.
+  def test_interval_fill_gaps_coverage(self):
+    return DiffTestBlueprint(
+        trace=TextProto(r''),
+        query="""
+        PERFETTO PRAGMA pipelines = 1;
+        CREATE PERFETTO TABLE spans AS
+        SELECT 2 AS ts, 3 AS dur, 1 AS id
+        UNION ALL SELECT 4, 3, 2
+        UNION ALL SELECT 25, -1, 3
+        UNION ALL SELECT NULL, 5, 4;
+
+        FROM spans
+        |> INTERVAL FILL GAPS WITH (
+             SELECT 0 AS ts, 10 AS dur UNION ALL SELECT 20, 10)
+        |> ORDER BY ts, id;
+        """,
+        out=Csv("""
+        "ts","dur","id"
+        "[NULL]",5,4
+        0,2,"[NULL]"
+        2,3,1
+        4,3,2
+        7,3,"[NULL]"
+        20,5,"[NULL]"
+        25,-1,3
+        """))
+
+  # An alias still reaches its columns.
+  def test_interval_fill_gaps_keeps_aliases(self):
+    return DiffTestBlueprint(
+        trace=TextProto(r''),
+        query="""
+        PERFETTO PRAGMA pipelines = 1;
+        CREATE PERFETTO TABLE spans AS SELECT 2 AS ts, 3 AS dur, 'run' AS state;
+
+        FROM spans AS s
+        |> INTERVAL FILL GAPS WITH (SELECT 0 AS ts, 10 AS dur, 'idle' AS state)
+        |> SELECT s.ts, s.state
+        |> ORDER BY ts;
+        """,
+        out=Csv("""
+        "ts","state"
+        0,"idle"
+        2,"run"
+        5,"idle"
+        """))
+
+  # A dataframe column and a SQL one are brought to one type.
+  def test_interval_fill_gaps_unifies_types(self):
+    return DiffTestBlueprint(
+        trace=TextProto(r''),
+        query="""
+        PERFETTO PRAGMA pipelines = 1;
+        CREATE PERFETTO TABLE spans AS
+        SELECT 1 AS ts, 2 AS dur, 1 AS cpu, 1.5 AS weight;
+
+        FROM spans
+        |> INTERVAL FILL GAPS WITH (SELECT 0 AS ts, 5 AS dur, 0 AS weight)
+        |> ORDER BY ts;
+        """,
+        out=Csv("""
+        "ts","dur","cpu","weight"
+        0,1,"[NULL]",0.000000
+        1,2,1,1.500000
+        3,2,"[NULL]",0.000000
+        """))
+
+  # PER columns are brought to one type even when they are not output.
+  def test_interval_fill_gaps_unifies_unused_per_types(self):
+    return DiffTestBlueprint(
+        trace=TextProto(r''),
+        query="""
+        PERFETTO PRAGMA pipelines = 1;
+        CREATE PERFETTO TABLE spans AS
+        SELECT 2 AS ts, 3 AS dur, 0 AS cpu
+        UNION ALL SELECT 1, 2, 1;
+        CREATE PERFETTO TABLE lanes AS
+        SELECT 0 AS ts, 10 AS dur, 0.0 AS cpu
+        UNION ALL SELECT 0, 4, 1.0;
+
+        FROM spans
+        |> INTERVAL FILL GAPS WITH lanes PER cpu
+        |> SELECT ts, dur
+        |> ORDER BY ts, dur;
+        """,
+        out=Csv("""
+        "ts","dur"
+        0,1
+        0,2
+        1,2
+        2,3
+        3,1
+        5,5
+        """))
+
+  def test_interval_fill_gaps_needs_background_bounds(self):
+    return DiffTestBlueprint(
+        trace=TextProto(r''),
+        query="""
+        PERFETTO PRAGMA pipelines = 1;
+        FROM (SELECT 0 AS ts, 1 AS dur)
+        |> INTERVAL FILL GAPS WITH (SELECT 0 AS dur);
+        """,
+        out=ExpectedError('expected the background to have a ts'))
+
+  def test_interval_fill_gaps_needs_every_per_column_or_none(self):
+    return DiffTestBlueprint(
+        trace=TextProto(r''),
+        query="""
+        PERFETTO PRAGMA pipelines = 1;
+        FROM (SELECT 0 AS ts, 1 AS dur, 0 AS cpu, 0 AS state)
+        |> INTERVAL FILL GAPS WITH (SELECT 0 AS ts, 1 AS dur, 0 AS cpu)
+           PER cpu, state;
+        """,
+        out=ExpectedError('every PER column or none'))
+
+  def test_interval_fill_gaps_needs_background_columns_in_the_input(self):
+    return DiffTestBlueprint(
+        trace=TextProto(r''),
+        query="""
+        PERFETTO PRAGMA pipelines = 1;
+        FROM (SELECT 0 AS ts, 1 AS dur)
+        |> INTERVAL FILL GAPS WITH (SELECT 0 AS ts, 5 AS dur, 1 AS filled);
+        """,
+        out=ExpectedError("the input to have the background's 'filled'"))
+
+  def test_interval_fill_gaps_refuses_strings_meeting_numbers(self):
+    return DiffTestBlueprint(
+        trace=TextProto(r''),
+        query="""
+        PERFETTO PRAGMA pipelines = 1;
+        CREATE PERFETTO TABLE spans AS SELECT 2 AS ts, 3 AS dur, 'run' AS state;
+
+        FROM spans
+        |> INTERVAL FILL GAPS WITH (SELECT 0 AS ts, 10 AS dur, 1 AS state);
+        """,
+        out=ExpectedError('holds strings in one input and numbers in another'))
+
+  def test_interval_fill_gaps_refuses_a_negative_ts(self):
+    return DiffTestBlueprint(
+        trace=TextProto(r''),
+        query="""
+        PERFETTO PRAGMA pipelines = 1;
+        FROM (SELECT -1 AS ts, 2 AS dur)
+        |> INTERVAL FILL GAPS WITH (SELECT 0 AS ts, 10 AS dur);
+        """,
+        out=ExpectedError('ts is below zero'))
+
+  def test_interval_fill_gaps_refuses_overlapping_background(self):
+    return DiffTestBlueprint(
+        trace=TextProto(r''),
+        query="""
+        PERFETTO PRAGMA pipelines = 1;
+        FROM (SELECT 0 AS ts, 1 AS dur)
+        |> INTERVAL FILL GAPS WITH (
+             SELECT 0 AS ts, 10 AS dur UNION ALL SELECT 5, 10);
+        """,
+        out=ExpectedError('overlap within a lane'))
+
+  # SELECT, EXTEND and SET parse any expression, but only a column can be
+  # computed yet.
+  def test_computed_columns_are_not_supported_yet(self):
+    return DiffTestBlueprint(
+        trace=TextProto(r''),
+        query="""
+        PERFETTO PRAGMA pipelines = 1;
+        FROM (SELECT 1 AS a)
+        |> EXTEND a + 1 AS b;
+        """,
+        out=ExpectedError('a computed column is not supported yet'))
diff --git a/test/traced_integrationtest.cc b/test/traced_integrationtest.cc
index 3c7ebcf..777ea42 100644
--- a/test/traced_integrationtest.cc
+++ b/test/traced_integrationtest.cc
@@ -38,9 +38,12 @@
 #include "test/gtest_and_gmock.h"
 #include "test/test_helper.h"
 
+#include "protos/perfetto/common/trace_stats.gen.h"
+#include "protos/perfetto/config/process_stats/process_stats_config.gen.h"
 #include "protos/perfetto/config/test_config.gen.h"
 #include "protos/perfetto/config/trace_config.gen.h"
 #include "protos/perfetto/trace/perfetto/tracing_service_event.gen.h"
+#include "protos/perfetto/trace/perfetto/tracing_v2_producer_stats.gen.h"
 #include "protos/perfetto/trace/test_event.gen.h"
 #include "protos/perfetto/trace/trace.gen.h"
 #include "protos/perfetto/trace/trace_packet.gen.h"
@@ -50,6 +53,7 @@
 
 namespace {
 
+using ::testing::Contains;
 using ::testing::ContainsRegex;
 using ::testing::Each;
 using ::testing::ElementsAreArray;
@@ -585,4 +589,59 @@
 }
 #endif
 
+// Tracing v2 over IPC needs memfd, so this runs only on Linux and Android.
+#if PERFETTO_BUILDFLAG(PERFETTO_START_DAEMONS) &&         \
+    (PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX_BUT_NOT_QNX) || \
+     PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID))
+// A traced_probes data source that selects v2 writes through the ring buffer
+// of traced_probes.
+TEST(PerfettoTracedIntegrationTest, ProbesDataSourceUsesTracingV2) {
+  base::TestTaskRunner task_runner;
+
+  TestHelper helper(&task_runner);
+  helper.StartServiceIfRequired();
+  ProbesProducerThread probes(GetTestProducerSockName());
+  probes.Connect();
+  helper.ConnectConsumer();
+  helper.WaitForConsumerConnect();
+  helper.WaitForDataSourceConnected("linux.process_stats");
+
+  TraceConfig trace_config;
+  auto* buffer = trace_config.add_buffers();
+  buffer->set_size_kb(1024);
+  buffer->set_experimental_mode(TraceConfig::BufferConfig::TRACE_BUFFER_V2);
+  trace_config.set_duration_ms(200);
+
+  auto* ds_config = trace_config.add_data_sources()->mutable_config();
+  ds_config->set_name("linux.process_stats");
+  ds_config->mutable_experimental_tracing_v2()->set_use_v2_probability_percent(
+      100);
+  protos::gen::ProcessStatsConfig process_stats_config;
+  process_stats_config.set_scan_all_processes_on_start(true);
+  ds_config->set_process_stats_config_raw(
+      process_stats_config.SerializeAsString());
+
+  helper.StartTracing(trace_config);
+  helper.WaitForTracingDisabled();
+  helper.ReadData();
+  helper.WaitForReadData();
+
+  EXPECT_THAT(
+      helper.trace(),
+      Contains(Property(&protos::gen::TracePacket::has_process_tree, true)));
+
+  // Producer stats cover only producers with an attached ring buffer.
+  // The process tree writer is the only v2 writer, so chunks_read > 0 means
+  // its data came through the ring buffer.
+  const protos::gen::ExperimentalTracingV2ProducerStats* stats = nullptr;
+  for (const auto& packet : helper.full_trace()) {
+    if (packet.has_experimental_tracing_v2_producer_stats())
+      stats = &packet.experimental_tracing_v2_producer_stats();
+  }
+  ASSERT_NE(stats, nullptr);
+  EXPECT_EQ(stats->producer_name(), "perfetto.traced_probes");
+  EXPECT_GT(stats->chunks_read(), 0u);
+}
+#endif
+
 }  // namespace perfetto
diff --git a/tools/extract_linux_syscall_tables b/tools/extract_linux_syscall_tables
index e5365dd..1b28b4d 100755
--- a/tools/extract_linux_syscall_tables
+++ b/tools/extract_linux_syscall_tables
@@ -11,7 +11,7 @@
 SELF_PATH = os.path.relpath(__file__, PROJECT_ROOT).replace('\\', '/')
 
 syscalls = {}
-archs = ['arm64', 'arm32', 'x86', 'x86_64']
+archs = ['arm64', 'arm32', 'x86', 'x86_64', 's390x']
 
 
 def print_tables():
@@ -62,7 +62,7 @@
 # Parses a .tbl file (new format). With |abis|, keeps only the rows of
 # those ABIs, as the kernel's build does for an architecture that shares
 # the generic table.
-def parse_tlb(data, abis=None):
+def parse_tbl(data, abis=None):
   table = {}
   for line in data.splitlines():
     line = line.strip()
@@ -90,22 +90,25 @@
   KSRC = 'https://raw.githubusercontent.com/torvalds/linux/v7.2/'
 
   response = urlopen(KSRC + 'arch/x86/entry/syscalls/syscall_64.tbl')
-  syscalls['x86_64'] = parse_tlb(response.read().decode())
+  syscalls['x86_64'] = parse_tbl(response.read().decode())
 
   response = urlopen(KSRC + 'arch/x86/entry/syscalls/syscall_32.tbl')
-  syscalls['x86'] = parse_tlb(response.read().decode())
+  syscalls['x86'] = parse_tbl(response.read().decode())
 
   response = urlopen(KSRC + 'arch/arm/tools/syscall.tbl')
-  syscalls['arm32'] = parse_tlb(response.read().decode())
+  syscalls['arm32'] = parse_tbl(response.read().decode())
 
   # arm64 shares the generic table (arch/arm64/tools/syscall_64.tbl links
   # to it), taking the ABIs scripts/Makefile.asm-headers gives every
   # 64-bit architecture plus those arch/arm64/kernel/Makefile.syscalls adds.
   response = urlopen(KSRC + 'scripts/syscall.tbl')
-  syscalls['arm64'] = parse_tlb(
+  syscalls['arm64'] = parse_tbl(
       response.read().decode(),
       abis={'common', '64', 'renameat', 'rlimit', 'memfd_secret'})
 
+  response = urlopen(KSRC + 'arch/s390/kernel/syscalls/syscall.tbl')
+  syscalls['s390x'] = parse_tbl(response.read().decode(), abis={'common', '64'})
+
   dst_file = os.path.join(PROJECT_ROOT, 'src', 'kernel_utils',
                           'syscall_table_generated.h')
   tmp_file = dst_file + '.tmp'
diff --git a/tools/gen_c_protos b/tools/gen_c_protos
index 5b0961f..c2d5db9 100755
--- a/tools/gen_c_protos
+++ b/tools/gen_c_protos
@@ -55,6 +55,7 @@
     'protos/perfetto/trace/track_event/debug_annotation.proto',
     'protos/perfetto/trace/track_event/state_descriptor.proto',
     'protos/perfetto/trace/track_event/track_descriptor.proto',
+    'protos/perfetto/trace/track_event/track_dimension.proto',
     'protos/perfetto/trace/track_event/track_event.proto',
 ]
 
diff --git a/tools/install-build-deps b/tools/install-build-deps
index 346cc0b..9d8674b 100755
--- a/tools/install-build-deps
+++ b/tools/install-build-deps
@@ -591,7 +591,7 @@
 
 # Sysroots required to cross-compile Linux targets (linux-arm{,64}).
 # These are taken from Chromium's build/linux/sysroot_scripts/sysroots.json.
-BUILD_DEPS_LINUX_CROSS_SYSROOTS = [
+BUILD_DEPS_LINUX_CROSS_SYSROOTS_ARM = [
     Dependency(
         'buildtools/debian_sid_arm-sysroot.tgz',
         'https://commondatastorage.googleapis.com/chrome-linux-sysroot/toolchain/11d6f690ca49e8ba01a1d8c5346cedad2cf308fd/debian_sid_arm_sysroot.tar.xz',
@@ -603,10 +603,18 @@
         'e4389eab2fe363f3fbdfa4d3ce9d94457d78fd2c0e62171a7534867623eadc90',
         'linux', 'all'),
 ]
+BUILD_DEPS_LINUX_CROSS_SYSROOTS_S390X = [
+    Dependency(
+        'buildtools/debian_bullseye_s390x-sysroot.tgz',
+        'https://commondatastorage.googleapis.com/chrome-linux-sysroot/46d561a32665a7ef4db334d66ba10b0db7750eea3fed1fee4896c2f5c4f87167',
+        '46d561a32665a7ef4db334d66ba10b0db7750eea3fed1fee4896c2f5c4f87167',
+        'linux', 'all'),
+]
 
 ALL_DEPS = (
     BUILD_DEPS_HOST + BUILD_DEPS_BAZEL + BUILD_DEPS_ANDROID +
-    BUILD_DEPS_LINUX_CROSS_SYSROOTS + TEST_DEPS_ANDROID +
+    BUILD_DEPS_LINUX_CROSS_SYSROOTS_ARM +
+    BUILD_DEPS_LINUX_CROSS_SYSROOTS_S390X + TEST_DEPS_ANDROID +
     EMULATOR_DEPS_ANDROID + UI_DEPS + BUILD_DEPS_RUST + SYNTAQLITE_DEPS)
 
 ROOT_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
@@ -962,6 +970,10 @@
       action='store_true',
       help='Debian sysroots for target_os="linux" target_cpu="arm|arm64"')
   parser.add_argument(
+      '--linux-s390x',
+      action='store_true',
+      help='Debian sysroots for target_os="linux" target_cpu="s390x"')
+  parser.add_argument(
       '--ui',
       action='store_true',
       help='Node and NPM packages to Build the Web-based UI via ./ui/build')
@@ -1026,7 +1038,9 @@
   if args.android:
     deps += BUILD_DEPS_ANDROID + TEST_DEPS_ANDROID + EMULATOR_DEPS_ANDROID
   if args.linux_arm:
-    deps += BUILD_DEPS_LINUX_CROSS_SYSROOTS
+    deps += BUILD_DEPS_LINUX_CROSS_SYSROOTS_ARM
+  if args.linux_s390x:
+    deps += BUILD_DEPS_LINUX_CROSS_SYSROOTS_S390X
   if args.ui:
     deps += UI_DEPS
   # TODO(b/360084012) Change the arg name to bigtrace
diff --git a/ui/src/base/array_utils.ts b/ui/src/base/array_utils.ts
index 54f2a1f..2b08894 100644
--- a/ui/src/base/array_utils.ts
+++ b/ui/src/base/array_utils.ts
@@ -61,7 +61,7 @@
 //       in the position before current element at `to` index.
 export function moveArrayItem<T>(array: T[], from: number, to: number) {
   if (from === to) return;
-  const value = array[from];
+  const value = array[from]!;
   array.splice(from, 1);
   if (from < to) {
     // We have deleted an item, therefore we need to adjust the target index.
diff --git a/ui/src/base/async_memo.ts b/ui/src/base/async_memo.ts
index 592775c..a4f55d0 100644
--- a/ui/src/base/async_memo.ts
+++ b/ui/src/base/async_memo.ts
@@ -66,8 +66,9 @@
  * - Only the latest pending task per memo is kept (intermediates dropped)
  * - Each memo has a single-entry cache (most recent result)
  * - If compute() returns an AsyncDisposable, it is automatically disposed
- *   before running the next task and when the memo is disposed. Disposal runs
- *   through the queue to stay synchronized with in-flight tasks.
+ *   once the next task's result replaces it and when the memo is disposed.
+ *   Disposal runs through the queue to stay synchronized with in-flight tasks.
+ *   Until replaced, the previous result remains usable via retainOn.
  */
 
 import m from 'mithril';
@@ -179,7 +180,7 @@
  * memos should share a SerialTaskQueue for atomic compute task execution.
  *
  * If T is an AsyncDisposable, the memo will automatically dispose of previous
- * results before running a new compute and when the memo is disposed.
+ * results once a new compute replaces them and when the memo is disposed.
  */
 export class AsyncMemo<T> {
   private cache?: Cache<T>;
@@ -238,15 +239,35 @@
       this.pendingKey = key;
       this.queue.schedule(this, async () => {
         try {
-          // Dispose of previous result before running new task
-          await this.disposeCache();
           const result = await compute({
             get isCancelled() {
               return signal.cancelled;
             },
           });
 
+          const previous = this.cache;
           this.finaliseTask(key, result);
+
+          // Dispose of the previous result now that it has been replaced.
+          // Doing this after (rather than before) compute keeps the previous
+          // result usable via retainOn while the new one is computed.
+          //
+          // Disposal is scheduled as a separate task rather than run inline so
+          // that it runs after any tasks already queued which captured the
+          // previous result (e.g. a dependent memo's compute). Once the cache
+          // has been replaced, no new tasks can capture it. A fresh key is used
+          // so that later tasks on this memo can't replace (and leak) it.
+          if (
+            previous !== undefined &&
+            this.cache !== previous &&
+            this.cache?.data !== previous.data &&
+            isAsyncDisposable(previous.data)
+          ) {
+            const stale = previous.data;
+            this.queue.schedule({}, async () => {
+              await stale[Symbol.asyncDispose]();
+            });
+          }
         } catch (e) {
           // Support both throwing and returning TASK_CANCELLED
           if (e === TASK_CANCELLED) {
diff --git a/ui/src/base/async_memo_unittest.ts b/ui/src/base/async_memo_unittest.ts
index 2685c4c..d691f34 100644
--- a/ui/src/base/async_memo_unittest.ts
+++ b/ui/src/base/async_memo_unittest.ts
@@ -218,40 +218,6 @@
   expect(queryFn).toHaveBeenCalledTimes(1);
 });
 
-test('disabled memo returns retained data without computing', async () => {
-  const slot = new AsyncMemo<number>();
-  const retainOn: Array<'table'> = ['table'];
-
-  slot.use({key: {table: 'a'}, compute: async () => 1, retainOn});
-  await flushPromises();
-
-  // While a dependency is rebuilt the memo is disabled: nothing is scheduled,
-  // so it's not pending, but the data retained from the old key is returned.
-  const compute = vi.fn().mockResolvedValue(2);
-  const disabled = slot.use({
-    key: {table: ''},
-    compute,
-    enabled: false,
-    retainOn,
-  });
-  await flushPromises();
-  expect(disabled).toEqual({data: 1, isPending: false});
-  expect(compute).not.toHaveBeenCalled();
-
-  // Once enabled, it computes for the new key, showing stale data meanwhile.
-  const pending = slot.use({
-    key: {table: 'b'},
-    compute,
-    enabled: true,
-    retainOn,
-  });
-  expect(pending).toEqual({data: 1, isPending: true});
-  await flushPromises();
-  const done = slot.use({key: {table: 'b'}, compute, enabled: true, retainOn});
-  expect(done).toEqual({data: 2, isPending: false});
-  expect(compute).toHaveBeenCalledTimes(1);
-});
-
 test('use after dispose throws', async () => {
   const slot = new AsyncMemo<number>();
 
@@ -294,7 +260,7 @@
   expect(queryFn2).not.toHaveBeenCalled();
 });
 
-test('AsyncDisposable is disposed before running next queryFn', async () => {
+test('AsyncDisposable is disposed after next queryFn replaces it', async () => {
   const slot = new AsyncMemo<AsyncDisposable>();
 
   const events: string[] = [];
@@ -327,14 +293,165 @@
 
   expect(events).toEqual(['query1']);
 
-  // Second query with different key - should dispose first before running second
+  // Second query with different key - should dispose first after running second
   slot.use({key: {id: 2}, compute: queryFn2});
   await flushPromises();
 
-  expect(events).toEqual(['query1', 'dispose1', 'query2']);
+  expect(events).toEqual(['query1', 'query2', 'dispose1']);
   expect(disposable1[Symbol.asyncDispose]).toHaveBeenCalledTimes(1);
 });
 
+test('retainOn keeps AsyncDisposable alive until replaced', async () => {
+  const slot = new AsyncMemo<AsyncDisposable>();
+
+  const events: string[] = [];
+  let resolveQuery2: () => void;
+  const query2Promise = new Promise<void>((resolve) => {
+    resolveQuery2 = resolve;
+  });
+
+  const disposable1: AsyncDisposable = {
+    [Symbol.asyncDispose]: vi.fn().mockImplementation(async () => {
+      events.push('dispose1');
+    }),
+  };
+
+  const disposable2: AsyncDisposable = {
+    [Symbol.asyncDispose]: vi.fn().mockImplementation(async () => {
+      events.push('dispose2');
+    }),
+  };
+
+  const queryFn1 = vi.fn().mockImplementation(async () => {
+    events.push('query1');
+    return disposable1;
+  });
+
+  const queryFn2 = vi.fn().mockImplementation(async () => {
+    events.push('query2-start');
+    await query2Promise;
+    events.push('query2-end');
+    return disposable2;
+  });
+
+  // First query
+  slot.use({
+    key: {filter: 'a', page: 1},
+    compute: queryFn1,
+    retainOn: ['page'],
+  });
+  await flushPromises();
+
+  // Change only page (in retainOn) while query2 is in-flight
+  slot.use({
+    key: {filter: 'a', page: 2},
+    compute: queryFn2,
+    retainOn: ['page'],
+  });
+  await flushPromises();
+
+  // The previous disposable should still be returned and not yet disposed
+  const pending = slot.use({
+    key: {filter: 'a', page: 2},
+    compute: queryFn2,
+    retainOn: ['page'],
+  });
+  expect(pending.data).toBe(disposable1);
+  expect(pending.isPending).toBe(true);
+  expect(events).toEqual(['query1', 'query2-start']);
+
+  // Complete query2
+  resolveQuery2!();
+  await flushPromises();
+
+  // The previous disposable should only be disposed once replaced
+  const done = slot.use({
+    key: {filter: 'a', page: 2},
+    compute: queryFn2,
+    retainOn: ['page'],
+  });
+  expect(done.data).toBe(disposable2);
+  expect(done.isPending).toBe(false);
+  expect(events).toEqual(['query1', 'query2-start', 'query2-end', 'dispose1']);
+  expect(disposable1[Symbol.asyncDispose]).toHaveBeenCalledTimes(1);
+  expect(disposable2[Symbol.asyncDispose]).not.toHaveBeenCalled();
+});
+
+test('retained AsyncDisposable outlives tasks queued against it', async () => {
+  const queue = new AtomicTaskQueue();
+  const tableSlot = new AsyncMemo<AsyncDisposable>(queue);
+  const dataSlot = new AsyncMemo<string>(queue);
+
+  const events: string[] = [];
+  let resolveBuild2: () => void;
+  const build2Promise = new Promise<void>((resolve) => {
+    resolveBuild2 = resolve;
+  });
+
+  let table1Disposed = false;
+  const table1: AsyncDisposable = {
+    [Symbol.asyncDispose]: vi.fn().mockImplementation(async () => {
+      table1Disposed = true;
+      events.push('dispose1');
+    }),
+  };
+  const table2: AsyncDisposable = {
+    [Symbol.asyncDispose]: vi.fn().mockImplementation(async () => {
+      events.push('dispose2');
+    }),
+  };
+
+  const build1 = vi.fn().mockImplementation(async () => {
+    events.push('build1');
+    return table1;
+  });
+  const build2 = vi.fn().mockImplementation(async () => {
+    events.push('build2-start');
+    await build2Promise;
+    events.push('build2-end');
+    return table2;
+  });
+
+  tableSlot.use({key: {src: 'a'}, compute: build1, retainOn: ['src']});
+  await flushPromises();
+
+  // Change the source (in retainOn) - table2 starts building
+  tableSlot.use({key: {src: 'b'}, compute: build2, retainOn: ['src']});
+  await flushPromises();
+  expect(events).toEqual(['build1', 'build2-start']);
+
+  // While table2 is building, a dependent task is queued against the retained
+  // table1.
+  const retained = tableSlot.use({
+    key: {src: 'b'},
+    compute: build2,
+    retainOn: ['src'],
+  });
+  expect(retained.data).toBe(table1);
+  dataSlot.use({
+    key: {table: 1},
+    compute: async () => {
+      events.push(`fetch1 (disposed=${table1Disposed})`);
+      return 'data1';
+    },
+  });
+
+  // Complete table2 - table1 must not be disposed until the fetch has run
+  resolveBuild2!();
+  await flushPromises();
+  await flushPromises();
+
+  expect(events).toEqual([
+    'build1',
+    'build2-start',
+    'build2-end',
+    'fetch1 (disposed=false)',
+    'dispose1',
+  ]);
+  expect(table1[Symbol.asyncDispose]).toHaveBeenCalledTimes(1);
+  expect(table2[Symbol.asyncDispose]).not.toHaveBeenCalled();
+});
+
 test('slot dispose calls AsyncDisposable dispose after in-flight task completes', async () => {
   const slot = new AsyncMemo<AsyncDisposable>();
 
diff --git a/ui/src/base/bezier_arrow.ts b/ui/src/base/bezier_arrow.ts
index 4e444df..4239f62 100644
--- a/ui/src/base/bezier_arrow.ts
+++ b/ui/src/base/bezier_arrow.ts
@@ -188,9 +188,9 @@
   });
 
   ctx.beginPath();
-  ctx.moveTo(transformedPoints[0].x, transformedPoints[0].y);
-  ctx.lineTo(transformedPoints[1].x, transformedPoints[1].y);
-  ctx.lineTo(transformedPoints[2].x, transformedPoints[2].y);
+  ctx.moveTo(transformedPoints[0]!.x, transformedPoints[0]!.y);
+  ctx.lineTo(transformedPoints[1]!.x, transformedPoints[1]!.y);
+  ctx.lineTo(transformedPoints[2]!.x, transformedPoints[2]!.y);
   ctx.closePath();
   ctx.fill();
 }
diff --git a/ui/src/base/binary_search.ts b/ui/src/base/binary_search.ts
index 211a28b..5a9665c 100644
--- a/ui/src/base/binary_search.ts
+++ b/ui/src/base/binary_search.ts
@@ -23,11 +23,11 @@
 ): number {
   if (i === j) return -1;
   if (i + 1 === j) {
-    return needle >= haystack[i] ? i : -1;
+    return needle >= haystack[i]! ? i : -1;
   }
 
   const mid = Math.floor((j - i) / 2) + i;
-  const midValue = haystack[mid];
+  const midValue = haystack[mid]!;
   if (needle < midValue) {
     return searchImpl(haystack, needle, i, mid);
   } else {
@@ -43,7 +43,7 @@
 ): Range {
   if (i === j) return [i, j];
   if (i + 1 === j) {
-    if (haystack[i] <= needle) {
+    if (haystack[i]! <= needle) {
       return [i, j];
     } else {
       return [i, i];
@@ -51,7 +51,7 @@
   }
 
   const mid = Math.floor((j - i) / 2) + i;
-  const midValue = haystack[mid];
+  const midValue = haystack[mid]!;
 
   if (needle < midValue) {
     return searchRangeImpl(haystack, needle, i, mid);
diff --git a/ui/src/base/canvas2d_renderer.ts b/ui/src/base/canvas2d_renderer.ts
index ffded3a..5a2cd1c 100644
--- a/ui/src/base/canvas2d_renderer.ts
+++ b/ui/src/base/canvas2d_renderer.ts
@@ -86,9 +86,9 @@
 
     for (let i = 0; i < count; i++) {
       // Transform X from data space to screen space (centered)
-      const screenX = xs[i] * scale + offset;
-      const y = rowTopFromLayout(rowLayout, depths[i]);
-      const h = rowHeightFromLayout(rowLayout, depths[i]);
+      const screenX = xs[i]! * scale + offset;
+      const y = rowTopFromLayout(rowLayout, depths[i]!);
+      const h = rowHeightFromLayout(rowLayout, depths[i]!);
 
       // CPU-side culling
       if (clip !== undefined) {
@@ -107,7 +107,7 @@
       }
 
       // Convert packed RGBA (0xRRGGBBAA) to CSS string
-      const rgba = colors[i];
+      const rgba = colors[i]!;
       if (previousColor !== rgba) {
         const r = (rgba >> 24) & 0xff;
         const g = (rgba >> 16) & 0xff;
@@ -135,15 +135,15 @@
     let previousColor: number | undefined = undefined;
 
     for (let i = 0; i < count; i++) {
-      const depth = depths[i];
+      const depth = depths[i]!;
 
       // Compute row position from two-tier formula
       const y = rowTopFromLayout(rowLayout, depth);
       const h = rowHeightFromLayout(rowLayout, depth);
 
       // Transform X from data coordinates to screen coordinates
-      const startPx = starts[i] * scale + offset;
-      const rawEndPx = ends[i] * scale + offset;
+      const startPx = starts[i]! * scale + offset;
+      const rawEndPx = ends[i]! * scale + offset;
       // Inset the right edge so adjacent slices stay visually distinct.
       const endPx = Math.max(startPx + 1, rawEndPx - SLICE_GAP_PX);
       const w = Math.max(endPx - startPx, 1);
@@ -184,7 +184,7 @@
       }
 
       // Convert packed RGBA (0xRRGGBBAA) to CSS string
-      const rgba = colors[i];
+      const rgba = colors[i]!;
       if (previousColor !== rgba) {
         const r = (rgba >> 24) & 0xff;
         const g = (rgba >> 16) & 0xff;
@@ -196,7 +196,7 @@
       }
       ctx.fillRect(drawX, drawY, drawW, drawH);
 
-      const flags = patterns[i];
+      const flags = patterns[i]!;
       if (flags & RECT_PATTERN_HATCHED && w >= 5) {
         ctx.fillStyle = getHatchedPattern(ctx);
         ctx.fillRect(drawX, drawY, drawW, drawH);
@@ -246,8 +246,8 @@
 
     for (let i = 0; i < count; i++) {
       // Compute segment bounds
-      const x = Math.round(tx(xs[i]));
-      const nextX = Math.round(tx(xnext[i]));
+      const x = Math.round(tx(xs[i]!));
+      const nextX = Math.round(tx(xnext[i]!));
 
       // Don't render segments that are fully outside the clip region
       if (clip) {
@@ -260,10 +260,10 @@
         if (physX >= clip.right) break;
       }
 
-      const y = ty(ys[i]);
-      const minY = ty(minYs[i]);
-      const maxY = ty(maxYs[i]);
-      const fill = fillAlpha[i];
+      const y = ty(ys[i]!);
+      const minY = ty(minYs[i]!);
+      const maxY = ty(maxYs[i]!);
+      const fill = fillAlpha[i]!;
 
       // If fillAlpha is close to zero, don't draw anything at all
       if (fill >= 0.01) {
diff --git a/ui/src/base/canvas2d_renderer_unittest.ts b/ui/src/base/canvas2d_renderer_unittest.ts
index db02b41..e258460 100644
--- a/ui/src/base/canvas2d_renderer_unittest.ts
+++ b/ui/src/base/canvas2d_renderer_unittest.ts
@@ -45,6 +45,6 @@
 
     expect(rects.length).toBe(2);
     const [a, b] = rects;
-    expect(b.x - (a.x + a.w)).toBeCloseTo(SLICE_GAP_PX);
+    expect(b!.x - (a!.x + a!.w)).toBeCloseTo(SLICE_GAP_PX);
   });
 });
diff --git a/ui/src/base/color.ts b/ui/src/base/color.ts
index 81e753e..47aa47e2 100644
--- a/ui/src/base/color.ts
+++ b/ui/src/base/color.ts
@@ -244,9 +244,9 @@
   let b: number = 0;
 
   if (hex.length === 4) {
-    r = parseInt(hex[1] + hex[1], 16);
-    g = parseInt(hex[2] + hex[2], 16);
-    b = parseInt(hex[3] + hex[3], 16);
+    r = parseInt(hex[1]! + hex[1]!, 16);
+    g = parseInt(hex[2]! + hex[2]!, 16);
+    b = parseInt(hex[3]! + hex[3]!, 16);
   } else if (hex.length === 7) {
     r = parseInt(hex.substring(1, 3), 16);
     g = parseInt(hex.substring(3, 5), 16);
diff --git a/ui/src/base/comparison_utils.ts b/ui/src/base/comparison_utils.ts
index 555ee25..e6c15f8 100644
--- a/ui/src/base/comparison_utils.ts
+++ b/ui/src/base/comparison_utils.ts
@@ -78,10 +78,10 @@
   if (a instanceof Uint8Array && b instanceof Uint8Array) {
     // Do the lexicographical comparison
     for (let i = 0; i < a.length && i < b.length; i++) {
-      if (a[i] < b[i]) {
+      if (a[i]! < b[i]!) {
         return -1;
       }
-      if (a[i] > b[i]) {
+      if (a[i]! > b[i]!) {
         return 1;
       }
     }
diff --git a/ui/src/base/fuzzy.ts b/ui/src/base/fuzzy.ts
index 7291948..d3389b4 100644
--- a/ui/src/base/fuzzy.ts
+++ b/ui/src/base/fuzzy.ts
@@ -75,7 +75,7 @@
     const result = fuzzySearchMultiKey(items, [keyLookup], searchTerm);
     return result.map((res) => ({
       item: res.item,
-      segments: res.segments[0],
+      segments: res.segments[0]!,
       score: res.score,
     }));
   } else {
diff --git a/ui/src/base/fuzzy_unittest.ts b/ui/src/base/fuzzy_unittest.ts
index 488538c..24935b5 100644
--- a/ui/src/base/fuzzy_unittest.ts
+++ b/ui/src/base/fuzzy_unittest.ts
@@ -95,7 +95,7 @@
       ];
       const results = fuzzySearch(items, (x) => x, 'trace');
       for (let i = 0; i < results.length - 1; i++) {
-        expect(results[i].score).toBeGreaterThanOrEqual(results[i + 1].score);
+        expect(results[i]!.score).toBeGreaterThanOrEqual(results[i + 1]!.score);
       }
     });
 
@@ -123,20 +123,20 @@
 
     it('produces valid matching segments for exact match', () => {
       const results = fuzzySearch(['foo'], (x) => x, 'foo');
-      expect(results[0].segments).toEqual([{matching: true, value: 'foo'}]);
+      expect(results[0]!.segments).toEqual([{matching: true, value: 'foo'}]);
     });
 
     it('produces non-matching single segment for empty search term', () => {
       const results = fuzzySearch(['foo'], (x) => x, '');
-      expect(results[0].segments).toEqual([{matching: false, value: 'foo'}]);
+      expect(results[0]!.segments).toEqual([{matching: false, value: 'foo'}]);
     });
 
     it('correctly splits matching and non-matching segments', () => {
       const results = fuzzySearch(['ababc'], (x) => x, 'abc');
       expect(results.length).toBe(1);
-      const reconstructed = results[0].segments.map((s) => s.value).join('');
+      const reconstructed = results[0]!.segments.map((s) => s.value).join('');
       expect(reconstructed).toBe('ababc');
-      const matchedText = results[0].segments
+      const matchedText = results[0]!.segments
         .filter((s) => s.matching)
         .map((s) => s.value)
         .join('');
@@ -173,10 +173,10 @@
       const results = fuzzySearch(items, keyLookups, 'Data');
       expect(results.length).toBeGreaterThan(0);
       for (const res of results) {
-        expect(res.segments[0].map((s) => s.value).join('')).toBe(
+        expect(res.segments[0]!.map((s) => s.value).join('')).toBe(
           res.item.name,
         );
-        expect(res.segments[1].map((s) => s.value).join('')).toBe(
+        expect(res.segments[1]!.map((s) => s.value).join('')).toBe(
           res.item.source,
         );
       }
@@ -186,13 +186,13 @@
       const results = fuzzySearch(items, keyLookups, '');
       expect(results.length).toBe(items.length);
       for (let i = 0; i < items.length; i++) {
-        expect(results[i].item).toEqual(items[i]);
-        expect(results[i].score).toBe(1);
-        expect(results[i].segments[0]).toEqual([
-          {matching: false, value: items[i].name},
+        expect(results[i]!.item).toEqual(items[i]);
+        expect(results[i]!.score).toBe(1);
+        expect(results[i]!.segments[0]).toEqual([
+          {matching: false, value: items[i]!.name},
         ]);
-        expect(results[i].segments[1]).toEqual([
-          {matching: false, value: items[i].source},
+        expect(results[i]!.segments[1]).toEqual([
+          {matching: false, value: items[i]!.source},
         ]);
       }
     });
@@ -200,7 +200,7 @@
     it('orders multi-key results by overall match score', () => {
       const results = fuzzySearch(items, keyLookups, 'Data');
       for (let i = 0; i < results.length - 1; i++) {
-        expect(results[i].score).toBeGreaterThanOrEqual(results[i + 1].score);
+        expect(results[i]!.score).toBeGreaterThanOrEqual(results[i + 1]!.score);
       }
     });
   });
diff --git a/ui/src/base/gl/sdf.ts b/ui/src/base/gl/sdf.ts
index 83a307e..c9485db 100644
--- a/ui/src/base/gl/sdf.ts
+++ b/ui/src/base/gl/sdf.ts
@@ -38,8 +38,8 @@
   const n = vertices.length;
 
   for (let i = 0, j = n - 1; i < n; j = i++) {
-    const vi = vertices[i];
-    const vj = vertices[j];
+    const vi = vertices[i]!;
+    const vj = vertices[j]!;
 
     // Ray casting: count edge crossings to the right of the point
     if (
@@ -62,8 +62,8 @@
   // Find minimum distance to any edge
   let minDist = Infinity;
   for (let i = 0; i < n; i++) {
-    const a = vertices[i];
-    const b = vertices[(i + 1) % n];
+    const a = vertices[i]!;
+    const b = vertices[(i + 1) % n]!;
     minDist = Math.min(minDist, sdSegment(p, a, b));
   }
 
diff --git a/ui/src/base/high_precision_time_span_unittest.ts b/ui/src/base/high_precision_time_span_unittest.ts
index 521af94..bcd5e41 100644
--- a/ui/src/base/high_precision_time_span_unittest.ts
+++ b/ui/src/base/high_precision_time_span_unittest.ts
@@ -27,7 +27,7 @@
   if (array.length > 2) throw new Error(`Bad time format ${time}`);
   const [base, fractions] = array;
   const negative = time.startsWith('-');
-  const numBase = BigInt(base);
+  const numBase = BigInt(base!);
 
   if (fractions) {
     const numFractions = Number(`0.${fractions}`);
diff --git a/ui/src/base/high_precision_time_unittest.ts b/ui/src/base/high_precision_time_unittest.ts
index 28ed90d..c9b56ac 100644
--- a/ui/src/base/high_precision_time_unittest.ts
+++ b/ui/src/base/high_precision_time_unittest.ts
@@ -26,7 +26,7 @@
   if (array.length > 2) throw new Error(`Bad time format ${time}`);
   const [base, fractions] = array;
   const negative = time.startsWith('-');
-  const numBase = BigInt(base);
+  const numBase = BigInt(base!);
 
   if (fractions) {
     const numFractions = Number(`0.${fractions}`);
diff --git a/ui/src/base/hotkeys.ts b/ui/src/base/hotkeys.ts
index ff0a187..768a32b 100644
--- a/ui/src/base/hotkeys.ts
+++ b/ui/src/base/hotkeys.ts
@@ -250,7 +250,9 @@
 
 // Return true if |key| matches the event's key.
 function compareKeys(e: KeyboardEventLike, key: Key): boolean {
-  return e.key.toLowerCase() === key.toLowerCase();
+  // The space bar reports ' ' rather than its name.
+  const eventKey = e.key === ' ' ? 'Space' : e.key;
+  return eventKey.toLowerCase() === key.toLowerCase();
 }
 
 // Return true if modifiers specified in |mods| match those in the event.
diff --git a/ui/src/base/hotkeys_unittest.ts b/ui/src/base/hotkeys_unittest.ts
index 4deac01..3f2e9f6 100644
--- a/ui/src/base/hotkeys_unittest.ts
+++ b/ui/src/base/hotkeys_unittest.ts
@@ -55,6 +55,12 @@
     expect(checkHotkey('Escape', {key: 'Escape'})).toBe(true);
   });
 
+  test('Space', () => {
+    expect(checkHotkey('Space', {key: ' '})).toBe(true);
+    expect(checkHotkey('Space', {key: 's'})).toBe(false);
+    expect(checkHotkey('Shift+Space', {key: ' ', shiftKey: true})).toBe(true);
+  });
+
   test('Shift+A', () => {
     const hotkey: Hotkey = 'Shift+A';
     expect(checkHotkey(hotkey, {key: 'a'})).toBe(false);
diff --git a/ui/src/base/logging.ts b/ui/src/base/logging.ts
index 8fa2714..265b32b 100644
--- a/ui/src/base/logging.ts
+++ b/ui/src/base/logging.ts
@@ -52,7 +52,7 @@
     if (err.error === null || err.error === undefined) {
       // Wasm case.
       const errLines = `${err.message}`.split('\n');
-      errMsg = errLines[0];
+      errMsg = errLines[0]!;
       errorObj = {stack: errLines.slice(1).join('\n')};
     } else {
       // Standard JS case.
diff --git a/ui/src/base/number_format.ts b/ui/src/base/number_format.ts
index 1e25fb4..b5a7775 100644
--- a/ui/src/base/number_format.ts
+++ b/ui/src/base/number_format.ts
@@ -164,8 +164,8 @@
   value: number,
   prefixes: [number, string][],
 ): {mantissa: number; prefix: string} {
-  let multiplier = prefixes[0][0];
-  let prefix = prefixes[0][1];
+  let multiplier = prefixes[0]![0];
+  let prefix = prefixes[0]![1];
   const absV = Math.abs(value);
   for (const [m, p] of prefixes) {
     if (m > absV) break;
diff --git a/ui/src/base/object_utils.ts b/ui/src/base/object_utils.ts
index 80529ee..0bc47be 100644
--- a/ui/src/base/object_utils.ts
+++ b/ui/src/base/object_utils.ts
@@ -12,76 +12,6 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-import {ensureExists} from './assert';
-import {exists} from './utils';
-
-export type PathKey = string | number;
-export type Path = PathKey[];
-
-/**
- * Gets the |value| at a |path| of |object|. If a portion of the path doesn't
- * exist, |undefined| is returned.
- *
- * Example:
- * const obj = {
- *   a: [
- *     {b: 'c'},
- *     {d: 'e', f: 123},
- *   ],
- * };
- * getPath(obj, ['a']) -> [{b: 'c'}, {d: 'e', f: 123}]
- * getPath(obj, ['a', 1]) -> {d: 'e', f: 123}
- * getPath(obj, ['a', 1, 'd']) -> 'e'
- * getPath(obj, ['g']) -> undefined
- * getPath(obj, ['g', 'h']) -> undefined
- *
- * Note: This is an appropriate use of `any`, as we are knowingly getting fast
- * and loose with the type system in this function: it's basically JavaScript.
- * Attempting to pretend it's anything else would result in superfluous type
- * assertions which would serve no benefit.
- */
-// eslint-disable-next-line @typescript-eslint/no-explicit-any
-export function getPath<T>(obj: any, path: Path): T | undefined {
-  let x = obj;
-  for (const node of path) {
-    if (x === undefined) return undefined;
-    x = x[node];
-  }
-  return x;
-}
-
-/**
- * Sets the |value| at |path| of |object|. If the final node of the path doesn't
- * exist, the value will be created. Otherwise, TypeError is thrown.
- *
- * Example:
- * const obj = {
- *   a: [
- *     {b: 'c'},
- *     {d: 'e', f: 123},
- *   ],
- * };
- * setPath(obj, ['a'], 'foo') -> {a: 'foo'}
- * setPath(obj, ['a', 1], 'foo') -> {a: [{b: 'c'}, 'foo']}
- * setPath(obj, ['g'], 'foo') -> {a: [...], g: 'foo'}
- * setPath(obj, ['g', 'h'], 'foo') -> TypeError!
- */
-// eslint-disable-next-line @typescript-eslint/no-explicit-any
-export function setPath<T>(obj: any, path: Path, value: T): void {
-  const pathClone = [...path];
-  let o = obj;
-  while (pathClone.length > 1) {
-    const p = ensureExists(pathClone.shift());
-    o = o[p];
-  }
-
-  const p = pathClone.shift();
-  if (!exists(p)) {
-    throw TypeError('Path array is empty');
-  }
-  o[p] = value;
-}
-
 export function shallowEquals(a: unknown, b: unknown) {
   if (a === b) {
     return true;
@@ -118,3 +48,13 @@
 ): value is T[keyof T] {
   return Object.values(enm).includes(value);
 }
+
+/**
+ * Recursively freezes an object and all its properties to prevent mutation.
+ */
+export function deepFreeze<T>(obj: T): T {
+  if (obj === null || typeof obj !== 'object') return obj;
+  Object.freeze(obj);
+  Object.values(obj).forEach(deepFreeze);
+  return obj;
+}
diff --git a/ui/src/base/object_utils_unittest.ts b/ui/src/base/object_utils_unittest.ts
index 6be2931..d392b4d 100644
--- a/ui/src/base/object_utils_unittest.ts
+++ b/ui/src/base/object_utils_unittest.ts
@@ -12,70 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-import {getPath, setPath, shallowEquals} from './object_utils';
-
-describe('getPath', () => {
-  const nested = {quux: 'qux'};
-  const value = {
-    foo: {
-      bar: [1, 2, 3],
-    },
-    baz: nested,
-  };
-
-  test('happy path', () => {
-    expect(getPath(value, ['foo', 'bar', 1])).toBe(2);
-    expect(getPath(value, ['foo', 'bar', 2])).toBe(3);
-    expect(getPath(value, ['foo', 'bar'])).toEqual([1, 2, 3]);
-    expect(getPath(value, ['foo'])).toEqual({bar: [1, 2, 3]});
-    expect(getPath(value, [])).toBe(value);
-    expect(getPath(value, ['baz'])).toBe(nested);
-  });
-
-  it('returns undefined when path is incomplete', () => {
-    // value.quux does not exist so we expect undefined to be returned
-    expect(getPath(value, ['quux'])).toBe(undefined);
-    expect(getPath(value, ['quux', 'corge'])).toBe(undefined);
-  });
-});
-
-describe('setPath', () => {
-  const nested = {quux: 'qux'};
-  const value = {
-    foo: {
-      bar: [1, 2, 3],
-    },
-    baz: nested,
-  };
-
-  test('happy path', () => {
-    setPath(value, ['foo', 'bar', 1], 10);
-    expect(value).toEqual({
-      foo: {
-        bar: [1, 10, 3],
-      },
-      baz: nested,
-    });
-  });
-
-  it('appends node when target node is missing', () => {
-    setPath(value, ['quux'], 'abc');
-    expect((value as unknown as {quux: string})['quux']).toBe('abc');
-  });
-
-  it('throws when path node(s) are missing', () => {
-    // value.quux does not exist, so setting value.quux.corge is an error.
-    expect(() => {
-      setPath(value, ['quux', 'corge'], 'abc');
-    }).toThrowError(TypeError);
-  });
-
-  it('throws when path is empty', () => {
-    expect(() => {
-      setPath(value, [], 'abc');
-    }).toThrowError(TypeError);
-  });
-});
+import {deepFreeze, shallowEquals} from './object_utils';
 
 test('shallowEquals', () => {
   const one = 1;
@@ -94,3 +31,43 @@
   expect(shallowEquals({nestedFoo}, {nestedFoo})).toBe(true);
   expect(shallowEquals({nestedFoo}, {nestedFooDupe})).toBe(false);
 });
+
+describe('deepFreeze', () => {
+  test('returns primitives and null unchanged', () => {
+    expect(deepFreeze(42)).toBe(42);
+    expect(deepFreeze('hello')).toBe('hello');
+    expect(deepFreeze(true)).toBe(true);
+    expect(deepFreeze(null)).toBe(null);
+    expect(deepFreeze(undefined)).toBe(undefined);
+  });
+
+  test('recursively freezes nested objects and arrays', () => {
+    const obj = {
+      a: 1,
+      nested: {
+        b: 'two',
+        arr: [{c: 3}, 4],
+      },
+    };
+
+    const frozen = deepFreeze(obj);
+    expect(frozen).toBe(obj);
+    expect(Object.isFrozen(frozen)).toBe(true);
+    expect(Object.isFrozen(frozen.nested)).toBe(true);
+    expect(Object.isFrozen(frozen.nested.arr)).toBe(true);
+    expect(Object.isFrozen(frozen.nested.arr[0])).toBe(true);
+
+    expect(() => {
+      frozen.a = 2;
+    }).toThrow(TypeError);
+    expect(() => {
+      frozen.nested.b = 'three';
+    }).toThrow(TypeError);
+    expect(() => {
+      frozen.nested.arr.push(5);
+    }).toThrow(TypeError);
+    expect(() => {
+      (frozen.nested.arr[0] as {c: number}).c = 99;
+    }).toThrow(TypeError);
+  });
+});
diff --git a/ui/src/base/source_map_utils.ts b/ui/src/base/source_map_utils.ts
index 20aafe1..3dc6d46 100644
--- a/ui/src/base/source_map_utils.ts
+++ b/ui/src/base/source_map_utils.ts
@@ -69,7 +69,7 @@
 
   // Try exact match first
   if (bundleFileName in registry) {
-    return registry[bundleFileName];
+    return registry[bundleFileName]!;
   }
 
   // Try to find by partial match (handles different path prefixes)
@@ -114,7 +114,7 @@
 
     do {
       if (i >= encoded.length) break;
-      const digit = BASE64_CHARS.indexOf(encoded[i++]);
+      const digit = BASE64_CHARS.indexOf(encoded[i++]!);
       if (digit === -1) {
         // Handle invalid characters gracefully, though source maps should be valid
         continuation = 0;
@@ -157,15 +157,15 @@
       const decoded = decodeVLQ(segment);
       if (decoded.length === 0) continue;
 
-      genCol += decoded[0];
+      genCol += decoded[0]!;
 
       if (decoded.length >= 4) {
-        sourceIndex += decoded[1];
-        sourceLine += decoded[2];
-        sourceCol += decoded[3];
+        sourceIndex += decoded[1]!;
+        sourceLine += decoded[2]!;
+        sourceCol += decoded[3]!;
         const hasName = decoded.length >= 5;
         if (hasName) {
-          nameIndex += decoded[4];
+          nameIndex += decoded[4]!;
         }
 
         segments.push({
@@ -198,7 +198,7 @@
 
   while (left <= right) {
     const mid = Math.floor((left + right) / 2);
-    const segment = segments[mid];
+    const segment = segments[mid]!;
 
     if (segment.genCol <= targetCol) {
       // This could be a match, but check if there's a better one to the right
@@ -230,7 +230,7 @@
     return {source: null, line: null, column: null, name: null};
   }
 
-  const segments = processed.lineSegments[targetLine];
+  const segments = processed.lineSegments[targetLine]!;
   const bestMatch = binarySearchSegment(segments, column);
 
   if (
@@ -246,10 +246,10 @@
       hasNames &&
       bestMatch.nameIndex >= 0 &&
       bestMatch.nameIndex < sourceMap.names.length
-        ? sourceMap.names[bestMatch.nameIndex]
+        ? sourceMap.names[bestMatch.nameIndex]!
         : null;
     return {
-      source: sourceMap.sources[bestMatch.sourceIndex],
+      source: sourceMap.sources[bestMatch.sourceIndex]!,
       line: bestMatch.sourceLine + 1,
       column: bestMatch.sourceCol,
       name,
@@ -273,9 +273,9 @@
       continue;
     }
 
-    const file = match[1];
-    const lineNum = parseInt(match[2], 10);
-    const colNum = parseInt(match[3], 10);
+    const file = match[1]!;
+    const lineNum = parseInt(match[2]!, 10);
+    const colNum = parseInt(match[3]!, 10);
 
     try {
       // Extract just the filename from the path
diff --git a/ui/src/base/store.ts b/ui/src/base/store.ts
deleted file mode 100644
index 7e9128e..0000000
--- a/ui/src/base/store.ts
+++ /dev/null
@@ -1,208 +0,0 @@
-// 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 {produce, type Draft} from 'immer';
-import {getPath, type Path, setPath} from './object_utils';
-
-export type Migrate<T> = (init: unknown) => T;
-export type Edit<T> = (draft: Draft<T>) => void;
-
-/**
- * Create a new root-level store.
- *
- * @template T The type of this store's state.
- * @param {T} initialState Initial state of the store.
- * @returns {Store<T>} The newly created store.
- */
-export function createStore<T>(initialState: T): Store<T> {
-  return new RootStore<T>(initialState);
-}
-
-export interface Store<T> {
-  /**
-   * Access the immutable state of this store.
-   */
-  get state(): T;
-
-  /**
-   * Mutate the store's state.
-   *
-   * @param edits The edit (or edits) to the store.
-   */
-  edit(edits: Edit<T> | Edit<T>[]): void;
-
-  /**
-   * Create a sub-store from a subtree of the state from this store.
-   *
-   * The returned store looks and feels like a regular store but acts only on a
-   * specific subtree of its parent store. Reads are writes are channelled
-   * through to the parent store via the |migrate| function.
-   *
-   * |migrate| is called the first time we access our sub-store's state and
-   * whenever the subtree changes in the root store.
-   * This migrate function takes the state of the subtree from the sub-store's
-   * parent store which has unknown type and is responsible for returning a
-   * value whose type matches that of the sub-store's state.
-   *
-   * Sub-stores may be created over the top of subtrees which are not yet fully
-   * defined. The state is written to the parent store on first edit. The
-   * sub-store can also deal with the underlying subtree becoming undefined
-   * again at some point in the future, and so is robust to unpredictable
-   * changes to the root store.
-   *
-   * @template U The type of the sub-store's state.
-   * @param path The path to the subtree this sub-store is based on.
-   * @example
-   * // Given a store whose state takes the form:
-   * {
-   *   foo: {
-   *     bar: [ {baz: 123}, {baz: 42} ],
-   *   },
-   * }
-   *
-   * // A sub-store crated on path: ['foo','bar', 1] would only see the state:
-   * {
-   *   baz: 42,
-   * }
-   * @param migrate A function used to migrate from the parent store's subtree
-   * to the sub-store's state.
-   * @example
-   * interface RootState {dict: {[key: string]: unknown}};
-   * interface SubState {foo: string};
-   *
-   * const store = createStore({dict: {}});
-   * const migrate = (init: unknown) => (init ?? {foo: 'bar'}) as SubState;
-   * const subStore = store.createSubStore(store, ['dict', 'foo'], migrate);
-   * // |dict['foo']| will be created the first time we edit our sub-store.
-   * Warning: Migration functions should properly validate the incoming state.
-   * Blindly using type assertions can lead to instability.
-   * @returns {Store<U>} The newly created sub-store.
-   */
-  createSubStore<U>(path: Path, migrate: Migrate<U>): Store<U>;
-}
-
-/**
- * This class implements a standalone store (i.e. one that does not depend on a
- * subtree of another store).
- * @template T The type of the store's state.
- */
-class RootStore<T> implements Store<T> {
-  private internalState: T;
-
-  constructor(initialState: T) {
-    // Run initial state through immer to take advantage of auto-freezing
-    this.internalState = produce(initialState, () => {});
-  }
-
-  get state() {
-    return this.internalState;
-  }
-
-  edit(edit: Edit<T> | Edit<T>[]): void {
-    if (Array.isArray(edit)) {
-      this.applyEdits(edit);
-    } else {
-      this.applyEdits([edit]);
-    }
-  }
-
-  private applyEdits(edits: Edit<T>[]): void {
-    const newState = edits.reduce((state, edit) => {
-      return produce(state, edit);
-    }, this.internalState);
-
-    this.internalState = newState;
-  }
-
-  createSubStore<U>(path: Path, migrate: Migrate<U>): Store<U> {
-    return new SubStore(this, path, migrate);
-  }
-}
-
-/**
- * This class implements a sub-store, one that is based on a subtree of another
- * store. The parent store can be a root level store or another sub-store.
- *
- * This particular implementation of a sub-tree implements a write-through cache
- * style implementation. The sub-store's state is cached internally and all
- * edits are written through to the parent store as with a best-effort approach.
- * If the subtree does not exist in the parent store, an error is printed to
- * the console but the operation is still treated as a success.
- *
- * @template T The type of the sub-store's state.
- * @template ParentT The type of the parent store's state.
- */
-class SubStore<T, ParentT> implements Store<T> {
-  private parentState: unknown;
-  private cachedState: T;
-
-  constructor(
-    private readonly parentStore: Store<ParentT>,
-    private readonly path: Path,
-    private readonly migrate: (init: unknown) => T,
-  ) {
-    this.parentState = getPath<unknown>(this.parentStore.state, this.path);
-
-    // Run initial state through immer to take advantage of auto-freezing
-    this.cachedState = produce(migrate(this.parentState), () => {});
-  }
-
-  get state(): T {
-    const parentState = getPath<unknown>(this.parentStore.state, this.path);
-    if (this.parentState === parentState) {
-      return this.cachedState;
-    } else {
-      this.parentState = parentState;
-      return (this.cachedState = produce(this.cachedState, () => {
-        return this.migrate(parentState);
-      }));
-    }
-  }
-
-  edit(edit: Edit<T> | Edit<T>[]): void {
-    if (Array.isArray(edit)) {
-      this.applyEdits(edit);
-    } else {
-      this.applyEdits([edit]);
-    }
-  }
-
-  private applyEdits(edits: Edit<T>[]): void {
-    const newState = edits.reduce((state, edit) => {
-      return produce(state, edit);
-    }, this.cachedState);
-
-    this.parentState = newState;
-    try {
-      this.parentStore.edit((draft) => {
-        setPath(draft, this.path, newState);
-      });
-    } catch (error) {
-      if (error instanceof TypeError) {
-        console.warn('Failed to update parent store at ', this.path);
-      } else {
-        throw error;
-      }
-    }
-
-    this.cachedState = newState;
-  }
-
-  createSubStore<SubtreeState>(
-    path: Path,
-    migrate: Migrate<SubtreeState>,
-  ): Store<SubtreeState> {
-    return new SubStore(this, path, migrate);
-  }
-}
diff --git a/ui/src/base/store_unittest.ts b/ui/src/base/store_unittest.ts
deleted file mode 100644
index f790a88..0000000
--- a/ui/src/base/store_unittest.ts
+++ /dev/null
@@ -1,300 +0,0 @@
-// 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 type {Draft} from 'immer';
-import {createStore} from './store';
-import {exists} from './utils';
-
-interface Bar {
-  value: number;
-}
-
-interface Foo {
-  counter: number;
-  nested: Bar;
-}
-
-function migrateFoo(init: unknown): Foo {
-  const migrated: Foo = {
-    counter: 123,
-    nested: {
-      value: 456,
-    },
-  };
-  if (exists(init) && typeof init === 'object') {
-    if ('counter' in init && typeof init.counter === 'number') {
-      migrated.counter = init.counter;
-    }
-    if ('nested' in init && typeof init.nested === 'object' && init.nested) {
-      if ('value' in init.nested && typeof init.nested.value === 'number') {
-        migrated.nested.value = init.nested.value;
-      }
-    }
-  }
-
-  console.log('migrating', init);
-
-  return migrated;
-}
-
-interface State {
-  foo: Foo;
-}
-
-const initialState: State = {
-  foo: {
-    counter: 0,
-    nested: {
-      value: 42,
-    },
-  },
-};
-
-describe('root store', () => {
-  test('edit', () => {
-    const store = createStore(initialState);
-    store.edit((draft) => {
-      draft.foo.counter += 123;
-    });
-
-    expect(store.state).toEqual({
-      foo: {
-        counter: 123,
-        nested: {
-          value: 42,
-        },
-      },
-    });
-  });
-
-  test('state [in]equality', () => {
-    const store = createStore(initialState);
-    store.edit((draft) => {
-      draft.foo.counter = 88;
-    });
-    expect(store.state).not.toBe(initialState);
-    expect(store.state.foo).not.toBe(initialState.foo);
-    expect(store.state.foo.nested).toBe(initialState.foo.nested);
-  });
-
-  it('can take multiple edits at once', () => {
-    const store = createStore(initialState);
-
-    store.edit([
-      (draft) => {
-        draft.foo.counter += 10;
-      },
-      (draft) => {
-        draft.foo.counter += 10;
-      },
-    ]);
-
-    expect(store.state).toEqual({
-      foo: {
-        counter: 20,
-        nested: {
-          value: 42,
-        },
-      },
-    });
-  });
-
-  it('can support a huge number of edits', () => {
-    const store = createStore(initialState);
-    const N = 100_000;
-    const edits = Array(N).fill((draft: Draft<State>) => {
-      draft.foo.counter++;
-    });
-    store.edit(edits);
-    expect(store.state.foo.counter).toEqual(N);
-  });
-});
-
-describe('sub-store', () => {
-  test('edit', () => {
-    const store = createStore(initialState);
-    const subStore = store.createSubStore<Foo>(['foo'], (x) => x as Foo);
-
-    subStore.edit((draft) => {
-      draft.counter += 1;
-    });
-
-    expect(subStore.state).toEqual({
-      counter: 1,
-      nested: {
-        value: 42,
-      },
-    });
-
-    expect(store.state).toEqual({
-      foo: {
-        counter: 1,
-        nested: {
-          value: 42,
-        },
-      },
-    });
-  });
-
-  test('edit from root store', () => {
-    const store = createStore(initialState);
-    const subStore = store.createSubStore<Foo>(['foo'], (x) => x as Foo);
-
-    store.edit((draft) => {
-      draft.foo.counter += 1;
-    });
-
-    expect(subStore.state).toEqual({
-      counter: 1,
-      nested: {
-        value: 42,
-      },
-    });
-  });
-
-  it('can create more substores and edit', () => {
-    const store = createStore(initialState);
-    const fooState = store.createSubStore<Foo>(['foo'], (x) => x as Foo);
-    const nestedStore = fooState.createSubStore<Bar>(
-      ['nested'],
-      (x) => x as Bar,
-    );
-
-    nestedStore.edit((draft) => {
-      draft.value += 1;
-    });
-
-    expect(nestedStore.state).toEqual({
-      value: 43,
-    });
-  });
-
-  it('handles reading when path doesn\t exist in root store', () => {
-    const store = createStore(initialState);
-
-    // This target node is missing - baz doesn't exist in State
-    const subStore = store.createSubStore<Foo>(['baz'], (x) => x as Foo);
-    expect(subStore.state).toBe(undefined);
-  });
-
-  it("handles edit when path doesn't exist in root store", () => {
-    const store = createStore(initialState);
-    const value: Foo = {
-      counter: 123,
-      nested: {
-        value: 456,
-      },
-    };
-
-    // This target node is missing - baz doesn't exist in State
-    const subStore = store.createSubStore<Foo>(['baz', 'quux'], () => value);
-
-    // Edits should work just fine, but the root store will not be modified.
-    subStore.edit((draft) => {
-      draft.counter += 1;
-    });
-  });
-
-  it('immutable [in]equality works', () => {
-    const store = createStore(initialState);
-    const subStore = store.createSubStore<Foo>(['foo'], migrateFoo);
-    const before = subStore.state;
-
-    subStore.edit((draft) => {
-      draft.counter += 1;
-    });
-
-    const after = subStore.state;
-
-    // something has changed so root should not equal
-    expect(before).not.toBe(after);
-
-    // nested has not changed and so should be the before version.
-    expect(before.nested).toBe(after.nested);
-  });
-
-  // This test depends on the migrate function - if it attempts to preserve
-  // equality then we might have a chance, but our migrate function here does
-  // not, and I'm not sure we can expect people do provide one that does.
-  // TODO(stevegolton): See if we can get this working, regardless of migrate
-  // function implementation.
-  it.skip('unrelated state refs are still equal when modified from root store', () => {
-    const store = createStore(initialState);
-    const subStore = store.createSubStore<Foo>(['foo'], migrateFoo);
-    const before = subStore.state;
-
-    // Check that unrelated state is still the same even though subtree is
-    // modified from the root store
-    store.edit((draft) => {
-      draft.foo.counter = 1234;
-    });
-
-    expect(before.nested).toBe(subStore.state.nested);
-    expect(subStore.state.counter).toBe(1234);
-  });
-
-  it('works when underlying state is undefined', () => {
-    interface RootState {
-      dict: {[key: string]: unknown};
-    }
-    interface ProxyState {
-      bar: string;
-    }
-
-    const store = createStore<RootState>({dict: {}});
-    const migrate = (init: unknown) => (init ?? {bar: 'bar'}) as ProxyState;
-    const subStore = store.createSubStore(['dict', 'foo'], migrate);
-
-    // Check initial migration works, yet underlying store is untouched
-    expect(subStore.state.bar).toBe('bar');
-    expect(store.state.dict['foo']).toBe(undefined);
-
-    // Check updates work
-    subStore.edit((draft) => {
-      draft.bar = 'baz';
-    });
-    expect(subStore.state.bar).toBe('baz');
-    expect((store.state.dict['foo'] as ProxyState).bar).toBe('baz');
-  });
-
-  test('chained substores', () => {
-    interface State {
-      dict: {[key: string]: unknown};
-    }
-
-    interface FooState {
-      bar: {
-        baz: string;
-      };
-    }
-
-    const store = createStore<State>({dict: {}});
-
-    const DEFAULT_FOO_STATE: FooState = {bar: {baz: 'abc'}};
-    const fooStore = store.createSubStore(
-      ['dict', 'foo'],
-      (init) => init ?? DEFAULT_FOO_STATE,
-    );
-
-    const subFooStore = fooStore.createSubStore(
-      ['bar'],
-      (x) => x as FooState['bar'],
-    );
-
-    // Since the entry for 'foo' will be undefined in the dict, we expect the
-    // migrate function on fooStore to return DEFAULT_FOO_STATE, and thus the
-    // state of the subFooStore will be DEFAULT_FOO_STATE.bar.
-    expect(subFooStore.state).toEqual({baz: 'abc'});
-  });
-});
diff --git a/ui/src/base/string_utils.ts b/ui/src/base/string_utils.ts
index b7e3fb8..bf9ab29 100644
--- a/ui/src/base/string_utils.ts
+++ b/ui/src/base/string_utils.ts
@@ -68,7 +68,7 @@
 export function binaryEncode(buf: Uint8Array): string {
   let str = '';
   for (let i = 0; i < buf.length; i++) {
-    str += String.fromCharCode(buf[i]);
+    str += String.fromCharCode(buf[i]!);
   }
   return str;
 }
diff --git a/ui/src/base/touchscreen_handler.ts b/ui/src/base/touchscreen_handler.ts
index 2fd6502..9a6c5d5 100644
--- a/ui/src/base/touchscreen_handler.ts
+++ b/ui/src/base/touchscreen_handler.ts
@@ -101,7 +101,7 @@
 
     if (e.touches.length !== 1) return;
 
-    const t = e.touches[0];
+    const t = e.touches[0]!;
     this.tapStart = t;
     this.tapStartTime = performance.now();
     this.lastTouch = t;
@@ -156,7 +156,7 @@
     // 1. A pan, which is a tapdown followed by a rapid movement.
     // 2. A mouse-like touchmouse_emulation event, which we trigger when the user
     //    taps down and then doesn't move for TAP_TIMEOUT_MS.
-    const t = e.touches[0];
+    const t = e.touches[0]!;
     const dXInit = t.clientX - this.tapStart.clientX;
     const dYInit = t.clientY - this.tapStart.clientY;
     const distSq = dXInit * dXInit + dYInit * dYInit;
@@ -201,7 +201,7 @@
     this.lastPinch = undefined;
 
     if (mode === 'mouse_emulation') {
-      const t = e.changedTouches[0];
+      const t = e.changedTouches[0]!;
       this.callbacks.onTapUp?.({
         deltaX: 0,
         deltaY: 0,
@@ -215,20 +215,20 @@
     if (e.touches.length !== 2) return;
 
     if (this.lastPinch === undefined) {
-      this.lastPinch = [e.touches[0], e.touches[1]];
+      this.lastPinch = [e.touches[0]!, e.touches[1]!];
     }
 
     function distance(t: ArrayLike<Touch>) {
-      const dX = t[0].clientX - t[1].clientX;
-      const dY = t[0].clientY - t[1].clientY;
+      const dX = t[0]!.clientX - t[1]!.clientX;
+      const dY = t[0]!.clientY - t[1]!.clientY;
       return Math.sqrt(dX * dX + dY * dY);
     }
 
-    const delta = Math.round(distance(this.lastPinch) - distance(e.touches));
-    this.lastPinch = [e.touches[0], e.touches[1]];
+    const delta = Math.round(distance(this.lastPinch!) - distance(e.touches));
+    this.lastPinch = [e.touches[0]!, e.touches[1]!];
 
-    const midX = (e.touches[0].clientX + e.touches[1].clientX) / 2;
-    const midY = (e.touches[0].clientY + e.touches[1].clientY) / 2;
+    const midX = (e.touches[0]!.clientX + e.touches[1]!.clientX) / 2;
+    const midY = (e.touches[0]!.clientY + e.touches[1]!.clientY) / 2;
 
     this.callbacks.onPinchZoom?.({
       clientX: Math.round(midX),
diff --git a/ui/src/base/zoned_interaction_handler_unittest.ts b/ui/src/base/zoned_interaction_handler_unittest.ts
index 1a62c71..8977042 100644
--- a/ui/src/base/zoned_interaction_handler_unittest.ts
+++ b/ui/src/base/zoned_interaction_handler_unittest.ts
@@ -188,7 +188,7 @@
     );
 
     expect(handleWheel).toHaveBeenCalled();
-    expect(handleWheel.mock.calls[0][0]).toMatchObject({
+    expect(handleWheel.mock.calls[0]![0]).toMatchObject({
       position: {x: 50, y: 50},
       deltaX: 5,
       deltaY: 10,
diff --git a/ui/src/bigtrace/base/iso_date.ts b/ui/src/bigtrace/base/iso_date.ts
index dbd3a97..afde77c 100644
--- a/ui/src/bigtrace/base/iso_date.ts
+++ b/ui/src/bigtrace/base/iso_date.ts
@@ -34,7 +34,7 @@
 
 function toUtc(iso: string): Date {
   const [y, mo, d] = iso.split('-').map(Number);
-  return new Date(Date.UTC(y, mo - 1, d));
+  return new Date(Date.UTC(y!, mo! - 1, d));
 }
 
 export function isoDate(year: number, month: number, day: number): string {
@@ -81,7 +81,7 @@
 
 export function yearMonthOf(iso: string): YearMonth {
   const [y, mo] = iso.split('-').map(Number);
-  return {year: y, month: mo - 1};
+  return {year: y!, month: mo! - 1};
 }
 
 export function shiftMonth(ym: YearMonth, by: number): YearMonth {
diff --git a/ui/src/bigtrace/pages/bigtrace_settings_bar.ts b/ui/src/bigtrace/pages/bigtrace_settings_bar.ts
index c5348a7..fe6d660 100644
--- a/ui/src/bigtrace/pages/bigtrace_settings_bar.ts
+++ b/ui/src/bigtrace/pages/bigtrace_settings_bar.ts
@@ -189,7 +189,7 @@
 
 function formatSettingValue(values: ReadonlyArray<string>): string {
   if (values.length === 0) return '(empty)';
-  if (values.length === 1) return values[0] === '' ? '(empty)' : values[0];
+  if (values.length === 1) return values[0] === '' ? '(empty)' : values[0]!;
   if (values.length <= 3) return values.join(', ');
   return `${values.slice(0, 2).join(', ')}, +${values.length - 2} more`;
 }
diff --git a/ui/src/bigtrace/pages/device_filter_modal.ts b/ui/src/bigtrace/pages/device_filter_modal.ts
index 7e44be3..e5b1def 100644
--- a/ui/src/bigtrace/pages/device_filter_modal.ts
+++ b/ui/src/bigtrace/pages/device_filter_modal.ts
@@ -52,7 +52,7 @@
 ): string {
   const parts: string[] = [];
   const part = (values: ReadonlyArray<string>, noun: string) => {
-    if (values.length === 1) parts.push(values[0]);
+    if (values.length === 1) parts.push(values[0]!);
     else if (values.length > 1) parts.push(count(values.length, noun));
   };
   part(formFactors, 'form factor');
diff --git a/ui/src/bigtrace/pages/query_launcher.ts b/ui/src/bigtrace/pages/query_launcher.ts
index 2968860..e8b90f5 100644
--- a/ui/src/bigtrace/pages/query_launcher.ts
+++ b/ui/src/bigtrace/pages/query_launcher.ts
@@ -260,7 +260,7 @@
         ? this.activeCuj
         : anchorCuj !== undefined && byCuj.has(anchorCuj)
           ? anchorCuj
-          : groups[0][0];
+          : groups[0]![0];
     const options = byCuj.get(active) ?? [];
     const appliedInActive = options.some((p) => p.id === appliedId);
     const shown = appliedInActive ? applied : undefined;
diff --git a/ui/src/bigtrace/pages/query_tabs_state.ts b/ui/src/bigtrace/pages/query_tabs_state.ts
index 8659255..36a9e5d 100644
--- a/ui/src/bigtrace/pages/query_tabs_state.ts
+++ b/ui/src/bigtrace/pages/query_tabs_state.ts
@@ -756,7 +756,7 @@
     if (this.tabs.length <= 1) return;
     const index = this.tabs.findIndex((t) => t.id === tabId);
     if (index === -1) return;
-    const tabToClose = this.tabs[index];
+    const tabToClose = this.tabs[index]!;
     if (tabToClose.pollInterval !== undefined) {
       window.clearTimeout(tabToClose.pollInterval);
       tabToClose.pollInterval = undefined;
@@ -767,7 +767,7 @@
     this.tabs.splice(index, 1);
     if (this.activeTabId === tabId) {
       const newIndex = Math.min(index, this.tabs.length - 1);
-      this.activeTabId = this.tabs[newIndex].id;
+      this.activeTabId = this.tabs[newIndex]!.id;
     }
     this.markDirty();
   }
@@ -785,14 +785,14 @@
     if (draggedIndex === -1) return;
     const [dragged] = this.tabs.splice(draggedIndex, 1);
     if (beforeId === undefined) {
-      this.tabs.push(dragged);
+      this.tabs.push(dragged!);
       return;
     }
     const beforeIndex = this.tabs.findIndex((t) => t.id === beforeId);
     if (beforeIndex === -1) {
-      this.tabs.push(dragged);
+      this.tabs.push(dragged!);
     } else {
-      this.tabs.splice(beforeIndex, 0, dragged);
+      this.tabs.splice(beforeIndex, 0, dragged!);
     }
   }
 
@@ -865,7 +865,7 @@
         // Restored tabs get new IDs, so activate by index instead.
         const idx = parsed.tabs.findIndex((t) => t.id === parsed.activeTabId);
         if (idx >= 0 && idx < this.tabs.length) {
-          this.activeTabId = this.tabs[idx].id;
+          this.activeTabId = this.tabs[idx]!.id;
         }
       }
     }
diff --git a/ui/src/bigtrace/pages/query_tabs_state_unittest.ts b/ui/src/bigtrace/pages/query_tabs_state_unittest.ts
index 422f119..64e6ba9 100644
--- a/ui/src/bigtrace/pages/query_tabs_state_unittest.ts
+++ b/ui/src/bigtrace/pages/query_tabs_state_unittest.ts
@@ -353,7 +353,7 @@
       },
     ];
     expect(src.traceFilters).toHaveLength(1);
-    expect(src.querySettings[0].values).toEqual(['/traces']);
+    expect(src.querySettings[0]!.values).toEqual(['/traces']);
   });
 
   test('an unknown id is a no-op', () => {
@@ -458,7 +458,7 @@
     openSettings(tab);
     edit(tab);
     closeSettings(tab, {keep: true});
-    expect(tab.querySettings[0].values).toEqual(['/other']);
+    expect(tab.querySettings[0]!.values).toEqual(['/other']);
     expect(tab.traceFilters).toEqual([]);
     expect(tab.limit).toBe(10);
     expect(tab.traceLimit).toBe(11);
@@ -470,10 +470,10 @@
   test('the snapshot is a copy: later mutation of the tab does not reach it', () => {
     const tab = workingTab();
     openSettings(tab);
-    tab.querySettings[0].values.push('/extra');
+    tab.querySettings[0]!.values.push('/extra');
     (tab.traceFilters as unknown[]).push({field: 'x', op: 'is null'});
     closeSettings(tab, {keep: false});
-    expect(tab.querySettings[0].values).toEqual(['/traces']);
+    expect(tab.querySettings[0]!.values).toEqual(['/traces']);
     expect(tab.traceFilters).toHaveLength(1);
   });
 
@@ -481,8 +481,8 @@
     const tab = workingTab();
     const snap = snapshotTabConfig(tab);
     restoreTabConfig(tab, snap);
-    tab.querySettings[0].values.push('/extra');
-    expect(snap.querySettings[0].values).toEqual(['/traces']);
+    tab.querySettings[0]!.values.push('/extra');
+    expect(snap.querySettings[0]!.values).toEqual(['/traces']);
   });
 
   test('a new tab starting its first query has no session and keeps its setup', () => {
@@ -606,7 +606,7 @@
     expect(traceUuidsActive(tab)).toBe(true);
     // Filter-mode configuration is hidden, not cleared...
     expect(tab.traceFilters).toHaveLength(1);
-    expect(tab.querySettings[0].values).toEqual(['/traces']);
+    expect(tab.querySettings[0]!.values).toEqual(['/traces']);
     // ...and an earlier stint's values survive re-entry.
     expect(
       tab.querySettings.find((s) => s.settingId === TRACE_UUIDS_SETTING_ID)
@@ -765,7 +765,7 @@
     );
     const tabs = new QueryTabsState();
     expect(tabs.tabs).toHaveLength(1);
-    expect(tabs.tabs[0].experimentFilter).toBeUndefined();
+    expect(tabs.tabs[0]!.experimentFilter).toBeUndefined();
   });
 
   test('a preset naming an experiment runs the query over it', () => {
@@ -881,18 +881,18 @@
 
   test('a stored range round-trips; a corrupt one re-defaults', () => {
     storeTab({kind: 'fixed', from: '2026-09-20', to: '2026-09-25'});
-    expect(new QueryTabsState().tabs[0].dateFilter).toEqual({
+    expect(new QueryTabsState().tabs[0]!.dateFilter).toEqual({
       kind: 'fixed',
       from: '2026-09-20',
       to: '2026-09-25',
     });
 
     storeTab(null);
-    expect(new QueryTabsState().tabs[0].dateFilter).toBeNull();
+    expect(new QueryTabsState().tabs[0]!.dateFilter).toBeNull();
 
     // A hand-edited or foreign-build entry must not reach the date math.
     storeTab({kind: 'fixed', from: 123});
-    const restored = new QueryTabsState().tabs[0].dateFilter;
+    const restored = new QueryTabsState().tabs[0]!.dateFilter;
     expect(restored).toBeUndefined();
     expect(() => describeDateFilter(restored, '2026-10-05')).not.toThrow();
   });
diff --git a/ui/src/bigtrace/pages/results_panel_unittest.ts b/ui/src/bigtrace/pages/results_panel_unittest.ts
index ddf5c9f..59eef38 100644
--- a/ui/src/bigtrace/pages/results_panel_unittest.ts
+++ b/ui/src/bigtrace/pages/results_panel_unittest.ts
@@ -80,7 +80,7 @@
   uuid: string,
   client: BigtraceQueryClient,
 ): BigTraceEditorTab {
-  const tab = tabsState.tabs[0];
+  const tab = tabsState.tabs[0]!;
   tab.materialize = true;
   tab.configured = true;
   tab.editorText = SQL;
diff --git a/ui/src/bigtrace/pages/value_list_unittest.ts b/ui/src/bigtrace/pages/value_list_unittest.ts
index b6ff7c8..fc9a68b 100644
--- a/ui/src/bigtrace/pages/value_list_unittest.ts
+++ b/ui/src/bigtrace/pages/value_list_unittest.ts
@@ -162,7 +162,7 @@
     const {calls, load} = makeLoader();
     h = mount(load);
     expect(calls).toHaveLength(1);
-    expect(calls[0].search).toBe('');
+    expect(calls[0]!.search).toBe('');
     expect(vi.getTimerCount()).toBe(0);
     expect(h.notes()).toEqual(['Loading…']);
   });
@@ -170,7 +170,7 @@
   test('a typing burst becomes one request after the debounce', async () => {
     const {calls, load} = makeLoader();
     h = mount(load);
-    calls[0].resolve(['Pixel 8', 'Pixel 9', 'Galaxy']);
+    calls[0]!.resolve(['Pixel 8', 'Pixel 9', 'Galaxy']);
     await flush();
     h.redraw();
     expect(h.rows()).toEqual(['Pixel 8', 'Pixel 9', 'Galaxy']);
@@ -187,13 +187,13 @@
     await vi.advanceTimersByTimeAsync(1);
     h.redraw();
     expect(calls).toHaveLength(2);
-    expect(calls[1].search).toBe('abc');
+    expect(calls[1]!.search).toBe('abc');
   });
 
   test('reverting to the sent search cancels the pending timer', async () => {
     const {calls, load} = makeLoader();
     h = mount(load);
-    calls[0].resolve(['x']);
+    calls[0]!.resolve(['x']);
     await flush();
     h.redraw();
     h.attrs.search = 'a';
@@ -210,19 +210,19 @@
   test('a facet change aborts the request in flight and drops its answer', async () => {
     const {calls, load} = makeLoader({honourAbort: false});
     h = mount(load);
-    const first = calls[0];
+    const first = calls[0]!;
     h.attrs.facet = [{field: 'ff', op: 'in', value: ['phone']}];
     h.redraw();
     expect(first.signal?.aborted).toBe(true);
     expect(calls).toHaveLength(2);
-    expect(calls[1].facet).toEqual(h.attrs.facet);
+    expect(calls[1]!.facet).toEqual(h.attrs.facet);
     // The loader ignored the abort and answers late: not shown.
     first.resolve(['STALE']);
     await flush();
     h.redraw();
     expect(h.rows()).toEqual([]);
     expect(h.notes()).toEqual(['Loading…']);
-    calls[1].resolve(['fresh']);
+    calls[1]!.resolve(['fresh']);
     await flush();
     h.redraw();
     expect(h.rows()).toEqual(['fresh']);
@@ -244,7 +244,7 @@
   test('searching keeps the last list, narrowed locally, while updating', async () => {
     const {calls, load} = makeLoader();
     h = mount(load);
-    calls[0].resolve(['Pixel 8', 'Pixel 9', 'Galaxy']);
+    calls[0]!.resolve(['Pixel 8', 'Pixel 9', 'Galaxy']);
     await flush();
     h.redraw();
     h.attrs.search = 'pix';
@@ -258,7 +258,7 @@
     expect(h.rows()).toEqual(['Pixel 8', 'Pixel 9']);
     expect(h.notes()).toEqual(['Updating…']);
     expect(h.root.querySelectorAll('mark')).toHaveLength(2);
-    calls[1].resolve(['Pixel 8']);
+    calls[1]!.resolve(['Pixel 8']);
     await flush();
     h.redraw();
     expect(h.rows()).toEqual(['Pixel 8']);
@@ -270,7 +270,7 @@
     h.attrs.pinSelected = true;
     h.attrs.selected.add('b');
     h.attrs.selected.add('a');
-    calls[0].resolve(['c', 'a', 'd']);
+    calls[0]!.resolve(['c', 'a', 'd']);
     await flush();
     h.redraw();
     expect(h.rows()).toEqual(['a', 'b', 'c', 'd']);
@@ -282,13 +282,13 @@
   test('without pinning, rows keep their order and ticking does not move them', async () => {
     const {calls, load} = makeLoader();
     h = mount(load);
-    calls[0].resolve(['ALPHA', 'BETA', 'STABLE']);
+    calls[0]!.resolve(['ALPHA', 'BETA', 'STABLE']);
     await flush();
     h.redraw();
     const boxes = h.root.querySelectorAll<HTMLInputElement>(
       'input[type=checkbox]',
     );
-    boxes[1].click();
+    boxes[1]!.click();
     h.redraw();
     expect(h.attrs.selected.has('BETA')).toBe(true);
     expect(h.rows()).toEqual(['ALPHA', 'BETA', 'STABLE']);
@@ -297,7 +297,7 @@
   test('a failure is shown once, not refetched, and Retry asks again', async () => {
     const {calls, load} = makeLoader();
     h = mount(load);
-    calls[0].reject(
+    calls[0]!.reject(
       new BigtraceHttpError(400, '{"error":{"message":"bad col"}}'),
     );
     await flush();
@@ -318,7 +318,7 @@
     h.redraw();
     expect(calls).toHaveLength(2);
     expect(h.notes()).toEqual(['Loading…']);
-    calls[1].resolve(['ok']);
+    calls[1]!.resolve(['ok']);
     await flush();
     h.redraw();
     expect(h.rows()).toEqual(['ok']);
@@ -328,7 +328,7 @@
   test('a failure is forgotten when the facet changes', async () => {
     const {calls, load} = makeLoader();
     h = mount(load);
-    calls[0].reject(new BigtraceHttpError(400, 'x'));
+    calls[0]!.reject(new BigtraceHttpError(400, 'x'));
     await flush();
     h.redraw();
     h.attrs.facet = [{field: 'f', op: '=', value: 1}];
@@ -340,7 +340,7 @@
   test('empty answers and the limit note', async () => {
     const {calls, load} = makeLoader();
     h = mount(load);
-    calls[0].resolve([]);
+    calls[0]!.resolve([]);
     await flush();
     h.redraw();
     expect(h.notes()).toEqual(['No values match.']);
@@ -348,7 +348,7 @@
 
     const under = makeLoader();
     h = mount(under.load);
-    under.calls[0].resolve(
+    under.calls[0]!.resolve(
       Array.from({length: VALUE_LIST_LIMIT - 1}, (_, i) => `v${i}`),
     );
     await flush();
@@ -358,7 +358,7 @@
 
     const at = makeLoader();
     h = mount(at.load);
-    at.calls[0].resolve(
+    at.calls[0]!.resolve(
       Array.from({length: VALUE_LIST_LIMIT}, (_, i) => `v${i}`),
     );
     await flush();
@@ -374,7 +374,7 @@
     h.attrs.search = 'q';
     h.redraw();
     expect(vi.getTimerCount()).toBe(1);
-    const signal = calls[0].signal;
+    const signal = calls[0]!.signal;
     const redraw = vi.spyOn(m, 'redraw');
     h.unmount();
     h = undefined;
@@ -388,7 +388,7 @@
   test('toggling a row does not refetch', async () => {
     const {calls, load} = makeLoader();
     h = mount(load);
-    calls[0].resolve(['a', 'b']);
+    calls[0]!.resolve(['a', 'b']);
     await flush();
     h.redraw();
     const box = h.root.querySelector<HTMLInputElement>('input[type=checkbox]');
diff --git a/ui/src/bigtrace/query/bigtrace_async_data_source.ts b/ui/src/bigtrace/query/bigtrace_async_data_source.ts
index c90e327..48bc0e4 100644
--- a/ui/src/bigtrace/query/bigtrace_async_data_source.ts
+++ b/ui/src/bigtrace/query/bigtrace_async_data_source.ts
@@ -156,7 +156,7 @@
           const col = model.columns?.find((c) => c.field === key);
           const alias =
             col !== undefined && col.alias !== undefined ? col.alias : key;
-          mappedRow[alias] = row[key];
+          mappedRow[alias] = row[key]!;
         }
       }
       return mappedRow;
diff --git a/ui/src/bigtrace/query/bigtrace_async_data_source_unittest.ts b/ui/src/bigtrace/query/bigtrace_async_data_source_unittest.ts
index 6af0f73..cf1d2fb 100644
--- a/ui/src/bigtrace/query/bigtrace_async_data_source_unittest.ts
+++ b/ui/src/bigtrace/query/bigtrace_async_data_source_unittest.ts
@@ -120,7 +120,7 @@
   // Settle the first window so later renders are range changes, not initial.
   async function loaded(ds: BigtraceAsyncDataSource, calls: Call[]) {
     ds.useRows(model(0, 100));
-    calls[0].resolve(PAGE);
+    calls[0]!.resolve(PAGE);
     await vi.advanceTimersByTimeAsync(0);
     calls.length = 0;
   }
@@ -143,7 +143,7 @@
     ds.useRows(model(0, 100));
     await vi.advanceTimersByTimeAsync(FETCH_DEBOUNCE_MS * 4);
     expect(calls).toHaveLength(1);
-    expect(calls[0].signal?.aborted).toBe(false);
+    expect(calls[0]!.signal?.aborted).toBe(false);
   });
 
   test('a burst of scroll ticks costs one fetch, for the last window', async () => {
@@ -159,7 +159,7 @@
 
     await vi.advanceTimersByTimeAsync(FETCH_DEBOUNCE_MS);
     expect(calls).toHaveLength(1);
-    expect(calls[0].offset).toBe(800);
+    expect(calls[0]!.offset).toBe(800);
   });
 
   test('a newer window aborts the request it replaces', async () => {
@@ -170,14 +170,14 @@
     ds.useRows(model(200, 100));
     await vi.advanceTimersByTimeAsync(FETCH_DEBOUNCE_MS);
     expect(calls).toHaveLength(1);
-    const superseded = calls[0];
+    const superseded = calls[0]!;
 
     // Scroll on while that one is still in flight.
     ds.useRows(model(900, 100));
     await vi.advanceTimersByTimeAsync(FETCH_DEBOUNCE_MS);
     expect(calls).toHaveLength(2);
     expect(superseded.signal?.aborted).toBe(true);
-    expect(calls[1].signal?.aborted).toBe(false);
+    expect(calls[1]!.signal?.aborted).toBe(false);
   });
 
   test('a superseded reply does not replace the newer window', async () => {
@@ -191,9 +191,9 @@
     await vi.advanceTimersByTimeAsync(FETCH_DEBOUNCE_MS);
 
     // The abandoned request answers anyway, after the newer one landed.
-    calls[1].resolve({...PAGE, rows: [{a: 'new'}]});
+    calls[1]!.resolve({...PAGE, rows: [{a: 'new'}]});
     await vi.advanceTimersByTimeAsync(0);
-    calls[0].resolve({...PAGE, rows: [{a: 'stale'}]});
+    calls[0]!.resolve({...PAGE, rows: [{a: 'stale'}]});
     await vi.advanceTimersByTimeAsync(0);
 
     expect(ds.useRows(model(900, 100)).rows).toEqual([{a: 'new'}]);
diff --git a/ui/src/bigtrace/query/bigtrace_query_client.ts b/ui/src/bigtrace/query/bigtrace_query_client.ts
index 7cf4571..2068311 100644
--- a/ui/src/bigtrace/query/bigtrace_query_client.ts
+++ b/ui/src/bigtrace/query/bigtrace_query_client.ts
@@ -631,7 +631,7 @@
       if (response.status === 404) {
         // Extract UUID from /query_executions/{uuid}[:action]; else use path.
         const m = path.match(/\/query_executions\/([^/:?#]+)/);
-        throw new QueryNotFoundError(m ? m[1] : path);
+        throw new QueryNotFoundError(m ? m[1]! : path);
       }
       if (response.status === 403) {
         // Most 403s here are an unauthenticated session; fold the hint into
@@ -685,7 +685,7 @@
   const rows = (result.rows ?? []).map((row) => {
     const out: DataGridRow = {};
     for (let i = 0; i < schema.length; i++) {
-      const {name, type} = schema[i];
+      const {name, type} = schema[i]!;
       out[name] = parseCellValue(row.values[i], type);
     }
     return out;
diff --git a/ui/src/bigtrace/query/bigtrace_query_client_unittest.ts b/ui/src/bigtrace/query/bigtrace_query_client_unittest.ts
index 006124b..6115ca7 100644
--- a/ui/src/bigtrace/query/bigtrace_query_client_unittest.ts
+++ b/ui/src/bigtrace/query/bigtrace_query_client_unittest.ts
@@ -234,7 +234,7 @@
       'file_name',
       'size_bytes',
     ]);
-    expect(schema.columns[0].defaultVisible).toBe(true);
+    expect(schema.columns[0]!.defaultVisible).toBe(true);
   });
 
   test('listTraceMetadataColumnValues POSTs column, search and coerced trace_filters', async () => {
@@ -513,18 +513,18 @@
       ],
     });
     expect(page.columns).toEqual(['id', 'score', 'data', 'name']);
-    expect(page.rows[0].id).toBe(123n);
-    expect(page.rows[0].score).toBe(3.14);
-    expect(page.rows[0].data).toBeInstanceOf(Uint8Array);
-    expect(Array.from(page.rows[0].data as Uint8Array)).toEqual([
+    expect(page.rows[0]!.id).toBe(123n);
+    expect(page.rows[0]!.score).toBe(3.14);
+    expect(page.rows[0]!.data).toBeInstanceOf(Uint8Array);
+    expect(Array.from(page.rows[0]!.data as Uint8Array)).toEqual([
       104, 101, 108, 108, 111,
     ]);
-    expect(page.rows[0].name).toBe('alice');
+    expect(page.rows[0]!.name).toBe('alice');
 
-    expect(page.rows[1].id).toBeNull();
-    expect(page.rows[1].score).toBeNull();
-    expect(page.rows[1].data).toBeNull();
-    expect(page.rows[1].name).toBeNull();
+    expect(page.rows[1]!.id).toBeNull();
+    expect(page.rows[1]!.score).toBeNull();
+    expect(page.rows[1]!.data).toBeNull();
+    expect(page.rows[1]!.name).toBeNull();
   });
 
   test('derives columns from schema', () => {
@@ -601,8 +601,8 @@
     // Ids stay numbers and denial flags stay booleans: the wire types are
     // the UI's types, with nothing in between to drift.
     expect(got).toEqual([item]);
-    expect(typeof got[0].experimentId).toBe('number');
-    expect(got[0].isControlDenied).toBe(true);
+    expect(typeof got[0]!.experimentId).toBe('number');
+    expect(got[0]!.isControlDenied).toBe(true);
   });
 
   test('listExperiments reads an absent list as no matches', async () => {
diff --git a/ui/src/bigtrace/query/bigtrace_trace_list_data_source_unittest.ts b/ui/src/bigtrace/query/bigtrace_trace_list_data_source_unittest.ts
index 8996dbd..6e0a944 100644
--- a/ui/src/bigtrace/query/bigtrace_trace_list_data_source_unittest.ts
+++ b/ui/src/bigtrace/query/bigtrace_trace_list_data_source_unittest.ts
@@ -124,7 +124,7 @@
     ds.useRows(flatModel({limit: 0}));
     await flush();
     expect(calls).toHaveLength(1);
-    expect(calls[0].limit).toBe(100);
+    expect(calls[0]!.limit).toBe(100);
   });
 
   test('initial fetch ships settings + paging and exposes the rows', async () => {
@@ -134,10 +134,10 @@
     await flush();
 
     expect(calls).toHaveLength(1);
-    expect(calls[0].settings).toBe(SETTINGS);
-    expect(calls[0].limit).toBe(100);
-    expect(calls[0].offset).toBe(0);
-    expect(calls[0].orderBy).toBe('');
+    expect(calls[0]!.settings).toBe(SETTINGS);
+    expect(calls[0]!.limit).toBe(100);
+    expect(calls[0]!.offset).toBe(0);
+    expect(calls[0]!.orderBy).toBe('');
 
     const rows = ds.useRows(flatModel({limit: 100}));
     expect(rows.rows).toEqual(PAGE.rows);
@@ -156,7 +156,7 @@
     await flush();
 
     expect(calls).toHaveLength(2);
-    expect(calls[1].orderBy).toBe('size_bytes desc');
+    expect(calls[1]!.orderBy).toBe('size_bytes desc');
   });
 
   test('ships the visible-column projection and the filter array', async () => {
@@ -169,10 +169,10 @@
     await flush();
 
     expect(calls).toHaveLength(1);
-    expect(calls[0].columns).toEqual(['file_name', 'size_bytes']);
+    expect(calls[0]!.columns).toEqual(['file_name', 'size_bytes']);
     // The data source passes the Filter[] straight through; the HTTP client is
     // what coerces values to the always-strings wire form.
-    expect(calls[0].filter).toEqual(filters);
+    expect(calls[0]!.filter).toEqual(filters);
   });
 
   test('omits the projection when no columns are visible', async () => {
@@ -180,7 +180,7 @@
     const ds = new BigtraceTraceListDataSource(client, () => SETTINGS);
     ds.useRows(flatModel({limit: 100}));
     await flush();
-    expect(calls[0].columns).toBeUndefined();
+    expect(calls[0]!.columns).toBeUndefined();
   });
 
   test('refetches when the settings thunk changes', async () => {
@@ -201,7 +201,7 @@
     ds.useRows(flatModel({limit: 100}));
     await flush();
     expect(calls).toHaveLength(2);
-    expect(calls[1].settings).toBe(settings);
+    expect(calls[1]!.settings).toBe(settings);
   });
 
   test('refetches only on TRACE_ADDRESS changes, not query-option / metadata edits', async () => {
@@ -406,7 +406,7 @@
     await flush();
 
     expect(calls).toHaveLength(1);
-    expect(calls[0].experimentFilter).toEqual({
+    expect(calls[0]!.experimentFilter).toEqual({
       experimentId: 1,
       controlId: 2,
       isTreatment: true,
@@ -431,19 +431,19 @@
     ds.useRows(flatModel({limit: 100}));
     await flush();
     expect(calls).toHaveLength(2);
-    expect(calls[1].experimentFilter).toEqual(filter);
+    expect(calls[1]!.experimentFilter).toEqual(filter);
 
     filter = {experimentId: 1, controlId: 2, isTreatment: false};
     ds.useRows(flatModel({limit: 100}));
     await flush();
     expect(calls).toHaveLength(3);
-    expect(calls[2].experimentFilter?.isTreatment).toBe(false);
+    expect(calls[2]!.experimentFilter?.isTreatment).toBe(false);
 
     filter = undefined;
     ds.useRows(flatModel({limit: 100}));
     await flush();
     expect(calls).toHaveLength(4);
-    expect(calls[3].experimentFilter).toBeUndefined();
+    expect(calls[3]!.experimentFilter).toBeUndefined();
 
     // Nothing changed since: the grid stays put.
     ds.useRows(flatModel({limit: 100}));
diff --git a/ui/src/bigtrace/query/column_values_loader_unittest.ts b/ui/src/bigtrace/query/column_values_loader_unittest.ts
index 2496965..2b284db 100644
--- a/ui/src/bigtrace/query/column_values_loader_unittest.ts
+++ b/ui/src/bigtrace/query/column_values_loader_unittest.ts
@@ -58,7 +58,7 @@
     expect(result).toBe('ok');
     expect(calls).toBe(RETRY_ATTEMPTS + 1);
     expect(waits.length).toBe(RETRY_ATTEMPTS);
-    expect(waits[1]).toBeGreaterThan(waits[0]);
+    expect(waits[1]).toBeGreaterThan(waits[0]!);
   });
 
   test('withRetry gives up after the last attempt', async () => {
diff --git a/ui/src/bigtrace/query/date_filter_unittest.ts b/ui/src/bigtrace/query/date_filter_unittest.ts
index b41e5c7..f3ef629 100644
--- a/ui/src/bigtrace/query/date_filter_unittest.ts
+++ b/ui/src/bigtrace/query/date_filter_unittest.ts
@@ -62,16 +62,18 @@
       rest: [own],
       intact: true,
     });
-    expect(splitDateFilters([pair[0], own], pair)).toEqual({
+    expect(splitDateFilters([pair[0]!, own], pair)).toEqual({
       rest: [own],
       intact: false,
     });
     // A grid filter that duplicates one half is swept out with the pair but
     // is not a removal: the range stays.
-    expect(splitDateFilters([pair[0], pair[0], pair[1], own], pair)).toEqual({
-      rest: [own],
-      intact: true,
-    });
+    expect(splitDateFilters([pair[0]!, pair[0]!, pair[1]!, own], pair)).toEqual(
+      {
+        rest: [own],
+        intact: true,
+      },
+    );
   });
 
   test("a history run's date pair becomes a fixed range", () => {
diff --git a/ui/src/bigtrace/query/history_store.ts b/ui/src/bigtrace/query/history_store.ts
index 0ad4f9e..022fce5 100644
--- a/ui/src/bigtrace/query/history_store.ts
+++ b/ui/src/bigtrace/query/history_store.ts
@@ -61,7 +61,7 @@
     now.getDate() - 1,
   ).toDateString();
   if (dayKey === yesterdayKey) return 'Yesterday';
-  return `${MONTH_NAMES[d.getMonth()].slice(0, 3)} ${d.getDate()}, ${d.getFullYear()}`;
+  return `${MONTH_NAMES[d.getMonth()]!.slice(0, 3)} ${d.getDate()}, ${d.getFullYear()}`;
 }
 
 // Buckets sorted entries by local calendar day.
diff --git a/ui/src/bigtrace/query/local_preset_store.ts b/ui/src/bigtrace/query/local_preset_store.ts
index 4e5f1df..eb64cbe 100644
--- a/ui/src/bigtrace/query/local_preset_store.ts
+++ b/ui/src/bigtrace/query/local_preset_store.ts
@@ -123,7 +123,7 @@
     const presets = this.list();
     const idx = presets.findIndex((p) => p.id === id);
     if (idx < 0) return;
-    presets[idx] = {...presets[idx], ...details};
+    presets[idx] = {...presets[idx]!, ...details};
     this.write(presets);
   }
 
diff --git a/ui/src/bigtrace/query/local_preset_store_unittest.ts b/ui/src/bigtrace/query/local_preset_store_unittest.ts
index e975fcd..66df05e 100644
--- a/ui/src/bigtrace/query/local_preset_store_unittest.ts
+++ b/ui/src/bigtrace/query/local_preset_store_unittest.ts
@@ -226,7 +226,7 @@
       presetFromTab(fakeTab(), {name: 'New name', id: saved.id}),
     );
     expect(localPresetStore.list()).toHaveLength(1);
-    expect(localPresetStore.list()[0].name).toBe('New name');
+    expect(localPresetStore.list()[0]!.name).toBe('New name');
   });
 });
 
diff --git a/ui/src/bigtrace/settings/column_order.ts b/ui/src/bigtrace/settings/column_order.ts
index 9935268..c60cd91 100644
--- a/ui/src/bigtrace/settings/column_order.ts
+++ b/ui/src/bigtrace/settings/column_order.ts
@@ -27,7 +27,7 @@
 ): T[] {
   const i = items.findIndex((it) => nameOf(it) === LINK_COLUMN);
   if (i <= 0) return [...items];
-  return [items[i], ...items.slice(0, i), ...items.slice(i + 1)];
+  return [items[i]!, ...items.slice(0, i), ...items.slice(i + 1)];
 }
 
 export function linkNameFirst(names: readonly string[]): string[] {
diff --git a/ui/src/bigtrace/settings/tab_bound_setting.ts b/ui/src/bigtrace/settings/tab_bound_setting.ts
index 0936fd0..cfc45f2 100644
--- a/ui/src/bigtrace/settings/tab_bound_setting.ts
+++ b/ui/src/bigtrace/settings/tab_bound_setting.ts
@@ -162,7 +162,7 @@
   switch (setting.type) {
     case 'number': {
       if (raw.length === 0) return undefined;
-      const n = parseFloat(raw[0]);
+      const n = parseFloat(raw[0]!);
       return Number.isFinite(n) ? (n as unknown as T) : undefined;
     }
     case 'boolean':
diff --git a/ui/src/bigtrace/widgets/date_range_calendar_unittest.ts b/ui/src/bigtrace/widgets/date_range_calendar_unittest.ts
index 74fc46e..d15d414 100644
--- a/ui/src/bigtrace/widgets/date_range_calendar_unittest.ts
+++ b/ui/src/bigtrace/widgets/date_range_calendar_unittest.ts
@@ -67,12 +67,12 @@
       expect(b.type).toBe('button');
       expect(b.getAttribute('aria-label')).toMatch(/^October \d+, 2026$/);
     }
-    const picked = days[12];
+    const picked = days[12]!;
     expect(picked.getAttribute('aria-label')).toBe('October 13, 2026');
     expect(picked.getAttribute('aria-pressed')).toBe('true');
     expect(picked.disabled).toBe(false);
-    expect(days[0].getAttribute('aria-pressed')).toBe('false');
+    expect(days[0]!.getAttribute('aria-pressed')).toBe('false');
     // Days past `max` are shown but disabled.
-    expect(days[13].disabled).toBe(true);
+    expect(days[13]!.disabled).toBe(true);
   });
 });
diff --git a/ui/src/chrome_extension/chrome_tracing_controller.ts b/ui/src/chrome_extension/chrome_tracing_controller.ts
index b0c536a..a2a733e 100644
--- a/ui/src/chrome_extension/chrome_tracing_controller.ts
+++ b/ui/src/chrome_extension/chrome_tracing_controller.ts
@@ -113,7 +113,7 @@
     return key
       .split(separator)
       .map((part, index) => {
-        return index === 0 ? part : part[0].toUpperCase() + part.slice(1);
+        return index === 0 ? part : part[0]!.toUpperCase() + part.slice(1);
       })
       .join('');
   }
diff --git a/ui/src/chrome_extension/trace_config_utils.ts b/ui/src/chrome_extension/trace_config_utils.ts
index 7913f1b..353db67 100644
--- a/ui/src/chrome_extension/trace_config_utils.ts
+++ b/ui/src/chrome_extension/trace_config_utils.ts
@@ -45,7 +45,7 @@
 
   for (let index = 0; index < minVerArray.length; index++) {
     if (runVerArray[index] === minVerArray[index]) continue;
-    return runVerArray[index] > minVerArray[index];
+    return runVerArray[index]! > minVerArray[index]!;
   }
   return true; // Exact version match.
 }
diff --git a/ui/src/components/aggregation_adapter.ts b/ui/src/components/aggregation_adapter.ts
index 5b58417..ef6bd74 100644
--- a/ui/src/components/aggregation_adapter.ts
+++ b/ui/src/components/aggregation_adapter.ts
@@ -275,7 +275,7 @@
     throw new Error('No presets provided');
   }
   const idx = Math.min(Math.max(0, presetIndex), configOrPresets.length - 1);
-  return getPresetConfig(configOrPresets[idx]);
+  return getPresetConfig(configOrPresets[idx]!);
 }
 
 interface PreparedAggregation extends AsyncDisposable {
diff --git a/ui/src/components/colorizer.ts b/ui/src/components/colorizer.ts
index 78fbb4b..080c287 100644
--- a/ui/src/components/colorizer.ts
+++ b/ui/src/components/colorizer.ts
@@ -115,7 +115,7 @@
 // based on a string seed.
 export function materialColorScheme(seed: string): ColorScheme {
   const colorIdx = hash(seed, MD_PALETTE.length);
-  return MD_PALETTE[colorIdx];
+  return MD_PALETTE[colorIdx]!;
 }
 
 const proceduralColorCache = new Map<string, ColorScheme>();
@@ -167,14 +167,14 @@
 export function colorForPriority(priority: number): ColorScheme {
   if (priority < 100) {
     // Realtime scheduling priorities (0..99) -> Red
-    return MD_PALETTE[0];
+    return MD_PALETTE[0]!;
   }
   if (priority < 120) {
     // High priority CFS tasks (100..119) -> Yellow
-    return MD_PALETTE[17];
+    return MD_PALETTE[17]!;
   }
   // Priority 120 onwards (nice >= 0) -> Blue
-  return MD_PALETTE[5];
+  return MD_PALETTE[5]!;
 }
 
 export function colorForCpu(cpu: number): Color {
diff --git a/ui/src/components/details/args.ts b/ui/src/components/details/args.ts
index 00dd836..7d331e3 100644
--- a/ui/src/components/details/args.ts
+++ b/ui/src/components/details/args.ts
@@ -67,7 +67,7 @@
   }
   if (args !== null && typeof args === 'object') {
     if (Object.keys(args).length === 1) {
-      const [[childName, value]] = Object.entries(args);
+      const [childName, value] = Object.entries(args)[0]!;
       return renderArgsTree(
         trace,
         `${key}.${childName}`,
diff --git a/ui/src/components/details/slice_args_parser.ts b/ui/src/components/details/slice_args_parser.ts
index ca9b6d9..d7dda72 100644
--- a/ui/src/components/details/slice_args_parser.ts
+++ b/ui/src/components/details/slice_args_parser.ts
@@ -55,7 +55,7 @@
   let match;
   const re = /([^\.\[\]]+)|\[(\d+)\]/g;
   while ((match = re.exec(key)) !== null) {
-    result.push(match[2] ? parseInt(match[2]) : match[1]);
+    result.push(match[2] ? parseInt(match[2]) : match[1]!);
   }
   return result;
 }
diff --git a/ui/src/components/distribution_panel.ts b/ui/src/components/distribution_panel.ts
index 81ebeb5..c195d5b 100644
--- a/ui/src/components/distribution_panel.ts
+++ b/ui/src/components/distribution_panel.ts
@@ -627,7 +627,7 @@
     ...columns,
     ...(inputs.filter === undefined ? [] : [inputs.filter.col]),
   ])) {
-    schema[col] = inputs.dataset.schema[col];
+    schema[col] = inputs.dataset.schema[col]!;
   }
   return schema;
 }
diff --git a/ui/src/components/sql_utils/sched.ts b/ui/src/components/sql_utils/sched.ts
index f92f231..cc923e2 100644
--- a/ui/src/components/sql_utils/sched.ts
+++ b/ui/src/components/sql_utils/sched.ts
@@ -141,16 +141,16 @@
       `(irq_context is null or irq_context = 0)`,
     ],
   });
-  if (prevRunnable.length === 0 || prevRunnable[0].wakerId === undefined) {
+  if (prevRunnable.length === 0 || prevRunnable[0]!.wakerId === undefined) {
     return undefined;
   }
-  const waker = await getThreadState(engine, prevRunnable[0].wakerId);
+  const waker = await getThreadState(engine, prevRunnable[0]!.wakerId);
   if (waker === undefined) {
     return undefined;
   }
   return {
     wakerCpu: waker?.cpu,
-    wakerUtid: prevRunnable[0].wakerUtid,
-    wakeupTs: prevRunnable[0].ts,
+    wakerUtid: prevRunnable[0]!.wakerUtid,
+    wakeupTs: prevRunnable[0]!.ts,
   };
 }
diff --git a/ui/src/components/sql_utils/slice.ts b/ui/src/components/sql_utils/slice.ts
index 8b7afe1..e8d7bfc 100644
--- a/ui/src/components/sql_utils/slice.ts
+++ b/ui/src/components/sql_utils/slice.ts
@@ -196,7 +196,7 @@
   );
   for (const [_, slice] of Object.entries(slices)) {
     if (slice.parentId !== undefined) {
-      const parent = slices[slice.parentId];
+      const parent = slices[slice.parentId]!;
       slice.parent = parent;
       parent.children.push(slice);
     }
diff --git a/ui/src/components/sql_utils/thread_state.ts b/ui/src/components/sql_utils/thread_state.ts
index 50ea7e5..4dabbf9 100644
--- a/ui/src/components/sql_utils/thread_state.ts
+++ b/ui/src/components/sql_utils/thread_state.ts
@@ -74,7 +74,7 @@
   if (state === null) {
     return 'Unknown';
   }
-  let result = states[state[0]];
+  let result = states[state[0]!]!;
   if (ioWait === true) {
     result += ' (IO)';
   } else if (ioWait === false) {
@@ -82,7 +82,7 @@
   }
   for (let i = 1; i < state.length; i++) {
     result += state[i] === '+' ? ' ' : ' + ';
-    result += states[state[i]];
+    result += states[state[i]!]!;
   }
   // state is some string we don't know how to translate.
   if (result === undefined) return state;
diff --git a/ui/src/components/tracks/breakdown_tracks.ts b/ui/src/components/tracks/breakdown_tracks.ts
index ad6d60c..c2d46f0 100644
--- a/ui/src/components/tracks/breakdown_tracks.ts
+++ b/ui/src/components/tracks/breakdown_tracks.ts
@@ -501,7 +501,7 @@
         children = new Map<string, TrackNode>();
         cache.set(currentNode.uri!, children);
       }
-      const colName = columns[colIndex];
+      const colName = columns[colIndex]!;
       const colResRaw = iter.get(colName);
       const childName = colResRaw === null ? 'NULL' : colResRaw.toString();
 
diff --git a/ui/src/components/tracks/counter_track.ts b/ui/src/components/tracks/counter_track.ts
index 8f1c8cac..369fa8d 100644
--- a/ui/src/components/tracks/counter_track.ts
+++ b/ui/src/components/tracks/counter_track.ts
@@ -14,7 +14,7 @@
 
 import m from 'mithril';
 import {valueIfAllEqual} from '../../base/array_utils';
-import {assertUnreachable, ensureExists} from '../../base/assert';
+import {assertUnreachable} from '../../base/assert';
 import {searchSegment} from '../../base/binary_search';
 import {HSLColor} from '../../base/color';
 import type {Point2D} from '../../base/geom';
@@ -284,8 +284,6 @@
   protected readonly trace: Trace;
   protected readonly uri: string;
   private readonly getSqlSource: () => string;
-  // The SQL source being loaded by useData(), if not done yet.
-  private loadingSqlSource?: string;
   private readonly rangeSharer: RangeSharer;
   private readonly onInitFn?: () => Promise<void>;
 
@@ -645,9 +643,9 @@
     if (left === -1) return undefined;
 
     return {
-      tsRel: data.timestampsRel[left],
+      tsRel: data.timestampsRel[left]!,
       tsEndRel: right === -1 ? undefined : data.timestampsRel[right],
-      lastDisplayValue: data.lastDisplayValues[left],
+      lastDisplayValue: data.lastDisplayValues[left]!,
     };
   }
 
@@ -671,11 +669,8 @@
     const {yMode, yDisplay} = this;
 
     // A sqlSource can change faster than its table builds, e.g. with live
-    // data. Keep loading the current one until done, then move to the latest,
-    // so that the track renders a few updates late rather than never. A failed
-    // build throws on the next render, as for a static sqlSource.
-    const sqlSource = this.loadingSqlSource ?? this.sqlSource;
-    this.loadingSqlSource = undefined;
+    // data. Keep rendering the previous table until the new one is ready.
+    const sqlSource = this.sqlSource;
     const tableResult = this.tableSlot.use({
       key: {
         sqlSource,
@@ -683,9 +678,11 @@
         yDisplay,
       },
       compute: () => this.createMipmapTable(sqlSource),
+      retainOn: ['sqlSource'],
     });
 
     const table = tableResult.data;
+    if (table === undefined) return undefined;
 
     // Step 2: Calculate buffered bounds and fetch counter data
     const visibleSpan = visibleWindow.toTimeSpan();
@@ -708,13 +705,12 @@
         resolution: bounds.resolution,
         yMode,
         yDisplay,
-        tableName: table?.tableName ?? '',
+        tableName: table.tableName,
       },
-      enabled: table !== undefined,
       compute: async (signal) => {
         return await this.trace.taskTracker.track(
           this.fetchCounterData(
-            ensureExists(table),
+            table,
             queryStart,
             queryEnd,
             bounds.resolution,
@@ -726,10 +722,6 @@
       retainOn: ['start', 'end', 'resolution', 'tableName'],
     });
 
-    if (tableResult.isPending || dataResult.isPending) {
-      this.loadingSqlSource = sqlSource;
-    }
-
     const counters = dataResult.data;
     if (counters === undefined) return undefined;
 
@@ -973,8 +965,8 @@
     let min = 0;
     let max = 0;
     for (let row = 0; row < numRows; row++) {
-      min = Math.min(min, minCol[row]);
-      max = Math.max(max, maxCol[row]);
+      min = Math.min(min, minCol[row]!);
+      max = Math.max(max, maxCol[row]!);
     }
 
     // timestampsRelNext[i] = timestampsRel[i+1], last element = end - start.
diff --git a/ui/src/components/tracks/counter_track_unittest.ts b/ui/src/components/tracks/counter_track_unittest.ts
index a9f5ac8..7572097 100644
--- a/ui/src/components/tracks/counter_track_unittest.ts
+++ b/ui/src/components/tracks/counter_track_unittest.ts
@@ -52,8 +52,24 @@
   // Rows returned by the global limits query; empty if the source is empty.
   limitsRows = [[0, 10]];
 
+  // How long building a table takes, to span several frames.
+  createDelayMs = 0;
+
+  // Queries that used a table after it was dropped.
+  readonly useAfterDrop: string[] = [];
+  private readonly dropped = new Set<string>();
+
   async query(sql: string): Promise<QueryResult> {
     this.log.push(sql);
+    for (const name of this.dropped) {
+      if (new RegExp(`\\b${name}\\b`).test(sql)) this.useAfterDrop.push(sql);
+    }
+    if (sql.startsWith('DROP TABLE')) {
+      this.dropped.add(sql.split(' ').at(-1)!);
+    }
+    if (sql.startsWith('CREATE VIRTUAL TABLE') && this.createDelayMs > 0) {
+      await new Promise((resolve) => setTimeout(resolve, this.createDelayMs));
+    }
     if (sql.includes('AS minDisplayValue')) {
       return numericResult(
         ['minDisplayValue', 'maxDisplayValue', 'tsRel', 'lastDisplayValue'],
@@ -83,7 +99,7 @@
 }
 
 function tableName(createStatement: string): string {
-  return createStatement.split(' ')[3];
+  return createStatement.split(' ')[3]!;
 }
 
 function setup() {
@@ -181,10 +197,36 @@
   expect(created).toHaveLength(2);
   expect(created[1]).toContain('FROM b');
   expect(engine.droppedTables()).toEqual([
-    `DROP TABLE IF EXISTS ${tableName(first)}`,
+    `DROP TABLE IF EXISTS ${tableName(first!)}`,
   ]);
   const dataQueries = engine.log.filter((q) => q.includes('minDisplayValue'));
-  expect(dataQueries.at(-1)).toContain(tableName(created[1]));
+  expect(dataQueries.at(-1)).toContain(tableName(created[1]!));
+});
+
+test('dynamic sqlSource keeps the old table drawn while rebuilding', async () => {
+  const {engine, trace, drawStepArea, renderCtx} = setup();
+  let sqlSource = 'SELECT ts, value FROM a';
+  const track = CounterTrack.create({
+    trace,
+    uri: 'test',
+    sqlSource: () => sqlSource,
+  });
+  await renderUntilSettled(track, renderCtx);
+
+  // Every frame during the rebuild draws the old data, not an empty track.
+  engine.createDelayMs = 20;
+  sqlSource = 'SELECT ts, value FROM b';
+  for (let i = 0; i < 10; i++) {
+    drawStepArea.mockClear();
+    track.render(renderCtx);
+    expect(drawStepArea).toHaveBeenCalledTimes(1);
+    await new Promise((resolve) => setTimeout(resolve, 5));
+  }
+  await renderUntilSettled(track, renderCtx);
+
+  expect(engine.createdTables()).toHaveLength(2);
+  expect(engine.droppedTables()).toHaveLength(1);
+  expect(engine.useAfterDrop).toEqual([]);
 });
 
 test('dynamic sqlSource changing on every frame is drawn', async () => {
@@ -201,6 +243,7 @@
   await renderUntilSettled(track, renderCtx);
   expect(drawStepArea).toHaveBeenCalled();
   expect(engine.createdTables().length).toBeGreaterThan(1);
+  expect(engine.useAfterDrop).toEqual([]);
 });
 
 test('materialization evaluates a dynamic sqlSource once', async () => {
diff --git a/ui/src/components/tracks/debug_slice_track_details_panel.ts b/ui/src/components/tracks/debug_slice_track_details_panel.ts
index 08de714..1145192 100644
--- a/ui/src/components/tracks/debug_slice_track_details_panel.ts
+++ b/ui/src/components/tracks/debug_slice_track_details_panel.ts
@@ -185,7 +185,7 @@
       if (key.startsWith(RAW_PREFIX)) {
         this.data.rawCols[key.substr(RAW_PREFIX.length)] = (
           row as {[key: string]: SqlValue}
-        )[key];
+        )[key]!;
       }
     }
 
diff --git a/ui/src/components/tracks/slice_track.ts b/ui/src/components/tracks/slice_track.ts
index f670518..a438f9a 100644
--- a/ui/src/components/tracks/slice_track.ts
+++ b/ui/src/components/tracks/slice_track.ts
@@ -489,7 +489,7 @@
     const rowLayout = this.buildRowLayout();
 
     // Helper: get Y position for a slice at index j
-    const sliceTop = (j: number) => rowTopFromLayout(rowLayout, depths[j]);
+    const sliceTop = (j: number) => rowTopFromLayout(rowLayout, depths[j]!);
 
     // Collect text labels to render in a second pass
     const textLabels: Array<{
@@ -508,7 +508,7 @@
     let selectedIdx = -1;
 
     for (let j = 0; j < count; j++) {
-      const slice = slices[j];
+      const slice = slices[j]!;
       const colorVariant = colorVariants[j];
       const cs = slice.colorScheme;
       const color =
@@ -525,16 +525,16 @@
       }
 
       // Collect text labels
-      const w = ends[j] - starts[j];
+      const w = ends[j]! - starts[j]!;
       const wPx = w * pxPerNs;
 
       // Skip text on collapsed rows (too small to read)
-      if (this.sliceLayout.collapsed && depths[j] > 0) continue;
+      if (this.sliceLayout.collapsed && depths[j]! > 0) continue;
 
       // Skip slices that are too narrow to show text
       if (wPx < SLICE_MIN_WIDTH_FOR_TEXT_PX) continue;
 
-      const x = starts[j];
+      const x = starts[j]!;
       const xPx = x * pxPerNs + baseOffsetPx;
 
       // Skip slices that are completely offscreen
@@ -557,7 +557,7 @@
         const clampedRight = Math.min(xPx + wPx, pxEnd);
         const clampedW = clampedRight - clampedLeft;
         const rectXCenter = clampedLeft + clampedW / 2;
-        const yCenter = rowHeightFromLayout(rowLayout, depths[j]) / 2;
+        const yCenter = rowHeightFromLayout(rowLayout, depths[j]!) / 2;
         const titleOffset = subTitle ? -4 : 1; // Move title up if there's a subtitle
         const titleY = Math.floor(y + yCenter) + titleOffset;
         const subTitleY = Math.floor(y + yCenter) + 6;
@@ -589,11 +589,11 @@
     // Draw fill ratio light overlay on the unfilled portion of each slice
     ctx.fillStyle = `#FFFFFF50`;
     for (let j = 0; j < count; j++) {
-      const slice = slices[j];
+      const slice = slices[j]!;
       const fillRatio = clamp(slice.fillRatio, 0, 1);
       if (floatEqual(fillRatio, 1)) continue;
-      const left = Math.max(starts[j] * pxPerNs + baseOffsetPx, 0);
-      const right = Math.min(ends[j] * pxPerNs + baseOffsetPx, pxEnd);
+      const left = Math.max(starts[j]! * pxPerNs + baseOffsetPx, 0);
+      const right = Math.min(ends[j]! * pxPerNs + baseOffsetPx, pxEnd);
       const width = right - left;
       const lightSectionDrawWidth = width * (1 - fillRatio);
       if (lightSectionDrawWidth < 1) continue;
@@ -603,7 +603,7 @@
         left + (width - lightSectionDrawWidth),
         y,
         lightSectionDrawWidth,
-        rowHeightFromLayout(rowLayout, depths[j]),
+        rowHeightFromLayout(rowLayout, depths[j]!),
       );
     }
 
@@ -629,9 +629,9 @@
       // Huge rects can be subject to flickering due to floating point precision
       // issues, so we clamp the selection rect to a reasonable size offscreen.
       const SEL_OFFSCREEN_MAX_PX = 20;
-      const selLeftRaw = starts[selectedIdx] * pxPerNs + baseOffsetPx;
+      const selLeftRaw = starts[selectedIdx]! * pxPerNs + baseOffsetPx;
       const selLeft = Math.max(selLeftRaw, -SEL_OFFSCREEN_MAX_PX);
-      const selRightRaw = ends[selectedIdx] * pxPerNs + baseOffsetPx;
+      const selRightRaw = ends[selectedIdx]! * pxPerNs + baseOffsetPx;
       const selRight = Math.min(selRightRaw, pxEnd + SEL_OFFSCREEN_MAX_PX);
       const selW = selRight - selLeft;
       const selY = sliceTop(selectedIdx);
@@ -642,7 +642,7 @@
         selLeft,
         selY - THICKNESS / 2,
         selW,
-        rowHeightFromLayout(rowLayout, depths[selectedIdx]) + THICKNESS,
+        rowHeightFromLayout(rowLayout, depths[selectedIdx]!) + THICKNESS,
       );
     }
   }
@@ -665,7 +665,7 @@
     let selectedIdx = -1;
 
     for (let j = 0; j < count; j++) {
-      const instant = instants[j];
+      const instant = instants[j]!;
       const colorVariant = colorVariants[j];
       const cs = instant.colorScheme;
       const color =
@@ -700,9 +700,9 @@
     // Draw selection highlight for instants
     if (selectedIdx !== -1) {
       const selX =
-        xs[selectedIdx] * pxPerNs + baseOffsetPx - this.instantWidthPx / 2;
-      const selY = rowTopFromLayout(rowLayout, instantDepths[selectedIdx]);
-      const selH = rowHeightFromLayout(rowLayout, instantDepths[selectedIdx]);
+        xs[selectedIdx]! * pxPerNs + baseOffsetPx - this.instantWidthPx / 2;
+      const selY = rowTopFromLayout(rowLayout, instantDepths[selectedIdx]!);
+      const selH = rowHeightFromLayout(rowLayout, instantDepths[selectedIdx]!);
       const THICKNESS = 3;
       ctx.strokeStyle = trackCtx.colors.COLOR_TIMELINE_OVERLAY;
       ctx.lineWidth = THICKNESS;
@@ -929,7 +929,7 @@
     const countCol = cols.__count;
     const depthCol = cols.__depth;
     const schemaKeys = Object.keys(dataset.schema);
-    const schemaCols = schemaKeys.map((k) => cols[k]);
+    const schemaCols = schemaKeys.map((k) => cols[k]!);
     const xs = new Float32Array(tsCol);
     const depths = new Uint16Array(depthCol);
 
@@ -950,11 +950,11 @@
       const colorScheme = this.getColor(row, title);
 
       instants[i] = {
-        id: idCol[i],
+        id: idCol[i]!,
         title,
         subtitle,
         colorScheme,
-        count: countCol[i],
+        count: countCol[i]!,
         row,
       };
     }
@@ -1038,7 +1038,7 @@
     const depthCol = cols.__depth;
     const incompleteCol = cols.__incomplete;
     const schemaKeys = Object.keys(dataset.schema);
-    const schemaCols = schemaKeys.map((k) => cols[k]);
+    const schemaCols = schemaKeys.map((k) => cols[k]!);
 
     const starts = new Float32Array(startCol);
     const ends = new Float32Array(count);
@@ -1056,7 +1056,7 @@
       const title = this.getTitle(row);
       const subtitle = this.getSubtitle(row);
       const colorScheme = this.getColor(row, title);
-      const end = endCol[i];
+      const end = endCol[i]!;
       const isIncomplete = incompleteCol[i] === 1;
 
       // Incomplete slices are assigned a +Infinity end
@@ -1065,11 +1065,11 @@
         ? RECT_PATTERN_FADE_RIGHT
         : (this.attrs.slicePattern?.(row) ?? 0);
       slices[i] = {
-        id: idCol[i],
+        id: idCol[i]!,
         title,
         subtitle,
         colorScheme,
-        count: countCol[i],
+        count: countCol[i]!,
         fillRatio: this.attrs.fillRatio?.(row) ?? 1,
         row,
       };
@@ -1094,7 +1094,7 @@
   ): InferRowType<T> {
     const row: Record<string, SqlValue> = {};
     for (let k = 0; k < keys.length; k++) {
-      row[keys[k]] = cols[k][i];
+      row[keys[k]!] = cols[k]![i]!;
     }
     return row as InferRowType<T>;
   }
@@ -1147,7 +1147,7 @@
       const hoveredTitle = highlightedSliceName;
       // Index based iteration is more efficient than .map
       for (let i = 0; i < slices.length; i++) {
-        const {id, title} = slices[i];
+        const {id, title} = slices[i]!;
         variants[i] =
           id === hoveredSliceId || title === hoveredTitle
             ? ColorVariant.VARIANT
@@ -1276,8 +1276,8 @@
       for (let i = 0; i < sliceBufs.count; i++) {
         if (sliceBufs.depths[i] !== depth) continue;
 
-        const startPx = sliceBufs.starts[i] * pxPerNs + baseOffsetPx;
-        const endPx = sliceBufs.ends[i] * pxPerNs + baseOffsetPx;
+        const startPx = sliceBufs.starts[i]! * pxPerNs + baseOffsetPx;
+        const endPx = sliceBufs.ends[i]! * pxPerNs + baseOffsetPx;
         if (startPx <= x && x <= endPx) {
           return sliceBufs.slices[i];
         }
@@ -1289,7 +1289,7 @@
       for (let i = 0; i < instantBufs.count; i++) {
         if (instantBufs.depths[i] !== depth) continue;
 
-        const instantX = instantBufs.xs[i] * pxPerNs + baseOffsetPx;
+        const instantX = instantBufs.xs[i]! * pxPerNs + baseOffsetPx;
         if (x >= instantX - halfWidth && x <= instantX + halfWidth) {
           return instantBufs.instants[i];
         }
@@ -1404,17 +1404,17 @@
     const {starts, ends, count} = this.currentDataFrame.slices;
     for (let i = 0; i < count; i++) {
       // Convert relative start to absolute time
-      const sliceStartNs = frameStartNs + starts[i];
+      const sliceStartNs = frameStartNs + starts[i]!;
       checkBoundary(sliceStartNs);
 
-      const sliceEndNs = frameStartNs + ends[i];
+      const sliceEndNs = frameStartNs + ends[i]!;
       checkBoundary(sliceEndNs);
     }
 
     // Check instants
     const instants = this.currentDataFrame.instants;
     for (let i = 0; i < instants.count; i++) {
-      const instantNs = frameStartNs + instants.xs[i];
+      const instantNs = frameStartNs + instants.xs[i]!;
       checkBoundary(instantNs);
     }
 
diff --git a/ui/src/components/widgets/charts/bar_chart.ts b/ui/src/components/widgets/charts/bar_chart.ts
index 0f24c4c..79105e7 100644
--- a/ui/src/components/widgets/charts/bar_chart.ts
+++ b/ui/src/components/widgets/charts/bar_chart.ts
@@ -263,7 +263,7 @@
       formatter: isStacked
         ? undefined
         : (params: Array<{name?: string; value?: number}>) => {
-            const p = Array.isArray(params) ? params[0] : params;
+            const p = Array.isArray(params) ? params[0]! : params;
             return renderTooltip([
               m('div', p.name ?? ''),
               m('div', `${measureLabel}: ${fmtMeasure(p.value ?? 0)}`),
@@ -410,7 +410,7 @@
           if (minIdx <= maxIdx) {
             const labels: Array<string | number> = [];
             for (let i = minIdx; i <= maxIdx; i++) {
-              labels.push(items[i].label);
+              labels.push(items[i]!.label);
             }
             if (labels.length > 0) {
               onBrush(labels);
diff --git a/ui/src/components/widgets/charts/boxplot.ts b/ui/src/components/widgets/charts/boxplot.ts
index e88fb8d..fdb439f 100644
--- a/ui/src/components/widgets/charts/boxplot.ts
+++ b/ui/src/components/widgets/charts/boxplot.ts
@@ -186,11 +186,11 @@
         if (v === undefined) return '';
         return renderTooltip([
           m('div', m('b', params.name ?? '')),
-          m('div', `Max: ${fmtVal(v[5] ?? v[4])}`),
-          m('div', `Q3: ${fmtVal(v[4] ?? v[3])}`),
-          m('div', `Median: ${fmtVal(v[3] ?? v[2])}`),
-          m('div', `Q1: ${fmtVal(v[2] ?? v[1])}`),
-          m('div', `Min: ${fmtVal(v[1] ?? v[0])}`),
+          m('div', `Max: ${fmtVal(v[5] ?? v[4]!)}`),
+          m('div', `Q3: ${fmtVal(v[4] ?? v[3]!)}`),
+          m('div', `Median: ${fmtVal(v[3] ?? v[2]!)}`),
+          m('div', `Q1: ${fmtVal(v[2] ?? v[1]!)}`),
+          m('div', `Min: ${fmtVal(v[1] ?? v[0]!)}`),
         ]);
       },
     }),
diff --git a/ui/src/components/widgets/charts/chart_sql_source.ts b/ui/src/components/widgets/charts/chart_sql_source.ts
index 8f5c205..f6e540c 100644
--- a/ui/src/components/widgets/charts/chart_sql_source.ts
+++ b/ui/src/components/widgets/charts/chart_sql_source.ts
@@ -371,7 +371,7 @@
     const whereClause = this.buildWhereClause(config.filters);
     const groupByExprs = config.dimensions.map((d) => d.column);
     const direction = config.orderDirection ?? 'desc';
-    const firstDimAlias = this.dimAlias(config.dimensions[0], 0);
+    const firstDimAlias = this.dimAlias(config.dimensions[0]!, 0);
     const orderAlias = this.measureAlias(config.measures, 0);
 
     const dimAliases = config.dimensions.map((d, i) => this.dimAlias(d, i));
@@ -606,7 +606,7 @@
     measures: ReadonlyArray<MeasureSpec>,
     index: number,
   ): string {
-    const meas = measures[index];
+    const meas = measures[index]!;
     if (meas.alias !== undefined) {
       validateColumnName(meas.alias);
       return meas.alias;
@@ -661,7 +661,7 @@
         filter.field,
       ),
     );
-    if (parts.length === 1) return parts[0];
+    if (parts.length === 1) return parts[0]!;
     const joiner = negated ? ' AND ' : ' OR ';
     return `(${parts.join(joiner)})`;
   }
diff --git a/ui/src/components/widgets/charts/chart_utils.ts b/ui/src/components/widgets/charts/chart_utils.ts
index 559e9c0..98d7b64 100644
--- a/ui/src/components/widgets/charts/chart_utils.ts
+++ b/ui/src/components/widgets/charts/chart_utils.ts
@@ -55,8 +55,8 @@
   const idx = (p / 100) * (sorted.length - 1);
   const lower = Math.floor(idx);
   const upper = Math.ceil(idx);
-  if (lower === upper) return sorted[lower];
-  return sorted[lower] + (sorted[upper] - sorted[lower]) * (idx - lower);
+  if (lower === upper) return sorted[lower]!;
+  return sorted[lower]! + (sorted[upper]! - sorted[lower]!) * (idx - lower);
 }
 
 // ---------------------------------------------------------------------------
@@ -97,8 +97,8 @@
     areas?: ReadonlyArray<{coordRange?: [number, number]}>;
   };
   const areas = p.areas;
-  if (areas !== undefined && areas.length > 0 && areas[0].coordRange) {
-    const [a, b] = areas[0].coordRange;
+  if (areas !== undefined && areas.length > 0 && areas[0]!.coordRange) {
+    const [a, b] = areas[0]!.coordRange;
     return [Math.min(a, b), Math.max(a, b)];
   }
   return undefined;
@@ -121,7 +121,7 @@
   };
   const areas = p.areas;
   if (areas === undefined || areas.length === 0) return undefined;
-  const coordRange = areas[0].coordRange;
+  const coordRange = areas[0]!.coordRange;
   if (coordRange === undefined) return undefined;
   const [[x1, x2], [y1, y2]] = coordRange;
   return {
diff --git a/ui/src/components/widgets/charts/flamegraph_chart.ts b/ui/src/components/widgets/charts/flamegraph_chart.ts
index 52ed4c4..7999c2d 100644
--- a/ui/src/components/widgets/charts/flamegraph_chart.ts
+++ b/ui/src/components/widgets/charts/flamegraph_chart.ts
@@ -94,17 +94,17 @@
   const short = /^#([0-9a-f])([0-9a-f])([0-9a-f])$/i.exec(c);
   if (short) {
     return [
-      parseInt(short[1] + short[1], 16),
-      parseInt(short[2] + short[2], 16),
-      parseInt(short[3] + short[3], 16),
+      parseInt(short[1]! + short[1]!, 16),
+      parseInt(short[2]! + short[2]!, 16),
+      parseInt(short[3]! + short[3]!, 16),
     ];
   }
   const long = /^#([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})$/i.exec(c);
   if (long) {
     return [
-      parseInt(long[1], 16),
-      parseInt(long[2], 16),
-      parseInt(long[3], 16),
+      parseInt(long[1]!, 16),
+      parseInt(long[2]!, 16),
+      parseInt(long[3]!, 16),
     ];
   }
   return undefined;
diff --git a/ui/src/components/widgets/charts/heatmap.ts b/ui/src/components/widgets/charts/heatmap.ts
index 84de0f1..c81ccaf 100644
--- a/ui/src/components/widgets/charts/heatmap.ts
+++ b/ui/src/components/widgets/charts/heatmap.ts
@@ -276,11 +276,11 @@
           if (xMin <= xMax && yMin <= yMax) {
             const selectedX: string[] = [];
             for (let i = xMin; i <= xMax; i++) {
-              selectedX.push(xLabels[i]);
+              selectedX.push(xLabels[i]!);
             }
             const selectedY: string[] = [];
             for (let i = yMin; i <= yMax; i++) {
-              selectedY.push(yLabels[i]);
+              selectedY.push(yLabels[i]!);
             }
             if (selectedX.length > 0 && selectedY.length > 0) {
               onBrush({xLabels: selectedX, yLabels: selectedY});
diff --git a/ui/src/components/widgets/charts/histogram.ts b/ui/src/components/widgets/charts/histogram.ts
index 438768a..4709e52 100644
--- a/ui/src/components/widgets/charts/histogram.ts
+++ b/ui/src/components/widgets/charts/histogram.ts
@@ -234,7 +234,7 @@
         }
 
         // Regular bucket
-        const bucket = data.buckets[idx];
+        const bucket = data.buckets[idx]!;
         const pct =
           totalWithNull > 0
             ? ((bucket.count / totalWithNull) * 100).toFixed(1)
@@ -316,8 +316,8 @@
           const maxIdx = Math.min(buckets.length - 1, endIdx);
           if (minIdx <= maxIdx && minIdx < buckets.length) {
             onBrush({
-              start: buckets[minIdx].start,
-              end: buckets[maxIdx].end,
+              start: buckets[minIdx]!.start,
+              end: buckets[maxIdx]!.end,
             });
           }
         }
diff --git a/ui/src/components/widgets/charts/histogram_loader.ts b/ui/src/components/widgets/charts/histogram_loader.ts
index 15e409a..46ddcc7 100644
--- a/ui/src/components/widgets/charts/histogram_loader.ts
+++ b/ui/src/components/widgets/charts/histogram_loader.ts
@@ -185,7 +185,7 @@
       bucketIndex = bucketCount - 1;
     }
 
-    const bucket = buckets[bucketIndex];
+    const bucket = buckets[bucketIndex]!;
     buckets[bucketIndex] = {...bucket, count: bucket.count + 1};
   }
 
diff --git a/ui/src/components/widgets/charts/line_chart.ts b/ui/src/components/widgets/charts/line_chart.ts
index f6f84e4..eb1326b 100644
--- a/ui/src/components/widgets/charts/line_chart.ts
+++ b/ui/src/components/widgets/charts/line_chart.ts
@@ -317,7 +317,7 @@
         }>,
       ) => {
         if (!Array.isArray(params) || params.length === 0) return '';
-        const xVal = params[0].data?.[0];
+        const xVal = params[0]!.data?.[0];
         const header = xVal !== undefined ? `X: ${fmtX(xVal)}` : '';
         return renderTooltip([
           m('div', header),
diff --git a/ui/src/components/widgets/charts/line_chart_loader.ts b/ui/src/components/widgets/charts/line_chart_loader.ts
index 5e83542..ae76b8d 100644
--- a/ui/src/components/widgets/charts/line_chart_loader.ts
+++ b/ui/src/components/widgets/charts/line_chart_loader.ts
@@ -181,13 +181,13 @@
 ): LineChartPoint[] {
   if (points.length <= maxPoints) return [...points];
   if (maxPoints <= 2) {
-    return [points[0], points[points.length - 1]];
+    return [points[0]!, points[points.length - 1]!];
   }
-  const result: LineChartPoint[] = [points[0]];
+  const result: LineChartPoint[] = [points[0]!];
   const step = (points.length - 1) / (maxPoints - 1);
   for (let i = 1; i < maxPoints - 1; i++) {
-    result.push(points[Math.round(i * step)]);
+    result.push(points[Math.round(i * step)]!);
   }
-  result.push(points[points.length - 1]);
+  result.push(points[points.length - 1]!);
   return result;
 }
diff --git a/ui/src/components/widgets/charts/pie_chart.ts b/ui/src/components/widgets/charts/pie_chart.ts
index 3a81a5f..3385b15 100644
--- a/ui/src/components/widgets/charts/pie_chart.ts
+++ b/ui/src/components/widgets/charts/pie_chart.ts
@@ -199,7 +199,7 @@
         const p = params as EChartClickParams;
         const idx = p.dataIndex;
         if (idx !== undefined && idx >= 0 && idx < slices.length) {
-          onSliceClick(slices[idx]);
+          onSliceClick(slices[idx]!);
         }
       },
     },
diff --git a/ui/src/components/widgets/charts/scorecard_unittest.ts b/ui/src/components/widgets/charts/scorecard_unittest.ts
index 87d8ab7..4dcc686 100644
--- a/ui/src/components/widgets/charts/scorecard_unittest.ts
+++ b/ui/src/components/widgets/charts/scorecard_unittest.ts
@@ -37,7 +37,7 @@
   // Use regex to handle both '.' and ',' as decimal separators.
   const match = result.match(/[.,](\d+)$/);
   if (match) {
-    expect(match[1].length).toBeLessThanOrEqual(2);
+    expect(match[1]!.length).toBeLessThanOrEqual(2);
   }
 });
 
diff --git a/ui/src/components/widgets/charts_svg/histogram_svg.ts b/ui/src/components/widgets/charts_svg/histogram_svg.ts
index 907f344..4d12a5c 100644
--- a/ui/src/components/widgets/charts_svg/histogram_svg.ts
+++ b/ui/src/components/widgets/charts_svg/histogram_svg.ts
@@ -68,10 +68,10 @@
       const isNull = idx >= data.buckets.length;
       const nCount = data.nullCount ?? 0;
       const totalWithNull = data.totalCount + nCount;
-      const count = isNull ? nCount : data.buckets[idx].count;
+      const count = isNull ? nCount : data.buckets[idx]!.count;
       const header = isNull
         ? 'NULL'
-        : `${fmtX(data.buckets[idx].start)} – ${fmtX(data.buckets[idx].end)}`;
+        : `${fmtX(data.buckets[idx]!.start)} – ${fmtX(data.buckets[idx]!.end)}`;
       const pct =
         totalWithNull > 0 ? ((count / totalWithNull) * 100).toFixed(1) : '0';
       return m(ChartTooltip, [
@@ -233,7 +233,7 @@
     const sel = attrs.selection;
     const isSelected = (i: number): boolean => {
       if (sel === undefined || i >= buckets.length) return false;
-      const b = buckets[i];
+      const b = buckets[i]!;
       // Point selection (start == end): highlight the bucket containing it.
       // Buckets are half-open [start, end) so a value on a boundary belongs
       // to the next bucket — except the last bucket, which must be inclusive
@@ -399,7 +399,7 @@
       // Final right-edge tick at the last bucket end.
       buckets.length > 0 &&
         (() => {
-          const last = buckets[buckets.length - 1];
+          const last = buckets[buckets.length - 1]!;
           const x = slotX(dataSlots - 1) + adjBarWidth;
           return m('g', [
             m('line', {
@@ -488,7 +488,7 @@
     if (buckets.length === 0) return;
     const lo = clamp(Math.min(start, current), 0, dataSlots - 1);
     const hi = clamp(Math.max(start, current), 0, dataSlots - 1);
-    onBrush({start: buckets[lo].start, end: buckets[hi].end});
+    onBrush({start: buckets[lo]!.start, end: buckets[hi]!.end});
   }
 
   private handlePointerMove(
diff --git a/ui/src/components/widgets/charts_svg/line_chart_svg.ts b/ui/src/components/widgets/charts_svg/line_chart_svg.ts
index 65dc590..48b1d51 100644
--- a/ui/src/components/widgets/charts_svg/line_chart_svg.ts
+++ b/ui/src/components/widgets/charts_svg/line_chart_svg.ts
@@ -120,7 +120,7 @@
         ChartLegend,
         data.series.map((s, i) => {
           const last =
-            s.points.length > 0 ? s.points[s.points.length - 1].y : undefined;
+            s.points.length > 0 ? s.points[s.points.length - 1]!.y : undefined;
           const hidden = this.hiddenSeries.has(s.name);
           return m(ChartLegend.Entry, {
             name: s.name,
@@ -606,7 +606,7 @@
       this.hover = undefined;
       return;
     }
-    if (seriesPlots.length === 0 || seriesPlots[0].points.length === 0) return;
+    if (seriesPlots.length === 0 || seriesPlots[0]!.points.length === 0) return;
     const px = e.clientX - rect.left;
     if (px < padLeft || px > padLeft + plotW) {
       if (this.hover !== undefined) {
@@ -617,11 +617,11 @@
     const xVal =
       xRange.min + ((px - padLeft) / (plotW || 1)) * (xRange.max - xRange.min);
     // Nearest index in series 0 (assumes shared x; first series is reference).
-    const pts = seriesPlots[0].points;
+    const pts = seriesPlots[0]!.points;
     let bestIdx = 0;
     let bestDist = Infinity;
     for (let i = 0; i < pts.length; i++) {
-      const d = Math.abs(pts[i].x - xVal);
+      const d = Math.abs(pts[i]!.x - xVal);
       if (d < bestDist) {
         bestDist = d;
         bestIdx = i;
@@ -631,7 +631,7 @@
       clientX: e.clientX,
       clientY: e.clientY,
       index: bestIdx,
-      xValue: pts[bestIdx].x,
+      xValue: pts[bestIdx]!.x,
     };
   }
 }
@@ -651,7 +651,7 @@
   const result: SeriesPlot[] = [];
   const cum = new Map<number, number>();
   for (let i = 0; i < series.length; i++) {
-    const s = series[i];
+    const s = series[i]!;
     const stackedPoints: {x: number; y: number; raw: number}[] = [];
     for (const p of s.points) {
       const prev = cum.get(p.x) ?? 0;
@@ -676,7 +676,7 @@
   if (s.points.length === 0) return '';
   let d = '';
   for (let i = 0; i < s.points.length; i++) {
-    const p = s.points[i];
+    const p = s.points[i]!;
     d += (i === 0 ? 'M' : 'L') + xToPx(p.x) + ',' + yToPx(p.y) + ' ';
   }
   return d.trim();
@@ -694,18 +694,19 @@
 ): string {
   if (s.points.length === 0) return '';
   const top = s.points;
-  const bottom = index > 0 ? all[index - 1].points : undefined;
+  const bottom = index > 0 ? all[index - 1]!.points : undefined;
   let d = '';
   for (let i = 0; i < top.length; i++) {
-    d += (i === 0 ? 'M' : 'L') + xToPx(top[i].x) + ',' + yToPx(top[i].y) + ' ';
+    d +=
+      (i === 0 ? 'M' : 'L') + xToPx(top[i]!.x) + ',' + yToPx(top[i]!.y) + ' ';
   }
   if (bottom !== undefined) {
     for (let i = bottom.length - 1; i >= 0; i--) {
-      d += 'L' + xToPx(bottom[i].x) + ',' + yToPx(bottom[i].y) + ' ';
+      d += 'L' + xToPx(bottom[i]!.x) + ',' + yToPx(bottom[i]!.y) + ' ';
     }
   } else {
-    d += 'L' + xToPx(top[top.length - 1].x) + ',' + baselinePx + ' ';
-    d += 'L' + xToPx(top[0].x) + ',' + baselinePx + ' ';
+    d += 'L' + xToPx(top[top.length - 1]!.x) + ',' + baselinePx + ' ';
+    d += 'L' + xToPx(top[0]!.x) + ',' + baselinePx + ' ';
   }
   d += 'Z';
   return d;
diff --git a/ui/src/components/widgets/datagrid/data_source.ts b/ui/src/components/widgets/datagrid/data_source.ts
index 2a882d5..7b9c18f 100644
--- a/ui/src/components/widgets/datagrid/data_source.ts
+++ b/ui/src/components/widgets/datagrid/data_source.ts
@@ -14,7 +14,13 @@
 
 import type {AsyncMemoResult} from '../../../base/async_memo';
 import type {Row, SqlValue} from '../../../trace_processor/query_result';
-import type {AggregateFunction, Filter, GroupPath, IdBasedTree} from './model';
+import type {
+  AggregateFunction,
+  Filter,
+  GroupPath,
+  IdBasedTree,
+  QuickFilter,
+} from './model';
 
 /**
  * Data source interface for DataGrid.
@@ -84,6 +90,11 @@
 // Flat mode: simple column selection
 export interface FlatModel extends DataSourceModelBase {
   readonly mode: 'flat';
+  // Whole-table text filter, applied in addition to (AND-ed with) the column
+  // filters. Ignored when the text is empty. Only in flat mode: in pivot mode
+  // most cells show a sample or a total rather than a row's value, so "rows
+  // containing the text" has no clear meaning there.
+  readonly quickFilter?: QuickFilter;
   readonly columns: readonly {
     readonly field: string;
     readonly alias: string;
diff --git a/ui/src/components/widgets/datagrid/datagrid.scss b/ui/src/components/widgets/datagrid/datagrid.scss
index 7535b43..4b7ffe9 100644
--- a/ui/src/components/widgets/datagrid/datagrid.scss
+++ b/ui/src/components/widgets/datagrid/datagrid.scss
@@ -64,6 +64,19 @@
     color: var(--pf-color-text-muted);
   }
 
+  // Must come after __groupby-column so it wins on group-by cells.
+  &__cell--quick-filter-match {
+    background-color: color-mix(
+      in srgb,
+      var(--pf-color-accent) 15%,
+      transparent
+    );
+  }
+
+  &__quick-filter {
+    width: 200px;
+  }
+
   &__table {
     flex: 1;
     overflow: auto;
diff --git a/ui/src/components/widgets/datagrid/datagrid.ts b/ui/src/components/widgets/datagrid/datagrid.ts
index 56ebda9..5816c51 100644
--- a/ui/src/components/widgets/datagrid/datagrid.ts
+++ b/ui/src/components/widgets/datagrid/datagrid.ts
@@ -37,6 +37,7 @@
 import {Icon} from '../../../widgets/icon';
 import {LinearProgress} from '../../../widgets/linear_progress';
 import {MenuDivider, MenuItem} from '../../../widgets/menu';
+import {TextInput} from '../../../widgets/text_input';
 import {
   AggregateMenu,
   ColumnMenu,
@@ -84,8 +85,16 @@
   type GroupPath,
   type IdBasedTree,
   type Pivot,
+  type QuickFilter,
   type SortDirection,
 } from './model';
+import {valueMatchesQuickFilter} from './quick_filter_utils';
+
+// How long to wait after the last keystroke in the quick filter box before
+// applying the filter.
+const QUICK_FILTER_DEBOUNCE_MS = 250;
+
+const QUICK_FILTER_MATCH_CLASS = 'pf-data-grid__cell--quick-filter-match';
 
 // Compare two SqlValues for equality, handling nulls, undefined, and different types.
 function sqlValuesEqual(a: SqlValue, b: SqlValue): boolean {
@@ -110,7 +119,7 @@
 function groupPathsEqual(a: GroupPath, b: GroupPath): boolean {
   if (a.length !== b.length) return false;
   for (let i = 0; i < a.length; i++) {
-    if (!sqlValuesEqual(a[i], b[i])) return false;
+    if (!sqlValuesEqual(a[i]!, b[i]!)) return false;
   }
   return true;
 }
@@ -300,6 +309,36 @@
   readonly disableFilterControls?: boolean;
 
   /**
+   * When true, shows a "Filter rows" text box in the toolbar. Typing in it
+   * hides every row where no visible column contains the text, and highlights
+   * the matching cells. It matches raw values, not formatted ones.
+   *
+   * The box is only shown for flat tables (including pivot drill-downs): it is
+   * always hidden in pivot mode and ID-based tree mode. Defaults to false.
+   */
+  readonly enableQuickFilter?: boolean;
+
+  /**
+   * The quick filter text - can operate in controlled or uncontrolled mode.
+   *
+   * In controlled mode: Provide this prop along with onQuickFilterChanged callback.
+   * In uncontrolled mode: Omit this prop to let the grid manage the quick
+   * filter text internally.
+   */
+  readonly quickFilter?: string;
+
+  /**
+   * Initial quick filter text to apply on first load.
+   * This is ignored in controlled mode (i.e. when `quickFilter` is provided).
+   */
+  readonly initialQuickFilter?: string;
+
+  /**
+   * Called when the quick filter text changes (after the user stops typing).
+   */
+  readonly onQuickFilterChanged?: (text: string) => void;
+
+  /**
    * Defines how data should be pivoted - can operate in controlled or
    * uncontrolled mode.
    *
@@ -446,6 +485,8 @@
   readonly showColumnControls: boolean;
   readonly showPivotControls: boolean;
   readonly showFilterControls: boolean;
+  // The active quick filter text, used to highlight matching cells.
+  readonly quickFilterText: string;
 }
 
 /**
@@ -470,6 +511,12 @@
   private pivot?: Pivot;
   private tree?: IdBasedTree;
 
+  // The applied quick filter text, and the text currently in the box. They
+  // differ while the user is typing, until the debounce timer fires.
+  private quickFilter = '';
+  private quickFilterInput = '';
+  private quickFilterDebounceTimer?: ReturnType<typeof setTimeout>;
+
   // Track pagination state from virtual scrolling
   private paginationOffset: number = 0;
   private paginationLimit: number = 100;
@@ -498,6 +545,15 @@
     if (attrs.initialTree) {
       this.tree = attrs.initialTree;
     }
+
+    if (attrs.initialQuickFilter !== undefined) {
+      this.quickFilter = attrs.initialQuickFilter;
+      this.quickFilterInput = attrs.initialQuickFilter;
+    }
+  }
+
+  onremove() {
+    clearTimeout(this.quickFilterDebounceTimer);
   }
 
   view({attrs}: m.Vnode<DataGridAttrs>) {
@@ -509,6 +565,8 @@
       filters,
       pivot,
       tree,
+      quickFilter,
+      enableQuickFilter = false,
       schema,
       structuredQueryCompatMode = false,
       toolbarItemsLeft,
@@ -522,6 +580,13 @@
     if (filters) this.filters = filters;
     if (pivot) this.pivot = pivot;
     if (tree) this.tree = tree;
+    if (quickFilter !== undefined) {
+      this.quickFilter = quickFilter;
+      // Don't overwrite what the user is typing before it's been applied.
+      if (this.quickFilterDebounceTimer === undefined) {
+        this.quickFilterInput = quickFilter;
+      }
+    }
 
     // Determine if we're in tree mode (has id-based tree config)
     const isTreeMode = this.tree !== undefined;
@@ -551,9 +616,17 @@
       this.pivot.groupBy.length > 0 &&
       this.pivot.drillDown === undefined;
 
+    // The quick filter is only offered for flat tables:
+    // - In tree mode, removing non-matching rows would also hide their
+    //   matching descendants.
+    // - In pivot mode, most cells show a sampled value or a total rather than
+    //   a row's value, so "rows containing the text" has no clear meaning.
+    const showQuickFilter = enableQuickFilter && !isTreeMode && !isPivotMode;
+    const quickFilterText = showQuickFilter ? this.quickFilter : '';
+
     // Build the model for data source queries
     const datasource = getOrCreateDataSource(data);
-    const model = this.buildDataSourceModel();
+    const model = this.buildDataSourceModel(quickFilterText);
 
     // Fetch data using the slot-like API
     const rowsResult = datasource.useRows(model);
@@ -634,6 +707,7 @@
         showColumnControls,
         showPivotControls,
         showFilterControls,
+        quickFilterText,
       };
 
       gridColumns = this.buildFlatColumns(flatContext);
@@ -656,6 +730,7 @@
         ],
         rightItems: [
           toolbarItemsRight,
+          showQuickFilter && this.renderQuickFilterBox(attrs),
           showExportButton &&
             m(ExportButton, {
               onExportData: (format) =>
@@ -720,12 +795,12 @@
             EmptyState,
             {
               title:
-                this.filters.length > 0
+                this.filters.length > 0 || quickFilterText !== ''
                   ? 'No results match your filters'
                   : (emptyStateMessage ?? 'No data available'),
               fillHeight: true,
             },
-            this.filters.length > 0 &&
+            (this.filters.length > 0 || quickFilterText !== '') &&
               m(Button, {
                 variant: ButtonVariant.Filled,
                 icon: Icons.FilterOff,
@@ -741,7 +816,7 @@
    * Builds a DataSourceModel from the current state.
    * The model shape depends on whether we're in pivot, tree, or flat mode.
    */
-  private buildDataSourceModel(): DataSourceModel {
+  private buildDataSourceModel(quickFilterText: string): DataSourceModel {
     // Extract sort from columns (flat mode only)
     const sortedColumn = this.columns.find((c) => c.sort);
     const sort = sortedColumn
@@ -767,6 +842,10 @@
         mode: 'flat',
         sort,
         filters: [...(this.filters ?? []), ...drillDownFilters],
+        quickFilter: buildQuickFilter(
+          quickFilterText,
+          this.columns.map((col) => col.field),
+        ),
         columns: this.columns
           .map((col) => ({
             field: col.field,
@@ -829,6 +908,10 @@
         ...baseModel,
         mode: 'flat',
         sort,
+        quickFilter: buildQuickFilter(
+          quickFilterText,
+          this.columns.map((col) => col.field),
+        ),
         columns: this.columns
           .map((col) => ({
             field: col.field,
@@ -869,6 +952,41 @@
   private clearFilters(attrs: DataGridAttrs): void {
     this.filters = [];
     attrs.onFiltersChanged?.([]);
+    if (this.quickFilter !== '' || this.quickFilterInput !== '') {
+      this.setQuickFilter('', attrs);
+    }
+  }
+
+  private renderQuickFilterBox(attrs: DataGridAttrs): m.Children {
+    return m(TextInput, {
+      className: 'pf-data-grid__quick-filter',
+      leftIcon: Icons.Search,
+      placeholder: 'Filter rows\u2026',
+      title:
+        'Shows rows where any visible column contains this text. ' +
+        'Matches raw values.',
+      value: this.quickFilterInput,
+      onInput: (text: string) => this.onQuickFilterInput(text, attrs),
+    });
+  }
+
+  // Updates the box immediately, but only applies the filter once the user has
+  // stopped typing for QUICK_FILTER_DEBOUNCE_MS.
+  private onQuickFilterInput(text: string, attrs: DataGridAttrs): void {
+    this.quickFilterInput = text;
+    clearTimeout(this.quickFilterDebounceTimer);
+    this.quickFilterDebounceTimer = setTimeout(() => {
+      this.setQuickFilter(text, attrs);
+      m.redraw();
+    }, QUICK_FILTER_DEBOUNCE_MS);
+  }
+
+  private setQuickFilter(text: string, attrs: DataGridAttrs): void {
+    clearTimeout(this.quickFilterDebounceTimer);
+    this.quickFilterDebounceTimer = undefined;
+    this.quickFilter = text;
+    this.quickFilterInput = text;
+    attrs.onQuickFilterChanged?.(text);
   }
 
   private removeFilter(index: number, attrs: DataGridAttrs): void {
@@ -910,7 +1028,7 @@
     let insertIndex = toIndex;
     if (fromIndex < toIndex) insertIndex--;
     if (position === 'after') insertIndex++;
-    newColumns.splice(insertIndex, 0, removed);
+    newColumns.splice(insertIndex, 0, removed!);
 
     this.columns = newColumns;
     attrs.onColumnsChanged?.(newColumns);
@@ -1249,7 +1367,7 @@
     let insertIndex = toIndex;
     if (fromIndex < toIndex) insertIndex--;
     if (position === 'after') insertIndex++;
-    groupBy.splice(insertIndex, 0, removed);
+    groupBy.splice(insertIndex, 0, removed!);
 
     const newPivot: Pivot = {...this.pivot, groupBy};
     this.pivot = newPivot;
@@ -1269,7 +1387,7 @@
     let insertIndex = toIndex;
     if (fromIndex < toIndex) insertIndex--;
     if (position === 'after') insertIndex++;
-    aggregates.splice(insertIndex, 0, removed);
+    aggregates.splice(insertIndex, 0, removed!);
 
     const newPivot: Pivot = {...this.pivot, aggregates};
     this.pivot = newPivot;
@@ -1648,7 +1766,14 @@
    * Builds grid rows for flat (non-pivot) mode.
    */
   private buildFlatRows(ctx: FlatGridBuildContext): m.Children[][] {
-    const {attrs, rowsResult, columnInfoCache, tree, showFilterControls} = ctx;
+    const {
+      attrs,
+      rowsResult,
+      columnInfoCache,
+      tree,
+      showFilterControls,
+      quickFilterText,
+    } = ctx;
 
     if (rowsResult.rows === undefined) return [];
 
@@ -1714,6 +1839,10 @@
           return m(
             GridCell,
             {
+              className: classNames(
+                valueMatchesQuickFilter(value, quickFilterText) &&
+                  QUICK_FILTER_MATCH_CLASS,
+              ),
               actionButtons: colInfo?.actions?.(value, row),
               align: isRich ? (rendered.align ?? 'left') : getAligment(value),
               nullish: isRich
@@ -1835,7 +1964,7 @@
 
     // Build groupBy columns
     for (let i = 0; i < pivot.groupBy.length; i++) {
-      const groupByCol = pivot.groupBy[i];
+      const groupByCol = pivot.groupBy[i]!;
       const field = groupByCol.field;
       const sort = groupByCol.sort;
       const colId = groupByCol.id;
@@ -1915,7 +2044,7 @@
     // Build aggregate columns
     const aggregates = pivot.aggregates ?? [];
     for (let i = 0; i < aggregates.length; i++) {
-      const agg = aggregates[i];
+      const agg = aggregates[i]!;
       const sort = agg.sort;
       const alias = getAggregateAlias(agg);
 
@@ -2082,9 +2211,9 @@
 
         // Render groupBy columns
         for (let i = 0; i < numGroupBy; i++) {
-          const groupByCol = pivot.groupBy[i];
+          const groupByCol = pivot.groupBy[i]!;
           const {id, field} = groupByCol;
-          const value = row[id];
+          const value = row[id]!;
 
           // Column is a rollup if its index is greater than the row's level
           const isRollupColumn = i > rowLevel;
@@ -2160,10 +2289,10 @@
                         const drillDownRow: {field: string; value: SqlValue}[] =
                           [];
                         for (let j = 0; j <= rowLevel; j++) {
-                          const col = pivot.groupBy[j];
+                          const col = pivot.groupBy[j]!;
                           drillDownRow.push({
                             field: col.field,
-                            value: row[col.id],
+                            value: row[col.id]!,
                           });
                         }
                         this.drillDown(drillDownRow, attrs);
@@ -2172,7 +2301,7 @@
                     showFilterControls && m(MenuDivider),
                   ],
                   showFilterControls &&
-                    m(CellFilterMenu, {
+                    m(CellFilterMenu!, {
                       value,
                       onFilterAdd: (filter) =>
                         this.addFilter({field, ...filter}, attrs),
@@ -2200,8 +2329,8 @@
                 // Build a row with only the groupBy columns up to rowLevel
                 const drillDownRow: {field: string; value: SqlValue}[] = [];
                 for (let j = 0; j <= rowLevel; j++) {
-                  const col = pivot.groupBy[j];
-                  drillDownRow.push({field: col.field, value: row[col.id]});
+                  const col = pivot.groupBy[j]!;
+                  drillDownRow.push({field: col.field, value: row[col.id]!});
                 }
                 this.drillDown(drillDownRow, attrs);
               },
@@ -2214,7 +2343,7 @@
         // Render aggregate columns
         for (const agg of aggregates) {
           const alias = getAggregateAlias(agg);
-          const value = row[alias];
+          const value = row[alias]!;
 
           // For aggregates with a field, we can use the field's cell renderer
           let cellRenderer =
@@ -2305,10 +2434,10 @@
 
       // Map aliases to field paths for column name lookup
       for (let i = 0; i < columns.length; i++) {
-        const alias = columns[i];
-        const field = fieldPaths[i];
+        const alias = columns[i]!;
+        const field = fieldPaths[i]!;
         if (alias !== field) {
-          columnNames[alias] = columnNames[field];
+          columnNames[alias] = columnNames[field]!;
         }
       }
     }
@@ -2471,3 +2600,14 @@
 function getColumnAlias(col: Column): string {
   return col.id;
 }
+
+/**
+ * Builds the data source quick filter for the given text and fields, or
+ * undefined if there's no filter text.
+ */
+function buildQuickFilter(
+  text: string,
+  fields: readonly string[],
+): QuickFilter | undefined {
+  return text === '' ? undefined : {text, fields};
+}
diff --git a/ui/src/components/widgets/datagrid/datagrid_jsdomtest.ts b/ui/src/components/widgets/datagrid/datagrid_jsdomtest.ts
index ba71cf1..d37bc9f 100644
--- a/ui/src/components/widgets/datagrid/datagrid_jsdomtest.ts
+++ b/ui/src/components/widgets/datagrid/datagrid_jsdomtest.ts
@@ -13,9 +13,9 @@
 // limitations under the License.
 
 import m from 'mithril';
-import {afterEach, beforeEach, describe, expect, test} from 'vitest';
+import {afterEach, beforeEach, describe, expect, test, vi} from 'vitest';
 import {prettyDOM, queryAllByRole} from '@testing-library/dom';
-import {DataGrid, type DataGridAttrs} from './datagrid';
+import {DataGrid, type DataGridApi, type DataGridAttrs} from './datagrid';
 import {InMemoryDataSource} from './in_memory_data_source';
 import type {ColumnSchema} from './datagrid_schema';
 import type {Column, Filter} from './model';
@@ -102,7 +102,7 @@
 function getMenuItems(rerender: () => void, triggerLabel: string): string[] {
   const menuButton = queryAllByRole(container, 'button', {
     name: triggerLabel,
-  })[0];
+  })[0]!;
   expect(menuButton, dumpDom()).toBeTruthy();
   menuButton.dispatchEvent(new window.MouseEvent('click', {bubbles: true}));
   rerender();
@@ -288,3 +288,154 @@
     expect(items, dumpDom()).not.toContain('Group by this column');
   });
 });
+
+describe('DataGrid quick filter', () => {
+  const QUICK_FILTER_DATA = [
+    {name: 'apple', value: 10},
+    {name: 'banana', value: 20},
+    {name: 'cherry', value: 31},
+  ];
+
+  beforeEach(() => {
+    vi.useFakeTimers();
+  });
+
+  afterEach(() => {
+    vi.useRealTimers();
+  });
+
+  // Renders a grid over QUICK_FILTER_DATA with the quick filter enabled,
+  // capturing the latest DataGrid API.
+  function renderQuickFilterGrid(attrs: Partial<DataGridAttrs>) {
+    let api: DataGridApi | undefined;
+    const rerender = renderDataGrid({
+      data: new InMemoryDataSource(QUICK_FILTER_DATA),
+      onReady: (a) => (api = a),
+      enableQuickFilter: true,
+      ...attrs,
+    });
+    return {rerender, getApi: () => api!};
+  }
+
+  // The quick filter sent to the data source (only flat models have one).
+  function getModelQuickFilter(api: DataGridApi) {
+    const model = api.getModel();
+    return model.mode === 'flat' ? model.quickFilter : undefined;
+  }
+
+  function getQuickFilterBox(): HTMLInputElement | null {
+    return container.querySelector<HTMLInputElement>(
+      'input[placeholder="Filter rows\u2026"]',
+    );
+  }
+
+  function typeInQuickFilterBox(text: string) {
+    const input = getQuickFilterBox();
+    expect(input, dumpDom()).toBeTruthy();
+    input!.value = text;
+    input!.dispatchEvent(new window.Event('input', {bubbles: true}));
+  }
+
+  test('quick filter box is shown when enabled', () => {
+    renderQuickFilterGrid({});
+    expect(getQuickFilterBox(), dumpDom()).toBeTruthy();
+  });
+
+  test('typing filters rows after the debounce', () => {
+    const onQuickFilterChanged = vi.fn();
+    const {rerender, getApi} = renderQuickFilterGrid({onQuickFilterChanged});
+    expect(getApi().getRowCount()).toBe(3);
+
+    typeInQuickFilterBox('AN');
+    rerender();
+    // Not applied until the user stops typing.
+    expect(getApi().getRowCount()).toBe(3);
+    expect(onQuickFilterChanged).not.toHaveBeenCalled();
+
+    vi.advanceTimersByTime(250);
+    rerender();
+    // Only 'banana' contains 'an' (case-insensitive).
+    expect(getApi().getRowCount()).toBe(1);
+    expect(getModelQuickFilter(getApi())).toEqual({
+      text: 'AN',
+      fields: ['name', 'value'],
+    });
+    expect(onQuickFilterChanged).toHaveBeenCalledWith('AN');
+  });
+
+  test('matches numbers by their raw value', () => {
+    const {getApi} = renderQuickFilterGrid({initialQuickFilter: '1'});
+    // 10 and 31.
+    expect(getApi().getRowCount()).toBe(2);
+  });
+
+  test('no matches shows the empty state, and "Clear filters" clears it', () => {
+    const onQuickFilterChanged = vi.fn();
+    const {rerender, getApi} = renderQuickFilterGrid({
+      initialQuickFilter: 'zzz',
+      onQuickFilterChanged,
+    });
+    expect(getApi().getRowCount()).toBe(0);
+    expect(container.textContent, dumpDom()).toContain(
+      'No results match your filters',
+    );
+
+    // The empty state isn't exposed to the accessibility tree under jsdom, so
+    // find the button by its label instead of by role.
+    const clear = Array.from(container.querySelectorAll('button')).find(
+      (button) => button.textContent?.includes('Clear filters'),
+    );
+    expect(clear, dumpDom()).toBeTruthy();
+    clear!.dispatchEvent(new window.MouseEvent('click', {bubbles: true}));
+    rerender();
+    expect(getApi().getRowCount()).toBe(3);
+    expect(getQuickFilterBox()?.value).toBe('');
+    expect(onQuickFilterChanged).toHaveBeenCalledWith('');
+  });
+
+  test('quick filter box is hidden in pivot mode', () => {
+    const {getApi} = renderQuickFilterGrid({
+      initialQuickFilter: 'x',
+      initialPivot: {
+        groupBy: [{id: 'g', field: 'name'}],
+        aggregates: [{id: 'c', function: 'COUNT'}],
+      },
+    });
+    expect(getQuickFilterBox(), dumpDom()).toBeNull();
+    expect(getApi().getModel().mode).toBe('pivot');
+  });
+
+  test('quick filter box is shown when drilling down into a pivot group', () => {
+    const {getApi} = renderQuickFilterGrid({
+      initialColumns: COLUMNS,
+      initialQuickFilter: 'an',
+      initialPivot: {
+        groupBy: [{id: 'g', field: 'name'}],
+        aggregates: [{id: 'c', function: 'COUNT'}],
+        drillDown: [{field: 'name', value: 'banana'}],
+      },
+    });
+    expect(getQuickFilterBox(), dumpDom()).toBeTruthy();
+    expect(getModelQuickFilter(getApi())).toEqual({
+      text: 'an',
+      fields: ['name', 'value'],
+    });
+    expect(getApi().getRowCount()).toBe(1);
+  });
+
+  test('quick filter is off by default: no box, and its text is ignored', () => {
+    const {getApi} = renderQuickFilterGrid({
+      enableQuickFilter: undefined,
+      initialQuickFilter: 'zzz',
+    });
+    expect(getQuickFilterBox(), dumpDom()).toBeNull();
+    expect(getApi().getRowCount()).toBe(3);
+  });
+
+  test('quick filter box is hidden in tree mode', () => {
+    renderQuickFilterGrid({
+      initialTree: {idField: 'value', parentIdField: 'value'},
+    });
+    expect(getQuickFilterBox(), dumpDom()).toBeNull();
+  });
+});
diff --git a/ui/src/components/widgets/datagrid/datagrid_schema.ts b/ui/src/components/widgets/datagrid/datagrid_schema.ts
index 4f56153..ac0aaba 100644
--- a/ui/src/components/widgets/datagrid/datagrid_schema.ts
+++ b/ui/src/components/widgets/datagrid/datagrid_schema.ts
@@ -236,7 +236,7 @@
   let currentSchema = schema;
 
   for (let i = 0; i < parts.length; i++) {
-    const part = parts[i];
+    const part = parts[i]!;
     const entry = maybeUndefined(currentSchema[part]);
 
     if (!entry) {
diff --git a/ui/src/components/widgets/datagrid/export_utils.ts b/ui/src/components/widgets/datagrid/export_utils.ts
index f0abcb2..e16f976 100644
--- a/ui/src/components/widgets/datagrid/export_utils.ts
+++ b/ui/src/components/widgets/datagrid/export_utils.ts
@@ -60,7 +60,7 @@
   return rows.map((row) => {
     const formattedRow: Record<string, string> = {};
     for (const colAlias of columns) {
-      const value = row[colAlias];
+      const value = row[colAlias]!;
       // Use field path for schema lookup if provided, otherwise use alias
       const fieldPath = aliasToField?.[colAlias] ?? colAlias;
       const formatter = schema
diff --git a/ui/src/components/widgets/datagrid/in_memory_data_source.ts b/ui/src/components/widgets/datagrid/in_memory_data_source.ts
index fe9bb62..4861286 100644
--- a/ui/src/components/widgets/datagrid/in_memory_data_source.ts
+++ b/ui/src/components/widgets/datagrid/in_memory_data_source.ts
@@ -14,7 +14,7 @@
 
 import type {AsyncMemoResult} from '../../../base/async_memo';
 import {stringifyJsonWithBigints} from '../../../base/json_utils';
-import {assertUnreachable} from '../../../base/assert';
+import {assertUnreachable, ensureDefined} from '../../../base/assert';
 import type {Row, SqlValue} from '../../../trace_processor/query_result';
 import type {
   DataSource,
@@ -22,8 +22,12 @@
   DataSourceRows,
   FlatModel,
 } from './data_source';
-import type {Filter} from './model';
+import type {AggregateFunction, Filter, QuickFilter} from './model';
 import {splitPath} from './datagrid_schema';
+import {
+  isQuickFilterActive,
+  valueMatchesQuickFilter,
+} from './quick_filter_utils';
 
 // Column shape from FlatModel
 type FlatColumn = FlatModel['columns'][number];
@@ -33,11 +37,13 @@
   private filteredSortedData: ReadonlyArray<Row> = [];
   private distinctValuesCache = new Map<string, ReadonlyArray<SqlValue>>();
   private parameterKeysCache = new Map<string, ReadonlyArray<string>>();
-  private aggregateSummariesCache: Row = {};
+  private aggregateSummariesCache?: Row;
+  private aggregateSummariesKey?: string;
 
   // Cached state for diffing
   private oldColumns?: readonly FlatColumn[];
   private oldFilters: ReadonlyArray<Filter> = [];
+  private oldQuickFilter?: QuickFilter;
   private oldSort?: FlatModel['sort'];
 
   constructor(data: ReadonlyArray<Row>) {
@@ -65,21 +71,27 @@
       };
     });
     const filters = model.filters ?? [];
+    const quickFilter = isQuickFilterActive(model.quickFilter)
+      ? model.quickFilter
+      : undefined;
     const sort = model.sort;
 
     if (
       !this.areColumnsEqual(columns, this.oldColumns) ||
       !this.areFiltersEqual(filters, this.oldFilters) ||
+      !this.isQuickFilterEqual(quickFilter, this.oldQuickFilter) ||
       !this.isSortEqual(sort, this.oldSort)
     ) {
       this.oldColumns = columns;
       this.oldFilters = filters;
+      this.oldQuickFilter = quickFilter;
       this.oldSort = sort;
 
       // Clear aggregate summaries cache
-      this.aggregateSummariesCache = {};
+      this.aggregateSummariesCache = undefined;
 
       let result = this.applyFilters(this.data, filters);
+      result = this.applyQuickFilter(result, quickFilter);
 
       // Project columns to use aliases as keys (for consistency with SQL data source)
       result = this.projectColumns(result, columns);
@@ -115,7 +127,7 @@
       // Compute distinct values from base data (not filtered)
       const uniqueValues = new Set<SqlValue>();
       for (const row of this.data) {
-        uniqueValues.add(row[column]);
+        uniqueValues.add(row[column]!);
       }
 
       // Sort with null-aware comparison
@@ -192,12 +204,36 @@
   /**
    * Fetch aggregate summaries (aggregates across all filtered rows).
    */
-  useAggregateSummaries(_model: DataSourceModel): AsyncMemoResult<Row> {
-    // Aggregates are computed in useRows, just return the cache
-    const data = this.aggregateSummariesCache;
+  useAggregateSummaries(model: DataSourceModel): AsyncMemoResult<Row> {
+    // Only support flat mode
+    if (model.mode !== 'flat') {
+      return {data: {}, isPending: false};
+    }
+
+    // Columns are projected by alias in useRows, so aggregate over
+    // filteredSortedData using each column's alias. The cache is invalidated
+    // by useRows whenever columns/filters/sort change, and here whenever the
+    // set of aggregate functions changes.
+    const aggColumns = model.columns.filter((c) => c.aggregate !== undefined);
+    const key = aggColumns.map((c) => `${c.alias}:${c.aggregate}`).join(',');
+
+    if (
+      this.aggregateSummariesCache === undefined ||
+      this.aggregateSummariesKey !== key
+    ) {
+      const summaries: Row = {};
+      for (const col of aggColumns) {
+        const values = this.filteredSortedData
+          .map((row) => row[col.alias])
+          .filter((v) => v !== undefined);
+        summaries[col.alias] = computeAggregate(col.aggregate!, values);
+      }
+      this.aggregateSummariesCache = summaries;
+      this.aggregateSummariesKey = key;
+    }
 
     return {
-      data,
+      data: this.aggregateSummariesCache,
       isPending: false,
     };
   }
@@ -222,12 +258,25 @@
     if (a.length !== b.length) return false;
 
     return a.every((colA, i) => {
-      const colB = b[i];
+      const colB = b[i]!;
       return colA.alias === colB.alias && colA.field === colB.field;
     });
   }
 
   /**
+   * Compare quick filters for equality.
+   */
+  private isQuickFilterEqual(a?: QuickFilter, b?: QuickFilter): boolean {
+    if (a === b) return true;
+    if (!a || !b) return false;
+    return (
+      a.text === b.text &&
+      a.fields.length === b.fields.length &&
+      a.fields.every((field, i) => field === b.fields[i])
+    );
+  }
+
+  /**
    * Compare sort configurations for equality.
    */
   private isSortEqual(a: FlatModel['sort'], b: FlatModel['sort']): boolean {
@@ -248,7 +297,7 @@
       const projectedRow: Row = {};
       for (const col of columns) {
         // Map field value to alias key
-        projectedRow[col.alias] = row[col.field];
+        projectedRow[col.alias] = row[col.field]!;
       }
       return projectedRow;
     });
@@ -281,7 +330,7 @@
     return data.filter((row) => {
       // Check if row passes all filters
       return filters.every((filter) => {
-        const value = row[filter.field];
+        const value = row[filter.field]!;
 
         switch (filter.op) {
           case '=':
@@ -333,6 +382,26 @@
     });
   }
 
+  // Keep only rows where at least one of the quick filter fields matches.
+  private applyQuickFilter(
+    data: ReadonlyArray<Row>,
+    quickFilter: QuickFilter | undefined,
+  ): ReadonlyArray<Row> {
+    if (quickFilter === undefined) {
+      return data;
+    }
+    // Index rows the same way as columns (see useRows). Missing fields are
+    // treated as null so they never match.
+    const fields = quickFilter.fields.map((field) =>
+      splitPath(field).join('.'),
+    );
+    return data.filter((row) =>
+      fields.some((field) =>
+        valueMatchesQuickFilter(row[field] ?? null, quickFilter.text),
+      ),
+    );
+  }
+
   private applySorting(
     data: ReadonlyArray<Row>,
     sortColumn: string,
@@ -433,3 +502,104 @@
     return Number(a) - Number(b);
   }
 }
+
+/**
+ * Compute an aggregate over a list of values, mirroring the semantics of the
+ * equivalent SQL used by SQLDataSource (see sql_utils.ts). NULLs are ignored,
+ * and aggregates over no (non-NULL) values return NULL (or 0 for
+ * COUNT_DISTINCT).
+ */
+function computeAggregate(
+  func: AggregateFunction,
+  values: ReadonlyArray<SqlValue>,
+): SqlValue {
+  const nonNull = values.filter((v) => v !== null);
+  switch (func) {
+    case 'ANY':
+    case 'MIN':
+      return extremum(nonNull, (cmp) => cmp < 0);
+    case 'MAX':
+      return extremum(nonNull, (cmp) => cmp > 0);
+    case 'SUM':
+      return sumNumeric(nonNull.filter(isNumeric));
+    case 'AVG': {
+      const numeric = nonNull.filter(isNumeric);
+      if (numeric.length === 0) return null;
+      return Number(sumNumeric(numeric)) / numeric.length;
+    }
+    case 'COUNT_DISTINCT':
+      return new Set(nonNull.map(distinctKey)).size;
+    case 'P25':
+    case 'P50':
+    case 'P75':
+    case 'P90':
+    case 'P95':
+    case 'P99':
+      const p = Number(func.slice(1)); // Strip the 'P'
+      return percentile(nonNull.filter(isNumeric).map(Number), p);
+    default:
+      assertUnreachable(func);
+  }
+}
+
+function sumNumeric(values: ReadonlyArray<number | bigint>): SqlValue {
+  if (values.length === 0) return null;
+  // Keep bigint precision if every value is a bigint.
+  if (values.every((v) => typeof v === 'bigint')) {
+    return (values as bigint[]).reduce((a, b) => a + b, 0n);
+  }
+  return values.reduce<number>((a, b) => a + Number(b), 0);
+}
+
+function extremum(
+  values: ReadonlyArray<SqlValue>,
+  better: (cmp: number) => boolean,
+): SqlValue {
+  if (values.length === 0) return null;
+  return values.reduce((result, value) =>
+    better(compareForAggregate(value, result)) ? value : result,
+  );
+}
+
+// Order non-NULL values like sqlite: numbers < strings < blobs.
+function compareForAggregate(a: SqlValue, b: SqlValue): number {
+  const rank = (v: SqlValue) =>
+    isNumeric(v) ? 0 : typeof v === 'string' ? 1 : 2;
+  const rankDiff = rank(a) - rank(b);
+  if (rankDiff !== 0) return rankDiff;
+  if (isNumeric(a)) return compareNumeric(a, b);
+  if (typeof a === 'string' && typeof b === 'string') {
+    return a < b ? -1 : a > b ? 1 : 0;
+  }
+  if (a instanceof Uint8Array && b instanceof Uint8Array) {
+    const len = Math.min(a.length, b.length);
+    for (let i = 0; i < len; i++) {
+      // len is min(a.length, b.length) so accessing a[i] and b[i] is safe - use
+      // non-null assertion instead of ensureDefined for performance.
+      const ax = a[i]!;
+      const bx = b[i]!;
+      if (ax !== bx) return ax - bx;
+    }
+    return a.length - b.length;
+  }
+  return 0;
+}
+
+function distinctKey(value: SqlValue): string {
+  if (isNumeric(value)) return `n:${value}`;
+  if (typeof value === 'string') return `s:${value}`;
+  if (value instanceof Uint8Array) return `b:${value.join(',')}`;
+  return 'null';
+}
+
+// Linear interpolation between closest ranks, matching sqlite's percentile().
+function percentile(values: number[], p: number): SqlValue {
+  if (values.length === 0) return null;
+  const sorted = [...values].sort((a, b) => a - b);
+  const ix = ((sorted.length - 1) * p) / 100;
+  // sorted is non-empty and 0 <= p <= 100, so 0 <= ix <= length - 1 and both
+  // floor(ix) and ceil(ix) are in bounds.
+  const lo = ensureDefined(sorted[Math.floor(ix)]);
+  const hi = ensureDefined(sorted[Math.ceil(ix)]);
+  return lo + (hi - lo) * (ix - Math.floor(ix));
+}
diff --git a/ui/src/components/widgets/datagrid/in_memory_data_source_unittest.ts b/ui/src/components/widgets/datagrid/in_memory_data_source_unittest.ts
index c02ff84..aa7cce1 100644
--- a/ui/src/components/widgets/datagrid/in_memory_data_source_unittest.ts
+++ b/ui/src/components/widgets/datagrid/in_memory_data_source_unittest.ts
@@ -15,7 +15,7 @@
 import type {Row} from '../../../trace_processor/query_result';
 import type {FlatModel} from './data_source';
 import {InMemoryDataSource} from './in_memory_data_source';
-import type {Filter} from './model';
+import type {Filter, QuickFilter} from './model';
 
 describe('InMemoryDataSource', () => {
   const sampleData: ReadonlyArray<Row> = [
@@ -97,12 +97,14 @@
   function makeModel(options?: {
     columns?: FlatModel['columns'];
     filters?: readonly Filter[];
+    quickFilter?: QuickFilter;
     sort?: FlatModel['sort'];
   }): FlatModel {
     return {
       mode: 'flat',
       columns: options?.columns ?? defaultColumns,
       filters: options?.filters,
+      quickFilter: options?.quickFilter,
       sort: options?.sort,
     };
   }
@@ -125,7 +127,7 @@
       const filters: Filter[] = [{field: 'name', op: '=', value: 'Alice'}];
       const result = dataSource.useRows(makeModel({filters}));
       expect(result.totalRows).toBe(1);
-      expect(result.rows?.[0].name).toBe('Alice');
+      expect(result.rows?.[0]!.name).toBe('Alice');
     });
 
     test('inequality filter', () => {
@@ -169,7 +171,7 @@
       const filters: Filter[] = [{field: 'value', op: 'is null'}];
       const result = dataSource.useRows(makeModel({filters}));
       expect(result.totalRows).toBe(1);
-      expect(result.rows?.[0].id).toBe(4); // David
+      expect(result.rows?.[0]!.id).toBe(4); // David
     });
 
     test('is not null filter', () => {
@@ -183,14 +185,14 @@
       const filters: Filter[] = [{field: 'name', op: 'glob', value: 'A*e'}];
       const result = dataSource.useRows(makeModel({filters}));
       expect(result.totalRows).toBe(1);
-      expect(result.rows?.[0].name).toBe('Alice');
+      expect(result.rows?.[0]!.name).toBe('Alice');
     });
 
     test('glob filter with ?', () => {
       const filters: Filter[] = [{field: 'name', op: 'glob', value: 'B?b'}];
       const result = dataSource.useRows(makeModel({filters}));
       expect(result.totalRows).toBe(1);
-      expect(result.rows?.[0].name).toBe('Bob');
+      expect(result.rows?.[0]!.name).toBe('Bob');
     });
 
     test('multiple filters', () => {
@@ -216,6 +218,55 @@
     });
   });
 
+  describe('quick filter', () => {
+    const ids = (model: FlatModel) =>
+      dataSource.useRows(model).rows?.map((r) => r.id);
+
+    test('keeps rows where any field matches, ignoring case', () => {
+      const quickFilter = {text: 'AL', fields: ['name', 'tag']};
+      // Alice (name), Mallory (name).
+      expect(ids(makeModel({quickFilter}))).toEqual([1, 6]);
+    });
+
+    test('only looks in the given fields', () => {
+      const quickFilter = {text: 'a', fields: ['tag']};
+      expect(ids(makeModel({quickFilter}))).toEqual([1, 3, 7]);
+    });
+
+    test('never matches a field that is missing from the row', () => {
+      // A missing value must not be treated as the text "undefined".
+      const quickFilter = {text: 'undefined', fields: ['missing']};
+      expect(ids(makeModel({quickFilter}))).toEqual([]);
+    });
+
+    test('can look in a field with a dot in the name', () => {
+      // 'foo..bar' is the escaped path for the 'foo.bar' key.
+      const quickFilter = {text: 'value 3', fields: ['foo..bar']};
+      // Charlie, Mallory.
+      expect(ids(makeModel({quickFilter}))).toEqual([3, 6]);
+    });
+
+    test('empty text keeps all rows', () => {
+      const quickFilter = {text: '', fields: ['name']};
+      expect(dataSource.useRows(makeModel({quickFilter})).totalRows).toBe(
+        sampleData.length,
+      );
+    });
+
+    test('is combined with filters using AND', () => {
+      const filters: Filter[] = [{field: 'active', op: '=', value: 1}];
+      const quickFilter = {text: 'e', fields: ['name']};
+      // Alice, Charlie, Eve, Trent have an 'e' and are active.
+      expect(ids(makeModel({filters, quickFilter}))).toEqual([1, 3, 5, 7]);
+    });
+
+    test('changing the quick filter text recomputes rows', () => {
+      const fields = ['name'];
+      expect(ids(makeModel({quickFilter: {text: 'bob', fields}}))).toEqual([2]);
+      expect(ids(makeModel({quickFilter: {text: 'eve', fields}}))).toEqual([5]);
+    });
+  });
+
   describe('sorting', () => {
     test('sort by string ascending', () => {
       const result = dataSource.useRows(
@@ -312,6 +363,126 @@
     });
   });
 
+  describe('aggregate summaries', () => {
+    function summarize(model: FlatModel) {
+      dataSource.useRows(model);
+      const result = dataSource.useAggregateSummaries(model);
+      expect(result.isPending).toBe(false);
+      return result.data;
+    }
+
+    test('returns an empty row when no columns have aggregates', () => {
+      expect(summarize(makeModel())).toEqual({});
+    });
+
+    test('computes aggregates over numeric values, ignoring nulls', () => {
+      // Values: 100, 200, 150, null, 100, 300n, 250n
+      const summaries = summarize(
+        makeModel({
+          columns: [
+            {field: 'value', alias: 'sum', aggregate: 'SUM'},
+            {field: 'value', alias: 'avg', aggregate: 'AVG'},
+            {field: 'value', alias: 'min', aggregate: 'MIN'},
+            {field: 'value', alias: 'max', aggregate: 'MAX'},
+            {field: 'value', alias: 'distinct', aggregate: 'COUNT_DISTINCT'},
+            {field: 'value', alias: 'p25', aggregate: 'P25'},
+            {field: 'value', alias: 'p50', aggregate: 'P50'},
+          ],
+        }),
+      );
+      expect(summaries).toEqual({
+        sum: 1100,
+        avg: 1100 / 6,
+        min: 100,
+        max: 300n,
+        distinct: 5,
+        p25: 112.5,
+        p50: 175,
+      });
+    });
+
+    test('computes aggregates over string values', () => {
+      const summaries = summarize(
+        makeModel({
+          columns: [
+            {field: 'name', alias: 'any', aggregate: 'ANY'},
+            {field: 'name', alias: 'min', aggregate: 'MIN'},
+            {field: 'name', alias: 'max', aggregate: 'MAX'},
+            {field: 'tag', alias: 'distinct', aggregate: 'COUNT_DISTINCT'},
+          ],
+        }),
+      );
+      expect(summaries).toEqual({
+        any: 'Alice',
+        min: 'Alice',
+        max: 'Trent',
+        distinct: 3,
+      });
+    });
+
+    test('keeps bigint precision when summing only bigints', () => {
+      // Tag C: David (null), Mallory (300n)
+      const summaries = summarize(
+        makeModel({
+          columns: [{field: 'value', alias: 'sum', aggregate: 'SUM'}],
+          filters: [{field: 'tag', op: '=', value: 'C'}],
+        }),
+      );
+      expect(summaries).toEqual({sum: 300n});
+    });
+
+    test('returns null (or 0 for COUNT_DISTINCT) when all values are null', () => {
+      const summaries = summarize(
+        makeModel({
+          columns: [
+            {field: 'value', alias: 'sum', aggregate: 'SUM'},
+            {field: 'value', alias: 'avg', aggregate: 'AVG'},
+            {field: 'value', alias: 'max', aggregate: 'MAX'},
+            {field: 'value', alias: 'p50', aggregate: 'P50'},
+            {field: 'value', alias: 'distinct', aggregate: 'COUNT_DISTINCT'},
+          ],
+          filters: [{field: 'name', op: '=', value: 'David'}],
+        }),
+      );
+      expect(summaries).toEqual({
+        sum: null,
+        avg: null,
+        max: null,
+        p50: null,
+        distinct: 0,
+      });
+    });
+
+    test('aggregates only over filtered rows', () => {
+      const columns: FlatModel['columns'] = [
+        {field: 'value', alias: 'sum', aggregate: 'SUM'},
+      ];
+      expect(summarize(makeModel({columns}))).toEqual({sum: 1100});
+
+      // Active: Alice (100), Charlie (150), Eve (100), Trent (250n)
+      const filters: Filter[] = [{field: 'active', op: '=', value: 1}];
+      expect(summarize(makeModel({columns, filters}))).toEqual({sum: 600});
+    });
+
+    test('recomputes when the aggregate function changes', () => {
+      expect(
+        summarize(
+          makeModel({
+            columns: [{field: 'value', alias: 'value', aggregate: 'SUM'}],
+          }),
+        ),
+      ).toEqual({value: 1100});
+
+      expect(
+        summarize(
+          makeModel({
+            columns: [{field: 'value', alias: 'value', aggregate: 'MIN'}],
+          }),
+        ),
+      ).toEqual({value: 100});
+    });
+  });
+
   describe('caching behavior', () => {
     test('data is not reprocessed if columns and filters are identical', () => {
       const filters: Filter[] = [{field: 'tag', op: '=', value: 'A'}];
@@ -367,11 +538,11 @@
 
       const result1 = dataSource.useRows(makeModel({filters: filters1}));
       expect(result1.rows?.length).toBe(1);
-      expect(result1.rows?.[0].id).toBe(1);
+      expect(result1.rows?.[0]!.id).toBe(1);
 
       const result2 = dataSource.useRows(makeModel({filters: filters2}));
       expect(result2.rows?.length).toBe(1);
-      expect(result2.rows?.[0].id).toBe(2);
+      expect(result2.rows?.[0]!.id).toBe(2);
 
       expect(result1.rows).not.toBe(result2.rows);
     });
diff --git a/ui/src/components/widgets/datagrid/model.ts b/ui/src/components/widgets/datagrid/model.ts
index 6ac5b44..7eea9b0 100644
--- a/ui/src/components/widgets/datagrid/model.ts
+++ b/ui/src/components/widgets/datagrid/model.ts
@@ -58,6 +58,16 @@
 
 export type FilterOpAndValue = OpFilter | InFilter | NullFilter;
 
+// A whole-table text filter. Keeps rows where at least one of `fields`
+// contains `text` (see valueMatchesQuickFilter() for the exact rules).
+//
+// Unlike column filters (Filter), which each target one column and are
+// combined with AND, a quick filter matches if ANY of its fields matches.
+export interface QuickFilter {
+  readonly text: string;
+  readonly fields: readonly string[];
+}
+
 interface AggregateField extends ColumnBase {
   readonly function: AggregateFunction;
   readonly field: string;
diff --git a/ui/src/components/widgets/datagrid/quick_filter_utils.ts b/ui/src/components/widgets/datagrid/quick_filter_utils.ts
new file mode 100644
index 0000000..96532a3
--- /dev/null
+++ b/ui/src/components/widgets/datagrid/quick_filter_utils.ts
@@ -0,0 +1,53 @@
+// Copyright (C) 2026 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 type {SqlValue} from '../../../trace_processor/query_result';
+import type {QuickFilter} from './model';
+
+/**
+ * Returns true if the quick filter should be applied, i.e. it has non-empty text.
+ */
+export function isQuickFilterActive(
+  quickFilter: QuickFilter | undefined,
+): quickFilter is QuickFilter {
+  return quickFilter !== undefined && quickFilter.text !== '';
+}
+
+/**
+ * Returns true if `value` matches the quick filter `text`.
+ *
+ * The rules are:
+ * 1. The value, converted to text, contains the filter text.
+ * 2. Upper/lowercase is ignored for A-Z only.
+ * 3. Nulls and blobs never match.
+ * An empty filter text matches nothing.
+ *
+ * Keep in sync with quickFilterToSql() in sql_utils.ts, which implements the
+ * same rules in SQL.
+ */
+export function valueMatchesQuickFilter(
+  value: SqlValue,
+  text: string,
+): boolean {
+  if (text === '' || value === null || value instanceof Uint8Array) {
+    return false;
+  }
+  return asciiLowerCase(String(value)).includes(asciiLowerCase(text));
+}
+
+// Lowercases A-Z only, to match the SQL side (which only expands A-Z into
+// case-insensitive glob character classes).
+function asciiLowerCase(s: string): string {
+  return s.replace(/[A-Z]/g, (c) => c.toLowerCase());
+}
diff --git a/ui/src/components/widgets/datagrid/quick_filter_utils_unittest.ts b/ui/src/components/widgets/datagrid/quick_filter_utils_unittest.ts
new file mode 100644
index 0000000..c2c8c47
--- /dev/null
+++ b/ui/src/components/widgets/datagrid/quick_filter_utils_unittest.ts
@@ -0,0 +1,71 @@
+// Copyright (C) 2026 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 {
+  isQuickFilterActive,
+  valueMatchesQuickFilter,
+} from './quick_filter_utils';
+
+describe('valueMatchesQuickFilter', () => {
+  test('substring match', () => {
+    expect(valueMatchesQuickFilter('foobar', 'oba')).toBe(true);
+    expect(valueMatchesQuickFilter('foobar', 'baz')).toBe(false);
+  });
+
+  test('ignores A-Z case', () => {
+    expect(valueMatchesQuickFilter('FooBar', 'foob')).toBe(true);
+    expect(valueMatchesQuickFilter('foobar', 'FOOB')).toBe(true);
+  });
+
+  test('does not ignore case for non-ASCII letters', () => {
+    expect(valueMatchesQuickFilter('é', 'é')).toBe(true);
+    expect(valueMatchesQuickFilter('É', 'é')).toBe(false);
+  });
+
+  test('numbers and bigints match their text form', () => {
+    expect(valueMatchesQuickFilter(1258291, '1258')).toBe(true);
+    expect(valueMatchesQuickFilter(1.5, '1.5')).toBe(true);
+    expect(valueMatchesQuickFilter(123456789012345678n, '9012')).toBe(true);
+    expect(valueMatchesQuickFilter(42, '43')).toBe(false);
+  });
+
+  test('null and blobs never match', () => {
+    expect(valueMatchesQuickFilter(null, 'null')).toBe(false);
+    expect(valueMatchesQuickFilter(new Uint8Array([49]), '1')).toBe(false);
+  });
+
+  test('empty text matches nothing', () => {
+    expect(valueMatchesQuickFilter('foo', '')).toBe(false);
+  });
+
+  test('special characters are matched literally', () => {
+    expect(valueMatchesQuickFilter('a*b', '*')).toBe(true);
+    expect(valueMatchesQuickFilter('ab', '*')).toBe(false);
+    expect(valueMatchesQuickFilter('a[b', '[')).toBe(true);
+    expect(valueMatchesQuickFilter("it's", "'")).toBe(true);
+    expect(valueMatchesQuickFilter('a?b', '?')).toBe(true);
+    expect(valueMatchesQuickFilter('ab', '?')).toBe(false);
+  });
+});
+
+describe('isQuickFilterActive', () => {
+  test('inactive when undefined or empty', () => {
+    expect(isQuickFilterActive(undefined)).toBe(false);
+    expect(isQuickFilterActive({text: '', fields: ['a']})).toBe(false);
+  });
+
+  test('active with text', () => {
+    expect(isQuickFilterActive({text: 'x', fields: []})).toBe(true);
+  });
+});
diff --git a/ui/src/components/widgets/datagrid/sql_data_source/flat.ts b/ui/src/components/widgets/datagrid/sql_data_source/flat.ts
index 9bc5dce..fbb7ca4 100644
--- a/ui/src/components/widgets/datagrid/sql_data_source/flat.ts
+++ b/ui/src/components/widgets/datagrid/sql_data_source/flat.ts
@@ -22,7 +22,9 @@
 import {runQueryForQueryTable} from '../../../query_table/queries';
 import type {DataSourceRows, FlatModel} from '../data_source';
 import {type SQLTableSchema, SQLSchemaResolver} from '../sql_schema';
-import {filterToSql, quoteIdentifier} from '../sql_utils';
+import type {Filter, QuickFilter} from '../model';
+import {isQuickFilterActive} from '../quick_filter_utils';
+import {filterToSql, quickFilterToSql, quoteIdentifier} from '../sql_utils';
 
 export class SQLDataSourceFlat {
   private readonly rowCountSlot: AsyncMemo<number>;
@@ -49,7 +51,7 @@
    * Returns aggregate summaries for columns that have an aggregate function defined.
    */
   getSummaries(model: FlatModel): AsyncMemoResult<Row> {
-    const {columns, filters = []} = model;
+    const {columns, filters = [], quickFilter} = model;
 
     // Find columns with aggregate functions
     const aggColumns = columns.filter((col) => col.aggregate !== undefined);
@@ -63,6 +65,7 @@
       key: {
         columns: aggColumns,
         filters: serializeFilters(filters),
+        quickFilter: serializeQuickFilter(quickFilter),
       },
       compute: async () => {
         const resolver = new SQLSchemaResolver(this.sqlSchema);
@@ -78,9 +81,14 @@
           );
         }
 
+        const whereConditions = buildWhereConditions(
+          resolver,
+          filters,
+          quickFilter,
+        );
         let sql = `SELECT ${selectExprs.join(', ')}`;
         sql = addFromClause(sql, resolver);
-        sql = addFilterClause(sql, resolver, filters);
+        sql = addWhereClause(sql, whereConditions);
 
         const result = await this.engine.query(sql);
         return result.firstRow({}) as Row;
@@ -89,7 +97,7 @@
   }
 
   getRows(model: FlatModel): DataSourceRows {
-    const {columns, filters = [], pagination, sort} = model;
+    const {columns, filters = [], quickFilter, pagination, sort} = model;
 
     // Load the row count first
     const rowCountResult = this.rowCountSlot.use({
@@ -97,12 +105,14 @@
         // The row count doesn't depend on pagination or sort
         columns,
         filters: serializeFilters(filters),
+        quickFilter: serializeQuickFilter(quickFilter),
       },
       compute: async () => {
         const query = buildQuery(this.sqlSchema, {
           mode: 'flat',
           columns,
           filters,
+          quickFilter,
         });
         const result = await this.engine.query(
           `SELECT COUNT(*) as count FROM (${query})`,
@@ -115,6 +125,7 @@
       key: {
         columns: model.columns,
         filters: serializeFilters(filters),
+        quickFilter: serializeQuickFilter(quickFilter),
         pagination,
         sort,
       },
@@ -173,15 +184,50 @@
   return filters?.map((filter) => filterToSql(filter, filter.field));
 }
 
+/**
+ * Returns a version of the quick filter suitable for use as a cache key.
+ * Inactive quick filters (empty text) all map to undefined, so they don't
+ * trigger refetches.
+ */
+function serializeQuickFilter(quickFilter: QuickFilter | undefined) {
+  return isQuickFilterActive(quickFilter) ? quickFilter : undefined;
+}
+
+/**
+ * Builds the WHERE conditions for the column filters and quick filter, to be
+ * joined with AND.
+ *
+ * This resolves every referenced column path, which can add joins to the
+ * resolver. Call it before `resolver.buildJoinClauses()`.
+ */
+function buildWhereConditions(
+  resolver: SQLSchemaResolver,
+  filters: readonly Filter[] = [],
+  quickFilter?: QuickFilter,
+): string[] {
+  const conditions = filters.map((filter) => {
+    const sqlExpr = resolver.resolveColumnPath(filter.field);
+    return filterToSql(filter, sqlExpr ?? filter.field);
+  });
+  if (isQuickFilterActive(quickFilter)) {
+    const sqlExprs = quickFilter.fields.map(
+      (field) => resolver.resolveColumnPath(field) ?? field,
+    );
+    conditions.push(quickFilterToSql(quickFilter.text, sqlExprs));
+  }
+  return conditions;
+}
+
 function buildQuery(
   sqlSchema: SQLTableSchema,
-  {columns, filters, pagination, sort}: FlatModel,
+  {columns, filters, quickFilter, pagination, sort}: FlatModel,
 ): string {
   const resolver = new SQLSchemaResolver(sqlSchema);
 
   let sql = buildSelectClause(resolver, columns);
+  const whereConditions = buildWhereConditions(resolver, filters, quickFilter);
   sql = addFromClause(sql, resolver);
-  sql = addFilterClause(sql, resolver, filters);
+  sql = addWhereClause(sql, whereConditions);
   sql = addOrderByClause(sql, sort);
   sql = addPaginationClause(sql, pagination);
 
@@ -221,16 +267,8 @@
   return sql;
 }
 
-function addFilterClause(
-  sql: string,
-  resolver: SQLSchemaResolver,
-  filters: FlatModel['filters'],
-): string {
-  if (filters && filters.length > 0) {
-    const whereConditions = filters.map((filter) => {
-      const sqlExpr = resolver.resolveColumnPath(filter.field);
-      return filterToSql(filter, sqlExpr ?? filter.field);
-    });
+function addWhereClause(sql: string, whereConditions: string[]): string {
+  if (whereConditions.length > 0) {
     sql += `\nWHERE ${whereConditions.join(' AND ')}`;
   }
   return sql;
diff --git a/ui/src/components/widgets/datagrid/sql_data_source/rollup_tree.ts b/ui/src/components/widgets/datagrid/sql_data_source/rollup_tree.ts
index 282caa5..17ee561 100644
--- a/ui/src/components/widgets/datagrid/sql_data_source/rollup_tree.ts
+++ b/ui/src/components/widgets/datagrid/sql_data_source/rollup_tree.ts
@@ -350,12 +350,12 @@
     const columnAliases: Record<string, string> = {};
     const aliasToColumn: Record<string, string> = {};
     for (let i = 0; i < groupBy.length; i++) {
-      columnAliases[`__group_${i}`] = quoteIdentifier(groupBy[i].alias);
-      aliasToColumn[groupBy[i].alias] = `__group_${i}`;
+      columnAliases[`__group_${i}`] = quoteIdentifier(groupBy[i]!.alias);
+      aliasToColumn[groupBy[i]!.alias] = `__group_${i}`;
     }
     for (let i = 0; i < aggregates.length; i++) {
-      columnAliases[`__agg_${i}`] = quoteIdentifier(aggregates[i].alias);
-      aliasToColumn[aggregates[i].alias] = `__agg_${i}`;
+      columnAliases[`__agg_${i}`] = quoteIdentifier(aggregates[i]!.alias);
+      aliasToColumn[aggregates[i]!.alias] = `__agg_${i}`;
     }
     return {columnAliases, aliasToColumn};
   }
@@ -820,7 +820,7 @@
   const groupColIndices = Object.keys(aliases)
     .map((key) => {
       const match = key.match(groupColPattern);
-      return match ? parseInt(match[1], 10) : -1;
+      return match ? parseInt(match[1]!, 10) : -1;
     })
     .filter((idx) => idx >= 0);
 
diff --git a/ui/src/components/widgets/datagrid/sql_schema.ts b/ui/src/components/widgets/datagrid/sql_schema.ts
index e601d54..4138b52 100644
--- a/ui/src/components/widgets/datagrid/sql_schema.ts
+++ b/ui/src/components/widgets/datagrid/sql_schema.ts
@@ -279,7 +279,7 @@
     }
 
     const [first, ...rest] = parts;
-    const colDef = maybeUndefined(schema.columns?.[first]);
+    const colDef = maybeUndefined(schema.columns?.[first!]);
 
     if (!colDef) {
       // Column not found in schema - treat as raw column name.
@@ -287,7 +287,7 @@
       // name (which may come from user/trace data rather than a trusted
       // schema definition) must be quoted as an identifier.
       if (rest.length === 0) {
-        return `${currentAlias}.${quoteIdentifier(first)}`;
+        return `${currentAlias}.${quoteIdentifier(first!)}`;
       }
       return undefined;
     }
@@ -402,7 +402,7 @@
     }
 
     const [first, ...rest] = parts;
-    const colDef = maybeUndefined(schema.columns?.[first]);
+    const colDef = maybeUndefined(schema.columns?.[first!]);
     if (!colDef) {
       return undefined;
     }
diff --git a/ui/src/components/widgets/datagrid/sql_utils.ts b/ui/src/components/widgets/datagrid/sql_utils.ts
index 5a19c53..d964075 100644
--- a/ui/src/components/widgets/datagrid/sql_utils.ts
+++ b/ui/src/components/widgets/datagrid/sql_utils.ts
@@ -14,6 +14,7 @@
 
 import {assertUnreachable} from '../../../base/assert';
 import type {SqlValue} from '../../../trace_processor/query_result';
+import {escapeSearchQuery} from '../../../trace_processor/query_utils';
 import type {AggregateFunction, Filter} from './model';
 
 /**
@@ -92,7 +93,7 @@
   if (pathsWithoutNulls.length > 0) {
     if (columns.length === 1) {
       // Single column: simple IN
-      const values = pathsWithoutNulls.map((p) => sqlValue(p[0])).join(', ');
+      const values = pathsWithoutNulls.map((p) => sqlValue(p[0]!)).join(', ');
       conditions.push(`${columns[0]} IN (${values})`);
     } else {
       // Multiple columns: tuple IN
@@ -112,7 +113,7 @@
   if (conditions.length === 0) {
     return 'FALSE';
   } else if (conditions.length === 1) {
-    return conditions[0];
+    return conditions[0]!;
   } else {
     return `(${conditions.join(' OR ')})`;
   }
@@ -136,7 +137,7 @@
   if (pathsWithoutNulls.length > 0) {
     if (columns.length === 1) {
       // Single column: simple NOT IN
-      const values = pathsWithoutNulls.map((p) => sqlValue(p[0])).join(', ');
+      const values = pathsWithoutNulls.map((p) => sqlValue(p[0]!)).join(', ');
       conditions.push(`${columns[0]} NOT IN (${values})`);
     } else {
       // Multiple columns: tuple NOT IN
@@ -156,7 +157,7 @@
   if (conditions.length === 0) {
     return 'TRUE';
   } else if (conditions.length === 1) {
-    return conditions[0];
+    return conditions[0]!;
   } else {
     return conditions.join(' AND ');
   }
@@ -192,6 +193,34 @@
 }
 
 /**
+ * Builds a SQL condition that is true if any of `sqlExprs` contains `text`.
+ * E.g., quickFilterToSql('fo', ['a', 'b']) returns:
+ * ((typeof(a) != 'blob' AND CAST(a AS TEXT) GLOB '*[fF][oO]*') OR (...b...))
+ *
+ * The rules are:
+ * 1. The value, converted to text, contains the filter text.
+ * 2. Upper/lowercase is ignored for A-Z only.
+ * 3. Nulls and blobs never match.
+ *
+ * Keep in sync with valueMatchesQuickFilter() in quick_filter_utils.ts, which
+ * implements the same rules in JS.
+ */
+export function quickFilterToSql(
+  text: string,
+  sqlExprs: readonly string[],
+): string {
+  if (sqlExprs.length === 0) {
+    return 'FALSE';
+  }
+  const pattern = escapeSearchQuery(text);
+  const conditions = sqlExprs.map(
+    (expr) =>
+      `(typeof(${expr}) != 'blob' AND CAST(${expr} AS TEXT) GLOB ${pattern})`,
+  );
+  return `(${conditions.join(' OR ')})`;
+}
+
+/**
  * Builds an aggregate expression string from function and field.
  * E.g., sqlAggregateExpr('SUM', 'dur') returns 'SUM(dur)'.
  */
diff --git a/ui/src/components/widgets/datagrid/sql_utils_unittest.ts b/ui/src/components/widgets/datagrid/sql_utils_unittest.ts
index bdf1d93..ba3f421 100644
--- a/ui/src/components/widgets/datagrid/sql_utils_unittest.ts
+++ b/ui/src/components/widgets/datagrid/sql_utils_unittest.ts
@@ -15,6 +15,7 @@
 import {
   filterToSql,
   quoteIdentifier,
+  quickFilterToSql,
   sqlAggregateExpr,
   sqlPathMatch,
   sqlPathNotMatch,
@@ -359,3 +360,40 @@
     ).toBe("col NOT IN ('a', 'b')");
   });
 });
+
+describe('quickFilterToSql', () => {
+  test('single column', () => {
+    expect(quickFilterToSql('fo', ['a'])).toBe(
+      "((typeof(a) != 'blob' AND CAST(a AS TEXT) GLOB '*[fF][oO]*'))",
+    );
+  });
+
+  test('multiple columns are OR-ed', () => {
+    expect(quickFilterToSql('x', ['a', 'b'])).toBe(
+      "((typeof(a) != 'blob' AND CAST(a AS TEXT) GLOB '*[xX]*') OR " +
+        "(typeof(b) != 'blob' AND CAST(b AS TEXT) GLOB '*[xX]*'))",
+    );
+  });
+
+  test('no columns matches nothing', () => {
+    expect(quickFilterToSql('x', [])).toBe('FALSE');
+  });
+
+  test('digits are not case-expanded', () => {
+    expect(quickFilterToSql('12', ['a'])).toContain("GLOB '*12*'");
+  });
+
+  test('non-ASCII letters are not case-expanded', () => {
+    expect(quickFilterToSql('é', ['a'])).toContain("GLOB '*é*'");
+  });
+
+  test('glob special characters are escaped', () => {
+    expect(quickFilterToSql('*', ['a'])).toContain("GLOB '*[*]*'");
+    expect(quickFilterToSql('?', ['a'])).toContain("GLOB '*[?]*'");
+    expect(quickFilterToSql('[', ['a'])).toContain("GLOB '*[[]*'");
+  });
+
+  test('single quotes are escaped', () => {
+    expect(quickFilterToSql("'", ['a'])).toContain("GLOB '*''*'");
+  });
+});
diff --git a/ui/src/components/widgets/query_history.ts b/ui/src/components/widgets/query_history.ts
index 4d3590e..4edaec8 100644
--- a/ui/src/components/widgets/query_history.ts
+++ b/ui/src/components/widgets/query_history.ts
@@ -38,7 +38,7 @@
     // Items are stored with most recent first (index 0)
     // Iterate forward and separate starred from unstarred
     for (let i = 0; i < queryHistoryStorage.data.length; i++) {
-      const entry = queryHistoryStorage.data[i];
+      const entry = queryHistoryStorage.data[i]!;
       const arr = entry.starred ? starred : unstarred;
       arr.push({trace, index: i, entry, runQuery, setQuery});
     }
@@ -130,19 +130,19 @@
     let existingIndex = -1;
 
     for (let i = 0; i < items.length; i++) {
-      if (!items[i].starred) {
+      if (!items[i]!.starred) {
         countUnstarred++;
         lastUnstarred = i;
       }
 
-      if (items[i].query === query) {
+      if (items[i]!.query === query) {
         existingIndex = i;
       }
     }
 
     // If query already exists, move it to the front (index 0)
     if (existingIndex !== -1) {
-      const isStarred = items[existingIndex].starred;
+      const isStarred = items[existingIndex]!.starred;
       items.splice(existingIndex, 1);
       // Re-add at the front with same starred status
       items.unshift({query, starred: isStarred});
@@ -163,7 +163,7 @@
 
   setStarred(index: number, starred: boolean) {
     assertTrue(index >= 0 && index < this.data.length);
-    this.data[index].starred = starred;
+    this.data[index]!.starred = starred;
     this.save();
   }
 
diff --git a/ui/src/components/widgets/query_history_unittest.ts b/ui/src/components/widgets/query_history_unittest.ts
index 7b228aa..59f4c76 100644
--- a/ui/src/components/widgets/query_history_unittest.ts
+++ b/ui/src/components/widgets/query_history_unittest.ts
@@ -26,8 +26,8 @@
     it('should add new query at the front of history', () => {
       queryHistoryStorage.saveQuery('SELECT 1');
       expect(queryHistoryStorage.data.length).toBe(1);
-      expect(queryHistoryStorage.data[0].query).toBe('SELECT 1');
-      expect(queryHistoryStorage.data[0].starred).toBe(false);
+      expect(queryHistoryStorage.data[0]!.query).toBe('SELECT 1');
+      expect(queryHistoryStorage.data[0]!.starred).toBe(false);
     });
 
     it('should add multiple different queries with most recent first', () => {
@@ -36,9 +36,9 @@
       queryHistoryStorage.saveQuery('SELECT 3');
 
       expect(queryHistoryStorage.data.length).toBe(3);
-      expect(queryHistoryStorage.data[0].query).toBe('SELECT 3');
-      expect(queryHistoryStorage.data[1].query).toBe('SELECT 2');
-      expect(queryHistoryStorage.data[2].query).toBe('SELECT 1');
+      expect(queryHistoryStorage.data[0]!.query).toBe('SELECT 3');
+      expect(queryHistoryStorage.data[1]!.query).toBe('SELECT 2');
+      expect(queryHistoryStorage.data[2]!.query).toBe('SELECT 1');
     });
 
     it('should move existing unstarred query to the front when rerun', () => {
@@ -51,9 +51,9 @@
       queryHistoryStorage.saveQuery('SELECT 1');
 
       expect(queryHistoryStorage.data.length).toBe(3);
-      expect(queryHistoryStorage.data[0].query).toBe('SELECT 1');
-      expect(queryHistoryStorage.data[1].query).toBe('SELECT 3');
-      expect(queryHistoryStorage.data[2].query).toBe('SELECT 2');
+      expect(queryHistoryStorage.data[0]!.query).toBe('SELECT 1');
+      expect(queryHistoryStorage.data[1]!.query).toBe('SELECT 3');
+      expect(queryHistoryStorage.data[2]!.query).toBe('SELECT 2');
     });
 
     it('should move existing starred query to the front and preserve starred status', () => {
@@ -64,16 +64,16 @@
       // Array is now: [SELECT 3, SELECT 2, SELECT 1]
       // Star SELECT 3 (at index 0)
       queryHistoryStorage.setStarred(0, true);
-      expect(queryHistoryStorage.data[0].starred).toBe(true);
+      expect(queryHistoryStorage.data[0]!.starred).toBe(true);
 
       // Rerun the starred query
       queryHistoryStorage.saveQuery('SELECT 3');
 
       expect(queryHistoryStorage.data.length).toBe(3);
-      expect(queryHistoryStorage.data[0].query).toBe('SELECT 3');
-      expect(queryHistoryStorage.data[0].starred).toBe(true);
-      expect(queryHistoryStorage.data[1].query).toBe('SELECT 2');
-      expect(queryHistoryStorage.data[2].query).toBe('SELECT 1');
+      expect(queryHistoryStorage.data[0]!.query).toBe('SELECT 3');
+      expect(queryHistoryStorage.data[0]!.starred).toBe(true);
+      expect(queryHistoryStorage.data[1]!.query).toBe('SELECT 2');
+      expect(queryHistoryStorage.data[2]!.query).toBe('SELECT 1');
     });
 
     it('should move query from middle of history to front', () => {
@@ -87,10 +87,10 @@
       queryHistoryStorage.saveQuery('SELECT 2');
 
       expect(queryHistoryStorage.data.length).toBe(4);
-      expect(queryHistoryStorage.data[0].query).toBe('SELECT 2');
-      expect(queryHistoryStorage.data[1].query).toBe('SELECT 4');
-      expect(queryHistoryStorage.data[2].query).toBe('SELECT 3');
-      expect(queryHistoryStorage.data[3].query).toBe('SELECT 1');
+      expect(queryHistoryStorage.data[0]!.query).toBe('SELECT 2');
+      expect(queryHistoryStorage.data[1]!.query).toBe('SELECT 4');
+      expect(queryHistoryStorage.data[2]!.query).toBe('SELECT 3');
+      expect(queryHistoryStorage.data[3]!.query).toBe('SELECT 1');
     });
 
     it('should handle rerunning the most recent query', () => {
@@ -102,8 +102,8 @@
       queryHistoryStorage.saveQuery('SELECT 2');
 
       expect(queryHistoryStorage.data.length).toBe(2);
-      expect(queryHistoryStorage.data[0].query).toBe('SELECT 2');
-      expect(queryHistoryStorage.data[1].query).toBe('SELECT 1');
+      expect(queryHistoryStorage.data[0]!.query).toBe('SELECT 2');
+      expect(queryHistoryStorage.data[1]!.query).toBe('SELECT 1');
     });
 
     it('should enforce maxItems limit for unstarred queries', () => {
@@ -118,9 +118,9 @@
       queryHistoryStorage.saveQuery('SELECT 4'); // Should remove SELECT 1 (oldest)
 
       expect(queryHistoryStorage.data.length).toBe(3);
-      expect(queryHistoryStorage.data[0].query).toBe('SELECT 4');
-      expect(queryHistoryStorage.data[1].query).toBe('SELECT 3');
-      expect(queryHistoryStorage.data[2].query).toBe('SELECT 2');
+      expect(queryHistoryStorage.data[0]!.query).toBe('SELECT 4');
+      expect(queryHistoryStorage.data[1]!.query).toBe('SELECT 3');
+      expect(queryHistoryStorage.data[2]!.query).toBe('SELECT 2');
 
       // Restore original maxItems
       queryHistoryStorage.maxItems = originalMaxItems;
@@ -148,11 +148,11 @@
 
       // Should have 4 total: 1 starred + 3 unstarred
       expect(queryHistoryStorage.data.length).toBe(4);
-      expect(queryHistoryStorage.data[0].query).toBe('SELECT 5');
-      expect(queryHistoryStorage.data[1].query).toBe('SELECT 4');
-      expect(queryHistoryStorage.data[2].query).toBe('SELECT 3');
-      expect(queryHistoryStorage.data[2].starred).toBe(true);
-      expect(queryHistoryStorage.data[3].query).toBe('SELECT 2');
+      expect(queryHistoryStorage.data[0]!.query).toBe('SELECT 5');
+      expect(queryHistoryStorage.data[1]!.query).toBe('SELECT 4');
+      expect(queryHistoryStorage.data[2]!.query).toBe('SELECT 3');
+      expect(queryHistoryStorage.data[2]!.starred).toBe(true);
+      expect(queryHistoryStorage.data[3]!.query).toBe('SELECT 2');
 
       queryHistoryStorage.maxItems = originalMaxItems;
     });
@@ -169,16 +169,16 @@
 
       // Star SELECT 4 (at index 0)
       queryHistoryStorage.setStarred(0, true);
-      expect(queryHistoryStorage.data[0].query).toBe('SELECT 4');
+      expect(queryHistoryStorage.data[0]!.query).toBe('SELECT 4');
 
       // Rerun the starred query - it should stay at index 0
       queryHistoryStorage.saveQuery('SELECT 4');
 
       expect(queryHistoryStorage.data.length).toBe(3);
-      expect(queryHistoryStorage.data[0].query).toBe('SELECT 4');
-      expect(queryHistoryStorage.data[0].starred).toBe(true);
-      expect(queryHistoryStorage.data[1].query).toBe('SELECT 3');
-      expect(queryHistoryStorage.data[2].query).toBe('SELECT 2');
+      expect(queryHistoryStorage.data[0]!.query).toBe('SELECT 4');
+      expect(queryHistoryStorage.data[0]!.starred).toBe(true);
+      expect(queryHistoryStorage.data[1]!.query).toBe('SELECT 3');
+      expect(queryHistoryStorage.data[2]!.query).toBe('SELECT 2');
 
       queryHistoryStorage.maxItems = originalMaxItems;
     });
@@ -189,7 +189,7 @@
       queryHistoryStorage.saveQuery('SELECT 1');
       queryHistoryStorage.setStarred(0, true);
 
-      expect(queryHistoryStorage.data[0].starred).toBe(true);
+      expect(queryHistoryStorage.data[0]!.starred).toBe(true);
     });
 
     it('should unstar a query', () => {
@@ -197,7 +197,7 @@
       queryHistoryStorage.setStarred(0, true);
       queryHistoryStorage.setStarred(0, false);
 
-      expect(queryHistoryStorage.data[0].starred).toBe(false);
+      expect(queryHistoryStorage.data[0]!.starred).toBe(false);
     });
   });
 
@@ -211,8 +211,8 @@
       queryHistoryStorage.remove(1); // Remove SELECT 2
 
       expect(queryHistoryStorage.data.length).toBe(2);
-      expect(queryHistoryStorage.data[0].query).toBe('SELECT 3');
-      expect(queryHistoryStorage.data[1].query).toBe('SELECT 1');
+      expect(queryHistoryStorage.data[0]!.query).toBe('SELECT 3');
+      expect(queryHistoryStorage.data[1]!.query).toBe('SELECT 1');
     });
 
     it('should remove first query', () => {
@@ -223,7 +223,7 @@
       queryHistoryStorage.remove(0); // Remove SELECT 2
 
       expect(queryHistoryStorage.data.length).toBe(1);
-      expect(queryHistoryStorage.data[0].query).toBe('SELECT 1');
+      expect(queryHistoryStorage.data[0]!.query).toBe('SELECT 1');
     });
 
     it('should remove last query', () => {
@@ -234,7 +234,7 @@
       queryHistoryStorage.remove(1); // Remove SELECT 1
 
       expect(queryHistoryStorage.data.length).toBe(1);
-      expect(queryHistoryStorage.data[0].query).toBe('SELECT 2');
+      expect(queryHistoryStorage.data[0]!.query).toBe('SELECT 2');
     });
   });
 
diff --git a/ui/src/components/widgets/sql/details/details.ts b/ui/src/components/widgets/sql/details/details.ts
index a2e97ea..1848b0e 100644
--- a/ui/src/components/widgets/sql/details/details.ts
+++ b/ui/src/components/widgets/sql/details/details.ts
@@ -472,11 +472,11 @@
     const data: Data = {
       valueExpressions: this.expressions,
       values: [],
-      argSetExpressions: this.argSets.map((index) => this.expressions[index]),
+      argSetExpressions: this.argSets.map((index) => this.expressions[index]!),
       argSets: [],
       sqlIdRefs: this.sqlIdRefs.map((ref) => ({
         tableName: ref.tableName,
-        idExpression: this.expressions[ref.id],
+        idExpression: this.expressions[ref.id]!,
       })),
       sqlIdRefData: [],
     };
@@ -496,7 +496,7 @@
     `)
     ).firstRow({});
     for (let i = 0; i < this.expressions.length; ++i) {
-      data.values.push(row[label(i)]);
+      data.values.push(row[label(i)]!);
     }
 
     // Fetch the arg sets based on the fetched arg set ids.
@@ -767,8 +767,8 @@
       });
     }
     case 'sql_id_ref':
-      const ref = data.sqlIdRefs[value.ref];
-      const refData = data.sqlIdRefData[value.ref];
+      const ref = data.sqlIdRefs[value.ref]!;
+      const refData = data.sqlIdRefData[value.ref]!;
       let rhs: m.Children;
       let children: m.Children;
       if (refData instanceof Err) {
diff --git a/ui/src/components/widgets/sql/pivot_table/aggregations.ts b/ui/src/components/widgets/sql/pivot_table/aggregations.ts
index fa2749d..ec53752 100644
--- a/ui/src/components/widgets/sql/pivot_table/aggregations.ts
+++ b/ui/src/components/widgets/sql/pivot_table/aggregations.ts
@@ -108,13 +108,13 @@
 
 export function getAggregationValue(agg: Aggregation, row: Row): SqlValue {
   if (agg.op !== 'average') {
-    return row[aggregationId(agg)];
+    return row[aggregationId(agg)]!;
   }
   const sum = sqlValueAsNumber(
-    row[aggregationId({op: 'sum', column: agg.column})],
+    row[aggregationId({op: 'sum', column: agg.column})]!,
   );
   const count = sqlValueAsNumber(
-    row[aggregationId({op: 'count', column: agg.column})],
+    row[aggregationId({op: 'count', column: agg.column})]!,
   );
   if (sum === null || count === null) return null;
   return sum / count;
diff --git a/ui/src/components/widgets/sql/pivot_table/pivot_table.ts b/ui/src/components/widgets/sql/pivot_table/pivot_table.ts
index d44ffa5..dd71b01 100644
--- a/ui/src/components/widgets/sql/pivot_table/pivot_table.ts
+++ b/ui/src/components/widgets/sql/pivot_table/pivot_table.ts
@@ -133,7 +133,7 @@
           const value = node.getPivotValue(index);
           const renderedCell = (function () {
             if (value === undefined) return undefined;
-            return state.getPivots()[index].renderCell(value);
+            return state.getPivots()[index]!.renderCell(value);
           })();
           const content = [
             (status === 'collapsed' || status === 'expanded') &&
diff --git a/ui/src/components/widgets/sql/pivot_table/pivot_table_state.ts b/ui/src/components/widgets/sql/pivot_table/pivot_table_state.ts
index 19e4ab9..66919fd 100644
--- a/ui/src/components/widgets/sql/pivot_table/pivot_table_state.ts
+++ b/ui/src/components/widgets/sql/pivot_table/pivot_table_state.ts
@@ -137,13 +137,13 @@
   }
 
   public removePivot(index: number) {
-    this.sortByPivot(this.pivots[index], undefined);
+    this.sortByPivot(this.pivots[index]!, undefined);
     this.pivots.splice(index, 1);
     this.reload();
   }
 
   public removeAggregation(index: number) {
-    this.sortByAggregation(this.aggregations[index], undefined);
+    this.sortByAggregation(this.aggregations[index]!, undefined);
     this.aggregations.splice(index, 1);
     this.reload();
   }
@@ -215,7 +215,7 @@
   public isSortedByPivot(pivot: TableColumn): SortDirection | undefined {
     if (this.orderBy.length === 0) return undefined;
     const id = pivotId(pivot);
-    const head = this.orderBy[0];
+    const head = this.orderBy[0]!;
     if (head.type === 'pivot' && head.id === id) return head.direction;
     return undefined;
   }
@@ -223,7 +223,7 @@
   public isSortedByAggregation(agg: Aggregation): SortDirection | undefined {
     if (this.orderBy.length === 0) return undefined;
     const id = aggregationId(agg);
-    const head = this.orderBy[0];
+    const head = this.orderBy[0]!;
     if (head.type === 'aggregation' && head.id === id) return head.direction;
     return undefined;
   }
diff --git a/ui/src/components/widgets/sql/pivot_table/pivot_tree_node.ts b/ui/src/components/widgets/sql/pivot_table/pivot_tree_node.ts
index 11ebbc1..1305905 100644
--- a/ui/src/components/widgets/sql/pivot_table/pivot_tree_node.ts
+++ b/ui/src/components/widgets/sql/pivot_table/pivot_tree_node.ts
@@ -107,14 +107,14 @@
     for (const row of rows) {
       let node = root;
       for (const pivot of config.pivots) {
-        node = node.getOrCreateChild(row[pivotId(pivot)]);
+        node = node.getOrCreateChild(row[pivotId(pivot)]!);
       }
       // Update the raw values for the node.
       for (const agg of root.config.basicAggregations) {
         const id = aggregationId(agg);
         node.aggregationValuesSelf[id] = basicAggregations[agg.op](
-          node.aggregationValuesSelf[id],
-          row[aggregationId(agg)],
+          node.aggregationValuesSelf[id]!,
+          row[aggregationId(agg)]!,
         );
       }
     }
@@ -177,7 +177,7 @@
   // Get the value of the aggregation at the given index.
   getAggregationValue(index: number): SqlValue {
     return getAggregationValueImpl(
-      this.config.aggregations[index],
+      this.config.aggregations[index]!,
       this.aggregationValues,
     );
   }
@@ -240,7 +240,7 @@
 
   private getFilter(): Filter {
     return StandardFilters.valueEquals(
-      this.config.pivots[this.getPivotIndex()].column,
+      this.config.pivots[this.getPivotIndex()]!.column,
       ensureDefined(this.pivotValue),
     );
   }
@@ -249,7 +249,7 @@
   private getPivotId(): string | undefined {
     const index = this.getPivotIndex();
     if (index === -1) return undefined;
-    return pivotId(this.config.pivots[index]);
+    return pivotId(this.config.pivots[index]!);
   }
 
   private getOrCreateChild(value: SqlValue): PivotTreeNode {
@@ -274,7 +274,7 @@
         const id = aggregationId(agg);
         this.aggregationValues[id] = basicAggregations[agg.op](
           this.aggregationValues[id] ?? null,
-          child.aggregationValues[id],
+          child.aggregationValues[id]!,
         );
       }
     }
diff --git a/ui/src/components/widgets/sql/table/columns.ts b/ui/src/components/widgets/sql/table/columns.ts
index 7765be4..cb3a66f 100644
--- a/ui/src/components/widgets/sql/table/columns.ts
+++ b/ui/src/components/widgets/sql/table/columns.ts
@@ -701,7 +701,7 @@
       ) {
         const entries = Object.entries(value);
         if (entries.length === 1) {
-          const [nestedKey, nestedValue] = entries[0];
+          const [nestedKey, nestedValue] = entries[0]!;
           return condense(`${key}.${nestedKey}`, nestedValue);
         }
       }
diff --git a/ui/src/components/widgets/sql/table/filters.ts b/ui/src/components/widgets/sql/table/filters.ts
index d7a4032..4d06427 100644
--- a/ui/src/components/widgets/sql/table/filters.ts
+++ b/ui/src/components/widgets/sql/table/filters.ts
@@ -97,7 +97,7 @@
   return (
     a.op === b.op &&
     a.columns.length === b.columns.length &&
-    a.columns.every((c, i) => isSqlColumnEqual(c, b.columns[i]))
+    a.columns.every((c, i) => isSqlColumnEqual(c, b.columns[i]!))
   );
 }
 
@@ -106,7 +106,7 @@
   b: ReadonlyArray<Filter>,
 ) {
   if (a.length !== b.length) return false;
-  return a.every((f, i) => isFilterEqual(f, b[i]));
+  return a.every((f, i) => isFilterEqual(f, b[i]!));
 }
 
 export function renderFilters(filters: Filters): m.Children {
@@ -149,7 +149,9 @@
   }
 
   static valueIsOneOf(col: SqlColumn, values: SqlValue[]): Filter {
-    if (values.length === 1) return StandardFilters.valueEquals(col, values[0]);
+    if (values.length === 1) {
+      return StandardFilters.valueEquals(col, values[0]!);
+    }
     if (values.length === 0) {
       return {
         columns: [],
diff --git a/ui/src/components/widgets/sql/table/menus/cast_column_menu.ts b/ui/src/components/widgets/sql/table/menus/cast_column_menu.ts
index c66a8d7..16d5b6a 100644
--- a/ui/src/components/widgets/sql/table/menus/cast_column_menu.ts
+++ b/ui/src/components/widgets/sql/table/menus/cast_column_menu.ts
@@ -147,10 +147,10 @@
                 underlyingSqlType(params.type)
             ) {
               // If the underlying types are the same, there is no need for a SQL cast, we only need to reinterpret the data.
-              return (cols: string[]) => cols[0];
+              return (cols: string[]) => cols[0]!;
             }
             return (cols: string[]) =>
-              `CAST(${cols[0]} AS ${underlyingSqlType(params.type)})`;
+              `CAST(${cols[0]!} AS ${underlyingSqlType(params.type)})`;
           })();
 
           // Create a CastColumn wrapping the source column
diff --git a/ui/src/components/widgets/sql/table/menus/transform_column_menu.ts b/ui/src/components/widgets/sql/table/menus/transform_column_menu.ts
index 0cf6cfd..e3e2c25 100644
--- a/ui/src/components/widgets/sql/table/menus/transform_column_menu.ts
+++ b/ui/src/components/widgets/sql/table/menus/transform_column_menu.ts
@@ -56,7 +56,7 @@
 ): (trace: Trace, column: SqlColumn, ...params: string[]) => TableColumn {
   return (trace: Trace, column: SqlColumn, ...params: string[]) => {
     const sqlExpr = new SqlExpression(
-      (cols: string[]) => exprFn(cols[0], ...params),
+      (cols: string[]) => exprFn(cols[0]!, ...params),
       [column],
     );
     return createTableColumn({
@@ -254,7 +254,7 @@
     if (this.paramState.length !== params.length) {
       this.paramState = range(params.length).map((index) => {
         if (index < initialValues.length) {
-          return {value: initialValues[index], error: false};
+          return {value: initialValues[index]!, error: false};
         }
         return {value: '', error: false};
       });
@@ -266,8 +266,8 @@
         submitLabel: attrs.formSubmitLabel,
         onSubmit: (e: Event) => {
           params.forEach((param, index) => {
-            const value = this.paramState[index].value;
-            this.paramState[index].error = !(param.validate?.(value) ?? true);
+            const value = this.paramState[index]!.value;
+            this.paramState[index]!.error = !(param.validate?.(value) ?? true);
           });
 
           const hasError = this.paramState.some((state) => state.error);
@@ -278,7 +278,7 @@
                 state: attrs.state,
                 transformType: attrs.transformType,
                 values: params.map((param, index) => {
-                  const value = this.paramState[index].value;
+                  const value = this.paramState[index]!.value;
                   if (value === '' && param.defaultValue !== undefined) {
                     return param.defaultValue;
                   }
@@ -297,12 +297,14 @@
         m(TextInput, {
           id: `${this.uuid}_param_${index}`,
           placeholder: param.placeholder,
-          value: this.paramState[index].value,
+          value: this.paramState[index]!.value,
           oninput: (e: InputEvent) => {
-            this.paramState[index].value = (e.target as HTMLInputElement).value;
-            this.paramState[index].error = false;
+            this.paramState[index]!.value = (
+              e.target as HTMLInputElement
+            ).value;
+            this.paramState[index]!.error = false;
           },
-          style: this.paramState[index].error
+          style: this.paramState[index]!.error
             ? {
                 border: '1px solid red',
                 outline: 'none',
diff --git a/ui/src/components/widgets/sql/table/query_builder.ts b/ui/src/components/widgets/sql/table/query_builder.ts
index 8b77d07..4cfbf97 100644
--- a/ui/src/components/widgets/sql/table/query_builder.ts
+++ b/ui/src/components/widgets/sql/table/query_builder.ts
@@ -131,7 +131,7 @@
 
     // Check if this join is already present.
     for (let i = 0; i < this.tables.length; ++i) {
-      const table = this.tables[i];
+      const table = this.tables[i]!;
       if (
         table.table === column.source.table &&
         table.innerJoin === (column.source.innerJoin ?? false) &&
@@ -172,13 +172,13 @@
       }
       return `${this.tableAlias}.${column.column}`;
     }
-    const table = this.tables[column.sourceTableId];
+    const table = this.tables[column.sourceTableId]!;
     // Dependent tables are 0-indexed, but we want to display them as 1-indexed to reserve 0 for the primary table.
     return `${table.table}_${column.sourceTableId + 1}.${column.column}`;
   }
 
   printJoin(joinIndex: number): string {
-    const join = this.tables[joinIndex];
+    const join = this.tables[joinIndex]!;
     const alias = `${join.table}_${joinIndex + 1}`;
     const clauses = Object.entries(join.joinOn).map(
       ([key, value]) => `${alias}.${key} = ${this.printReference(value)}`,
diff --git a/ui/src/components/widgets/sql/table/sql_column.ts b/ui/src/components/widgets/sql/table/sql_column.ts
index fe91f03..a05095f 100644
--- a/ui/src/components/widgets/sql/table/sql_column.ts
+++ b/ui/src/components/widgets/sql/table/sql_column.ts
@@ -70,7 +70,7 @@
   }
   // Special case: If the join is performed on a single column `id`, we can use a simpler representation (i.e. `table[id].column`).
   if (arrayEquals(Object.keys(column.source.joinOn), ['id'])) {
-    return `${column.source.table}[${sqlColumnId(Object.values(column.source.joinOn)[0])}].${column.column}`;
+    return `${column.source.table}[${sqlColumnId(Object.values(column.source.joinOn)[0]!)}].${column.column}`;
   }
   // Otherwise, we need to list all the join constraints.
   const lookup = Object.entries(column.source.joinOn)
diff --git a/ui/src/components/widgets/sql/table/state.ts b/ui/src/components/widgets/sql/table/state.ts
index 65372c4..46c9b2f 100644
--- a/ui/src/components/widgets/sql/table/state.ts
+++ b/ui/src/components/widgets/sql/table/state.ts
@@ -315,10 +315,10 @@
 
   isSortedBy(column: TableColumn): SortDirection | undefined {
     if (this.orderBy.length === 0) return undefined;
-    if (tableColumnId(this.orderBy[0].column) !== tableColumnId(column)) {
+    if (tableColumnId(this.orderBy[0]!.column) !== tableColumnId(column)) {
       return undefined;
     }
-    return this.orderBy[0].direction;
+    return this.orderBy[0]!.direction;
   }
 
   getOrderedBy(): ColumnOrderClause[] {
@@ -338,7 +338,7 @@
   }
 
   hideColumnAtIndex(index: number) {
-    const column = this.columns[index];
+    const column = this.columns[index]!;
     this.columns.splice(index, 1);
     this.willRemoveColumn(column);
     // TODO(altimin): we can avoid the fetch here if the orderBy hasn't changed.
@@ -346,7 +346,7 @@
   }
 
   replaceColumnAtIndex(index: number, column: TableColumn) {
-    this.willRemoveColumn(this.columns[index]);
+    this.willRemoveColumn(this.columns[index]!);
     this.columns[index] = column;
     this.reload({offset: 'keep'});
   }
diff --git a/ui/src/components/widgets/sql/table/table.ts b/ui/src/components/widgets/sql/table/table.ts
index 8250a4e..a39c4e7 100644
--- a/ui/src/components/widgets/sql/table/table.ts
+++ b/ui/src/components/widgets/sql/table/table.ts
@@ -64,7 +64,7 @@
   addColumn: (column: TableColumn) => void,
 ): RenderedCell {
   const {columns} = state.getCurrentRequest();
-  const sqlValue = row[columns[sqlColumnId(column.display ?? column.column)]];
+  const sqlValue = row[columns[sqlColumnId(column.display ?? column.column)]!]!;
 
   const result = column.renderCell(
     sqlValue,
@@ -165,7 +165,7 @@
     const additionalColumnMenuItems: AdditionalColumnMenuItems = {};
     this.state.getSelectedColumns().forEach((column) => {
       const columnAlias =
-        this.state.getCurrentRequest().columns[sqlColumnId(column.column)];
+        this.state.getCurrentRequest().columns[sqlColumnId(column.column)]!;
 
       additionalColumnMenuItems[columnAlias] = addColumnMenuItems(
         column,
@@ -216,7 +216,7 @@
         ),
         additionalColumnMenuItems &&
           additionalColumnMenuItems[
-            this.state.getCurrentRequest().columns[sqlColumnId(column.column)]
+            this.state.getCurrentRequest().columns[sqlColumnId(column.column)]!
           ],
         // Menu items before divider apply to selected column
         m(MenuDivider),
diff --git a/ui/src/components/widgets/treetable.ts b/ui/src/components/widgets/treetable.ts
index 362448d..0f8aca7 100644
--- a/ui/src/components/widgets/treetable.ts
+++ b/ui/src/components/widgets/treetable.ts
@@ -111,6 +111,6 @@
 
   keyForRow(row: T, attrs: TreeTableAttrs<T>): string {
     const {columns} = attrs;
-    return columns[0].getData(row);
+    return columns[0]!.getData(row);
   }
 }
diff --git a/ui/src/core/analytics_impl.ts b/ui/src/core/analytics_impl.ts
index c1a5129..3538a9d 100644
--- a/ui/src/core/analytics_impl.ts
+++ b/ui/src/core/analytics_impl.ts
@@ -55,7 +55,7 @@
       return `https://${name}.example.com/converted_non_url_referrer`;
     }
   } else {
-    return document.referrer.split('?')[0];
+    return document.referrer.split('?')[0]!;
   }
 }
 
diff --git a/ui/src/core/command_manager_unittest.ts b/ui/src/core/command_manager_unittest.ts
index b921988..7aa19a0 100644
--- a/ui/src/core/command_manager_unittest.ts
+++ b/ui/src/core/command_manager_unittest.ts
@@ -33,7 +33,7 @@
     };
     const remapped = remapHotkeys([cmd], [overlay]);
 
-    expect(remapped[0].defaultHotkey).toBe('X');
+    expect(remapped[0]!.defaultHotkey).toBe('X');
   });
 
   test('double layer', () => {
@@ -51,7 +51,7 @@
     };
     const remapped = remapHotkeys([cmd], [overlay1, overlay2]);
 
-    expect(remapped[0].defaultHotkey).toBe('Z');
+    expect(remapped[0]!.defaultHotkey).toBe('Z');
   });
 
   test('not defined in layer', () => {
@@ -66,7 +66,7 @@
     };
     const remapped = remapHotkeys([cmd], [overlay1]);
 
-    expect(remapped[0].defaultHotkey).toBe('P');
+    expect(remapped[0]!.defaultHotkey).toBe('P');
   });
 
   test('no overlays', () => {
@@ -78,7 +78,7 @@
     };
     const remapped = remapHotkeys([cmd], []);
 
-    expect(remapped[0].defaultHotkey).toBe('P');
+    expect(remapped[0]!.defaultHotkey).toBe('P');
   });
 
   test('cmd without default hotkey gets remapped', () => {
@@ -92,7 +92,7 @@
     };
     const remapped = remapHotkeys([cmd], [overlay]);
 
-    expect(remapped[0].defaultHotkey).toBe('X');
+    expect(remapped[0]!.defaultHotkey).toBe('X');
   });
 });
 
diff --git a/ui/src/core/embedder/default_plugins.ts b/ui/src/core/embedder/default_plugins.ts
index 4370fd8..b64dc3a 100644
--- a/ui/src/core/embedder/default_plugins.ts
+++ b/ui/src/core/embedder/default_plugins.ts
@@ -26,6 +26,7 @@
   'com.android.AndroidCujs',
   'com.android.AndroidDmabuf',
   'com.android.AndroidGpu',
+  'com.android.AndroidInputLifecycle',
   'com.android.AndroidLockContention',
   'com.android.AndroidLog',
   'com.android.AndroidLongBatteryTracing',
diff --git a/ui/src/core/event_set.ts b/ui/src/core/event_set.ts
index 9a23158..32c9294 100644
--- a/ui/src/core/event_set.ts
+++ b/ui/src/core/event_set.ts
@@ -648,7 +648,7 @@
     }
 
     if (newParents.length === 1) {
-      return newParents[0];
+      return newParents[0]!;
     }
 
     // The union of concrete EventSets is a concrete EventSets with all
diff --git a/ui/src/core/load_trace.ts b/ui/src/core/load_trace.ts
index 4ba71ee..d7db738 100644
--- a/ui/src/core/load_trace.ts
+++ b/ui/src/core/load_trace.ts
@@ -523,7 +523,7 @@
 // component trace if that trace was previously opened individually.
 async function computeGlobalUuid(uuids: string[]): Promise<string> {
   if (uuids.length === 0) return '';
-  if (uuids.length === 1) return uuids[0];
+  if (uuids.length === 1) return uuids[0]!;
   const sortedUuids = [...uuids].sort();
   return await sha1(sortedUuids.join(';'));
 }
diff --git a/ui/src/core/open_trace_files.ts b/ui/src/core/open_trace_files.ts
index 6a12f1f..08ce300 100644
--- a/ui/src/core/open_trace_files.ts
+++ b/ui/src/core/open_trace_files.ts
@@ -22,6 +22,6 @@
   if (files.length > 1 && app.commands.hasCommand(OPEN_MULTIPLE_TRACES_CMD)) {
     app.commands.runCommand(OPEN_MULTIPLE_TRACES_CMD, files);
   } else if (files.length > 0) {
-    app.openTraceFromFile(files[0]);
+    app.openTraceFromFile(files[0]!);
   }
 }
diff --git a/ui/src/core/plugin_manager.ts b/ui/src/core/plugin_manager.ts
index 2e219a6..b977b1a 100644
--- a/ui/src/core/plugin_manager.ts
+++ b/ui/src/core/plugin_manager.ts
@@ -320,7 +320,7 @@
 
     // Only include entries that match the regex
     if (match) {
-      const newKey = match[1];
+      const newKey = match[1]!;
       // Use the capture group (what comes after the prefix) as the new key
       result[newKey] = value;
     }
diff --git a/ui/src/core/router.ts b/ui/src/core/router.ts
index d19590f..d019780 100644
--- a/ui/src/core/router.ts
+++ b/ui/src/core/router.ts
@@ -212,7 +212,7 @@
     const now = Date.now();
     while (
       this.recentChanges.length > 0 &&
-      now - this.recentChanges[0] > WINDOW_MS
+      now - this.recentChanges[0]! > WINDOW_MS
     ) {
       this.recentChanges.shift();
     }
diff --git a/ui/src/core/router_unittest.ts b/ui/src/core/router_unittest.ts
index 7cf4934..03277d9 100644
--- a/ui/src/core/router_unittest.ts
+++ b/ui/src/core/router_unittest.ts
@@ -72,6 +72,11 @@
     const route = Router.parseUrl(url);
     expect(route.fragment).toBe('myfragment');
   });
+
+  test('hideStatusbar parsing', () => {
+    const route = Router.parseUrl('http://localhost/?hideStatusbar=true');
+    expect(route.args.hideStatusbar).toBe(true);
+  });
 });
 
 describe('Router.parseFragment', () => {
@@ -140,4 +145,9 @@
     const {args} = Router.parseFragment('#!/?hideSidebar=helloworld!');
     expect(args.hideSidebar).toEqual(undefined);
   });
+
+  test('bad hideStatusbar is coerced to default', () => {
+    const {args} = Router.parseFragment('#!/?hideStatusbar=helloworld!');
+    expect(args.hideStatusbar).toEqual(undefined);
+  });
 });
diff --git a/ui/src/core/search_manager.ts b/ui/src/core/search_manager.ts
index 6ffe3f8..5a5e112 100644
--- a/ui/src/core/search_manager.ts
+++ b/ui/src/core/search_manager.ts
@@ -165,7 +165,7 @@
     };
 
     for (let i = 0; i < numRows; i++) {
-      const {id, ts, track} = allResults[i];
+      const {id, ts, track} = allResults[i]!;
       searchResults.eventIds[i] = id;
       searchResults.tses[i] = ts;
       searchResults.trackUris.push(track.uri);
@@ -209,10 +209,10 @@
       }
     }
     this._onResultStep?.({
-      eventId: this._results.eventIds[this._resultIndex],
-      ts: Time.fromRaw(this._results.tses[this._resultIndex]),
-      trackUri: this._results.trackUris[this._resultIndex],
-      source: this._results.sources[this._resultIndex],
+      eventId: this._results.eventIds[this._resultIndex]!,
+      ts: Time.fromRaw(this._results.tses[this._resultIndex]!),
+      trackUri: this._results.trackUris[this._resultIndex]!,
+      source: this._results.sources[this._resultIndex]!,
     });
   }
 
diff --git a/ui/src/core/settings_manager.ts b/ui/src/core/settings_manager.ts
index f27b764..ab9653d 100644
--- a/ui/src/core/settings_manager.ts
+++ b/ui/src/core/settings_manager.ts
@@ -13,6 +13,7 @@
 // limitations under the License.
 
 import type {z} from 'zod';
+import {deepFreeze} from '../base/object_utils';
 import type {
   Setting,
   SettingDescriptor,
@@ -23,13 +24,6 @@
 
 export const PERFETTO_SETTINGS_STORAGE_KEY = 'perfettoSettings';
 
-function deepFreeze<T>(obj: T): T {
-  if (obj === null || typeof obj !== 'object') return obj;
-  Object.freeze(obj);
-  Object.values(obj).forEach(deepFreeze);
-  return obj;
-}
-
 // Implement the Setting interface for registered settings
 export class SettingImpl<T> implements Setting<T> {
   // Record what the raw value was at startup. This is used to determine if a
diff --git a/ui/src/core/settings_manager_unittest.ts b/ui/src/core/settings_manager_unittest.ts
index 8259781..d91a019 100644
--- a/ui/src/core/settings_manager_unittest.ts
+++ b/ui/src/core/settings_manager_unittest.ts
@@ -129,9 +129,9 @@
 
     const allSettings = settingsManager.getAllSettings();
     expect(allSettings.length).toBe(3);
-    expect(allSettings[0].id).toBe(boolSettingDesc.id); // test.bool
-    expect(allSettings[1].id).toBe(numberSettingDesc.id); // test.number
-    expect(allSettings[2].id).toBe(stringSettingDesc.id); // test.string
+    expect(allSettings[0]!.id).toBe(boolSettingDesc.id); // test.bool
+    expect(allSettings[1]!.id).toBe(numberSettingDesc.id); // test.number
+    expect(allSettings[2]!.id).toBe(stringSettingDesc.id); // test.string
   });
 
   test('isReloadRequired should be false initially', () => {
diff --git a/ui/src/core/state_serialization.ts b/ui/src/core/state_serialization.ts
index 3f1709e..f6db904 100644
--- a/ui/src/core/state_serialization.ts
+++ b/ui/src/core/state_serialization.ts
@@ -154,9 +154,7 @@
   }
 
   const store = new Array<SerializedStoreState>();
-  const traceStore = trace.store;
-
-  for (const [id, pluginState] of Object.entries(traceStore.state)) {
+  for (const [id, pluginState] of trace.storageEntries) {
     store.push({id, state: pluginState});
   }
 
@@ -220,11 +218,9 @@
   appState: SerializedAppState,
   trace: TraceImpl,
 ): void {
-  trace.store.edit((draft) => {
-    for (const p of appState.store ?? []) {
-      draft[p.id] = p.state ?? {};
-    }
-  });
+  for (const p of appState.store ?? []) {
+    trace.setStorageState(p.id, p.state ?? {});
+  }
 }
 
 /**
diff --git a/ui/src/core/state_serialization_unittest.ts b/ui/src/core/state_serialization_unittest.ts
index 6f7abed..de8e70d 100644
--- a/ui/src/core/state_serialization_unittest.ts
+++ b/ui/src/core/state_serialization_unittest.ts
@@ -232,17 +232,17 @@
     expect(serialized.collapsed).toBe(false);
     expect(serialized.isSummary).toBe(true);
     expect(serialized.children).toHaveLength(1);
-    expect(serialized.children![0].name).toBe('Track 1');
-    expect(serialized.children![0].uri).toBe('test.track.1');
+    expect(serialized.children![0]!.name).toBe('Track 1');
+    expect(serialized.children![0]!.uri).toBe('test.track.1');
 
     const deserialized = deserializeTrackNode(serialized);
     expect(deserialized.name).toBe('Group A');
     expect(deserialized.collapsed).toBe(false);
     expect(deserialized.isSummary).toBe(true);
     expect(deserialized.children).toHaveLength(1);
-    expect(deserialized.children[0].name).toBe('Track 1');
-    expect(deserialized.children[0].uri).toBe('test.track.1');
-    expect(deserialized.children[0].removable).toBe(true);
+    expect(deserialized.children[0]!.name).toBe('Track 1');
+    expect(deserialized.children[0]!.uri).toBe('test.track.1');
+    expect(deserialized.children[0]!.removable).toBe(true);
   });
 
   test('serialize and deserialize non-default workspaces', () => {
@@ -265,13 +265,13 @@
 
     const serialized = serializeAppState(trace);
     expect(serialized.workspaces).toHaveLength(1);
-    expect(serialized.workspaces![0].title).toBe('Custom Workspace');
-    expect(serialized.workspaces![0].userEditable).toBe(false);
-    expect(serialized.workspaces![0].tracks).toHaveLength(1);
-    expect(serialized.workspaces![0].tracks[0].name).toBe('Custom Track');
-    expect(serialized.workspaces![0].tracks[0].uri).toBe('foo.bar.track');
-    expect(serialized.workspaces![0].pinnedTracks).toHaveLength(1);
-    expect(serialized.workspaces![0].pinnedTracks[0].uri).toBe(
+    expect(serialized.workspaces![0]!.title).toBe('Custom Workspace');
+    expect(serialized.workspaces![0]!.userEditable).toBe(false);
+    expect(serialized.workspaces![0]!.tracks).toHaveLength(1);
+    expect(serialized.workspaces![0]!.tracks[0]!.name).toBe('Custom Track');
+    expect(serialized.workspaces![0]!.tracks[0]!.uri).toBe('foo.bar.track');
+    expect(serialized.workspaces![0]!.pinnedTracks).toHaveLength(1);
+    expect(serialized.workspaces![0]!.pinnedTracks[0]!.uri).toBe(
       'foo.bar.pinned',
     );
 
@@ -283,11 +283,11 @@
     expect(restoredWs).toBeDefined();
     expect(restoredWs!.userEditable).toBe(false);
     expect(restoredWs!.tracks.children).toHaveLength(1);
-    expect(restoredWs!.tracks.children[0].name).toBe('Custom Track');
-    expect(restoredWs!.tracks.children[0].uri).toBe('foo.bar.track');
+    expect(restoredWs!.tracks.children[0]!.name).toBe('Custom Track');
+    expect(restoredWs!.tracks.children[0]!.uri).toBe('foo.bar.track');
     expect(restoredWs!.pinnedTracks).toHaveLength(1);
-    expect(restoredWs!.pinnedTracks[0].name).toBe('Pinned Track');
-    expect(restoredWs!.pinnedTracks[0].uri).toBe('foo.bar.pinned');
+    expect(restoredWs!.pinnedTracks[0]!.name).toBe('Pinned Track');
+    expect(restoredWs!.pinnedTracks[0]!.uri).toBe('foo.bar.pinned');
   });
 
   test('serialize and deserialize current workspace', () => {
@@ -341,7 +341,7 @@
     );
 
     const serialized = serializeAppState(trace);
-    expect(serialized.workspaces![0].id).toBe('stable-plugin-id-1234');
+    expect(serialized.workspaces![0]!.id).toBe('stable-plugin-id-1234');
 
     const targetTrace = createFakeTraceImpl();
     deserializeAppStatePhase2(serialized, targetTrace);
@@ -351,9 +351,9 @@
       (w) => w !== targetTrace.defaultWorkspace,
     );
     expect(nonDefaultWorkspaces).toHaveLength(1);
-    expect(nonDefaultWorkspaces[0].id).toBe('stable-plugin-id-1234');
-    expect(nonDefaultWorkspaces[0].title).toBe('Plugin Workspace');
-    expect(nonDefaultWorkspaces[0].tracks.children).toHaveLength(1);
+    expect(nonDefaultWorkspaces[0]!.id).toBe('stable-plugin-id-1234');
+    expect(nonDefaultWorkspaces[0]!.title).toBe('Plugin Workspace');
+    expect(nonDefaultWorkspaces[0]!.tracks.children).toHaveLength(1);
   });
 
   test('legacy state without workspaces preserves existing non-default workspaces', () => {
@@ -371,7 +371,7 @@
       (w) => w !== targetTrace.defaultWorkspace,
     );
     expect(nonDefaultWorkspaces).toHaveLength(1);
-    expect(nonDefaultWorkspaces[0].title).toBe('Plugin Workspace');
+    expect(nonDefaultWorkspaces[0]!.title).toBe('Plugin Workspace');
   });
 
   test('state with empty workspaces removes existing non-default workspaces', () => {
diff --git a/ui/src/core/tab_manager.ts b/ui/src/core/tab_manager.ts
index c2a5aae..58bd265 100644
--- a/ui/src/core/tab_manager.ts
+++ b/ui/src/core/tab_manager.ts
@@ -107,10 +107,10 @@
           this._currentTab = 'current_selection';
         } else if (currentTabIdx < this._openTabs.length - 1) {
           // Pick the tab to the right
-          this._currentTab = this._openTabs[currentTabIdx];
+          this._currentTab = this._openTabs[currentTabIdx]!;
         } else {
           // Pick the last tab
-          const lastTab = this._openTabs[this._openTabs.length - 1];
+          const lastTab = this._openTabs[this._openTabs.length - 1]!;
           this._currentTab = lastTab;
         }
       }
diff --git a/ui/src/core/timeline.ts b/ui/src/core/timeline.ts
index 3062921..4912b16 100644
--- a/ui/src/core/timeline.ts
+++ b/ui/src/core/timeline.ts
@@ -398,7 +398,7 @@
         return getTraceMidnightInTimezone(
           this.traceInfo.start,
           this.traceInfo.unixOffset,
-          timezoneOffsetMap[this.timezoneOverride.get()],
+          timezoneOffsetMap[this.timezoneOverride.get()]!,
         );
       case TimestampFormat.TraceTz:
         return getTraceMidnightInTimezone(
@@ -433,7 +433,7 @@
   }
 
   get customTimezoneOffset(): number {
-    return timezoneOffsetMap[this.timezoneOverride.get()];
+    return timezoneOffsetMap[this.timezoneOverride.get()]!;
   }
 
   // Animate to a new visible window using ease-in-ease-out
diff --git a/ui/src/core/trace_impl.ts b/ui/src/core/trace_impl.ts
index 3297b91..7349d6b 100644
--- a/ui/src/core/trace_impl.ts
+++ b/ui/src/core/trace_impl.ts
@@ -13,10 +13,9 @@
 // limitations under the License.
 
 import {DisposableStack} from '../base/disposable_stack';
-import {createStore, type Migrate, type Store} from '../base/store';
 import {TimelineImpl} from './timeline';
 import type {Command} from '../public/commands';
-import type {Trace} from '../public/trace';
+import type {Storage, StorageDescriptor, Trace} from '../public/trace';
 import type {ScrollToArgs} from '../public/scroll_helper';
 import type {Engine, EngineBase} from '../trace_processor/engine';
 import type {CommandManagerImpl} from './command_manager';
@@ -41,6 +40,7 @@
 import type {TraceInfoImpl} from './trace_info_impl';
 import type {PageHandler, PageManager} from '../public/page';
 import {createProxy} from '../base/utils';
+import {deepFreeze} from '../base/object_utils';
 import type {PageManagerImpl} from './page_manager';
 import type {FeatureFlagManager, FlagSettings} from '../public/feature_flag';
 import type {SerializedAppState} from './state_serialization_schema';
@@ -83,10 +83,19 @@
   readonly initialPage = new InitialPageManagerImpl();
   readonly loadingErrors: string[] = [];
   readonly app: AppImpl;
-  readonly store = createStore<Record<string, unknown>>({});
+  private readonly storageState = new Map<string, unknown>();
 
-  // Do we need this?
-  readonly pluginSerializableState = createStore<{[key: string]: {}}>({});
+  getStorageState(id: string): unknown {
+    return this.storageState.get(id);
+  }
+
+  setStorageState(id: string, value: unknown): void {
+    this.storageState.set(id, deepFreeze(value));
+  }
+
+  get storageEntries(): IterableIterator<[string, unknown]> {
+    return this.storageState.entries();
+  }
 
   constructor(app: AppImpl, engine: EngineBase, traceInfo: TraceInfoImpl) {
     this.app = app;
@@ -352,8 +361,34 @@
     return this.app.perfDebugging;
   }
 
-  mountStore<T>(id: string, migrate: Migrate<T>): Store<T> {
-    return this.store.createSubStore([id], migrate);
+  registerStorage<T>(descriptor: StorageDescriptor<T>): Storage<T> {
+    return new TraceStorage(this, descriptor);
+  }
+}
+
+class TraceStorage<T> implements Storage<T> {
+  private cache?: {rawValue: unknown; normalizedValue: T};
+
+  constructor(
+    private readonly trace: TraceImpl,
+    private readonly desc: StorageDescriptor<T>,
+  ) {}
+
+  get(): T {
+    const rawValue = this.trace.getStorageState(this.desc.id);
+    const cache = this.cache;
+    if (cache !== undefined && cache.rawValue === rawValue) {
+      return cache.normalizedValue;
+    }
+    const result = this.desc.schema.safeParse(rawValue);
+    const value = result.success ? result.data : this.desc.defaultValue;
+    const normalizedValue = deepFreeze(value);
+    this.cache = {rawValue, normalizedValue};
+    return normalizedValue;
+  }
+
+  set(newValue: T): void {
+    this.trace.setStorageState(this.desc.id, newValue);
   }
 }
 
diff --git a/ui/src/core/trace_stream.ts b/ui/src/core/trace_stream.ts
index 7bcfdd1..e0fe7c3 100644
--- a/ui/src/core/trace_stream.ts
+++ b/ui/src/core/trace_stream.ts
@@ -199,7 +199,7 @@
 
     let data;
     if (chunks.length === 1) {
-      data = chunks[0];
+      data = chunks[0]!;
     } else {
       // Stitch all the chunks into one big array:
       data = new Uint8Array(bytesRead);
@@ -268,7 +268,7 @@
   private stream: TraceFileStream;
 
   constructor(private traceFiles: ReadonlyArray<File>) {
-    this.stream = new TraceFileStream(traceFiles[this.index]);
+    this.stream = new TraceFileStream(traceFiles[this.index]!);
     this.bytesRead = 0;
     // The total size of the TAR archive is the sum of:
     // - 512 bytes for each file's header.
@@ -285,11 +285,11 @@
       case 'HEADER': {
         // Construct the 512-byte TAR header for the current file.
         const data = new Uint8Array(512);
-        const name = this.traceFiles[this.index].name;
+        const name = this.traceFiles[this.index]!.name;
         for (let i = 0; i < Math.min(name.length, 99); ++i) {
           data[i] = name.charCodeAt(i);
         }
-        const size = this.traceFiles[this.index].size.toString(8);
+        const size = this.traceFiles[this.index]!.size.toString(8);
         if (size.length >= 12) {
           throw new Error('Trace file size is too big to encode as tar file');
         }
@@ -347,7 +347,7 @@
         } else {
           // Otherwise, move to the HEADER state for the next file.
           this.state = {kind: 'HEADER'};
-          this.stream = new TraceFileStream(this.traceFiles[++this.index]);
+          this.stream = new TraceFileStream(this.traceFiles[++this.index]!);
         }
         if (lastBlockSize === 0) {
           // If the file size is a multiple of 512, no padding is needed.
diff --git a/ui/src/core_plugins/dev.perfetto.CoreCommands/legacy_macros_schema_unittest.ts b/ui/src/core_plugins/dev.perfetto.CoreCommands/legacy_macros_schema_unittest.ts
index bc3cc00..06cd28c 100644
--- a/ui/src/core_plugins/dev.perfetto.CoreCommands/legacy_macros_schema_unittest.ts
+++ b/ui/src/core_plugins/dev.perfetto.CoreCommands/legacy_macros_schema_unittest.ts
@@ -27,8 +27,8 @@
     const result = legacyMacrosConfigSchema.parse(input);
 
     expect(result['my-macro']).toHaveLength(2);
-    expect(result['my-macro'][0].id).toBe('dev.perfetto.RunQuery');
-    expect(result['my-macro'][0].args).toEqual(['SELECT * FROM slice']);
+    expect(result['my-macro']![0]!.id).toBe('dev.perfetto.RunQuery');
+    expect(result['my-macro']![0]!.args).toEqual(['SELECT * FROM slice']);
     expect(result['another-macro']).toHaveLength(1);
   });
 
diff --git a/ui/src/core_plugins/dev.perfetto.ExtensionServers/extension_server.ts b/ui/src/core_plugins/dev.perfetto.ExtensionServers/extension_server.ts
index 102204e..cbd963f 100644
--- a/ui/src/core_plugins/dev.perfetto.ExtensionServers/extension_server.ts
+++ b/ui/src/core_plugins/dev.perfetto.ExtensionServers/extension_server.ts
@@ -388,7 +388,7 @@
       const rs = await Promise.all(macrosPerMod);
       return rs.flatMap((r, i) => {
         if (!r.ok) return [];
-        const source = sourceLabel(m, server.enabledModules[i]);
+        const source = sourceLabel(m, server.enabledModules[i]!);
         return r.value.map((macro) => ({...macro, source}));
       });
     }),
diff --git a/ui/src/core_plugins/dev.perfetto.ExtensionServers/extension_server_unittest.ts b/ui/src/core_plugins/dev.perfetto.ExtensionServers/extension_server_unittest.ts
index ecade00..8dfffba 100644
--- a/ui/src/core_plugins/dev.perfetto.ExtensionServers/extension_server_unittest.ts
+++ b/ui/src/core_plugins/dev.perfetto.ExtensionServers/extension_server_unittest.ts
@@ -351,7 +351,7 @@
       expect(mockApp.addSqlPackages).toHaveBeenCalledTimes(1);
       expect(mockApp.addProtoDescriptors).toHaveBeenCalledTimes(1);
 
-      const macros = await mockApp.getMacrosAdded()[0];
+      const macros = await mockApp.getMacrosAdded()[0]!;
       expect(macros.map((m) => m.id).sort()).toEqual([
         'test.android1',
         'test.default1',
@@ -399,7 +399,7 @@
         testExtServer({enabledModules: ['default', 'android']}),
       ]);
 
-      const sqlPackages = await mockApp.getSqlPackagesAdded()[0];
+      const sqlPackages = await mockApp.getSqlPackagesAdded()[0]!;
       expect(sqlPackages).toHaveLength(1);
       expect(sqlPackages[0]?.name).toBe('test');
       expect(sqlPackages[0]?.modules.map((m) => m.name).sort()).toEqual([
@@ -434,7 +434,7 @@
       const mockApp = createMockAppImpl();
       initializeServers(mockApp as unknown as AppImpl, [testExtServer()]);
 
-      const sqlPackages = await mockApp.getSqlPackagesAdded()[0];
+      const sqlPackages = await mockApp.getSqlPackagesAdded()[0]!;
       expect(sqlPackages).toHaveLength(1);
       expect(sqlPackages[0]?.name).toBe('myext');
       expect(sqlPackages[0]?.modules).toHaveLength(2);
diff --git a/ui/src/core_plugins/dev.perfetto.ExtensionServers/index.ts b/ui/src/core_plugins/dev.perfetto.ExtensionServers/index.ts
index 439360f..ac99f39 100644
--- a/ui/src/core_plugins/dev.perfetto.ExtensionServers/index.ts
+++ b/ui/src/core_plugins/dev.perfetto.ExtensionServers/index.ts
@@ -164,7 +164,7 @@
 ): m.Children {
   const servers = setting.get();
   const shareServer = (index: number) => {
-    const server = servers[index];
+    const server = servers[index]!;
     const stripped = stripSecrets(server);
     const json = JSON.stringify(stripped);
     const b64 = base64Encode(utf8Encode(json));
@@ -179,8 +179,8 @@
   const toggleEnabled = (index: number) => {
     const newServers = [...servers];
     newServers[index] = {
-      ...newServers[index],
-      enabled: !newServers[index].enabled,
+      ...newServers[index]!,
+      enabled: !newServers[index]!.enabled,
     };
     setting.set(newServers);
   };
@@ -217,13 +217,13 @@
             [...servers.keys()]
               .sort((a, b) => {
                 const aManaged =
-                  servers[a].origin === 'embedder_managed' ? 0 : 1;
+                  servers[a]!.origin === 'embedder_managed' ? 0 : 1;
                 const bManaged =
-                  servers[b].origin === 'embedder_managed' ? 0 : 1;
+                  servers[b]!.origin === 'embedder_managed' ? 0 : 1;
                 return aManaged - bManaged || a - b;
               })
               .map((idx) => {
-                const server = servers[idx];
+                const server = servers[idx]!;
                 return m(
                   '.pf-extension-servers-settings__item',
                   {key: idx},
@@ -369,7 +369,7 @@
     // Server already configured — replace its enabled modules with those from
     // the shared link and open the edit modal so the user can review.
     await editServer(setting, dupIdx, {
-      ...servers[dupIdx],
+      ...servers[dupIdx]!,
       enabledModules: prefill.enabledModules,
     });
   } else {
diff --git a/ui/src/core_plugins/dev.perfetto.FlowEvents/flow_manager.ts b/ui/src/core_plugins/dev.perfetto.FlowEvents/flow_manager.ts
index fac8bca..0131429 100644
--- a/ui/src/core_plugins/dev.perfetto.FlowEvents/flow_manager.ts
+++ b/ui/src/core_plugins/dev.perfetto.FlowEvents/flow_manager.ts
@@ -638,5 +638,5 @@
       selectedFlowFound = true;
     }
   }
-  return boundFlows[0].id;
+  return boundFlows[0]!.id;
 }
diff --git a/ui/src/core_plugins/dev.perfetto.GlobalGroups/index.ts b/ui/src/core_plugins/dev.perfetto.GlobalGroups/index.ts
index fcaab5e..a5cbb45 100644
--- a/ui/src/core_plugins/dev.perfetto.GlobalGroups/index.ts
+++ b/ui/src/core_plugins/dev.perfetto.GlobalGroups/index.ts
@@ -22,8 +22,8 @@
     trace.onTraceReady.addListener(() => {
       // If there is only one group, expand it
       const rootLevelChildren = trace.defaultWorkspace.children;
-      if (rootLevelChildren.length === 1 && rootLevelChildren[0].hasChildren) {
-        rootLevelChildren[0].expand();
+      if (rootLevelChildren.length === 1 && rootLevelChildren[0]!.hasChildren) {
+        rootLevelChildren[0]!.expand();
       }
     });
   }
diff --git a/ui/src/core_plugins/dev.perfetto.MultiTraceOpen/multi_trace_controller.ts b/ui/src/core_plugins/dev.perfetto.MultiTraceOpen/multi_trace_controller.ts
index 2a12dd9..6f4d26d 100644
--- a/ui/src/core_plugins/dev.perfetto.MultiTraceOpen/multi_trace_controller.ts
+++ b/ui/src/core_plugins/dev.perfetto.MultiTraceOpen/multi_trace_controller.ts
@@ -451,7 +451,7 @@
     }
     const copy = [...this._traces];
     const [anchor] = copy.splice(idx, 1);
-    return [anchor, ...copy];
+    return [anchor!, ...copy];
   }
 
   private mergeFiles(): MergeFile[] {
diff --git a/ui/src/core_plugins/dev.perfetto.MultiTraceOpen/multi_trace_controller_unittest.ts b/ui/src/core_plugins/dev.perfetto.MultiTraceOpen/multi_trace_controller_unittest.ts
index 6278a69..ed690f0 100644
--- a/ui/src/core_plugins/dev.perfetto.MultiTraceOpen/multi_trace_controller_unittest.ts
+++ b/ui/src/core_plugins/dev.perfetto.MultiTraceOpen/multi_trace_controller_unittest.ts
@@ -138,8 +138,8 @@
 
       expect(controller.traces).toHaveLength(2);
       // Analysis starts immediately, so status should be 'analyzing'
-      expect(controller.traces[0].status).toBe('analyzing');
-      expect(controller.traces[1].status).toBe('analyzing');
+      expect(controller.traces[0]!.status).toBe('analyzing');
+      expect(controller.traces[1]!.status).toBe('analyzing');
       expect(onStateChanged).toHaveBeenCalled();
 
       // Wait for analysis to complete
@@ -152,8 +152,8 @@
       });
 
       // Now traces should be analyzed
-      expect(controller.traces[0].status).toBe('analyzed');
-      expect(controller.traces[1].status).toBe('analyzed');
+      expect(controller.traces[0]!.status).toBe('analyzed');
+      expect(controller.traces[1]!.status).toBe('analyzed');
     });
 
     it('should handle format error messages', async () => {
@@ -170,7 +170,7 @@
         onAnalysisCompleted.mockImplementation(() => resolve());
       });
 
-      const trace = controller.traces[0];
+      const trace = controller.traces[0]!;
       expect(trace.status).toBe('error');
       if (trace.status === 'error') {
         expect(trace.error).toContain("doesn't look like a Perfetto trace");
@@ -187,7 +187,7 @@
       controller.removeTrace('uuid1');
 
       expect(controller.traces).toHaveLength(1);
-      expect(controller.traces[0].uuid).toBe('uuid2');
+      expect(controller.traces[0]!.uuid).toBe('uuid2');
       expect(onStateChanged).toHaveBeenCalled();
     });
 
@@ -261,16 +261,16 @@
 
       controller.addFiles([file]);
       // Analysis starts immediately, so status should be 'analyzing'
-      expect(controller.traces[0].status).toBe('analyzing');
+      expect(controller.traces[0]!.status).toBe('analyzing');
 
       // Wait for async analysis to complete
       await new Promise<void>((resolve) => {
         onAnalysisCompleted.mockImplementation(() => resolve());
       });
 
-      expect(controller.traces[0].status).toBe('analyzed');
-      if (controller.traces[0].status === 'analyzed') {
-        expect(controller.traces[0].analysis.format).toBe('Perfetto');
+      expect(controller.traces[0]!.status).toBe('analyzed');
+      if (controller.traces[0]!.status === 'analyzed') {
+        expect(controller.traces[0]!.analysis.format).toBe('Perfetto');
       }
     });
 
@@ -280,16 +280,16 @@
 
       controller.addFiles([file]);
       // Analysis starts immediately, so status should be 'analyzing'
-      expect(controller.traces[0].status).toBe('analyzing');
+      expect(controller.traces[0]!.status).toBe('analyzing');
 
       // Wait for async analysis to complete
       await new Promise<void>((resolve) => {
         onAnalysisCompleted.mockImplementation(() => resolve());
       });
 
-      expect(controller.traces[0].status).toBe('error');
-      if (controller.traces[0].status === 'error') {
-        expect(controller.traces[0].error).toBe('Test analysis error');
+      expect(controller.traces[0]!.status).toBe('error');
+      if (controller.traces[0]!.status === 'error') {
+        expect(controller.traces[0]!.error).toBe('Test analysis error');
       }
     });
   });
diff --git a/ui/src/core_plugins/dev.perfetto.MultiTraceOpen/trace_analyzer.ts b/ui/src/core_plugins/dev.perfetto.MultiTraceOpen/trace_analyzer.ts
index 4bcd922..1ff895e 100644
--- a/ui/src/core_plugins/dev.perfetto.MultiTraceOpen/trace_analyzer.ts
+++ b/ui/src/core_plugins/dev.perfetto.MultiTraceOpen/trace_analyzer.ts
@@ -181,7 +181,7 @@
 
     const signals = await queryFileSignals(engine);
     return {
-      format: mapTraceType(leafNodes[0]),
+      format: mapTraceType(leafNodes[0]!),
       ...signals,
     };
   }
diff --git a/ui/src/core_plugins/dev.perfetto.SearchUtils/search_benchmark_page.ts b/ui/src/core_plugins/dev.perfetto.SearchUtils/search_benchmark_page.ts
index 0817eb5..b7faad5 100644
--- a/ui/src/core_plugins/dev.perfetto.SearchUtils/search_benchmark_page.ts
+++ b/ui/src/core_plugins/dev.perfetto.SearchUtils/search_benchmark_page.ts
@@ -400,9 +400,9 @@
     const results: SearchResultEvent[] = [];
     for (let i = 0; i < searchResults.totalResults; i++) {
       results.push({
-        id: searchResults.eventIds[i],
-        ts: searchResults.tses[i],
-        trackUri: searchResults.trackUris[i],
+        id: searchResults.eventIds[i]!,
+        ts: searchResults.tses[i]!,
+        trackUri: searchResults.trackUris[i]!,
       });
     }
 
diff --git a/ui/src/core_plugins/dev.perfetto.SearchUtils/search_results_tab.ts b/ui/src/core_plugins/dev.perfetto.SearchUtils/search_results_tab.ts
index d41aab7..2d44764 100644
--- a/ui/src/core_plugins/dev.perfetto.SearchUtils/search_results_tab.ts
+++ b/ui/src/core_plugins/dev.perfetto.SearchUtils/search_results_tab.ts
@@ -70,9 +70,9 @@
 
     if (searchResults) {
       for (let i = 0; i < searchResults.totalResults; i++) {
-        const eventId = searchResults.eventIds[i];
-        const ts = searchResults.tses[i];
-        const trackUri = searchResults.trackUris[i];
+        const eventId = searchResults.eventIds[i]!;
+        const ts = searchResults.tses[i]!;
+        const trackUri = searchResults.trackUris[i]!;
 
         rowData.push({
           id: eventId,
diff --git a/ui/src/core_plugins/dev.perfetto.SettingsPage/settings_page.ts b/ui/src/core_plugins/dev.perfetto.SettingsPage/settings_page.ts
index 53de6a9..98efca0 100644
--- a/ui/src/core_plugins/dev.perfetto.SettingsPage/settings_page.ts
+++ b/ui/src/core_plugins/dev.perfetto.SettingsPage/settings_page.ts
@@ -179,8 +179,8 @@
       this.filterText,
     ).map((res) => ({
       item: res.item,
-      nameSegments: res.segments[0],
-      descriptionSegments: res.segments[1],
+      nameSegments: res.segments[0]!,
+      descriptionSegments: res.segments[1]!,
     }));
   }
 
diff --git a/ui/src/core_plugins/dev.perfetto.Timeline/current_selection_tab.ts b/ui/src/core_plugins/dev.perfetto.Timeline/current_selection_tab.ts
index db35993..a816ff1 100644
--- a/ui/src/core_plugins/dev.perfetto.Timeline/current_selection_tab.ts
+++ b/ui/src/core_plugins/dev.perfetto.Timeline/current_selection_tab.ts
@@ -76,7 +76,7 @@
   // not available.
   const activeTab =
     tabs.find((tab) => tab.id === trace.selection.currentSelectionSubTab) ??
-    tabs[0];
+    tabs[0]!;
 
   // Determine if any tab content is loading
   const isLoading = tabs.some((tab) => tab.isLoading);
diff --git a/ui/src/core_plugins/dev.perfetto.Timeline/gridline_helper.ts b/ui/src/core_plugins/dev.perfetto.Timeline/gridline_helper.ts
index 4747d6b..6ac1867 100644
--- a/ui/src/core_plugins/dev.perfetto.Timeline/gridline_helper.ts
+++ b/ui/src/core_plugins/dev.perfetto.Timeline/gridline_helper.ts
@@ -155,7 +155,7 @@
   ) {
     if (time >= timeSpan.start) {
       patternIndex = patternIndex % tickPattern.length;
-      const type = tickPattern[patternIndex];
+      const type = tickPattern[patternIndex]!;
       yield {type, time: Time.add(time, offset)};
     }
   }
diff --git a/ui/src/core_plugins/dev.perfetto.Timeline/search_overview_track.ts b/ui/src/core_plugins/dev.perfetto.Timeline/search_overview_track.ts
index f6c27f6..0a6d21c 100644
--- a/ui/src/core_plugins/dev.perfetto.Timeline/search_overview_track.ts
+++ b/ui/src/core_plugins/dev.perfetto.Timeline/search_overview_track.ts
@@ -221,8 +221,8 @@
     if (!this.searchSummary) return;
 
     for (let i = 0; i < this.searchSummary.tsStarts.length; i++) {
-      const tStart = Time.fromRaw(this.searchSummary.tsStarts[i]);
-      const tEnd = Time.fromRaw(this.searchSummary.tsEnds[i]);
+      const tStart = Time.fromRaw(this.searchSummary.tsStarts[i]!);
+      const tEnd = Time.fromRaw(this.searchSummary.tsEnds[i]!);
       if (!visibleWindow.overlaps(tStart, tEnd)) {
         continue;
       }
@@ -245,7 +245,7 @@
       const start = results.tses[index];
       if (start !== -1n) {
         const triangleStart = Math.max(
-          timescale.timeToPx(Time.fromRaw(start)),
+          timescale.timeToPx(Time.fromRaw(start)!),
           0,
         );
         ctx.fillStyle = '#000';
diff --git a/ui/src/core_plugins/dev.perfetto.Timeline/track_tree_view.ts b/ui/src/core_plugins/dev.perfetto.Timeline/track_tree_view.ts
index 25bc1b2..97967d3 100644
--- a/ui/src/core_plugins/dev.perfetto.Timeline/track_tree_view.ts
+++ b/ui/src/core_plugins/dev.perfetto.Timeline/track_tree_view.ts
@@ -121,7 +121,7 @@
   ctx.fillRect(0, 0, 1, 1);
   const imageData = ctx.getImageData(0, 0, 1, 1);
   const [r, g, b, a] = imageData.data;
-  const packed = ((r << 24) | (g << 16) | (b << 8) | a) >>> 0;
+  const packed = ((r! << 24) | (g! << 16) | (b! << 8) | a!) >>> 0;
 
   cssColorCache.set(cssColor, packed);
   return packed;
@@ -529,8 +529,8 @@
     const gridColor = cssColorToRgba(COLOR_BORDER_SECONDARY);
 
     for (let i = 0; i < count; i++) {
-      starts[i] = tickPositions[i];
-      ends[i] = tickPositions[i] + 1;
+      starts[i] = tickPositions[i]!;
+      ends[i] = tickPositions[i]! + 1;
       colors[i] = gridColor;
       patterns[i] = 0;
       depths[i] = 0;
diff --git a/ui/src/core_plugins/dev.perfetto.Timeline/track_view.ts b/ui/src/core_plugins/dev.perfetto.Timeline/track_view.ts
index 73f598a..e7eb2f1 100644
--- a/ui/src/core_plugins/dev.perfetto.Timeline/track_view.ts
+++ b/ui/src/core_plugins/dev.perfetto.Timeline/track_view.ts
@@ -459,7 +459,7 @@
 
     if (searchIndex !== -1 && searchResults !== undefined) {
       // using _ = autoTimer();
-      const uri = searchResults.trackUris[searchIndex];
+      const uri = searchResults.trackUris[searchIndex]!;
       // Highlight if this or any children match the search results
       if (uri === node.uri || node.getTrackByUri(uri)) {
         return true;
diff --git a/ui/src/engine_bench/index.ts b/ui/src/engine_bench/index.ts
index a33b0b4..c68c423 100644
--- a/ui/src/engine_bench/index.ts
+++ b/ui/src/engine_bench/index.ts
@@ -108,19 +108,19 @@
     sorted.length - 1,
     Math.max(0, Math.floor((p / 100) * sorted.length)),
   );
-  return sorted[idx];
+  return sorted[idx]!;
 }
 
 function summarise(samples: Sample[]): Partial<Record<Phase, Stats>> {
   const out: Partial<Record<Phase, Stats>> = {};
   if (samples.length === 0) return out;
-  for (const k of Object.keys(samples[0]) as Phase[]) {
+  for (const k of Object.keys(samples[0]!) as Phase[]) {
     const vals = samples.map((s) => s[k]).sort((a, b) => a - b);
     out[k] = {
-      min: vals[0],
+      min: vals[0]!,
       p50: percentile(vals, 50),
       p95: percentile(vals, 95),
-      max: vals[vals.length - 1],
+      max: vals[vals.length - 1]!,
       mean: vals.reduce((a, b) => a + b, 0) / vals.length,
     };
   }
diff --git a/ui/src/frontend/android_bug_tool.ts b/ui/src/frontend/android_bug_tool.ts
index 954e5da..f442493 100644
--- a/ui/src/frontend/android_bug_tool.ts
+++ b/ui/src/frontend/android_bug_tool.ts
@@ -69,7 +69,7 @@
             deferred.resolve({
               issueId: response.issueId,
               issueTitle: response.issueTitle,
-              file: files[0],
+              file: files[0]!,
             });
           } else {
             throw new Error('ABT: Got no attachments from extension');
diff --git a/ui/src/frontend/error_dialog.ts b/ui/src/frontend/error_dialog.ts
index e09cdab..cef3d5f 100644
--- a/ui/src/frontend/error_dialog.ts
+++ b/ui/src/frontend/error_dialog.ts
@@ -297,7 +297,7 @@
   }
 
   private fileBug(err: ErrorDetails) {
-    const errTitle = err.message.split('\n', 1)[0].substring(0, 80);
+    const errTitle = err.message.split('\n', 1)[0]!.substring(0, 80);
     let url = 'https://goto.google.com/perfetto-ui-bug';
     url += '?title=' + encodeURIComponent(`UI Error: ${errTitle}`);
     url += '&description=';
@@ -420,7 +420,7 @@
   let inner = message.replace(/^Trace parse failure: /, '');
   const legacy = /^Trace parse failure \((.*)\) \(ERR:tp-parse\)/s.exec(inner);
   if (legacy) {
-    inner = legacy[1];
+    inner = legacy[1]!;
   }
   return inner.replace(/\s*\(ERR:tp-(?:corrupt|parse)\)/g, '').trim();
 }
diff --git a/ui/src/frontend/omnibox.ts b/ui/src/frontend/omnibox.ts
index e1db2d5..1e84fdc 100644
--- a/ui/src/frontend/omnibox.ts
+++ b/ui/src/frontend/omnibox.ts
@@ -131,8 +131,8 @@
       searchTerm,
     ).map((result) => {
       return {
-        segments: result.segments[0],
-        sourceSegments: result.item.source ? result.segments[1] : undefined,
+        segments: result.segments[0]!,
+        sourceSegments: result.item.source ? result.segments[1]! : undefined,
         ...result.item,
       };
     });
@@ -566,13 +566,7 @@
                   e.preventDefault();
 
                   const option = options[selectedOptionIndex];
-                  // Return values from indexing arrays can be undefined.
-                  // We should enable noUncheckedIndexedAccess in
-                  // tsconfig.json.
-                  /* eslint-disable
-                      @typescript-eslint/strict-boolean-expressions */
                   if (option) {
-                    /* eslint-enable */
                     closeOnSubmit && this.close(attrs);
 
                     const mod = e.metaKey || e.ctrlKey;
diff --git a/ui/src/frontend/task_tracker/task_tracker_unittest.ts b/ui/src/frontend/task_tracker/task_tracker_unittest.ts
index 7a2d720..8ebdc42 100644
--- a/ui/src/frontend/task_tracker/task_tracker_unittest.ts
+++ b/ui/src/frontend/task_tracker/task_tracker_unittest.ts
@@ -75,15 +75,15 @@
 
     const tasks = tracker.tasks;
     expect(tasks).toHaveLength(1);
-    expect(tasks[0].label).toBe('my task');
-    expect(tasks[0].elapsed).toBeGreaterThanOrEqual(0);
+    expect(tasks[0]!.label).toBe('my task');
+    expect(tasks[0]!.elapsed).toBeGreaterThanOrEqual(0);
   });
 
   test('uses anonymous label by default', () => {
     const deferred = defer<void>();
     tracker.track(deferred);
 
-    expect(tracker.tasks[0].label).toBe('anonymous');
+    expect(tracker.tasks[0]!.label).toBe('anonymous');
   });
 
   test('can track multiple promises', () => {
diff --git a/ui/src/frontend/topbar.ts b/ui/src/frontend/topbar.ts
index 88e090c..8392f8a 100644
--- a/ui/src/frontend/topbar.ts
+++ b/ui/src/frontend/topbar.ts
@@ -91,7 +91,7 @@
       } else {
         // If no tab is open, show the first registered one.
         if (!mgr.currentTabUri && mgr.registeredTabs.length > 0) {
-          mgr.showTab(mgr.registeredTabs[0].uri);
+          mgr.showTab(mgr.registeredTabs[0]!.uri);
         } else {
           mgr.visible = true;
         }
diff --git a/ui/src/frontend/trace_actions.ts b/ui/src/frontend/trace_actions.ts
index b51d3d2..93a5969 100644
--- a/ui/src/frontend/trace_actions.ts
+++ b/ui/src/frontend/trace_actions.ts
@@ -86,7 +86,7 @@
       },
     });
   } else if (src.type === 'URL') {
-    const fileName = src.url.split('/').slice(-1)[0];
+    const fileName = src.url.split('/').slice(-1)[0]!;
     downloadUrl({url: src.url, fileName});
   } else if (src.type === 'ARRAY_BUFFER') {
     const blob = new Blob([src.buffer], {type: 'application/octet-stream'});
diff --git a/ui/src/frontend/ui_main.ts b/ui/src/frontend/ui_main.ts
index 7ad231f..a47d4cd 100644
--- a/ui/src/frontend/ui_main.ts
+++ b/ui/src/frontend/ui_main.ts
@@ -77,7 +77,9 @@
       ),
       m(CookieConsent),
       maybeRenderFullscreenModalDialog(),
-      showStatusBarFlag.get() && renderStatusBar(app),
+      showStatusBarFlag.get() &&
+        !app.initialRouteArgs.hideStatusbar &&
+        renderStatusBar(app),
       app.perfDebugging.renderPerfStats(),
     ]);
   }
diff --git a/ui/src/frontend/value.ts b/ui/src/frontend/value.ts
index cebc1e3..b082ad6 100644
--- a/ui/src/frontend/value.ts
+++ b/ui/src/frontend/value.ts
@@ -157,7 +157,7 @@
   } else if (isDict(value)) {
     const nodes: m.Children[] = [];
     for (const key of Object.keys(value.items)) {
-      nodes.push(renderValue(key, value.items[key]));
+      nodes.push(renderValue(key, value.items[key]!));
     }
     return m(TreeNode, {left, right: `dict`}, nodes);
   } else {
@@ -188,7 +188,7 @@
 export function renderDict(dict: Dict): m.Child {
   const rows: m.Children[] = [];
   for (const key of Object.keys(dict.items)) {
-    rows.push(renderValue(key, dict.items[key]));
+    rows.push(renderValue(key, dict.items[key]!));
   }
   return m(Tree, rows);
 }
diff --git a/ui/src/plugins/com.android.AndroidBinderViz/index.ts b/ui/src/plugins/com.android.AndroidBinderViz/index.ts
index 7ac9649..aca9d5b 100644
--- a/ui/src/plugins/com.android.AndroidBinderViz/index.ts
+++ b/ui/src/plugins/com.android.AndroidBinderViz/index.ts
@@ -61,7 +61,7 @@
     description: string,
   ): Promise<TrackNode> {
     // The titles live under a "Binder" group, so drop the redundant prefix.
-    const sideName = perspective[0].toUpperCase() + perspective.slice(1);
+    const sideName = perspective[0]!.toUpperCase() + perspective.slice(1);
     const binderCounterBreakdowns = new BreakdownTracks({
       trace: ctx,
       trackTitle: `${sideName} Transaction Counts`,
diff --git a/ui/src/plugins/com.android.AndroidGpu/index.ts b/ui/src/plugins/com.android.AndroidGpu/index.ts
index 5036bd4..b2a23ad 100644
--- a/ui/src/plugins/com.android.AndroidGpu/index.ts
+++ b/ui/src/plugins/com.android.AndroidGpu/index.ts
@@ -40,7 +40,7 @@
     for (const track of gpuCounterTracks) {
       const trackIds = track.tags?.trackIds;
       if (trackIds === undefined || trackIds.length !== 1) continue;
-      const trackId = trackIds[0];
+      const trackId = trackIds[0]!;
 
       const name = String(track.tags?.name ?? '');
       const unit = String(track.tags?.unit ?? '');
diff --git a/ui/src/plugins/com.android.AndroidInputLifecycle/android_input_event_source.ts b/ui/src/plugins/com.android.AndroidInputLifecycle/android_input_event_source.ts
index 79ac02b..c83b41b 100644
--- a/ui/src/plugins/com.android.AndroidInputLifecycle/android_input_event_source.ts
+++ b/ui/src/plugins/com.android.AndroidInputLifecycle/android_input_event_source.ts
@@ -59,6 +59,7 @@
   use(sliceId: number): AsyncMemoResult<InputChainRow[]> {
     return this.dataSlot.use({
       key: {sliceId},
+      retainOn: ['sliceId'],
       compute: async () => {
         const resolvedSliceId = await this.resolveSliceId(sliceId);
         const rows = await this.fetchRows(resolvedSliceId);
diff --git a/ui/src/plugins/com.android.AndroidInputLifecycle/index.ts b/ui/src/plugins/com.android.AndroidInputLifecycle/index.ts
index 283e59d..ba3d320 100644
--- a/ui/src/plugins/com.android.AndroidInputLifecycle/index.ts
+++ b/ui/src/plugins/com.android.AndroidInputLifecycle/index.ts
@@ -47,7 +47,8 @@
   static readonly id = 'com.android.AndroidInputLifecycle';
   static readonly description =
     'Visualise connected input events in the lifecycle from touch to frame, ' +
-    "with latencies for the various input stages. Activate by running the command 'Android: View Input Lifecycle'.";
+    'with latencies for the various input stages. Select any slice in the ' +
+    'input pipeline to draw arrows and show the Input Lifecycle tab.';
 
   private static extensionSettings = new Map<string, Setting<boolean>>();
 
@@ -100,41 +101,24 @@
       new RelatedEventsOverlay(trace, () => this.getConnections(trace, source)),
     );
 
-    trace.tabs.registerTab({
-      uri: 'com.android.AndroidInputLifecycleTab',
-      isEphemeral: false,
-      content: {
-        getTitle: () => 'Android Input Lifecycle',
-        render: () => {
-          const {data: rows, isPending} = this.useRowState(trace, source);
-
-          if (rows) {
-            this.applyInitialSelection(trace, rows);
-          }
-
-          return m(AndroidInputLifecycleTab, {
+    trace.selection.registerTrackEventSelectionTab({
+      id: 'android_input_lifecycle',
+      name: 'Input Lifecycle',
+      render: () => {
+        const {data: rows, isPending} = this.useRows(trace, source);
+        if (!rows || rows.length === 0) return undefined;
+        return {
+          isLoading: isPending,
+          content: m(AndroidInputLifecycleTab, {
             trace,
-            rows: rows ?? [],
+            rows,
             visibleRowIds: this.visibleRowIds,
-            loading: isPending,
             pinningManager,
             onToggleVisibility: (rowId) => this.toggleVisibility(rowId),
-            onToggleAllVisibility: () => this.toggleAllVisibility(rows ?? []),
+            onToggleAllVisibility: () => this.toggleAllVisibility(rows),
             activeExtensions,
-          });
-        },
-      },
-      onHide: () => {
-        this.visibleRowIds.clear();
-        this.lastAppliedEventId = undefined;
-      },
-    });
-
-    trace.commands.registerCommand({
-      id: 'com.android.openAndroidInputLifecycleTab',
-      name: 'Android: View Input Lifecycle',
-      callback: () => {
-        trace.tabs.showTab('com.android.AndroidInputLifecycleTab');
+          }),
+        };
       },
     });
 
@@ -231,42 +215,35 @@
   // Fetch or reuse cached row data for the currently selected slice. Can call
   // this function every render cycle without performance concerns, as the
   // underlying data slot will ensure the query is only executed once per
-  // sliceId.
-  private useRowState(
+  // sliceId. On first load for a given selection, the row containing the
+  // selected slice is made visible so that its arrows are drawn.
+  private useRows(
     trace: Trace,
     source: AndroidInputEventSource,
   ): AsyncMemoResult<InputChainRow[]> {
     const selection = trace.selection.selection;
-
-    if (selection.kind !== 'track_event') {
+    if (
+      selection.kind !== 'track_event' ||
+      trace.tracks.getTrack(selection.trackUri)?.renderer.rootTableName !==
+        'slice'
+    ) {
+      this.lastAppliedEventId = undefined;
+      this.visibleRowIds.clear();
       return {data: [], isPending: false};
     }
 
-    return source.use(selection.eventId);
-  }
-
-  private applyInitialSelection(trace: Trace, rows: InputChainRow[]) {
-    const selection = trace.selection.selection;
-    if (selection.kind !== 'track_event') return;
-
-    const eventId = selection.eventId;
-    if (this.lastAppliedEventId === eventId) return;
-
-    this.lastAppliedEventId = eventId;
-    this.visibleRowIds.clear();
-
-    for (const row of rows) {
-      const ids: number[] = [];
-      for (const stageData of row.stagesData.values()) {
-        if (stageData.nav) {
-          ids.push(stageData.nav.id);
-        }
-      }
-      if (ids.includes(eventId)) {
-        this.visibleRowIds.add(row.uiRowId);
-        break;
-      }
+    const result = source.use(selection.eventId);
+    if (!result.isPending && this.lastAppliedEventId !== selection.eventId) {
+      this.lastAppliedEventId = selection.eventId;
+      this.visibleRowIds.clear();
+      const row = result.data.find((r) =>
+        Array.from(r.stagesData.values()).some(
+          (s) => s.nav?.id === selection.eventId,
+        ),
+      );
+      if (row) this.visibleRowIds.add(row.uiRowId);
     }
+    return result;
   }
 
   private getConnections(
@@ -274,7 +251,7 @@
     source: AndroidInputEventSource,
   ): ArrowConnection[] {
     const connections: ArrowConnection[] = [...this.allEventConnections];
-    const {data: rows} = this.useRowState(trace, source);
+    const {data: rows} = this.useRows(trace, source);
     if (!rows) return connections;
 
     const visibleRows = rows.filter((r) => this.visibleRowIds.has(r.uiRowId));
@@ -331,8 +308,8 @@
       }
 
       for (let i = 0; i < steps.length - 1; i++) {
-        const start = steps[i];
-        const end = steps[i + 1];
+        const start = steps[i]!;
+        const end = steps[i + 1]!;
         connections.push({
           start: {
             trackUri: start.trackUri,
diff --git a/ui/src/plugins/com.android.AndroidInputLifecycle/tab.ts b/ui/src/plugins/com.android.AndroidInputLifecycle/tab.ts
index 89b6a44..62eb02b 100644
--- a/ui/src/plugins/com.android.AndroidInputLifecycle/tab.ts
+++ b/ui/src/plugins/com.android.AndroidInputLifecycle/tab.ts
@@ -27,9 +27,6 @@
 import type {Trace} from '../../public/trace';
 import {Anchor} from '../../widgets/anchor';
 import {Checkbox} from '../../widgets/checkbox';
-import {EmptyState} from '../../widgets/empty_state';
-import {DetailsShell} from '../../widgets/details_shell';
-import {Spinner} from '../../widgets/spinner';
 
 import {
   AndroidInputEventSource,
@@ -38,44 +35,17 @@
 import type {InputLifecycleExtension, NavTarget} from './extensions/interface';
 
 export interface AndroidInputLifecycleTabAttrs {
-  trace: Trace;
-  rows: InputChainRow[];
-  visibleRowIds: Set<string>;
-  loading: boolean;
-  pinningManager: TrackPinningManager;
-  onToggleVisibility: (rowId: string) => void;
-  onToggleAllVisibility: () => void;
-  activeExtensions: InputLifecycleExtension[];
+  readonly trace: Trace;
+  readonly rows: ReadonlyArray<InputChainRow>;
+  readonly visibleRowIds: ReadonlySet<string>;
+  readonly pinningManager: TrackPinningManager;
+  readonly onToggleVisibility: (rowId: string) => void;
+  readonly onToggleAllVisibility: () => void;
+  readonly activeExtensions: ReadonlyArray<InputLifecycleExtension>;
 }
 
 export class AndroidInputLifecycleTab implements m.ClassComponent<AndroidInputLifecycleTabAttrs> {
   view({attrs}: m.Vnode<AndroidInputLifecycleTabAttrs>): m.Children {
-    if (attrs.loading) {
-      return m(
-        DetailsShell,
-        {title: 'Android Input Lifecycle'},
-        m(
-          'div',
-          {
-            style: {
-              display: 'flex',
-              justifyContent: 'center',
-              padding: '20px',
-            },
-          },
-          m(Spinner, {}),
-        ),
-      );
-    }
-
-    return m(
-      DetailsShell,
-      {title: 'Android Input Lifecycle'},
-      this.renderGrid(attrs),
-    );
-  }
-
-  private renderGrid(attrs: AndroidInputLifecycleTabAttrs): m.Children {
     const {rows, visibleRowIds, trace, pinningManager} = attrs;
     const allVisible =
       rows.length > 0 && rows.every((r) => visibleRowIds.has(r.uiRowId));
@@ -153,11 +123,6 @@
 
         return [...fixedCells, ...stageCells];
       }),
-      emptyState: m(EmptyState, {
-        title: 'No input event selected',
-        description: 'Select an input event to see latency breakdown.',
-        icon: Icons.Android,
-      }),
     });
   }
 }
diff --git a/ui/src/plugins/com.android.AndroidLockContention/index.ts b/ui/src/plugins/com.android.AndroidLockContention/index.ts
index 3e456f6..7675c7e 100644
--- a/ui/src/plugins/com.android.AndroidLockContention/index.ts
+++ b/ui/src/plugins/com.android.AndroidLockContention/index.ts
@@ -395,7 +395,7 @@
           start: {
             trackUri: trackUri,
             ts: Time.fromRaw(middleTs),
-            depth: targets[0].depth,
+            depth: targets[0]!.depth,
           },
           end: {
             trackUri: ownerTrackUri,
diff --git a/ui/src/plugins/com.android.AndroidLockContention/lock_owner_details_panel.ts b/ui/src/plugins/com.android.AndroidLockContention/lock_owner_details_panel.ts
index 2248c06..198d912 100644
--- a/ui/src/plugins/com.android.AndroidLockContention/lock_owner_details_panel.ts
+++ b/ui/src/plugins/com.android.AndroidLockContention/lock_owner_details_panel.ts
@@ -187,7 +187,7 @@
     const {trace, plugin, rows, monitorThreadStates, monitorBlockedFunctions} =
       attrs;
 
-    const ownerTid = rows.length > 0 ? rows[0].blockingThreadTid : undefined;
+    const ownerTid = rows.length > 0 ? rows[0]!.blockingThreadTid : undefined;
     const customTrackUri =
       ownerTid !== undefined && ownerTid !== null
         ? `com.android.AndroidLockContention#OwnerEvents_Counter_${ownerTid}`
@@ -196,7 +196,7 @@
       ? plugin.pinningManager.isTrackPinned(customTrackUri)
       : false;
 
-    const threadTrackUri = rows.length > 0 ? rows[0].ownerTrackUri : undefined;
+    const threadTrackUri = rows.length > 0 ? rows[0]!.ownerTrackUri : undefined;
     const isThreadPinned = threadTrackUri
       ? plugin.pinningManager.isTrackPinned(threadTrackUri)
       : false;
diff --git a/ui/src/plugins/com.android.AndroidLog/index.ts b/ui/src/plugins/com.android.AndroidLog/index.ts
index d36efa4..22fcf96 100644
--- a/ui/src/plugins/com.android.AndroidLog/index.ts
+++ b/ui/src/plugins/com.android.AndroidLog/index.ts
@@ -16,8 +16,8 @@
 import m from 'mithril';
 import {createAggregationTab} from '../../components/aggregation_adapter';
 import {
-  type LogFilteringCriteria,
   type LogPanelCache,
+  LOG_FILTERING_CRITERIA_SCHEMA,
   LogPanel,
 } from './logs_panel';
 import {ANDROID_LOGS_TRACK_KIND} from '../../public/track_kinds';
@@ -26,33 +26,18 @@
 import type {Engine} from '../../trace_processor/engine';
 import {NUM, NUM_NULL, STR_NULL} from '../../trace_processor/query_result';
 import {createPerProcessLogTrack, createPerThreadLogTrack} from './logs_track';
-import {exists} from '../../base/utils';
 import {TrackNode} from '../../public/workspace';
 import {escapeSearchQuery} from '../../trace_processor/query_utils';
 import {Anchor} from '../../widgets/anchor';
 import {Icons} from '../../base/semantic_icons';
 import {AndroidLogSelectionAggregator} from './log_selection_aggregator';
+import {z} from 'zod';
 import {getMachineCount, maybeMachineLabel} from '../../public/utils';
 
-const VERSION = 1;
-
-const DEFAULT_STATE: AndroidLogPluginState = {
-  version: VERSION,
-  filter: {
-    // The first two log priorities are ignored.
-    minimumLevel: 2,
-    tags: [],
-    isTagRegex: false,
-    textEntry: '',
-    hideNonMatching: true,
-    machineExcludeList: [],
-  },
-};
-
-interface AndroidLogPluginState {
-  version: number;
-  filter: LogFilteringCriteria;
-}
+export const ANDROID_LOG_STATE_SCHEMA = z.object({
+  version: z.literal(1),
+  filter: LOG_FILTERING_CRITERIA_SCHEMA,
+});
 
 async function getMachines(engine: Engine): Promise<LogPanelCache> {
   // A machine might not provide Android logs, even if configured to do so.
@@ -114,14 +99,6 @@
   static readonly id = 'com.android.AndroidLog';
   async onTraceLoad(ctx: Trace): Promise<void> {
     const numMachines = await getMachineCount(ctx.engine);
-    const store = ctx.mountStore<AndroidLogPluginState>(
-      'com.android.AndroidLogFilterState',
-      (init) => {
-        return exists(init) && (init as {version: unknown}).version === VERSION
-          ? (init as AndroidLogPluginState)
-          : DEFAULT_STATE;
-      },
-    );
 
     const result = await ctx.engine.query(
       `select count(1) as cnt from android_logs`,
@@ -297,10 +274,22 @@
     const androidLogsTabUri = 'perfetto.AndroidLog#tab';
 
     // Eternal tabs should always be available even if there is nothing to show
-    const filterStore = store.createSubStore(
-      ['filter'],
-      (x) => x as LogFilteringCriteria,
-    );
+    const storage = ctx.registerStorage({
+      id: 'com.android.AndroidLogFilterState',
+      schema: ANDROID_LOG_STATE_SCHEMA,
+      defaultValue: {
+        version: 1,
+        filter: {
+          // The first two log priorities are ignored.
+          minimumLevel: 2,
+          tags: [],
+          isTagRegex: false,
+          textEntry: '',
+          hideNonMatching: true,
+          machineExcludeList: [],
+        },
+      },
+    });
 
     const cache = await getMachines(ctx.engine);
 
@@ -308,7 +297,13 @@
       isEphemeral: false,
       uri: androidLogsTabUri,
       content: {
-        render: () => m(LogPanel, {filterStore, cache, trace: ctx}),
+        render: () =>
+          m(LogPanel, {
+            trace: ctx,
+            cache,
+            filter: storage.get().filter,
+            onFilterChange: (filter) => storage.set({...storage.get(), filter}),
+          }),
         getTitle: () => 'Android Logs',
       },
     });
diff --git a/ui/src/plugins/com.android.AndroidLog/logs_panel.ts b/ui/src/plugins/com.android.AndroidLog/logs_panel.ts
index 51bd81d..0d51e1b 100644
--- a/ui/src/plugins/com.android.AndroidLog/logs_panel.ts
+++ b/ui/src/plugins/com.android.AndroidLog/logs_panel.ts
@@ -41,22 +41,26 @@
 } from '../../widgets/grid';
 import {classNames} from '../../base/classnames';
 import {TagInput} from '../../widgets/tag_input';
-import type {Store} from '../../base/store';
 import type {Trace} from '../../public/trace';
 import {Icons} from '../../base/semantic_icons';
 import {MenuItem} from '../../widgets/menu';
 import {AtomicTaskQueue, AsyncMemo} from '../../base/async_memo';
+import {z} from 'zod';
 
 const ROW_H = 24;
 
-export interface LogFilteringCriteria {
-  readonly minimumLevel: number;
-  readonly tags: string[];
-  readonly isTagRegex?: boolean;
-  readonly textEntry: string;
-  readonly hideNonMatching: boolean;
-  readonly machineExcludeList: number[];
-}
+export const LOG_FILTERING_CRITERIA_SCHEMA = z.object({
+  minimumLevel: z.number(),
+  tags: z.array(z.string()),
+  isTagRegex: z.boolean().optional(),
+  textEntry: z.string(),
+  hideNonMatching: z.boolean(),
+  machineExcludeList: z.array(z.number()),
+});
+
+export type LogFilteringCriteria = z.infer<
+  typeof LOG_FILTERING_CRITERIA_SCHEMA
+>;
 
 export interface LogPanelCache {
   readonly uniqueMachineIds: number[];
@@ -64,9 +68,10 @@
 }
 
 export interface LogPanelAttrs {
-  readonly cache: LogPanelCache;
-  readonly filterStore: Store<LogFilteringCriteria>;
   readonly trace: Trace;
+  readonly cache: LogPanelCache;
+  readonly filter: LogFilteringCriteria;
+  readonly onFilterChange: (filter: LogFilteringCriteria) => void;
 }
 
 interface Pagination {
@@ -110,7 +115,7 @@
 
   view({attrs}: m.CVnode<LogPanelAttrs>) {
     const visibleSpan = attrs.trace.timeline.visibleWindow.toTimeSpan();
-    const filters = attrs.filterStore.state;
+    const filters = attrs.filter;
     const pagination = this.pagination;
     const engine = attrs.trace.engine;
 
@@ -143,7 +148,8 @@
         buttons: m(LogsFilters, {
           trace: attrs.trace,
           cache: attrs.cache,
-          store: attrs.filterStore,
+          filter: attrs.filter,
+          onFilterChange: attrs.onFilterChange,
         }),
       },
       this.renderGrid(attrs.trace, entries, attrs.cache),
@@ -237,10 +243,10 @@
 
     const rows: GridRow[] = [];
     for (let i = 0; i < entries.timestamps.length; i++) {
-      const priority = priorities[i];
-      const priorityLetter = LOG_PRIORITIES[priority][0];
-      const ts = timestamps[i];
-      const eventId = ids[i];
+      const priority = priorities[i]!;
+      const priorityLetter = LOG_PRIORITIES[priority]![0];
+      const ts = timestamps[i]!;
+      const eventId = ids[i]!;
       const priorityClass = `pf-logs-panel__row--${classForPriority(priority)}`;
       const isHighlighted = entries.isHighlighted[i];
       const className = classNames(
@@ -253,7 +259,7 @@
           m(
             GridCell,
             {className, align: 'right'},
-            machineNames.get(machineIds[i]) ?? machineIds[i],
+            machineNames.get(machineIds[i]!) ?? machineIds[i],
           ),
         m(
           GridCell,
@@ -390,63 +396,71 @@
 interface LogsFiltersAttrs {
   readonly trace: Trace;
   readonly cache: LogPanelCache;
-  readonly store: Store<LogFilteringCriteria>;
+  readonly filter: LogFilteringCriteria;
+  readonly onFilterChange: (filter: LogFilteringCriteria) => void;
 }
 
 export class LogsFilters implements m.ClassComponent<LogsFiltersAttrs> {
   view({attrs}: m.CVnode<LogsFiltersAttrs>) {
     const hasMachineIds = attrs.cache.uniqueMachineIds.length > 1;
+    const filterState = attrs.filter;
 
     return [
       m('span', 'Log Level'),
       m(LogPriorityWidget, {
         trace: attrs.trace,
         options: LOG_PRIORITIES,
-        selectedIndex: attrs.store.state.minimumLevel,
+        selectedIndex: filterState.minimumLevel,
         onSelect: (minimumLevel) => {
-          attrs.store.edit((draft) => {
-            draft.minimumLevel = minimumLevel;
+          attrs.onFilterChange({
+            ...attrs.filter,
+            minimumLevel,
           });
         },
       }),
       m(TagInput, {
         leftIcon: 'label',
         placeholder: 'Filter by tag...',
-        tags: attrs.store.state.tags,
+        tags: filterState.tags,
         onTagAdd: (tag) => {
-          attrs.store.edit((draft) => {
-            draft.tags.push(tag);
+          attrs.onFilterChange({
+            ...attrs.filter,
+            tags: [...attrs.filter.tags, tag],
           });
         },
         onTagRemove: (index) => {
-          attrs.store.edit((draft) => {
-            draft.tags.splice(index, 1);
+          attrs.onFilterChange({
+            ...attrs.filter,
+            tags: attrs.filter.tags.filter((_, i) => i !== index),
           });
         },
       }),
       m(Button, {
         icon: 'regular_expression',
         tooltip: 'Use regex',
-        active: !!attrs.store.state.isTagRegex,
+        active: !!filterState.isTagRegex,
         onclick: () => {
-          attrs.store.edit((draft) => {
-            draft.isTagRegex = !draft.isTagRegex;
+          attrs.onFilterChange({
+            ...attrs.filter,
+            isTagRegex: !attrs.filter.isTagRegex,
           });
         },
       }),
       m(LogTextWidget, {
         trace: attrs.trace,
         onChange: (text) => {
-          attrs.store.edit((draft) => {
-            draft.textEntry = text;
+          attrs.onFilterChange({
+            ...attrs.filter,
+            textEntry: text,
           });
         },
       }),
       m(FilterByTextWidget, {
-        hideNonMatching: attrs.store.state.hideNonMatching,
+        hideNonMatching: filterState.hideNonMatching,
         onClick: () => {
-          attrs.store.edit((draft) => {
-            draft.hideNonMatching = !draft.hideNonMatching;
+          attrs.onFilterChange({
+            ...attrs.filter,
+            hideNonMatching: !attrs.filter.hideNonMatching,
           });
         },
       }),
@@ -455,7 +469,7 @@
   }
 
   private renderFilterPanel(attrs: LogsFiltersAttrs) {
-    const machineExcludeList = attrs.store.state.machineExcludeList;
+    const machineExcludeList = attrs.filter.machineExcludeList;
     const options: MultiSelectOption[] = attrs.cache.uniqueMachineIds.map(
       (uMachineId) => {
         return {
@@ -475,7 +489,7 @@
       position: PopupPosition.Top,
       options,
       onChange: (diffs: MultiSelectDiff[]) => {
-        const newList = new Set<number>(machineExcludeList);
+        const newList = new Set<number>(attrs.filter.machineExcludeList);
         diffs.forEach(({checked, id}) => {
           const machineId = Number(id);
           if (checked) {
@@ -484,8 +498,9 @@
             newList.add(machineId);
           }
         });
-        attrs.store.edit((draft) => {
-          draft.machineExcludeList = Array.from(newList);
+        attrs.onFilterChange({
+          ...attrs.filter,
+          machineExcludeList: Array.from(newList),
         });
       },
     });
diff --git a/ui/src/plugins/com.android.AndroidLog/storage_schema_unittest.ts b/ui/src/plugins/com.android.AndroidLog/storage_schema_unittest.ts
new file mode 100644
index 0000000..b1cec02
--- /dev/null
+++ b/ui/src/plugins/com.android.AndroidLog/storage_schema_unittest.ts
@@ -0,0 +1,63 @@
+// Copyright (C) 2026 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 {ANDROID_LOG_STATE_SCHEMA} from './index';
+
+describe('ANDROID_LOG_STATE_SCHEMA', () => {
+  test('accepts a fully populated state', () => {
+    const state = {
+      version: 1,
+      filter: {
+        minimumLevel: 4,
+        tags: ['foo', 'bar'],
+        isTagRegex: true,
+        textEntry: 'error',
+        hideNonMatching: false,
+        machineExcludeList: [1, 2],
+      },
+    };
+    expect(ANDROID_LOG_STATE_SCHEMA.parse(state)).toEqual(state);
+  });
+
+  test('rejects undefined (relies on defaultValue)', () => {
+    expect(ANDROID_LOG_STATE_SCHEMA.safeParse(undefined).success).toBe(false);
+  });
+
+  test('rejects a missing version', () => {
+    const result = ANDROID_LOG_STATE_SCHEMA.safeParse({filter: {}});
+    expect(result.success).toBe(false);
+  });
+
+  test('rejects a partial filter', () => {
+    const result = ANDROID_LOG_STATE_SCHEMA.safeParse({
+      version: 1,
+      filter: {textEntry: 'x'},
+    });
+    expect(result.success).toBe(false);
+  });
+
+  test('rejects wrongly typed fields', () => {
+    const result = ANDROID_LOG_STATE_SCHEMA.safeParse({
+      version: 1,
+      filter: {
+        minimumLevel: 'high',
+        tags: [],
+        textEntry: '',
+        hideNonMatching: true,
+        machineExcludeList: [],
+      },
+    });
+    expect(result.success).toBe(false);
+  });
+});
diff --git a/ui/src/plugins/com.android.DayExplorer/index.ts b/ui/src/plugins/com.android.DayExplorer/index.ts
index cd8d0ae..aa17e82 100644
--- a/ui/src/plugins/com.android.DayExplorer/index.ts
+++ b/ui/src/plugins/com.android.DayExplorer/index.ts
@@ -14,7 +14,7 @@
 
 import m from 'mithril';
 import {uuidv4} from '../../base/uuid';
-import type {Trace} from '../../public/trace';
+import type {Storage, Trace} from '../../public/trace';
 import StandardGroupsPlugin from '../dev.perfetto.StandardGroups';
 import type {PerfettoPlugin} from '../../public/plugin';
 import {CounterTrack} from '../../components/tracks/counter_track';
@@ -34,13 +34,11 @@
 import {Memo} from '../../base/memo';
 import {TreeExplorerPanel} from '../../components/tree_explorer_panel';
 import SupportPlugin from '../com.android.AndroidLongBatterySupport';
-import type {Store} from '../../base/store';
 import {z} from 'zod';
-import {ensureExists} from '../../base/assert';
 
 const DAY_EXPLORER_TRACK_KIND = 'day_explorer_counter_track';
 
-const DAY_EXPLORER_PLUGIN_STATE_SCHEMA = z.object({
+export const DAY_EXPLORER_PLUGIN_STATE_SCHEMA = z.object({
   areaSelectionFlamegraphState: TREE_EXPLORER_STATE_SCHEMA.optional(),
 });
 
@@ -50,13 +48,6 @@
   static readonly id = 'com.android.DayExplorer';
   static readonly dependencies = [StandardGroupsPlugin, SupportPlugin];
 
-  private store?: Store<DayExplorerPluginState>;
-
-  private migrateDayExplorerPluginState(init: unknown): DayExplorerPluginState {
-    const result = DAY_EXPLORER_PLUGIN_STATE_SCHEMA.safeParse(init);
-    return result.data ?? {};
-  }
-
   private support(ctx: Trace) {
     return ctx.plugins.getPlugin(SupportPlugin);
   }
@@ -148,7 +139,10 @@
     });
   }
 
-  private createDayExplorerFlameGraphPanel(trace: Trace) {
+  private createDayExplorerFlameGraphPanel(
+    trace: Trace,
+    storage: Storage<DayExplorerPluginState>,
+  ) {
     const fetcherMemo = new Memo<TreeExplorerFetcher | undefined>();
     return {
       id: 'day_explorer_flamegraph_selection',
@@ -157,22 +151,26 @@
         const fetcher = fetcherMemo.use({
           key: areaSelectionKey(selection),
           compute: () => {
-            const metrics = this.computeDayExplorerFlameGraph(selection);
+            const metrics = this.computeDayExplorerFlameGraph(
+              selection,
+              storage,
+            );
             return metrics && new TreeExplorerFetcher(trace, metrics);
           },
         });
         if (fetcher === undefined) {
           return undefined;
         }
-        const store = ensureExists(this.store);
         return {
           isLoading: false,
           content: m(TreeExplorerPanel, {
             fetcher,
-            state: store.state.areaSelectionFlamegraphState,
+            state: storage.get().areaSelectionFlamegraphState,
             onStateChange: (state) => {
-              store.edit((draft) => {
-                draft.areaSelectionFlamegraphState = state;
+              const current = storage.get();
+              storage.set({
+                ...current,
+                areaSelectionFlamegraphState: state,
               });
             },
           }),
@@ -183,6 +181,7 @@
 
   private computeDayExplorerFlameGraph(
     currentSelection: AreaSelection,
+    storage: Storage<DayExplorerPluginState>,
   ): ReadonlyArray<TreeExplorerQueryMetric> | undefined {
     // The flame graph will be shown when any day explorer track is in the area
     // selection. The selection is used to filter by time, and we filter the graph
@@ -255,12 +254,13 @@
       ],
       nameColumnLabel: 'Component',
     });
-    const store = ensureExists(this.store);
-    store.edit((draft) => {
-      draft.areaSelectionFlamegraphState = updateTreeExplorerState(
-        draft.areaSelectionFlamegraphState,
+    const current = storage.get();
+    storage.set({
+      ...current,
+      areaSelectionFlamegraphState: updateTreeExplorerState(
+        current.areaSelectionFlamegraphState,
         metrics,
-      );
+      ),
     });
     return metrics;
   }
@@ -330,15 +330,17 @@
   }
 
   async onTraceLoad(ctx: Trace): Promise<void> {
-    this.store = ctx.mountStore(DayExplorerPlugin.id, (init) =>
-      this.migrateDayExplorerPluginState(init),
-    );
+    const storage = ctx.registerStorage({
+      id: DayExplorerPlugin.id,
+      schema: DAY_EXPLORER_PLUGIN_STATE_SCHEMA,
+      defaultValue: {},
+    });
 
     const support = this.support(ctx);
     const features = await support.features(ctx.engine);
 
     ctx.selection.registerAreaSelectionTab(
-      this.createDayExplorerFlameGraphPanel(ctx),
+      this.createDayExplorerFlameGraphPanel(ctx, storage),
     );
 
     if (features.has('google3')) {
diff --git a/ui/src/plugins/com.android.DayExplorer/storage_schema_unittest.ts b/ui/src/plugins/com.android.DayExplorer/storage_schema_unittest.ts
new file mode 100644
index 0000000..51a71b0
--- /dev/null
+++ b/ui/src/plugins/com.android.DayExplorer/storage_schema_unittest.ts
@@ -0,0 +1,64 @@
+// Copyright (C) 2026 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 {DAY_EXPLORER_PLUGIN_STATE_SCHEMA} from './index';
+
+const TREE_STATE = {
+  selectedMetricId: 'self',
+  addedMetricIds: ['total'],
+  displayMode: 'tree',
+  filters: [{kind: 'SHOW_STACK', filter: 'foo'}],
+  view: {kind: 'TOP_DOWN'},
+};
+
+describe('DAY_EXPLORER_PLUGIN_STATE_SCHEMA', () => {
+  test('accepts empty state', () => {
+    expect(DAY_EXPLORER_PLUGIN_STATE_SCHEMA.parse({})).toEqual({});
+  });
+
+  test('accepts a populated state', () => {
+    const state = {areaSelectionFlamegraphState: TREE_STATE};
+    expect(DAY_EXPLORER_PLUGIN_STATE_SCHEMA.parse(state)).toEqual(state);
+  });
+
+  test('fills defaults in nested tree explorer state', () => {
+    const result = DAY_EXPLORER_PLUGIN_STATE_SCHEMA.parse({
+      areaSelectionFlamegraphState: {
+        selectedMetricId: 'self',
+        filters: [],
+        view: {kind: 'BOTTOM_UP'},
+      },
+    });
+    expect(result.areaSelectionFlamegraphState).toEqual({
+      selectedMetricId: 'self',
+      addedMetricIds: [],
+      displayMode: 'flamegraph',
+      filters: [],
+      view: {kind: 'BOTTOM_UP'},
+    });
+  });
+
+  test('rejects an invalid tree explorer state', () => {
+    const result = DAY_EXPLORER_PLUGIN_STATE_SCHEMA.safeParse({
+      areaSelectionFlamegraphState: {...TREE_STATE, view: {kind: 'NOT_A_VIEW'}},
+    });
+    expect(result.success).toBe(false);
+  });
+
+  test('rejects undefined (relies on defaultValue)', () => {
+    expect(DAY_EXPLORER_PLUGIN_STATE_SCHEMA.safeParse(undefined).success).toBe(
+      false,
+    );
+  });
+});
diff --git a/ui/src/plugins/com.android.HeapDumpExplorer/heap_dump_page.ts b/ui/src/plugins/com.android.HeapDumpExplorer/heap_dump_page.ts
index 855db5d..4799827 100644
--- a/ui/src/plugins/com.android.HeapDumpExplorer/heap_dump_page.ts
+++ b/ui/src/plugins/com.android.HeapDumpExplorer/heap_dump_page.ts
@@ -64,7 +64,7 @@
             t.pathHashes === active.pathHashes &&
             t.isDominator === active.isDominator,
         )) ||
-      tabs[tabs.length - 1];
+      tabs[tabs.length - 1]!;
     return fgTabKey(tab.pathHashes, tab.isDominator);
   }
   const objId = session.activeInstanceObjId;
diff --git a/ui/src/plugins/com.android.HeapDumpExplorer/index.ts b/ui/src/plugins/com.android.HeapDumpExplorer/index.ts
index 793efbd..9969538 100644
--- a/ui/src/plugins/com.android.HeapDumpExplorer/index.ts
+++ b/ui/src/plugins/com.android.HeapDumpExplorer/index.ts
@@ -25,7 +25,7 @@
 } from '../dev.perfetto.HeapProfile';
 import {HeapDumpPage} from './heap_dump_page';
 import {HeapDumpExplorerSession} from './session';
-import {migrateHdeState} from './persisted_state';
+import {DEFAULT_HDE_STATE, HDE_STATE_SCHEMA} from './persisted_state';
 import type {time} from '../../base/time';
 
 const PLUGIN_ID = 'com.android.HeapDumpExplorer';
@@ -48,9 +48,13 @@
   }
 
   constructor(trace: Trace) {
-    // The core restores this store (phase 1) before plugins run, so the session
+    // The core restores this storage (phase 1) before plugins run, so the session
     // reads any shared-link state straight from it.
-    const store = trace.mountStore(PLUGIN_ID, migrateHdeState);
+    const storage = trace.registerStorage({
+      id: PLUGIN_ID,
+      schema: HDE_STATE_SCHEMA,
+      defaultValue: DEFAULT_HDE_STATE,
+    });
 
     const hideDefaultChangedHint = trace.settings.register({
       id: 'com.android.HideHeapDumpExplorerDefaultChangedHint',
@@ -68,7 +72,7 @@
       trace.engine,
       hideDefaultChangedHint,
       defaultFlamegraph,
-      store,
+      storage,
     );
   }
 
diff --git a/ui/src/plugins/com.android.HeapDumpExplorer/nav_state.ts b/ui/src/plugins/com.android.HeapDumpExplorer/nav_state.ts
index bcd1eba..64c3114 100644
--- a/ui/src/plugins/com.android.HeapDumpExplorer/nav_state.ts
+++ b/ui/src/plugins/com.android.HeapDumpExplorer/nav_state.ts
@@ -127,13 +127,13 @@
   // Views with underscores: "flamegraph_objects" is the only multi-word view.
   let view: string;
   let param: string;
-  if (path.startsWith('flamegraph_objects')) {
+  if (path!.startsWith('flamegraph_objects')) {
     view = 'flamegraph-objects';
-    param = path.slice('flamegraph_objects'.length + 1) || '';
+    param = path!.slice('flamegraph_objects'.length + 1) || '';
   } else {
-    const idx = path.indexOf('_');
-    view = idx === -1 ? path : path.slice(0, idx);
-    param = idx === -1 ? '' : path.slice(idx + 1);
+    const idx = path!.indexOf('_');
+    view = idx === -1 ? path! : path!.slice(0, idx);
+    param = idx === -1 ? '' : path!.slice(idx + 1);
   }
 
   switch (view) {
diff --git a/ui/src/plugins/com.android.HeapDumpExplorer/persisted_state.ts b/ui/src/plugins/com.android.HeapDumpExplorer/persisted_state.ts
index a456fd1..c567118 100644
--- a/ui/src/plugins/com.android.HeapDumpExplorer/persisted_state.ts
+++ b/ui/src/plugins/com.android.HeapDumpExplorer/persisted_state.ts
@@ -16,7 +16,7 @@
 import {TREE_EXPLORER_STATE_SCHEMA} from '../../widgets/tree_explorer';
 
 // Schema for the slice of Heap Dump Explorer state that survives in a shared
-// permalink. The session writes this on every state change via mountStore;
+// permalink. The session writes this on every state change via registerStorage;
 // the core serializes it into the permalink and restores it before the plugin
 // loads (see core/state_serialization.ts).
 //
@@ -62,8 +62,4 @@
 
 export type HdeState = z.infer<typeof HDE_STATE_SCHEMA>;
 
-// An unparseable or older permalink falls back to empty state rather than
-// throwing.
-export function migrateHdeState(init: unknown): HdeState {
-  return HDE_STATE_SCHEMA.safeParse(init).data ?? {};
-}
+export const DEFAULT_HDE_STATE: HdeState = {};
diff --git a/ui/src/plugins/com.android.HeapDumpExplorer/queries.ts b/ui/src/plugins/com.android.HeapDumpExplorer/queries.ts
index adad08f..b546cab 100644
--- a/ui/src/plugins/com.android.HeapDumpExplorer/queries.ts
+++ b/ui/src/plugins/com.android.HeapDumpExplorer/queries.ts
@@ -845,7 +845,7 @@
   for (const [targetId, chain] of pathChains) {
     const path: PathEntry[] = [];
     for (let i = 0; i < chain.length; i++) {
-      const row = nodeMap.get(chain[i]);
+      const row = nodeMap.get(chain[i]!);
       if (!row) continue;
       const field =
         i < chain.length - 1
@@ -986,7 +986,7 @@
   for (const [targetId, chain] of pathChains) {
     const path: PathEntry[] = [];
     for (let i = 0; i < chain.length; i++) {
-      const row = nodeMap.get(chain[i]);
+      const row = nodeMap.get(chain[i]!);
       if (!row) continue;
       const field =
         i < chain.length - 1
@@ -1132,7 +1132,7 @@
           OR c.deobfuscated_name = '${classObjName}')
     `);
     const rows = collectRows(cRes);
-    if (rows.length > 0) classObjRow = rows[0];
+    if (rows.length > 0) classObjRow = rows[0]!;
   }
 
   const instanceFields =
@@ -1158,7 +1158,7 @@
             idx: i,
             value: {
               kind: 'prim',
-              v: formatPrimValue(arrayElementType, values[i]),
+              v: formatPrimValue(arrayElementType, values[i]!),
             },
           });
         }
@@ -1541,7 +1541,7 @@
   const count = Math.min(nativesPtrs.length, bufferObjIds.length);
   for (let i = 0; i < count; i++) {
     if (bufferObjIds[i] !== undefined && bufferObjIds[i] !== 0) {
-      bufferMap.set(nativesPtrs[i], bufferObjIds[i]);
+      bufferMap.set(nativesPtrs[i]!, bufferObjIds[i]!);
     }
   }
 
diff --git a/ui/src/plugins/com.android.HeapDumpExplorer/session.ts b/ui/src/plugins/com.android.HeapDumpExplorer/session.ts
index 38ed4b6..18bbd36 100644
--- a/ui/src/plugins/com.android.HeapDumpExplorer/session.ts
+++ b/ui/src/plugins/com.android.HeapDumpExplorer/session.ts
@@ -13,9 +13,8 @@
 // limitations under the License.
 
 import type {Engine} from '../../trace_processor/engine';
-import type {Trace} from '../../public/trace';
+import type {Storage, Trace} from '../../public/trace';
 import type {Setting} from '../../public/settings';
-import type {Store} from '../../base/store';
 import {NUM} from '../../trace_processor/query_result';
 
 import {SQL_PREAMBLE} from './components';
@@ -66,10 +65,10 @@
   return `${isDominator ? 'd' : 'n'}:${pathHashes}`;
 }
 
-// The persistent state lives in the mountStore'd `store`, which the core
+// The persistent state lives in the registered storage `storage`, which the core
 // serializes into permalinks and restores before the plugin loads. The session
-// is a thin controller over it: mutations are store edits, views render from
-// the store, restoration is automatic. Non-serializable trace-derived data (the
+// is a thin controller over it: mutations are storage edits, views render from
+// the storage, restoration is automatic. Non-serializable trace-derived data (the
 // dumps, per-tab counts) is cached here instead.
 export class HeapDumpExplorerSession {
   private _dumps: ReadonlyArray<HeapDump> = [];
@@ -88,9 +87,19 @@
     readonly engine: Engine,
     readonly hideDefaultChangedHint: Setting<boolean>,
     readonly defaultFlamegraph: Setting<boolean>,
-    private readonly store: Store<HdeState>,
+    private readonly storage: Storage<HdeState>,
   ) {}
 
+  private edit(
+    fn: (draft: {-readonly [K in keyof HdeState]: HdeState[K]}) => void,
+  ): void {
+    const next: {-readonly [K in keyof HdeState]: HdeState[K]} = {
+      ...this.storage.get(),
+    };
+    fn(next);
+    this.storage.set(next);
+  }
+
   get defaultView(): DefaultNavView {
     return this.defaultFlamegraph.get() ? 'flamegraph' : 'overview';
   }
@@ -100,7 +109,7 @@
   }
 
   get activeDump(): HeapDump | null {
-    const ref = this.store.state.activeDump;
+    const ref = this.storage.get().activeDump;
     if (ref === undefined) return null;
     return (
       this._dumps.find((d) => d.upid === ref.upid && d.ts === BigInt(ref.ts)) ??
@@ -113,17 +122,17 @@
   async loadDumps(): Promise<boolean> {
     this._dumps = await queries.loadDumpsList(this.engine);
     this.hasFieldValues = await queries.hasFieldValues(this.engine);
-    const ref = this.store.state.activeDump;
+    const ref = this.storage.get().activeDump;
     const restored =
       ref !== undefined &&
       this._dumps.some((d) => d.upid === ref.upid && d.ts === BigInt(ref.ts));
     if (restored) {
-      for (const t of this.store.state.flamegraphTabs ?? []) {
+      for (const t of this.storage.get().flamegraphTabs ?? []) {
         this.loadCount(t.pathHashes, t.isDominator);
       }
     } else {
       const first = this._dumps.length > 0 ? this._dumps[0] : undefined;
-      this.store.edit((s) => {
+      this.edit((s) => {
         s.activeDump =
           first === undefined
             ? undefined
@@ -149,7 +158,7 @@
 
   private switchToDump(d: HeapDump): void {
     this._counts.clear();
-    this.store.edit((s) => {
+    this.edit((s) => {
       s.activeDump = {upid: d.upid, ts: d.ts.toString()};
       s.flamegraphTabs = undefined;
       s.instanceTabs = undefined;
@@ -159,12 +168,12 @@
   }
 
   get nav(): NavState {
-    return subpageToState(this.store.state.nav, this.defaultView);
+    return subpageToState(this.storage.get().nav, this.defaultView);
   }
 
   // The current nav as a route path (no query params).
   get navPath(): string {
-    if (this.store.state.nav === undefined) {
+    if (this.storage.get().nav === undefined) {
       return '';
     }
     return stateToPath(this.nav);
@@ -172,7 +181,7 @@
 
   navigate(view: NavView, params: Record<string, unknown> = {}): void {
     const sub = stateToSubpage({view, params} as NavState);
-    this.store.edit((s) => {
+    this.edit((s) => {
       s.nav = sub;
     });
     this.trace.navigate(makeHref(sub));
@@ -194,10 +203,10 @@
     // sync and clobbers the user's later manual filter edits. Query params are
     // already gone (the router strips them), but path-encoded ones (e.g.
     // objects_<class>) survive in the URL, so we must rewrite it here.
-    const nav = subpageToState(this.store.state.nav, this.defaultView);
+    const nav = subpageToState(this.storage.get().nav, this.defaultView);
     delete (nav.params as Record<string, unknown>)[key];
     const sub = stateToSubpage(nav);
-    this.store.edit((s) => {
+    this.edit((s) => {
       s.nav = sub;
     });
     // Replace the current URL instead of navigating to avoid creating a new
@@ -211,7 +220,7 @@
     const sub = subpage?.startsWith('/') ? subpage.slice(1) : subpage;
     const incomingPath = (sub ?? '').split('?')[0];
     if (incomingPath !== this.navPath) {
-      this.store.edit((s) => {
+      this.edit((s) => {
         s.nav = sub
           ? stateToSubpage(subpageToState(sub, this.defaultView))
           : undefined;
@@ -220,7 +229,7 @@
   }
 
   get flamegraphTabs(): ReadonlyArray<FlamegraphTabView> {
-    return (this.store.state.flamegraphTabs ?? []).map((t) => ({
+    return (this.storage.get().flamegraphTabs ?? []).map((t) => ({
       pathHashes: t.pathHashes,
       isDominator: t.isDominator,
       count: this._counts.get(countKey(t.pathHashes, t.isDominator)) ?? null,
@@ -259,7 +268,7 @@
   // Adds the flamegraph tab for a selection in the active dump if not open.
   private openFlamegraphTab(pathHashes: string, isDominator: boolean): void {
     if (this.activeDump === null) return;
-    const tabs = this.store.state.flamegraphTabs ?? [];
+    const tabs = this.storage.get().flamegraphTabs ?? [];
     if (
       tabs.some(
         (t) => t.pathHashes === pathHashes && t.isDominator === isDominator,
@@ -267,7 +276,7 @@
     ) {
       return;
     }
-    this.store.edit((s) => {
+    this.edit((s) => {
       s.flamegraphTabs = [
         ...(s.flamegraphTabs ?? []),
         {pathHashes, isDominator},
@@ -278,7 +287,7 @@
 
   closeFlamegraph(pathHashes: string, isDominator: boolean): void {
     const active = this.activeFlamegraph;
-    this.store.edit((s) => {
+    this.edit((s) => {
       s.flamegraphTabs = (s.flamegraphTabs ?? []).filter(
         (t) => !(t.pathHashes === pathHashes && t.isDominator === isDominator),
       );
@@ -295,7 +304,7 @@
   syncFlamegraphTabFromNav(): void {
     const active = this.activeFlamegraph;
     if (active === null) return;
-    const tabs = this.store.state.flamegraphTabs ?? [];
+    const tabs = this.storage.get().flamegraphTabs ?? [];
     if (
       !tabs.some(
         (t) =>
@@ -321,7 +330,7 @@
   }
 
   get instanceTabs(): ReadonlyArray<{objId: number; label: string}> {
-    return this.store.state.instanceTabs ?? [];
+    return this.storage.get().instanceTabs ?? [];
   }
 
   // The active object's id, derived from the nav (not stored), or null.
@@ -331,9 +340,9 @@
   }
 
   private openInstanceTab(objId: number, label?: string): void {
-    const tabs = this.store.state.instanceTabs ?? [];
+    const tabs = this.storage.get().instanceTabs ?? [];
     if (tabs.some((t) => t.objId === objId)) return;
-    this.store.edit((s) => {
+    this.edit((s) => {
       s.instanceTabs = [
         ...(s.instanceTabs ?? []),
         {objId, label: truncateInstanceLabel(label ?? 'Instance')},
@@ -343,7 +352,7 @@
 
   closeInstanceTab(objId: number): void {
     const wasActive = this.activeInstanceObjId === objId;
-    this.store.edit((s) => {
+    this.edit((s) => {
       s.instanceTabs = (s.instanceTabs ?? []).filter((t) => t.objId !== objId);
     });
     if (wasActive) this.navigate(this.defaultView);
@@ -353,26 +362,26 @@
     const nav = this.nav;
     if (nav.view !== 'object') return;
     const {id, label} = nav.params;
-    const tabs = this.store.state.instanceTabs ?? [];
+    const tabs = this.storage.get().instanceTabs ?? [];
     if (!tabs.some((t) => t.objId === id)) this.openInstanceTab(id, label);
   }
 
   get flamegraphPanelState(): TreeExplorerState | undefined {
-    return this.store.state.flamegraphPanelState;
+    return this.storage.get().flamegraphPanelState;
   }
 
   setFlamegraphPanelState(state: TreeExplorerState): void {
-    this.store.edit((s) => {
+    this.edit((s) => {
       s.flamegraphPanelState = state;
     });
   }
 
   get callstackPanelState(): TreeExplorerState | undefined {
-    return this.store.state.callstackPanelState;
+    return this.storage.get().callstackPanelState;
   }
 
   setCallstackPanelState(state: TreeExplorerState): void {
-    this.store.edit((s) => {
+    this.edit((s) => {
       s.callstackPanelState = state;
     });
   }
diff --git a/ui/src/plugins/com.android.HeapDumpExplorer/storage_schema_unittest.ts b/ui/src/plugins/com.android.HeapDumpExplorer/storage_schema_unittest.ts
new file mode 100644
index 0000000..00bf406
--- /dev/null
+++ b/ui/src/plugins/com.android.HeapDumpExplorer/storage_schema_unittest.ts
@@ -0,0 +1,59 @@
+// Copyright (C) 2026 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 {DEFAULT_HDE_STATE, HDE_STATE_SCHEMA} from './persisted_state';
+
+const TREE_STATE = {
+  selectedMetricId: 'self',
+  addedMetricIds: ['total'],
+  displayMode: 'tree',
+  filters: [{kind: 'SHOW_STACK', filter: 'foo'}],
+  view: {kind: 'TOP_DOWN'},
+};
+
+describe('HDE_STATE_SCHEMA', () => {
+  test('accepts the default state', () => {
+    expect(HDE_STATE_SCHEMA.parse(DEFAULT_HDE_STATE)).toEqual({});
+  });
+
+  test('accepts a fully populated state', () => {
+    const state = {
+      activeDump: {upid: 3, ts: '123456789012345'},
+      nav: 'flamegraph',
+      flamegraphTabs: [{pathHashes: 'abc', isDominator: true}],
+      instanceTabs: [{objId: 42, label: 'java.lang.String'}],
+      flamegraphPanelState: TREE_STATE,
+      callstackPanelState: TREE_STATE,
+    };
+    expect(HDE_STATE_SCHEMA.parse(state)).toEqual(state);
+  });
+
+  test('rejects a numeric dump timestamp', () => {
+    const result = HDE_STATE_SCHEMA.safeParse({
+      activeDump: {upid: 3, ts: 123},
+    });
+    expect(result.success).toBe(false);
+  });
+
+  test('rejects malformed tabs', () => {
+    const result = HDE_STATE_SCHEMA.safeParse({
+      instanceTabs: [{objId: '42'}],
+    });
+    expect(result.success).toBe(false);
+  });
+
+  test('rejects undefined (relies on defaultValue)', () => {
+    expect(HDE_STATE_SCHEMA.safeParse(undefined).success).toBe(false);
+  });
+});
diff --git a/ui/src/plugins/com.android.HeapDumpExplorer/views/bitmap_gallery_view.ts b/ui/src/plugins/com.android.HeapDumpExplorer/views/bitmap_gallery_view.ts
index 16e03b3..3d59dbf 100644
--- a/ui/src/plugins/com.android.HeapDumpExplorer/views/bitmap_gallery_view.ts
+++ b/ui/src/plugins/com.android.HeapDumpExplorer/views/bitmap_gallery_view.ts
@@ -235,7 +235,7 @@
       if (!vnode.attrs.row.hasPixelData) return;
       obs = new IntersectionObserver(
         ([entry]) => {
-          if (entry.isIntersecting) {
+          if (entry!.isIntersecting) {
             load(
               vnode.attrs.engine,
               vnode.attrs.activeDump,
diff --git a/ui/src/plugins/com.android.HeapDumpExplorer/views/overview_view.ts b/ui/src/plugins/com.android.HeapDumpExplorer/views/overview_view.ts
index bef162f..2e87122 100644
--- a/ui/src/plugins/com.android.HeapDumpExplorer/views/overview_view.ts
+++ b/ui/src/plugins/com.android.HeapDumpExplorer/views/overview_view.ts
@@ -267,29 +267,19 @@
       const showHint = showDefaultChangedHint;
       const heapIndices: number[] = [];
       for (let i = 0; i < overview.heaps.length; i++) {
-        const h = overview.heaps[i];
+        const h = overview.heaps[i]!;
         if (h.java + h.native_ > 0) {
           heapIndices.push(i);
         }
       }
       const heaps = heapIndices.map((i) => overview.heaps[i]);
-      const totalJava = heaps.reduce((a, h) => a + h.java, 0);
-      const totalNative = heaps.reduce((a, h) => a + h.native_, 0);
 
-      const heapRows: Row[] = [
-        {
-          heap: 'Total',
-          java_size: totalJava,
-          native_size: totalNative,
-          total_size: totalJava + totalNative,
-        },
-        ...heaps.map((h) => ({
-          heap: h.name,
-          java_size: h.java,
-          native_size: h.native_,
-          total_size: h.java + h.native_,
-        })),
-      ];
+      const heapRows: Row[] = heaps.map((h) => ({
+        heap: h!.name,
+        java_size: h!.java,
+        native_size: h!.native_,
+        total_size: h!.java + h!.native_,
+      }));
 
       const processLabel =
         (activeDump.processName ?? '<unknown>') +
@@ -377,9 +367,9 @@
               data: heapRows,
               initialColumns: [
                 {id: 'heap', field: 'heap'},
-                {id: 'java_size', field: 'java_size'},
-                {id: 'native_size', field: 'native_size'},
-                {id: 'total_size', field: 'total_size'},
+                {id: 'java_size', field: 'java_size', aggregate: 'SUM'},
+                {id: 'native_size', field: 'native_size', aggregate: 'SUM'},
+                {id: 'total_size', field: 'total_size', aggregate: 'SUM'},
               ],
             }),
           ]),
diff --git a/ui/src/plugins/com.android.MemoryViz/index.ts b/ui/src/plugins/com.android.MemoryViz/index.ts
index 112c184..e207dcd 100644
--- a/ui/src/plugins/com.android.MemoryViz/index.ts
+++ b/ui/src/plugins/com.android.MemoryViz/index.ts
@@ -93,7 +93,7 @@
         ];
         trackPromises.push(
           ...tracks.map(([trackName, displayName]) =>
-            this.createBreakdownTrack(ctx, window, trackName, displayName),
+            this.createBreakdownTrack(ctx, window, trackName!, displayName!),
           ),
         );
         const createdTracks = await Promise.all(trackPromises);
diff --git a/ui/src/plugins/com.android.PinAndroidPerfMetrics/handlers/fullTraceJankMetricHandler.ts b/ui/src/plugins/com.android.PinAndroidPerfMetrics/handlers/fullTraceJankMetricHandler.ts
index 5441eec..ee85650 100644
--- a/ui/src/plugins/com.android.PinAndroidPerfMetrics/handlers/fullTraceJankMetricHandler.ts
+++ b/ui/src/plugins/com.android.PinAndroidPerfMetrics/handlers/fullTraceJankMetricHandler.ts
@@ -36,7 +36,7 @@
       return undefined;
     }
     return {
-      process: expandProcessName(match.groups.process),
+      process: expandProcessName(match.groups.process!),
       jankType: match.groups.jankType as JankType,
       isWeighted: !!match.groups.jps,
     };
diff --git a/ui/src/plugins/com.android.PinAndroidPerfMetrics/handlers/pinBlockingCall.ts b/ui/src/plugins/com.android.PinAndroidPerfMetrics/handlers/pinBlockingCall.ts
index 43307ca..79e5d32 100644
--- a/ui/src/plugins/com.android.PinAndroidPerfMetrics/handlers/pinBlockingCall.ts
+++ b/ui/src/plugins/com.android.PinAndroidPerfMetrics/handlers/pinBlockingCall.ts
@@ -44,10 +44,10 @@
       return undefined;
     }
     const metricData: BlockingCallMetricData = {
-      process: expandProcessName(match.groups.process),
-      cujName: match.groups.cujName,
-      blockingCallName: match.groups.blockingCallName,
-      aggregation: match.groups.aggregation,
+      process: expandProcessName(match.groups.process!),
+      cujName: match.groups.cujName!,
+      blockingCallName: match.groups.blockingCallName!,
+      aggregation: match.groups.aggregation!,
     };
     return metricData;
   }
diff --git a/ui/src/plugins/com.android.PinAndroidPerfMetrics/handlers/pinCujMetricHandler.ts b/ui/src/plugins/com.android.PinAndroidPerfMetrics/handlers/pinCujMetricHandler.ts
index 2819887..16f398e 100644
--- a/ui/src/plugins/com.android.PinAndroidPerfMetrics/handlers/pinCujMetricHandler.ts
+++ b/ui/src/plugins/com.android.PinAndroidPerfMetrics/handlers/pinCujMetricHandler.ts
@@ -32,7 +32,7 @@
       return undefined;
     }
     return {
-      cujName: match.groups.cujName,
+      cujName: match.groups.cujName!,
     };
   }
 
diff --git a/ui/src/plugins/com.android.PinAndroidPerfMetrics/handlers/pinCujScoped.ts b/ui/src/plugins/com.android.PinAndroidPerfMetrics/handlers/pinCujScoped.ts
index bc1ca45..dc9c529 100644
--- a/ui/src/plugins/com.android.PinAndroidPerfMetrics/handlers/pinCujScoped.ts
+++ b/ui/src/plugins/com.android.PinAndroidPerfMetrics/handlers/pinCujScoped.ts
@@ -43,8 +43,8 @@
       return undefined;
     }
     return {
-      process: expandProcessName(match.groups.process),
-      cujName: match.groups.cujName,
+      process: expandProcessName(match.groups.process!),
+      cujName: match.groups.cujName!,
       jankType: match.groups.jankType as JankType,
       isWeighted: !!match.groups.jps,
     };
diff --git a/ui/src/plugins/com.android.PinAndroidPerfMetrics/handlers/pinNotificationsBlockingCall.ts b/ui/src/plugins/com.android.PinAndroidPerfMetrics/handlers/pinNotificationsBlockingCall.ts
index 3736c3a..bb94e61 100644
--- a/ui/src/plugins/com.android.PinAndroidPerfMetrics/handlers/pinNotificationsBlockingCall.ts
+++ b/ui/src/plugins/com.android.PinAndroidPerfMetrics/handlers/pinNotificationsBlockingCall.ts
@@ -39,8 +39,8 @@
       return undefined;
     }
     const metricData: NotificationsBlockingCallMetricData = {
-      notificationName: match.groups.blockingCallName,
-      aggregation: match.groups.aggregation,
+      notificationName: match.groups.blockingCallName!,
+      aggregation: match.groups.aggregation!,
     };
     return metricData;
   }
diff --git a/ui/src/plugins/com.android.PinAndroidPerfMetrics/index.ts b/ui/src/plugins/com.android.PinAndroidPerfMetrics/index.ts
index 2bf1072..9a93fef 100644
--- a/ui/src/plugins/com.android.PinAndroidPerfMetrics/index.ts
+++ b/ui/src/plugins/com.android.PinAndroidPerfMetrics/index.ts
@@ -37,7 +37,7 @@
   if (match === null) {
     return [];
   }
-  const capturedString = match[1];
+  const capturedString = match[1]!;
   let metricList: string[] = [];
   if (capturedString.includes('--')) {
     metricList = capturedString.split('--');
diff --git a/ui/src/plugins/com.android.ProcessState/details_panel.ts b/ui/src/plugins/com.android.ProcessState/details_panel.ts
new file mode 100644
index 0000000..1b8742f
--- /dev/null
+++ b/ui/src/plugins/com.android.ProcessState/details_panel.ts
@@ -0,0 +1,97 @@
+// Copyright (C) 2026 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 m from 'mithril';
+import {Icons} from '../../base/semantic_icons';
+import {Time} from '../../base/time';
+import {DurationWidget} from '../../components/widgets/duration';
+import {Timestamp} from '../../components/widgets/timestamp';
+import type {TrackEventDetailsPanel} from '../../public/details_panel';
+import type {Trace} from '../../public/trace';
+import type {DatasetSchema} from '../../trace_processor/dataset';
+import type {Row} from '../../trace_processor/query_result';
+import {sqlValueToReadableString} from '../../trace_processor/sql_utils';
+import {Anchor} from '../../widgets/anchor';
+import {DetailsShell} from '../../widgets/details_shell';
+import {GridLayout} from '../../widgets/grid_layout';
+import {Section} from '../../widgets/section';
+import {Tree, TreeNode} from '../../widgets/tree';
+
+export interface ProcessStateRow extends Row {
+  readonly id: number;
+  readonly ts: bigint;
+  readonly dur: bigint;
+}
+
+/** Lists the columns of `schema` for one process state slice. */
+export class ProcessStateDetailsPanel implements TrackEventDetailsPanel {
+  constructor(
+    private readonly trace: Trace,
+    private readonly schema: DatasetSchema,
+    private readonly row: ProcessStateRow,
+    // Set on the overview row: links to the same slice on the owner track.
+    private readonly ownerUri?: string,
+  ) {}
+
+  render() {
+    const {trace, row, ownerUri} = this;
+    return m(
+      DetailsShell,
+      {title: 'Slice'},
+      m(
+        GridLayout,
+        m(
+          Section,
+          {title: 'Details'},
+          m(Tree, [
+            m(TreeNode, {left: 'ID', right: row.id}),
+            m(TreeNode, {
+              left: 'Start time',
+              right: m(Timestamp, {trace, ts: Time.fromRaw(row.ts)}),
+            }),
+            m(TreeNode, {
+              left: 'Duration',
+              right: m(DurationWidget, {trace, dur: row.dur}),
+            }),
+            ...Object.keys(this.schema)
+              .filter((key) => !['id', 'ts', 'dur'].includes(key))
+              .map((key) => {
+                const text = sqlValueToReadableString(row[key]);
+                return m(TreeNode, {
+                  left: key,
+                  right:
+                    key === 'process_name' && ownerUri !== undefined
+                      ? m(
+                          Anchor,
+                          {
+                            icon: Icons.UpdateSelection,
+                            title: 'Show in process group',
+                            onclick: () =>
+                              trace.selection.selectTrackEvent(
+                                ownerUri,
+                                row.id,
+                                {scrollToSelection: true},
+                              ),
+                          },
+                          text,
+                        )
+                      : text,
+                });
+              }),
+          ]),
+        ),
+      ),
+    );
+  }
+}
diff --git a/ui/src/plugins/com.android.ProcessState/index.ts b/ui/src/plugins/com.android.ProcessState/index.ts
index 16a329e..c3b3d18 100644
--- a/ui/src/plugins/com.android.ProcessState/index.ts
+++ b/ui/src/plugins/com.android.ProcessState/index.ts
@@ -20,9 +20,9 @@
   makeColorScheme,
 } from '../../components/colorizer';
 import {SliceTrack} from '../../components/tracks/slice_track';
-import {SliceTrackDetailsPanel} from '../../components/tracks/slice_track_details_panel';
 import type {PerfettoPlugin} from '../../public/plugin';
 import type {Trace} from '../../public/trace';
+import type {TrackRenderer} from '../../public/track';
 import {TrackNode} from '../../public/workspace';
 import {SourceDataset} from '../../trace_processor/dataset';
 import {
@@ -33,6 +33,7 @@
   STR,
   STR_NULL,
 } from '../../trace_processor/query_result';
+import ProcessThreadGroupsPlugin from '../dev.perfetto.ProcessThreadGroups';
 import {
   ProcessExitsAggregator,
   ProcessStartsAggregator,
@@ -42,6 +43,7 @@
   TAG_COUNT_TRACK,
   TAG_PROCESS_TRACK,
 } from './aggregators';
+import {ProcessStateDetailsPanel} from './details_panel';
 import {ProcessStateCountTrack} from './state_count_track';
 
 const BASE_SCHEMA = {
@@ -77,28 +79,52 @@
 
 const PROCESS_STATE_SCHEMA = {...NONEXISTENT_SCHEMA, ...EXITED_SCHEMA} as const;
 
+const FREEZER_SCHEMA = {
+  id: NUM,
+  ts: LONG,
+  dur: LONG,
+  upid: NUM,
+  pid: NUM,
+  process_name: STR_NULL,
+  state: STR,
+} as const;
+
 const SLATE = makeColorScheme(new HSLColor([210, 18, 48]));
 
+// The per-process tracks come in their hundreds, so keep them compact.
+const COMPACT_SLICES = {sliceHeight: 12, titleSizePx: 10};
+
+// Below every other process-scoped track (-50..30) so it appears first.
+const PROCESS_GROUP_SORT_ORDER = -100;
+
+// Keeps the freezer lanes out of the aggregators, which scope by the state
+// track's tag.
+const TAG_FREEZER_TRACK = 'android_freezer';
+
 /**
  * Visualizes Android framework process states over the lifetime of a trace.
  *
- * Everything lives under one dedicated top level group rather than under the
- * per-process groups, because in long memory or AOT traces the processes
- * carrying state data often have no other track data at all, and so get no
- * process group to attach to.
+ * A process's state timeline lives in its process group. It is also mirrored
+ * under one dedicated top level group, which in long memory traces is the only
+ * place most of them can appear: those processes carry no other track data,
+ * and so get no process group at all.
  */
 export default class ProcessState implements PerfettoPlugin {
   static readonly id = 'com.android.ProcessState';
   static readonly description =
     'Visualizes Android framework process states: per-state concurrency ' +
-    'counters and a per-process state timeline.';
+    'counters, and per-process state and freezer timelines.';
+  static readonly dependencies = [ProcessThreadGroupsPlugin];
 
   async onTraceLoad(ctx: Trace): Promise<void> {
     if (!(await this.hasProcessStateData(ctx))) {
       return;
     }
 
-    await ctx.engine.query(`INCLUDE PERFETTO MODULE android.process_state;`);
+    await ctx.engine.query(`
+      INCLUDE PERFETTO MODULE android.process_state;
+      INCLUDE PERFETTO MODULE android.freezer;
+    `);
 
     ctx.selection.registerAreaSelectionTab(
       createAggregationTab(ctx, new ProcessStateResidencyAggregator(ctx)),
@@ -167,18 +193,22 @@
     return summary;
   }
 
-  // One timeline per process. Ordered by uid so that the successive processes
-  // of a respawning app sit next to each other - that adjacency is the only
-  // thing tying an app's lifetimes together, since each restart gets its own
-  // upid.
+  // One timeline per process, with its freezer timeline as a child when the
+  // trace has freezer data for it. Ordered by uid so that the successive
+  // processes of a respawning app sit next to each other - that adjacency is
+  // the only thing tying an app's lifetimes together, since each restart gets
+  // its own upid.
   private async createProcessTracks(ctx: Trace): Promise<TrackNode> {
     const byProcess = new TrackNode({name: 'By process', isSummary: true});
+    const groups = ctx.plugins.getPlugin(ProcessThreadGroupsPlugin);
 
     const processes = await ctx.engine.query(`
       SELECT
         upid,
         pid,
-        process_name AS name
+        process_name AS name,
+        upid IN (SELECT upid FROM _android_freezer_intervals)
+          AS hasFreezer
       FROM _android_process_state_intervals
       GROUP BY upid
       ORDER BY
@@ -188,56 +218,142 @@
     `);
 
     for (
-      const it = processes.iter({upid: NUM, pid: NUM, name: STR_NULL});
+      const it = processes.iter({
+        upid: NUM,
+        pid: NUM,
+        name: STR_NULL,
+        hasFreezer: NUM,
+      });
       it.valid();
       it.next()
     ) {
-      const {upid, pid} = it;
+      const {upid, pid, hasFreezer} = it;
       const name = it.name ?? `${pid}`;
       const uri = processTrackUri(upid);
-      ctx.tracks.registerTrack({
+      const processGroup = groups.getGroupForProcess(upid);
+      const overviewUri = this.registerProcessTrack(ctx, processGroup, {
         uri,
-        renderer: SliceTrack.create({
-          trace: ctx,
-          uri,
-          dataset: new SourceDataset({
-            schema: PROCESS_STATE_SCHEMA,
-            src: '_android_process_state_intervals',
-            filter: {col: 'upid', eq: upid},
-          }),
-          // These tracks come in their hundreds, so keep them compact.
-          sliceLayout: {sliceHeight: 12, titleSizePx: 10},
-          sliceName: (row) => row.state,
-          colorizer: (row) => {
-            if (row.state === 'NONEXISTENT') return SLATE;
-            if (row.state === 'EXITED') return GRAY;
-            return getColorForSlice(row.state);
-          },
-          detailsPanel: (row) => {
-            const schema =
-              row.state === 'NONEXISTENT'
-                ? NONEXISTENT_SCHEMA
-                : row.state === 'EXITED'
-                  ? EXITED_SCHEMA
-                  : BASE_SCHEMA;
-            return new SliceTrackDetailsPanel(
-              ctx,
-              new SourceDataset({
-                schema,
-                src: '_android_process_state_intervals',
-                filter: {col: 'upid', eq: upid},
-              }),
-              row,
-            );
-          },
-          rootTableName: '_android_process_state_intervals',
-        }),
-        tags: {type: TAG_PROCESS_TRACK, upid},
+        tag: TAG_PROCESS_TRACK,
+        upid,
         description: `Framework process state of ${name} (${pid}) over time.`,
+        create: (trackUri, ownerUri) =>
+          SliceTrack.create({
+            trace: ctx,
+            uri: trackUri,
+            dataset: new SourceDataset({
+              schema: PROCESS_STATE_SCHEMA,
+              src: '_android_process_state_intervals',
+              filter: {col: 'upid', eq: upid},
+            }),
+            sliceLayout: COMPACT_SLICES,
+            sliceName: (row) => row.state,
+            colorizer: (row) => {
+              if (row.state === 'NONEXISTENT') return SLATE;
+              if (row.state === 'EXITED') return GRAY;
+              return getColorForSlice(row.state);
+            },
+            detailsPanel: (row) => {
+              const schema =
+                row.state === 'NONEXISTENT'
+                  ? NONEXISTENT_SCHEMA
+                  : row.state === 'EXITED'
+                    ? EXITED_SCHEMA
+                    : BASE_SCHEMA;
+              return new ProcessStateDetailsPanel(ctx, schema, row, ownerUri);
+            },
+            rootTableName:
+              ownerUri === undefined
+                ? '_android_process_state_intervals'
+                : undefined,
+          }),
       });
-      byProcess.addChildLast(new TrackNode({uri, name: `${name} ${pid}`}));
+      const overviewNode = new TrackNode({
+        uri: overviewUri,
+        name: `${name} ${pid}`,
+      });
+      const groupNode = new TrackNode({
+        uri,
+        name: 'Process state',
+        sortOrder: PROCESS_GROUP_SORT_ORDER,
+      });
+
+      if (hasFreezer) {
+        const freezerUri = `${uri}.freezer`;
+        const overviewFreezerUri = this.registerProcessTrack(
+          ctx,
+          processGroup,
+          {
+            uri: freezerUri,
+            tag: TAG_FREEZER_TRACK,
+            upid,
+            description: `Freezer state of ${name} (${pid}) over time.`,
+            create: (trackUri, ownerUri) =>
+              SliceTrack.create({
+                trace: ctx,
+                uri: trackUri,
+                dataset: new SourceDataset({
+                  schema: FREEZER_SCHEMA,
+                  src: '_android_freezer_intervals',
+                  filter: {col: 'upid', eq: upid},
+                }),
+                sliceLayout: COMPACT_SLICES,
+                sliceName: (row) => row.state,
+                colorizer: (row) => getColorForSlice(row.state),
+                detailsPanel: (row) =>
+                  new ProcessStateDetailsPanel(
+                    ctx,
+                    FREEZER_SCHEMA,
+                    row,
+                    ownerUri,
+                  ),
+                rootTableName:
+                  ownerUri === undefined
+                    ? '_android_freezer_intervals'
+                    : undefined,
+              }),
+          },
+        );
+        overviewNode.addChildLast(
+          new TrackNode({uri: overviewFreezerUri, name: 'Freezer'}),
+        );
+        groupNode.addChildLast(
+          new TrackNode({uri: freezerUri, name: 'Freezer'}),
+        );
+      }
+
+      byProcess.addChildLast(overviewNode);
+      processGroup?.addChildInOrder(groupNode);
     }
 
     return byProcess;
   }
+
+  // Registers a process-scoped track. The process group owns it when there is
+  // one; the 'By process' overview then gets a mirror under `${uri}.overview`
+  // that links back to the owner, which alone keeps rootTableName so that
+  // selecting a slice by id lands on it. Returns the uri for the overview node.
+  private registerProcessTrack(
+    ctx: Trace,
+    processGroup: TrackNode | undefined,
+    track: {
+      uri: string;
+      tag: string;
+      upid: number;
+      description: string;
+      create: (trackUri: string, ownerUri?: string) => TrackRenderer;
+    },
+  ): string {
+    const {uri, tag, upid, description, create} = track;
+    const overviewUri = processGroup !== undefined ? `${uri}.overview` : uri;
+    for (const trackUri of processGroup ? [uri, overviewUri] : [uri]) {
+      const isOwner = trackUri === uri;
+      ctx.tracks.registerTrack({
+        uri: trackUri,
+        renderer: create(trackUri, isOwner ? undefined : uri),
+        tags: {type: tag, upid},
+        description,
+      });
+    }
+    return overviewUri;
+  }
 }
diff --git a/ui/src/plugins/com.android.SysUIWorkspace/index.ts b/ui/src/plugins/com.android.SysUIWorkspace/index.ts
index f2488a8..ec4cb74 100644
--- a/ui/src/plugins/com.android.SysUIWorkspace/index.ts
+++ b/ui/src/plugins/com.android.SysUIWorkspace/index.ts
@@ -226,14 +226,14 @@
       const {groupName, trackName} = match.groups;
 
       const newTrack = track.clone();
-      newTrack.name = trackName;
+      newTrack.name = trackName!;
 
-      if (!trackGroups.has(groupName)) {
+      if (!trackGroups.has(groupName!)) {
         const newGroup = new TrackNode({name: groupName, isSummary: true});
         this.ws.addChildLast(newGroup);
-        trackGroups.set(groupName, newGroup);
+        trackGroups.set(groupName!, newGroup);
       }
-      trackGroups.get(groupName)!.addChildLast(newTrack);
+      trackGroups.get(groupName!)!.addChildLast(newTrack);
     });
   }
 }
diff --git a/ui/src/plugins/com.arm.ArmTelemetry/cpu_page.ts b/ui/src/plugins/com.arm.ArmTelemetry/cpu_page.ts
index 27fb1b0..130670f 100644
--- a/ui/src/plugins/com.arm.ArmTelemetry/cpu_page.ts
+++ b/ui/src/plugins/com.arm.ArmTelemetry/cpu_page.ts
@@ -83,7 +83,7 @@
         onchange: (e: Event) => {
           const input = ensureIsInstance(e.target, HTMLInputElement);
           if (!input.files) return;
-          const file = input.files[0];
+          const file = input.files[0]!;
           // Forward CPU files to the CPU Info Manager
           const reader = new FileReader();
           reader.onloadend = () => {
diff --git a/ui/src/plugins/com.arm.ArmTelemetry/index.ts b/ui/src/plugins/com.arm.ArmTelemetry/index.ts
index 65d0fd1..578ab35 100644
--- a/ui/src/plugins/com.arm.ArmTelemetry/index.ts
+++ b/ui/src/plugins/com.arm.ArmTelemetry/index.ts
@@ -368,7 +368,7 @@
         });
 
         if (exists(found)) {
-          const cpu = m.cpus[0];
+          const cpu = m.cpus[0]!;
           if (!found.cpus.includes(cpu)) {
             found.cpus.push(cpu);
           }
@@ -446,11 +446,11 @@
       // Optimize query if it is applicable to all the CPUS
       if (
         metrics.length == 1 &&
-        metrics[0].cpus.length == applicableCpus.length &&
-        metrics[0].cpus.every((c) => applicableCpus.includes(c))
+        metrics[0]!.cpus.length == applicableCpus.length &&
+        metrics[0]!.cpus.every((c) => applicableCpus.includes(c))
       ) {
-        const metric = metrics[0];
-        const firstTable = eventTableName(metric.events[0]);
+        const metric = metrics[0]!;
+        const firstTable = eventTableName(metric.events[0]!);
         const fromClause = metric.events.slice(1).reduce((acc, counter) => {
           const counterTable = eventTableName(counter);
           return (
@@ -478,7 +478,7 @@
           DROP TABLE IF EXISTS ${tableName};
           CREATE TABLE ${tableName} AS
           ${metrics.reduce<string>((acc, metric) => {
-            const firstTable = eventTableName(metric.events[0]);
+            const firstTable = eventTableName(metric.events[0]!);
             const fromClause = metric.events.slice(1).reduce((acc, counter) => {
               const counterTable = eventTableName(counter);
               return (
diff --git a/ui/src/plugins/com.arm.ArmTelemetry/pmu.ts b/ui/src/plugins/com.arm.ArmTelemetry/pmu.ts
index b6ec1b0..842f5d1 100644
--- a/ui/src/plugins/com.arm.ArmTelemetry/pmu.ts
+++ b/ui/src/plugins/com.arm.ArmTelemetry/pmu.ts
@@ -529,7 +529,7 @@
         .map((option) => option.id),
     );
     this.metricOptions.forEach((metric) => {
-      metric.checked = availableMetrics[metric.id].events.every((eventName) =>
+      metric.checked = availableMetrics[metric.id]!.events.every((eventName) =>
         completePmuList.has(eventName),
       );
     });
@@ -545,7 +545,7 @@
     const pmus = new Set<string>();
     this.metricOptions.forEach((metric) => {
       if (metric.checked) {
-        this.cpuDesc?.metrics[metric.id].events.forEach((eventName) =>
+        this.cpuDesc?.metrics[metric.id]!.events.forEach((eventName) =>
           pmus.add(eventName),
         );
       }
@@ -571,8 +571,8 @@
 
     this.metricOptions.forEach((metric) => {
       if (!metric.checked) {
-        metric.checked = availableMetrics[metric.id].events.every((eventName) =>
-          completePmuList.has(eventName),
+        metric.checked = availableMetrics[metric.id]!.events.every(
+          (eventName) => completePmuList.has(eventName),
         );
       }
     });
@@ -907,7 +907,7 @@
             throw new Error('Not an input element');
           }
           if (!e.target.files) return;
-          const file = e.target.files[0];
+          const file = e.target.files[0]!;
           const reader = new FileReader();
           reader.onloadend = () => {
             if (reader.error) {
@@ -1092,7 +1092,7 @@
           name: cpuState.cpuLeader,
           rawEvent: {
             type: cpuPerfType,
-            config: Number(cpuDesc.events[cpuState.cpuLeader].code),
+            config: Number(cpuDesc.events[cpuState.cpuLeader]!.code),
           },
         };
 
@@ -1103,7 +1103,7 @@
               name: pmu,
               rawEvent: {
                 type: cpuPerfType,
-                config: Number(cpuDesc.events[pmu].code),
+                config: Number(cpuDesc.events[pmu]!.code),
               },
             };
           });
@@ -1156,8 +1156,8 @@
         return [[], `Invalid CPU range: ${part}`];
       }
       const [startStrRaw, endStrRaw] = rangeParts;
-      const startStr = startStrRaw.trim();
-      const endStr = endStrRaw.trim();
+      const startStr = startStrRaw!.trim();
+      const endStr = endStrRaw!.trim();
       const start = parseCpuNumber(startStr);
       const end = parseCpuNumber(endStr);
 
diff --git a/ui/src/plugins/com.arm.ArmTelemetry/pmu_unittest.ts b/ui/src/plugins/com.arm.ArmTelemetry/pmu_unittest.ts
index 24fb6f7..fec9cc6 100644
--- a/ui/src/plugins/com.arm.ArmTelemetry/pmu_unittest.ts
+++ b/ui/src/plugins/com.arm.ArmTelemetry/pmu_unittest.ts
@@ -230,11 +230,11 @@
   if (subpage.kind !== 'PROBES_PAGE') {
     throw new Error('Expected PMU record section to be a probes page');
   }
-  return subpage.probes[0];
+  return subpage.probes[0]!;
 }
 
 function getPmuSettingForTest(probe = createPmuProbeForTest()): ProbeSetting {
-  return probe.settings!.testSetting;
+  return probe.settings!.testSetting!;
 }
 
 function validSerializedPmuConfig(
@@ -282,7 +282,7 @@
   const vnode = setting.render() as unknown as {
     children: Array<{attrs: {state: PerfConfigurationState}}>;
   };
-  return vnode.children[0].attrs.state;
+  return vnode.children[0]!.attrs.state;
 }
 
 function initializePmuTabForTest(setting: ProbeSetting) {
@@ -297,7 +297,7 @@
       };
     }>;
   };
-  const perfConfigurationVnode = containerVnode.children[0];
+  const perfConfigurationVnode = containerVnode.children[0]!;
   const perfConfiguration = new perfConfigurationVnode.tag();
   perfConfiguration.oninit({attrs: perfConfigurationVnode.attrs});
   const rendered = perfConfiguration.view({
@@ -659,13 +659,13 @@
     setting.deserialize(validSerializedPmuConfig());
 
     const {state, perfCpuConfigurations} = initializePmuTabForTest(setting);
-    expect(perfCpuConfigurations[0].controller.cpus).toEqual(
+    expect(perfCpuConfigurations[0]!.controller.cpus).toEqual(
       new Map([['0x4114d', 'Test CPU']]),
     );
 
     specManager.add(CPU_SPEC_2);
 
-    expect(state.tabs[0].configuration).toEqual({
+    expect(state.tabs[0]!.configuration).toEqual({
       cpuSelected: '0x4114d',
       pmusSelected: ['CPU_CYCLES', 'INST_RETIRED'],
       onCpuSelected: expect.any(Function),
@@ -678,14 +678,16 @@
       frequency: 1000,
       captureCallstack: true,
     });
-    expect(perfCpuConfigurations[0].controller.cpus).toEqual(
+    expect(perfCpuConfigurations[0]!.controller.cpus).toEqual(
       new Map([
         ['0x4114d', 'Test CPU'],
         [getCpuId(CPU_SPEC_2), 'Added Test CPU'],
       ]),
     );
     expect(
-      perfCpuConfigurations[0].controller.pmuOptions.map((option) => option.id),
+      perfCpuConfigurations[0]!.controller.pmuOptions.map(
+        (option) => option.id,
+      ),
     ).toEqual(['CPU_CYCLES', 'INST_RETIRED']);
     expect(app.raf.scheduleFullRedraw).toHaveBeenCalled();
   });
@@ -717,7 +719,7 @@
     });
 
     const {state, perfCpuConfigurations} = initializePmuTabForTest(setting);
-    expect(perfCpuConfigurations[0].controller.cpus).toEqual(
+    expect(perfCpuConfigurations[0]!.controller.cpus).toEqual(
       new Map([['0x4114d', 'Test CPU']]),
     );
 
@@ -792,8 +794,8 @@
     });
 
     expect(state.currentTabKey).toEqual('tab-1');
-    expect(state.tabs[0].key).toEqual('tab-1');
-    expect(state.tabs[1].key).not.toEqual('tab-1');
+    expect(state.tabs[0]!.key).toEqual('tab-1');
+    expect(state.tabs[1]!.key).not.toEqual('tab-1');
     expect(new Set(state.tabs.map((tab) => tab.key)).size).toEqual(2);
   });
 
@@ -976,29 +978,29 @@
     [
       'invalid perf CPU event type',
       (state: PerfConfigurationState) => {
-        state.tabs[0].configuration.cpuPerfType = '0';
+        state.tabs[0]!.configuration.cpuPerfType = '0';
       },
       'PMU Configuration Error: Invalid perf CPU event type',
     ],
     [
       'invalid sampling frequency',
       (state: PerfConfigurationState) => {
-        state.tabs[0].configuration.frequency = 0;
+        state.tabs[0]!.configuration.frequency = 0;
       },
       'PMU Configuration Error: Invalid sampling frequency',
     ],
     [
       'invalid sampling period',
       (state: PerfConfigurationState) => {
-        state.tabs[0].configuration.sampleByFrequency = false;
-        state.tabs[0].configuration.period = 0;
+        state.tabs[0]!.configuration.sampleByFrequency = false;
+        state.tabs[0]!.configuration.period = 0;
       },
       'PMU Configuration Error: Invalid sampling period',
     ],
     [
       'invalid target CPUs',
       (state: PerfConfigurationState) => {
-        state.tabs[0].configuration.targetCpus = '1,,3';
+        state.tabs[0]!.configuration.targetCpus = '1,,3';
       },
       'PMU Configuration Error: Invalid target CPU value',
     ],
diff --git a/ui/src/plugins/com.example.State/index.ts b/ui/src/plugins/com.example.State/index.ts
index 39a342d..9614124 100644
--- a/ui/src/plugins/com.example.State/index.ts
+++ b/ui/src/plugins/com.example.State/index.ts
@@ -12,52 +12,45 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-import {createStore, type Store} from '../../base/store';
-import {exists} from '../../base/utils';
+import {z} from 'zod';
 import type {Trace} from '../../public/trace';
 import type {PerfettoPlugin} from '../../public/plugin';
 import QueryPagePlugin from '../dev.perfetto.QueryPage';
 
-interface State {
-  counter: number;
-}
+export const STATE_SCHEMA = z.object({
+  counter: z.number(),
+});
+
+type State = z.infer<typeof STATE_SCHEMA>;
+
+const DEFAULT_STATE: State = {
+  counter: 0,
+};
 
 // This example plugin shows using state that is persisted in the
 // permalink.
 export default class implements PerfettoPlugin {
   static readonly id = 'com.example.State';
   static readonly dependencies = [QueryPagePlugin];
-  private store: Store<State> = createStore({counter: 0});
-
-  private migrate(initialState: unknown): State {
-    if (
-      exists(initialState) &&
-      typeof initialState === 'object' &&
-      'counter' in initialState &&
-      typeof initialState.counter === 'number'
-    ) {
-      return {counter: initialState.counter};
-    } else {
-      return {counter: 0};
-    }
-  }
 
   async onTraceLoad(ctx: Trace): Promise<void> {
-    this.store = ctx.mountStore('com.example.SkeletonStore', (init: unknown) =>
-      this.migrate(init),
-    );
+    const storage = ctx.registerStorage({
+      id: 'com.example.State',
+      schema: STATE_SCHEMA,
+      defaultValue: DEFAULT_STATE,
+    });
 
     ctx.commands.registerCommand({
       id: 'com.example.ShowCounter',
       name: 'Show ExampleState counter',
       callback: () => {
-        const counter = this.store.state.counter;
+        const counter = storage.get().counter;
         ctx.plugins.getPlugin(QueryPagePlugin).addQueryResultsTab({
           query: `SELECT ${counter} as counter;`,
           title: `Show counter ${counter}`,
         });
-        this.store.edit((draft) => {
-          ++draft.counter;
+        storage.set({
+          counter: counter + 1,
         });
       },
     });
diff --git a/ui/src/plugins/com.google.PixelMemory/index.ts b/ui/src/plugins/com.google.PixelMemory/index.ts
index 087ef65..faeea3f 100644
--- a/ui/src/plugins/com.google.PixelMemory/index.ts
+++ b/ui/src/plugins/com.google.PixelMemory/index.ts
@@ -199,7 +199,7 @@
       return {findMaxSql, noteTarget};
     } else {
       // pidList.length === 1
-      const noteTarget = pidList[0];
+      const noteTarget = pidList[0]!;
       const findMaxSql = `
         SELECT
           ts,
diff --git a/ui/src/plugins/com.meta.GpuCompute/details.ts b/ui/src/plugins/com.meta.GpuCompute/details.ts
index 8069f2a..c13ba61 100644
--- a/ui/src/plugins/com.meta.GpuCompute/details.ts
+++ b/ui/src/plugins/com.meta.GpuCompute/details.ts
@@ -597,7 +597,7 @@
   type Row = (typeof rows)[number];
   const pairs: Array<[Row, Row?]> = [];
   for (let i = 0; i < Math.ceil(rows.length / 2); i += 1) {
-    pairs.push([rows[i], rows[Math.ceil(rows.length / 2) + i]]);
+    pairs.push([rows[i]!, rows[Math.ceil(rows.length / 2) + i]]);
   }
 
   return m('table.pf-gpu-compute__metric-table', [
@@ -914,7 +914,7 @@
 
     return m(
       '.pf-gpu-compute__pad',
-      renderSingleTable(state.kernelTableData[0]),
+      renderSingleTable(state.kernelTableData[0]!),
     );
   },
 };
diff --git a/ui/src/plugins/com.meta.GpuCompute/index.ts b/ui/src/plugins/com.meta.GpuCompute/index.ts
index f4889fb..b88b4b3 100644
--- a/ui/src/plugins/com.meta.GpuCompute/index.ts
+++ b/ui/src/plugins/com.meta.GpuCompute/index.ts
@@ -163,7 +163,7 @@
       // while the query was in flight, discard the result.
       if (this.sliceId !== requestedSliceId) return;
       const hasMetrics = Array.isArray(data) && data.length > 0;
-      this.setToolbarInfo(hasMetrics ? data[0].toolbar : undefined);
+      this.setToolbarInfo(hasMetrics ? data[0]!.toolbar : undefined);
       if (!hasMetrics) {
         this.sliceId = firstId;
         this.ctx.activeInfoTab = 'summary';
@@ -287,7 +287,7 @@
           const hasMetrics = Array.isArray(data) && data.length > 0;
           return {
             hasMetrics,
-            toolbar: hasMetrics ? data[0].toolbar : undefined,
+            toolbar: hasMetrics ? data[0]!.toolbar : undefined,
           };
         },
       });
diff --git a/ui/src/plugins/com.meta.GpuCompute/summary.ts b/ui/src/plugins/com.meta.GpuCompute/summary.ts
index f058d1d..74f3eaa 100644
--- a/ui/src/plugins/com.meta.GpuCompute/summary.ts
+++ b/ui/src/plugins/com.meta.GpuCompute/summary.ts
@@ -115,7 +115,7 @@
       (n) =>
         `(SELECT cv.value FROM counter_vals cv WHERE cv.slice_id = cs.id AND cv.metric_name = '${n}' LIMIT 1)`,
     );
-    return names.length === 1 ? parts[0] : `COALESCE(${parts.join(', ')})`;
+    return names.length === 1 ? parts[0]! : `COALESCE(${parts.join(', ')})`;
   };
 
   const sql = `
diff --git a/ui/src/plugins/com.meta.GpuCompute/toolbar.ts b/ui/src/plugins/com.meta.GpuCompute/toolbar.ts
index 049c6a5..cf4a07c 100644
--- a/ui/src/plugins/com.meta.GpuCompute/toolbar.ts
+++ b/ui/src/plugins/com.meta.GpuCompute/toolbar.ts
@@ -149,7 +149,7 @@
     const i = opts.options.findIndex((o) => o.id === opts.baselineId);
     if (i < 0) return '—';
 
-    return `${i} - ${trunc(opts.options[i].label)}`;
+    return `${i} - ${trunc(opts.options[i]!.label)}`;
   })();
 
   // Available terminology providers for the View popup dropdown
diff --git a/ui/src/plugins/dev.perfetto.AggregateProfiles/aggregate_profiles_page.ts b/ui/src/plugins/dev.perfetto.AggregateProfiles/aggregate_profiles_page.ts
index c3cea65..eb44872 100644
--- a/ui/src/plugins/dev.perfetto.AggregateProfiles/aggregate_profiles_page.ts
+++ b/ui/src/plugins/dev.perfetto.AggregateProfiles/aggregate_profiles_page.ts
@@ -102,7 +102,7 @@
     );
     const next = Math.max(cur, 0) + step;
     if (next >= 0 && next < attrs.profiles.length) {
-      this.selectProfile(attrs, attrs.profiles[next]);
+      this.selectProfile(attrs, attrs.profiles[next]!);
     }
   }
 
diff --git a/ui/src/plugins/dev.perfetto.AggregateProfiles/index.ts b/ui/src/plugins/dev.perfetto.AggregateProfiles/index.ts
index 5ccbc1e..03144d2 100644
--- a/ui/src/plugins/dev.perfetto.AggregateProfiles/index.ts
+++ b/ui/src/plugins/dev.perfetto.AggregateProfiles/index.ts
@@ -24,38 +24,28 @@
   type AggregateProfilesPageState,
   AGGREGATE_PROFILES_PAGE_STATE_SCHEMA,
 } from './types';
-import type {Store} from '../../base/store';
-import {ensureExists} from '../../base/assert';
 
 export default class implements PerfettoPlugin {
   static readonly id = 'dev.perfetto.AggregateProfiles';
-  private store?: Store<AggregateProfilesPageState>;
-
-  private migratePageState(init: unknown): AggregateProfilesPageState {
-    const result = AGGREGATE_PROFILES_PAGE_STATE_SCHEMA.safeParse(init);
-    return result.data ?? {};
-  }
 
   async onTraceLoad(trace: Trace): Promise<void> {
-    this.store = trace.mountStore('dev.perfetto.AggregateProfiles', (init) =>
-      this.migratePageState(init),
-    );
+    const storage = trace.registerStorage({
+      id: 'dev.perfetto.AggregateProfiles',
+      schema: AGGREGATE_PROFILES_PAGE_STATE_SCHEMA,
+      defaultValue: {},
+    });
     const profiles = await this.getProfiles(trace);
     if (profiles.length === 0) {
       return;
     }
-    const store = ensureExists(this.store);
     trace.pages.registerPage({
       route: '/aggregateprofiles',
       render: () =>
         m(AggregateProfilesPage, {
           trace,
-          state: store.state,
+          state: storage.get(),
           onStateChange: (state: AggregateProfilesPageState) => {
-            store.edit((draft) => {
-              draft.selectedProfileId = state.selectedProfileId;
-              draft.flamegraphState = state.flamegraphState;
-            });
+            storage.set(state);
           },
           profiles,
         }),
@@ -68,7 +58,7 @@
       icon: 'analytics',
     });
     trace.onTraceReady.addListener(async () => {
-      const hasAnyTracks = trace.workspaces.all[0].flatTracks.length > 0;
+      const hasAnyTracks = trace.workspaces.all[0]!.flatTracks.length > 0;
       // TODO(lalitm): it's really bad that we're unconditionally navigating
       // to the profiles page: really we should check if the user has not already
       // set a page and then only navigate if no page is set. However:
diff --git a/ui/src/plugins/dev.perfetto.AggregateProfiles/storage_schema_unittest.ts b/ui/src/plugins/dev.perfetto.AggregateProfiles/storage_schema_unittest.ts
new file mode 100644
index 0000000..9a29534
--- /dev/null
+++ b/ui/src/plugins/dev.perfetto.AggregateProfiles/storage_schema_unittest.ts
@@ -0,0 +1,76 @@
+// Copyright (C) 2026 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 {AGGREGATE_PROFILES_PAGE_STATE_SCHEMA} from './types';
+
+const TREE_STATE = {
+  selectedMetricId: 'self',
+  addedMetricIds: ['total'],
+  displayMode: 'tree',
+  filters: [{kind: 'SHOW_STACK', filter: 'foo'}],
+  view: {kind: 'TOP_DOWN'},
+};
+
+describe('AGGREGATE_PROFILES_PAGE_STATE_SCHEMA', () => {
+  test('accepts empty state', () => {
+    expect(AGGREGATE_PROFILES_PAGE_STATE_SCHEMA.parse({})).toEqual({});
+  });
+
+  test('accepts a populated state', () => {
+    const state = {flamegraphState: TREE_STATE};
+    expect(AGGREGATE_PROFILES_PAGE_STATE_SCHEMA.parse(state)).toEqual(state);
+  });
+
+  test('fills defaults in nested tree explorer state', () => {
+    const result = AGGREGATE_PROFILES_PAGE_STATE_SCHEMA.parse({
+      flamegraphState: {
+        selectedMetricId: 'self',
+        filters: [],
+        view: {kind: 'BOTTOM_UP'},
+      },
+    });
+    expect(result.flamegraphState).toEqual({
+      selectedMetricId: 'self',
+      addedMetricIds: [],
+      displayMode: 'flamegraph',
+      filters: [],
+      view: {kind: 'BOTTOM_UP'},
+    });
+  });
+
+  test('rejects an invalid tree explorer state', () => {
+    const result = AGGREGATE_PROFILES_PAGE_STATE_SCHEMA.safeParse({
+      flamegraphState: {...TREE_STATE, view: {kind: 'NOT_A_VIEW'}},
+    });
+    expect(result.success).toBe(false);
+  });
+
+  test('rejects undefined (relies on defaultValue)', () => {
+    expect(
+      AGGREGATE_PROFILES_PAGE_STATE_SCHEMA.safeParse(undefined).success,
+    ).toBe(false);
+  });
+
+  test('accepts a selected profile id', () => {
+    const state = {selectedProfileId: 'profile-1', flamegraphState: TREE_STATE};
+    expect(AGGREGATE_PROFILES_PAGE_STATE_SCHEMA.parse(state)).toEqual(state);
+  });
+
+  test('rejects a non-string selected profile id', () => {
+    const result = AGGREGATE_PROFILES_PAGE_STATE_SCHEMA.safeParse({
+      selectedProfileId: 42,
+    });
+    expect(result.success).toBe(false);
+  });
+});
diff --git a/ui/src/plugins/dev.perfetto.AggregationBenchmark/benchmark.ts b/ui/src/plugins/dev.perfetto.AggregationBenchmark/benchmark.ts
index 7cceeb9..b8fb509 100644
--- a/ui/src/plugins/dev.perfetto.AggregationBenchmark/benchmark.ts
+++ b/ui/src/plugins/dev.perfetto.AggregationBenchmark/benchmark.ts
@@ -347,7 +347,7 @@
 function shuffle<T>(array: T[]): T[] {
   for (let i = array.length - 1; i > 0; i--) {
     const j = Math.floor(Math.random() * (i + 1));
-    [array[i], array[j]] = [array[j], array[i]];
+    [array[i], array[j]] = [array[j]!, array[i]!];
   }
   return array;
 }
@@ -360,9 +360,9 @@
   if (n === 0) throw new Error('No results to average');
 
   return {
-    approach: results[0].approach,
-    trackCount: results[0].trackCount,
-    rowCount: results[0].rowCount,
+    approach: results[0]!.approach,
+    trackCount: results[0]!.trackCount,
+    rowCount: results[0]!.rowCount,
     queryBuildTimeMs:
       results.reduce((sum, r) => sum + r.queryBuildTimeMs, 0) / n,
     queryExecuteTimeMs:
diff --git a/ui/src/plugins/dev.perfetto.AutoPinAndExpandTracks/index.ts b/ui/src/plugins/dev.perfetto.AutoPinAndExpandTracks/index.ts
index 99fbf90..63af99e 100644
--- a/ui/src/plugins/dev.perfetto.AutoPinAndExpandTracks/index.ts
+++ b/ui/src/plugins/dev.perfetto.AutoPinAndExpandTracks/index.ts
@@ -65,7 +65,7 @@
       if (!e.target.files) {
         return;
       }
-      const file = e.target.files[0];
+      const file = e.target.files[0]!;
       const textPromise = file.text();
 
       // Reset the value so onchange will be fired with the same file.
@@ -259,7 +259,7 @@
     let mostSimilarTrackDifferenceScore: number = 0;
 
     for (let i = 0; i < localTracks.length; i++) {
-      const localTrack = localTracks[i];
+      const localTrack = localTracks[i]!;
       const differenceScore = this.calculateSimilarityScore(
         localTrack.savedTrack,
         savedTrack,
diff --git a/ui/src/plugins/dev.perfetto.CpuFreq/cpu_freq_track.ts b/ui/src/plugins/dev.perfetto.CpuFreq/cpu_freq_track.ts
index 859a392..cb9f0a5 100644
--- a/ui/src/plugins/dev.perfetto.CpuFreq/cpu_freq_track.ts
+++ b/ui/src/plugins/dev.perfetto.CpuFreq/cpu_freq_track.ts
@@ -101,10 +101,10 @@
   if (left === -1) return undefined;
 
   return {
-    ts: Time.fromRaw(data.timestamps[left]),
+    ts: Time.fromRaw(data.timestamps[left]!),
     tsEnd: right === -1 ? undefined : Time.fromRaw(data.timestamps[right]),
-    value: data.lastFreqKHz[left],
-    idle: data.lastIdleValues[left],
+    value: data.lastFreqKHz[left]!,
+    idle: data.lastIdleValues[left]!,
   };
 }
 
@@ -315,11 +315,11 @@
         }
       }
 
-      const ts = tsCol[i];
-      const minFreq = minFreqCol[i];
-      const maxFreq = maxFreqCol[i];
-      const lastFreq = lastFreqCol[i];
-      const lastIdle = lastIdleCol[i];
+      const ts = tsCol[i]!;
+      const minFreq = minFreqCol[i]!;
+      const maxFreq = maxFreqCol[i]!;
+      const lastFreq = lastFreqCol[i]!;
+      const lastIdle = lastIdleCol[i]!;
 
       // Populate step area buffers with raw values
       const x = Number(ts - start);
@@ -329,7 +329,7 @@
       fills[i] = lastIdle < 0 ? 1.0 : 0.0;
       if (i > 0) {
         xnext[i - 1] = x;
-        const yprev = ys[i - 1];
+        const yprev = ys[i - 1]!;
         minYs[i] = Math.min(minFreq, yprev);
         maxYs[i] = Math.max(maxFreq, yprev);
       } else {
diff --git a/ui/src/plugins/dev.perfetto.DataExplorer/clipboard_operations.ts b/ui/src/plugins/dev.perfetto.DataExplorer/clipboard_operations.ts
index fa02763..26e18b5 100644
--- a/ui/src/plugins/dev.perfetto.DataExplorer/clipboard_operations.ts
+++ b/ui/src/plugins/dev.perfetto.DataExplorer/clipboard_operations.ts
@@ -152,7 +152,7 @@
   const updatedLayouts = new Map(state.nodeLayouts);
   clipboard.clipboardNodes.forEach((entry, index) => {
     if (!entry.isDocked) {
-      updatedLayouts.set(newNodes[index].nodeId, {
+      updatedLayouts.set(newNodes[index]!.nodeId, {
         x: entry.relativeX + pasteOffsetX,
         y: entry.relativeY + pasteOffsetY,
       });
diff --git a/ui/src/plugins/dev.perfetto.DataExplorer/clipboard_operations_unittest.ts b/ui/src/plugins/dev.perfetto.DataExplorer/clipboard_operations_unittest.ts
index c5d8df8..3de2d53 100644
--- a/ui/src/plugins/dev.perfetto.DataExplorer/clipboard_operations_unittest.ts
+++ b/ui/src/plugins/dev.perfetto.DataExplorer/clipboard_operations_unittest.ts
@@ -56,9 +56,9 @@
 
       expect(result).toBeDefined();
       expect(result?.clipboardNodes).toHaveLength(1);
-      expect(result?.clipboardNodes[0].relativeX).toBe(0);
-      expect(result?.clipboardNodes[0].relativeY).toBe(0);
-      expect(result?.clipboardNodes[0].isDocked).toBe(false);
+      expect(result?.clipboardNodes[0]!.relativeX).toBe(0);
+      expect(result?.clipboardNodes[0]!.relativeY).toBe(0);
+      expect(result?.clipboardNodes[0]!.isDocked).toBe(false);
     });
 
     it('should compute relative positions for multiple nodes', () => {
@@ -76,11 +76,11 @@
       expect(result).toBeDefined();
       expect(result?.clipboardNodes).toHaveLength(2);
       // First node is at origin (min x/y)
-      expect(result?.clipboardNodes[0].relativeX).toBe(0);
-      expect(result?.clipboardNodes[0].relativeY).toBe(0);
+      expect(result?.clipboardNodes[0]!.relativeX).toBe(0);
+      expect(result?.clipboardNodes[0]!.relativeY).toBe(0);
       // Second node is offset
-      expect(result?.clipboardNodes[1].relativeX).toBe(200);
-      expect(result?.clipboardNodes[1].relativeY).toBe(200);
+      expect(result?.clipboardNodes[1]!.relativeX).toBe(200);
+      expect(result?.clipboardNodes[1]!.relativeY).toBe(200);
     });
 
     it('should mark nodes without layout as docked', () => {
@@ -94,8 +94,8 @@
       });
 
       expect(result).toBeDefined();
-      expect(result?.clipboardNodes[0].isDocked).toBe(false);
-      expect(result?.clipboardNodes[1].isDocked).toBe(true);
+      expect(result?.clipboardNodes[0]!.isDocked).toBe(false);
+      expect(result?.clipboardNodes[1]!.isDocked).toBe(true);
     });
 
     it('should clone nodes for the clipboard', () => {
@@ -108,7 +108,7 @@
 
       expect(result).toBeDefined();
       // Cloned node should not be the same object reference
-      expect(result?.clipboardNodes[0].node).not.toBe(node);
+      expect(result?.clipboardNodes[0]!.node).not.toBe(node);
     });
 
     it('should capture primaryInput connections between selected nodes', () => {
@@ -127,9 +127,9 @@
 
       expect(result).toBeDefined();
       expect(result?.clipboardConnections).toHaveLength(1);
-      expect(result?.clipboardConnections[0].fromIndex).toBe(0);
-      expect(result?.clipboardConnections[0].toIndex).toBe(1);
-      expect(result?.clipboardConnections[0].portIndex).toBeUndefined();
+      expect(result?.clipboardConnections[0]!.fromIndex).toBe(0);
+      expect(result?.clipboardConnections[0]!.toIndex).toBe(1);
+      expect(result?.clipboardConnections[0]!.portIndex).toBeUndefined();
     });
 
     it('should not capture connections to nodes outside the selection', () => {
@@ -170,7 +170,7 @@
 
       expect(result).toBeDefined();
       expect(result?.clipboardConnections).toHaveLength(1);
-      expect(result?.clipboardConnections[0].portIndex).toBe(0);
+      expect(result?.clipboardConnections[0]!.portIndex).toBe(0);
     });
   });
 
@@ -231,7 +231,7 @@
       expect(result).toBeDefined();
       expect(result?.selectedNodes.size).toBe(1);
       // The selected ID should be the NEW (cloned) node's ID, not the clipboard node
-      const pastedNodeId = result?.rootNodes[0].nodeId;
+      const pastedNodeId = result?.rootNodes[0]!.nodeId;
       expect(result?.selectedNodes.has(pastedNodeId ?? '')).toBe(true);
     });
 
@@ -250,7 +250,7 @@
       );
 
       expect(result).toBeDefined();
-      const pastedNodeId = result?.rootNodes[0].nodeId ?? '';
+      const pastedNodeId = result?.rootNodes[0]!.nodeId ?? '';
       const layout = result?.nodeLayouts.get(pastedNodeId);
       expect(layout).toBeDefined();
       // relativeX + pasteOffsetX (50), relativeY + pasteOffsetY (50)
@@ -273,7 +273,7 @@
       );
 
       expect(result).toBeDefined();
-      const pastedNodeId = result?.rootNodes[0].nodeId ?? '';
+      const pastedNodeId = result?.rootNodes[0]!.nodeId ?? '';
       expect(result?.nodeLayouts.has(pastedNodeId)).toBe(false);
     });
 
@@ -312,8 +312,8 @@
       expect(result2).toBeDefined();
       expect(result2?.rootNodes).toHaveLength(2);
       // The two pasted nodes should have different IDs
-      expect(result2?.rootNodes[0].nodeId).not.toBe(
-        result2?.rootNodes[1].nodeId,
+      expect(result2?.rootNodes[0]!.nodeId).not.toBe(
+        result2?.rootNodes[1]!.nodeId,
       );
     });
 
diff --git a/ui/src/plugins/dev.perfetto.DataExplorer/dashboard/dashboard.ts b/ui/src/plugins/dev.perfetto.DataExplorer/dashboard/dashboard.ts
index 0c34bf8..401f910 100644
--- a/ui/src/plugins/dev.perfetto.DataExplorer/dashboard/dashboard.ts
+++ b/ui/src/plugins/dev.perfetto.DataExplorer/dashboard/dashboard.ts
@@ -1212,7 +1212,7 @@
         .join(', ');
       // Pick any sourceNodeId in the group for clear/remove operations —
       // those functions already propagate across linked sources.
-      const representativeSourceId = sourceIds[0];
+      const representativeSourceId = sourceIds[0]!;
       const chips = columns.sort().flatMap((col) => {
         // Gather filters for this column from all sources in the group.
         const colFilters: DashboardBrushFilter[] = [];
diff --git a/ui/src/plugins/dev.perfetto.DataExplorer/dashboard/dashboard_chart_view.ts b/ui/src/plugins/dev.perfetto.DataExplorer/dashboard/dashboard_chart_view.ts
index 1345431..63bc219 100644
--- a/ui/src/plugins/dev.perfetto.DataExplorer/dashboard/dashboard_chart_view.ts
+++ b/ui/src/plugins/dev.perfetto.DataExplorer/dashboard/dashboard_chart_view.ts
@@ -424,7 +424,7 @@
       if (hasNull) {
         parts.push(`${column} IS NULL`);
       }
-      clauses.push(parts.length > 1 ? `(${parts.join(' OR ')})` : parts[0]);
+      clauses.push(parts.length > 1 ? `(${parts.join(' OR ')})` : parts[0]!);
     }
 
     for (const rc of rangeConditions) {
@@ -442,7 +442,7 @@
   columns: ReadonlyArray<{name: string}>,
   chartType: ChartType = 'bar',
 ): ChartConfig {
-  const column = columns.length > 0 ? columns[0].name : '';
+  const column = columns.length > 0 ? columns[0]!.name : '';
   return {
     id: generateChartId(),
     column,
diff --git a/ui/src/plugins/dev.perfetto.DataExplorer/dashboard/dashboard_registry_unittest.ts b/ui/src/plugins/dev.perfetto.DataExplorer/dashboard/dashboard_registry_unittest.ts
index dc3b8b4..dd081a9 100644
--- a/ui/src/plugins/dev.perfetto.DataExplorer/dashboard/dashboard_registry_unittest.ts
+++ b/ui/src/plugins/dev.perfetto.DataExplorer/dashboard/dashboard_registry_unittest.ts
@@ -178,14 +178,14 @@
     ];
     const result = validateDashboardItems(items);
     expect(result).toHaveLength(1);
-    expect(result?.[0].kind).toBe('chart');
+    expect(result?.[0]!.kind).toBe('chart');
   });
 
   test('validates label items', () => {
     const items = [{kind: 'label', id: 'l1', text: 'Hello'}];
     const result = validateDashboardItems(items);
     expect(result).toHaveLength(1);
-    expect(result?.[0].kind).toBe('label');
+    expect(result?.[0]!.kind).toBe('label');
   });
 
   test('rejects chart without sourceNodeId', () => {
@@ -481,7 +481,7 @@
     const items = [{kind: 'divider', id: 'd1', row: 3}];
     const result = validateDashboardItems(items);
     expect(result).toHaveLength(1);
-    expect(result?.[0].kind).toBe('divider');
+    expect(result?.[0]!.kind).toBe('divider');
   });
 
   test('rejects divider without id', () => {
diff --git a/ui/src/plugins/dev.perfetto.DataExplorer/data_explorer.ts b/ui/src/plugins/dev.perfetto.DataExplorer/data_explorer.ts
index 3c3080e..bb4fdb8 100644
--- a/ui/src/plugins/dev.perfetto.DataExplorer/data_explorer.ts
+++ b/ui/src/plugins/dev.perfetto.DataExplorer/data_explorer.ts
@@ -793,7 +793,7 @@
     if (tab.dashboards.length <= 1) return;
     const idx = tab.dashboards.findIndex((d) => d.id === dbId);
     if (idx === -1) return;
-    const itemCount = tab.dashboards[idx].items.length;
+    const itemCount = tab.dashboards[idx]!.items.length;
 
     const doRemove = () => {
       const currentIdx = tab.dashboards.findIndex((d) => d.id === dbId);
@@ -803,7 +803,7 @@
       if (tab.activeSubTab === dbId) {
         if (tab.dashboards.length > 0) {
           const newIdx = Math.min(currentIdx, tab.dashboards.length - 1);
-          tab.activeSubTab = tab.dashboards[newIdx].id;
+          tab.activeSubTab = tab.dashboards[newIdx]!.id;
         } else {
           tab.activeSubTab = 'graph';
         }
diff --git a/ui/src/plugins/dev.perfetto.DataExplorer/data_explorer_tabs_storage.ts b/ui/src/plugins/dev.perfetto.DataExplorer/data_explorer_tabs_storage.ts
index ae4441e..3248233 100644
--- a/ui/src/plugins/dev.perfetto.DataExplorer/data_explorer_tabs_storage.ts
+++ b/ui/src/plugins/dev.perfetto.DataExplorer/data_explorer_tabs_storage.ts
@@ -64,7 +64,7 @@
 export const STORE_VERSION = 2;
 
 // Schema for the permalink store.
-const DATA_EXPLORER_PERSISTED_STATE_SCHEMA = z.object({
+export const DATA_EXPLORER_PERSISTED_STATE_SCHEMA = z.object({
   // Only version numbers allowed are 1 and 2.
   // v1 = old single-graph format, v2 = multi-tab format.
   version: z.union([z.literal(1), z.literal(STORE_VERSION)]),
@@ -83,18 +83,6 @@
 >;
 
 /**
- * Validates permalink state for the Data Explorer. Permalink state comes from
- * untrusted JSON, so anything that doesn't match the schema is discarded and
- * an empty state is returned instead.
- */
-export function parseDataExplorerPersistedState(
-  init: unknown,
-): DataExplorerPersistedState {
-  const result = DATA_EXPLORER_PERSISTED_STATE_SCHEMA.safeParse(init);
-  return result.data ?? {version: STORE_VERSION};
-}
-
-/**
  * Storage class for data explorer tabs state.
  * Persists tab layout (IDs, titles, serialized graphs) and active tab to
  * localStorage so that the Data Explorer survives page reloads.
diff --git a/ui/src/plugins/dev.perfetto.DataExplorer/data_explorer_tabs_storage_unittest.ts b/ui/src/plugins/dev.perfetto.DataExplorer/data_explorer_tabs_storage_unittest.ts
index 88f1667..084b83c 100644
--- a/ui/src/plugins/dev.perfetto.DataExplorer/data_explorer_tabs_storage_unittest.ts
+++ b/ui/src/plugins/dev.perfetto.DataExplorer/data_explorer_tabs_storage_unittest.ts
@@ -12,14 +12,9 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-import {
-  parseDataExplorerPersistedState,
-  STORE_VERSION,
-} from './data_explorer_tabs_storage';
+import {DATA_EXPLORER_PERSISTED_STATE_SCHEMA} from './data_explorer_tabs_storage';
 
-describe('parseDataExplorerPersistedState', () => {
-  const EMPTY_STATE = {version: STORE_VERSION};
-
+describe('DATA_EXPLORER_PERSISTED_STATE_SCHEMA', () => {
   describe('valid state', () => {
     test('accepts v2 multi-tab state', () => {
       const state = {
@@ -38,22 +33,22 @@
           },
         ],
       };
-      expect(parseDataExplorerPersistedState(state)).toEqual(state);
+      expect(DATA_EXPLORER_PERSISTED_STATE_SCHEMA.parse(state)).toEqual(state);
     });
 
     test('accepts v1 single-graph state', () => {
       const state = {version: 1, graphJson: '{}'};
-      expect(parseDataExplorerPersistedState(state)).toEqual(state);
+      expect(DATA_EXPLORER_PERSISTED_STATE_SCHEMA.parse(state)).toEqual(state);
     });
 
     test('accepts state with only a version', () => {
-      expect(parseDataExplorerPersistedState({version: 2})).toEqual({
+      expect(DATA_EXPLORER_PERSISTED_STATE_SCHEMA.parse({version: 2})).toEqual({
         version: 2,
       });
     });
 
     test('strips unknown top-level keys', () => {
-      const result = parseDataExplorerPersistedState({
+      const result = DATA_EXPLORER_PERSISTED_STATE_SCHEMA.parse({
         version: 2,
         unexpected: 'value',
       });
@@ -61,7 +56,7 @@
     });
 
     test('strips unknown keys inside tabs', () => {
-      const result = parseDataExplorerPersistedState({
+      const result = DATA_EXPLORER_PERSISTED_STATE_SCHEMA.parse({
         version: 2,
         tabs: [{id: 'tab-1', title: 'Graph 1', dashboards: []}],
       });
@@ -72,9 +67,9 @@
     });
   });
 
-  describe('invalid state falls back to empty state', () => {
+  describe('invalid state is rejected', () => {
     test('rejects non-string tab title', () => {
-      const result = parseDataExplorerPersistedState({
+      const result = DATA_EXPLORER_PERSISTED_STATE_SCHEMA.safeParse({
         version: 2,
         tabs: [
           {
@@ -84,62 +79,73 @@
         ],
         activeTabId: 'tab-1',
       });
-      expect(result).toEqual(EMPTY_STATE);
+      expect(result.success).toBe(false);
     });
 
     test('rejects non-string tab id', () => {
-      const result = parseDataExplorerPersistedState({
+      const result = DATA_EXPLORER_PERSISTED_STATE_SCHEMA.safeParse({
         version: 2,
         tabs: [{id: 123, title: 'Graph 1'}],
       });
-      expect(result).toEqual(EMPTY_STATE);
+      expect(result.success).toBe(false);
     });
 
     test('rejects non-string graphJson', () => {
-      const result = parseDataExplorerPersistedState({
+      const result = DATA_EXPLORER_PERSISTED_STATE_SCHEMA.safeParse({
         version: 1,
         graphJson: {nodes: []},
       });
-      expect(result).toEqual(EMPTY_STATE);
+      expect(result.success).toBe(false);
     });
 
     test('rejects non-array tabs', () => {
-      const result = parseDataExplorerPersistedState({
+      const result = DATA_EXPLORER_PERSISTED_STATE_SCHEMA.safeParse({
         version: 2,
         tabs: {id: 'tab-1', title: 'Graph 1'},
       });
-      expect(result).toEqual(EMPTY_STATE);
+      expect(result.success).toBe(false);
     });
 
     test('rejects malformed dashboard', () => {
-      const result = parseDataExplorerPersistedState({
+      const result = DATA_EXPLORER_PERSISTED_STATE_SCHEMA.safeParse({
         version: 2,
         dashboards: [{id: 'db-1'}],
       });
-      expect(result).toEqual(EMPTY_STATE);
+      expect(result.success).toBe(false);
     });
 
     test('rejects unsupported version', () => {
-      expect(parseDataExplorerPersistedState({version: 3})).toEqual(
-        EMPTY_STATE,
-      );
-      expect(parseDataExplorerPersistedState({version: '2'})).toEqual(
-        EMPTY_STATE,
-      );
+      expect(
+        DATA_EXPLORER_PERSISTED_STATE_SCHEMA.safeParse({version: 3}).success,
+      ).toBe(false);
+      expect(
+        DATA_EXPLORER_PERSISTED_STATE_SCHEMA.safeParse({version: '2'}).success,
+      ).toBe(false);
     });
 
     test('rejects missing version', () => {
-      expect(parseDataExplorerPersistedState({graphJson: '{}'})).toEqual(
-        EMPTY_STATE,
-      );
+      expect(
+        DATA_EXPLORER_PERSISTED_STATE_SCHEMA.safeParse({graphJson: '{}'})
+          .success,
+      ).toBe(false);
     });
 
     test('rejects non-object input', () => {
-      expect(parseDataExplorerPersistedState(undefined)).toEqual(EMPTY_STATE);
-      expect(parseDataExplorerPersistedState(null)).toEqual(EMPTY_STATE);
-      expect(parseDataExplorerPersistedState('state')).toEqual(EMPTY_STATE);
-      expect(parseDataExplorerPersistedState(42)).toEqual(EMPTY_STATE);
-      expect(parseDataExplorerPersistedState([])).toEqual(EMPTY_STATE);
+      expect(
+        DATA_EXPLORER_PERSISTED_STATE_SCHEMA.safeParse(undefined).success,
+      ).toBe(false);
+      expect(DATA_EXPLORER_PERSISTED_STATE_SCHEMA.safeParse(null).success).toBe(
+        false,
+      );
+      expect(
+        DATA_EXPLORER_PERSISTED_STATE_SCHEMA.safeParse('state').success,
+      ).toBe(false);
+      expect(DATA_EXPLORER_PERSISTED_STATE_SCHEMA.safeParse(42).success).toBe(
+        false,
+      );
+      expect(DATA_EXPLORER_PERSISTED_STATE_SCHEMA.safeParse([]).success).toBe(
+        false,
+      );
     });
   });
 });
diff --git a/ui/src/plugins/dev.perfetto.DataExplorer/datagrid_node_creation.ts b/ui/src/plugins/dev.perfetto.DataExplorer/datagrid_node_creation.ts
index 4472205..af0fbca 100644
--- a/ui/src/plugins/dev.perfetto.DataExplorer/datagrid_node_creation.ts
+++ b/ui/src/plugins/dev.perfetto.DataExplorer/datagrid_node_creation.ts
@@ -119,7 +119,7 @@
   // Check if the source node has exactly one child that's an AddColumnsNode with same join
   if (
     sourceNode.nextNodes.length === 1 &&
-    sourceNode.nextNodes[0].type === NodeType.kAddColumns
+    sourceNode.nextNodes[0]!.type === NodeType.kAddColumns
   ) {
     const existingAddColumnsNode = sourceNode.nextNodes[0] as AddColumnsNode;
     if (
@@ -159,9 +159,9 @@
   // If the source node has exactly one child and it's a FilterNode, add to that
   if (
     sourceNode.nextNodes.length === 1 &&
-    sourceNode.nextNodes[0].type === NodeType.kFilter
+    sourceNode.nextNodes[0]!.type === NodeType.kFilter
   ) {
-    const existingFilterNode = sourceNode.nextNodes[0];
+    const existingFilterNode = sourceNode.nextNodes[0]!;
     setFiltersOnNode(
       existingFilterNode,
       [
diff --git a/ui/src/plugins/dev.perfetto.DataExplorer/datagrid_node_creation_unittest.ts b/ui/src/plugins/dev.perfetto.DataExplorer/datagrid_node_creation_unittest.ts
index f28e597..04813f5 100644
--- a/ui/src/plugins/dev.perfetto.DataExplorer/datagrid_node_creation_unittest.ts
+++ b/ui/src/plugins/dev.perfetto.DataExplorer/datagrid_node_creation_unittest.ts
@@ -302,7 +302,7 @@
 
       // A new node should have been inserted
       expect(source.nextNodes).toHaveLength(1);
-      expect(source.nextNodes[0].type).toBe(NodeType.kFilter);
+      expect(source.nextNodes[0]!.type).toBe(NodeType.kFilter);
       expect(deps.initializedNodes.size).toBe(1);
       expect(stateUpdates).toHaveLength(1);
     });
@@ -330,9 +330,9 @@
 
       // New filter node should be inserted between source and sort
       expect(source.nextNodes).toHaveLength(1);
-      expect(source.nextNodes[0].type).toBe(NodeType.kFilter);
+      expect(source.nextNodes[0]!.type).toBe(NodeType.kFilter);
       // Sort should now be downstream of the new filter
-      expect(source.nextNodes[0].nextNodes).toContain(sortChild);
+      expect(source.nextNodes[0]!.nextNodes).toContain(sortChild);
     });
   });
 });
diff --git a/ui/src/plugins/dev.perfetto.DataExplorer/graph_io.ts b/ui/src/plugins/dev.perfetto.DataExplorer/graph_io.ts
index c24146b..a3f52e5 100644
--- a/ui/src/plugins/dev.perfetto.DataExplorer/graph_io.ts
+++ b/ui/src/plugins/dev.perfetto.DataExplorer/graph_io.ts
@@ -105,7 +105,7 @@
   input.onchange = async (event) => {
     const files = (event.target as HTMLInputElement).files;
     if (files && files.length > 0) {
-      const file = files[0];
+      const file = files[0]!;
       const reader = new FileReader();
       reader.onload = async (e) => {
         const text = e.target?.result as string;
@@ -299,7 +299,7 @@
       ...currentState,
       rootNodes: allNodes,
       nodeLayouts: newNodeLayouts,
-      selectedNodes: new Set([allNodes[0].nodeId]),
+      selectedNodes: new Set([allNodes[0]!.nodeId]),
       labels,
       loadGeneration: (currentState.loadGeneration ?? 0) + 1,
     }));
@@ -391,7 +391,7 @@
   input.onchange = (event) => {
     const files = (event.target as HTMLInputElement).files;
     if (files === null || files.length === 0) return;
-    const file = files[0];
+    const file = files[0]!;
     const reader = new FileReader();
     reader.onload = async (e) => {
       const text = e.target?.result;
diff --git a/ui/src/plugins/dev.perfetto.DataExplorer/history_manager.ts b/ui/src/plugins/dev.perfetto.DataExplorer/history_manager.ts
index 9c73228..76ce75d 100644
--- a/ui/src/plugins/dev.perfetto.DataExplorer/history_manager.ts
+++ b/ui/src/plugins/dev.perfetto.DataExplorer/history_manager.ts
@@ -86,7 +86,7 @@
     this.currentIndex--;
     this.isUndoRedoInProgress = true;
     const state = deserializeState(
-      this.history[this.currentIndex],
+      this.history[this.currentIndex]!,
       this.trace,
       this.sqlModules,
     );
@@ -103,7 +103,7 @@
     this.currentIndex++;
     this.isUndoRedoInProgress = true;
     const state = deserializeState(
-      this.history[this.currentIndex],
+      this.history[this.currentIndex]!,
       this.trace,
       this.sqlModules,
     );
diff --git a/ui/src/plugins/dev.perfetto.DataExplorer/history_manager_unittest.ts b/ui/src/plugins/dev.perfetto.DataExplorer/history_manager_unittest.ts
index 75bbbe7..6cc0ca9 100644
--- a/ui/src/plugins/dev.perfetto.DataExplorer/history_manager_unittest.ts
+++ b/ui/src/plugins/dev.perfetto.DataExplorer/history_manager_unittest.ts
@@ -125,7 +125,7 @@
     // Undo: remove aggregation node
     const undoneState = historyManager.undo();
     expect(undoneState).not.toBeNull();
-    expect(undoneState!.rootNodes[0].nextNodes.length).toBe(0);
+    expect(undoneState!.rootNodes[0]!.nextNodes.length).toBe(0);
   });
 
   test('should ignore layout-only changes', () => {
@@ -346,13 +346,13 @@
     // Undo: connection should be restored
     const undoneState = historyManager.undo();
     expect(undoneState).not.toBeNull();
-    expect(undoneState!.rootNodes[0].nextNodes.length).toBe(1);
-    expect(undoneState!.rootNodes[0].nextNodes[0].type).toBe(aggNode.type);
+    expect(undoneState!.rootNodes[0]!.nextNodes.length).toBe(1);
+    expect(undoneState!.rootNodes[0]!.nextNodes[0]!.type).toBe(aggNode.type);
 
     // Redo: connection should be removed again
     const redoneState = historyManager.redo();
     expect(redoneState).not.toBeNull();
-    expect(redoneState!.rootNodes[0].nextNodes.length).toBe(0);
+    expect(redoneState!.rootNodes[0]!.nextNodes.length).toBe(0);
   });
 
   test('should track multiple connection changes', () => {
@@ -412,12 +412,12 @@
     // Undo once: should have 1 connection
     const undoneState1 = historyManager.undo();
     expect(undoneState1).not.toBeNull();
-    expect(undoneState1!.rootNodes[0].nextNodes.length).toBe(1);
+    expect(undoneState1!.rootNodes[0]!.nextNodes.length).toBe(1);
 
     // Undo again: should have 0 connections
     const undoneState2 = historyManager.undo();
     expect(undoneState2).not.toBeNull();
-    expect(undoneState2!.rootNodes[0].nextNodes.length).toBe(0);
+    expect(undoneState2!.rootNodes[0]!.nextNodes.length).toBe(0);
   });
 
   // ========================================
@@ -467,14 +467,14 @@
     // Undo: filters should be empty
     const undoneState = historyManager.undo();
     expect(undoneState).not.toBeNull();
-    const restoredFilterNode = undoneState!.rootNodes[0]
+    const restoredFilterNode = undoneState!.rootNodes[0]!
       .nextNodes[0] as FilterNode;
     expect(restoredFilterNode.attrs.filters?.length ?? 0).toBe(0);
 
     // Redo: filter should be back
     const redoneState = historyManager.redo();
     expect(redoneState).not.toBeNull();
-    const redoneFilterNode = redoneState!.rootNodes[0]
+    const redoneFilterNode = redoneState!.rootNodes[0]!
       .nextNodes[0] as FilterNode;
     expect(redoneFilterNode.attrs.filters?.length ?? 0).toBe(1);
     const redoneFilter = redoneFilterNode.attrs.filters?.[0];
@@ -543,7 +543,7 @@
     // Undo once: should have 1 filter
     const undoneState1 = historyManager.undo();
     expect(undoneState1).not.toBeNull();
-    const filterNode1 = undoneState1!.rootNodes[0].nextNodes[0] as FilterNode;
+    const filterNode1 = undoneState1!.rootNodes[0]!.nextNodes[0] as FilterNode;
     expect(filterNode1.attrs.filters?.length ?? 0).toBe(1);
     const undoneFilter1 = filterNode1.attrs.filters?.[0];
     if (undoneFilter1 && 'value' in undoneFilter1) {
@@ -554,14 +554,14 @@
     // Undo again: should have 0 filters
     const undoneState2 = historyManager.undo();
     expect(undoneState2).not.toBeNull();
-    const filterNode2 = undoneState2!.rootNodes[0].nextNodes[0] as FilterNode;
+    const filterNode2 = undoneState2!.rootNodes[0]!.nextNodes[0] as FilterNode;
     expect(filterNode2.attrs.filters?.length ?? 0).toBe(0);
 
     // Redo twice: should have 2 filters back
     historyManager.redo();
     const redoneState = historyManager.redo();
     expect(redoneState).not.toBeNull();
-    const filterNode3 = redoneState!.rootNodes[0].nextNodes[0] as FilterNode;
+    const filterNode3 = redoneState!.rootNodes[0]!.nextNodes[0] as FilterNode;
     expect(filterNode3.attrs.filters?.length ?? 0).toBe(2);
   });
 
@@ -608,7 +608,7 @@
     // Undo: no columns should be checked
     const undoneState = historyManager.undo();
     expect(undoneState).not.toBeNull();
-    const restoredAggNode = undoneState!.rootNodes[0]
+    const restoredAggNode = undoneState!.rootNodes[0]!
       .nextNodes[0] as AggregationNode;
     const uncheckedCols = restoredAggNode.attrs.groupByColumns?.filter(
       (c) => c.checked,
@@ -618,13 +618,13 @@
     // Redo: 'id' column should be checked
     const redoneState = historyManager.redo();
     expect(redoneState).not.toBeNull();
-    const redoneAggNode = redoneState!.rootNodes[0]
+    const redoneAggNode = redoneState!.rootNodes[0]!
       .nextNodes[0] as AggregationNode;
     const checkedCols = redoneAggNode.attrs.groupByColumns?.filter(
       (c) => c.checked,
     );
     expect(checkedCols?.length ?? 0).toBe(1);
-    expect(checkedCols?.[0].name).toBe('id');
+    expect(checkedCols?.[0]!.name).toBe('id');
   });
 
   // ========================================
@@ -712,10 +712,10 @@
     // Undo: aggregation should be restored
     const undoneState = historyManager.undo();
     expect(undoneState).not.toBeNull();
-    expect(undoneState!.rootNodes[0].nextNodes.length).toBe(1);
+    expect(undoneState!.rootNodes[0]!.nextNodes.length).toBe(1);
 
     // Verify the restored node is an aggregation
-    const restoredNode = undoneState!.rootNodes[0].nextNodes[0];
+    const restoredNode = undoneState!.rootNodes[0]!.nextNodes[0]!;
     expect(restoredNode.type).toBe(aggNode.type);
   });
 
@@ -801,27 +801,31 @@
     // Undo to state 3: aggregation should be gone
     const state3Restored = historyManager.undo();
     expect(state3Restored).not.toBeNull();
-    const filterNode3 = state3Restored!.rootNodes[0].nextNodes[0] as FilterNode;
+    const filterNode3 = state3Restored!.rootNodes[0]!
+      .nextNodes[0] as FilterNode;
     expect(filterNode3.nextNodes.length).toBe(0);
     expect(filterNode3.attrs.filters?.length).toBe(1);
 
     // Undo to state 2: filter should be empty
     const state2Restored = historyManager.undo();
     expect(state2Restored).not.toBeNull();
-    const filterNode2 = state2Restored!.rootNodes[0].nextNodes[0] as FilterNode;
+    const filterNode2 = state2Restored!.rootNodes[0]!
+      .nextNodes[0] as FilterNode;
     expect(filterNode2.attrs.filters?.length ?? 0).toBe(0);
 
     // Undo to state 1: no filter node
     const state1Restored = historyManager.undo();
     expect(state1Restored).not.toBeNull();
-    expect(state1Restored!.rootNodes[0].nextNodes.length).toBe(0);
+    expect(state1Restored!.rootNodes[0]!.nextNodes.length).toBe(0);
 
     // Redo all the way forward
     historyManager.redo(); // State 2
     historyManager.redo(); // State 3
     const state4Restored = historyManager.redo(); // State 4
     expect(state4Restored).not.toBeNull();
-    expect(state4Restored!.rootNodes[0].nextNodes[0].nextNodes.length).toBe(1);
+    expect(state4Restored!.rootNodes[0]!.nextNodes[0]!.nextNodes.length).toBe(
+      1,
+    );
   });
 
   // ========================================
@@ -876,7 +880,7 @@
     // Single undo returns to state1
     const undoneState = historyManager.undo();
     expect(undoneState).not.toBeNull();
-    expect(undoneState!.rootNodes[0].nextNodes.length).toBe(0); // Back to just table
+    expect(undoneState!.rootNodes[0]!.nextNodes.length).toBe(0); // Back to just table
 
     // No more undo points
     expect(historyManager.canUndo()).toBe(false);
diff --git a/ui/src/plugins/dev.perfetto.DataExplorer/index.ts b/ui/src/plugins/dev.perfetto.DataExplorer/index.ts
index ce5ce0c..698d5b3 100644
--- a/ui/src/plugins/dev.perfetto.DataExplorer/index.ts
+++ b/ui/src/plugins/dev.perfetto.DataExplorer/index.ts
@@ -15,8 +15,7 @@
 import './styles.scss';
 import m from 'mithril';
 import type {PerfettoPlugin} from '../../public/plugin';
-import type {Trace} from '../../public/trace';
-import type {Store} from '../../base/store';
+import type {Storage, Trace} from '../../public/trace';
 import {shortUuid} from '../../base/uuid';
 import {getErrorMessage} from '../../base/errors';
 import {debounce} from '../../base/rate_limiters';
@@ -48,7 +47,7 @@
   createEmptyState,
   serializeAllDashboards,
   deserializeDashboardsForTab,
-  parseDataExplorerPersistedState,
+  DATA_EXPLORER_PERSISTED_STATE_SCHEMA,
   STORE_VERSION,
 } from './data_explorer_tabs_storage';
 import {dashboardRegistry} from './dashboard/dashboard_registry';
@@ -73,8 +72,8 @@
   // Track whether we've successfully loaded state from local storage
   private hasAttemptedStateLoad = false;
 
-  // Store for persisting state in permalinks
-  private permalinkStore?: Store<DataExplorerPersistedState>;
+  // Storage for persisting state in permalinks
+  private permalinkStorage?: Storage<DataExplorerPersistedState>;
 
   // Debounced saves to avoid expensive serialization on every state change
   private debouncedSave = debounce(() => {
@@ -146,7 +145,7 @@
     // If we closed the active tab, switch to an adjacent one
     if (this.activeTabId === tabId) {
       const newIndex = Math.min(index, this.tabs.length - 1);
-      this.activeTabId = this.tabs[newIndex].id;
+      this.activeTabId = this.tabs[newIndex]!.id;
     }
 
     this.debouncedSave();
@@ -183,13 +182,13 @@
     const [draggedTab] = this.tabs.splice(draggedIndex, 1);
 
     if (beforeTabId === undefined) {
-      this.tabs.push(draggedTab);
+      this.tabs.push(draggedTab!);
     } else {
       const beforeIndex = this.tabs.findIndex((t) => t.id === beforeTabId);
       if (beforeIndex === -1) {
-        this.tabs.push(draggedTab);
+        this.tabs.push(draggedTab!);
       } else {
-        this.tabs.splice(beforeIndex, 0, draggedTab);
+        this.tabs.splice(beforeIndex, 0, draggedTab!);
       }
     }
 
@@ -261,16 +260,17 @@
   // --- Permalink store ---
 
   private mountPermalinkStore(trace: Trace): void {
-    if (this.permalinkStore) return;
+    if (this.permalinkStorage) return;
 
-    this.permalinkStore = trace.mountStore<DataExplorerPersistedState>(
-      'dev.perfetto.DataExplorer',
-      parseDataExplorerPersistedState,
-    );
+    this.permalinkStorage = trace.registerStorage({
+      id: 'dev.perfetto.DataExplorer',
+      schema: DATA_EXPLORER_PERSISTED_STATE_SCHEMA,
+      defaultValue: {version: STORE_VERSION},
+    });
   }
 
   private saveToPermalinkStore(): void {
-    if (!this.permalinkStore) return;
+    if (!this.permalinkStorage) return;
 
     const hasDashboardContent = (tab: DataExplorerTab): boolean =>
       tab.dashboards.some((db) => db.items.length > 0);
@@ -288,13 +288,11 @@
             : undefined,
       }));
 
-    this.permalinkStore.edit((draft) => {
-      draft.version = STORE_VERSION;
-      draft.tabs = tabsData.length > 0 ? tabsData : undefined;
-      draft.activeTabId = this.activeTabId;
-      draft.dashboards = serializeAllDashboards(this.tabs);
-      // Clear deprecated single-graph field
-      draft.graphJson = undefined;
+    this.permalinkStorage.set({
+      version: STORE_VERSION,
+      tabs: tabsData.length > 0 ? tabsData : undefined,
+      activeTabId: this.activeTabId,
+      dashboards: serializeAllDashboards(this.tabs),
     });
   }
 
@@ -363,7 +361,7 @@
 
   private loadStateFromSources(trace: Trace, sqlModules: SqlModules): void {
     // Priority 1: Check permalink store
-    const permalinkState = this.permalinkStore?.state;
+    const permalinkState = this.permalinkStorage?.get();
     if (permalinkState) {
       // Try multi-tab format first (version 2+)
       if (permalinkState.tabs !== undefined && permalinkState.tabs.length > 0) {
@@ -378,7 +376,7 @@
             permalinkState.activeTabId !== undefined &&
             this.tabs.some((t) => t.id === permalinkState.activeTabId)
               ? permalinkState.activeTabId
-              : this.tabs[0].id;
+              : this.tabs[0]!.id;
           return;
         } catch (e) {
           const msg = getErrorMessage(e);
@@ -429,7 +427,7 @@
           (t) => t.id === persistedTabs.activeTabId,
         )
           ? persistedTabs.activeTabId
-          : this.tabs[0].id;
+          : this.tabs[0]!.id;
         return;
       } catch (e) {
         console.debug(
diff --git a/ui/src/plugins/dev.perfetto.DataExplorer/json_handler_unittest.ts b/ui/src/plugins/dev.perfetto.DataExplorer/json_handler_unittest.ts
index 5bbc4f7..b09f2a3 100644
--- a/ui/src/plugins/dev.perfetto.DataExplorer/json_handler_unittest.ts
+++ b/ui/src/plugins/dev.perfetto.DataExplorer/json_handler_unittest.ts
@@ -175,7 +175,7 @@
     const deserializedState = deserializeState(json, trace, sqlModules);
 
     expect(deserializedState.rootNodes.length).toBe(1);
-    const deserializedTableNode = deserializedState.rootNodes[0];
+    const deserializedTableNode = deserializedState.rootNodes[0]!;
     expect(deserializedTableNode.nextNodes.length).toBe(1);
     const deserializedModifyNode = deserializedTableNode.nextNodes[0];
     expect(
@@ -201,14 +201,14 @@
           {
             name: 'name',
             checked: true,
-            type: sliceTable.columns[0].type,
+            type: sliceTable.columns[0]!.type,
           },
         ],
         aggregations: [
           {
             column: {
               name: 'dur',
-              type: sliceTable.columns[2].type,
+              type: sliceTable.columns[2]!.type,
             },
             aggregationOp: 'SUM',
             newColumnName: 'total_dur',
@@ -230,22 +230,22 @@
     const deserializedState = deserializeState(json, trace, sqlModules);
 
     expect(deserializedState.rootNodes.length).toBe(1);
-    const deserializedTableNode = deserializedState.rootNodes[0];
+    const deserializedTableNode = deserializedState.rootNodes[0]!;
     expect(deserializedTableNode.nextNodes.length).toBe(1);
     const deserializedAggregationNode = deserializedTableNode
       .nextNodes[0] as AggregationNode;
     expect(deserializedAggregationNode.primaryInput?.nodeId).toBe(
       deserializedTableNode.nodeId,
     );
-    expect(deserializedAggregationNode.attrs.groupByColumns[0].name).toBe(
+    expect(deserializedAggregationNode.attrs.groupByColumns[0]!.name).toBe(
       'name',
     );
     expect(
-      deserializedAggregationNode.attrs.aggregations[0].aggregationOp,
+      deserializedAggregationNode.attrs.aggregations[0]!.aggregationOp,
     ).toBe('SUM');
-    expect(deserializedAggregationNode.attrs.aggregations[0].column?.name).toBe(
-      'dur',
-    );
+    expect(
+      deserializedAggregationNode.attrs.aggregations[0]!.column?.name,
+    ).toBe('dur');
   });
 
   test('serializes and deserializes sql source node', () => {
@@ -300,7 +300,7 @@
     expect(deserializedState.rootNodes.length).toBe(2);
 
     // Find the sql node in the deserialized graph
-    const deserializedTableNode1 = deserializedState.rootNodes[0];
+    const deserializedTableNode1 = deserializedState.rootNodes[0]!;
     const deserializedSqlNode = deserializedTableNode1
       .nextNodes[0] as SqlSourceNode;
 
@@ -312,10 +312,10 @@
     // rootNodeIds are serialized in order and restored in the same order.
     // tableNode1 (slice) was connected to port 0, tableNode2 (thread) to port 1.
     expect(deserializedSqlNode.secondaryInputs.connections.get(0)?.nodeId).toBe(
-      deserializedState.rootNodes[0].nodeId,
+      deserializedState.rootNodes[0]!.nodeId,
     );
     expect(deserializedSqlNode.secondaryInputs.connections.get(1)?.nodeId).toBe(
-      deserializedState.rootNodes[1].nodeId,
+      deserializedState.rootNodes[1]!.nodeId,
     );
   });
 
@@ -350,8 +350,8 @@
     const deserializedState = deserializeState(json, trace, sqlModules);
 
     expect(deserializedState.rootNodes.length).toBe(2);
-    const deserializedTableNode1 = deserializedState.rootNodes[0];
-    const deserializedTableNode2 = deserializedState.rootNodes[1];
+    const deserializedTableNode1 = deserializedState.rootNodes[0]!;
+    const deserializedTableNode2 = deserializedState.rootNodes[1]!;
     expect(deserializedTableNode1.nextNodes.length).toBe(1);
     const deserializedIntervalIntersectNode = deserializedTableNode1
       .nextNodes[0] as IntervalIntersectNode;
@@ -409,9 +409,9 @@
     const deserializedState = deserializeState(json, trace, sqlModules);
 
     expect(deserializedState.rootNodes.length).toBe(3);
-    const deserializedTableNode1 = deserializedState.rootNodes[0];
-    const deserializedTableNode2 = deserializedState.rootNodes[1];
-    const deserializedTableNode3 = deserializedState.rootNodes[2];
+    const deserializedTableNode1 = deserializedState.rootNodes[0]!;
+    const deserializedTableNode2 = deserializedState.rootNodes[1]!;
+    const deserializedTableNode3 = deserializedState.rootNodes[2]!;
     expect(deserializedTableNode1.nextNodes.length).toBe(1);
     const deserializedIntervalIntersectNode = deserializedTableNode1
       .nextNodes[0] as IntervalIntersectNode;
@@ -471,7 +471,7 @@
     const deserializedState = deserializeState(json, trace, sqlModules);
 
     expect(deserializedState.rootNodes.length).toBe(1);
-    const deserializedTableNode = deserializedState.rootNodes[0];
+    const deserializedTableNode = deserializedState.rootNodes[0]!;
     expect(deserializedTableNode.nextNodes.length).toBe(1);
     const deserializedModifyNode = deserializedTableNode
       .nextNodes[0] as ModifyColumnsNode;
@@ -511,7 +511,7 @@
     const deserializedState = deserializeState(json, trace, sqlModules);
 
     expect(deserializedState.rootNodes.length).toBe(1);
-    const deserializedTableNode = deserializedState.rootNodes[0];
+    const deserializedTableNode = deserializedState.rootNodes[0]!;
     expect(deserializedTableNode.nextNodes.length).toBe(1);
     const deserializedFilterNode = deserializedTableNode
       .nextNodes[0] as FilterNode;
@@ -557,7 +557,7 @@
     const deserializedState = deserializeState(json, trace, sqlModules);
 
     expect(deserializedState.rootNodes.length).toBe(1);
-    const deserializedTableNode = deserializedState.rootNodes[0];
+    const deserializedTableNode = deserializedState.rootNodes[0]!;
     expect(deserializedTableNode.nextNodes.length).toBe(1);
     const deserializedFilterNode = deserializedTableNode
       .nextNodes[0] as FilterNode;
@@ -596,8 +596,8 @@
     const deserializedState = deserializeState(json, trace, sqlModules);
 
     expect(deserializedState.rootNodes.length).toBe(2);
-    const deserializedTableNode = deserializedState.rootNodes[0];
-    const deserializedSliceNode = deserializedState.rootNodes[1];
+    const deserializedTableNode = deserializedState.rootNodes[0]!;
+    const deserializedSliceNode = deserializedState.rootNodes[1]!;
 
     // Coordinates are normalized so top-left is at (minX, minY)
     // Original: tableNode (10, 20), sliceNode (100, 200)
@@ -641,7 +641,7 @@
     const deserializedState = deserializeState(json, trace, sqlModules);
 
     expect(deserializedState.rootNodes.length).toBe(1);
-    const deserializedTableNode = deserializedState.rootNodes[0];
+    const deserializedTableNode = deserializedState.rootNodes[0]!;
     expect(deserializedTableNode.nextNodes.length).toBe(1);
     const deserializedFilterNode = deserializedTableNode
       .nextNodes[0] as FilterNode;
@@ -702,7 +702,7 @@
       sqlModules,
     );
     const deserializedTableNode1 =
-      deserializedStateWithPrimaryInput.rootNodes[0];
+      deserializedStateWithPrimaryInput.rootNodes[0]!;
     const deserializedModifyNode1 = deserializedTableNode1
       .nextNodes[0] as ModifyColumnsNode;
     expect(deserializedModifyNode1.primaryInput?.nodeId).toBe(
@@ -744,7 +744,7 @@
     const deserializedState = deserializeState(json, trace, sqlModules);
 
     expect(deserializedState.rootNodes.length).toBe(1);
-    const deserializedTableNode = deserializedState.rootNodes[0];
+    const deserializedTableNode = deserializedState.rootNodes[0]!;
     expect(deserializedTableNode.nextNodes.length).toBe(1);
     const deserializedModifyNode = deserializedTableNode
       .nextNodes[0] as ModifyColumnsNode;
@@ -753,7 +753,7 @@
       .nextNodes[0] as FilterNode;
     expect(deserializedFilterNode.attrs.filters).toBeDefined();
     expect(deserializedFilterNode.attrs.filters?.length).toBe(1);
-    expect(deserializedFilterNode.attrs.filters?.[0].column).toBe('new_col');
+    expect(deserializedFilterNode.attrs.filters?.[0]!.column).toBe('new_col');
   });
 
   test('serializes and deserializes add columns node', () => {
@@ -784,7 +784,7 @@
     const deserializedState = deserializeState(json, trace, sqlModules);
 
     expect(deserializedState.rootNodes.length).toBe(1);
-    const deserializedTableNode = deserializedState.rootNodes[0];
+    const deserializedTableNode = deserializedState.rootNodes[0]!;
     expect(deserializedTableNode.nextNodes.length).toBe(1);
     const deserializedNode = deserializedTableNode
       .nextNodes[0] as AddColumnsNode;
@@ -838,8 +838,8 @@
 
     // Verify root nodes
     expect(deserializedState.rootNodes.length).toBe(2);
-    const deserializedTableNode1 = deserializedState.rootNodes[0];
-    const deserializedTableNode2 = deserializedState.rootNodes[1];
+    const deserializedTableNode1 = deserializedState.rootNodes[0]!;
+    const deserializedTableNode2 = deserializedState.rootNodes[1]!;
 
     // Verify main connection (primaryInput)
     expect(deserializedTableNode1.nextNodes.length).toBe(1);
@@ -862,7 +862,7 @@
 
     // Verify tableNode2 has the connection back to addColumnsNode
     expect(deserializedTableNode2.nextNodes.length).toBe(1);
-    expect(deserializedTableNode2.nextNodes[0].nodeId).toBe(
+    expect(deserializedTableNode2.nextNodes[0]!.nodeId).toBe(
       deserializedAddColumnsNode.nodeId,
     );
 
@@ -899,12 +899,12 @@
     // Get all columns from the table to find one to rename
     const allColumns = tableNode1.finalCols;
     // Find a column to rename (let's use the first one)
-    const columnToRename = allColumns[0];
+    const columnToRename = allColumns[0]!;
 
     // Create modify columns node that renames a column using alias
     const selectedColumnsWithAlias = [
       {
-        ...allColumns[0],
+        ...allColumns[0]!,
         alias: 'renamed_column',
         checked: true,
       },
@@ -1044,10 +1044,10 @@
 
     // Verify the aggregation node sees the aliased column
     expect(aggregationNode.attrs.groupByColumns.length).toBe(1);
-    expect(aggregationNode.attrs.groupByColumns[0].name).toBe(
+    expect(aggregationNode.attrs.groupByColumns[0]!.name).toBe(
       'timestamp_alias',
     );
-    expect(aggregationNode.attrs.groupByColumns[0].name).toBe(
+    expect(aggregationNode.attrs.groupByColumns[0]!.name).toBe(
       'timestamp_alias',
     );
 
@@ -1064,7 +1064,7 @@
 
     // Navigate to the deserialized aggregation node
     expect(deserializedState.rootNodes.length).toBe(1);
-    const deserializedTableNode = deserializedState.rootNodes[0];
+    const deserializedTableNode = deserializedState.rootNodes[0]!;
     expect(deserializedTableNode.nextNodes.length).toBe(1);
 
     const deserializedModifyNode = deserializedTableNode.nextNodes[0] as
@@ -1090,10 +1090,10 @@
     expect(deserializedAggNode).toBeDefined();
     expect(deserializedAggNode?.type).toBe(NodeType.kAggregation);
     expect(deserializedAggNode?.attrs.groupByColumns.length).toBe(1);
-    expect(deserializedAggNode?.attrs.groupByColumns[0].name).toBe(
+    expect(deserializedAggNode?.attrs.groupByColumns[0]!.name).toBe(
       'timestamp_alias',
     );
-    expect(deserializedAggNode?.attrs.groupByColumns[0].name).toBe(
+    expect(deserializedAggNode?.attrs.groupByColumns[0]!.name).toBe(
       'timestamp_alias',
     );
   });
@@ -1124,7 +1124,7 @@
     const deserializedState = deserializeState(json, trace, sqlModules);
 
     expect(deserializedState.rootNodes.length).toBe(1);
-    const deserializedTableNode = deserializedState.rootNodes[0];
+    const deserializedTableNode = deserializedState.rootNodes[0]!;
     expect(deserializedTableNode.nextNodes.length).toBe(1);
     const deserializedNode = deserializedTableNode
       .nextNodes[0] as LimitAndOffsetNode;
@@ -1160,7 +1160,7 @@
     const deserializedState = deserializeState(json, trace, sqlModules);
 
     expect(deserializedState.rootNodes.length).toBe(1);
-    const deserializedTableNode = deserializedState.rootNodes[0];
+    const deserializedTableNode = deserializedState.rootNodes[0]!;
     expect(deserializedTableNode.nextNodes.length).toBe(1);
     const deserializedNode = deserializedTableNode.nextNodes[0] as SortNode;
     expect(deserializedNode.attrs.sortCriteria).toEqual([
@@ -1206,23 +1206,23 @@
     const deserializedState = deserializeState(json, trace, sqlModules);
 
     expect(deserializedState.rootNodes.length).toBe(1);
-    const deserializedTableNode = deserializedState.rootNodes[0];
+    const deserializedTableNode = deserializedState.rootNodes[0]!;
     expect(deserializedTableNode.nextNodes.length).toBe(1);
     const deserializedNode = deserializedTableNode.nextNodes[0] as FilterNode;
 
     // Verify filters
     expect(deserializedNode.attrs.filters).toBeDefined();
     expect(deserializedNode.attrs.filters?.length).toBe(2);
-    expect(deserializedNode.attrs.filters?.[0].column).toBe('name');
-    expect(deserializedNode.attrs.filters?.[0].op).toBe('=');
+    expect(deserializedNode.attrs.filters?.[0]!.column).toBe('name');
+    expect(deserializedNode.attrs.filters?.[0]!.op).toBe('=');
     if (
       deserializedNode.attrs.filters?.[0] &&
       'value' in deserializedNode.attrs.filters[0]
     ) {
       expect(deserializedNode.attrs.filters[0].value).toBe('test');
     }
-    expect(deserializedNode.attrs.filters?.[1].column).toBe('dur');
-    expect(deserializedNode.attrs.filters?.[1].op).toBe('>');
+    expect(deserializedNode.attrs.filters?.[1]!.column).toBe('dur');
+    expect(deserializedNode.attrs.filters?.[1]!.op).toBe('>');
     if (
       deserializedNode.attrs.filters?.[1] &&
       'value' in deserializedNode.attrs.filters[1]
@@ -1269,17 +1269,17 @@
     const deserializedState = deserializeState(json, trace, sqlModules);
 
     expect(deserializedState.rootNodes.length).toBe(1);
-    const deserializedTableNode = deserializedState.rootNodes[0];
+    const deserializedTableNode = deserializedState.rootNodes[0]!;
     expect(deserializedTableNode.nextNodes.length).toBe(1);
     const deserializedNode = deserializedTableNode.nextNodes[0] as FilterNode;
 
     // Verify filter
     expect(deserializedNode.attrs.filters).toBeDefined();
     expect(deserializedNode.attrs.filters?.length).toBe(1);
-    expect(deserializedNode.attrs.filters?.[0].column).toBe('name');
-    expect(deserializedNode.attrs.filters?.[0].op).toBe('is null');
+    expect(deserializedNode.attrs.filters?.[0]!.column).toBe('name');
+    expect(deserializedNode.attrs.filters?.[0]!.op).toBe('is null');
     // Null filters don't have a value property
-    expect('value' in deserializedNode.attrs.filters![0]).toBe(false);
+    expect('value' in deserializedNode.attrs.filters![0]!).toBe(false);
   });
 
   test('serializes and deserializes merge node with equality condition', () => {
@@ -1324,8 +1324,8 @@
     const deserializedState = deserializeState(json, trace, sqlModules);
 
     expect(deserializedState.rootNodes.length).toBe(2);
-    const deserializedTableNode1 = deserializedState.rootNodes[0];
-    const deserializedTableNode2 = deserializedState.rootNodes[1];
+    const deserializedTableNode1 = deserializedState.rootNodes[0]!;
+    const deserializedTableNode2 = deserializedState.rootNodes[1]!;
     expect(deserializedTableNode1.nextNodes.length).toBe(1);
     const deserializedJoinNode = deserializedTableNode1
       .nextNodes[0] as JoinNode;
@@ -1386,7 +1386,7 @@
     const deserializedState = deserializeState(json, trace, sqlModules);
 
     expect(deserializedState.rootNodes.length).toBe(2);
-    const deserializedTableNode1 = deserializedState.rootNodes[0];
+    const deserializedTableNode1 = deserializedState.rootNodes[0]!;
     expect(deserializedTableNode1.nextNodes.length).toBe(1);
     const deserializedJoinNode = deserializedTableNode1
       .nextNodes[0] as JoinNode;
@@ -1446,8 +1446,8 @@
     expect(deserializedState.rootNodes.length).toBe(2);
 
     // Find the join node
-    const table1 = deserializedState.rootNodes[0];
-    const table2 = deserializedState.rootNodes[1];
+    const table1 = deserializedState.rootNodes[0]!;
+    const table2 = deserializedState.rootNodes[1]!;
     expect(table1.nextNodes.length).toBe(1);
     expect(table2.nextNodes.length).toBe(1);
     expect(table1.nextNodes[0]).toBe(table2.nextNodes[0]); // Same join node
@@ -1516,9 +1516,9 @@
     const deserializedState = deserializeState(json, trace, sqlModules);
 
     expect(deserializedState.rootNodes.length).toBe(3);
-    const deserializedTableNode1 = deserializedState.rootNodes[0];
-    const deserializedTableNode2 = deserializedState.rootNodes[1];
-    const deserializedTableNode3 = deserializedState.rootNodes[2];
+    const deserializedTableNode1 = deserializedState.rootNodes[0]!;
+    const deserializedTableNode2 = deserializedState.rootNodes[1]!;
+    const deserializedTableNode3 = deserializedState.rootNodes[2]!;
     expect(deserializedTableNode1.nextNodes.length).toBe(1);
     const deserializedUnionNode = deserializedTableNode1
       .nextNodes[0] as UnionNode;
@@ -1537,16 +1537,16 @@
       (deserializedUnionNode as UnionNode).attrs.selectedColumns.length,
     ).toBe(2);
     expect(
-      (deserializedUnionNode as UnionNode).attrs.selectedColumns[0].name,
+      (deserializedUnionNode as UnionNode).attrs.selectedColumns[0]!.name,
     ).toBe('name');
     expect(
-      (deserializedUnionNode as UnionNode).attrs.selectedColumns[0].checked,
+      (deserializedUnionNode as UnionNode).attrs.selectedColumns[0]!.checked,
     ).toBe(true);
     expect(
-      (deserializedUnionNode as UnionNode).attrs.selectedColumns[1].name,
+      (deserializedUnionNode as UnionNode).attrs.selectedColumns[1]!.name,
     ).toBe('ts');
     expect(
-      (deserializedUnionNode as UnionNode).attrs.selectedColumns[1].checked,
+      (deserializedUnionNode as UnionNode).attrs.selectedColumns[1]!.checked,
     ).toBe(true);
   });
 
@@ -1606,7 +1606,7 @@
     const deserializedState = deserializeState(json, trace, sqlModules);
 
     expect(deserializedState.rootNodes.length).toBe(2);
-    const deserializedTableNode1 = deserializedState.rootNodes[0];
+    const deserializedTableNode1 = deserializedState.rootNodes[0]!;
     expect(deserializedTableNode1.nextNodes.length).toBe(1);
     const deserializedJoinNode = deserializedTableNode1
       .nextNodes[0] as JoinNode;
@@ -1615,8 +1615,8 @@
       .nextNodes[0] as FilterNode;
     expect(deserializedFilterNode.attrs.filters).toBeDefined();
     expect(deserializedFilterNode.attrs.filters?.length).toBe(1);
-    expect(deserializedFilterNode.attrs.filters?.[0].column).toBe('dur');
-    expect(deserializedFilterNode.attrs.filters?.[0].op).toBe('>');
+    expect(deserializedFilterNode.attrs.filters?.[0]!.column).toBe('dur');
+    expect(deserializedFilterNode.attrs.filters?.[0]!.op).toBe('>');
   });
 
   test('serializes and deserializes union node', () => {
@@ -1659,13 +1659,13 @@
     const deserializedState = deserializeState(json, trace, sqlModules);
 
     expect(deserializedState.rootNodes.length).toBe(2);
-    const deserializedTableNode1 = deserializedState.rootNodes[0];
+    const deserializedTableNode1 = deserializedState.rootNodes[0]!;
     expect(deserializedTableNode1.nextNodes.length).toBe(1);
     const deserializedUnionNode = deserializedTableNode1
       .nextNodes[0] as UnionNode;
     // Verify unchecked column is preserved
     expect(
-      (deserializedUnionNode as UnionNode).attrs.selectedColumns[1].checked,
+      (deserializedUnionNode as UnionNode).attrs.selectedColumns[1]!.checked,
     ).toBe(false);
   });
 
@@ -1749,12 +1749,12 @@
           {
             name: 'name',
             checked: true,
-            type: sliceTable.columns[0].type,
+            type: sliceTable.columns[0]!.type,
           },
           {
             name: 'ts',
             checked: true,
-            type: sliceTable.columns[1].type,
+            type: sliceTable.columns[1]!.type,
           },
         ],
       },
@@ -1776,13 +1776,13 @@
     const deserializedState = deserializeState(json, trace, sqlModules);
 
     expect(deserializedState.rootNodes.length).toBe(1);
-    const deserializedTableNode = deserializedState.rootNodes[0];
+    const deserializedTableNode = deserializedState.rootNodes[0]!;
     expect(deserializedTableNode.nextNodes.length).toBe(1);
     const deserializedNode = deserializedTableNode
       .nextNodes[0] as ModifyColumnsNode;
     expect(deserializedNode.attrs.selectedColumns.length).toBe(2);
-    expect(deserializedNode.attrs.selectedColumns[0].name).toBe('name');
-    expect(deserializedNode.attrs.selectedColumns[1].name).toBe('ts');
+    expect(deserializedNode.attrs.selectedColumns[0]!.name).toBe('name');
+    expect(deserializedNode.attrs.selectedColumns[1]!.name).toBe('ts');
   });
 
   test('serializes modify columns node without primaryInput', () => {
@@ -1820,19 +1820,19 @@
           {
             name: 'name',
             checked: true,
-            type: sliceTable.columns[0].type,
+            type: sliceTable.columns[0]!.type,
           },
           {
             name: 'ts',
             checked: true,
-            type: sliceTable.columns[1].type,
+            type: sliceTable.columns[1]!.type,
           },
         ],
         aggregations: [
           {
             column: {
               name: 'dur',
-              type: sliceTable.columns[2].type,
+              type: sliceTable.columns[2]!.type,
             },
             aggregationOp: 'SUM',
             newColumnName: 'total_dur',
@@ -1840,7 +1840,7 @@
           {
             column: {
               name: 'dur',
-              type: sliceTable.columns[2].type,
+              type: sliceTable.columns[2]!.type,
             },
             aggregationOp: 'AVG',
             newColumnName: 'avg_dur',
@@ -1848,7 +1848,7 @@
           {
             column: {
               name: 'dur',
-              type: sliceTable.columns[2].type,
+              type: sliceTable.columns[2]!.type,
             },
             aggregationOp: 'COUNT',
             newColumnName: 'count',
@@ -1873,27 +1873,29 @@
     const deserializedState = deserializeState(json, trace, sqlModules);
 
     expect(deserializedState.rootNodes.length).toBe(1);
-    const deserializedTableNode = deserializedState.rootNodes[0];
+    const deserializedTableNode = deserializedState.rootNodes[0]!;
     expect(deserializedTableNode.nextNodes.length).toBe(1);
     const deserializedAggregationNode = deserializedTableNode
       .nextNodes[0] as AggregationNode;
     expect(deserializedAggregationNode.attrs.groupByColumns.length).toBe(2);
-    expect(deserializedAggregationNode.attrs.groupByColumns[1].name).toBe('ts');
+    expect(deserializedAggregationNode.attrs.groupByColumns[1]!.name).toBe(
+      'ts',
+    );
     expect(deserializedAggregationNode.attrs.aggregations.length).toBe(3);
     expect(
-      deserializedAggregationNode.attrs.aggregations[0].aggregationOp,
+      deserializedAggregationNode.attrs.aggregations[0]!.aggregationOp,
     ).toBe('SUM');
     expect(
-      deserializedAggregationNode.attrs.aggregations[0].newColumnName,
+      deserializedAggregationNode.attrs.aggregations[0]!.newColumnName,
     ).toBe('total_dur');
     expect(
-      deserializedAggregationNode.attrs.aggregations[1].aggregationOp,
+      deserializedAggregationNode.attrs.aggregations[1]!.aggregationOp,
     ).toBe('AVG');
     expect(
-      deserializedAggregationNode.attrs.aggregations[1].newColumnName,
+      deserializedAggregationNode.attrs.aggregations[1]!.newColumnName,
     ).toBe('avg_dur');
     expect(
-      deserializedAggregationNode.attrs.aggregations[2].aggregationOp,
+      deserializedAggregationNode.attrs.aggregations[2]!.aggregationOp,
     ).toBe('COUNT');
   });
 
@@ -1923,7 +1925,7 @@
           {
             name: 'name',
             checked: true,
-            type: sliceTable.columns[0].type,
+            type: sliceTable.columns[0]!.type,
           },
         ],
       },
@@ -1937,14 +1939,14 @@
           {
             name: 'name',
             checked: true,
-            type: sliceTable.columns[0].type,
+            type: sliceTable.columns[0]!.type,
           },
         ],
         aggregations: [
           {
             column: {
               name: 'dur_ms',
-              type: sliceTable.columns[2].type,
+              type: sliceTable.columns[2]!.type,
             },
             aggregationOp: 'SUM',
             newColumnName: 'total_dur_ms',
@@ -2031,7 +2033,7 @@
           {
             name: 'name',
             checked: true,
-            type: sliceTable.columns[0].type,
+            type: sliceTable.columns[0]!.type,
           },
         ],
       },
@@ -2045,7 +2047,7 @@
           {
             name: 'ts',
             checked: true,
-            type: sliceTable.columns[1].type,
+            type: sliceTable.columns[1]!.type,
           },
         ],
       },
@@ -2064,7 +2066,7 @@
     const deserializedState = deserializeState(json, trace, sqlModules);
 
     expect(deserializedState.rootNodes.length).toBe(1);
-    const deserializedTableNode = deserializedState.rootNodes[0];
+    const deserializedTableNode = deserializedState.rootNodes[0]!;
     expect(deserializedTableNode.nextNodes.length).toBe(2);
 
     const branch1 = deserializedTableNode.nextNodes[0] as ModifyColumnsNode;
@@ -2139,7 +2141,7 @@
     expect(deserializedState.rootNodes.length).toBe(2);
 
     // Find the deserialized slices node (first root)
-    const deserializedSlicesNode = deserializedState.rootNodes[0];
+    const deserializedSlicesNode = deserializedState.rootNodes[0]!;
     expect(deserializedSlicesNode).toBeInstanceOf(SlicesSourceNode);
     expect(deserializedSlicesNode.nextNodes.length).toBe(1);
 
@@ -2227,8 +2229,8 @@
     expect(deserializedState.rootNodes.length).toBe(2);
 
     // Verify the diamond converges at union
-    const deserializedTableNode1 = deserializedState.rootNodes[0];
-    const deserializedTableNode2 = deserializedState.rootNodes[1];
+    const deserializedTableNode1 = deserializedState.rootNodes[0]!;
+    const deserializedTableNode2 = deserializedState.rootNodes[1]!;
 
     const deserializedFilterNode = deserializedTableNode1
       .nextNodes[0] as FilterNode;
@@ -2239,8 +2241,8 @@
     expect(deserializedSortNode.nextNodes.length).toBe(1);
 
     // Both should converge to the same union node
-    const deserializedUnionNode1 = deserializedFilterNode.nextNodes[0];
-    const deserializedUnionNode2 = deserializedSortNode.nextNodes[0];
+    const deserializedUnionNode1 = deserializedFilterNode.nextNodes[0]!;
+    const deserializedUnionNode2 = deserializedSortNode.nextNodes[0]!;
     expect(deserializedUnionNode1.nodeId).toBe(deserializedUnionNode2.nodeId);
   });
 
@@ -2280,14 +2282,14 @@
           {
             name: 'name',
             checked: true,
-            type: sliceTable.columns[0].type,
+            type: sliceTable.columns[0]!.type,
           },
         ],
         aggregations: [
           {
             column: {
               name: 'dur',
-              type: sliceTable.columns[2].type,
+              type: sliceTable.columns[2]!.type,
             },
             aggregationOp: 'SUM',
             newColumnName: 'total_dur',
@@ -2314,26 +2316,26 @@
     expect(deserializedState.rootNodes.length).toBe(1);
 
     // Walk the chain and verify all connections
-    let currentNode = deserializedState.rootNodes[0];
+    let currentNode = deserializedState.rootNodes[0]!;
     expect(currentNode).toBeInstanceOf(TableSourceNode);
 
-    currentNode = currentNode.nextNodes[0];
+    currentNode = currentNode.nextNodes[0]!;
     expect(currentNode).toBeInstanceOf(FilterNode);
     expect((currentNode as FilterNode).primaryInput).toBeDefined();
 
-    currentNode = currentNode.nextNodes[0];
+    currentNode = currentNode.nextNodes[0]!;
     expect(currentNode).toBeInstanceOf(FilterNode);
     expect((currentNode as FilterNode).primaryInput).toBeDefined();
 
-    currentNode = currentNode.nextNodes[0];
+    currentNode = currentNode.nextNodes[0]!;
     expect(currentNode).toBeInstanceOf(SortNode);
     expect((currentNode as SortNode).primaryInput).toBeDefined();
 
-    currentNode = currentNode.nextNodes[0];
+    currentNode = currentNode.nextNodes[0]!;
     expect(currentNode).toBeInstanceOf(AggregationNode);
     expect((currentNode as AggregationNode).primaryInput).toBeDefined();
 
-    currentNode = currentNode.nextNodes[0];
+    currentNode = currentNode.nextNodes[0]!;
     expect(currentNode).toBeInstanceOf(LimitAndOffsetNode);
     expect((currentNode as LimitAndOffsetNode).primaryInput).toBeDefined();
     expect(currentNode.nextNodes.length).toBe(0); // End of chain
@@ -2394,7 +2396,7 @@
     expect(deserializedState.rootNodes.length).toBe(3);
 
     // Find interval intersect node
-    const deserializedTableNode1 = deserializedState.rootNodes[0];
+    const deserializedTableNode1 = deserializedState.rootNodes[0]!;
     const deserializedIntervalIntersectNode = deserializedTableNode1
       .nextNodes[0] as IntervalIntersectNode;
     expect(deserializedIntervalIntersectNode).toBeInstanceOf(
@@ -2463,7 +2465,7 @@
     const deserializedState = deserializeState(json, trace, sqlModules);
 
     // Table -> Sort -> Limit (filter should be orphaned)
-    const deserializedTableNode = deserializedState.rootNodes[0];
+    const deserializedTableNode = deserializedState.rootNodes[0]!;
     expect(deserializedTableNode.nextNodes.length).toBe(1);
 
     const deserializedSortNode = deserializedTableNode.nextNodes[0] as SortNode;
@@ -2523,7 +2525,7 @@
     const deserializedState = deserializeState(json, trace, sqlModules);
 
     // Find union node
-    const deserializedTableNode1 = deserializedState.rootNodes[0];
+    const deserializedTableNode1 = deserializedState.rootNodes[0]!;
     const deserializedUnionNode = deserializedTableNode1
       .nextNodes[0] as UnionNode;
 
@@ -2531,7 +2533,7 @@
     expect(deserializedUnionNode.secondaryInputs.connections.size).toBe(2);
 
     // tableNode2 should have no nextNodes
-    const deserializedTableNode2 = deserializedState.rootNodes[1];
+    const deserializedTableNode2 = deserializedState.rootNodes[1]!;
     expect(deserializedTableNode2.nextNodes.length).toBe(0);
   });
 
@@ -2630,14 +2632,14 @@
     expect(deserializedState.rootNodes.length).toBe(3);
 
     // Verify first subgraph
-    const deserializedTableNode1 = deserializedState.rootNodes[0];
+    const deserializedTableNode1 = deserializedState.rootNodes[0]!;
     expect(deserializedTableNode1.nextNodes.length).toBe(1);
     expect(deserializedTableNode1.nextNodes[0]).toBeInstanceOf(FilterNode);
 
     // Verify second subgraph
-    const deserializedTableNode2 = deserializedState.rootNodes[1];
+    const deserializedTableNode2 = deserializedState.rootNodes[1]!;
     expect(deserializedTableNode2.nextNodes.length).toBe(1);
-    const deserializedSortNode = deserializedTableNode2.nextNodes[0];
+    const deserializedSortNode = deserializedTableNode2.nextNodes[0]!;
     expect(deserializedSortNode).toBeInstanceOf(SortNode);
     expect(deserializedSortNode.nextNodes.length).toBe(1);
     expect(deserializedSortNode.nextNodes[0]).toBeInstanceOf(
@@ -2645,7 +2647,7 @@
     );
 
     // Verify third subgraph
-    const deserializedSlicesNode = deserializedState.rootNodes[2];
+    const deserializedSlicesNode = deserializedState.rootNodes[2]!;
     expect(deserializedSlicesNode).toBeInstanceOf(SlicesSourceNode);
     expect(deserializedSlicesNode.nextNodes.length).toBe(0);
   });
@@ -2816,8 +2818,8 @@
 
     // After normalization, the minimum coordinates (400, 250) become (0, 0)
     // All other coordinates are shifted accordingly
-    const tableNodeId = deserializedState.rootNodes[0].nodeId;
-    const sliceNodeId = deserializedState.rootNodes[1].nodeId;
+    const tableNodeId = deserializedState.rootNodes[0]!.nodeId;
+    const sliceNodeId = deserializedState.rootNodes[1]!.nodeId;
 
     expect(deserializedState.nodeLayouts.get(tableNodeId)).toEqual({
       x: 100,
@@ -2852,7 +2854,7 @@
     const json = serializeState(initialState);
     const deserializedState = deserializeState(json, trace, sqlModules);
 
-    const tableNodeId = deserializedState.rootNodes[0].nodeId;
+    const tableNodeId = deserializedState.rootNodes[0]!.nodeId;
     expect(deserializedState.nodeLayouts.get(tableNodeId)).toEqual({
       x: 0,
       y: 0,
@@ -3191,7 +3193,7 @@
         labels: [],
       };
       const state = deserializeRaw(graph);
-      const src1 = state.rootNodes[0];
+      const src1 = state.rootNodes[0]!;
       const joinNode = src1.nextNodes[0] as JoinNode;
       // After migration, 'name' column should be found and checked: true preserved.
       const nameCol = joinNode.attrs.leftColumns?.find(
@@ -3251,13 +3253,13 @@
       };
       const state = deserializeRaw(graph);
       const modNode = state.rootNodes[0] as ModifyColumnsNode;
-      expect(modNode.attrs.selectedColumns[0].type).toEqual(
+      expect(modNode.attrs.selectedColumns[0]!.type).toEqual(
         PerfettoSqlTypes.INT,
       );
-      expect(modNode.attrs.selectedColumns[1].type).toEqual(
+      expect(modNode.attrs.selectedColumns[1]!.type).toEqual(
         PerfettoSqlTypes.STRING,
       );
-      expect(modNode.attrs.selectedColumns[2].type).toBeUndefined();
+      expect(modNode.attrs.selectedColumns[2]!.type).toBeUndefined();
     });
 
     it('migrates legacy string types in AggregationNode groupByColumns', () => {
@@ -3284,10 +3286,10 @@
       };
       const state = deserializeRaw(graph);
       const aggNode = state.rootNodes[0] as AggregationNode;
-      expect(aggNode.attrs.groupByColumns[0].type).toEqual(
+      expect(aggNode.attrs.groupByColumns[0]!.type).toEqual(
         PerfettoSqlTypes.TIMESTAMP,
       );
-      expect(aggNode.attrs.groupByColumns[1].type).toEqual(
+      expect(aggNode.attrs.groupByColumns[1]!.type).toEqual(
         PerfettoSqlTypes.STRING,
       );
     });
@@ -3319,7 +3321,7 @@
       };
       const state = deserializeRaw(graph);
       const aggNode = state.rootNodes[0] as AggregationNode;
-      expect(aggNode.attrs.aggregations[0].column?.type).toEqual(
+      expect(aggNode.attrs.aggregations[0]!.column?.type).toEqual(
         PerfettoSqlTypes.DURATION,
       );
     });
@@ -3347,10 +3349,10 @@
       };
       const state = deserializeRaw(graph);
       const unionNode = state.rootNodes[0] as UnionNode;
-      expect(unionNode.attrs.selectedColumns[0].type).toEqual(
+      expect(unionNode.attrs.selectedColumns[0]!.type).toEqual(
         PerfettoSqlTypes.INT,
       );
-      expect(unionNode.attrs.selectedColumns[1].type).toEqual(
+      expect(unionNode.attrs.selectedColumns[1]!.type).toEqual(
         PerfettoSqlTypes.TIMESTAMP,
       );
     });
diff --git a/ui/src/plugins/dev.perfetto.DataExplorer/multi_node_operations_unittest.ts b/ui/src/plugins/dev.perfetto.DataExplorer/multi_node_operations_unittest.ts
index e6288f9..72f1fd1 100644
--- a/ui/src/plugins/dev.perfetto.DataExplorer/multi_node_operations_unittest.ts
+++ b/ui/src/plugins/dev.perfetto.DataExplorer/multi_node_operations_unittest.ts
@@ -163,13 +163,13 @@
       // First paste
       const newNodes1 = clipboardNodes.map((entry) => entry.node.clone());
       expect(newNodes1).toHaveLength(1);
-      expect(newNodes1[0].nodeId).not.toBe(node1.nodeId);
+      expect(newNodes1[0]!.nodeId).not.toBe(node1.nodeId);
 
       // Second paste - should create different nodes
       const newNodes2 = clipboardNodes.map((entry) => entry.node.clone());
       expect(newNodes2).toHaveLength(1);
-      expect(newNodes2[0].nodeId).not.toBe(node1.nodeId);
-      expect(newNodes2[0].nodeId).not.toBe(newNodes1[0].nodeId);
+      expect(newNodes2[0]!.nodeId).not.toBe(node1.nodeId);
+      expect(newNodes2[0]!.nodeId).not.toBe(newNodes1[0]!.nodeId);
     });
 
     test('should restore connections between pasted nodes', () => {
@@ -287,13 +287,13 @@
       // Verify connections are restored
       // Find the restored table node (should be root)
       expect(restoredState!.rootNodes.length).toBe(1);
-      const restoredTable = restoredState!.rootNodes[0];
+      const restoredTable = restoredState!.rootNodes[0]!;
       expect(restoredTable.nextNodes.length).toBe(1);
 
-      const restoredFilter1 = restoredTable.nextNodes[0];
+      const restoredFilter1 = restoredTable.nextNodes[0]!;
       expect(restoredFilter1.nextNodes.length).toBe(1);
 
-      const restoredFilter2 = restoredFilter1.nextNodes[0];
+      const restoredFilter2 = restoredFilter1.nextNodes[0]!;
       expect(restoredFilter2.nextNodes.length).toBe(0);
     });
   });
diff --git a/ui/src/plugins/dev.perfetto.DataExplorer/node_actions_unittest.ts b/ui/src/plugins/dev.perfetto.DataExplorer/node_actions_unittest.ts
index 0c800ef..f1d37d8 100644
--- a/ui/src/plugins/dev.perfetto.DataExplorer/node_actions_unittest.ts
+++ b/ui/src/plugins/dev.perfetto.DataExplorer/node_actions_unittest.ts
@@ -55,9 +55,9 @@
       actions.onAddAndConnectTable?.('my_table', 2);
 
       expect(addAndConnectTableCalls).toHaveLength(1);
-      expect(addAndConnectTableCalls[0].tableName).toBe('my_table');
-      expect(addAndConnectTableCalls[0].node).toBe(node);
-      expect(addAndConnectTableCalls[0].portIndex).toBe(2);
+      expect(addAndConnectTableCalls[0]!.tableName).toBe('my_table');
+      expect(addAndConnectTableCalls[0]!.node).toBe(node);
+      expect(addAndConnectTableCalls[0]!.portIndex).toBe(2);
     });
 
     it('should delegate onInsertModifyColumnsNode with correct descriptor key', () => {
@@ -67,9 +67,9 @@
       actions.onInsertModifyColumnsNode?.(1);
 
       expect(insertNodeAtPortCalls).toHaveLength(1);
-      expect(insertNodeAtPortCalls[0].node).toBe(node);
-      expect(insertNodeAtPortCalls[0].portIndex).toBe(1);
-      expect(insertNodeAtPortCalls[0].descriptorKey).toBe('modify_columns');
+      expect(insertNodeAtPortCalls[0]!.node).toBe(node);
+      expect(insertNodeAtPortCalls[0]!.portIndex).toBe(1);
+      expect(insertNodeAtPortCalls[0]!.descriptorKey).toBe('modify_columns');
     });
 
     it('should delegate onInsertCounterToIntervalsNode with correct descriptor key', () => {
@@ -79,9 +79,9 @@
       actions.onInsertCounterToIntervalsNode?.(3);
 
       expect(insertNodeAtPortCalls).toHaveLength(1);
-      expect(insertNodeAtPortCalls[0].node).toBe(node);
-      expect(insertNodeAtPortCalls[0].portIndex).toBe(3);
-      expect(insertNodeAtPortCalls[0].descriptorKey).toBe(
+      expect(insertNodeAtPortCalls[0]!.node).toBe(node);
+      expect(insertNodeAtPortCalls[0]!.portIndex).toBe(3);
+      expect(insertNodeAtPortCalls[0]!.descriptorKey).toBe(
         'counter_to_intervals',
       );
     });
@@ -111,9 +111,9 @@
       actions.onAddAndConnectTable?.('table_a', 1);
 
       expect(addAndConnectTableCalls).toHaveLength(1);
-      expect(addAndConnectTableCalls[0].node).toBe(node);
-      expect(addAndConnectTableCalls[0].tableName).toBe('table_a');
-      expect(addAndConnectTableCalls[0].portIndex).toBe(1);
+      expect(addAndConnectTableCalls[0]!.node).toBe(node);
+      expect(addAndConnectTableCalls[0]!.tableName).toBe('table_a');
+      expect(addAndConnectTableCalls[0]!.portIndex).toBe(1);
     });
 
     it('should delegate onInsertModifyColumnsNode once nodeRef is set', () => {
@@ -126,8 +126,8 @@
       actions.onInsertModifyColumnsNode?.(5);
 
       expect(insertNodeAtPortCalls).toHaveLength(1);
-      expect(insertNodeAtPortCalls[0].node).toBe(node);
-      expect(insertNodeAtPortCalls[0].descriptorKey).toBe('modify_columns');
+      expect(insertNodeAtPortCalls[0]!.node).toBe(node);
+      expect(insertNodeAtPortCalls[0]!.descriptorKey).toBe('modify_columns');
     });
 
     it('should delegate onInsertCounterToIntervalsNode once nodeRef is set', () => {
@@ -140,8 +140,8 @@
       actions.onInsertCounterToIntervalsNode?.(7);
 
       expect(insertNodeAtPortCalls).toHaveLength(1);
-      expect(insertNodeAtPortCalls[0].node).toBe(node);
-      expect(insertNodeAtPortCalls[0].descriptorKey).toBe(
+      expect(insertNodeAtPortCalls[0]!.node).toBe(node);
+      expect(insertNodeAtPortCalls[0]!.descriptorKey).toBe(
         'counter_to_intervals',
       );
     });
@@ -205,8 +205,8 @@
       node.context.actions?.onAddAndConnectTable?.('test_table', 0);
 
       expect(addAndConnectTableCalls).toHaveLength(1);
-      expect(addAndConnectTableCalls[0].tableName).toBe('test_table');
-      expect(addAndConnectTableCalls[0].node).toBe(node);
+      expect(addAndConnectTableCalls[0]!.tableName).toBe('test_table');
+      expect(addAndConnectTableCalls[0]!.node).toBe(node);
     });
   });
 });
diff --git a/ui/src/plugins/dev.perfetto.DataExplorer/node_crud_operations.ts b/ui/src/plugins/dev.perfetto.DataExplorer/node_crud_operations.ts
index ee74780..934c1f9 100644
--- a/ui/src/plugins/dev.perfetto.DataExplorer/node_crud_operations.ts
+++ b/ui/src/plugins/dev.perfetto.DataExplorer/node_crud_operations.ts
@@ -250,7 +250,7 @@
     return;
   }
 
-  const lastNode = newNodes[newNodes.length - 1];
+  const lastNode = newNodes[newNodes.length - 1]!;
   deps.onStateUpdate((currentState) => ({
     ...currentState,
     rootNodes: [...currentState.rootNodes, ...newNodes],
diff --git a/ui/src/plugins/dev.perfetto.DataExplorer/pbtxt_import.ts b/ui/src/plugins/dev.perfetto.DataExplorer/pbtxt_import.ts
index e1d9234..080bed9 100644
--- a/ui/src/plugins/dev.perfetto.DataExplorer/pbtxt_import.ts
+++ b/ui/src/plugins/dev.perfetto.DataExplorer/pbtxt_import.ts
@@ -132,8 +132,8 @@
       acc,
       buildNodesFromMetricConfig(
         {
-          query: allTemplateSpecs[i].query,
-          metricsState: templateSpecToMetricsState(allTemplateSpecs[i]),
+          query: allTemplateSpecs[i]!.query,
+          metricsState: templateSpecToMetricsState(allTemplateSpecs[i]!),
         },
         chainX,
         sharedQueries,
@@ -150,8 +150,8 @@
       acc,
       buildNodesFromMetricConfig(
         {
-          query: allMetricSpecs[i].query,
-          metricsState: metricSpecToMetricsState(allMetricSpecs[i]),
+          query: allMetricSpecs[i]!.query,
+          metricsState: metricSpecToMetricsState(allMetricSpecs[i]!),
         },
         chainX,
         sharedQueries,
@@ -1049,7 +1049,7 @@
       result.push(...subNodes);
       // The last node from the sub-group becomes the input for the next.
       if (subNodes.length > 0) {
-        currentInputId = subNodes[subNodes.length - 1].nodeId;
+        currentInputId = subNodes[subNodes.length - 1]!.nodeId;
       }
     }
     return result;
@@ -1111,7 +1111,7 @@
   const stringRhs = f.stringRhs ?? [];
   const doubleRhs = f.doubleRhs ?? [];
   const int64Rhs = f.int64Rhs ?? [];
-  if (stringRhs.length > 0) return stringRhs[0];
+  if (stringRhs.length > 0) return stringRhs[0]!;
   if (doubleRhs.length > 0) return String(doubleRhs[0]);
   if (int64Rhs.length > 0) return String(int64Rhs[0]);
   return '';
diff --git a/ui/src/plugins/dev.perfetto.DataExplorer/pbtxt_import_unittest.ts b/ui/src/plugins/dev.perfetto.DataExplorer/pbtxt_import_unittest.ts
index b036337..b0ebe6a 100644
--- a/ui/src/plugins/dev.perfetto.DataExplorer/pbtxt_import_unittest.ts
+++ b/ui/src/plugins/dev.perfetto.DataExplorer/pbtxt_import_unittest.ts
@@ -80,12 +80,12 @@
     const result = decomposeStructuredQuery(sq, 0, 0);
 
     expect(result.nodes).toHaveLength(1);
-    expect(result.nodes[0].type).toBe(NodeType.kTable);
-    expect((result.nodes[0].state as Record<string, unknown>).sqlTable).toBe(
+    expect(result.nodes[0]!.type).toBe(NodeType.kTable);
+    expect((result.nodes[0]!.state as Record<string, unknown>).sqlTable).toBe(
       'my_table',
     );
     expect(result.rootNodeIds).toHaveLength(1);
-    expect(result.finalNodeId).toBe(result.nodes[0].nodeId);
+    expect(result.finalNodeId).toBe(result.nodes[0]!.nodeId);
   });
 
   it('decomposes a simple_slices source without globs', () => {
@@ -96,7 +96,7 @@
     const result = decomposeStructuredQuery(sq, 0, 0);
 
     expect(result.nodes).toHaveLength(1);
-    expect(result.nodes[0].type).toBe(NodeType.kSimpleSlices);
+    expect(result.nodes[0]!.type).toBe(NodeType.kSimpleSlices);
   });
 
   it('decomposes simple_slices with globs into SlicesSource + Filter', () => {
@@ -111,10 +111,10 @@
 
     // Should produce SlicesSourceNode + FilterNode with GLOB filters.
     expect(result.nodes).toHaveLength(2);
-    expect(result.nodes[0].type).toBe(NodeType.kSimpleSlices);
-    expect(result.nodes[1].type).toBe(NodeType.kFilter);
+    expect(result.nodes[0]!.type).toBe(NodeType.kSimpleSlices);
+    expect(result.nodes[1]!.type).toBe(NodeType.kFilter);
 
-    const filterState = result.nodes[1].state as Record<string, unknown>;
+    const filterState = result.nodes[1]!.state as Record<string, unknown>;
     const filters = filterState.filters as Array<Record<string, unknown>>;
     expect(filters).toHaveLength(2);
     expect(filters[0]).toEqual({
@@ -131,8 +131,8 @@
     });
 
     // Check wiring.
-    expect(result.nodes[0].nextNodes).toContain(result.nodes[1].nodeId);
-    expect(filterState.primaryInputId).toBe(result.nodes[0].nodeId);
+    expect(result.nodes[0]!.nextNodes).toContain(result.nodes[1]!.nodeId);
+    expect(filterState.primaryInputId).toBe(result.nodes[0]!.nodeId);
   });
 
   it('decomposes a SQL source', () => {
@@ -143,8 +143,8 @@
     const result = decomposeStructuredQuery(sq, 0, 0);
 
     expect(result.nodes).toHaveLength(1);
-    expect(result.nodes[0].type).toBe(NodeType.kSqlSource);
-    expect((result.nodes[0].state as Record<string, unknown>).sql).toBe(
+    expect(result.nodes[0]!.type).toBe(NodeType.kSqlSource);
+    expect((result.nodes[0]!.state as Record<string, unknown>).sql).toBe(
       'SELECT * FROM slice',
     );
   });
@@ -164,20 +164,20 @@
     const result = decomposeStructuredQuery(sq, 0, 0);
 
     expect(result.nodes).toHaveLength(2);
-    expect(result.nodes[0].type).toBe(NodeType.kTable);
-    expect(result.nodes[1].type).toBe(NodeType.kFilter);
+    expect(result.nodes[0]!.type).toBe(NodeType.kTable);
+    expect(result.nodes[1]!.type).toBe(NodeType.kFilter);
 
     // Check filter state
-    const filterState = result.nodes[1].state as Record<string, unknown>;
+    const filterState = result.nodes[1]!.state as Record<string, unknown>;
     const filters = filterState.filters as Array<Record<string, unknown>>;
     expect(filters).toHaveLength(1);
-    expect(filters[0].column).toBe('name');
-    expect(filters[0].op).toBe('=');
-    expect(filters[0].value).toBe('foo');
+    expect(filters[0]!.column).toBe('name');
+    expect(filters[0]!.op).toBe('=');
+    expect(filters[0]!.value).toBe('foo');
 
     // Check wiring
-    expect(result.nodes[0].nextNodes).toContain(result.nodes[1].nodeId);
-    expect(filterState.primaryInputId).toBe(result.nodes[0].nodeId);
+    expect(result.nodes[0]!.nextNodes).toContain(result.nodes[1]!.nodeId);
+    expect(filterState.primaryInputId).toBe(result.nodes[0]!.nodeId);
   });
 
   it('decomposes table with group_by', () => {
@@ -198,23 +198,23 @@
     const result = decomposeStructuredQuery(sq, 0, 0);
 
     expect(result.nodes).toHaveLength(2);
-    expect(result.nodes[0].type).toBe(NodeType.kTable);
-    expect(result.nodes[1].type).toBe(NodeType.kAggregation);
+    expect(result.nodes[0]!.type).toBe(NodeType.kTable);
+    expect(result.nodes[1]!.type).toBe(NodeType.kAggregation);
 
-    const aggState = result.nodes[1].state as Record<string, unknown>;
+    const aggState = result.nodes[1]!.state as Record<string, unknown>;
     const groupByCols = aggState.groupByColumns as Array<
       Record<string, unknown>
     >;
     expect(groupByCols).toHaveLength(1);
-    expect(groupByCols[0].name).toBe('process_name');
+    expect(groupByCols[0]!.name).toBe('process_name');
 
     const aggs = aggState.aggregations as Array<Record<string, unknown>>;
     expect(aggs).toHaveLength(1);
-    expect((aggs[0].column as Record<string, unknown> | undefined)?.name).toBe(
+    expect((aggs[0]!.column as Record<string, unknown> | undefined)?.name).toBe(
       'dur',
     );
-    expect(aggs[0].aggregationOp).toBe('SUM');
-    expect(aggs[0].newColumnName).toBe('total_dur');
+    expect(aggs[0]!.aggregationOp).toBe('SUM');
+    expect(aggs[0]!.newColumnName).toBe('total_dur');
   });
 
   it('decomposes table with limit and offset', () => {
@@ -227,8 +227,8 @@
     const result = decomposeStructuredQuery(sq, 0, 0);
 
     expect(result.nodes).toHaveLength(2);
-    expect(result.nodes[1].type).toBe(NodeType.kLimitAndOffset);
-    const state = result.nodes[1].state as Record<string, unknown>;
+    expect(result.nodes[1]!.type).toBe(NodeType.kLimitAndOffset);
+    const state = result.nodes[1]!.state as Record<string, unknown>;
     expect(state.limit).toBe(10);
     expect(state.offset).toBe(5);
   });
@@ -249,12 +249,12 @@
     const result = decomposeStructuredQuery(sq, 0, 0);
 
     expect(result.nodes).toHaveLength(2);
-    expect(result.nodes[1].type).toBe(NodeType.kSort);
-    const state = result.nodes[1].state as Record<string, unknown>;
+    expect(result.nodes[1]!.type).toBe(NodeType.kSort);
+    const state = result.nodes[1]!.state as Record<string, unknown>;
     const criteria = state.sortCriteria as Array<Record<string, unknown>>;
     expect(criteria).toHaveLength(1);
-    expect(criteria[0].colName).toBe('dur');
-    expect(criteria[0].direction).toBe('DESC');
+    expect(criteria[0]!.colName).toBe('dur');
+    expect(criteria[0]!.direction).toBe('DESC');
   });
 
   it('decomposes nested inner_query', () => {
@@ -274,13 +274,13 @@
     const result = decomposeStructuredQuery(sq, 0, 0);
 
     expect(result.nodes).toHaveLength(2);
-    expect(result.nodes[0].type).toBe(NodeType.kTable);
-    expect(result.nodes[1].type).toBe(NodeType.kFilter);
+    expect(result.nodes[0]!.type).toBe(NodeType.kTable);
+    expect(result.nodes[1]!.type).toBe(NodeType.kFilter);
 
-    const filterState = result.nodes[1].state as Record<string, unknown>;
+    const filterState = result.nodes[1]!.state as Record<string, unknown>;
     const filters = filterState.filters as Array<Record<string, unknown>>;
-    expect(filters[0].op).toBe('>');
-    expect(filters[0].value).toBe('1000');
+    expect(filters[0]!.op).toBe('>');
+    expect(filters[0]!.value).toBe('1000');
   });
 
   it('decomposes deeply nested query chain', () => {
@@ -315,15 +315,15 @@
 
     // Should produce: Table → Filter → Aggregation → Limit
     expect(result.nodes).toHaveLength(4);
-    expect(result.nodes[0].type).toBe(NodeType.kTable);
-    expect(result.nodes[1].type).toBe(NodeType.kFilter);
-    expect(result.nodes[2].type).toBe(NodeType.kAggregation);
-    expect(result.nodes[3].type).toBe(NodeType.kLimitAndOffset);
+    expect(result.nodes[0]!.type).toBe(NodeType.kTable);
+    expect(result.nodes[1]!.type).toBe(NodeType.kFilter);
+    expect(result.nodes[2]!.type).toBe(NodeType.kAggregation);
+    expect(result.nodes[3]!.type).toBe(NodeType.kLimitAndOffset);
 
     // Check chain wiring
-    expect(result.nodes[0].nextNodes).toContain(result.nodes[1].nodeId);
-    expect(result.nodes[1].nextNodes).toContain(result.nodes[2].nodeId);
-    expect(result.nodes[2].nextNodes).toContain(result.nodes[3].nodeId);
+    expect(result.nodes[0]!.nextNodes).toContain(result.nodes[1]!.nodeId);
+    expect(result.nodes[1]!.nextNodes).toContain(result.nodes[2]!.nodeId);
+    expect(result.nodes[2]!.nextNodes).toContain(result.nodes[3]!.nodeId);
   });
 
   it('decomposes interval_intersect', () => {
@@ -356,7 +356,7 @@
     const result = decomposeStructuredQuery(sq, 0, 0);
 
     expect(result.nodes).toHaveLength(1);
-    expect(result.nodes[0].type).toBe(NodeType.kSqlSource);
+    expect(result.nodes[0]!.type).toBe(NodeType.kSqlSource);
   });
 
   it('assigns layout positions', () => {
@@ -375,14 +375,14 @@
 
     // Source nodes should have layouts; dockable nodes (filter) should not
     // (the graph renderer docks them to their parent when no layout is set).
-    const tableNode = result.nodes[0];
+    const tableNode = result.nodes[0]!;
     expect(result.layouts.has(tableNode.nodeId)).toBe(true);
     const firstLayout = result.layouts.get(tableNode.nodeId);
     expect(firstLayout?.x).toBe(100);
     expect(firstLayout?.y).toBe(200);
 
     // Filter is a dockable node — no layout position
-    const filterNode = result.nodes[1];
+    const filterNode = result.nodes[1]!;
     expect(result.layouts.has(filterNode.nodeId)).toBe(false);
   });
 });
@@ -399,9 +399,9 @@
     expect(state.metricIdPrefix).toBe('memory_per_process');
     const cols = state.valueColumns as Array<Record<string, unknown>>;
     expect(cols).toHaveLength(2);
-    expect(cols[0].column).toBe('avg_rss');
-    expect(cols[0].unit).toBe('COUNT');
-    expect(cols[1].column).toBe('total_swap');
+    expect(cols[0]!.column).toBe('avg_rss');
+    expect(cols[0]!.unit).toBe('COUNT');
+    expect(cols[1]!.column).toBe('total_swap');
   });
 
   it('maps valueColumnSpecs with unit and polarity', () => {
@@ -422,11 +422,11 @@
 
     const cols = state.valueColumns as Array<Record<string, unknown>>;
     expect(cols).toHaveLength(1);
-    expect(cols[0].column).toBe('duration');
-    expect(cols[0].unit).toBe('TIME_NANOS');
-    expect(cols[0].polarity).toBe('LOWER_IS_BETTER');
-    expect(cols[0].displayName).toBe('Duration');
-    expect(cols[0].displayHelp).toBe('Total duration in ns');
+    expect(cols[0]!.column).toBe('duration');
+    expect(cols[0]!.unit).toBe('TIME_NANOS');
+    expect(cols[0]!.polarity).toBe('LOWER_IS_BETTER');
+    expect(cols[0]!.displayName).toBe('Duration');
+    expect(cols[0]!.displayHelp).toBe('Total duration in ns');
   });
 
   it('maps custom unit', () => {
@@ -443,8 +443,8 @@
     const state = templateSpecToMetricsState(spec);
 
     const cols = state.valueColumns as Array<Record<string, unknown>>;
-    expect(cols[0].unit).toBe('CUSTOM');
-    expect(cols[0].customUnit).toBe('jank_score');
+    expect(cols[0]!.unit).toBe('CUSTOM');
+    expect(cols[0]!.customUnit).toBe('jank_score');
   });
 
   it('maps dimension configs from dimensionsSpecs', () => {
@@ -678,7 +678,7 @@
 
     // inner_query_id without a sharedQueries map falls back to SqlSourceNode.
     expect(result.nodes).toHaveLength(1);
-    expect(result.nodes[0].type).toBe(NodeType.kSqlSource);
+    expect(result.nodes[0]!.type).toBe(NodeType.kSqlSource);
   });
 });
 
@@ -707,10 +707,10 @@
     const result = decomposeStructuredQuery(sq, 0, 0);
 
     expect(result.nodes).toHaveLength(2);
-    expect(result.nodes[0].type).toBe(NodeType.kTable);
-    expect(result.nodes[1].type).toBe(NodeType.kFilter);
+    expect(result.nodes[0]!.type).toBe(NodeType.kTable);
+    expect(result.nodes[1]!.type).toBe(NodeType.kFilter);
 
-    const filterState = result.nodes[1].state as Record<string, unknown>;
+    const filterState = result.nodes[1]!.state as Record<string, unknown>;
     const filters = filterState.filters as Array<Record<string, unknown>>;
     expect(filters).toHaveLength(2);
     expect(filters[0]).toEqual({
@@ -753,16 +753,16 @@
     const result = decomposeStructuredQuery(sq, 0, 0);
 
     expect(result.nodes).toHaveLength(2);
-    expect(result.nodes[1].type).toBe(NodeType.kFilter);
+    expect(result.nodes[1]!.type).toBe(NodeType.kFilter);
 
-    const filterState = result.nodes[1].state as Record<string, unknown>;
+    const filterState = result.nodes[1]!.state as Record<string, unknown>;
     expect(filterState.filterOperator).toBe('OR');
     const filters = filterState.filters as Array<Record<string, unknown>>;
     expect(filters).toHaveLength(2);
-    expect(filters[0].column).toBe('name');
-    expect(filters[0].value).toBe('foo');
-    expect(filters[1].column).toBe('name');
-    expect(filters[1].value).toBe('bar');
+    expect(filters[0]!.column).toBe('name');
+    expect(filters[0]!.value).toBe('foo');
+    expect(filters[1]!.column).toBe('name');
+    expect(filters[1]!.value).toBe('bar');
   });
 
   it('converts AND of sub-groups to multiple chained FilterNodes', () => {
@@ -808,21 +808,21 @@
 
     // Table + 2 filter nodes (one per sub-group).
     expect(result.nodes).toHaveLength(3);
-    expect(result.nodes[0].type).toBe(NodeType.kTable);
-    expect(result.nodes[1].type).toBe(NodeType.kFilter);
-    expect(result.nodes[2].type).toBe(NodeType.kFilter);
+    expect(result.nodes[0]!.type).toBe(NodeType.kTable);
+    expect(result.nodes[1]!.type).toBe(NodeType.kFilter);
+    expect(result.nodes[2]!.type).toBe(NodeType.kFilter);
 
     // First sub-group: OR of name='foo' and name='bar'.
-    const state1 = result.nodes[1].state as Record<string, unknown>;
+    const state1 = result.nodes[1]!.state as Record<string, unknown>;
     expect(state1.filterOperator).toBe('OR');
     const filters1 = state1.filters as Array<Record<string, unknown>>;
     expect(filters1).toHaveLength(2);
 
     // Second sub-group: AND of dur > 1000.
-    const state2 = result.nodes[2].state as Record<string, unknown>;
+    const state2 = result.nodes[2]!.state as Record<string, unknown>;
     const filters2 = state2.filters as Array<Record<string, unknown>>;
     expect(filters2).toHaveLength(1);
-    expect(filters2[0].column).toBe('dur');
+    expect(filters2[0]!.column).toBe('dur');
   });
 
   it('falls back to freeform for mixed filters + sql_expressions', () => {
@@ -845,9 +845,9 @@
     const result = decomposeStructuredQuery(sq, 0, 0);
 
     expect(result.nodes).toHaveLength(2);
-    expect(result.nodes[1].type).toBe(NodeType.kFilter);
+    expect(result.nodes[1]!.type).toBe(NodeType.kFilter);
 
-    const filterState = result.nodes[1].state as Record<string, unknown>;
+    const filterState = result.nodes[1]!.state as Record<string, unknown>;
     expect(filterState.filterMode).toBe('freeform');
     expect(filterState.sqlExpression).toBe('dur > 1000 AND LENGTH(name) > 10');
   });
@@ -883,9 +883,9 @@
     const result = decomposeStructuredQuery(sq, 0, 0);
 
     expect(result.nodes).toHaveLength(2);
-    expect(result.nodes[1].type).toBe(NodeType.kFilter);
+    expect(result.nodes[1]!.type).toBe(NodeType.kFilter);
 
-    const filterState = result.nodes[1].state as Record<string, unknown>;
+    const filterState = result.nodes[1]!.state as Record<string, unknown>;
     expect(filterState.filterMode).toBe('freeform');
     expect(filterState.sqlExpression).toBe(
       "LENGTH(name) > 10 AND (name = 'foo' OR name = 'bar')",
@@ -919,19 +919,19 @@
 
     // Table + filter from `filters` + filter from `experimentalFilterGroup`.
     expect(result.nodes).toHaveLength(3);
-    expect(result.nodes[0].type).toBe(NodeType.kTable);
-    expect(result.nodes[1].type).toBe(NodeType.kFilter);
-    expect(result.nodes[2].type).toBe(NodeType.kFilter);
+    expect(result.nodes[0]!.type).toBe(NodeType.kTable);
+    expect(result.nodes[1]!.type).toBe(NodeType.kFilter);
+    expect(result.nodes[2]!.type).toBe(NodeType.kFilter);
 
     // First filter node is from `filters` field.
-    const state1 = result.nodes[1].state as Record<string, unknown>;
+    const state1 = result.nodes[1]!.state as Record<string, unknown>;
     const filters1 = state1.filters as Array<Record<string, unknown>>;
-    expect(filters1[0].column).toBe('category');
+    expect(filters1[0]!.column).toBe('category');
 
     // Second filter node is from `experimentalFilterGroup`.
-    const state2 = result.nodes[2].state as Record<string, unknown>;
+    const state2 = result.nodes[2]!.state as Record<string, unknown>;
     const filters2 = state2.filters as Array<Record<string, unknown>>;
-    expect(filters2[0].column).toBe('dur');
+    expect(filters2[0]!.column).toBe('dur');
   });
 });
 
@@ -951,15 +951,15 @@
     const result = decomposeStructuredQuery(sq, 0, 0);
 
     expect(result.nodes).toHaveLength(2);
-    const filterState = result.nodes[1].state as Record<string, unknown>;
+    const filterState = result.nodes[1]!.state as Record<string, unknown>;
     expect(filterState.filterOperator).toBe('OR');
     const filters = filterState.filters as Array<Record<string, unknown>>;
     expect(filters).toHaveLength(3);
-    expect(filters[0].value).toBe('foo');
-    expect(filters[1].value).toBe('bar');
-    expect(filters[2].value).toBe('baz');
-    expect(filters[0].column).toBe('name');
-    expect(filters[0].op).toBe('=');
+    expect(filters[0]!.value).toBe('foo');
+    expect(filters[1]!.value).toBe('bar');
+    expect(filters[2]!.value).toBe('baz');
+    expect(filters[0]!.column).toBe('name');
+    expect(filters[0]!.op).toBe('=');
   });
 
   it('separates multi-value and single-value filters into chained nodes', () => {
@@ -983,25 +983,25 @@
 
     // Table + AND FilterNode (category=gfx) + OR FilterNode (name IN ...)
     expect(result.nodes).toHaveLength(3);
-    expect(result.nodes[0].type).toBe(NodeType.kTable);
-    expect(result.nodes[1].type).toBe(NodeType.kFilter);
-    expect(result.nodes[2].type).toBe(NodeType.kFilter);
+    expect(result.nodes[0]!.type).toBe(NodeType.kTable);
+    expect(result.nodes[1]!.type).toBe(NodeType.kFilter);
+    expect(result.nodes[2]!.type).toBe(NodeType.kFilter);
 
     // First filter: single-value, AND mode (default).
-    const state1 = result.nodes[1].state as Record<string, unknown>;
+    const state1 = result.nodes[1]!.state as Record<string, unknown>;
     const filters1 = state1.filters as Array<Record<string, unknown>>;
     expect(filters1).toHaveLength(1);
-    expect(filters1[0].column).toBe('category');
-    expect(filters1[0].value).toBe('gfx');
+    expect(filters1[0]!.column).toBe('category');
+    expect(filters1[0]!.value).toBe('gfx');
 
     // Second filter: multi-value, OR mode.
-    const state2 = result.nodes[2].state as Record<string, unknown>;
+    const state2 = result.nodes[2]!.state as Record<string, unknown>;
     expect(state2.filterOperator).toBe('OR');
     const filters2 = state2.filters as Array<Record<string, unknown>>;
     expect(filters2).toHaveLength(3);
-    expect(filters2[0].value).toBe('DrawFrame');
-    expect(filters2[1].value).toBe('doFrame');
-    expect(filters2[2].value).toBe('queueBuffer');
+    expect(filters2[0]!.value).toBe('DrawFrame');
+    expect(filters2[1]!.value).toBe('doFrame');
+    expect(filters2[2]!.value).toBe('queueBuffer');
   });
 
   it('handles double_rhs filter values', () => {
@@ -1018,10 +1018,10 @@
 
     const result = decomposeStructuredQuery(sq, 0, 0);
 
-    const filterState = result.nodes[1].state as Record<string, unknown>;
+    const filterState = result.nodes[1]!.state as Record<string, unknown>;
     const filters = filterState.filters as Array<Record<string, unknown>>;
-    expect(filters[0].value).toBe('3.14');
-    expect(filters[0].op).toBe('>');
+    expect(filters[0]!.value).toBe('3.14');
+    expect(filters[0]!.op).toBe('>');
   });
 
   it('handles IS_NULL filter with no RHS values', () => {
@@ -1037,11 +1037,11 @@
 
     const result = decomposeStructuredQuery(sq, 0, 0);
 
-    const filterState = result.nodes[1].state as Record<string, unknown>;
+    const filterState = result.nodes[1]!.state as Record<string, unknown>;
     const filters = filterState.filters as Array<Record<string, unknown>>;
-    expect(filters[0].column).toBe('parent_id');
-    expect(filters[0].op).toBe('IS NULL');
-    expect(filters[0].value).toBe('');
+    expect(filters[0]!.column).toBe('parent_id');
+    expect(filters[0]!.op).toBe('IS NULL');
+    expect(filters[0]!.value).toBe('');
   });
 
   it('handles IS_NOT_NULL filter with no RHS values', () => {
@@ -1057,10 +1057,10 @@
 
     const result = decomposeStructuredQuery(sq, 0, 0);
 
-    const filterState = result.nodes[1].state as Record<string, unknown>;
+    const filterState = result.nodes[1]!.state as Record<string, unknown>;
     const filters = filterState.filters as Array<Record<string, unknown>>;
-    expect(filters[0].op).toBe('IS NOT NULL');
-    expect(filters[0].value).toBe('');
+    expect(filters[0]!.op).toBe('IS NOT NULL');
+    expect(filters[0]!.value).toBe('');
   });
 
   it('handles UNKNOWN operator by defaulting to =', () => {
@@ -1077,10 +1077,10 @@
 
     const result = decomposeStructuredQuery(sq, 0, 0);
 
-    const filterState = result.nodes[1].state as Record<string, unknown>;
+    const filterState = result.nodes[1]!.state as Record<string, unknown>;
     const filters = filterState.filters as Array<Record<string, unknown>>;
     // UNKNOWN (0) is not in FILTER_OP_MAP, so falls back to '='.
-    expect(filters[0].op).toBe('=');
+    expect(filters[0]!.op).toBe('=');
   });
 
   it('handles multiple filters with different RHS types', () => {
@@ -1111,7 +1111,7 @@
 
     const result = decomposeStructuredQuery(sq, 0, 0);
 
-    const filterState = result.nodes[1].state as Record<string, unknown>;
+    const filterState = result.nodes[1]!.state as Record<string, unknown>;
     const filters = filterState.filters as Array<Record<string, unknown>>;
     expect(filters).toHaveLength(4);
     expect(filters[0]).toEqual({
@@ -1154,13 +1154,13 @@
     const result = decomposeStructuredQuery(sq, 0, 0);
 
     expect(result.nodes).toHaveLength(2);
-    expect(result.nodes[1].type).toBe(NodeType.kModifyColumns);
-    const modState = result.nodes[1].state as Record<string, unknown>;
+    expect(result.nodes[1]!.type).toBe(NodeType.kModifyColumns);
+    const modState = result.nodes[1]!.state as Record<string, unknown>;
     const cols = modState.selectedColumns as Array<Record<string, unknown>>;
     expect(cols).toHaveLength(2);
-    expect(cols[0].name).toBe('ts + dur');
-    expect(cols[0].alias).toBe('end_ts');
-    expect(cols[1].name).toBe('name');
+    expect(cols[0]!.name).toBe('ts + dur');
+    expect(cols[0]!.alias).toBe('end_ts');
+    expect(cols[1]!.name).toBe('name');
   });
 
   it('handles select_columns with deprecated column_name field', () => {
@@ -1171,10 +1171,10 @@
 
     const result = decomposeStructuredQuery(sq, 0, 0);
 
-    const modState = result.nodes[1].state as Record<string, unknown>;
+    const modState = result.nodes[1]!.state as Record<string, unknown>;
     const cols = modState.selectedColumns as Array<Record<string, unknown>>;
-    expect(cols[0].name).toBe('ts');
-    expect(cols[0].alias).toBe('timestamp');
+    expect(cols[0]!.name).toBe('ts');
+    expect(cols[0]!.alias).toBe('timestamp');
   });
 
   it('prefers column_name_or_expression over deprecated column_name', () => {
@@ -1191,11 +1191,11 @@
 
     const result = decomposeStructuredQuery(sq, 0, 0);
 
-    const modState = result.nodes[1].state as Record<string, unknown>;
+    const modState = result.nodes[1]!.state as Record<string, unknown>;
     const cols = modState.selectedColumns as Array<Record<string, unknown>>;
     // Should prefer columnNameOrExpression over deprecated columnName.
-    expect(cols[0].name).toBe('CAST(ts AS TEXT)');
-    expect(cols[0].alias).toBe('ts_text');
+    expect(cols[0]!.name).toBe('CAST(ts AS TEXT)');
+    expect(cols[0]!.alias).toBe('ts_text');
   });
 });
 
@@ -1210,7 +1210,7 @@
 
     // referenced_modules is silently ignored; only the table node is produced.
     expect(result.nodes).toHaveLength(1);
-    expect(result.nodes[0].type).toBe(NodeType.kTable);
+    expect(result.nodes[0]!.type).toBe(NodeType.kTable);
   });
 });
 
@@ -1226,8 +1226,8 @@
     const result = decomposeStructuredQuery(sq, 0, 0);
 
     expect(result.nodes).toHaveLength(1);
-    expect(result.nodes[0].type).toBe(NodeType.kTable);
-    const state = result.nodes[0].state as Record<string, unknown>;
+    expect(result.nodes[0]!.type).toBe(NodeType.kTable);
+    const state = result.nodes[0]!.state as Record<string, unknown>;
     // column_names are not persisted in the node state.
     expect(state.sqlTable).toBe('slice');
     expect(state.columnNames).toBeUndefined();
@@ -1245,7 +1245,7 @@
 
     // protobufjs --force-number sets unset to 0, and limit=0 means "unset".
     expect(result.nodes).toHaveLength(1);
-    expect(result.nodes[0].type).toBe(NodeType.kTable);
+    expect(result.nodes[0]!.type).toBe(NodeType.kTable);
   });
 
   it('creates LimitAndOffset node when only limit is set', () => {
@@ -1257,8 +1257,8 @@
     const result = decomposeStructuredQuery(sq, 0, 0);
 
     expect(result.nodes).toHaveLength(2);
-    expect(result.nodes[1].type).toBe(NodeType.kLimitAndOffset);
-    const state = result.nodes[1].state as Record<string, unknown>;
+    expect(result.nodes[1]!.type).toBe(NodeType.kLimitAndOffset);
+    const state = result.nodes[1]!.state as Record<string, unknown>;
     expect(state.limit).toBe(100);
     // offset=0 is treated as unset so it's not in the state.
     expect(state.offset).toBeUndefined();
@@ -1314,11 +1314,11 @@
 
     const result = decomposeStructuredQuery(sq, 0, 0);
 
-    const aggState = result.nodes[1].state as Record<string, unknown>;
+    const aggState = result.nodes[1]!.state as Record<string, unknown>;
     const aggs = aggState.aggregations as Array<Record<string, unknown>>;
-    expect(aggs[0].aggregationOp).toBe('COUNT');
-    expect(aggs[0].column).toBeUndefined();
-    expect(aggs[0].newColumnName).toBe('cnt');
+    expect(aggs[0]!.aggregationOp).toBe('COUNT');
+    expect(aggs[0]!.column).toBeUndefined();
+    expect(aggs[0]!.newColumnName).toBe('cnt');
   });
 
   it('handles PERCENTILE aggregate with percentile field', () => {
@@ -1340,10 +1340,10 @@
 
     const result = decomposeStructuredQuery(sq, 0, 0);
 
-    const aggState = result.nodes[1].state as Record<string, unknown>;
+    const aggState = result.nodes[1]!.state as Record<string, unknown>;
     const aggs = aggState.aggregations as Array<Record<string, unknown>>;
-    expect(aggs[0].aggregationOp).toBe('PERCENTILE');
-    expect(aggs[0].percentile).toBe(95);
+    expect(aggs[0]!.aggregationOp).toBe('PERCENTILE');
+    expect(aggs[0]!.percentile).toBe(95);
   });
 
   it('handles CUSTOM aggregate with custom_sql_expression', () => {
@@ -1363,9 +1363,9 @@
 
     const result = decomposeStructuredQuery(sq, 0, 0);
 
-    const aggState = result.nodes[1].state as Record<string, unknown>;
+    const aggState = result.nodes[1]!.state as Record<string, unknown>;
     const aggs = aggState.aggregations as Array<Record<string, unknown>>;
-    expect(aggs[0].aggregationOp).toBe('CUSTOM');
+    expect(aggs[0]!.aggregationOp).toBe('CUSTOM');
   });
 
   it('handles all aggregate ops', () => {
@@ -1407,9 +1407,9 @@
         },
       });
       const result = decomposeStructuredQuery(sq, 0, 0);
-      const aggState = result.nodes[1].state as Record<string, unknown>;
+      const aggState = result.nodes[1]!.state as Record<string, unknown>;
       const aggs = aggState.aggregations as Array<Record<string, unknown>>;
-      expect(aggs[0].aggregationOp).toBe(expected);
+      expect(aggs[0]!.aggregationOp).toBe(expected);
     }
   });
 });
@@ -1425,9 +1425,9 @@
 
     const result = decomposeStructuredQuery(sq, 0, 0);
 
-    const state = result.nodes[1].state as Record<string, unknown>;
+    const state = result.nodes[1]!.state as Record<string, unknown>;
     const criteria = state.sortCriteria as Array<Record<string, unknown>>;
-    expect(criteria[0].direction).toBe('ASC');
+    expect(criteria[0]!.direction).toBe('ASC');
   });
 
   it('handles multiple ordering specs', () => {
@@ -1449,13 +1449,13 @@
 
     const result = decomposeStructuredQuery(sq, 0, 0);
 
-    const state = result.nodes[1].state as Record<string, unknown>;
+    const state = result.nodes[1]!.state as Record<string, unknown>;
     const criteria = state.sortCriteria as Array<Record<string, unknown>>;
     expect(criteria).toHaveLength(2);
-    expect(criteria[0].colName).toBe('dur');
-    expect(criteria[0].direction).toBe('DESC');
-    expect(criteria[1].colName).toBe('ts');
-    expect(criteria[1].direction).toBe('ASC');
+    expect(criteria[0]!.colName).toBe('dur');
+    expect(criteria[0]!.direction).toBe('DESC');
+    expect(criteria[1]!.colName).toBe('ts');
+    expect(criteria[1]!.direction).toBe('ASC');
   });
 });
 
@@ -1500,17 +1500,17 @@
     // Table, Filter, Aggregation, Sort, LimitAndOffset
     // (select_columns is redundant after group_by and is skipped)
     expect(result.nodes).toHaveLength(5);
-    expect(result.nodes[0].type).toBe(NodeType.kTable);
-    expect(result.nodes[1].type).toBe(NodeType.kFilter);
-    expect(result.nodes[2].type).toBe(NodeType.kAggregation);
-    expect(result.nodes[3].type).toBe(NodeType.kSort);
-    expect(result.nodes[4].type).toBe(NodeType.kLimitAndOffset);
+    expect(result.nodes[0]!.type).toBe(NodeType.kTable);
+    expect(result.nodes[1]!.type).toBe(NodeType.kFilter);
+    expect(result.nodes[2]!.type).toBe(NodeType.kAggregation);
+    expect(result.nodes[3]!.type).toBe(NodeType.kSort);
+    expect(result.nodes[4]!.type).toBe(NodeType.kLimitAndOffset);
 
     // Verify chain wiring.
     for (let i = 0; i < result.nodes.length - 1; i++) {
-      expect(result.nodes[i].nextNodes).toContain(result.nodes[i + 1].nodeId);
+      expect(result.nodes[i]!.nextNodes).toContain(result.nodes[i + 1]!.nodeId);
     }
-    expect(result.finalNodeId).toBe(result.nodes[4].nodeId);
+    expect(result.finalNodeId).toBe(result.nodes[4]!.nodeId);
   });
 });
 
@@ -1528,8 +1528,8 @@
     const result = decomposeStructuredQuery(sq, 0, 0);
 
     expect(result.nodes).toHaveLength(1);
-    expect(result.nodes[0].type).toBe(NodeType.kTimeRangeSource);
-    const state = result.nodes[0].state as Record<string, unknown>;
+    expect(result.nodes[0]!.type).toBe(NodeType.kTimeRangeSource);
+    const state = result.nodes[0]!.state as Record<string, unknown>;
     expect(state.start).toBe('1000000');
   });
 });
@@ -1548,9 +1548,9 @@
     expect(state.metricIdPrefix).toBe('my_metric');
     const cols = state.valueColumns as Array<Record<string, unknown>>;
     expect(cols).toHaveLength(1);
-    expect(cols[0].column).toBe('total_dur');
-    expect(cols[0].unit).toBe('TIME_NANOS');
-    expect(cols[0].polarity).toBe('LOWER_IS_BETTER');
+    expect(cols[0]!.column).toBe('total_dur');
+    expect(cols[0]!.unit).toBe('TIME_NANOS');
+    expect(cols[0]!.polarity).toBe('LOWER_IS_BETTER');
   });
 
   it('handles missing value field', () => {
@@ -1585,8 +1585,8 @@
     const state = metricSpecToMetricsState(spec);
 
     const cols = state.valueColumns as Array<Record<string, unknown>>;
-    expect(cols[0].unit).toBe('CUSTOM');
-    expect(cols[0].customUnit).toBe('fps');
+    expect(cols[0]!.unit).toBe('CUSTOM');
+    expect(cols[0]!.customUnit).toBe('fps');
   });
 
   it('maps polarity HIGHER_IS_BETTER on metric spec', () => {
@@ -1599,7 +1599,7 @@
     const state = metricSpecToMetricsState(spec);
 
     const cols = state.valueColumns as Array<Record<string, unknown>>;
-    expect(cols[0].polarity).toBe('HIGHER_IS_BETTER');
+    expect(cols[0]!.polarity).toBe('HIGHER_IS_BETTER');
   });
 
   it('maps polarity NOT_APPLICABLE on metric spec', () => {
@@ -1612,7 +1612,7 @@
     const state = metricSpecToMetricsState(spec);
 
     const cols = state.valueColumns as Array<Record<string, unknown>>;
-    expect(cols[0].polarity).toBe('NOT_APPLICABLE');
+    expect(cols[0]!.polarity).toBe('NOT_APPLICABLE');
   });
 
   it('defaults polarity to NOT_APPLICABLE when unset', () => {
@@ -1624,7 +1624,7 @@
     const state = metricSpecToMetricsState(spec);
 
     const cols = state.valueColumns as Array<Record<string, unknown>>;
-    expect(cols[0].polarity).toBe('NOT_APPLICABLE');
+    expect(cols[0]!.polarity).toBe('NOT_APPLICABLE');
   });
 
   it('does not include bundle_id in state', () => {
@@ -1769,7 +1769,7 @@
     const state = templateSpecToMetricsState(spec);
 
     const cols = state.valueColumns as Array<Record<string, unknown>>;
-    expect(cols[0].polarity).toBe('HIGHER_IS_BETTER');
+    expect(cols[0]!.polarity).toBe('HIGHER_IS_BETTER');
   });
 });
 
@@ -1808,8 +1808,8 @@
     const result = decomposeStructuredQuery(sq, 0, 0, sharedQueries);
 
     expect(result.nodes).toHaveLength(1);
-    expect(result.nodes[0].type).toBe(NodeType.kTable);
-    const state = result.nodes[0].state as Record<string, unknown>;
+    expect(result.nodes[0]!.type).toBe(NodeType.kTable);
+    const state = result.nodes[0]!.state as Record<string, unknown>;
     expect(state.sqlTable).toBe('slice');
     expect(state.moduleName).toBe('linux.cpu');
   });
@@ -1856,8 +1856,8 @@
     const filterState = filterNode?.state as Record<string, unknown>;
     const filters = filterState.filters as Array<Record<string, unknown>>;
     expect(filters).toHaveLength(1);
-    expect(filters[0].column).toBe('dur');
-    expect(filters[0].op).toBe('>');
+    expect(filters[0]!.column).toBe('dur');
+    expect(filters[0]!.op).toBe('>');
   });
 
   it('falls back to SqlSourceNode when inner_query_id is not found', () => {
@@ -1877,7 +1877,7 @@
 
     // Not found in map — falls back to SqlSourceNode.
     expect(result.nodes).toHaveLength(1);
-    expect(result.nodes[0].type).toBe(NodeType.kSqlSource);
+    expect(result.nodes[0]!.type).toBe(NodeType.kSqlSource);
   });
 
   it('resolves nested inner_query_id references', () => {
@@ -1922,9 +1922,9 @@
     const filterNode = result.nodes.find((n) => n.type === NodeType.kFilter);
     const filterState = filterNode?.state as Record<string, unknown>;
     const filters = filterState.filters as Array<Record<string, unknown>>;
-    expect(filters[0].column).toBe('name');
-    expect(filters[0].op).toBe('GLOB');
-    expect(filters[0].value).toBe('Render*');
+    expect(filters[0]!.column).toBe('name');
+    expect(filters[0]!.op).toBe('GLOB');
+    expect(filters[0]!.value).toBe('Render*');
   });
 
   it('applies operations from the referencing query on top of resolved shared query', () => {
@@ -1957,8 +1957,8 @@
     const filterNode = result.nodes.find((n) => n.type === NodeType.kFilter);
     const filterState = filterNode?.state as Record<string, unknown>;
     const filters = filterState.filters as Array<Record<string, unknown>>;
-    expect(filters[0].column).toBe('dur');
-    expect(filters[0].value).toBe('5000');
+    expect(filters[0]!.column).toBe('dur');
+    expect(filters[0]!.value).toBe('5000');
   });
 });
 
@@ -2000,8 +2000,8 @@
     const result = decomposeStructuredQuery(sq, 0, 0, undefined, mockModules);
 
     expect(result.nodes).toHaveLength(1);
-    expect(result.nodes[0].type).toBe(NodeType.kTable);
-    const state = result.nodes[0].state as Record<string, unknown>;
+    expect(result.nodes[0]!.type).toBe(NodeType.kTable);
+    const state = result.nodes[0]!.state as Record<string, unknown>;
     expect(state.sqlTable).toBe('slice');
     expect(state.moduleName).toBe('slices');
   });
@@ -2015,8 +2015,8 @@
     const result = decomposeStructuredQuery(sq, 0, 0, undefined, mockModules);
 
     expect(result.nodes).toHaveLength(1);
-    expect(result.nodes[0].type).toBe(NodeType.kSqlSource);
-    const state = result.nodes[0].state as Record<string, unknown>;
+    expect(result.nodes[0]!.type).toBe(NodeType.kSqlSource);
+    const state = result.nodes[0]!.state as Record<string, unknown>;
     expect(state.sql).toBe('SELECT * FROM custom_table');
   });
 
@@ -2029,8 +2029,8 @@
     const result = decomposeStructuredQuery(sq, 0, 0, undefined, mockModules);
 
     expect(result.nodes).toHaveLength(1);
-    expect(result.nodes[0].type).toBe(NodeType.kSqlSource);
-    const state = result.nodes[0].state as Record<string, unknown>;
+    expect(result.nodes[0]!.type).toBe(NodeType.kSqlSource);
+    const state = result.nodes[0]!.state as Record<string, unknown>;
     expect(state.sql).toBe(
       'INCLUDE PERFETTO MODULE my.module;\nSELECT * FROM my_table',
     );
@@ -2045,8 +2045,8 @@
     const result = decomposeStructuredQuery(sq, 0, 0, undefined, mockModules);
 
     expect(result.nodes).toHaveLength(1);
-    expect(result.nodes[0].type).toBe(NodeType.kSqlSource);
-    const state = result.nodes[0].state as Record<string, unknown>;
+    expect(result.nodes[0]!.type).toBe(NodeType.kSqlSource);
+    const state = result.nodes[0]!.state as Record<string, unknown>;
     expect(state.sql).toBe('SELECT * FROM orphan_table');
   });
 
@@ -2058,8 +2058,8 @@
     const result = decomposeStructuredQuery(sq, 0, 0);
 
     expect(result.nodes).toHaveLength(1);
-    expect(result.nodes[0].type).toBe(NodeType.kTable);
-    const state = result.nodes[0].state as Record<string, unknown>;
+    expect(result.nodes[0]!.type).toBe(NodeType.kTable);
+    const state = result.nodes[0]!.state as Record<string, unknown>;
     expect(state.sqlTable).toBe('any_table');
     expect(state.moduleName).toBe('any.module');
   });
@@ -2262,9 +2262,9 @@
     const state = filter!.state as Record<string, unknown>;
     const filters = state.filters as Array<Record<string, unknown>>;
     expect(filters).toHaveLength(1);
-    expect(filters[0].column).toBe('state');
-    expect(filters[0].op).toBe('=');
-    expect(filters[0].value).toBe('Running');
+    expect(filters[0]!.column).toBe('state');
+    expect(filters[0]!.op).toBe('=');
+    expect(filters[0]!.value).toBe('Running');
   });
 
   it('aggregation groups by utid with SUM(dur) AS sum_dur', () => {
@@ -2273,11 +2273,11 @@
     const state = agg!.state as Record<string, unknown>;
     const groupByCols = state.groupByColumns as Array<Record<string, unknown>>;
     expect(groupByCols).toHaveLength(1);
-    expect(groupByCols[0].name).toBe('utid');
+    expect(groupByCols[0]!.name).toBe('utid');
     const aggs = state.aggregations as Array<Record<string, unknown>>;
     expect(aggs).toHaveLength(1);
-    expect(aggs[0].aggregationOp).toBe('SUM');
-    expect(aggs[0].newColumnName).toBe('sum_dur');
+    expect(aggs[0]!.aggregationOp).toBe('SUM');
+    expect(aggs[0]!.newColumnName).toBe('sum_dur');
   });
 
   it('sort by sum_dur DESC', () => {
@@ -2286,8 +2286,8 @@
     const state = sort!.state as Record<string, unknown>;
     const criteria = state.sortCriteria as Array<Record<string, unknown>>;
     expect(criteria).toHaveLength(1);
-    expect(criteria[0].colName).toBe('sum_dur');
-    expect(criteria[0].direction).toBe('DESC');
+    expect(criteria[0]!.colName).toBe('sum_dur');
+    expect(criteria[0]!.direction).toBe('DESC');
   });
 
   it('limit is 10', () => {
@@ -2328,11 +2328,11 @@
     const state = mc!.state as Record<string, unknown>;
     const cols = state.selectedColumns as Array<Record<string, unknown>>;
     expect(cols).toHaveLength(4);
-    expect(cols[0].name).toBe('id');
-    expect(cols[1].name).toBe('name');
-    expect(cols[2].name).toBe('utid');
-    expect(cols[3].name).toBe('sum_dur');
-    expect(cols[3].alias).toBe('total_running_time');
+    expect(cols[0]!.name).toBe('id');
+    expect(cols[1]!.name).toBe('name');
+    expect(cols[2]!.name).toBe('utid');
+    expect(cols[3]!.name).toBe('sum_dur');
+    expect(cols[3]!.alias).toBe('total_running_time');
   });
 
   it('ModifyColumns is chained after Join', () => {
@@ -2356,9 +2356,9 @@
 
     const valueCols = state.valueColumns as Array<Record<string, unknown>>;
     expect(valueCols).toHaveLength(1);
-    expect(valueCols[0].column).toBe('utid');
-    expect(valueCols[0].unit).toBe('COUNT');
-    expect(valueCols[0].polarity).toBe('NOT_APPLICABLE');
+    expect(valueCols[0]!.column).toBe('utid');
+    expect(valueCols[0]!.unit).toBe('COUNT');
+    expect(valueCols[0]!.polarity).toBe('NOT_APPLICABLE');
   });
 
   it('dockable modification nodes have no layout entries', () => {
@@ -2629,7 +2629,7 @@
     ).attrs;
     expect(metricsAttrs?.metricIdPrefix).toBe('x');
     expect(metricsAttrs?.valueColumns.length).toBe(1);
-    expect(metricsAttrs?.valueColumns[0].column).toBe('utid');
+    expect(metricsAttrs?.valueColumns[0]!.column).toBe('utid');
   });
 
   it('Metrics node has correct dimensions from cached availableColumns', () => {
diff --git a/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/charts/chart_config_popup.ts b/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/charts/chart_config_popup.ts
index fe89120..84ca11b 100644
--- a/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/charts/chart_config_popup.ts
+++ b/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/charts/chart_config_popup.ts
@@ -46,7 +46,7 @@
   if (agg === 'COUNT_DISTINCT') {
     // COUNT_DISTINCT works on any column; keep current or pick first.
     return (
-      currentCol ?? (allColumns.length > 0 ? allColumns[0].name : undefined)
+      currentCol ?? (allColumns.length > 0 ? allColumns[0]!.name : undefined)
     );
   }
   // Numeric aggregations: reset if current column isn't numeric.
@@ -54,7 +54,7 @@
   if (currentCol && numericNames.has(currentCol)) {
     return currentCol;
   }
-  return numericColumns.length > 0 ? numericColumns[0].name : undefined;
+  return numericColumns.length > 0 ? numericColumns[0]!.name : undefined;
 }
 
 export interface ChartConfigPopupContext {
diff --git a/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/column_selector.ts b/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/column_selector.ts
index 49dfe73..3443dfa 100644
--- a/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/column_selector.ts
+++ b/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/column_selector.ts
@@ -93,7 +93,7 @@
                 onchange: (e) => {
                   const newColumns = [...columns];
                   newColumns[index] = {
-                    ...newColumns[index],
+                    ...newColumns[index]!,
                     checked: (e.target as HTMLInputElement).checked,
                   };
                   onColumnsChange(newColumns);
@@ -110,7 +110,7 @@
                     onReorder: (from: number, to: number) => {
                       const newColumns = [...columns];
                       const [removed] = newColumns.splice(from, 1);
-                      newColumns.splice(to, 0, removed);
+                      newColumns.splice(to, 0, removed!);
                       onColumnsChange(newColumns);
                     },
                   },
diff --git a/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/function_list_unittest.ts b/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/function_list_unittest.ts
index 102bd29..9bd49c8 100644
--- a/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/function_list_unittest.ts
+++ b/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/function_list_unittest.ts
@@ -144,7 +144,7 @@
       );
 
       expect(results.length).toBe(1);
-      expect(results[0].fn.name).toBe('dur_ns_to_ms');
+      expect(results[0]!.fn.name).toBe('dur_ns_to_ms');
     });
 
     it('should find functions by partial name match', () => {
@@ -184,7 +184,7 @@
       );
 
       expect(results.length).toBe(1);
-      expect(results[0].fn.name).toBe('dur_ns_to_ms');
+      expect(results[0]!.fn.name).toBe('dur_ns_to_ms');
     });
   });
 
@@ -206,7 +206,7 @@
       );
 
       expect(results.length).toBe(1);
-      expect(results[0].fn.name).toBe('ts_to_unix_ms');
+      expect(results[0]!.fn.name).toBe('ts_to_unix_ms');
     });
   });
 
@@ -249,7 +249,7 @@
       );
 
       expect(filteredFunctions.length).toBe(1);
-      expect(filteredFunctions[0].fn.name).toBe('format_duration');
+      expect(filteredFunctions[0]!.fn.name).toBe('format_duration');
     });
   });
 });
diff --git a/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/graph/graph.ts b/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/graph/graph.ts
index 90e5e17..7f40fca 100644
--- a/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/graph/graph.ts
+++ b/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/graph/graph.ts
@@ -255,8 +255,8 @@
     if (i > 0) {
       menuItems.push(m(MenuDivider));
     }
-    menuItems.push(m(MenuTitle, {label: sections[i].title}));
-    menuItems.push(...sections[i].items);
+    menuItems.push(m(MenuTitle, {label: sections[i]!.title}));
+    menuItems.push(...sections[i]!.items);
   }
   return menuItems;
 }
@@ -744,8 +744,8 @@
       if (i > 0) {
         addNodeMenuItems.push(m(MenuDivider));
       }
-      addNodeMenuItems.push(m(MenuTitle, {label: sections[i].title}));
-      addNodeMenuItems.push(...sections[i].items);
+      addNodeMenuItems.push(m(MenuTitle, {label: sections[i]!.title}));
+      addNodeMenuItems.push(...sections[i]!.items);
     }
     addNodeMenuItems.push(m(MenuDivider));
     addNodeMenuItems.push(
@@ -978,7 +978,7 @@
           },
           onConnectionRemove: (index: number) => {
             handleConnectionRemove(
-              connections[index],
+              connections[index]!,
               rootNodes,
               attrs.onConnectionRemove,
             );
diff --git a/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/graph/node_box.ts b/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/graph/node_box.ts
index 7793ab1..5f5f03c 100644
--- a/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/graph/node_box.ts
+++ b/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/graph/node_box.ts
@@ -76,8 +76,8 @@
     if (i > 0) {
       menuItems.push(m(MenuDivider));
     }
-    menuItems.push(m(MenuTitle, {label: sections[i].title}));
-    menuItems.push(...sections[i].items);
+    menuItems.push(m(MenuTitle, {label: sections[i]!.title}));
+    menuItems.push(...sections[i]!.items);
   }
 
   return m(
diff --git a/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/graph/node_config.ts b/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/graph/node_config.ts
index a970195..4394858 100644
--- a/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/graph/node_config.ts
+++ b/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/graph/node_config.ts
@@ -140,12 +140,12 @@
   let next: Omit<Node, 'x' | 'y'> | undefined;
   if (
     qnode.nextNodes.length === 1 &&
-    singleNodeOperation(qnode.nextNodes[0].type) &&
-    qnode.nextNodes[0].primaryInput === qnode &&
-    innerSet.has(qnode.nextNodes[0].nodeId)
+    singleNodeOperation(qnode.nextNodes[0]!.type) &&
+    qnode.nextNodes[0]!.primaryInput === qnode &&
+    innerSet.has(qnode.nextNodes[0]!.nodeId)
   ) {
     next = buildReadOnlyNodeConfig(
-      qnode.nextNodes[0],
+      qnode.nextNodes[0]!,
       innerSet,
       connectedInputs,
       connectedOutputs,
diff --git a/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/graph_utils.ts b/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/graph_utils.ts
index 88a4acb..c0647d8 100644
--- a/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/graph_utils.ts
+++ b/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/graph_utils.ts
@@ -409,7 +409,7 @@
   const layouts = new Map<string, {x: number; y: number}>();
 
   for (let i = 0; i < children.length; i++) {
-    layouts.set(children[i].nodeId, {
+    layouts.set(children[i]!.nodeId, {
       x: parentLayout.x + UNDOCK_X_OFFSET + i * UNDOCK_STAGGER,
       y: parentLayout.y + i * UNDOCK_STAGGER,
     });
@@ -707,7 +707,7 @@
     );
   }
 
-  const endNode = endNodes[0];
+  const endNode = endNodes[0]!;
 
   // Collect all external connections (sources outside the group → inner nodes).
   const externalConnections: ExternalGroupConnection[] = [];
@@ -801,7 +801,7 @@
   // endNode no longer has direct outer connections; GroupNode owns them.
   // Mutate in-place so existing references to the array stay consistent.
   for (let i = endNode.nextNodes.length - 1; i >= 0; i--) {
-    if (!innerSet.has(endNode.nextNodes[i].nodeId)) {
+    if (!innerSet.has(endNode.nextNodes[i]!.nodeId)) {
       endNode.nextNodes.splice(i, 1);
     }
   }
diff --git a/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/graph_utils_unittest.ts b/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/graph_utils_unittest.ts
index 7b1139b..6302092 100644
--- a/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/graph_utils_unittest.ts
+++ b/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/graph_utils_unittest.ts
@@ -507,8 +507,8 @@
 
       const group = result.value;
       expect(group.externalConnections).toHaveLength(1);
-      expect(group.externalConnections[0].sourceNode).toBe(ext);
-      expect(group.externalConnections[0].innerTargetNode).toBe(a);
+      expect(group.externalConnections[0]!.sourceNode).toBe(ext);
+      expect(group.externalConnections[0]!.innerTargetNode).toBe(a);
     });
 
     it('should set outer nodes as nextNodes on the group', () => {
@@ -790,8 +790,8 @@
       expect(group.endNode).toBe(c);
       // A feeds into B from outside
       expect(group.externalConnections).toHaveLength(1);
-      expect(group.externalConnections[0].sourceNode).toBe(a);
-      expect(group.externalConnections[0].innerTargetNode).toBe(b);
+      expect(group.externalConnections[0]!.sourceNode).toBe(a);
+      expect(group.externalConnections[0]!.innerTargetNode).toBe(b);
       // outer is the successor
       expect(group.nextNodes).toHaveLength(1);
       expect(group.nextNodes[0]).toBe(outer);
diff --git a/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/join_widgets.ts b/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/join_widgets.ts
index 3fe550f..af51f88 100644
--- a/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/join_widgets.ts
+++ b/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/join_widgets.ts
@@ -301,7 +301,7 @@
           const inputValue = (e.target as HTMLInputElement).value;
           const newColumns = [...columns];
           newColumns[index] = {
-            ...newColumns[index],
+            ...newColumns[index]!,
             alias: inputValue.trim() === '' ? undefined : inputValue,
           };
           onColumnsChange(newColumns);
diff --git a/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/legacy_connections.ts b/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/legacy_connections.ts
index 77836c0..d7a4f3b 100644
--- a/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/legacy_connections.ts
+++ b/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/legacy_connections.ts
@@ -81,7 +81,7 @@
     const ids = s[spec.field] as string[] | undefined;
     if (!ids) return;
     for (let i = 0; i < ids.length; i++) {
-      const n = allNodes.get(ids[i]);
+      const n = allNodes.get(ids[i]!);
       if (n) node.secondaryInputs.connections.set(i, n);
     }
   } else if (spec.type === 'singleField') {
diff --git a/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/node_propagation_unittest.ts b/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/node_propagation_unittest.ts
index 070dad5..38067a1 100644
--- a/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/node_propagation_unittest.ts
+++ b/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/node_propagation_unittest.ts
@@ -51,7 +51,7 @@
       ]);
 
       // THE BUG: Rename 'name' to 'user_name' in ModifyColumnsNode
-      modifyNode.attrs.selectedColumns[1].alias = 'user_name';
+      modifyNode.attrs.selectedColumns[1]!.alias = 'user_name';
 
       // BEFORE FIX: AggregationNode would still show 'id', 'name', 'value'
       // AFTER FIX: We need to call onPrevNodesUpdated to propagate the change
@@ -79,37 +79,37 @@
 
       // Verify modify node has the original columns
       expect(modifyNode.attrs.selectedColumns).toHaveLength(3);
-      expect(modifyNode.attrs.selectedColumns[0].name).toBe('id');
-      expect(modifyNode.attrs.selectedColumns[1].name).toBe('name');
-      expect(modifyNode.attrs.selectedColumns[2].name).toBe('value');
+      expect(modifyNode.attrs.selectedColumns[0]!.name).toBe('id');
+      expect(modifyNode.attrs.selectedColumns[1]!.name).toBe('name');
+      expect(modifyNode.attrs.selectedColumns[2]!.name).toBe('value');
 
       // Initialize the aggregation node
       aggNode.onPrevNodesUpdated?.();
 
       // Verify aggregation node has the original columns
       expect(aggNode.attrs.groupByColumns).toHaveLength(3);
-      expect(aggNode.attrs.groupByColumns[0].name).toBe('id');
-      expect(aggNode.attrs.groupByColumns[1].name).toBe('name');
-      expect(aggNode.attrs.groupByColumns[2].name).toBe('value');
+      expect(aggNode.attrs.groupByColumns[0]!.name).toBe('id');
+      expect(aggNode.attrs.groupByColumns[1]!.name).toBe('name');
+      expect(aggNode.attrs.groupByColumns[2]!.name).toBe('value');
 
       // Now rename 'name' to 'user_name' in the modify node
-      modifyNode.attrs.selectedColumns[1].alias = 'user_name';
+      modifyNode.attrs.selectedColumns[1]!.alias = 'user_name';
 
       // Verify the finalCols of modify node uses the alias
       const modifyFinalCols = modifyNode.finalCols;
       expect(modifyFinalCols).toHaveLength(3);
-      expect(modifyFinalCols[0].name).toBe('id');
-      expect(modifyFinalCols[1].name).toBe('user_name'); // Should use alias
-      expect(modifyFinalCols[2].name).toBe('value');
+      expect(modifyFinalCols[0]!.name).toBe('id');
+      expect(modifyFinalCols[1]!.name).toBe('user_name'); // Should use alias
+      expect(modifyFinalCols[2]!.name).toBe('value');
 
       // Simulate the builder's onchange behavior: notify downstream nodes
       aggNode.onPrevNodesUpdated?.();
 
       // Verify aggregation node now sees the renamed column
       expect(aggNode.attrs.groupByColumns).toHaveLength(3);
-      expect(aggNode.attrs.groupByColumns[0].name).toBe('id');
-      expect(aggNode.attrs.groupByColumns[1].name).toBe('user_name'); // Should see the alias
-      expect(aggNode.attrs.groupByColumns[2].name).toBe('value');
+      expect(aggNode.attrs.groupByColumns[0]!.name).toBe('id');
+      expect(aggNode.attrs.groupByColumns[1]!.name).toBe('user_name'); // Should see the alias
+      expect(aggNode.attrs.groupByColumns[2]!.name).toBe('value');
     });
 
     it('should preserve checked status when columns are renamed', () => {
@@ -126,10 +126,10 @@
       initializeNodeChain([modifyNode, aggNode]);
 
       // Check a column in the aggregation node
-      aggNode.attrs.groupByColumns[1].checked = true; // Check 'name'
+      aggNode.attrs.groupByColumns[1]!.checked = true; // Check 'name'
 
       // Rename the checked column in modify node
-      modifyNode.attrs.selectedColumns[1].alias = 'user_name';
+      modifyNode.attrs.selectedColumns[1]!.alias = 'user_name';
 
       // Notify downstream
       aggNode.onPrevNodesUpdated?.();
@@ -161,20 +161,20 @@
       expect(aggNode.attrs.groupByColumns).toHaveLength(3);
 
       // Uncheck 'name' column in modify node (removes it from output)
-      modifyNode.attrs.selectedColumns[1].checked = false;
+      modifyNode.attrs.selectedColumns[1]!.checked = false;
 
       // Verify modify node's finalCols only has 2 columns now
       expect(modifyNode.finalCols).toHaveLength(2);
-      expect(modifyNode.finalCols[0].name).toBe('id');
-      expect(modifyNode.finalCols[1].name).toBe('value');
+      expect(modifyNode.finalCols[0]!.name).toBe('id');
+      expect(modifyNode.finalCols[1]!.name).toBe('value');
 
       // Notify downstream
       aggNode.onPrevNodesUpdated?.();
 
       // Aggregation node should now only have 2 columns
       expect(aggNode.attrs.groupByColumns).toHaveLength(2);
-      expect(aggNode.attrs.groupByColumns[0].name).toBe('id');
-      expect(aggNode.attrs.groupByColumns[1].name).toBe('value');
+      expect(aggNode.attrs.groupByColumns[0]!.name).toBe('id');
+      expect(aggNode.attrs.groupByColumns[1]!.name).toBe('value');
     });
 
     it('should handle column reordering in ModifyColumnsNode', () => {
@@ -195,7 +195,7 @@
 
       // Reorder: move 'value' to the front
       const cols = modifyNode.attrs.selectedColumns;
-      modifyNode.attrs.selectedColumns = [cols[2], cols[0], cols[1]];
+      modifyNode.attrs.selectedColumns = [cols[2]!, cols[0]!, cols[1]!];
 
       // Verify modify node's finalCols are reordered
       expectColumnNames(modifyNode, ['value', 'id', 'name']);
@@ -204,9 +204,9 @@
       aggNode.onPrevNodesUpdated?.();
 
       // Aggregation node should see the new order
-      expect(aggNode.attrs.groupByColumns[0].name).toBe('value');
-      expect(aggNode.attrs.groupByColumns[1].name).toBe('id');
-      expect(aggNode.attrs.groupByColumns[2].name).toBe('name');
+      expect(aggNode.attrs.groupByColumns[0]!.name).toBe('value');
+      expect(aggNode.attrs.groupByColumns[1]!.name).toBe('id');
+      expect(aggNode.attrs.groupByColumns[2]!.name).toBe('name');
     });
   });
 
@@ -232,7 +232,7 @@
       expectColumnNames(modify3, ['id', 'name', 'value']);
 
       // Rename 'name' to 'user_name' in modify1
-      modify1.attrs.selectedColumns[1].alias = 'user_name';
+      modify1.attrs.selectedColumns[1]!.alias = 'user_name';
 
       // Notify all downstream nodes (simulating builder's onchange)
       initializeNodeChain([modify2, modify3]);
@@ -263,7 +263,7 @@
       initializeNodeChain([modify1, modify2, modify3, modify4, modify5]);
 
       // Edit the MIDDLE node (modify3) - rename 'value' to 'amount'
-      modify3.attrs.selectedColumns[2].alias = 'amount';
+      modify3.attrs.selectedColumns[2]!.alias = 'amount';
 
       // Notify all downstream nodes (simulating builder's onchange)
       initializeNodeChain([modify4, modify5]);
@@ -294,8 +294,8 @@
       initializeNodeChain([modify1, aggNode]);
 
       // Check columns BEFORE renaming and BEFORE initializing modify2
-      aggNode.attrs.groupByColumns[0].checked = true; // Check 'id'
-      aggNode.attrs.groupByColumns[1].checked = true; // Check 'name'
+      aggNode.attrs.groupByColumns[0]!.checked = true; // Check 'id'
+      aggNode.attrs.groupByColumns[1]!.checked = true; // Check 'name'
 
       // Now initialize modify2 after aggNode has checked columns
       modify2.onPrevNodesUpdated?.();
@@ -305,7 +305,7 @@
       expect(modify2.finalCols.map((c) => c.name)).toContain('name');
 
       // Rename 'name' to 'user_name' in modify1
-      modify1.attrs.selectedColumns[1].alias = 'user_name';
+      modify1.attrs.selectedColumns[1]!.alias = 'user_name';
 
       // Notify all downstream nodes
       initializeNodeChain([aggNode, modify2]);
@@ -354,19 +354,19 @@
       initializeNodeChain([modify1, modify2, modify3]);
 
       // First edit: modify1 renames 'name' to 'user_name'
-      modify1.attrs.selectedColumns[1].alias = 'user_name';
+      modify1.attrs.selectedColumns[1]!.alias = 'user_name';
       initializeNodeChain([modify2, modify3]);
 
       expectColumnNames(modify3, ['id', 'user_name', 'value']);
 
       // Second edit: modify2 renames 'user_name' to 'username'
-      modify2.attrs.selectedColumns[1].alias = 'username';
+      modify2.attrs.selectedColumns[1]!.alias = 'username';
       modify3.onPrevNodesUpdated?.();
 
       expectColumnNames(modify3, ['id', 'username', 'value']);
 
       // Third edit: modify2 also renames 'id' to 'identifier'
-      modify2.attrs.selectedColumns[0].alias = 'identifier';
+      modify2.attrs.selectedColumns[0]!.alias = 'identifier';
       modify3.onPrevNodesUpdated?.();
 
       expectColumnNames(modify3, ['identifier', 'username', 'value']);
@@ -393,7 +393,7 @@
       expect(modify4.finalCols).toHaveLength(3);
 
       // Remove 'name' column in modify2 (middle of chain)
-      modify2.attrs.selectedColumns[1].checked = false;
+      modify2.attrs.selectedColumns[1]!.checked = false;
       initializeNodeChain([modify3, modify4]);
 
       // All downstream nodes should only have 2 columns now
@@ -424,7 +424,7 @@
       aggOnPrevNodesUpdatedSpy.mockClear();
 
       // Make a change in modify node and trigger propagation
-      modifyNode.attrs.selectedColumns[0].alias = 'identifier';
+      modifyNode.attrs.selectedColumns[0]!.alias = 'identifier';
       aggNode.onPrevNodesUpdated?.();
 
       // Verify it was called
@@ -459,7 +459,7 @@
       });
 
       // Check a column to include in output
-      aggNode.attrs.groupByColumns[0].checked = true; // Check 'id'
+      aggNode.attrs.groupByColumns[0]!.checked = true; // Check 'id'
 
       // User adds a modify columns node below
       // Initialize it - it should see 'id' and 'count' from aggregation
@@ -472,7 +472,7 @@
       ]);
 
       // User goes back to aggregation and renames "count" to "my_count"
-      aggNode.attrs.aggregations[0].newColumnName = 'my_count';
+      aggNode.attrs.aggregations[0]!.newColumnName = 'my_count';
 
       // Simulate the builder's onchange behavior: notify downstream nodes
       // This is what SHOULD happen automatically when user edits in UI
@@ -522,7 +522,7 @@
       });
 
       // Check a group by column
-      aggNode.attrs.groupByColumns[0].checked = true; // Check 'id'
+      aggNode.attrs.groupByColumns[0]!.checked = true; // Check 'id'
 
       // Initialize the modify node
       modifyNode.onPrevNodesUpdated?.();
@@ -535,8 +535,8 @@
       ]);
 
       // Rename both aggregation columns
-      aggNode.attrs.aggregations[0].newColumnName = 'num_rows';
-      aggNode.attrs.aggregations[1].newColumnName = 'sum_value';
+      aggNode.attrs.aggregations[0]!.newColumnName = 'num_rows';
+      aggNode.attrs.aggregations[1]!.newColumnName = 'sum_value';
 
       // Propagate changes
       modifyNode.onPrevNodesUpdated?.();
@@ -563,7 +563,7 @@
 
       // Initialize
       aggNode.onPrevNodesUpdated?.();
-      aggNode.attrs.groupByColumns[1].checked = true; // Check 'name'
+      aggNode.attrs.groupByColumns[1]!.checked = true; // Check 'name'
       aggNode.attrs.aggregations.push({
         aggregationOp: 'COUNT(*)',
         newColumnName: 'count',
@@ -576,7 +576,7 @@
       expectColumnNames(modify2, ['name', 'count']);
 
       // Rename aggregation column
-      aggNode.attrs.aggregations[0].newColumnName = 'total_count';
+      aggNode.attrs.aggregations[0]!.newColumnName = 'total_count';
 
       // Propagate to both downstream nodes
       initializeNodeChain([modify1, modify2]);
@@ -601,7 +601,7 @@
 
       // Initialize
       aggNode.onPrevNodesUpdated?.();
-      aggNode.attrs.groupByColumns[0].checked = true; // Check 'id'
+      aggNode.attrs.groupByColumns[0]!.checked = true; // Check 'id'
       aggNode.attrs.aggregations.push({
         aggregationOp: 'COUNT(*)',
         newColumnName: 'count',
@@ -613,7 +613,7 @@
       expectColumnNames(modifyNode, ['id', 'count']);
 
       // Rename aggregation column
-      aggNode.attrs.aggregations[0].newColumnName = 'row_count';
+      aggNode.attrs.aggregations[0]!.newColumnName = 'row_count';
 
       // Propagate through middle node to modify node
       initializeNodeChain([middleNode, modifyNode]);
@@ -635,7 +635,7 @@
 
       // Initialize agg1
       agg1.onPrevNodesUpdated?.();
-      agg1.attrs.groupByColumns[0].checked = true; // Group by 'id'
+      agg1.attrs.groupByColumns[0]!.checked = true; // Group by 'id'
       agg1.attrs.aggregations.push({
         aggregationOp: 'SUM',
         column: agg1.attrs.groupByColumns.find((c) => c.name === 'value'),
@@ -650,7 +650,7 @@
       ]);
 
       // In agg2, do another aggregation
-      agg2.attrs.groupByColumns[0].checked = true; // Group by 'id'
+      agg2.attrs.groupByColumns[0]!.checked = true; // Group by 'id'
       agg2.attrs.aggregations.push({
         aggregationOp: 'COUNT(*)',
         newColumnName: 'count',
@@ -661,7 +661,7 @@
       expectColumnNames(modifyNode, ['id', 'count']);
 
       // Now change column name in FIRST aggregation (agg1)
-      agg1.attrs.aggregations[0].newColumnName = 'sum_value';
+      agg1.attrs.aggregations[0]!.newColumnName = 'sum_value';
 
       // Propagate through the chain
       agg2.onPrevNodesUpdated?.();
@@ -674,7 +674,7 @@
       expectColumnNames(modifyNode, ['id', 'count']);
 
       // Now also change column name in SECOND aggregation (agg2)
-      agg2.attrs.aggregations[0].newColumnName = 'num_groups';
+      agg2.attrs.aggregations[0]!.newColumnName = 'num_groups';
 
       // Propagate to modify node
       modifyNode.onPrevNodesUpdated?.();
@@ -698,7 +698,7 @@
       aggNode.onPrevNodesUpdated?.();
 
       // Add a valid aggregation
-      aggNode.attrs.groupByColumns[0].checked = true; // Check 'id'
+      aggNode.attrs.groupByColumns[0]!.checked = true; // Check 'id'
       aggNode.attrs.aggregations.push({
         aggregationOp: 'COUNT(*)',
         newColumnName: 'count',
@@ -715,7 +715,7 @@
 
       // Now make the aggregation INVALID by removing the operation
       // (simulating user deleting the operation while editing)
-      aggNode.attrs.aggregations[0].aggregationOp = undefined;
+      aggNode.attrs.aggregations[0]!.aggregationOp = undefined;
 
       // Notify downstream
       modifyNode.onPrevNodesUpdated?.();
@@ -744,7 +744,7 @@
 
       // Initialize
       aggNode.onPrevNodesUpdated?.();
-      aggNode.attrs.groupByColumns[0].checked = true; // Check 'id'
+      aggNode.attrs.groupByColumns[0]!.checked = true; // Check 'id'
 
       // Start with an INVALID aggregation (no operation selected)
       aggNode.attrs.aggregations.push({
@@ -761,7 +761,7 @@
       ]);
 
       // Now make it valid by adding an operation
-      aggNode.attrs.aggregations[0].aggregationOp = 'COUNT(*)';
+      aggNode.attrs.aggregations[0]!.aggregationOp = 'COUNT(*)';
 
       // Notify downstream
       modifyNode.onPrevNodesUpdated?.();
@@ -786,7 +786,7 @@
 
       // Initialize
       aggNode.onPrevNodesUpdated?.();
-      aggNode.attrs.groupByColumns[0].checked = true; // Check 'id'
+      aggNode.attrs.groupByColumns[0]!.checked = true; // Check 'id'
 
       // Add multiple aggregations: some valid, some invalid
       aggNode.attrs.aggregations.push({
@@ -840,7 +840,7 @@
 
       // Initialize
       aggNode.onPrevNodesUpdated?.();
-      aggNode.attrs.groupByColumns[0].checked = true;
+      aggNode.attrs.groupByColumns[0]!.checked = true;
 
       // Scenario 1: User creates aggregation WITHOUT manual name (uses placeholder)
       aggNode.attrs.aggregations.push({
@@ -857,7 +857,7 @@
       );
 
       // Scenario 2: User manually enters their own name "my_custom_sum"
-      aggNode.attrs.aggregations[0].newColumnName = 'my_custom_sum';
+      aggNode.attrs.aggregations[0]!.newColumnName = 'my_custom_sum';
       modifyNode.onPrevNodesUpdated?.();
 
       // Should now see manual name, NOT placeholder
@@ -869,7 +869,7 @@
       );
 
       // Scenario 3: User changes manual name to something else
-      aggNode.attrs.aggregations[0].newColumnName = 'total_amount';
+      aggNode.attrs.aggregations[0]!.newColumnName = 'total_amount';
       modifyNode.onPrevNodesUpdated?.();
 
       // Should see the new manual name
@@ -884,7 +884,7 @@
       );
 
       // Scenario 4: User changes the operation (manual name still takes precedence)
-      aggNode.attrs.aggregations[0].aggregationOp = 'AVG';
+      aggNode.attrs.aggregations[0]!.aggregationOp = 'AVG';
       modifyNode.onPrevNodesUpdated?.();
 
       // Should STILL see "total_amount" (manual name), NOT "avg_value" (placeholder)
diff --git a/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/node_registry_unittest.ts b/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/node_registry_unittest.ts
index cb539d8..0c75d0e 100644
--- a/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/node_registry_unittest.ts
+++ b/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/node_registry_unittest.ts
@@ -247,8 +247,8 @@
       const result = registry.list();
 
       expect(result.length).toBe(1);
-      expect(result[0][0]).toBe('test-node');
-      expect(result[0][1]).toBe(descriptor);
+      expect(result[0]![0]).toBe('test-node');
+      expect(result[0]![1]).toBe(descriptor);
     });
 
     it('should reflect updates when node is re-registered', () => {
@@ -273,12 +273,12 @@
       registry.register('node1', descriptor1);
       let result = registry.list();
       expect(result.length).toBe(1);
-      expect(result[0][1].name).toBe('Node 1');
+      expect(result[0]![1].name).toBe('Node 1');
 
       registry.register('node1', descriptor2);
       result = registry.list();
       expect(result.length).toBe(1);
-      expect(result[0][1].name).toBe('Node 1 Updated');
+      expect(result[0]![1].name).toBe('Node 1 Updated');
     });
   });
 
diff --git a/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/nodes/add_columns_configuration_modal.ts b/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/nodes/add_columns_configuration_modal.ts
index fa7c0b8..49b9383 100644
--- a/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/nodes/add_columns_configuration_modal.ts
+++ b/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/nodes/add_columns_configuration_modal.ts
@@ -136,11 +136,11 @@
           onRightColumnChange(columnName);
         },
         onColumnToggle: (index: number, checked: boolean) => {
-          const colName = rightCols[index].name;
+          const colName = rightCols[index]!.name;
           onColumnToggle(colName, checked);
         },
         onColumnAlias: (index: number, alias: string) => {
-          const colName = rightCols[index].name;
+          const colName = rightCols[index]!.name;
           onColumnAlias(colName, alias);
         },
       }),
diff --git a/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/nodes/add_columns_node.ts b/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/nodes/add_columns_node.ts
index b3f5e2d..8f1fb65 100644
--- a/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/nodes/add_columns_node.ts
+++ b/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/nodes/add_columns_node.ts
@@ -236,7 +236,7 @@
     // Check against other computed columns
     for (let i = 0; i < (this.attrs.computedColumns?.length ?? 0); i++) {
       if (i === excludeIndex) continue; // Skip the column being edited
-      const col = this.attrs.computedColumns![i];
+      const col = this.attrs.computedColumns![i]!;
       if (col.name.trim() === trimmedName) {
         return `Column "${trimmedName}" already exists in computed columns`;
       }
@@ -1212,7 +1212,7 @@
       if (!this.attrs.computedColumns) return;
       const newComputedColumns = [...this.attrs.computedColumns];
       newComputedColumns[index] = {
-        ...newComputedColumns[index],
+        ...newComputedColumns[index]!,
         sqlType: newType,
       };
       this.attrs.computedColumns = newComputedColumns;
diff --git a/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/nodes/add_columns_suggestion_modal.ts b/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/nodes/add_columns_suggestion_modal.ts
index ed35a18..15282e1 100644
--- a/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/nodes/add_columns_suggestion_modal.ts
+++ b/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/nodes/add_columns_suggestion_modal.ts
@@ -59,7 +59,7 @@
   oncreate({attrs}: m.VnodeDOM<AddColumnsSuggestionModalAttrs>) {
     // Auto-select if there's only one suggestion and nothing is selected yet
     if (attrs.suggestions.length === 1 && !attrs.selectedTable) {
-      attrs.onTableSelect(attrs.suggestions[0].suggestedTable);
+      attrs.onTableSelect(attrs.suggestions[0]!.suggestedTable);
     }
   }
 
@@ -174,12 +174,12 @@
               },
               onColumnToggle: (index: number, checked: boolean) => {
                 if (!tableInfo) return;
-                const colName = tableInfo.columns[index].name;
+                const colName = tableInfo.columns[index]!.name;
                 onColumnToggle(colName, checked);
               },
               onColumnAlias: (index: number, alias: string) => {
                 if (!tableInfo) return;
-                const colName = tableInfo.columns[index].name;
+                const colName = tableInfo.columns[index]!.name;
                 onColumnAlias(colName, alias);
               },
             }),
diff --git a/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/nodes/aggregation_node_unittest.ts b/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/nodes/aggregation_node_unittest.ts
index 87e61c8..6419e01 100644
--- a/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/nodes/aggregation_node_unittest.ts
+++ b/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/nodes/aggregation_node_unittest.ts
@@ -137,7 +137,7 @@
           (agg.column !== undefined && agg.aggregationOp !== undefined);
       }
 
-      expect(node.attrs.aggregations[0].isValid).toBe(true);
+      expect(node.attrs.aggregations[0]!.isValid).toBe(true);
     });
 
     it('should validate PERCENTILE with column and percentile value', () => {
@@ -161,7 +161,7 @@
         }
       }
 
-      expect(node.attrs.aggregations[0].isValid).toBe(true);
+      expect(node.attrs.aggregations[0]!.isValid).toBe(true);
     });
 
     it('should invalidate PERCENTILE with percentile value out of range', () => {
@@ -185,7 +185,7 @@
         }
       }
 
-      expect(node.attrs.aggregations[0].isValid).toBe(false);
+      expect(node.attrs.aggregations[0]!.isValid).toBe(false);
     });
 
     it('should invalidate PERCENTILE without percentile value', () => {
@@ -208,7 +208,7 @@
         }
       }
 
-      expect(node.attrs.aggregations[0].isValid).toBe(false);
+      expect(node.attrs.aggregations[0]!.isValid).toBe(false);
     });
 
     it('should invalidate PERCENTILE without column', () => {
@@ -231,7 +231,7 @@
         }
       }
 
-      expect(node.attrs.aggregations[0].isValid).toBe(false);
+      expect(node.attrs.aggregations[0]!.isValid).toBe(false);
     });
 
     it('should validate MEDIAN with column', () => {
@@ -254,7 +254,7 @@
         }
       }
 
-      expect(node.attrs.aggregations[0].isValid).toBe(true);
+      expect(node.attrs.aggregations[0]!.isValid).toBe(true);
     });
 
     it('should invalidate MEDIAN without column', () => {
@@ -276,7 +276,7 @@
         }
       }
 
-      expect(node.attrs.aggregations[0].isValid).toBe(false);
+      expect(node.attrs.aggregations[0]!.isValid).toBe(false);
     });
 
     it('should validate SUM with column', () => {
@@ -299,7 +299,7 @@
         }
       }
 
-      expect(node.attrs.aggregations[0].isValid).toBe(true);
+      expect(node.attrs.aggregations[0]!.isValid).toBe(true);
     });
   });
 
@@ -326,9 +326,9 @@
 
       expect(node.attrs.aggregations).toBeDefined();
       expect(node.attrs.aggregations.length).toBe(1);
-      expect(node.attrs.aggregations[0].aggregationOp).toBe('PERCENTILE');
-      expect(node.attrs.aggregations[0].percentile).toBe(95);
-      expect(node.attrs.aggregations[0].newColumnName).toBe('p95_dur');
+      expect(node.attrs.aggregations[0]!.aggregationOp).toBe('PERCENTILE');
+      expect(node.attrs.aggregations[0]!.percentile).toBe(95);
+      expect(node.attrs.aggregations[0]!.newColumnName).toBe('p95_dur');
     });
 
     it('should serialize COUNT(*) aggregation without column', () => {
@@ -351,9 +351,9 @@
 
       expect(node.attrs.aggregations).toBeDefined();
       expect(node.attrs.aggregations.length).toBe(1);
-      expect(node.attrs.aggregations[0].aggregationOp).toBe('COUNT(*)');
-      expect(node.attrs.aggregations[0].column).toBeUndefined();
-      expect(node.attrs.aggregations[0].newColumnName).toBe('total_count');
+      expect(node.attrs.aggregations[0]!.aggregationOp).toBe('COUNT(*)');
+      expect(node.attrs.aggregations[0]!.column).toBeUndefined();
+      expect(node.attrs.aggregations[0]!.newColumnName).toBe('total_count');
     });
 
     it('should serialize MEDIAN aggregation', () => {
@@ -377,9 +377,9 @@
 
       expect(node.attrs.aggregations).toBeDefined();
       expect(node.attrs.aggregations.length).toBe(1);
-      expect(node.attrs.aggregations[0].aggregationOp).toBe('MEDIAN');
-      expect(node.attrs.aggregations[0].column?.name).toBe('value');
-      expect(node.attrs.aggregations[0].newColumnName).toBe('median_value');
+      expect(node.attrs.aggregations[0]!.aggregationOp).toBe('MEDIAN');
+      expect(node.attrs.aggregations[0]!.column?.name).toBe('value');
+      expect(node.attrs.aggregations[0]!.newColumnName).toBe('median_value');
     });
 
     it('should serialize multiple aggregations including new types', () => {
@@ -414,10 +414,10 @@
       ];
 
       expect(node.attrs.aggregations.length).toBe(3);
-      expect(node.attrs.aggregations[0].aggregationOp).toBe('COUNT(*)');
-      expect(node.attrs.aggregations[1].aggregationOp).toBe('MEDIAN');
-      expect(node.attrs.aggregations[2].aggregationOp).toBe('PERCENTILE');
-      expect(node.attrs.aggregations[2].percentile).toBe(99);
+      expect(node.attrs.aggregations[0]!.aggregationOp).toBe('COUNT(*)');
+      expect(node.attrs.aggregations[1]!.aggregationOp).toBe('MEDIAN');
+      expect(node.attrs.aggregations[2]!.aggregationOp).toBe('PERCENTILE');
+      expect(node.attrs.aggregations[2]!.percentile).toBe(99);
     });
   });
 
@@ -441,9 +441,9 @@
       );
 
       expect(node.attrs.aggregations.length).toBe(1);
-      expect(node.attrs.aggregations[0].aggregationOp).toBe('PERCENTILE');
-      expect(node.attrs.aggregations[0].percentile).toBe(95);
-      expect(node.attrs.aggregations[0].newColumnName).toBe('p95_dur');
+      expect(node.attrs.aggregations[0]!.aggregationOp).toBe('PERCENTILE');
+      expect(node.attrs.aggregations[0]!.percentile).toBe(95);
+      expect(node.attrs.aggregations[0]!.newColumnName).toBe('p95_dur');
     });
 
     it('should deserialize COUNT(*) aggregation without column', () => {
@@ -463,9 +463,9 @@
       );
 
       expect(node.attrs.aggregations.length).toBe(1);
-      expect(node.attrs.aggregations[0].aggregationOp).toBe('COUNT(*)');
-      expect(node.attrs.aggregations[0].column).toBeUndefined();
-      expect(node.attrs.aggregations[0].newColumnName).toBe('total_count');
+      expect(node.attrs.aggregations[0]!.aggregationOp).toBe('COUNT(*)');
+      expect(node.attrs.aggregations[0]!.column).toBeUndefined();
+      expect(node.attrs.aggregations[0]!.newColumnName).toBe('total_count');
     });
 
     it('should deserialize MEDIAN aggregation', () => {
@@ -486,9 +486,9 @@
       );
 
       expect(node.attrs.aggregations.length).toBe(1);
-      expect(node.attrs.aggregations[0].aggregationOp).toBe('MEDIAN');
-      expect(node.attrs.aggregations[0].column?.name).toBe('value');
-      expect(node.attrs.aggregations[0].newColumnName).toBe('median_value');
+      expect(node.attrs.aggregations[0]!.aggregationOp).toBe('MEDIAN');
+      expect(node.attrs.aggregations[0]!.column?.name).toBe('value');
+      expect(node.attrs.aggregations[0]!.newColumnName).toBe('median_value');
     });
 
     it('should migrate old COUNT_ALL to COUNT(*) for backward compatibility', () => {
@@ -510,9 +510,9 @@
       );
 
       expect(node.attrs.aggregations.length).toBe(1);
-      expect(node.attrs.aggregations[0].aggregationOp).toBe('COUNT(*)');
-      expect(node.attrs.aggregations[0].column).toBeUndefined();
-      expect(node.attrs.aggregations[0].newColumnName).toBe('total_count');
+      expect(node.attrs.aggregations[0]!.aggregationOp).toBe('COUNT(*)');
+      expect(node.attrs.aggregations[0]!.column).toBeUndefined();
+      expect(node.attrs.aggregations[0]!.newColumnName).toBe('total_count');
     });
   });
 
@@ -719,8 +719,8 @@
       );
 
       expect(node.finalCols.length).toBe(1);
-      expect(node.finalCols[0].name).toBe('count_dur');
-      expect(node.finalCols[0].type).toEqual(PerfettoSqlTypes.INT);
+      expect(node.finalCols[0]!.name).toBe('count_dur');
+      expect(node.finalCols[0]!.type).toEqual(PerfettoSqlTypes.INT);
     });
 
     it('should set INT type for COUNT(*) aggregation', () => {
@@ -742,8 +742,8 @@
       );
 
       expect(node.finalCols.length).toBe(1);
-      expect(node.finalCols[0].name).toBe('total_count');
-      expect(node.finalCols[0].type).toEqual(PerfettoSqlTypes.INT);
+      expect(node.finalCols[0]!.name).toBe('total_count');
+      expect(node.finalCols[0]!.type).toEqual(PerfettoSqlTypes.INT);
     });
 
     it('should preserve type for SUM aggregation', () => {
@@ -772,8 +772,8 @@
       );
 
       expect(node.finalCols.length).toBe(1);
-      expect(node.finalCols[0].name).toBe('total_dur');
-      expect(node.finalCols[0].type).toEqual(PerfettoSqlTypes.DURATION);
+      expect(node.finalCols[0]!.name).toBe('total_dur');
+      expect(node.finalCols[0]!.type).toEqual(PerfettoSqlTypes.DURATION);
     });
 
     it('should preserve type for MIN/MAX aggregations', () => {
@@ -808,10 +808,10 @@
       );
 
       expect(node.finalCols.length).toBe(2);
-      expect(node.finalCols[0].name).toBe('min_ts');
-      expect(node.finalCols[0].type).toEqual(PerfettoSqlTypes.TIMESTAMP);
-      expect(node.finalCols[1].name).toBe('max_ts');
-      expect(node.finalCols[1].type).toEqual(PerfettoSqlTypes.TIMESTAMP);
+      expect(node.finalCols[0]!.name).toBe('min_ts');
+      expect(node.finalCols[0]!.type).toEqual(PerfettoSqlTypes.TIMESTAMP);
+      expect(node.finalCols[1]!.name).toBe('max_ts');
+      expect(node.finalCols[1]!.type).toEqual(PerfettoSqlTypes.TIMESTAMP);
     });
 
     it('should set DOUBLE type for MEAN aggregation', () => {
@@ -834,8 +834,8 @@
       );
 
       expect(node.finalCols.length).toBe(1);
-      expect(node.finalCols[0].name).toBe('avg_value');
-      expect(node.finalCols[0].type).toEqual(PerfettoSqlTypes.DOUBLE);
+      expect(node.finalCols[0]!.name).toBe('avg_value');
+      expect(node.finalCols[0]!.type).toEqual(PerfettoSqlTypes.DOUBLE);
     });
 
     it('should set DOUBLE type for MEDIAN aggregation', () => {
@@ -858,8 +858,8 @@
       );
 
       expect(node.finalCols.length).toBe(1);
-      expect(node.finalCols[0].name).toBe('median_dur');
-      expect(node.finalCols[0].type).toEqual(PerfettoSqlTypes.DOUBLE);
+      expect(node.finalCols[0]!.name).toBe('median_dur');
+      expect(node.finalCols[0]!.type).toEqual(PerfettoSqlTypes.DOUBLE);
     });
 
     it('should set DOUBLE type for DURATION_WEIGHTED_MEAN aggregation', () => {
@@ -882,8 +882,8 @@
       );
 
       expect(node.finalCols.length).toBe(1);
-      expect(node.finalCols[0].name).toBe('weighted_avg_dur');
-      expect(node.finalCols[0].type).toEqual(PerfettoSqlTypes.DOUBLE);
+      expect(node.finalCols[0]!.name).toBe('weighted_avg_dur');
+      expect(node.finalCols[0]!.type).toEqual(PerfettoSqlTypes.DOUBLE);
     });
 
     it('should set DOUBLE type for PERCENTILE aggregation', () => {
@@ -907,8 +907,8 @@
       );
 
       expect(node.finalCols.length).toBe(1);
-      expect(node.finalCols[0].name).toBe('p95_dur');
-      expect(node.finalCols[0].type).toEqual(PerfettoSqlTypes.DOUBLE);
+      expect(node.finalCols[0]!.name).toBe('p95_dur');
+      expect(node.finalCols[0]!.type).toEqual(PerfettoSqlTypes.DOUBLE);
     });
 
     it('should include GROUP BY columns with their original types', () => {
@@ -926,8 +926,8 @@
           trace: createMockTrace(),
           groupByColumns: [
             {
-              name: inputCols[0].name,
-              type: inputCols[0].type,
+              name: inputCols[0]!.name,
+              type: inputCols[0]!.type,
               checked: true,
             },
           ],
@@ -946,10 +946,10 @@
       // First column should be the GROUP BY column (name) with preserved STRING type
       // Second column should be the aggregation result (total_value) with INT type
       expect(node.finalCols.length).toBe(2);
-      expect(node.finalCols[0].name).toBe('name');
-      expect(node.finalCols[0].type).toEqual(PerfettoSqlTypes.STRING);
-      expect(node.finalCols[1].name).toBe('total_value');
-      expect(node.finalCols[1].type).toEqual(PerfettoSqlTypes.INT);
+      expect(node.finalCols[0]!.name).toBe('name');
+      expect(node.finalCols[0]!.type).toEqual(PerfettoSqlTypes.STRING);
+      expect(node.finalCols[1]!.name).toBe('total_value');
+      expect(node.finalCols[1]!.type).toEqual(PerfettoSqlTypes.INT);
     });
   });
 
diff --git a/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/nodes/computed_column_components.ts b/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/nodes/computed_column_components.ts
index c524b0d..e466482 100644
--- a/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/nodes/computed_column_components.ts
+++ b/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/nodes/computed_column_components.ts
@@ -54,14 +54,14 @@
 
     const setCaseWhen = (index: number, newWhen: string) => {
       if (!column.cases) return;
-      column.cases[index].when = newWhen;
+      column.cases[index]!.when = newWhen;
       this.updateExpression(column);
       onchange();
     };
 
     const setCaseThen = (index: number, newThen: string) => {
       if (!column.cases) return;
-      column.cases[index].then = newThen;
+      column.cases[index]!.then = newThen;
       this.updateExpression(column);
       onchange();
     };
@@ -215,14 +215,14 @@
 
     const setIfCondition = (index: number, newIf: string) => {
       if (!column.clauses) return;
-      column.clauses[index].if = newIf;
+      column.clauses[index]!.if = newIf;
       this.updateExpression(column);
       onchange();
     };
 
     const setThenValue = (index: number, newThen: string) => {
       if (!column.clauses) return;
-      column.clauses[index].then = newThen;
+      column.clauses[index]!.then = newThen;
       this.updateExpression(column);
       onchange();
     };
diff --git a/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/nodes/connections_unittest.ts b/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/nodes/connections_unittest.ts
index f3102fe..07a3c18 100644
--- a/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/nodes/connections_unittest.ts
+++ b/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/nodes/connections_unittest.ts
@@ -1368,7 +1368,7 @@
         return {child, portIndex};
       });
 
-      expect(childConnections[0].portIndex).toBe(1); // B was at port 1
+      expect(childConnections[0]!.portIndex).toBe(1); // B was at port 1
 
       // Disconnect nodeB
       removeConnection(nodeA, nodeB);
@@ -2425,8 +2425,8 @@
 
       // VERIFY: B was connected via secondary input, so it's NOT orphaned
       expect(childConnections.length).toBe(1);
-      expect(childConnections[0].child).toBe(nodeB);
-      expect(childConnections[0].portIndex).toBeDefined(); // Secondary input!
+      expect(childConnections[0]!.child).toBe(nodeB);
+      expect(childConnections[0]!.portIndex).toBeDefined(); // Secondary input!
 
       // VERIFY BUG: Buggy code incorrectly treats B as orphaned
       expect(buggyOrphanedChildren).toContain(nodeB); // BUG!
@@ -2596,7 +2596,7 @@
 
       // Union allows unbounded inputs
       for (let i = 0; i < nodes.length; i++) {
-        addConnection(nodes[i], unionNode, i);
+        addConnection(nodes[i]!, unionNode, i);
       }
 
       // With 10 inputs, validation should pass (unbounded max)
diff --git a/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/nodes/create_slices_node.ts b/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/nodes/create_slices_node.ts
index 20ace1c..2b1e852 100644
--- a/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/nodes/create_slices_node.ts
+++ b/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/nodes/create_slices_node.ts
@@ -196,12 +196,12 @@
 
     // Auto-select starts timestamp if there's only one option
     if (startsTimestampCols.length === 1 && !this.attrs.startsTsColumn) {
-      this.attrs.startsTsColumn = startsTimestampCols[0].name;
+      this.attrs.startsTsColumn = startsTimestampCols[0]!.name;
     }
 
     // Auto-select ends timestamp if there's only one option
     if (endsTimestampCols.length === 1 && !this.attrs.endsTsColumn) {
-      this.attrs.endsTsColumn = endsTimestampCols[0].name;
+      this.attrs.endsTsColumn = endsTimestampCols[0]!.name;
     }
 
     // Auto-select duration columns in ts_dur mode
@@ -210,7 +210,7 @@
         (c) => c.type && typesEqual(c.type, PerfettoSqlTypes.DURATION),
       );
       if (startsDurationCols.length === 1 && !this.attrs.startsDurColumn) {
-        this.attrs.startsDurColumn = startsDurationCols[0].name;
+        this.attrs.startsDurColumn = startsDurationCols[0]!.name;
       }
     }
 
@@ -219,7 +219,7 @@
         (c) => c.type && typesEqual(c.type, PerfettoSqlTypes.DURATION),
       );
       if (endsDurationCols.length === 1 && !this.attrs.endsDurColumn) {
-        this.attrs.endsDurColumn = endsDurationCols[0].name;
+        this.attrs.endsDurColumn = endsDurationCols[0]!.name;
       }
     }
   }
@@ -456,9 +456,9 @@
 
     // Display the auto-selected column if there's only one option
     const autoTsColumn =
-      timestampCols.length === 1 ? timestampCols[0].name : tsColumn;
+      timestampCols.length === 1 ? timestampCols[0]!.name : tsColumn;
     const autoDurColumn =
-      durationCols.length === 1 ? durationCols[0].name : durColumn;
+      durationCols.length === 1 ? durationCols[0]!.name : durColumn;
 
     return [
       // Mode selector
diff --git a/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/nodes/create_slices_node_unittest.ts b/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/nodes/create_slices_node_unittest.ts
index 0487c24..26a8ab8 100644
--- a/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/nodes/create_slices_node_unittest.ts
+++ b/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/nodes/create_slices_node_unittest.ts
@@ -118,12 +118,12 @@
       const finalCols = createSlicesNode.finalCols;
 
       expect(finalCols.length).toBe(2);
-      expect(finalCols[0].name).toBe('ts');
-      expect(finalCols[0].type).toEqual({kind: 'timestamp'});
-      expect(finalCols[0].checked).toBe(true);
-      expect(finalCols[1].name).toBe('dur');
-      expect(finalCols[1].type).toEqual({kind: 'duration'});
-      expect(finalCols[1].checked).toBe(true);
+      expect(finalCols[0]!.name).toBe('ts');
+      expect(finalCols[0]!.type).toEqual({kind: 'timestamp'});
+      expect(finalCols[0]!.checked).toBe(true);
+      expect(finalCols[1]!.name).toBe('dur');
+      expect(finalCols[1]!.type).toEqual({kind: 'duration'});
+      expect(finalCols[1]!.checked).toBe(true);
     });
 
     it('should always return the same ts and dur columns regardless of input columns', () => {
diff --git a/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/nodes/group_node/group_node_unittest.ts b/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/nodes/group_node/group_node_unittest.ts
index a7a1c63..e442451 100644
--- a/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/nodes/group_node/group_node_unittest.ts
+++ b/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/nodes/group_node/group_node_unittest.ts
@@ -228,11 +228,11 @@
 
       expect(cloned.externalConnections).toHaveLength(1);
       // The inner target should be a cloned node, not the original
-      const clonedTarget = cloned.externalConnections[0].innerTargetNode;
+      const clonedTarget = cloned.externalConnections[0]!.innerTargetNode;
       expect(clonedTarget).not.toBe(a);
       expect(cloned.innerNodes).toContain(clonedTarget);
       // The source node should still reference the original external node
-      expect(cloned.externalConnections[0].sourceNode).toBe(ext);
+      expect(cloned.externalConnections[0]!.sourceNode).toBe(ext);
     });
 
     it('should not share state between original and clone', () => {
diff --git a/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/nodes/group_node/inner_graph_preview.ts b/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/nodes/group_node/inner_graph_preview.ts
index 8c69f91..5a4e244 100644
--- a/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/nodes/group_node/inner_graph_preview.ts
+++ b/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/nodes/group_node/inner_graph_preview.ts
@@ -55,11 +55,11 @@
     for (const n of groupNode.innerNodes) {
       if (
         n.nextNodes.length === 1 &&
-        singleNodeOperation(n.nextNodes[0].type) &&
-        n.nextNodes[0].primaryInput === n &&
-        innerSet.has(n.nextNodes[0].nodeId)
+        singleNodeOperation(n.nextNodes[0]!.type) &&
+        n.nextNodes[0]!.primaryInput === n &&
+        innerSet.has(n.nextNodes[0]!.nodeId)
       ) {
-        dockedIds.add(n.nextNodes[0].nodeId);
+        dockedIds.add(n.nextNodes[0]!.nodeId);
       }
     }
 
@@ -68,7 +68,7 @@
     // externalConnections array is ever reordered.
     const inputNodeIds = new Map<number, string>();
     for (let i = 0; i < groupNode.externalConnections.length; i++) {
-      const conn = groupNode.externalConnections[i];
+      const conn = groupNode.externalConnections[i]!;
       const inputId = `__input_${conn.groupPort}`;
       inputNodeIds.set(conn.groupPort, inputId);
 
@@ -138,7 +138,7 @@
     for (let i = 0; i < roots.length; i++) {
       nodes.push({
         ...buildReadOnlyNodeConfig(
-          roots[i],
+          roots[i]!,
           innerSet,
           connectedInputs,
           connectedOutputs,
@@ -151,7 +151,7 @@
     // Add "Input N" nodes for external connections.
     // Grey out disconnected inputs.
     for (let i = 0; i < groupNode.externalConnections.length; i++) {
-      const conn = groupNode.externalConnections[i];
+      const conn = groupNode.externalConnections[i]!;
       const isConnected = groupNode.secondaryInputs.connections.has(
         conn.groupPort,
       );
diff --git a/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/nodes/interval_intersect_node.ts b/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/nodes/interval_intersect_node.ts
index ae1c58c..118904d 100644
--- a/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/nodes/interval_intersect_node.ts
+++ b/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/nodes/interval_intersect_node.ts
@@ -245,7 +245,7 @@
     // Initialize connections from inputNodes
     if (inputNodes) {
       for (let i = 0; i < inputNodes.length; i++) {
-        this.secondaryInputs.connections.set(i, inputNodes[i]);
+        this.secondaryInputs.connections.set(i, inputNodes[i]!);
       }
     }
     this.nextNodes = [];
@@ -299,7 +299,7 @@
     if (this.attrs.partitionColumns && this.attrs.partitionColumns.length > 0) {
       for (const partitionCol of this.attrs.partitionColumns) {
         for (let i = 0; i < inputNodes.length; i++) {
-          const node = inputNodes[i];
+          const node = inputNodes[i]!;
           const cols = new Set(node.finalCols.map((c) => c.name));
           if (!cols.has(partitionCol)) {
             this.setValidationError(
@@ -507,7 +507,7 @@
 
     // Track which inputs each column appears in
     for (let i = 0; i < this.inputNodesList.length; i++) {
-      const node = this.inputNodesList[i];
+      const node = this.inputNodesList[i]!;
       const columns = node.finalCols.map((c) => c.name);
       for (const col of columns) {
         if (!EXCLUDED_COLUMNS.has(col) && !partitionColumns.has(col)) {
diff --git a/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/nodes/interval_intersect_node_unittest.ts b/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/nodes/interval_intersect_node_unittest.ts
index d66dc99..33901a8 100644
--- a/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/nodes/interval_intersect_node_unittest.ts
+++ b/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/nodes/interval_intersect_node_unittest.ts
@@ -65,8 +65,8 @@
       const node = makeIIN([node1, node2]);
 
       const cols = node.finalCols;
-      expect(cols[0].name).toBe('ts');
-      expect(cols[1].name).toBe('dur');
+      expect(cols[0]!.name).toBe('ts');
+      expect(cols[1]!.name).toBe('dur');
     });
 
     it('should include partition columns without suffix', () => {
@@ -82,9 +82,9 @@
       const node = makeIIN([node1, node2], ['utid']);
 
       const cols = node.finalCols;
-      expect(cols[0].name).toBe('ts');
-      expect(cols[1].name).toBe('dur');
-      expect(cols[2].name).toBe('utid');
+      expect(cols[0]!.name).toBe('ts');
+      expect(cols[1]!.name).toBe('dur');
+      expect(cols[2]!.name).toBe('utid');
     });
 
     it('should include id_N, ts_N, dur_N for each input with correct types', () => {
@@ -97,28 +97,28 @@
       const cols = node.finalCols;
 
       // After ts, dur (indexes 0, 1), we should have id_0, ts_0, dur_0
-      expect(cols[2].name).toBe('id_0');
-      expect(cols[2].type).toEqual({kind: 'int'});
-      expect(cols[3].name).toBe('ts_0');
-      expect(cols[3].type).toEqual({kind: 'timestamp'}); // ts columns are TIMESTAMP type
-      expect(cols[4].name).toBe('dur_0');
-      expect(cols[4].type).toEqual({kind: 'duration'}); // dur columns are DURATION type
+      expect(cols[2]!.name).toBe('id_0');
+      expect(cols[2]!.type).toEqual({kind: 'int'});
+      expect(cols[3]!.name).toBe('ts_0');
+      expect(cols[3]!.type).toEqual({kind: 'timestamp'}); // ts columns are TIMESTAMP type
+      expect(cols[4]!.name).toBe('dur_0');
+      expect(cols[4]!.type).toEqual({kind: 'duration'}); // dur columns are DURATION type
 
       // Then id_1, ts_1, dur_1
-      expect(cols[5].name).toBe('id_1');
-      expect(cols[5].type).toEqual({kind: 'int'});
-      expect(cols[6].name).toBe('ts_1');
-      expect(cols[6].type).toEqual({kind: 'timestamp'});
-      expect(cols[7].name).toBe('dur_1');
-      expect(cols[7].type).toEqual({kind: 'duration'});
+      expect(cols[5]!.name).toBe('id_1');
+      expect(cols[5]!.type).toEqual({kind: 'int'});
+      expect(cols[6]!.name).toBe('ts_1');
+      expect(cols[6]!.type).toEqual({kind: 'timestamp'});
+      expect(cols[7]!.name).toBe('dur_1');
+      expect(cols[7]!.type).toEqual({kind: 'duration'});
 
       // Then id_2, ts_2, dur_2
-      expect(cols[8].name).toBe('id_2');
-      expect(cols[8].type).toEqual({kind: 'int'});
-      expect(cols[9].name).toBe('ts_2');
-      expect(cols[9].type).toEqual({kind: 'timestamp'});
-      expect(cols[10].name).toBe('dur_2');
-      expect(cols[10].type).toEqual({kind: 'duration'});
+      expect(cols[8]!.name).toBe('id_2');
+      expect(cols[8]!.type).toEqual({kind: 'int'});
+      expect(cols[9]!.name).toBe('ts_2');
+      expect(cols[9]!.type).toEqual({kind: 'timestamp'});
+      expect(cols[10]!.name).toBe('dur_2');
+      expect(cols[10]!.type).toEqual({kind: 'duration'});
     });
 
     it('should include non-duplicated columns from all inputs', () => {
@@ -254,10 +254,10 @@
       const node = makeIIN([node1, node2], ['utid', 'upid']);
 
       const cols = node.finalCols;
-      expect(cols[0].name).toBe('ts');
-      expect(cols[1].name).toBe('dur');
-      expect(cols[2].name).toBe('utid');
-      expect(cols[3].name).toBe('upid');
+      expect(cols[0]!.name).toBe('ts');
+      expect(cols[1]!.name).toBe('dur');
+      expect(cols[2]!.name).toBe('utid');
+      expect(cols[3]!.name).toBe('upid');
     });
 
     it('should set all columns as checked', () => {
@@ -1224,7 +1224,7 @@
         (c) => c.name === 'id',
       );
       modifyNode.attrs.selectedColumns[idColIndex] = {
-        ...modifyNode.attrs.selectedColumns[idColIndex],
+        ...modifyNode.attrs.selectedColumns[idColIndex]!,
         type: customType,
         typeUserModified: true,
       };
diff --git a/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/nodes/join_node.ts b/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/nodes/join_node.ts
index a94cf2a..0f97c61 100644
--- a/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/nodes/join_node.ts
+++ b/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/nodes/join_node.ts
@@ -326,26 +326,26 @@
               },
               onLeftColumnToggle: (index: number, checked: boolean) => {
                 if (this.attrs.leftColumns) {
-                  this.attrs.leftColumns[index].checked = checked;
+                  this.attrs.leftColumns[index]!.checked = checked;
                   this.context.onchange?.();
                 }
               },
               onRightColumnToggle: (index: number, checked: boolean) => {
                 if (this.attrs.rightColumns) {
-                  this.attrs.rightColumns[index].checked = checked;
+                  this.attrs.rightColumns[index]!.checked = checked;
                   this.context.onchange?.();
                 }
               },
               onLeftColumnAlias: (index: number, alias: string) => {
                 if (this.attrs.leftColumns) {
-                  this.attrs.leftColumns[index].alias =
+                  this.attrs.leftColumns[index]!.alias =
                     alias.trim() === '' ? undefined : alias;
                   this.context.onchange?.();
                 }
               },
               onRightColumnAlias: (index: number, alias: string) => {
                 if (this.attrs.rightColumns) {
-                  this.attrs.rightColumns[index].alias =
+                  this.attrs.rightColumns[index]!.alias =
                     alias.trim() === '' ? undefined : alias;
                   this.context.onchange?.();
                 }
diff --git a/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/nodes/join_node_unittest.ts b/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/nodes/join_node_unittest.ts
index 1446fd2..fd64bd6 100644
--- a/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/nodes/join_node_unittest.ts
+++ b/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/nodes/join_node_unittest.ts
@@ -260,7 +260,7 @@
 
       const finalCols = joinNode.finalCols;
       expect(finalCols.length).toBe(1);
-      expect(finalCols[0].name).toBe('id');
+      expect(finalCols[0]!.name).toBe('id');
     });
 
     it('should return only checked columns from right source', () => {
@@ -435,12 +435,12 @@
       const leftCols = createCheckedColumns([
         {name: 'id', type: 'INT', checked: true},
       ]);
-      leftCols[0].alias = 'left_id';
+      leftCols[0]!.alias = 'left_id';
 
       const rightCols = createCheckedColumns([
         {name: 'id', type: 'INT', checked: true},
       ]);
-      rightCols[0].alias = 'right_id';
+      rightCols[0]!.alias = 'right_id';
 
       const joinNode = createJoinNodeWithInputs(
         node1,
@@ -462,8 +462,8 @@
       const finalCols = joinNode.finalCols;
 
       expect(finalCols.length).toBe(2);
-      expect(finalCols[0].alias).toBe('left_id');
-      expect(finalCols[1].alias).toBe('right_id');
+      expect(finalCols[0]!.alias).toBe('left_id');
+      expect(finalCols[1]!.alias).toBe('right_id');
     });
   });
 
@@ -1112,9 +1112,9 @@
       );
 
       // Verify initial state
-      expect(joinNode.attrs.leftColumns?.[0].checked).toBe(true);
-      expect(joinNode.attrs.leftColumns?.[1].checked).toBe(false);
-      expect(joinNode.attrs.rightColumns?.[0].checked).toBe(true);
+      expect(joinNode.attrs.leftColumns?.[0]!.checked).toBe(true);
+      expect(joinNode.attrs.leftColumns?.[1]!.checked).toBe(false);
+      expect(joinNode.attrs.rightColumns?.[0]!.checked).toBe(true);
 
       // Serialize the state via attrs
       const serialized = joinNode.attrs;
@@ -1131,9 +1131,9 @@
       expect(restoredNode.attrs.leftColumns?.length).toBe(2);
       expect(restoredNode.attrs.rightColumns?.length).toBe(1);
 
-      expect(restoredNode.attrs.leftColumns?.[0].checked).toBe(true);
-      expect(restoredNode.attrs.leftColumns?.[1].checked).toBe(false);
-      expect(restoredNode.attrs.rightColumns?.[0].checked).toBe(true);
+      expect(restoredNode.attrs.leftColumns?.[0]!.checked).toBe(true);
+      expect(restoredNode.attrs.leftColumns?.[1]!.checked).toBe(false);
+      expect(restoredNode.attrs.rightColumns?.[0]!.checked).toBe(true);
     });
 
     it('should preserve column aliases after serialization and deserialization', () => {
@@ -1151,12 +1151,12 @@
       const leftCols = createCheckedColumns([
         {name: 'id', type: 'INT', checked: true},
       ]);
-      leftCols[0].alias = 'left_id';
+      leftCols[0]!.alias = 'left_id';
 
       const rightCols = createCheckedColumns([
         {name: 'id', type: 'INT', checked: true},
       ]);
-      rightCols[0].alias = 'right_id';
+      rightCols[0]!.alias = 'right_id';
 
       // Create a join node with aliases
       const joinNode = createJoinNodeWithInputs(
@@ -1177,8 +1177,8 @@
       );
 
       // Verify initial state has aliases
-      expect(joinNode.attrs.leftColumns?.[0].alias).toBe('left_id');
-      expect(joinNode.attrs.rightColumns?.[0].alias).toBe('right_id');
+      expect(joinNode.attrs.leftColumns?.[0]!.alias).toBe('left_id');
+      expect(joinNode.attrs.rightColumns?.[0]!.alias).toBe('right_id');
 
       // Serialize the state via attrs
       const serialized = joinNode.attrs;
@@ -1191,10 +1191,10 @@
         {},
       );
 
-      expect(restoredNode.attrs.leftColumns?.[0].alias).toBe('left_id');
-      expect(restoredNode.attrs.rightColumns?.[0].alias).toBe('right_id');
-      expect(restoredNode.attrs.leftColumns?.[0].checked).toBe(true);
-      expect(restoredNode.attrs.rightColumns?.[0].checked).toBe(true);
+      expect(restoredNode.attrs.leftColumns?.[0]!.alias).toBe('left_id');
+      expect(restoredNode.attrs.rightColumns?.[0]!.alias).toBe('right_id');
+      expect(restoredNode.attrs.leftColumns?.[0]!.checked).toBe(true);
+      expect(restoredNode.attrs.rightColumns?.[0]!.checked).toBe(true);
     });
   });
 });
diff --git a/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/nodes/metrics_export_modal.ts b/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/nodes/metrics_export_modal.ts
index 93f1798..1320cfe 100644
--- a/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/nodes/metrics_export_modal.ts
+++ b/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/nodes/metrics_export_modal.ts
@@ -104,7 +104,7 @@
     const rowData: Row = {};
     for (let i = 0; i < dimensionNames.length; i++) {
       const dimValue = row.dimension?.[i];
-      rowData[dimensionNames[i]] = dimValue
+      rowData[dimensionNames[i]!] = dimValue
         ? getDimensionValue(dimValue)
         : null;
     }
@@ -197,10 +197,10 @@
           '.pf-metrics-result-box',
           valueColumns.length === 1
             ? [
-                m('.pf-metrics-result-header', valueColumns[0].column),
+                m('.pf-metrics-result-header', valueColumns[0]!.column),
                 m(
                   '.pf-metrics-result-content',
-                  renderResultForValue(valueColumns[0].column),
+                  renderResultForValue(valueColumns[0]!.column),
                 ),
               ]
             : m(Tabs, {
@@ -263,12 +263,12 @@
             i,
           );
           if (parsed !== undefined && parsed.rows.length > 0) {
-            resultStates.set(valueColumns[i].column, {
+            resultStates.set(valueColumns[i]!.column, {
               kind: 'data',
               result: parsed,
             });
           } else {
-            resultStates.set(valueColumns[i].column, {
+            resultStates.set(valueColumns[i]!.column, {
               kind: 'error',
               message: 'No metric data found',
             });
diff --git a/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/nodes/metrics_node_unittest.ts b/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/nodes/metrics_node_unittest.ts
index 938bc7a..0a6a8db 100644
--- a/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/nodes/metrics_node_unittest.ts
+++ b/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/nodes/metrics_node_unittest.ts
@@ -124,9 +124,9 @@
 
       expect(node.attrs.metricIdPrefix).toBe('my_metric');
       expect(node.attrs.valueColumns).toHaveLength(1);
-      expect(node.attrs.valueColumns[0].column).toBe('value1');
-      expect(node.attrs.valueColumns[0].unit).toBe('BYTES');
-      expect(node.attrs.valueColumns[0].polarity).toBe('HIGHER_IS_BETTER');
+      expect(node.attrs.valueColumns[0]!.column).toBe('value1');
+      expect(node.attrs.valueColumns[0]!.unit).toBe('BYTES');
+      expect(node.attrs.valueColumns[0]!.polarity).toBe('HIGHER_IS_BETTER');
       expect(node.attrs.dimensionUniqueness).toBe('UNIQUE');
     });
 
@@ -142,8 +142,8 @@
       );
 
       expect(node.attrs.valueColumns).toHaveLength(2);
-      expect(node.attrs.valueColumns[0].column).toBe('cpu_time');
-      expect(node.attrs.valueColumns[1].column).toBe('mem_bytes');
+      expect(node.attrs.valueColumns[0]!.column).toBe('cpu_time');
+      expect(node.attrs.valueColumns[1]!.column).toBe('mem_bytes');
     });
   });
 
@@ -450,7 +450,7 @@
       node.onPrevNodesUpdated();
 
       expect(node.attrs.valueColumns).toHaveLength(1);
-      expect(node.attrs.valueColumns[0].column).toBe('value');
+      expect(node.attrs.valueColumns[0]!.column).toBe('value');
     });
 
     it('should selectively remove only stale value columns from multi-value', () => {
@@ -474,7 +474,7 @@
       node.onPrevNodesUpdated();
 
       expect(node.attrs.valueColumns).toHaveLength(1);
-      expect(node.attrs.valueColumns[0].column).toBe('cpu');
+      expect(node.attrs.valueColumns[0]!.column).toBe('cpu');
     });
 
     it('should do nothing when no primary input', () => {
@@ -488,7 +488,7 @@
 
       // State should remain unchanged
       expect(node.attrs.valueColumns).toHaveLength(1);
-      expect(node.attrs.valueColumns[0].column).toBe('value');
+      expect(node.attrs.valueColumns[0]!.column).toBe('value');
     });
   });
 
@@ -568,10 +568,10 @@
       const dimNames = spec!.dimensionsSpecs?.map((d) => d.name);
       expect(dimNames).toEqual(['dim1', 'dim2']);
       // Verify types are inferred from column types.
-      expect(spec!.dimensionsSpecs?.[0].type).toBe(
+      expect(spec!.dimensionsSpecs?.[0]!.type).toBe(
         protos.TraceMetricV2Spec.DimensionType.STRING,
       );
-      expect(spec!.dimensionsSpecs?.[1].type).toBe(
+      expect(spec!.dimensionsSpecs?.[1]!.type).toBe(
         protos.TraceMetricV2Spec.DimensionType.INT64,
       );
     });
@@ -669,8 +669,8 @@
 
       const spec = node.getMetricTemplateSpec();
       expect(spec).toBeDefined();
-      expect(spec!.valueColumnSpecs?.[0].displayName).toBe('CPU Time');
-      expect(spec!.valueColumnSpecs?.[0].displayHelp).toBe(
+      expect(spec!.valueColumnSpecs?.[0]!.displayName).toBe('CPU Time');
+      expect(spec!.valueColumnSpecs?.[0]!.displayHelp).toBe(
         'Total CPU time in nanoseconds.',
       );
     });
@@ -691,8 +691,8 @@
       const spec = node.getMetricTemplateSpec();
 
       expect(spec?.valueColumnSpecs?.length).toBe(1);
-      expect(spec?.valueColumnSpecs?.[0].name).toBe('value');
-      expect(spec?.valueColumnSpecs?.[0].unit).toBe(
+      expect(spec?.valueColumnSpecs?.[0]!.name).toBe('value');
+      expect(spec?.valueColumnSpecs?.[0]!.unit).toBe(
         protos.TraceMetricV2Spec.MetricUnit.COUNT,
       );
     });
@@ -719,12 +719,12 @@
       const spec = node.getMetricTemplateSpec();
 
       expect(spec?.valueColumnSpecs?.length).toBe(2);
-      expect(spec?.valueColumnSpecs?.[0].name).toBe('cpu');
-      expect(spec?.valueColumnSpecs?.[0].unit).toBe(
+      expect(spec?.valueColumnSpecs?.[0]!.name).toBe('cpu');
+      expect(spec?.valueColumnSpecs?.[0]!.unit).toBe(
         protos.TraceMetricV2Spec.MetricUnit.TIME_NANOS,
       );
-      expect(spec?.valueColumnSpecs?.[1].name).toBe('mem');
-      expect(spec?.valueColumnSpecs?.[1].unit).toBe(
+      expect(spec?.valueColumnSpecs?.[1]!.name).toBe('mem');
+      expect(spec?.valueColumnSpecs?.[1]!.unit).toBe(
         protos.TraceMetricV2Spec.MetricUnit.BYTES,
       );
     });
@@ -758,7 +758,7 @@
 
       const spec = node.getMetricTemplateSpec();
 
-      expect(spec?.valueColumnSpecs?.[0].customUnit).toBe('my_custom_unit');
+      expect(spec?.valueColumnSpecs?.[0]!.customUnit).toBe('my_custom_unit');
     });
 
     it('should set polarity in value spec', () => {
@@ -768,7 +768,7 @@
 
       const spec = node.getMetricTemplateSpec();
 
-      expect(spec?.valueColumnSpecs?.[0].polarity).toBe(
+      expect(spec?.valueColumnSpecs?.[0]!.polarity).toBe(
         protos.TraceMetricV2Spec.MetricPolarity.LOWER_IS_BETTER,
       );
     });
@@ -799,9 +799,9 @@
 
       expect(node.attrs.metricIdPrefix).toBe('my_metric');
       expect(node.attrs.valueColumns).toHaveLength(1);
-      expect(node.attrs.valueColumns[0].column).toBe('value1');
-      expect(node.attrs.valueColumns[0].unit).toBe('BYTES');
-      expect(node.attrs.valueColumns[0].polarity).toBe('HIGHER_IS_BETTER');
+      expect(node.attrs.valueColumns[0]!.column).toBe('value1');
+      expect(node.attrs.valueColumns[0]!.unit).toBe('BYTES');
+      expect(node.attrs.valueColumns[0]!.polarity).toBe('HIGHER_IS_BETTER');
       expect(node.attrs.dimensionUniqueness).toBe('UNIQUE');
     });
 
@@ -817,8 +817,8 @@
       );
 
       expect(node.attrs.valueColumns).toHaveLength(2);
-      expect(node.attrs.valueColumns[0].column).toBe('cpu');
-      expect(node.attrs.valueColumns[1].column).toBe('mem');
+      expect(node.attrs.valueColumns[0]!.column).toBe('cpu');
+      expect(node.attrs.valueColumns[1]!.column).toBe('mem');
     });
   });
 
@@ -837,9 +837,9 @@
 
       expect(state.metricIdPrefix).toBe('restored_metric');
       expect(state.valueColumns).toHaveLength(1);
-      expect(state.valueColumns[0].column).toBe('value1');
-      expect(state.valueColumns[0].unit).toBe('MEGABYTES');
-      expect(state.valueColumns[0].polarity).toBe('LOWER_IS_BETTER');
+      expect(state.valueColumns[0]!.column).toBe('value1');
+      expect(state.valueColumns[0]!.unit).toBe('MEGABYTES');
+      expect(state.valueColumns[0]!.polarity).toBe('LOWER_IS_BETTER');
       expect(state.dimensionUniqueness).toBe('UNIQUE');
     });
 
@@ -857,8 +857,8 @@
       const state = MetricsNode.deserializeState(serialized);
 
       expect(state.valueColumns).toHaveLength(2);
-      expect(state.valueColumns[0].column).toBe('cpu');
-      expect(state.valueColumns[1].column).toBe('mem');
+      expect(state.valueColumns[0]!.column).toBe('cpu');
+      expect(state.valueColumns[1]!.column).toBe('mem');
     });
 
     it('should provide defaults for missing properties', () => {
@@ -885,9 +885,9 @@
 
       expect(state.metricIdPrefix).toBe('old_metric');
       expect(state.valueColumns).toHaveLength(1);
-      expect(state.valueColumns[0].column).toBe('value1');
-      expect(state.valueColumns[0].unit).toBe('BYTES');
-      expect(state.valueColumns[0].polarity).toBe('HIGHER_IS_BETTER');
+      expect(state.valueColumns[0]!.column).toBe('value1');
+      expect(state.valueColumns[0]!.unit).toBe('BYTES');
+      expect(state.valueColumns[0]!.polarity).toBe('HIGHER_IS_BETTER');
     });
 
     it('should migrate from old single-value format with custom unit', () => {
@@ -903,8 +903,8 @@
       const state = MetricsNode.deserializeState(oldFormat);
 
       expect(state.valueColumns).toHaveLength(1);
-      expect(state.valueColumns[0].unit).toBe('CUSTOM');
-      expect(state.valueColumns[0].customUnit).toBe('widgets');
+      expect(state.valueColumns[0]!.unit).toBe('CUSTOM');
+      expect(state.valueColumns[0]!.customUnit).toBe('widgets');
     });
 
     it('should migrate from old multi-value values[] array format', () => {
@@ -931,8 +931,8 @@
 
       expect(state.metricIdPrefix).toBe('old_metric');
       expect(state.valueColumns).toHaveLength(2);
-      expect(state.valueColumns[0].column).toBe('cpu');
-      expect(state.valueColumns[1].column).toBe('mem');
+      expect(state.valueColumns[0]!.column).toBe('cpu');
+      expect(state.valueColumns[1]!.column).toBe('mem');
     });
 
     it('should migrate from old metricId field', () => {
@@ -968,8 +968,8 @@
       expect(cloned.nodeId).not.toBe(node.nodeId);
       expect(cloned.attrs.metricIdPrefix).toBe('test');
       expect(cloned.attrs.valueColumns).toHaveLength(1);
-      expect(cloned.attrs.valueColumns[0].column).toBe('value1');
-      expect(cloned.attrs.valueColumns[0].unit).toBe('BYTES');
+      expect(cloned.attrs.valueColumns[0]!.column).toBe('value1');
+      expect(cloned.attrs.valueColumns[0]!.unit).toBe('BYTES');
       expect(cloned.attrs.dimensionUniqueness).toBe('UNIQUE');
     });
 
@@ -984,11 +984,11 @@
       const cloned = node.clone() as MetricsNode;
 
       // Mutate clone
-      cloned.attrs.valueColumns[0].unit = 'BYTES';
+      cloned.attrs.valueColumns[0]!.unit = 'BYTES';
       cloned.attrs.valueColumns.push(makeValueCol('extra'));
 
       // Original should be unaffected
-      expect(node.attrs.valueColumns[0].unit).toBe('COUNT');
+      expect(node.attrs.valueColumns[0]!.unit).toBe('COUNT');
       expect(node.attrs.valueColumns).toHaveLength(2);
     });
 
@@ -1135,8 +1135,8 @@
       expect(spec).toBeDefined();
       expect(spec?.idPrefix).toBe('process_metrics');
       expect(spec?.valueColumnSpecs?.length).toBe(1);
-      expect(spec?.valueColumnSpecs?.[0].name).toBe('cpu_time');
-      expect(spec?.valueColumnSpecs?.[0].unit).toBe(
+      expect(spec?.valueColumnSpecs?.[0]!.name).toBe('cpu_time');
+      expect(spec?.valueColumnSpecs?.[0]!.unit).toBe(
         protos.TraceMetricV2Spec.MetricUnit.TIME_NANOS,
       );
       const dimNames = spec?.dimensionsSpecs?.map((d) => d.name);
@@ -1198,9 +1198,9 @@
 
       expect(restoredNode.attrs.metricIdPrefix).toBe('original_metric');
       expect(restoredNode.attrs.valueColumns).toHaveLength(1);
-      expect(restoredNode.attrs.valueColumns[0].column).toBe('value1');
-      expect(restoredNode.attrs.valueColumns[0].unit).toBe('PERCENTAGE');
-      expect(restoredNode.attrs.valueColumns[0].polarity).toBe(
+      expect(restoredNode.attrs.valueColumns[0]!.column).toBe('value1');
+      expect(restoredNode.attrs.valueColumns[0]!.unit).toBe('PERCENTAGE');
+      expect(restoredNode.attrs.valueColumns[0]!.polarity).toBe(
         'HIGHER_IS_BETTER',
       );
       expect(restoredNode.attrs.dimensionUniqueness).toBe('UNIQUE');
@@ -1223,7 +1223,7 @@
       const restoredNode = new MetricsNode(restored, {});
 
       expect(restoredNode.attrs.valueColumns).toHaveLength(3);
-      expect(restoredNode.attrs.valueColumns[2].customUnit).toBe('pts');
+      expect(restoredNode.attrs.valueColumns[2]!.customUnit).toBe('pts');
     });
 
     it('should preserve value columns after deserialization and reconnection', () => {
@@ -1252,7 +1252,7 @@
 
       expect(restoredNode.availableColumns.length).toBe(3);
       expect(restoredNode.attrs.valueColumns).toHaveLength(1);
-      expect(restoredNode.attrs.valueColumns[0].column).toBe('metric_value');
+      expect(restoredNode.attrs.valueColumns[0]!.column).toBe('metric_value');
       expect(restoredNode.getDimensions()).toEqual(['id', 'category']);
       expectValidationSuccess(restoredNode);
     });
@@ -1377,8 +1377,8 @@
     expect(result).toBeDefined();
     expect(result?.metricId).toBe('my_metric_cpu');
     expect(result?.rows).toHaveLength(2);
-    expect(result?.rows[0]['process']).toBe('chrome');
-    expect(result?.rows[0]['cpu']).toBe(100);
+    expect(result?.rows[0]!['process']).toBe('chrome');
+    expect(result?.rows[0]!['cpu']).toBe(100);
     // Should NOT include 'mem' column
     expect('mem' in (result?.rows[0] ?? {})).toBe(false);
   });
@@ -1399,8 +1399,8 @@
 
     expect(result).toBeDefined();
     expect(result?.metricId).toBe('my_metric_mem');
-    expect(result?.rows[0]['mem']).toBe(200);
-    expect(result?.rows[1]['mem']).toBe(250);
+    expect(result?.rows[0]!['mem']).toBe(200);
+    expect(result?.rows[1]!['mem']).toBe(250);
     expect('cpu' in (result?.rows[0] ?? {})).toBe(false);
   });
 
@@ -1418,9 +1418,9 @@
     expect(result).toBeDefined();
     if (result !== undefined) {
       const schema = result.schema;
-      const processEntry = schema['process'];
-      const threadEntry = schema['thread'];
-      const cpuEntry = schema['cpu'];
+      const processEntry = schema['process']!;
+      const threadEntry = schema['thread']!;
+      const cpuEntry = schema['cpu']!;
       // Schema values for leaf columns are ColumnDef objects with columnType.
       expect(
         'columnType' in processEntry ? processEntry.columnType : undefined,
@@ -1457,6 +1457,6 @@
     );
 
     expect(result).toBeDefined();
-    expect(result?.rows[0]['val']).toBeNull();
+    expect(result?.rows[0]!['val']).toBeNull();
   });
 });
diff --git a/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/nodes/modify_columns_node.ts b/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/nodes/modify_columns_node.ts
index af489d1..5cd3c0d 100644
--- a/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/nodes/modify_columns_node.ts
+++ b/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/nodes/modify_columns_node.ts
@@ -255,7 +255,7 @@
             ) => {
               const newSelectedColumns = [...this.attrs.selectedColumns];
               newSelectedColumns[idx] = {
-                ...newSelectedColumns[idx],
+                ...newSelectedColumns[idx]!,
                 type: newType,
                 typeUserModified: true,
               };
@@ -269,7 +269,7 @@
                   const newSelectedColumns = [...this.attrs.selectedColumns];
                   const inputValue = (e.target as HTMLInputElement).value;
                   newSelectedColumns[index] = {
-                    ...newSelectedColumns[index],
+                    ...newSelectedColumns[index]!,
                     alias: inputValue.trim() === '' ? undefined : inputValue,
                   };
                   this.attrs.selectedColumns = newSelectedColumns;
diff --git a/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/nodes/modify_columns_node_unittest.ts b/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/nodes/modify_columns_node_unittest.ts
index c23773a..59f5997 100644
--- a/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/nodes/modify_columns_node_unittest.ts
+++ b/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/nodes/modify_columns_node_unittest.ts
@@ -135,8 +135,8 @@
 
       expect(node.attrs.selectedColumns).toBeDefined();
       expect(node.attrs.selectedColumns.length).toBe(2);
-      expect(node.attrs.selectedColumns[0].name).toBe('id');
-      expect(node.attrs.selectedColumns[1].name).toBe('status');
+      expect(node.attrs.selectedColumns[0]!.name).toBe('id');
+      expect(node.attrs.selectedColumns[1]!.name).toBe('status');
     });
 
     it('should serialize column aliases correctly', () => {
@@ -150,8 +150,8 @@
         createMockPrevNode(),
       );
 
-      expect(node.attrs.selectedColumns[0].alias).toBeUndefined();
-      expect(node.attrs.selectedColumns[1].alias).toBe('status_renamed');
+      expect(node.attrs.selectedColumns[0]!.alias).toBeUndefined();
+      expect(node.attrs.selectedColumns[1]!.alias).toBe('status_renamed');
     });
 
     it('should serialize checked status correctly', () => {
@@ -165,8 +165,8 @@
         createMockPrevNode(),
       );
 
-      expect(node.attrs.selectedColumns[0].checked).toBe(true);
-      expect(node.attrs.selectedColumns[1].checked).toBe(false);
+      expect(node.attrs.selectedColumns[0]!.checked).toBe(true);
+      expect(node.attrs.selectedColumns[1]!.checked).toBe(false);
     });
 
     it('should serialize column types as PerfettoSqlType objects', () => {
@@ -180,8 +180,8 @@
         createMockPrevNode(),
       );
 
-      expect(node.attrs.selectedColumns[0].type).toEqual({kind: 'int'});
-      expect(node.attrs.selectedColumns[1].type).toEqual({kind: 'timestamp'});
+      expect(node.attrs.selectedColumns[0]!.type).toEqual({kind: 'int'});
+      expect(node.attrs.selectedColumns[1]!.type).toEqual({kind: 'timestamp'});
     });
   });
 
@@ -200,8 +200,8 @@
       const finalCols = node.finalCols;
 
       expect(finalCols.length).toBe(2);
-      expect(finalCols[0].name).toBe('id');
-      expect(finalCols[1].name).toBe('value');
+      expect(finalCols[0]!.name).toBe('id');
+      expect(finalCols[1]!.name).toBe('value');
     });
 
     it('should use alias as column name in finalCols', () => {
@@ -216,7 +216,7 @@
       const finalCols = node.finalCols;
 
       expect(finalCols.length).toBe(1);
-      expect(finalCols[0].name).toBe('identifier');
+      expect(finalCols[0]!.name).toBe('identifier');
     });
   });
 
@@ -241,20 +241,20 @@
 
       // Verify initial state - all columns should be from source
       expect(modifyNode.attrs.selectedColumns.length).toBe(3);
-      expect(modifyNode.attrs.selectedColumns[2].name).toBe('value');
-      expect(modifyNode.attrs.selectedColumns[2].type).toEqual(
+      expect(modifyNode.attrs.selectedColumns[2]!.name).toBe('value');
+      expect(modifyNode.attrs.selectedColumns[2]!.type).toEqual(
         PerfettoSqlTypes.INT,
       );
 
       // User modifies the type of 'value' column to 'duration'
       modifyNode.attrs.selectedColumns[2] = {
-        ...modifyNode.attrs.selectedColumns[2],
+        ...modifyNode.attrs.selectedColumns[2]!,
         type: {kind: 'duration'},
         typeUserModified: true,
       };
 
       // Verify the type was modified
-      expect(modifyNode.attrs.selectedColumns[2].type).toEqual(
+      expect(modifyNode.attrs.selectedColumns[2]!.type).toEqual(
         PerfettoSqlTypes.DURATION,
       );
 
@@ -278,8 +278,8 @@
       modifyNode.onPrevNodesUpdated();
 
       // The modified type should be preserved!
-      expect(modifyNode.attrs.selectedColumns[2].name).toBe('value');
-      expect(modifyNode.attrs.selectedColumns[2].type).toEqual(
+      expect(modifyNode.attrs.selectedColumns[2]!.name).toBe('value');
+      expect(modifyNode.attrs.selectedColumns[2]!.type).toEqual(
         PerfettoSqlTypes.DURATION,
       );
     });
@@ -299,8 +299,8 @@
       modifyNode.onPrevNodesUpdated();
 
       // User customizes the node
-      modifyNode.attrs.selectedColumns[0].checked = false; // Uncheck 'id'
-      modifyNode.attrs.selectedColumns[1].alias = 'full_name'; // Rename 'name'
+      modifyNode.attrs.selectedColumns[0]!.checked = false; // Uncheck 'id'
+      modifyNode.attrs.selectedColumns[1]!.alias = 'full_name'; // Rename 'name'
 
       // Insert intermediate node
       const intermediateNode = createMockNode({
@@ -316,8 +316,8 @@
       modifyNode.onPrevNodesUpdated();
 
       // Customizations should be preserved
-      expect(modifyNode.attrs.selectedColumns[0].checked).toBe(false);
-      expect(modifyNode.attrs.selectedColumns[1].alias).toBe('full_name');
+      expect(modifyNode.attrs.selectedColumns[0]!.checked).toBe(false);
+      expect(modifyNode.attrs.selectedColumns[1]!.alias).toBe('full_name');
     });
   });
 
@@ -336,9 +336,9 @@
       const clonedNode = node.clone() as ModifyColumnsNode;
 
       // Aliases should be preserved in the cloned node
-      expect(clonedNode.attrs.selectedColumns[0].alias).toBeUndefined();
-      expect(clonedNode.attrs.selectedColumns[1].alias).toBe('full_name');
-      expect(clonedNode.attrs.selectedColumns[2].alias).toBe('amount');
+      expect(clonedNode.attrs.selectedColumns[0]!.alias).toBeUndefined();
+      expect(clonedNode.attrs.selectedColumns[1]!.alias).toBe('full_name');
+      expect(clonedNode.attrs.selectedColumns[2]!.alias).toBe('amount');
     });
 
     it('should preserve checked status when cloning', () => {
@@ -354,9 +354,9 @@
 
       const clonedNode = node.clone() as ModifyColumnsNode;
 
-      expect(clonedNode.attrs.selectedColumns[0].checked).toBe(true);
-      expect(clonedNode.attrs.selectedColumns[1].checked).toBe(false);
-      expect(clonedNode.attrs.selectedColumns[2].checked).toBe(true);
+      expect(clonedNode.attrs.selectedColumns[0]!.checked).toBe(true);
+      expect(clonedNode.attrs.selectedColumns[1]!.checked).toBe(false);
+      expect(clonedNode.attrs.selectedColumns[2]!.checked).toBe(true);
     });
 
     it('should preserve original column names when cloning with aliases', () => {
@@ -372,8 +372,8 @@
       const clonedNode = node.clone() as ModifyColumnsNode;
 
       // The original column name should be preserved, NOT the alias
-      expect(clonedNode.attrs.selectedColumns[0].name).toBe('id');
-      expect(clonedNode.attrs.selectedColumns[0].alias).toBe('identifier');
+      expect(clonedNode.attrs.selectedColumns[0]!.name).toBe('id');
+      expect(clonedNode.attrs.selectedColumns[0]!.alias).toBe('identifier');
     });
 
     it('should preserve typeUserModified flag when cloning', () => {
@@ -393,10 +393,10 @@
 
       const clonedNode = node.clone() as ModifyColumnsNode;
 
-      expect(clonedNode.attrs.selectedColumns[0].type).toEqual(
+      expect(clonedNode.attrs.selectedColumns[0]!.type).toEqual(
         PerfettoSqlTypes.DURATION,
       );
-      expect(clonedNode.attrs.selectedColumns[0].typeUserModified).toBe(true);
+      expect(clonedNode.attrs.selectedColumns[0]!.typeUserModified).toBe(true);
     });
 
     it('should create independent copies (mutations do not affect original)', () => {
@@ -411,12 +411,12 @@
       const clonedNode = node.clone() as ModifyColumnsNode;
 
       // Modify the cloned node
-      clonedNode.attrs.selectedColumns[0].alias = 'modified_alias';
-      clonedNode.attrs.selectedColumns[0].checked = false;
+      clonedNode.attrs.selectedColumns[0]!.alias = 'modified_alias';
+      clonedNode.attrs.selectedColumns[0]!.checked = false;
 
       // Original should be unchanged
-      expect(node.attrs.selectedColumns[0].alias).toBe('original_alias');
-      expect(node.attrs.selectedColumns[0].checked).toBe(true);
+      expect(node.attrs.selectedColumns[0]!.alias).toBe('original_alias');
+      expect(node.attrs.selectedColumns[0]!.checked).toBe(true);
     });
   });
 });
diff --git a/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/nodes/sort_node.ts b/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/nodes/sort_node.ts
index b4367a3..869caf0 100644
--- a/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/nodes/sort_node.ts
+++ b/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/nodes/sort_node.ts
@@ -197,7 +197,7 @@
       if (!this.attrs.sortCriteria) return;
       const newSortCriteria = [...this.attrs.sortCriteria];
       const [removed] = newSortCriteria.splice(from, 1);
-      newSortCriteria.splice(to, 0, removed);
+      newSortCriteria.splice(to, 0, removed!);
       this.attrs.sortCriteria = newSortCriteria;
       this.context.onchange?.();
       m.redraw();
@@ -217,7 +217,7 @@
             label: criterion.direction,
             onclick: () => {
               if (this.attrs.sortCriteria) {
-                this.attrs.sortCriteria[index].direction =
+                this.attrs.sortCriteria[index]!.direction =
                   criterion.direction === 'ASC' ? 'DESC' : 'ASC';
                 this.context.onchange?.();
                 m.redraw();
diff --git a/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/nodes/sources/sql_source.ts b/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/nodes/sources/sql_source.ts
index a830a55..4fa88b5 100644
--- a/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/nodes/sources/sql_source.ts
+++ b/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/nodes/sources/sql_source.ts
@@ -116,13 +116,13 @@
 
   // Check that all statements except the last are INCLUDE PERFETTO MODULE
   for (let i = 0; i < statements.length - 1; i++) {
-    if (!/^INCLUDE\s+PERFETTO\s+MODULE\b/i.test(statements[i])) {
+    if (!/^INCLUDE\s+PERFETTO\s+MODULE\b/i.test(statements[i]!)) {
       return 'Only INCLUDE PERFETTO MODULE statements are allowed before the SELECT query.';
     }
   }
 
   // Check that the last statement starts with SELECT (or WITH for CTEs)
-  const lastStatement = statements[statements.length - 1];
+  const lastStatement = statements[statements.length - 1]!;
   if (!/^(?:SELECT|WITH)\b/i.test(lastStatement)) {
     return 'The query must end with a SELECT statement.';
   }
@@ -285,7 +285,7 @@
     const dependencies: string[] = [];
     if (this.attrs.sql) {
       while ((match = regex.exec(this.attrs.sql)) !== null) {
-        dependencies.push(match[1]);
+        dependencies.push(match[1]!);
       }
     }
     return dependencies;
diff --git a/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/nodes/sources/sql_source_unittest.ts b/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/nodes/sources/sql_source_unittest.ts
index 155b8ce..a749413 100644
--- a/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/nodes/sources/sql_source_unittest.ts
+++ b/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/nodes/sources/sql_source_unittest.ts
@@ -121,7 +121,7 @@
       const sq = node.getStructuredQuery();
       expect(sq).toBeDefined();
       expect(sq?.sql?.dependencies?.length).toBe(1);
-      expect(sq?.sql?.dependencies?.[0].alias).toBe('input_0');
+      expect(sq?.sql?.dependencies?.[0]!.alias).toBe('input_0');
     });
 
     it('should include multiple dependencies with correct aliases', () => {
diff --git a/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/nodes/sources/timerange_source_unittest.ts b/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/nodes/sources/timerange_source_unittest.ts
index eb5bbb6..5682b72 100644
--- a/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/nodes/sources/timerange_source_unittest.ts
+++ b/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/nodes/sources/timerange_source_unittest.ts
@@ -334,21 +334,21 @@
       const node = makeNode({start: '100', end: '500', isDynamic: false});
 
       expect(node.finalCols.length).toBe(3);
-      expect(node.finalCols[0].name).toBe('id');
-      expect(node.finalCols[1].name).toBe('ts');
-      expect(node.finalCols[2].name).toBe('dur');
+      expect(node.finalCols[0]!.name).toBe('id');
+      expect(node.finalCols[1]!.name).toBe('ts');
+      expect(node.finalCols[2]!.name).toBe('dur');
     });
 
     it('should have correct column types', () => {
       const node = makeNode({start: '100', end: '500', isDynamic: false});
 
       expect(node.finalCols.length).toBe(3);
-      expect(node.finalCols[0].name).toBe('id');
-      expect(node.finalCols[0].type).toEqual({kind: 'int'});
-      expect(node.finalCols[1].name).toBe('ts');
-      expect(node.finalCols[1].type).toEqual({kind: 'timestamp'});
-      expect(node.finalCols[2].name).toBe('dur');
-      expect(node.finalCols[2].type).toEqual({kind: 'duration'});
+      expect(node.finalCols[0]!.name).toBe('id');
+      expect(node.finalCols[0]!.type).toEqual({kind: 'int'});
+      expect(node.finalCols[1]!.name).toBe('ts');
+      expect(node.finalCols[1]!.type).toEqual({kind: 'timestamp'});
+      expect(node.finalCols[2]!.name).toBe('dur');
+      expect(node.finalCols[2]!.type).toEqual({kind: 'duration'});
     });
   });
 
diff --git a/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/nodes/trace_summary_node_unittest.ts b/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/nodes/trace_summary_node_unittest.ts
index a9cc245..7ee5b8b 100644
--- a/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/nodes/trace_summary_node_unittest.ts
+++ b/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/nodes/trace_summary_node_unittest.ts
@@ -170,7 +170,7 @@
       const spec = node.getTraceSummarySpec();
       expect(spec).toBeDefined();
       expect(spec?.metricTemplateSpec).toHaveLength(1);
-      expect(spec?.metricTemplateSpec?.[0].idPrefix).toBe('my_metric');
+      expect(spec?.metricTemplateSpec?.[0]!.idPrefix).toBe('my_metric');
     });
 
     test('bundles multiple Metrics nodes', () => {
@@ -196,8 +196,8 @@
       connectSecondary(metrics2, node, 1);
 
       const spec = node.getTraceSummarySpec();
-      expect(spec?.metricTemplateSpec?.[0].idPrefix).toBe('first_metric');
-      expect(spec?.metricTemplateSpec?.[1].idPrefix).toBe('second_metric');
+      expect(spec?.metricTemplateSpec?.[0]!.idPrefix).toBe('first_metric');
+      expect(spec?.metricTemplateSpec?.[1]!.idPrefix).toBe('second_metric');
     });
   });
 
diff --git a/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/nodes/trace_summary_results_panel.ts b/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/nodes/trace_summary_results_panel.ts
index 2000551..ab2cf39 100644
--- a/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/nodes/trace_summary_results_panel.ts
+++ b/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/nodes/trace_summary_results_panel.ts
@@ -100,7 +100,7 @@
       });
     } else {
       for (let i = 0; i < specs.length; i++) {
-        const spec = specs[i];
+        const spec = specs[i]!;
         metrics.push({
           metricId: spec.id ?? `${bundle.bundleId ?? 'unknown'}_${i}`,
           valueName: spec.value ?? 'value',
@@ -128,7 +128,7 @@
         const rowData: Row = {};
         for (let i = 0; i < dimensionNames.length; i++) {
           const dimValue = row.dimension?.[i];
-          rowData[dimensionNames[i]] =
+          rowData[dimensionNames[i]!] =
             dimValue !== undefined && dimValue !== null
               ? parseDimensionValue(dimValue)
               : null;
@@ -308,7 +308,7 @@
           });
         }
         if (bundles.length === 1) {
-          const bundle = bundles[0];
+          const bundle = bundles[0]!;
           return m(DataGrid, {
             data: bundle.rows,
             schema: bundle.schema,
@@ -404,7 +404,7 @@
         const bundles = parseTraceSummaryProto(result.protoSummary);
         this.executionState = {kind: 'done', bundles, durationMs};
         if (bundles.length > 0) {
-          this.activeTab ??= bundles[0].metricId;
+          this.activeTab ??= bundles[0]!.metricId;
         }
       } else {
         this.executionState = {kind: 'error', message: 'No results returned'};
diff --git a/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/nodes/union_node.ts b/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/nodes/union_node.ts
index 2722b13..951c2fe 100644
--- a/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/nodes/union_node.ts
+++ b/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/nodes/union_node.ts
@@ -79,7 +79,7 @@
     // Initialize connections from inputNodes
     if (inputNodes) {
       for (let i = 0; i < inputNodes.length; i++) {
-        this.secondaryInputs.connections.set(i, inputNodes[i]);
+        this.secondaryInputs.connections.set(i, inputNodes[i]!);
       }
     }
     this.nextNodes = [];
@@ -116,11 +116,11 @@
     if (validPrevNodes.length === 0) {
       return [];
     }
-    let commonCols = validPrevNodes[0].finalCols.map((col) =>
+    let commonCols = validPrevNodes[0]!.finalCols.map((col) =>
       newColumnInfo(col, true),
     );
     for (let i = 1; i < validPrevNodes.length; i++) {
-      const currentNodeCols = validPrevNodes[i].finalCols;
+      const currentNodeCols = validPrevNodes[i]!.finalCols;
       commonCols = commonCols.filter((commonCol) =>
         currentNodeCols.some(
           (currentNodeCol) => currentNodeCol.name === commonCol.name,
diff --git a/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/nodes/union_node_unittest.ts b/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/nodes/union_node_unittest.ts
index f6707e5..13bc202 100644
--- a/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/nodes/union_node_unittest.ts
+++ b/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/nodes/union_node_unittest.ts
@@ -225,7 +225,7 @@
 
       const finalCols = unionNode.finalCols;
       expect(finalCols.length).toBe(1);
-      expect(finalCols[0].name).toBe('id');
+      expect(finalCols[0]!.name).toBe('id');
     });
 
     it('should return empty array when no columns are checked', () => {
@@ -281,9 +281,9 @@
 
       // Only 'id' should remain as it's the only common column
       expect(unionNode.attrs.selectedColumns.length).toBe(1);
-      expect(unionNode.attrs.selectedColumns[0].name).toBe('id');
+      expect(unionNode.attrs.selectedColumns[0]!.name).toBe('id');
       // 'id' should preserve its checked status (true)
-      expect(unionNode.attrs.selectedColumns[0].checked).toBe(true);
+      expect(unionNode.attrs.selectedColumns[0]!.checked).toBe(true);
     });
 
     it('should preserve checked status for columns that still exist', () => {
@@ -499,10 +499,10 @@
       const cloned = unionNode.clone() as UnionNode;
 
       // Modify the cloned state
-      (cloned as UnionNode).attrs.selectedColumns[0].checked = false;
+      (cloned as UnionNode).attrs.selectedColumns[0]!.checked = false;
 
       // Original should not be affected
-      expect(unionNode.attrs.selectedColumns[0].checked).toBe(true);
+      expect(unionNode.attrs.selectedColumns[0]!.checked).toBe(true);
     });
   });
 
@@ -660,7 +660,7 @@
         {},
       );
       expect(unionNode.attrs.selectedColumns.length).toBe(1);
-      expect(unionNode.attrs.selectedColumns[0].name).toBe('id');
+      expect(unionNode.attrs.selectedColumns[0]!.name).toBe('id');
     });
   });
 
@@ -672,7 +672,7 @@
       );
 
       expect(node.attrs.selectedColumns.length).toBe(1);
-      expect(node.attrs.selectedColumns[0].name).toBe('id');
+      expect(node.attrs.selectedColumns[0]!.name).toBe('id');
     });
   });
 });
diff --git a/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/nodes/visualisation_node.ts b/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/nodes/visualisation_node.ts
index 2e90eba..3597202 100644
--- a/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/nodes/visualisation_node.ts
+++ b/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/nodes/visualisation_node.ts
@@ -595,7 +595,7 @@
     );
     if (chartIndex === -1) return;
 
-    const config = this.attrs.chartConfigs[chartIndex];
+    const config = this.attrs.chartConfigs[chartIndex]!;
     this.attrs.chartConfigs[chartIndex] = {
       ...config,
       ...updates,
@@ -623,7 +623,7 @@
     );
     if (chartIndex === -1) return;
 
-    const original = this.attrs.chartConfigs[chartIndex];
+    const original = this.attrs.chartConfigs[chartIndex]!;
     const duplicate: ChartConfig = {
       ...original,
       id: generateChartId(),
@@ -656,7 +656,7 @@
       draggedIndex < targetIndex ? targetIndex - 1 : targetIndex;
 
     // Insert at new position
-    configs.splice(newTargetIndex, 0, draggedItem);
+    configs.splice(newTargetIndex, 0, draggedItem!);
 
     this.context.onchange?.();
   }
@@ -798,7 +798,7 @@
     if (!this.attrs.chartFilters || index >= this.attrs.chartFilters.length) {
       return;
     }
-    const filter = this.attrs.chartFilters[index];
+    const filter = this.attrs.chartFilters[index]!;
     this.attrs.chartFilters[index] = {
       ...filter,
       enabled: !(filter.enabled ?? true),
diff --git a/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/operations/filter.ts b/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/operations/filter.ts
index ecc7d91..5f4fbb6 100644
--- a/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/operations/filter.ts
+++ b/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/operations/filter.ts
@@ -226,7 +226,7 @@
   const [, colName, opName, valueText] = match;
 
   const col = sourceCols.find(
-    (c) => c.name.toLowerCase() === colName.toLowerCase(),
+    (c) => c.name.toLowerCase() === colName!.toLowerCase(),
   );
   if (col === undefined) {
     return {};
@@ -234,7 +234,7 @@
 
   // Find the exact operator object. We need to do a case-insensitive search.
   const op = ALL_FILTER_OPS.find(
-    (o) => o.displayName.toLowerCase() === opName.toLowerCase(),
+    (o) => o.displayName.toLowerCase() === opName!.toLowerCase(),
   );
 
   if (op === undefined) {
@@ -591,7 +591,7 @@
 
   // If only one column, create a simple flat group
   if (filtersByColumn.size === 1) {
-    const columnFilters = [...filtersByColumn.values()][0];
+    const columnFilters = [...filtersByColumn.values()][0]!;
     const protoFilters = createFiltersProto(columnFilters, sourceCols);
     if (!protoFilters) {
       return undefined;
diff --git a/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/operations/filter_unittest.ts b/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/operations/filter_unittest.ts
index db61767..3b586b6 100644
--- a/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/operations/filter_unittest.ts
+++ b/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/operations/filter_unittest.ts
@@ -79,8 +79,8 @@
         const result = createFiltersProto(filters, sourceCols);
 
         expect(result).toHaveLength(2);
-        expect(result![0].columnName).toBe('id');
-        expect(result![1].columnName).toBe('age');
+        expect(result![0]!.columnName).toBe('id');
+        expect(result![1]!.columnName).toBe('age');
       });
 
       it('should return undefined if all filters are disabled', () => {
@@ -100,8 +100,8 @@
         const result = createFiltersProto(filters, sourceCols);
 
         expect(result).toHaveLength(1);
-        expect(result![0].columnName).toBe('name');
-        expect(result![0].stringRhs).toEqual(['test']);
+        expect(result![0]!.columnName).toBe('name');
+        expect(result![0]!.stringRhs).toEqual(['test']);
       });
 
       it('should create proto for number filter', () => {
@@ -110,8 +110,8 @@
         const result = createFiltersProto(filters, sourceCols);
 
         expect(result).toHaveLength(1);
-        expect(result![0].columnName).toBe('id');
-        expect(result![0].int64Rhs).toEqual([42]);
+        expect(result![0]!.columnName).toBe('id');
+        expect(result![0]!.int64Rhs).toEqual([42]);
       });
 
       it('should handle multiple filters', () => {
@@ -124,9 +124,9 @@
         const result = createFiltersProto(filters, sourceCols);
 
         expect(result).toHaveLength(3);
-        expect(result![0].columnName).toBe('id');
-        expect(result![1].columnName).toBe('name');
-        expect(result![2].columnName).toBe('age');
+        expect(result![0]!.columnName).toBe('id');
+        expect(result![1]!.columnName).toBe('name');
+        expect(result![2]!.columnName).toBe('age');
       });
     });
 
diff --git a/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/query_builder_utils.ts b/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/query_builder_utils.ts
index bc3005a..0ba82d0 100644
--- a/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/query_builder_utils.ts
+++ b/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/query_builder_utils.ts
@@ -197,7 +197,7 @@
     }
   }
 
-  const root = queries[queries.length - 1];
+  const root = queries[queries.length - 1]!;
   const rootObj = protos.PerfettoSqlStructuredQuery.toObject(root);
   const resolved = inlineQueryRefs(rootObj, queryMap, new Set());
   return protos.PerfettoSqlStructuredQuery.fromObject(resolved);
diff --git a/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/results_panel.ts b/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/results_panel.ts
index 5337c70..dae8ce1 100644
--- a/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/results_panel.ts
+++ b/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/results_panel.ts
@@ -543,7 +543,7 @@
               m(
                 MenuItem,
                 {label: `From ${tableName}`},
-                buildColumnItems(joinidColumns[0].joinidColumn),
+                buildColumnItems(joinidColumns[0]!.joinidColumn),
               ),
             );
           } else {
@@ -591,6 +591,10 @@
           data: attrs.dataSource,
           disablePivotControls: true,
           structuredQueryCompatMode: true,
+          // Filters here become steps in the query graph (see onFilterAdd
+          // below). The quick filter would filter rows directly and bypass
+          // the graph, so turn it off.
+          enableQuickFilter: false,
           canAddColumns: false,
           canRemoveColumns: false,
           onColumnsChanged: (columns) => {
@@ -616,7 +620,7 @@
               }
               attrs.onFilterAdd(
                 normalizedFilters.length === 1
-                  ? normalizedFilters[0]
+                  ? normalizedFilters[0]!
                   : normalizedFilters,
                 operator,
               );
diff --git a/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/structured_query_builder_unittest.ts b/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/structured_query_builder_unittest.ts
index b291581..ad3cc63 100644
--- a/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/structured_query_builder_unittest.ts
+++ b/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/structured_query_builder_unittest.ts
@@ -90,8 +90,8 @@
       StructuredQueryBuilder.applyNodeColumnSelection(sq, node);
 
       expect(sq.selectColumns.length).toBe(2);
-      expect(sq.selectColumns[0].columnName).toBe('id');
-      expect(sq.selectColumns[1].columnName).toBe('age');
+      expect(sq.selectColumns[0]!.columnName).toBe('id');
+      expect(sq.selectColumns[1]!.columnName).toBe('age');
     });
 
     it('should include aliases when present', () => {
@@ -114,8 +114,8 @@
       StructuredQueryBuilder.applyNodeColumnSelection(sq, node);
 
       expect(sq.selectColumns.length).toBe(1);
-      expect(sq.selectColumns[0].columnName).toBe('id');
-      expect(sq.selectColumns[0].alias).toBe('identifier');
+      expect(sq.selectColumns[0]!.columnName).toBe('id');
+      expect(sq.selectColumns[0]!.alias).toBe('identifier');
     });
 
     it('should handle empty column list', () => {
diff --git a/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/utils.ts b/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/utils.ts
index 9f10f46..bd7b31c 100644
--- a/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/utils.ts
+++ b/ui/src/plugins/dev.perfetto.DataExplorer/query_builder/utils.ts
@@ -144,7 +144,7 @@
   };
 
   // Start with columns from the first array
-  const firstArray = columnArrays[0];
+  const firstArray = columnArrays[0]!;
   const commonColumns = new Set(
     firstArray
       .filter((c) => !excludedColumns.has(c.name) && !isTypeExcluded(c.type))
@@ -153,7 +153,7 @@
 
   // Intersect with columns from remaining arrays
   for (let i = 1; i < columnArrays.length; i++) {
-    const colsMap = new Map(columnArrays[i].map((c) => [c.name, c.type]));
+    const colsMap = new Map(columnArrays[i]!.map((c) => [c.name, c.type]));
     for (const col of commonColumns) {
       const colType = colsMap.get(col);
       if (colType === undefined || isTypeExcluded(colType)) {
diff --git a/ui/src/plugins/dev.perfetto.DataExplorer/recent_graphs.ts b/ui/src/plugins/dev.perfetto.DataExplorer/recent_graphs.ts
index dbfd311..4092610 100644
--- a/ui/src/plugins/dev.perfetto.DataExplorer/recent_graphs.ts
+++ b/ui/src/plugins/dev.perfetto.DataExplorer/recent_graphs.ts
@@ -104,10 +104,10 @@
       });
     } else {
       // Update the working slot in place
-      this._data[0].json = json;
-      this._data[0].timestamp = timestamp;
-      this._data[0].nodeCount = nodeCount;
-      this._data[0].labelCount = labelCount;
+      this._data[0]!.json = json;
+      this._data[0]!.timestamp = timestamp;
+      this._data[0]!.nodeCount = nodeCount;
+      this._data[0]!.labelCount = labelCount;
     }
     this.save();
   }
@@ -119,19 +119,19 @@
    */
   finalizeCurrentGraph(): void {
     const hasWorkingGraph =
-      this._data.length > 0 && (this._data[0].nodeCount ?? 0) > 0;
+      this._data.length > 0 && (this._data[0]!.nodeCount ?? 0) > 0;
     if (!hasWorkingGraph) {
       return;
     }
 
     // Give the current graph a proper name based on when it was finalized
-    this._data[0].name = this.generateName();
+    this._data[0]!.name = this.generateName();
 
     // Count unstarred items (excluding working slot which will become historical)
     let lastUnstarredIndex = -1;
     let unstarredCount = 0;
     for (let i = 0; i < this._data.length; i++) {
-      if (!this._data[i].starred) {
+      if (!this._data[i]!.starred) {
         unstarredCount++;
         lastUnstarredIndex = i;
       }
@@ -174,7 +174,7 @@
    */
   setStarred(index: number, starred: boolean): void {
     assertTrue(index >= 0 && index < this._data.length);
-    this._data[index].starred = starred;
+    this._data[index]!.starred = starred;
     this.save();
   }
 
@@ -183,7 +183,7 @@
    */
   rename(index: number, newName: string): void {
     assertTrue(index >= 0 && index < this._data.length);
-    this._data[index].name = newName.trim() || this._data[index].name;
+    this._data[index]!.name = newName.trim() || this._data[index]!.name;
     this.save();
   }
 
@@ -209,7 +209,7 @@
    */
   getJson(index: number): string | undefined {
     if (index >= 0 && index < this._data.length) {
-      return this._data[index].json;
+      return this._data[index]!.json;
     }
     return undefined;
   }
@@ -417,7 +417,7 @@
     const unstarred: Array<{entry: RecentGraphEntry; index: number}> = [];
 
     for (let i = 1; i < recentGraphs.length; i++) {
-      const entry = recentGraphs[i];
+      const entry = recentGraphs[i]!;
       // Skip empty placeholders (working slots with no content)
       if ((entry.nodeCount ?? 0) === 0) continue;
 
diff --git a/ui/src/plugins/dev.perfetto.DataExplorer/recent_graphs_unittest.ts b/ui/src/plugins/dev.perfetto.DataExplorer/recent_graphs_unittest.ts
index bbe5e9d..9f0ccf3 100644
--- a/ui/src/plugins/dev.perfetto.DataExplorer/recent_graphs_unittest.ts
+++ b/ui/src/plugins/dev.perfetto.DataExplorer/recent_graphs_unittest.ts
@@ -45,7 +45,7 @@
     test('should allow setting data directly', () => {
       recentGraphsStorage.data = [createEntry(3)];
       expect(recentGraphsStorage.data.length).toBe(1);
-      expect(recentGraphsStorage.data[0].nodeCount).toBe(3);
+      expect(recentGraphsStorage.data[0]!.nodeCount).toBe(3);
     });
   });
 
@@ -70,8 +70,8 @@
 
       // Should now have 2 entries: new working slot at 0, finalized graph at 1
       expect(recentGraphsStorage.data.length).toBe(2);
-      expect(recentGraphsStorage.data[0].nodeCount).toBe(0); // New empty working slot
-      expect(recentGraphsStorage.data[1].nodeCount).toBe(3); // Finalized graph
+      expect(recentGraphsStorage.data[0]!.nodeCount).toBe(0); // New empty working slot
+      expect(recentGraphsStorage.data[1]!.nodeCount).toBe(3); // Finalized graph
     });
 
     test('should enforce maxItems limit for unstarred graphs', () => {
@@ -165,14 +165,14 @@
       recentGraphsStorage.data = [createEntry(2)];
       recentGraphsStorage.setStarred(0, true);
 
-      expect(recentGraphsStorage.data[0].starred).toBe(true);
+      expect(recentGraphsStorage.data[0]!.starred).toBe(true);
     });
 
     test('should unstar a graph', () => {
       recentGraphsStorage.data = [createEntry(2, {starred: true})];
       recentGraphsStorage.setStarred(0, false);
 
-      expect(recentGraphsStorage.data[0].starred).toBe(false);
+      expect(recentGraphsStorage.data[0]!.starred).toBe(false);
     });
   });
 
@@ -181,21 +181,21 @@
       recentGraphsStorage.data = [createEntry(2)];
       recentGraphsStorage.rename(0, 'My Custom Name');
 
-      expect(recentGraphsStorage.data[0].name).toBe('My Custom Name');
+      expect(recentGraphsStorage.data[0]!.name).toBe('My Custom Name');
     });
 
     test('should trim whitespace from name', () => {
       recentGraphsStorage.data = [createEntry(2)];
       recentGraphsStorage.rename(0, '  Trimmed Name  ');
 
-      expect(recentGraphsStorage.data[0].name).toBe('Trimmed Name');
+      expect(recentGraphsStorage.data[0]!.name).toBe('Trimmed Name');
     });
 
     test('should keep original name if new name is empty', () => {
       recentGraphsStorage.data = [createEntry(2, {name: 'Original'})];
       recentGraphsStorage.rename(0, '   ');
 
-      expect(recentGraphsStorage.data[0].name).toBe('Original');
+      expect(recentGraphsStorage.data[0]!.name).toBe('Original');
     });
   });
 
@@ -227,7 +227,7 @@
       recentGraphsStorage.remove(2); // Remove middle entry
 
       expect(recentGraphsStorage.data.length).toBe(initialLength - 1);
-      expect(recentGraphsStorage.data[2].nodeCount).toBe(1); // Last entry moved up
+      expect(recentGraphsStorage.data[2]!.nodeCount).toBe(1); // Last entry moved up
     });
 
     test('should remove first entry', () => {
@@ -235,7 +235,7 @@
       recentGraphsStorage.remove(0);
 
       expect(recentGraphsStorage.data.length).toBe(1);
-      expect(recentGraphsStorage.data[0].nodeCount).toBe(2);
+      expect(recentGraphsStorage.data[0]!.nodeCount).toBe(2);
     });
 
     test('should remove last entry', () => {
@@ -243,7 +243,7 @@
       recentGraphsStorage.remove(1);
 
       expect(recentGraphsStorage.data.length).toBe(1);
-      expect(recentGraphsStorage.data[0].nodeCount).toBe(1);
+      expect(recentGraphsStorage.data[0]!.nodeCount).toBe(1);
     });
   });
 
@@ -323,7 +323,7 @@
       );
 
       expect(starred.length).toBe(1);
-      expect(starred[0].nodeCount).toBe(2);
+      expect(starred[0]!.nodeCount).toBe(2);
       expect(unstarred.length).toBe(2);
     });
   });
diff --git a/ui/src/plugins/dev.perfetto.DataExplorer/tab_io_unittest.ts b/ui/src/plugins/dev.perfetto.DataExplorer/tab_io_unittest.ts
index 13d1bc2..e151758 100644
--- a/ui/src/plugins/dev.perfetto.DataExplorer/tab_io_unittest.ts
+++ b/ui/src/plugins/dev.perfetto.DataExplorer/tab_io_unittest.ts
@@ -132,7 +132,7 @@
       {id: 'db1'},
     ] as unknown as SerializedDashboard[]);
     expect(result?.length).toBe(1);
-    expect(result?.[0].id).toBe('db1');
+    expect(result?.[0]!.id).toBe('db1');
   });
 
   test('skips entries that are primitives', () => {
@@ -142,7 +142,7 @@
       {id: 'db1'},
     ] as unknown as SerializedDashboard[]);
     expect(result?.length).toBe(1);
-    expect(result?.[0].id).toBe('db1');
+    expect(result?.[0]!.id).toBe('db1');
   });
 
   test('skips entries with missing id', () => {
@@ -151,7 +151,7 @@
       {id: 'db1'},
     ] as unknown as SerializedDashboard[]);
     expect(result?.length).toBe(1);
-    expect(result?.[0].id).toBe('db1');
+    expect(result?.[0]!.id).toBe('db1');
   });
 
   test('accepts entries with only id', () => {
@@ -160,8 +160,8 @@
       {id: 'db2'},
     ] as unknown as SerializedDashboard[]);
     expect(result?.length).toBe(2);
-    expect(result?.[0].id).toBe('db1');
-    expect(result?.[1].id).toBe('db2');
+    expect(result?.[0]!.id).toBe('db1');
+    expect(result?.[1]!.id).toBe('db2');
   });
 
   test('skips entries with non-string id', () => {
@@ -170,7 +170,7 @@
       {id: 'db1'},
     ] as unknown as SerializedDashboard[]);
     expect(result?.length).toBe(1);
-    expect(result?.[0].id).toBe('db1');
+    expect(result?.[0]!.id).toBe('db1');
   });
 
   test('returns undefined when ALL entries are invalid', () => {
@@ -192,9 +192,9 @@
     ];
     const result = deserializeDashboardsFromExport(serialized);
     expect(result?.length).toBe(1);
-    expect(result?.[0].id).toBe('db1');
-    expect(result?.[0].items.length).toBe(1);
-    expect(result?.[0].brushFilters).toEqual(new Map());
+    expect(result?.[0]!.id).toBe('db1');
+    expect(result?.[0]!.items.length).toBe(1);
+    expect(result?.[0]!.brushFilters).toEqual(new Map());
   });
 
   test('filters out invalid items during hydration', () => {
@@ -212,8 +212,8 @@
     ];
     const result = deserializeDashboardsFromExport(serialized);
     expect(result?.length).toBe(1);
-    expect(result?.[0].items.length).toBe(1);
-    expect((result?.[0].items[0] as {id: string}).id).toBe('lbl1');
+    expect(result?.[0]!.items.length).toBe(1);
+    expect((result?.[0]!.items[0] as {id: string}).id).toBe('lbl1');
   });
 
   test('returns empty items when all items are invalid', () => {
@@ -228,7 +228,7 @@
     ];
     const result = deserializeDashboardsFromExport(serialized);
     expect(result?.length).toBe(1);
-    expect(result?.[0].items).toEqual([]);
+    expect(result?.[0]!.items).toEqual([]);
   });
 
   test('hydrates dashboards with brush filters', () => {
@@ -241,8 +241,8 @@
       },
     ];
     const result = deserializeDashboardsFromExport(serialized);
-    expect(result?.[0].brushFilters.size).toBe(1);
-    expect(result?.[0].brushFilters.get('node1')).toEqual([
+    expect(result?.[0]!.brushFilters.size).toBe(1);
+    expect(result?.[0]!.brushFilters.get('node1')).toEqual([
       {column: 'ts', op: '>=', value: 100},
     ]);
   });
@@ -260,8 +260,8 @@
       },
     ];
     const result = deserializeDashboardsFromExport(serialized);
-    expect(result?.[0].brushFilters.get('node1')?.length).toBe(1);
-    expect(result?.[0].brushFilters.get('node1')?.[0].op).toBe('>=');
+    expect(result?.[0]!.brushFilters.get('node1')?.length).toBe(1);
+    expect(result?.[0]!.brushFilters.get('node1')?.[0]!.op).toBe('>=');
   });
 
   test('drops brush filters with missing column', () => {
@@ -275,7 +275,7 @@
     ];
     const result = deserializeDashboardsFromExport(serialized);
     // All filters for node1 are invalid, so the entry is dropped entirely
-    expect(result?.[0].brushFilters.size).toBe(0);
+    expect(result?.[0]!.brushFilters.size).toBe(0);
   });
 
   test('ignores non-object brushFilters (array)', () => {
@@ -287,7 +287,7 @@
     ] as unknown as SerializedDashboard[];
     const result = deserializeDashboardsFromExport(serialized);
     // brushFilters is an array, not a record — should fall back to empty map
-    expect(result?.[0].brushFilters).toEqual(new Map());
+    expect(result?.[0]!.brushFilters).toEqual(new Map());
   });
 
   test('ignores non-object brushFilters (string)', () => {
@@ -298,21 +298,21 @@
       },
     ] as unknown as SerializedDashboard[];
     const result = deserializeDashboardsFromExport(serialized);
-    expect(result?.[0].brushFilters).toEqual(new Map());
+    expect(result?.[0]!.brushFilters).toEqual(new Map());
   });
 
   test('handles dashboards with no items field', () => {
     const serialized: SerializedDashboard[] = [{id: 'db1'}];
     const result = deserializeDashboardsFromExport(serialized);
-    expect(result?.[0].items).toEqual([]);
+    expect(result?.[0]!.items).toEqual([]);
   });
 
   test('hydrates multiple dashboards', () => {
     const serialized: SerializedDashboard[] = [{id: 'db1'}, {id: 'db2'}];
     const result = deserializeDashboardsFromExport(serialized);
     expect(result?.length).toBe(2);
-    expect(result?.[0].id).toBe('db1');
-    expect(result?.[1].id).toBe('db2');
+    expect(result?.[0]!.id).toBe('db1');
+    expect(result?.[1]!.id).toBe('db2');
   });
 
   test('supports is null brush filter (no value field)', () => {
@@ -325,7 +325,7 @@
       },
     ];
     const result = deserializeDashboardsFromExport(serialized);
-    expect(result?.[0].brushFilters.get('node1')).toEqual([
+    expect(result?.[0]!.brushFilters.get('node1')).toEqual([
       {column: 'name', op: 'is null'},
     ]);
   });
@@ -356,8 +356,8 @@
     const result = serializeDashboardsForTab(tab);
     expect(result).toBeDefined();
     expect(result?.length).toBe(1);
-    expect(result?.[0].items).toBeUndefined();
-    expect(result?.[0].brushFilters).toBeUndefined();
+    expect(result?.[0]!.items).toBeUndefined();
+    expect(result?.[0]!.brushFilters).toBeUndefined();
   });
 
   test('serializes dashboard with label items', () => {
@@ -370,9 +370,9 @@
     ]);
     const result = serializeDashboardsForTab(tab);
     expect(result?.length).toBe(1);
-    expect(result?.[0].id).toBe('db1');
-    expect(result?.[0].items?.length).toBe(1);
-    expect(result?.[0].brushFilters).toBeUndefined();
+    expect(result?.[0]!.id).toBe('db1');
+    expect(result?.[0]!.items?.length).toBe(1);
+    expect(result?.[0]!.brushFilters).toBeUndefined();
   });
 
   test('serializes brush filters with BigInt conversion', () => {
@@ -387,8 +387,8 @@
       },
     ]);
     const result = serializeDashboardsForTab(tab);
-    expect(result?.[0].brushFilters).toBeDefined();
-    expect(result?.[0].brushFilters?.['node1']?.[0]).toEqual({
+    expect(result?.[0]!.brushFilters).toBeDefined();
+    expect(result?.[0]!.brushFilters?.['node1']?.[0]).toEqual({
       column: 'ts',
       op: '>=',
       value: 100,
@@ -410,8 +410,8 @@
     ]);
     const result = serializeDashboardsForTab(tab);
     expect(result?.length).toBe(2);
-    expect(result?.[0].id).toBe('db1');
-    expect(result?.[1].id).toBe('db2');
+    expect(result?.[0]!.id).toBe('db1');
+    expect(result?.[1]!.id).toBe('db2');
   });
 
   test('does not include graphTabId in output', () => {
@@ -438,7 +438,7 @@
       },
     ]);
     const result = serializeDashboardsForTab(tab);
-    expect(result?.[0].brushFilters?.['node1']?.[0]).toEqual({
+    expect(result?.[0]!.brushFilters?.['node1']?.[0]).toEqual({
       column: 'name',
       op: 'is null',
     });
@@ -488,17 +488,17 @@
     expect(hydrated?.length).toBe(2);
 
     // First dashboard: has items and brush filters
-    expect(hydrated?.[0].id).toBe('db1');
-    expect(hydrated?.[0].items.length).toBe(1);
-    expect(hydrated?.[0].brushFilters.size).toBe(1);
-    expect(hydrated?.[0].brushFilters.get('node1')).toEqual([
+    expect(hydrated?.[0]!.id).toBe('db1');
+    expect(hydrated?.[0]!.items.length).toBe(1);
+    expect(hydrated?.[0]!.brushFilters.size).toBe(1);
+    expect(hydrated?.[0]!.brushFilters.get('node1')).toEqual([
       {column: 'dur', op: '>=', value: 500},
     ]);
 
     // Second dashboard: empty items, no filters
-    expect(hydrated?.[1].id).toBe('db2');
-    expect(hydrated?.[1].items).toEqual([]);
-    expect(hydrated?.[1].brushFilters).toEqual(new Map());
+    expect(hydrated?.[1]!.id).toBe('db2');
+    expect(hydrated?.[1]!.items).toEqual([]);
+    expect(hydrated?.[1]!.brushFilters).toEqual(new Map());
   });
 
   test('round-trip through JSON.stringify/parse preserves data', () => {
@@ -529,9 +529,9 @@
 
     const hydrated = deserializeDashboardsFromExport(parsed);
     expect(hydrated?.length).toBe(1);
-    expect(hydrated?.[0].id).toBe('db1');
-    expect(hydrated?.[0].items.length).toBe(1);
-    expect(hydrated?.[0].brushFilters.get('n1')).toEqual([
+    expect(hydrated?.[0]!.id).toBe('db1');
+    expect(hydrated?.[0]!.items.length).toBe(1);
+    expect(hydrated?.[0]!.brushFilters.get('n1')).toEqual([
       {column: 'ts', op: '>=', value: 1000},
     ]);
   });
diff --git a/ui/src/plugins/dev.perfetto.Ftrace/common.ts b/ui/src/plugins/dev.perfetto.Ftrace/common.ts
index bc1c651..4b04286 100644
--- a/ui/src/plugins/dev.perfetto.Ftrace/common.ts
+++ b/ui/src/plugins/dev.perfetto.Ftrace/common.ts
@@ -12,22 +12,24 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+import {z} from 'zod';
+
 export const FTRACE_RAW_TRACK_KIND = 'FtraceRawTrack';
 
-export interface FtraceFilter {
-  // We use an exclude list rather than include list for filtering events, as we
-  // want to include all events by default but we won't know what names are
-  // present initially.
-  excludeList: string[];
-  // Inclusion list of ucpu ids shown in the standalone ftrace tab. Undefined
-  // means all CPUs are shown.
-  visibleCpus?: number[];
-}
+export const FTRACE_STATE_SCHEMA = z.object({
+  version: z.literal(2),
+  filter: z.object({
+    // We use an exclude list rather than include list for filtering events, as we
+    // want to include all events by default but we won't know what names are
+    // present initially.
+    excludeList: z.array(z.string()),
+    // Inclusion list of ucpu ids shown in the standalone ftrace tab. Undefined
+    // means all CPUs are shown.
+    visibleCpus: z.array(z.number()).optional(),
+  }),
+});
 
-export interface FtracePluginState {
-  version: number;
-  filter: FtraceFilter;
-}
+export type FtracePluginState = z.infer<typeof FTRACE_STATE_SCHEMA>;
 
 export interface FtraceStat {
   name: string;
diff --git a/ui/src/plugins/dev.perfetto.Ftrace/ftrace_track.ts b/ui/src/plugins/dev.perfetto.Ftrace/ftrace_track.ts
index bf8a0f8..3bf9bb0 100644
--- a/ui/src/plugins/dev.perfetto.Ftrace/ftrace_track.ts
+++ b/ui/src/plugins/dev.perfetto.Ftrace/ftrace_track.ts
@@ -12,13 +12,12 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-import type {Store} from '../../base/store';
 import {materialColorScheme} from '../../components/colorizer';
 import {SliceTrack} from '../../components/tracks/slice_track';
-import type {Trace} from '../../public/trace';
+import type {Storage, Trace} from '../../public/trace';
 import {SourceDataset} from '../../trace_processor/dataset';
 import {LONG, NUM, STR} from '../../trace_processor/query_result';
-import type {FtraceFilter} from './common';
+import type {FtracePluginState} from './common';
 import {FtraceEventDetailsPanel} from './ftrace_details_panel';
 
 const FTRACE_INSTANT_WIDTH_PX = 8;
@@ -27,7 +26,7 @@
   trace: Trace,
   uri: string,
   ucpu: number,
-  store: Store<FtraceFilter>,
+  storage: Storage<FtracePluginState>,
 ) {
   return SliceTrack.create({
     trace,
@@ -37,7 +36,7 @@
       // This dataset can change depending on the filter settings, so we pass a
       // function in here instead of a static dataset. This function is called
       // every render cycle by the track to see if the dataset has changed.
-      const excludeList = store.state.excludeList;
+      const excludeList = storage.get().filter.excludeList;
       return new SourceDataset({
         src: `
           SELECT *
diff --git a/ui/src/plugins/dev.perfetto.Ftrace/index.ts b/ui/src/plugins/dev.perfetto.Ftrace/index.ts
index 46eb79e..eebd86c 100644
--- a/ui/src/plugins/dev.perfetto.Ftrace/index.ts
+++ b/ui/src/plugins/dev.perfetto.Ftrace/index.ts
@@ -22,17 +22,15 @@
 import {Cpu} from '../../components/cpu';
 import {getMachineCount} from '../../public/utils';
 import {
-  type FtraceFilter,
-  type FtracePluginState as FtraceFilters,
+  type FtracePluginState,
   FTRACE_RAW_TRACK_KIND,
+  FTRACE_STATE_SCHEMA,
 } from './common';
 import {FtraceExplorer, type FtraceExplorerCache} from './ftrace_explorer';
 import {createFtraceTrack} from './ftrace_track';
 
-const VERSION = 2;
-
-const DEFAULT_STATE: FtraceFilters = {
-  version: VERSION,
+const DEFAULT_STATE: FtracePluginState = {
+  version: 2,
   filter: {
     excludeList: [],
   },
@@ -42,26 +40,11 @@
   static readonly id = 'dev.perfetto.Ftrace';
 
   async onTraceLoad(ctx: Trace): Promise<void> {
-    const store = ctx.mountStore<FtraceFilters>(
-      'dev.perfetto.FtraceFilters',
-      (init: unknown) => {
-        if (
-          typeof init === 'object' &&
-          init !== null &&
-          'version' in init &&
-          init.version === VERSION
-        ) {
-          return init as {} as FtraceFilters;
-        } else {
-          return DEFAULT_STATE;
-        }
-      },
-    );
-
-    const filterStore = store.createSubStore(
-      ['filter'],
-      (x) => x as FtraceFilter,
-    );
+    const storage = ctx.registerStorage({
+      id: 'dev.perfetto.FtraceFilters',
+      schema: FTRACE_STATE_SCHEMA,
+      defaultValue: DEFAULT_STATE,
+    });
 
     const ftraceTabUri = 'perfetto.FtraceRaw#FtraceEventsTab';
 
@@ -92,7 +75,7 @@
           ucpu: cpu.ucpu,
           kinds: [FTRACE_RAW_TRACK_KIND],
         },
-        renderer: createFtraceTrack(ctx, uri, cpu.ucpu, filterStore),
+        renderer: createFtraceTrack(ctx, uri, cpu.ucpu, storage),
       });
 
       const track = new TrackNode({
@@ -113,10 +96,13 @@
 
     // The event-name filter is shared (and persisted) across both the
     // standalone tab and the area-selection tab.
-    const onExcludeListChange = (excludeList: ReadonlyArray<string>) =>
-      filterStore.edit((draft) => {
-        draft.excludeList = Array.from(excludeList);
+    const onExcludeListChange = (excludeList: ReadonlyArray<string>) => {
+      const state = storage.get();
+      storage.set({
+        ...state,
+        filter: {...state.filter, excludeList: Array.from(excludeList)},
       });
+    };
 
     const allUcpus = cpus.map((c) => c.ucpu);
 
@@ -129,17 +115,20 @@
             trace: ctx,
             cache,
             cpus,
-            excludeList: filterStore.state.excludeList,
+            excludeList: storage.get().filter.excludeList,
             onExcludeListChange,
             // The standalone tab exposes a persisted cpu inclusion filter over
             // all cpus. Undefined persisted state means "show all".
             cpuFilter: {
               kind: 'selectable',
-              show: filterStore.state.visibleCpus ?? allUcpus,
-              onChange: (show) =>
-                filterStore.edit((draft) => {
-                  draft.visibleCpus = Array.from(show);
-                }),
+              show: storage.get().filter.visibleCpus ?? allUcpus,
+              onChange: (show) => {
+                const state = storage.get();
+                storage.set({
+                  ...state,
+                  filter: {...state.filter, visibleCpus: Array.from(show)},
+                });
+              },
             },
           }),
         getTitle: () => 'Ftrace Events',
@@ -175,7 +164,7 @@
             cache,
             cpus,
             bounds: {start: selection.start, end: selection.end},
-            excludeList: filterStore.state.excludeList,
+            excludeList: storage.get().filter.excludeList,
             onExcludeListChange,
             cpuFilter: {kind: 'fixed', show: selectedUcpus},
           }),
diff --git a/ui/src/plugins/dev.perfetto.Ftrace/storage_schema_unittest.ts b/ui/src/plugins/dev.perfetto.Ftrace/storage_schema_unittest.ts
new file mode 100644
index 0000000..c7f884e
--- /dev/null
+++ b/ui/src/plugins/dev.perfetto.Ftrace/storage_schema_unittest.ts
@@ -0,0 +1,41 @@
+// Copyright (C) 2026 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 {FTRACE_STATE_SCHEMA} from './common';
+
+describe('FTRACE_STATE_SCHEMA', () => {
+  test('accepts the default state', () => {
+    const state = {version: 2, filter: {excludeList: []}};
+    expect(FTRACE_STATE_SCHEMA.parse(state)).toEqual(state);
+  });
+
+  test('accepts a populated state', () => {
+    const state = {
+      version: 2,
+      filter: {
+        excludeList: ['sched_switch', 'sched_wakeup'],
+        visibleCpus: [0, 2],
+      },
+    };
+    expect(FTRACE_STATE_SCHEMA.parse(state)).toEqual(state);
+  });
+
+  test('rejects other versions', () => {
+    const result = FTRACE_STATE_SCHEMA.safeParse({
+      version: 1,
+      filter: {excludeList: []},
+    });
+    expect(result.success).toBe(false);
+  });
+});
diff --git a/ui/src/plugins/dev.perfetto.Gpu/index.ts b/ui/src/plugins/dev.perfetto.Gpu/index.ts
index b93f157..9cae7d2 100644
--- a/ui/src/plugins/dev.perfetto.Gpu/index.ts
+++ b/ui/src/plugins/dev.perfetto.Gpu/index.ts
@@ -487,7 +487,7 @@
       .map(([id]) => id);
     const groupSortOrder = new Map<number, number>();
     for (let i = 0; i < sortedGroupIds.length; i++) {
-      groupSortOrder.set(sortedGroupIds[i], CUSTOM_GROUP_SORT_BASE + i);
+      groupSortOrder.set(sortedGroupIds[i]!, CUSTOM_GROUP_SORT_BASE + i);
     }
 
     // Count ungrouped tracks per type to decide if a sub-group is needed,
@@ -663,7 +663,7 @@
       const gpu =
         gpuId !== null
           ? new Gpu(
-              ugpu ?? trackIds[0],
+              ugpu ?? trackIds[0]!,
               gpuId,
               machineId,
               gpuName ?? undefined,
diff --git a/ui/src/plugins/dev.perfetto.HeapProfile/index.ts b/ui/src/plugins/dev.perfetto.HeapProfile/index.ts
index 284f4ad..7e560b5 100644
--- a/ui/src/plugins/dev.perfetto.HeapProfile/index.ts
+++ b/ui/src/plugins/dev.perfetto.HeapProfile/index.ts
@@ -26,9 +26,8 @@
 import ProcessThreadGroupsPlugin from '../dev.perfetto.ProcessThreadGroups';
 import type {Track} from '../../public/track';
 import {TREE_EXPLORER_STATE_SCHEMA} from '../../widgets/tree_explorer';
-import type {Store} from '../../base/store';
+import type {Storage} from '../../public/trace';
 import {z} from 'zod';
-import {ensureExists} from '../../base/assert';
 import {Memo} from '../../base/memo';
 import {
   isProfileDescriptor,
@@ -49,7 +48,7 @@
 
 const EVENT_TABLE_NAME = 'heap_profile_events';
 
-const HEAP_PROFILE_PLUGIN_STATE_SCHEMA = z.record(
+export const HEAP_PROFILE_PLUGIN_STATE_SCHEMA = z.record(
   z.enum(ProfileType),
   z.object({
     trackFlamegraphState: TREE_EXPLORER_STATE_SCHEMA.optional(),
@@ -86,7 +85,6 @@
   }
 
   private readonly trackMap = new Map<string, Track>();
-  private store?: Store<HeapProfilePluginState>;
 
   private readonly nodeSelectedEvt = new EvtSource<{
     pathHashes: string;
@@ -106,28 +104,23 @@
     return this.nodeSelectedEvt.addListener(cb);
   }
 
-  private migrateHeapProfilePluginState(init: unknown): HeapProfilePluginState {
-    const result = HEAP_PROFILE_PLUGIN_STATE_SCHEMA.safeParse(init);
-    return (
-      result.data ?? {
+  async onTraceLoad(trace: Trace): Promise<void> {
+    const storage = trace.registerStorage({
+      id: HeapProfilePlugin.id,
+      schema: HEAP_PROFILE_PLUGIN_STATE_SCHEMA,
+      defaultValue: {
         [ProfileType.NATIVE_HEAP_PROFILE]: {},
         [ProfileType.GENERIC_HEAP_PROFILE]: {},
         [ProfileType.JAVA_HEAP_SAMPLES]: {},
         [ProfileType.JAVA_HEAP_GRAPH]: {},
         [ProfileType.OOME_CALLSTACK]: {},
-      }
-    );
-  }
-
-  async onTraceLoad(trace: Trace): Promise<void> {
-    this.store = trace.mountStore(HeapProfilePlugin.id, (init) =>
-      this.migrateHeapProfilePluginState(init),
-    );
+      },
+    });
     await this.createHeapProfileTable(trace);
     // Ordered by priority, so the tracks and the area-selection flamegraph tabs
     // registered below come out in the right order.
     const heapTypes = await this.getHeapTypes(trace);
-    await this.addProcessTracks(trace, heapTypes);
+    await this.addProcessTracks(trace, heapTypes, storage);
 
     // For applicable heap types, register an area selection
     for (const heapType of heapTypes) {
@@ -140,7 +133,12 @@
         continue;
       }
       trace.selection.registerAreaSelectionTab(
-        this.heapProfileSelectionHandler(trace, descriptor, heapType.priority),
+        this.heapProfileSelectionHandler(
+          trace,
+          descriptor,
+          heapType.priority,
+          storage,
+        ),
       );
     }
 
@@ -247,6 +245,7 @@
   private async addProcessTracks(
     trace: Trace,
     heapTypes: ReadonlyArray<{type: string; priority: number}>,
+    storage: Storage<HeapProfilePluginState>,
   ) {
     const trackGroupsPlugin = trace.plugins.getPlugin(
       ProcessThreadGroupsPlugin,
@@ -282,7 +281,6 @@
         const group = trackGroupsPlugin.getGroupForProcess(upid);
         if (!group) continue;
 
-        const store = ensureExists(this.store);
         const uri = trackUri(upid, heapType.type);
         const descriptor = profileDescriptor(heapType.type);
         const track: Track = {
@@ -297,10 +295,15 @@
             viewName,
             upid,
             incomplete,
-            store.state[descriptor.type].trackFlamegraphState,
+            storage.get()[descriptor.type]?.trackFlamegraphState,
             (state) => {
-              store.edit((draft) => {
-                draft[descriptor.type].trackFlamegraphState = state;
+              const current = storage.get();
+              storage.set({
+                ...current,
+                [descriptor.type]: {
+                  ...current[descriptor.type],
+                  trackFlamegraphState: state,
+                },
               });
             },
             heapType.type === 'java_heap_graph'
@@ -382,6 +385,7 @@
     trace: Trace,
     descriptor: ProfileDescriptor,
     priority: number,
+    storage: Storage<HeapProfilePluginState>,
   ): AreaSelectionTab {
     // One panel at a time, created for the selection it renders and disposed by
     // the memo as soon as the selection moves on. One memo per registered tab:
@@ -394,7 +398,6 @@
       // "lower first" priority to keep the same order (native before ART).
       priority: -priority,
       render: (selection: AreaSelection) => {
-        const store = ensureExists(this.store);
         const panel = panelMemo.use({
           key: areaSelectionKey(selection),
           compute: () => {
@@ -411,11 +414,15 @@
                   descriptor,
                   selection.start,
                   selection.end,
-                  store.state[descriptor.type].areaSelectionFlamegraphState,
+                  storage.get()[descriptor.type]?.areaSelectionFlamegraphState,
                   (state) => {
-                    store.edit((draft) => {
-                      draft[descriptor.type].areaSelectionFlamegraphState =
-                        state;
+                    const current = storage.get();
+                    storage.set({
+                      ...current,
+                      [descriptor.type]: {
+                        ...current[descriptor.type],
+                        areaSelectionFlamegraphState: state,
+                      },
                     });
                   },
                   /* isAreaSelection= */ true,
diff --git a/ui/src/plugins/dev.perfetto.HeapProfile/storage_schema_unittest.ts b/ui/src/plugins/dev.perfetto.HeapProfile/storage_schema_unittest.ts
new file mode 100644
index 0000000..847820e
--- /dev/null
+++ b/ui/src/plugins/dev.perfetto.HeapProfile/storage_schema_unittest.ts
@@ -0,0 +1,77 @@
+// Copyright (C) 2026 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 {ProfileType} from './common';
+import {HEAP_PROFILE_PLUGIN_STATE_SCHEMA} from './index';
+
+const EMPTY_STATE = {
+  [ProfileType.NATIVE_HEAP_PROFILE]: {},
+  [ProfileType.GENERIC_HEAP_PROFILE]: {},
+  [ProfileType.JAVA_HEAP_SAMPLES]: {},
+  [ProfileType.JAVA_HEAP_GRAPH]: {},
+  [ProfileType.OOME_CALLSTACK]: {},
+};
+
+const TREE_STATE = {
+  selectedMetricId: 'self',
+  addedMetricIds: ['total'],
+  displayMode: 'tree',
+  filters: [{kind: 'SHOW_STACK', filter: 'foo'}],
+  view: {kind: 'TOP_DOWN'},
+};
+
+describe('HEAP_PROFILE_PLUGIN_STATE_SCHEMA', () => {
+  test('accepts the registered default value', () => {
+    expect(HEAP_PROFILE_PLUGIN_STATE_SCHEMA.parse(EMPTY_STATE)).toEqual(
+      EMPTY_STATE,
+    );
+  });
+
+  test('accepts populated flamegraph states', () => {
+    const state = {
+      ...EMPTY_STATE,
+      [ProfileType.NATIVE_HEAP_PROFILE]: {
+        trackFlamegraphState: TREE_STATE,
+        areaSelectionFlamegraphState: TREE_STATE,
+      },
+    };
+    expect(HEAP_PROFILE_PLUGIN_STATE_SCHEMA.parse(state)).toEqual(state);
+  });
+
+  test('accepts state round-tripped through JSON (string keys)', () => {
+    const state = {
+      ...EMPTY_STATE,
+      [ProfileType.JAVA_HEAP_GRAPH]: {trackFlamegraphState: TREE_STATE},
+    };
+    const raw = JSON.parse(JSON.stringify(state));
+    expect(HEAP_PROFILE_PLUGIN_STATE_SCHEMA.parse(raw)).toEqual(state);
+  });
+
+  test('rejects state missing a profile type', () => {
+    const result = HEAP_PROFILE_PLUGIN_STATE_SCHEMA.safeParse({
+      [ProfileType.NATIVE_HEAP_PROFILE]: {},
+    });
+    expect(result.success).toBe(false);
+  });
+
+  test('rejects an invalid tree explorer state', () => {
+    const result = HEAP_PROFILE_PLUGIN_STATE_SCHEMA.safeParse({
+      ...EMPTY_STATE,
+      [ProfileType.NATIVE_HEAP_PROFILE]: {
+        trackFlamegraphState: {...TREE_STATE, filters: 'nope'},
+      },
+    });
+    expect(result.success).toBe(false);
+  });
+});
diff --git a/ui/src/plugins/dev.perfetto.Intelletto/chat_panel.ts b/ui/src/plugins/dev.perfetto.Intelletto/chat_panel.ts
index a3bc344..df3b1cb 100644
--- a/ui/src/plugins/dev.perfetto.Intelletto/chat_panel.ts
+++ b/ui/src/plugins/dev.perfetto.Intelletto/chat_panel.ts
@@ -277,7 +277,7 @@
             (md) => md.provider.id === providerId && md.model.id === modelId,
           );
           if (selected) {
-            onModelChange({providerId, modelId});
+            onModelChange({providerId: providerId!, modelId});
           }
           m.redraw();
         },
diff --git a/ui/src/plugins/dev.perfetto.Intelletto/chat_session.ts b/ui/src/plugins/dev.perfetto.Intelletto/chat_session.ts
index f2e93c0..4333afe 100644
--- a/ui/src/plugins/dev.perfetto.Intelletto/chat_session.ts
+++ b/ui/src/plugins/dev.perfetto.Intelletto/chat_session.ts
@@ -173,7 +173,7 @@
             // Attach the result to the most recent matching tool-call line that
             // doesn't have one yet (tool calls within a round execute in order).
             for (let i = this.lines.length - 1; i >= 0; i--) {
-              const line = this.lines[i];
+              const line = this.lines[i]!;
               if (
                 line.role === 'toolcall' &&
                 line.text === evt.name &&
diff --git a/ui/src/plugins/dev.perfetto.JournaldLog/index.ts b/ui/src/plugins/dev.perfetto.JournaldLog/index.ts
index 24d860d..e748ff7 100644
--- a/ui/src/plugins/dev.perfetto.JournaldLog/index.ts
+++ b/ui/src/plugins/dev.perfetto.JournaldLog/index.ts
@@ -13,84 +13,40 @@
 // limitations under the License.
 
 import m from 'mithril';
-import {
-  type JournaldLogFilteringCriteria,
-  JournaldLogPanel,
-} from './logs_panel';
+import {JOURNALD_FILTER_SCHEMA, JournaldLogPanel} from './logs_panel';
 import type {Trace} from '../../public/trace';
 import type {PerfettoPlugin} from '../../public/plugin';
 import {NUM, STR_NULL} from '../../trace_processor/query_result';
 import {createJournaldLogTrack} from './logs_track';
 import {TrackNode} from '../../public/workspace';
 import {escapeSearchQuery} from '../../trace_processor/query_utils';
-import {exists} from '../../base/utils';
+import {z} from 'zod';
 
-const VERSION = 1;
 const JOURNALD_LOGS_TRACK_KIND = 'JournaldLogTrack';
 
-const DEFAULT_STATE: JournaldLogPluginState = {
-  version: VERSION,
-  filter: {
-    // Show all levels by default (7 = DEBUG, the least severe).
-    minimumLevel: 7,
-    tags: [],
-    isTagRegex: false,
-    textEntry: '',
-    hideNonMatching: true,
-  },
-};
-
-interface JournaldLogPluginState {
-  version: number;
-  filter: JournaldLogFilteringCriteria;
-}
-
-function isJournaldLogFilteringCriteria(
-  value: unknown,
-): value is JournaldLogFilteringCriteria {
-  if (!exists(value) || typeof value !== 'object') {
-    return false;
-  }
-  const candidate = value as Record<string, unknown>;
-  return (
-    typeof candidate.minimumLevel === 'number' &&
-    Array.isArray(candidate.tags) &&
-    candidate.tags.every((tag) => typeof tag === 'string') &&
-    typeof candidate.textEntry === 'string' &&
-    typeof candidate.hideNonMatching === 'boolean' &&
-    (candidate.isTagRegex === undefined ||
-      typeof candidate.isTagRegex === 'boolean')
-  );
-}
-
-function migrateJournaldPluginState(init: unknown): JournaldLogPluginState {
-  if (!exists(init) || typeof init !== 'object') {
-    return DEFAULT_STATE;
-  }
-  const candidate = init as Record<string, unknown>;
-  if (
-    candidate.version === VERSION &&
-    isJournaldLogFilteringCriteria(candidate.filter)
-  ) {
-    return {
-      version: VERSION,
-      filter: candidate.filter,
-    };
-  }
-  return DEFAULT_STATE;
-}
-
-function migrateJournaldFilter(value: unknown): JournaldLogFilteringCriteria {
-  return isJournaldLogFilteringCriteria(value) ? value : DEFAULT_STATE.filter;
-}
+export const JOURNALD_STATE_SCHEMA = z.object({
+  version: z.literal(1), // Version number has to be === 1
+  filter: JOURNALD_FILTER_SCHEMA,
+});
 
 export default class implements PerfettoPlugin {
   static readonly id = 'dev.perfetto.JournaldLog';
   async onTraceLoad(ctx: Trace): Promise<void> {
-    const store = ctx.mountStore<JournaldLogPluginState>(
-      'dev.perfetto.JournaldLogFilterState',
-      migrateJournaldPluginState,
-    );
+    const storage = ctx.registerStorage({
+      id: 'dev.perfetto.JournaldLogFilterState',
+      schema: JOURNALD_STATE_SCHEMA,
+      defaultValue: {
+        version: 1,
+        filter: {
+          // Show all levels by default (7 = DEBUG, the least severe).
+          minimumLevel: 7,
+          tags: [],
+          isTagRegex: false,
+          textEntry: '',
+          hideNonMatching: true,
+        },
+      },
+    });
 
     const result = await ctx.engine.query(`
       INCLUDE PERFETTO MODULE linux.systemd_journald;
@@ -113,13 +69,16 @@
 
     const journaldLogsTabUri = 'perfetto.JournaldLog#tab';
 
-    const filterStore = store.createSubStore(['filter'], migrateJournaldFilter);
-
     ctx.tabs.registerTab({
       isEphemeral: false,
       uri: journaldLogsTabUri,
       content: {
-        render: () => m(JournaldLogPanel, {filterStore, trace: ctx}),
+        render: () =>
+          m(JournaldLogPanel, {
+            trace: ctx,
+            filter: storage.get().filter,
+            onFilterChange: (filter) => storage.set({...storage.get(), filter}),
+          }),
         getTitle: () => 'Journald Logs',
       },
     });
diff --git a/ui/src/plugins/dev.perfetto.JournaldLog/logs_panel.ts b/ui/src/plugins/dev.perfetto.JournaldLog/logs_panel.ts
index c05251d..d5cfbad 100644
--- a/ui/src/plugins/dev.perfetto.JournaldLog/logs_panel.ts
+++ b/ui/src/plugins/dev.perfetto.JournaldLog/logs_panel.ts
@@ -42,27 +42,32 @@
 } from '../../widgets/grid';
 import {classNames} from '../../base/classnames';
 import {TagInput} from '../../widgets/tag_input';
-import type {Store} from '../../base/store';
 import type {Trace} from '../../public/trace';
 import {Icons} from '../../base/semantic_icons';
 import {MenuItem} from '../../widgets/menu';
 import {AtomicTaskQueue, AsyncMemo} from '../../base/async_memo';
 import {Anchor} from '../../widgets/anchor';
 import {getThreadUriPrefix} from '../../public/utils';
+import {z} from 'zod';
 
 const ROW_H = 24;
 
-export interface JournaldLogFilteringCriteria {
-  readonly minimumLevel: number;
-  readonly tags: string[];
-  readonly isTagRegex?: boolean;
-  readonly textEntry: string;
-  readonly hideNonMatching: boolean;
-}
+export const JOURNALD_FILTER_SCHEMA = z.object({
+  minimumLevel: z.number(),
+  tags: z.array(z.string()),
+  isTagRegex: z.boolean().optional(),
+  textEntry: z.string(),
+  hideNonMatching: z.boolean(),
+});
+
+export type JournaldLogFilteringCriteria = z.infer<
+  typeof JOURNALD_FILTER_SCHEMA
+>;
 
 export interface JournaldLogPanelAttrs {
-  readonly filterStore: Store<JournaldLogFilteringCriteria>;
   readonly trace: Trace;
+  readonly filter: JournaldLogFilteringCriteria;
+  readonly onFilterChange: (filter: JournaldLogFilteringCriteria) => void;
 }
 
 interface Pagination {
@@ -119,7 +124,7 @@
 
   view({attrs}: m.CVnode<JournaldLogPanelAttrs>) {
     const visibleSpan = attrs.trace.timeline.visibleWindow.toTimeSpan();
-    const filters = attrs.filterStore.state;
+    const filters = attrs.filter;
     const pagination = this.pagination;
     const engine = attrs.trace.engine;
 
@@ -148,7 +153,8 @@
         title: 'Journald Logs',
         description: `Total messages: ${totalEvents}`,
         buttons: m(LogsFilters, {
-          store: attrs.filterStore,
+          filter: attrs.filter,
+          onFilterChange: attrs.onFilterChange,
         }),
       },
       this.renderGrid(attrs.trace, entries),
@@ -215,10 +221,10 @@
     const trace = this.trace;
     const rows: GridRow[] = [];
     for (let i = 0; i < entries.timestamps.length; i++) {
-      const priority = entries.priorities[i];
+      const priority = entries.priorities[i]!;
       const priorityName = JOURNALD_PRIORITIES[priority] ?? '?';
-      const ts = entries.timestamps[i];
-      const eventId = entries.ids[i];
+      const ts = entries.timestamps[i]!;
+      const eventId = entries.ids[i]!;
       const priorityClass = classForPriority(priority);
       const isHighlighted = entries.isHighlighted[i];
       const className = classNames(
@@ -275,7 +281,7 @@
                 Anchor,
                 {
                   onclick: () => {
-                    const uri = `${getThreadUriPrefix(entries.upids[i], entries.utids[i]!)}_state`;
+                    const uri = `${getThreadUriPrefix(entries.upids[i]!, entries.utids[i]!)}_state`;
                     trace.scrollTo({track: {uri, expandGroup: true}});
                   },
                 },
@@ -386,59 +392,67 @@
 }
 
 interface LogsFiltersAttrs {
-  readonly store: Store<JournaldLogFilteringCriteria>;
+  readonly filter: JournaldLogFilteringCriteria;
+  readonly onFilterChange: (filter: JournaldLogFilteringCriteria) => void;
 }
 
 class LogsFilters implements m.ClassComponent<LogsFiltersAttrs> {
   view({attrs}: m.CVnode<LogsFiltersAttrs>) {
+    const filterState = attrs.filter;
     return [
       m('span', 'Log Level'),
       m(LogPriorityWidget, {
         options: JOURNALD_PRIORITIES,
-        selectedIndex: attrs.store.state.minimumLevel,
+        selectedIndex: filterState.minimumLevel,
         onSelect: (minimumLevel) => {
-          attrs.store.edit((draft) => {
-            draft.minimumLevel = minimumLevel;
+          attrs.onFilterChange({
+            ...attrs.filter,
+            minimumLevel,
           });
         },
       }),
       m(TagInput, {
         leftIcon: 'label',
         placeholder: 'Filter by tag...',
-        tags: attrs.store.state.tags,
+        tags: filterState.tags,
         onTagAdd: (tag) => {
-          attrs.store.edit((draft) => {
-            draft.tags.push(tag);
+          attrs.onFilterChange({
+            ...attrs.filter,
+            tags: [...attrs.filter.tags, tag],
           });
         },
         onTagRemove: (index) => {
-          attrs.store.edit((draft) => {
-            draft.tags.splice(index, 1);
+          attrs.onFilterChange({
+            ...attrs.filter,
+            tags: attrs.filter.tags.filter((_, i) => i !== index),
           });
         },
       }),
       m(Button, {
         icon: 'regular_expression',
         tooltip: 'Use regex',
-        active: !!attrs.store.state.isTagRegex,
+        active: !!filterState.isTagRegex,
         onclick: () => {
-          attrs.store.edit((draft) => {
-            draft.isTagRegex = !draft.isTagRegex;
+          attrs.onFilterChange({
+            ...attrs.filter,
+            isTagRegex: !attrs.filter.isTagRegex,
           });
         },
       }),
       m(LogTextWidget, {
         onChange: (text) => {
-          attrs.store.edit((draft) => {
-            draft.textEntry = text;
+          attrs.onFilterChange({
+            ...attrs.filter,
+            textEntry: text,
           });
         },
       }),
       m(FilterByTextWidget, {
-        hideNonMatching: attrs.store.state.hideNonMatching,
+        hideNonMatching: filterState.hideNonMatching,
         onClick: () => {
-          attrs.store.edit((draft) => {
-            draft.hideNonMatching = !draft.hideNonMatching;
+          attrs.onFilterChange({
+            ...attrs.filter,
+            hideNonMatching: !attrs.filter.hideNonMatching,
           });
         },
       }),
diff --git a/ui/src/plugins/dev.perfetto.JournaldLog/logs_track.ts b/ui/src/plugins/dev.perfetto.JournaldLog/logs_track.ts
index 5a426e3..0c57205 100644
--- a/ui/src/plugins/dev.perfetto.JournaldLog/logs_track.ts
+++ b/ui/src/plugins/dev.perfetto.JournaldLog/logs_track.ts
@@ -84,7 +84,7 @@
       schema: LOGS_SCHEMA,
     }),
     initialMaxDepth: 7,
-    colorizer: (row) => DEPTH_TO_COLOR[row.depth],
+    colorizer: (row) => DEPTH_TO_COLOR[row.depth]!,
     tooltip: (slice) => [m('', m('b', slice.row.tag)), m('', slice.row.msg)],
     instantStyle: {
       width: EVT_PX,
diff --git a/ui/src/plugins/dev.perfetto.JournaldLog/storage_schema_unittest.ts b/ui/src/plugins/dev.perfetto.JournaldLog/storage_schema_unittest.ts
new file mode 100644
index 0000000..08b32e8
--- /dev/null
+++ b/ui/src/plugins/dev.perfetto.JournaldLog/storage_schema_unittest.ts
@@ -0,0 +1,61 @@
+// Copyright (C) 2026 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 {JOURNALD_STATE_SCHEMA} from './index';
+
+describe('JOURNALD_STATE_SCHEMA', () => {
+  test('accepts a fully populated state', () => {
+    const state = {
+      version: 1,
+      filter: {
+        minimumLevel: 3,
+        tags: ['kernel'],
+        isTagRegex: false,
+        textEntry: 'oom',
+        hideNonMatching: false,
+      },
+    };
+    expect(JOURNALD_STATE_SCHEMA.parse(state)).toEqual(state);
+  });
+
+  test('rejects undefined (relies on defaultValue)', () => {
+    expect(JOURNALD_STATE_SCHEMA.safeParse(undefined).success).toBe(false);
+  });
+
+  test('rejects a missing version', () => {
+    const result = JOURNALD_STATE_SCHEMA.safeParse({filter: {}});
+    expect(result.success).toBe(false);
+  });
+
+  test('rejects a partial filter', () => {
+    const result = JOURNALD_STATE_SCHEMA.safeParse({
+      version: 1,
+      filter: {textEntry: 'x'},
+    });
+    expect(result.success).toBe(false);
+  });
+
+  test('rejects wrongly typed fields', () => {
+    const result = JOURNALD_STATE_SCHEMA.safeParse({
+      version: 1,
+      filter: {
+        minimumLevel: 7,
+        tags: 'kernel',
+        textEntry: '',
+        hideNonMatching: true,
+      },
+    });
+    expect(result.success).toBe(false);
+  });
+});
diff --git a/ui/src/plugins/dev.perfetto.Llm/settings_ui.ts b/ui/src/plugins/dev.perfetto.Llm/settings_ui.ts
index 09b09ef..6abe2cd 100644
--- a/ui/src/plugins/dev.perfetto.Llm/settings_ui.ts
+++ b/ui/src/plugins/dev.perfetto.Llm/settings_ui.ts
@@ -119,7 +119,7 @@
               variant: ButtonVariant.Filled,
               onclick: () => {
                 // New providers default to the first registered protocol.
-                const protocol = protocols[0];
+                const protocol = protocols[0]!;
                 update(setting, (ps) => [
                   ...ps,
                   {
diff --git a/ui/src/plugins/dev.perfetto.LlmProtocolChromePrompt/chrome_prompt_protocol.ts b/ui/src/plugins/dev.perfetto.LlmProtocolChromePrompt/chrome_prompt_protocol.ts
index 4f27d65..b9c49a2 100644
--- a/ui/src/plugins/dev.perfetto.LlmProtocolChromePrompt/chrome_prompt_protocol.ts
+++ b/ui/src/plugins/dev.perfetto.LlmProtocolChromePrompt/chrome_prompt_protocol.ts
@@ -183,7 +183,7 @@
 function stripFences(text: string): string {
   const t = text.trim();
   const fence = /^```(?:json)?\s*\n?([\s\S]*?)\n?```$/i.exec(t);
-  return fence ? fence[1].trim() : t;
+  return fence ? fence[1]!.trim() : t;
 }
 
 // Return the first brace-balanced `{...}` substring, ignoring braces inside
diff --git a/ui/src/plugins/dev.perfetto.Memscope/index.ts b/ui/src/plugins/dev.perfetto.Memscope/index.ts
index b1591a4..8d7aa0b 100644
--- a/ui/src/plugins/dev.perfetto.Memscope/index.ts
+++ b/ui/src/plugins/dev.perfetto.Memscope/index.ts
@@ -190,7 +190,7 @@
   if (parts.length === 0) {
     return {tab: 'summary'};
   }
-  const upid = parseInt(parts[0], 10);
+  const upid = parseInt(parts[0]!, 10);
   const tab = parts[1] === 'smaps' ? 'smaps' : 'summary';
   return {
     upid: Number.isNaN(upid) ? Number.NaN : upid,
diff --git a/ui/src/plugins/dev.perfetto.Memscope/utils.ts b/ui/src/plugins/dev.perfetto.Memscope/utils.ts
index 49c3b4d..998b9d5 100644
--- a/ui/src/plugins/dev.perfetto.Memscope/utils.ts
+++ b/ui/src/plugins/dev.perfetto.Memscope/utils.ts
@@ -80,7 +80,7 @@
   const lastColon = fingerprint.lastIndexOf(':');
   if (lastColon === -1) {
     const match = fingerprint.match(/\b(userdebug|eng|user)\b/i);
-    return match ? (match[1].toLowerCase() as AndroidBuildVariant) : 'unknown';
+    return match ? (match[1]!.toLowerCase() as AndroidBuildVariant) : 'unknown';
   }
 
   const rest = fingerprint.substring(lastColon + 1);
diff --git a/ui/src/plugins/dev.perfetto.Memscope/views/connection.ts b/ui/src/plugins/dev.perfetto.Memscope/views/connection.ts
index 7694195..39fba8e 100644
--- a/ui/src/plugins/dev.perfetto.Memscope/views/connection.ts
+++ b/ui/src/plugins/dev.perfetto.Memscope/views/connection.ts
@@ -385,7 +385,7 @@
       if (line === '') continue;
       const match = line.match(/^([^\s]+)\s+.*model:([^ ]+)/);
       if (!match) continue;
-      devices.push({serial: match[1], model: match[2]});
+      devices.push({serial: match[1]!, model: match[2]!});
     }
 
     this.wsDevices = devices;
diff --git a/ui/src/plugins/dev.perfetto.Memscope/views/dashboard.ts b/ui/src/plugins/dev.perfetto.Memscope/views/dashboard.ts
index adc9401..bea435f 100644
--- a/ui/src/plugins/dev.perfetto.Memscope/views/dashboard.ts
+++ b/ui/src/plugins/dev.perfetto.Memscope/views/dashboard.ts
@@ -340,7 +340,7 @@
         const s = chartData.series.find(
           (sr: LineChartSeries) => sr.name === name,
         );
-        return s !== undefined && s.points.length > 0 ? s.points[0].y : 0;
+        return s !== undefined && s.points.length > 0 ? s.points[0]!.y : 0;
       };
       this.profileBaseline = {
         anonSwap: first('RSS Anon + Swap'),
diff --git a/ui/src/plugins/dev.perfetto.Memscope/views/landing_page/proc_mem_overview.ts b/ui/src/plugins/dev.perfetto.Memscope/views/landing_page/proc_mem_overview.ts
index 5ca7699..8edd12c 100644
--- a/ui/src/plugins/dev.perfetto.Memscope/views/landing_page/proc_mem_overview.ts
+++ b/ui/src/plugins/dev.perfetto.Memscope/views/landing_page/proc_mem_overview.ts
@@ -310,8 +310,8 @@
       compute: () => loadGrowthData(trace, upid),
     }).data;
     if (snaps === undefined || snaps.length < 2) return undefined;
-    const firstSnap = snaps[0];
-    const lastSnap = snaps[snaps.length - 1];
+    const firstSnap = snaps[0]!;
+    const lastSnap = snaps[snaps.length - 1]!;
     // Selected endpoint (nearest snapshot), or the latest when unselected.
     const sel = selTs !== undefined ? nearestByTs(snaps, selTs)! : lastSnap;
     // Baseline endpoint: an explicit baseline (when diffing), otherwise the
diff --git a/ui/src/plugins/dev.perfetto.Memscope/views/landing_page/section_widgets.ts b/ui/src/plugins/dev.perfetto.Memscope/views/landing_page/section_widgets.ts
index b54223e..b2b2394 100644
--- a/ui/src/plugins/dev.perfetto.Memscope/views/landing_page/section_widgets.ts
+++ b/ui/src/plugins/dev.perfetto.Memscope/views/landing_page/section_widgets.ts
@@ -115,7 +115,7 @@
           m(
             'tr',
             cells.map((cell, i) =>
-              m(opts.cols[i].num ? 'td.pf-memscope-table__num' : 'td', cell),
+              m(opts.cols[i]!.num ? 'td.pf-memscope-table__num' : 'td', cell),
             ),
           ),
         ),
diff --git a/ui/src/plugins/dev.perfetto.Memscope/views/landing_page/selection.ts b/ui/src/plugins/dev.perfetto.Memscope/views/landing_page/selection.ts
index 2881b9f..71a3bc4 100644
--- a/ui/src/plugins/dev.perfetto.Memscope/views/landing_page/selection.ts
+++ b/ui/src/plugins/dev.perfetto.Memscope/views/landing_page/selection.ts
@@ -34,7 +34,7 @@
 ): T | undefined {
   if (rows.length === 0) return undefined;
   if (ts === undefined) return rows[rows.length - 1];
-  let best = rows[0];
+  let best = rows[0]!;
   let bestDist = ts > best.ts ? ts - best.ts : best.ts - ts;
   for (const r of rows) {
     const dist = ts > r.ts ? ts - r.ts : r.ts - ts;
diff --git a/ui/src/plugins/dev.perfetto.Memscope/views/landing_page/smaps_detail.ts b/ui/src/plugins/dev.perfetto.Memscope/views/landing_page/smaps_detail.ts
index bba8ef4..29371dd 100644
--- a/ui/src/plugins/dev.perfetto.Memscope/views/landing_page/smaps_detail.ts
+++ b/ui/src/plugins/dev.perfetto.Memscope/views/landing_page/smaps_detail.ts
@@ -468,7 +468,7 @@
                 {
                   // Default to the latest snapshot when nothing is picked.
                   value: (
-                    this.selectedTs ?? snapshots[snapshots.length - 1].ts
+                    this.selectedTs ?? snapshots[snapshots.length - 1]!.ts
                   ).toString(),
                   onchange: (e: Event) => {
                     const v = (e.target as HTMLSelectElement).value;
diff --git a/ui/src/plugins/dev.perfetto.Memscope/views/landing_page/summary/bitmaps_section.ts b/ui/src/plugins/dev.perfetto.Memscope/views/landing_page/summary/bitmaps_section.ts
index 4de9ecf..024d4db 100644
--- a/ui/src/plugins/dev.perfetto.Memscope/views/landing_page/summary/bitmaps_section.ts
+++ b/ui/src/plugins/dev.perfetto.Memscope/views/landing_page/summary/bitmaps_section.ts
@@ -329,7 +329,7 @@
     const bySize = dims.slice().sort((a, b) => b.bytes - a.bytes);
     const byCount = dims.slice().sort((a, b) => b.count - a.count);
     const hasDims = dims.some((d) => d.key !== 'unknown');
-    const largest = bySize[0];
+    const largest = bySize[0]!;
 
     const javaRetained = data.javaRetainedByTs.get(cur.ts) ?? 0;
     // Bitmap heap-self + registered-native bytes (excludes the estimated ashmem
diff --git a/ui/src/plugins/dev.perfetto.Memscope/views/landing_page/summary/composition_timeline.ts b/ui/src/plugins/dev.perfetto.Memscope/views/landing_page/summary/composition_timeline.ts
index a20e965..02106c9 100644
--- a/ui/src/plugins/dev.perfetto.Memscope/views/landing_page/summary/composition_timeline.ts
+++ b/ui/src/plugins/dev.perfetto.Memscope/views/landing_page/summary/composition_timeline.ts
@@ -100,14 +100,14 @@
     let baseIdx =
       selection?.base !== undefined ? idxOfTs(selection.base) : undefined;
     if (baseIdx === selIdx) baseIdx = undefined;
-    const snap = snaps[selIdx];
+    const snap = snaps[selIdx]!;
     const base = baseIdx !== undefined ? snaps[baseIdx] : undefined;
 
     // Index of the snapshot whose x is closest to a clicked/brushed time.
     const nearestSnap = (x: number) => {
       let bestIdx = 0;
       for (let i = 1; i < snaps.length; i++) {
-        if (Math.abs(snaps[i].x - x) < Math.abs(snaps[bestIdx].x - x)) {
+        if (Math.abs(snaps[i]!.x - x) < Math.abs(snaps[bestIdx]!.x - x)) {
           bestIdx = i;
         }
       }
@@ -174,15 +174,15 @@
             selection:
               base !== undefined ? {start: base.x, end: snap.x} : undefined,
             onPointClick: (x: number) => {
-              onSelect({sel: snaps[nearestSnap(x)].ts});
+              onSelect({sel: snaps[nearestSnap(x)]!.ts});
             },
             onBrush: ({start, end}: {start: number; end: number}) => {
               const a = nearestSnap(start);
               const b = nearestSnap(end);
               onSelect(
                 a === b
-                  ? {sel: snaps[a].ts}
-                  : {sel: snaps[b].ts, base: snaps[a].ts},
+                  ? {sel: snaps[a]!.ts}
+                  : {sel: snaps[b]!.ts, base: snaps[a]!.ts},
               );
             },
           }),
diff --git a/ui/src/plugins/dev.perfetto.Memscope/views/landing_page/summary/java_section.ts b/ui/src/plugins/dev.perfetto.Memscope/views/landing_page/summary/java_section.ts
index de2d788..c954019 100644
--- a/ui/src/plugins/dev.perfetto.Memscope/views/landing_page/summary/java_section.ts
+++ b/ui/src/plugins/dev.perfetto.Memscope/views/landing_page/summary/java_section.ts
@@ -404,7 +404,7 @@
     // Drop trailing owners that are tiny next to the class's biggest one; the
     // SQL already ordered each list largest-first.
     for (const [cls, list] of retainerOf) {
-      const cutoff = list[0].bytes * RETAINER_MIN_SHARE;
+      const cutoff = list[0]!.bytes * RETAINER_MIN_SHARE;
       retainerOf.set(
         cls,
         list.filter((r) => r.bytes >= cutoff),
diff --git a/ui/src/plugins/dev.perfetto.Memscope/views/landing_page/summary/memory_map.ts b/ui/src/plugins/dev.perfetto.Memscope/views/landing_page/summary/memory_map.ts
index cfbdfc2..44fc83c 100644
--- a/ui/src/plugins/dev.perfetto.Memscope/views/landing_page/summary/memory_map.ts
+++ b/ui/src/plugins/dev.perfetto.Memscope/views/landing_page/summary/memory_map.ts
@@ -225,8 +225,8 @@
       },
     }).data?.tree;
 
-    const first = snaps[0];
-    const last = snaps[snaps.length - 1];
+    const first = snaps[0]!;
+    const last = snaps[snaps.length - 1]!;
     // Insight: biggest slice of the latest snapshot + fastest-growing slice.
     const catVal = (s: MemSnapshot, key: string) => {
       const r = s.byCategory.get(key);
@@ -536,7 +536,7 @@
     seg(
       b.label,
       bucketTotal > 0
-        ? (bucketBytes[i] / bucketTotal) * fileBytes
+        ? (bucketBytes[i]! / bucketTotal) * fileBytes
         : b.key === 'other_file'
           ? fileBytes
           : 0,
diff --git a/ui/src/plugins/dev.perfetto.Memscope/views/landing_page/summary/native_section.ts b/ui/src/plugins/dev.perfetto.Memscope/views/landing_page/summary/native_section.ts
index fcf6bc0..dfeaa2f 100644
--- a/ui/src/plugins/dev.perfetto.Memscope/views/landing_page/summary/native_section.ts
+++ b/ui/src/plugins/dev.perfetto.Memscope/views/landing_page/summary/native_section.ts
@@ -308,7 +308,7 @@
 function stackSnippet(frames: string[]): string[] {
   if (frames.length === 0) return ['(no app frames)'];
   if (frames.length <= 7) return frames;
-  const leaf = frames[0];
+  const leaf = frames[0]!;
   const middle = frames.slice(1, -2).slice(0, 4);
   const root = frames.slice(-2);
   return [leaf, ...middle, '…', ...root];
diff --git a/ui/src/plugins/dev.perfetto.Memscope/views/profile_page.ts b/ui/src/plugins/dev.perfetto.Memscope/views/profile_page.ts
index ac15aca..844b853 100644
--- a/ui/src/plugins/dev.perfetto.Memscope/views/profile_page.ts
+++ b/ui/src/plugins/dev.perfetto.Memscope/views/profile_page.ts
@@ -159,7 +159,7 @@
   const latest = (name: string): number => {
     const s = chartData.series.find((sr) => sr.name === name);
     if (s === undefined || s.points.length === 0) return 0;
-    return s.points[s.points.length - 1].y;
+    return s.points[s.points.length - 1]!.y;
   };
 
   const card = (
diff --git a/ui/src/plugins/dev.perfetto.Memscope/views/tabs/page_cache.ts b/ui/src/plugins/dev.perfetto.Memscope/views/tabs/page_cache.ts
index 3ba7bbf..291ea4e 100644
--- a/ui/src/plugins/dev.perfetto.Memscope/views/tabs/page_cache.ts
+++ b/ui/src/plugins/dev.perfetto.Memscope/views/tabs/page_cache.ts
@@ -197,8 +197,8 @@
   if (data === undefined || data.series.length < 4) return undefined;
   // Series order: Mapped+Dirty, Mapped+Clean, Unmapped+Dirty, Unmapped+Clean
   const last = (idx: number) => {
-    const pts = data.series[idx].points;
-    return pts.length > 0 ? pts[pts.length - 1].y : 0;
+    const pts = data.series[idx]!.points;
+    return pts.length > 0 ? pts[pts.length - 1]!.y : 0;
   };
   const mappedDirty = last(0);
   const mappedClean = last(1);
diff --git a/ui/src/plugins/dev.perfetto.Memscope/views/tabs/pressure_swap.ts b/ui/src/plugins/dev.perfetto.Memscope/views/tabs/pressure_swap.ts
index e530861..db44072 100644
--- a/ui/src/plugins/dev.perfetto.Memscope/views/tabs/pressure_swap.ts
+++ b/ui/src/plugins/dev.perfetto.Memscope/views/tabs/pressure_swap.ts
@@ -95,7 +95,7 @@
   }
   if (byTs.size < 2) return undefined;
   const timestamps = [...byTs.keys()].sort((a, b) => a - b);
-  if ((byTs.get(timestamps[0])?.get('SwapTotal') ?? 0) === 0) return undefined;
+  if ((byTs.get(timestamps[0]!)?.get('SwapTotal') ?? 0) === 0) return undefined;
   const dirtyPts: {x: number; y: number}[] = [];
   const cachedPts: {x: number; y: number}[] = [];
   const freePts: {x: number; y: number}[] = [];
diff --git a/ui/src/plugins/dev.perfetto.Memscope/views/tabs/processes.ts b/ui/src/plugins/dev.perfetto.Memscope/views/tabs/processes.ts
index ba32975..4aa98fc 100644
--- a/ui/src/plugins/dev.perfetto.Memscope/views/tabs/processes.ts
+++ b/ui/src/plugins/dev.perfetto.Memscope/views/tabs/processes.ts
@@ -67,8 +67,8 @@
   if (values.length < 2) {
     return m('span.pf-memscope-sparkline-empty', '—');
   }
-  let min = values[0];
-  let max = values[0];
+  let min = values[0]!;
+  let max = values[0]!;
   for (const v of values) {
     if (v < min) min = v;
     if (v > max) max = v;
@@ -84,8 +84,8 @@
       return `${x},${y}`;
     })
     .join(' ');
-  const last = values[values.length - 1];
-  const first = values[0];
+  const last = values[values.length - 1]!;
+  const first = values[0]!;
   const stroke =
     last > first
       ? 'var(--pf-color-danger)'
@@ -225,7 +225,7 @@
   for (let i = 0; i < OOM_SCORE_BUCKETS.length; i++) {
     const points = pointsByBucket.get(i)!;
     if (points.some((p) => p.y > 0)) {
-      const bucket = OOM_SCORE_BUCKETS[i];
+      const bucket = OOM_SCORE_BUCKETS[i]!;
       series.push({name: bucket.name, points, color: chipColor(bucket.color)});
     }
   }
@@ -295,7 +295,7 @@
   if (rest.length > 0) {
     const otherPoints = timestamps.map((ts, i) => ({
       x: (ts - t0) / 1e9,
-      y: rest.reduce((sum, r) => sum + r.points[i].y, 0),
+      y: rest.reduce((sum, r) => sum + r.points[i]!.y, 0),
     }));
     series.push({
       name: `Other (${rest.length} processes)`,
@@ -328,7 +328,7 @@
   t0: number,
   counters: readonly string[],
 ): LineChartData | undefined {
-  const bucket = OOM_SCORE_BUCKETS[bucketIdx];
+  const bucket = OOM_SCORE_BUCKETS[bucketIdx]!;
   const oomByUpid = new Map<number, number>();
   for (const [upid, counterMap] of data.processCountersByUpid) {
     const samples = counterMap.get('oom_score_adj');
diff --git a/ui/src/plugins/dev.perfetto.Memscope/views/tabs/system.ts b/ui/src/plugins/dev.perfetto.Memscope/views/tabs/system.ts
index 99ed261..6b64df5 100644
--- a/ui/src/plugins/dev.perfetto.Memscope/views/tabs/system.ts
+++ b/ui/src/plugins/dev.perfetto.Memscope/views/tabs/system.ts
@@ -171,7 +171,7 @@
   const getLatest = (name: string): number => {
     const arr = data.systemCounters.get(name);
     if (arr === undefined || arr.length === 0) return 0;
-    return Math.round(arr[arr.length - 1].value / 1024);
+    return Math.round(arr[arr.length - 1]!.value / 1024);
   };
   const totalKb = getLatest('MemTotal');
   if (totalKb === 0) return undefined;
diff --git a/ui/src/plugins/dev.perfetto.MetricsPage/metrics_page.ts b/ui/src/plugins/dev.perfetto.MetricsPage/metrics_page.ts
index 2d71f4a..c5982e5 100644
--- a/ui/src/plugins/dev.perfetto.MetricsPage/metrics_page.ts
+++ b/ui/src/plugins/dev.perfetto.MetricsPage/metrics_page.ts
@@ -270,14 +270,14 @@
 
       // Add dimensions
       for (let i = 0; i < dimensionNames.length; i++) {
-        const dimName = dimensionNames[i];
+        const dimName = dimensionNames[i]!;
         const dimValue = row.dimension?.[i];
         rowData[dimName] = dimValue ? getDimensionValue(dimValue) : null;
       }
 
       // Add all values (templates can have multiple value columns)
       for (let i = 0; i < valueNames.length; i++) {
-        const valueName = valueNames[i];
+        const valueName = valueNames[i]!;
         const val = row.values?.[i];
         rowData[valueName] = val ? getMetricValue(val) : null;
       }
diff --git a/ui/src/plugins/dev.perfetto.ProcessSummary/group_summary_track.ts b/ui/src/plugins/dev.perfetto.ProcessSummary/group_summary_track.ts
index 23cca02..30ff365 100644
--- a/ui/src/plugins/dev.perfetto.ProcessSummary/group_summary_track.ts
+++ b/ui/src/plugins/dev.perfetto.ProcessSummary/group_summary_track.ts
@@ -113,10 +113,10 @@
   const t = timescale.pxToHpTime(x).toTime('floor');
 
   const [i, j] = searchRange(data.starts, t, searchEq(data.lanes, lane));
-  if (i === j || i >= data.starts.length || t > data.ends[i]) return undefined;
+  if (i === j || i >= data.starts.length || t > data.ends[i]!) return undefined;
 
-  const utid = data.utids[i];
-  const count = data.counts[i];
+  const utid = data.utids[i]!;
+  const count = data.counts[i]!;
   const pid = threads.get(utid)?.pid;
   return {utid, lane, count, pid};
 }
@@ -284,7 +284,7 @@
       } else {
         // Not valid - traverse children
         for (let i = node.children.length - 1; i >= 0; i--) {
-          stack.push(node.children[i]);
+          stack.push(node.children[i]!);
         }
       }
     }
@@ -399,8 +399,8 @@
         }
       }
 
-      const ts = it.ts[row];
-      const dur = it.dur[row];
+      const ts = it.ts[row]!;
+      const dur = it.dur[row]!;
       const endTs = ts + dur;
 
       ends[row] = endTs;
@@ -413,7 +413,7 @@
 
       // Cache color scheme for 'sched' mode (depends on utid).
       if (this.mode === 'sched') {
-        const threadInfo = this.threads.get(it.utid[row]);
+        const threadInfo = this.threads.get(it.utid[row]!);
         colorSchemes[row] = colorForThread(threadInfo);
       }
     }
@@ -510,7 +510,7 @@
         return undefined;
       }
 
-      const trackUri = this.sliceTracks[laneIndex].uri;
+      const trackUri = this.sliceTracks[laneIndex]!.uri;
       const track = this.trace.tracks.getTrack(trackUri);
       const trackTitle = (track as {title?: string})?.title ?? trackUri;
 
@@ -601,8 +601,8 @@
     if (this.mode === 'sched') {
       const isHovering = timeline.hoveredUtid !== undefined;
       for (let i = 0; i < count; i++) {
-        const colorScheme = data.colorSchemes[i];
-        const utid = data.utids[i];
+        const colorScheme = data.colorSchemes[i]!;
+        const utid = data.utids[i]!;
         const threadInfo = this.threads.get(utid);
         // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
         const pid = (threadInfo ? threadInfo.pid : -1) || -1;
diff --git a/ui/src/plugins/dev.perfetto.QueryPage/index.ts b/ui/src/plugins/dev.perfetto.QueryPage/index.ts
index 31ff357..5ae437b 100644
--- a/ui/src/plugins/dev.perfetto.QueryPage/index.ts
+++ b/ui/src/plugins/dev.perfetto.QueryPage/index.ts
@@ -207,7 +207,7 @@
       persistedState &&
       editorTabs.some((t) => t.id === persistedState.activeTabId)
         ? persistedState.activeTabId
-        : editorTabs[0].id;
+        : editorTabs[0]!.id;
 
     // Helper to find the active tab
     function getActiveTab(): QueryEditorTab | undefined {
@@ -256,7 +256,7 @@
       // If we closed the active tab, switch to an adjacent one
       if (activeTabId === tabId) {
         const newIndex = Math.min(index, editorTabs.length - 1);
-        activeTabId = editorTabs[newIndex].id;
+        activeTabId = editorTabs[newIndex]!.id;
       }
 
       debouncedSave();
@@ -298,14 +298,14 @@
       // Find where to insert it
       if (beforeTabId === undefined) {
         // Insert at the end
-        editorTabs.push(draggedTab);
+        editorTabs.push(draggedTab!);
       } else {
         const beforeIndex = editorTabs.findIndex((t) => t.id === beforeTabId);
         if (beforeIndex === -1) {
           // beforeTabId not found, insert at end
-          editorTabs.push(draggedTab);
+          editorTabs.push(draggedTab!);
         } else {
-          editorTabs.splice(beforeIndex, 0, draggedTab);
+          editorTabs.splice(beforeIndex, 0, draggedTab!);
         }
       }
 
diff --git a/ui/src/plugins/dev.perfetto.QueryPage/results_table.ts b/ui/src/plugins/dev.perfetto.QueryPage/results_table.ts
index be950ab..959894d 100644
--- a/ui/src/plugins/dev.perfetto.QueryPage/results_table.ts
+++ b/ui/src/plugins/dev.perfetto.QueryPage/results_table.ts
@@ -100,7 +100,7 @@
  */
 export class ResultsTable implements m.Component<ResultsTableAttrs> {
   // The selected table for linking ID column values.
-  private selectedIdTable = ID_TABLE_OPTIONS[0].sqlTable;
+  private selectedIdTable = ID_TABLE_OPTIONS[0]!.sqlTable;
 
   // DataSource backing the grid. Built lazily from the result rows  and cached
   // for the lifetime of this instance.
diff --git a/ui/src/plugins/dev.perfetto.QueryPage/table_list_unittest.ts b/ui/src/plugins/dev.perfetto.QueryPage/table_list_unittest.ts
index d7983f3..3dde29c 100644
--- a/ui/src/plugins/dev.perfetto.QueryPage/table_list_unittest.ts
+++ b/ui/src/plugins/dev.perfetto.QueryPage/table_list_unittest.ts
@@ -102,9 +102,9 @@
     // "Cannot read properties of null (reading 'tag')" as the fuzzy results
     // reordered on each keystroke. Both entries must still render.
     const names = makeNames();
-    names.splice(15, 0, names[3]);
-    names.splice(40, 0, names[3]);
-    names.splice(70, 0, names[8]);
+    names.splice(15, 0, names[3]!);
+    names.splice(40, 0, names[3]!);
+    names.splice(70, 0, names[8]!);
 
     const sqlModules = makeSqlModules(names);
     const comp = {view: () => m(TableList, {sqlModules})};
diff --git a/ui/src/plugins/dev.perfetto.RecordTraceV2/adb/adb_msg.ts b/ui/src/plugins/dev.perfetto.RecordTraceV2/adb/adb_msg.ts
index 668e3ec..52516ea 100644
--- a/ui/src/plugins/dev.perfetto.RecordTraceV2/adb/adb_msg.ts
+++ b/ui/src/plugins/dev.perfetto.RecordTraceV2/adb/adb_msg.ts
@@ -88,7 +88,7 @@
 
 function generateChecksum(data: Uint8Array): number {
   let res = 0;
-  for (let i = 0; i < data.byteLength; i++) res += data[i];
+  for (let i = 0; i < data.byteLength; i++) res += data[i]!;
   return res & 0xffffffff;
 }
 
diff --git a/ui/src/plugins/dev.perfetto.RecordTraceV2/adb/websocket/adb_websocket_target_provider.ts b/ui/src/plugins/dev.perfetto.RecordTraceV2/adb/websocket/adb_websocket_target_provider.ts
index 38a75d1..2b2bdd1 100644
--- a/ui/src/plugins/dev.perfetto.RecordTraceV2/adb/websocket/adb_websocket_target_provider.ts
+++ b/ui/src/plugins/dev.perfetto.RecordTraceV2/adb/websocket/adb_websocket_target_provider.ts
@@ -85,8 +85,8 @@
         console.warn('Could not parse ADB device', line);
         continue;
       }
-      const serial = m[1];
-      const model = m[2];
+      const serial = m[1]!;
+      const model = m[2]!;
       devices.set(serial, model);
     }
     return devices;
diff --git a/ui/src/plugins/dev.perfetto.RecordTraceV2/adb/webusb/adb_webusb_device.ts b/ui/src/plugins/dev.perfetto.RecordTraceV2/adb/webusb/adb_webusb_device.ts
index 5ae31a4..1bebbc3 100644
--- a/ui/src/plugins/dev.perfetto.RecordTraceV2/adb/webusb/adb_webusb_device.ts
+++ b/ui/src/plugins/dev.perfetto.RecordTraceV2/adb/webusb/adb_webusb_device.ts
@@ -310,10 +310,10 @@
     remoteStreamId: number,
   ): TxQueueEntry {
     for (let i = 0; i < this.txQueue.length; i++) {
-      const tx = this.txQueue[i];
+      const tx = this.txQueue[i]!;
       if (tx.stream.localId !== localStreamId) continue;
       if (tx.stream.remoteId !== remoteStreamId) continue;
-      return this.txQueue.splice(i, 1)[0];
+      return this.txQueue.splice(i, 1)[0]!;
     }
     throw new WebusbTransportError(
       `Could not find ADB queue entry L=${localStreamId}, ` +
diff --git a/ui/src/plugins/dev.perfetto.RecordTraceV2/config/config_manager_unittest.ts b/ui/src/plugins/dev.perfetto.RecordTraceV2/config/config_manager_unittest.ts
index 5abda68..99aef77 100644
--- a/ui/src/plugins/dev.perfetto.RecordTraceV2/config/config_manager_unittest.ts
+++ b/ui/src/plugins/dev.perfetto.RecordTraceV2/config/config_manager_unittest.ts
@@ -148,7 +148,7 @@
   // dependency of cpu_sched) and nothing restored its settings.
   it('restores the settings of the probes not in the loaded config', () => {
     const cfgMgr = newConfigManager();
-    const defaultPreset = ANDROID_PRESETS[0];
+    const defaultPreset = ANDROID_PRESETS[0]!;
     cfgMgr.deserializeProbes(probesOf(defaultPreset));
     const pristine = dumpAllSettings(cfgMgr);
 
diff --git a/ui/src/plugins/dev.perfetto.RecordTraceV2/pages/advanced.ts b/ui/src/plugins/dev.perfetto.RecordTraceV2/pages/advanced.ts
index 1380ec0..e7c61c5 100644
--- a/ui/src/plugins/dev.perfetto.RecordTraceV2/pages/advanced.ts
+++ b/ui/src/plugins/dev.perfetto.RecordTraceV2/pages/advanced.ts
@@ -158,8 +158,8 @@
       // Set to 1/16th of the main buffer size, with reasonable limits.
       const minMax = [256, 8 * 1024];
       const bufSizeKb = Math.min(
-        Math.max(tc.defaultBuffer.sizeKb / 16, minMax[0]),
-        minMax[1],
+        Math.max(tc.defaultBuffer.sizeKb / 16, minMax[0]!),
+        minMax[1]!,
       );
       tc.addBuffer(ADV_PROC_ASSOC_BUF_ID, bufSizeKb);
 
diff --git a/ui/src/plugins/dev.perfetto.RecordTraceV2/pages/target_selection_page.ts b/ui/src/plugins/dev.perfetto.RecordTraceV2/pages/target_selection_page.ts
index 3597f50..45fc22c 100644
--- a/ui/src/plugins/dev.perfetto.RecordTraceV2/pages/target_selection_page.ts
+++ b/ui/src/plugins/dev.perfetto.RecordTraceV2/pages/target_selection_page.ts
@@ -576,7 +576,7 @@
           {
             onchange: (e: Event) => {
               const idx = (e.target as HTMLSelectElement).selectedIndex;
-              recMgr.setTarget(this.targets[idx]);
+              recMgr.setTarget(this.targets[idx]!);
               m.redraw();
             },
           },
diff --git a/ui/src/plugins/dev.perfetto.RecordTraceV2/pages/widgets/dropdown.ts b/ui/src/plugins/dev.perfetto.RecordTraceV2/pages/widgets/dropdown.ts
index a663d6a..930c7c3 100644
--- a/ui/src/plugins/dev.perfetto.RecordTraceV2/pages/widgets/dropdown.ts
+++ b/ui/src/plugins/dev.perfetto.RecordTraceV2/pages/widgets/dropdown.ts
@@ -37,7 +37,7 @@
   }
 
   private defaultValue(): T {
-    return this.attrs.defaultValue ?? this.attrs.options[0].value;
+    return this.attrs.defaultValue ?? this.attrs.options[0]!.value;
   }
 
   serialize() {
diff --git a/ui/src/plugins/dev.perfetto.RecordTraceV2/pages/widgets/slider.ts b/ui/src/plugins/dev.perfetto.RecordTraceV2/pages/widgets/slider.ts
index 00f6d8f..7840e30 100644
--- a/ui/src/plugins/dev.perfetto.RecordTraceV2/pages/widgets/slider.ts
+++ b/ui/src/plugins/dev.perfetto.RecordTraceV2/pages/widgets/slider.ts
@@ -76,7 +76,7 @@
   }
 
   onSliderChange(newIdx: number) {
-    this.onValueChange(this.attrs.values[newIdx]);
+    this.onValueChange(this.attrs.values[newIdx]!);
   }
 
   render() {
@@ -93,7 +93,7 @@
 
     // Find the index of the closest value in the slider.
     let idx = 0;
-    for (; idx < attrs.values.length && attrs.values[idx] < val; idx++) {}
+    for (; idx < attrs.values.length && attrs.values[idx]! < val; idx++) {}
 
     let spinnerCfg = {};
     if (attrs.isTime) {
diff --git a/ui/src/plugins/dev.perfetto.RecordTraceV2/recording_manager.ts b/ui/src/plugins/dev.perfetto.RecordTraceV2/recording_manager.ts
index e5cc238..abb0d46 100644
--- a/ui/src/plugins/dev.perfetto.RecordTraceV2/recording_manager.ts
+++ b/ui/src/plugins/dev.perfetto.RecordTraceV2/recording_manager.ts
@@ -262,9 +262,9 @@
     const presets = getPresetsForPlatform(this.currentPlatform);
     if (presets.length > 0) {
       this.loadConfig({
-        config: presets[0].session,
-        configId: `preset:${presets[0].id}`,
-        configName: presets[0].title,
+        config: presets[0]!.session,
+        configId: `preset:${presets[0]!.id}`,
+        configName: presets[0]!.title,
       });
     } else {
       this.clearSession();
diff --git a/ui/src/plugins/dev.perfetto.Sched/cpu_slice_track.ts b/ui/src/plugins/dev.perfetto.Sched/cpu_slice_track.ts
index 036eb08..a6f4a8b 100644
--- a/ui/src/plugins/dev.perfetto.Sched/cpu_slice_track.ts
+++ b/ui/src/plugins/dev.perfetto.Sched/cpu_slice_track.ts
@@ -117,7 +117,7 @@
       const variants = new Array<ColorVariant>(n);
 
       for (let i = 0; i < n; ++i) {
-        const row = slices[i].row;
+        const row = slices[i]!.row;
         const isThreadHovered = hoveredUtid === row.utid;
         const isProcessHovered = hoveredPid === row.pid;
 
diff --git a/ui/src/plugins/dev.perfetto.Sched/thread_state_details_panel.ts b/ui/src/plugins/dev.perfetto.Sched/thread_state_details_panel.ts
index ddf8824..c753999 100644
--- a/ui/src/plugins/dev.perfetto.Sched/thread_state_details_panel.ts
+++ b/ui/src/plugins/dev.perfetto.Sched/thread_state_details_panel.ts
@@ -278,7 +278,7 @@
       if (related.wakee === undefined || related.wakee.length == 0) {
         return null;
       }
-      const hasInterruptCtx = related.wakee[0].wakerInterruptCtx !== undefined;
+      const hasInterruptCtx = related.wakee[0]!.wakerInterruptCtx !== undefined;
       return m(
         TreeNode,
         {
diff --git a/ui/src/plugins/dev.perfetto.SqlModules/sql_modules_from_tp.ts b/ui/src/plugins/dev.perfetto.SqlModules/sql_modules_from_tp.ts
index 0488bdd..6b5a732 100644
--- a/ui/src/plugins/dev.perfetto.SqlModules/sql_modules_from_tp.ts
+++ b/ui/src/plugins/dev.perfetto.SqlModules/sql_modules_from_tp.ts
@@ -85,8 +85,8 @@
     name: e.name,
     type: e.type,
     desc: e.description,
-    table: m ? m[1] : null,
-    column: m ? m[2] : null,
+    table: m ? m[1]! : null,
+    column: m ? m[2]! : null,
   };
 }
 
diff --git a/ui/src/plugins/dev.perfetto.SqlModules/sql_modules_from_tp_unittest.ts b/ui/src/plugins/dev.perfetto.SqlModules/sql_modules_from_tp_unittest.ts
index 924f49b..d4dbbe7 100644
--- a/ui/src/plugins/dev.perfetto.SqlModules/sql_modules_from_tp_unittest.ts
+++ b/ui/src/plugins/dev.perfetto.SqlModules/sql_modules_from_tp_unittest.ts
@@ -171,14 +171,14 @@
 
   expect(queries).toHaveLength(1);
   expect(queries[0]).toContain('FROM __intrinsic_stdlib_objects');
-  const module = sqlModules.listModules()[0];
+  const module = sqlModules.listModules()[0]!;
   expect(module.includeKey).toBe('test.module');
   expect(module.tables.map((table) => table.name)).toEqual(['test_table']);
-  expect(module.tables[0].importance).toBe('high');
-  expect(module.tables[0].columns[0].name).toBe('value');
-  expect(module.functions[0].name).toBe('test_function');
-  expect(module.functions[0].returnType).toBe('LONG');
-  expect(module.tableFunctions[0].name).toBe('test_table_function');
-  expect(module.tableFunctions[0].returnCols[0].name).toBe('output');
-  expect(module.macros[0].name).toBe('test_macro');
+  expect(module.tables[0]!.importance).toBe('high');
+  expect(module.tables[0]!.columns[0]!.name).toBe('value');
+  expect(module.functions[0]!.name).toBe('test_function');
+  expect(module.functions[0]!.returnType).toBe('LONG');
+  expect(module.tableFunctions[0]!.name).toBe('test_table_function');
+  expect(module.tableFunctions[0]!.returnCols[0]!.name).toBe('output');
+  expect(module.macros[0]!.name).toBe('test_macro');
 });
diff --git a/ui/src/plugins/dev.perfetto.StackSamples/index.ts b/ui/src/plugins/dev.perfetto.StackSamples/index.ts
index a1fca9a..de1744d 100644
--- a/ui/src/plugins/dev.perfetto.StackSamples/index.ts
+++ b/ui/src/plugins/dev.perfetto.StackSamples/index.ts
@@ -14,9 +14,7 @@
 
 import m from 'mithril';
 import {z} from 'zod';
-import {ensureExists} from '../../base/assert';
 import {Memo} from '../../base/memo';
-import type {Store} from '../../base/store';
 import {
   metricsFromTableOrSubquery,
   TreeExplorerFetcher,
@@ -29,7 +27,7 @@
   type AreaSelection,
   type AreaSelectionTab,
 } from '../../public/selection';
-import type {Trace} from '../../public/trace';
+import type {Storage, Trace} from '../../public/trace';
 import type {Track} from '../../public/track';
 import {getThreadUriPrefix} from '../../public/utils';
 import {TrackNode} from '../../public/workspace';
@@ -65,7 +63,7 @@
 const LINUX_PERF_SOURCE = 'linux.perf';
 const MAX_AUTO_REVEALED_FLAMECHARTS = 16;
 
-const STACK_SAMPLES_PLUGIN_STATE_SCHEMA = z
+export const STACK_SAMPLES_PLUGIN_STATE_SCHEMA = z
   .object({
     areaSelectionFlamegraphStates: z
       .record(z.string(), TREE_EXPLORER_STATE_SCHEMA)
@@ -409,14 +407,14 @@
   static readonly id = 'dev.perfetto.StackSamples';
   static readonly dependencies = [ProcessThreadGroupsPlugin];
 
-  private store?: Store<StackSamplesPluginState>;
   private readonly counterNamesBySession = new Map<number, string[]>();
   private readonly counterNamesBySource = new Map<string, string[]>();
 
   async onTraceLoad(trace: Trace): Promise<void> {
-    this.store = trace.mountStore(StackSamplesPlugin.id, (init) => {
-      const result = STACK_SAMPLES_PLUGIN_STATE_SCHEMA.safeParse(init);
-      return result.data ?? {};
+    const storage = trace.registerStorage({
+      id: StackSamplesPlugin.id,
+      schema: STACK_SAMPLES_PLUGIN_STATE_SCHEMA,
+      defaultValue: {},
     });
     await this.cacheCounterNames(trace);
 
@@ -440,8 +438,7 @@
     }
     const multiSource = configs.length > 1;
     for (const config of configs) {
-      await this.addTracksForSource(trace, config, multiSource);
-      const store = ensureExists(this.store);
+      await this.addTracksForSource(trace, config, multiSource, storage);
       trace.selection.registerAreaSelectionTab(
         createStackSampleAreaSelectionTab(trace, {
           source: config.source,
@@ -449,11 +446,15 @@
           counterNames: this.counterNamesBySource.get(config.source) ?? [],
           counterNamesBySession: this.counterNamesBySession,
           getState: () =>
-            store.state.areaSelectionFlamegraphStates?.[config.source],
+            storage.get().areaSelectionFlamegraphStates?.[config.source],
           setState: (state) => {
-            store.edit((draft) => {
-              draft.areaSelectionFlamegraphStates ??= {};
-              draft.areaSelectionFlamegraphStates[config.source] = state;
+            const current = storage.get();
+            storage.set({
+              ...current,
+              areaSelectionFlamegraphStates: {
+                ...current.areaSelectionFlamegraphStates,
+                [config.source]: state,
+              },
             });
           },
         }),
@@ -476,7 +477,7 @@
 
     if (configs.length > 0) {
       trace.onTraceReady.addListener(async () => {
-        const preferredOrder = configs[0].order;
+        const preferredOrder = configs[0]!.order;
         await this.autoSelectSource(
           trace,
           configs.filter((config) => config.order === preferredOrder),
@@ -489,6 +490,7 @@
     trace: Trace,
     config: StackSampleSourceSchema,
     multiSource: boolean,
+    storage: Storage<StackSamplesPluginState>,
   ): Promise<void> {
     // With a single stack-sample source there is nothing to disambiguate;
     // only prefix track names with the source when several sources emit.
@@ -587,7 +589,7 @@
       ) {
         continue;
       }
-      const node = this.addScopeTracks(trace, config, {
+      const node = this.addScopeTracks(trace, config, storage, {
         upid,
         utid: undefined,
         sessionIds,
@@ -601,13 +603,16 @@
       groups.getGroupForProcess(upid)?.addChildInOrder(node);
     }
 
-    const store = ensureExists(this.store);
     const detailsPanelState = () =>
-      store.state.detailsPanelFlamegraphStates?.[config.source];
+      storage.get().detailsPanelFlamegraphStates?.[config.source];
     const onDetailsPanelStateChange = (state: TreeExplorerState) => {
-      store.edit((draft) => {
-        draft.detailsPanelFlamegraphStates ??= {};
-        draft.detailsPanelFlamegraphStates[config.source] = state;
+      const current = storage.get();
+      storage.set({
+        ...current,
+        detailsPanelFlamegraphStates: {
+          ...current.detailsPanelFlamegraphStates,
+          [config.source]: state,
+        },
       });
     };
 
@@ -763,6 +768,7 @@
   private addScopeTracks(
     trace: Trace,
     config: StackSampleSourceSchema,
+    storage: Storage<StackSamplesPluginState>,
     args: {
       readonly upid: number | undefined;
       readonly utid: number | undefined;
@@ -774,7 +780,6 @@
       readonly sortOrder: number;
     },
   ): TrackNode {
-    const store = ensureExists(this.store);
     const registerTrack = (
       uri: string,
       sessionId: SessionId | undefined,
@@ -791,11 +796,15 @@
             sessionId,
             summary,
           },
-          store.state.detailsPanelFlamegraphStates?.[config.source],
+          storage.get().detailsPanelFlamegraphStates?.[config.source],
           (state) => {
-            store.edit((draft) => {
-              draft.detailsPanelFlamegraphStates ??= {};
-              draft.detailsPanelFlamegraphStates[config.source] = state;
+            const current = storage.get();
+            storage.set({
+              ...current,
+              detailsPanelFlamegraphStates: {
+                ...current.detailsPanelFlamegraphStates,
+                [config.source]: state,
+              },
             });
           },
         ),
diff --git a/ui/src/plugins/dev.perfetto.StackSamples/sample_colors_unittest.ts b/ui/src/plugins/dev.perfetto.StackSamples/sample_colors_unittest.ts
index c72fe16..0aa4a85 100644
--- a/ui/src/plugins/dev.perfetto.StackSamples/sample_colors_unittest.ts
+++ b/ui/src/plugins/dev.perfetto.StackSamples/sample_colors_unittest.ts
@@ -42,9 +42,9 @@
         utid: 1,
         upid: 1,
       });
-      track.settings[0].update('mapping');
-      const instantColor = create.mock.calls[0][0].colorizer!;
-      const frameColor = create.mock.calls[1][0].colorizer!;
+      track.settings[0]!.update('mapping');
+      const instantColor = create.mock.calls[0]![0].colorizer!;
+      const frameColor = create.mock.calls[1]![0].colorizer!;
       const row = {
         id: 1,
         ts: 10n,
@@ -73,7 +73,7 @@
       utid: 1,
       upid: 1,
     });
-    const attrs = create.mock.calls[0][0];
+    const attrs = create.mock.calls[0]![0];
     const row = {
       id: 1,
       ts: 10n,
@@ -86,7 +86,7 @@
       sampleCount: 1,
     };
     const functionKey = attrs.getKey!();
-    expect(track.settings[0].value).toBe('function');
+    expect(track.settings[0]!.value).toBe('function');
     const functionColor = getColorForSlice(row.name, {
       stripTrailingDigits: false,
     });
@@ -95,13 +95,13 @@
       attrs.colorizer!({...row, category: 1, mappingName: '/lib/libc.so'}),
     ).toEqual(functionColor);
     expect(scheduleFullRedraw).not.toHaveBeenCalled();
-    track.settings[0].update('mapping');
+    track.settings[0]!.update('mapping');
     expect(attrs.getKey!()).not.toBe(functionKey);
     expect(attrs.colorizer!(row)).toEqual(
       sampleColorScheme(row.category, row.mappingName),
     );
     expect(scheduleFullRedraw).toHaveBeenCalledOnce();
-    track.settings[0].update('function');
+    track.settings[0]!.update('function');
     expect(attrs.getKey!()).toBe(functionKey);
     expect(attrs.colorizer!(row)).toEqual(functionColor);
     expect(scheduleFullRedraw).toHaveBeenCalledTimes(2);
@@ -122,8 +122,8 @@
       utid: 2,
       upid: 1,
     });
-    expect(first.settings[0].descriptor).toBe(second.settings[0].descriptor);
-    first.settings[0].update('mapping');
-    expect(second.settings[0].value).toBe('function');
+    expect(first.settings[0]!.descriptor).toBe(second.settings[0]!.descriptor);
+    first.settings[0]!.update('mapping');
+    expect(second.settings[0]!.value).toBe('function');
   });
 });
diff --git a/ui/src/plugins/dev.perfetto.StackSamples/stack_sample_sources.ts b/ui/src/plugins/dev.perfetto.StackSamples/stack_sample_sources.ts
index 1996988..f0ae09a 100644
--- a/ui/src/plugins/dev.perfetto.StackSamples/stack_sample_sources.ts
+++ b/ui/src/plugins/dev.perfetto.StackSamples/stack_sample_sources.ts
@@ -50,7 +50,7 @@
   const name = source
     .split(/[._-]+/)
     .filter((part) => part.length > 0)
-    .map((part) => part[0].toUpperCase() + part.slice(1))
+    .map((part) => part[0]!.toUpperCase() + part.slice(1))
     .join(' ');
   return name || 'Unknown';
 }
diff --git a/ui/src/plugins/dev.perfetto.StackSamples/storage_schema_unittest.ts b/ui/src/plugins/dev.perfetto.StackSamples/storage_schema_unittest.ts
new file mode 100644
index 0000000..cc24da2
--- /dev/null
+++ b/ui/src/plugins/dev.perfetto.StackSamples/storage_schema_unittest.ts
@@ -0,0 +1,53 @@
+// Copyright (C) 2026 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 {STACK_SAMPLES_PLUGIN_STATE_SCHEMA} from './index';
+
+const TREE_STATE = {
+  selectedMetricId: 'self',
+  addedMetricIds: ['total'],
+  displayMode: 'tree',
+  filters: [{kind: 'SHOW_STACK', filter: 'foo'}],
+  view: {kind: 'TOP_DOWN'},
+};
+
+describe('STACK_SAMPLES_PLUGIN_STATE_SCHEMA', () => {
+  test('accepts empty state', () => {
+    expect(STACK_SAMPLES_PLUGIN_STATE_SCHEMA.parse({})).toEqual({});
+  });
+
+  test('accepts per-source flamegraph states', () => {
+    const state = {
+      areaSelectionFlamegraphStates: {linux_perf: TREE_STATE},
+      detailsPanelFlamegraphStates: {
+        linux_perf: TREE_STATE,
+        simpleperf: TREE_STATE,
+      },
+    };
+    expect(STACK_SAMPLES_PLUGIN_STATE_SCHEMA.parse(state)).toEqual(state);
+  });
+
+  test('rejects an invalid per-source tree explorer state', () => {
+    const result = STACK_SAMPLES_PLUGIN_STATE_SCHEMA.safeParse({
+      detailsPanelFlamegraphStates: {linux_perf: {selectedMetricId: 1}},
+    });
+    expect(result.success).toBe(false);
+  });
+
+  test('rejects undefined (relies on defaultValue)', () => {
+    expect(STACK_SAMPLES_PLUGIN_STATE_SCHEMA.safeParse(undefined).success).toBe(
+      false,
+    );
+  });
+});
diff --git a/ui/src/plugins/dev.perfetto.TimelineSync/index.ts b/ui/src/plugins/dev.perfetto.TimelineSync/index.ts
index 3607539..3042503 100644
--- a/ui/src/plugins/dev.perfetto.TimelineSync/index.ts
+++ b/ui/src/plugins/dev.perfetto.TimelineSync/index.ts
@@ -177,7 +177,7 @@
       const selectedClients = new Array<ClientId>();
       const sel = ensureExists(clientsSelect).selectedOptions;
       for (let i = 0; i < sel.length; i++) {
-        const clientId = parseInt(sel[i].value);
+        const clientId = parseInt(sel[i]!.value);
         if (!isNaN(clientId)) selectedClients.push(clientId);
       }
       selectedClients.push(this._clientId); // Always add ourselves.
diff --git a/ui/src/plugins/dev.perfetto.TraceInfoPage/tabs/metadata.ts b/ui/src/plugins/dev.perfetto.TraceInfoPage/tabs/metadata.ts
index 3620816..619dfb9 100644
--- a/ui/src/plugins/dev.perfetto.TraceInfoPage/tabs/metadata.ts
+++ b/ui/src/plugins/dev.perfetto.TraceInfoPage/tabs/metadata.ts
@@ -204,8 +204,8 @@
 
   // If nothing matched a curated section, there is only the "Other" bucket;
   // drop its header and show a plain list.
-  if (sections.length === 1 && sections[0].title === OTHER_TITLE) {
-    sections[0] = {entries: sections[0].entries};
+  if (sections.length === 1 && sections[0]!.title === OTHER_TITLE) {
+    sections[0] = {entries: sections[0]!.entries};
   }
 
   return {
diff --git a/ui/src/plugins/dev.perfetto.TraceProcessorTrack/index.ts b/ui/src/plugins/dev.perfetto.TraceProcessorTrack/index.ts
index 67503d8..66b4323 100644
--- a/ui/src/plugins/dev.perfetto.TraceProcessorTrack/index.ts
+++ b/ui/src/plugins/dev.perfetto.TraceProcessorTrack/index.ts
@@ -31,7 +31,7 @@
 import type {MinimapRow} from '../../public/minimap';
 import type {PerfettoPlugin} from '../../public/plugin';
 import {areaSelectionKey, type AreaSelection} from '../../public/selection';
-import type {Trace} from '../../public/trace';
+import type {Storage, Trace} from '../../public/trace';
 import {COUNTER_TRACK_KIND, SLICE_TRACK_KIND} from '../../public/track_kinds';
 import {getMachineCount, getTrackName} from '../../public/utils';
 import {TrackNode} from '../../public/workspace';
@@ -60,7 +60,6 @@
 import {createTraceProcessorSliceTrack} from './trace_processor_slice_track';
 import {createTraceProcessorStateTrack} from './trace_processor_state_track';
 import type {TopLevelTrackGroup, TrackGroupSchema} from './types';
-import type {Store} from '../../base/store';
 import {z} from 'zod';
 import {
   createPerfettoIndex,
@@ -70,7 +69,7 @@
 import {CallstackDetailsSection} from './callstack_details_section';
 import {AsyncMemo, AtomicTaskQueue} from '../../base/async_memo';
 
-const TRACE_PROCESSOR_TRACK_PLUGIN_STATE_SCHEMA = z.object({
+export const TRACE_PROCESSOR_TRACK_PLUGIN_STATE_SCHEMA = z.object({
   areaSelectionFlamegraphState: TREE_EXPLORER_STATE_SCHEMA.optional(),
 });
 
@@ -103,24 +102,18 @@
   ];
 
   private groups = new Map<string, TrackNode>();
-  private store?: Store<TraceProcessorTrackPluginState>;
-
-  private migrateTraceProcessorTrackPluginState(
-    init: unknown,
-  ): TraceProcessorTrackPluginState {
-    const result = TRACE_PROCESSOR_TRACK_PLUGIN_STATE_SCHEMA.safeParse(init);
-    return result.data ?? {};
-  }
 
   async onTraceLoad(ctx: Trace): Promise<void> {
-    this.store = ctx.mountStore(TraceProcessorTrackPlugin.id, (init) =>
-      this.migrateTraceProcessorTrackPluginState(init),
-    );
+    const storage = ctx.registerStorage({
+      id: TraceProcessorTrackPlugin.id,
+      schema: TRACE_PROCESSOR_TRACK_PLUGIN_STATE_SCHEMA,
+      defaultValue: {},
+    });
 
     await this.addCounters(ctx);
     await this.addSlices(ctx);
     await this.addStates(ctx);
-    this.addAggregations(ctx);
+    this.addAggregations(ctx, storage);
     this.addMinimapContentProvider(ctx);
     this.addSearchProviders(ctx);
   }
@@ -642,7 +635,10 @@
     return newGroup;
   }
 
-  private addAggregations(ctx: Trace) {
+  private addAggregations(
+    ctx: Trace,
+    storage: Storage<TraceProcessorTrackPluginState>,
+  ) {
     ctx.selection.registerAreaSelectionTab(
       createAggregationTab(ctx, new CounterSelectionAggregator()),
     );
@@ -650,11 +646,14 @@
       createAggregationTab(ctx, new ThreadSliceAggregator(ctx)),
     );
     ctx.selection.registerAreaSelectionTab(
-      this.createSliceFlameGraphPanel(ctx),
+      this.createSliceFlameGraphPanel(ctx, storage),
     );
   }
 
-  private createSliceFlameGraphPanel(trace: Trace) {
+  private createSliceFlameGraphPanel(
+    trace: Trace,
+    storage: Storage<TraceProcessorTrackPluginState>,
+  ) {
     const queue = new AtomicTaskQueue();
     const memo = new AsyncMemo<SliceFlamegraphData | undefined>(queue);
 
@@ -667,25 +666,26 @@
           key: {
             selection: selectionKey,
           },
-          compute: () => this.computeSliceFlamegraph(trace, queue, selection),
+          compute: () =>
+            this.computeSliceFlamegraph(trace, queue, selection, storage),
         });
 
         // No data returned, return undefined to hide the tab.
         if (computed === undefined && !isPending) {
           return undefined;
         }
-
-        const store = ensureExists(this.store);
         return {
           isLoading: isPending,
           content:
             computed &&
             m(TreeExplorerPanel, {
               fetcher: computed.fetcher,
-              state: store.state.areaSelectionFlamegraphState,
+              state: storage.get().areaSelectionFlamegraphState,
               onStateChange: (state) => {
-                store.edit((draft) => {
-                  draft.areaSelectionFlamegraphState = state;
+                const current = storage.get();
+                storage.set({
+                  ...current,
+                  areaSelectionFlamegraphState: state,
                 });
               },
             }),
@@ -698,6 +698,7 @@
     trace: Trace,
     queue: AtomicTaskQueue,
     currentSelection: AreaSelection,
+    storage: Storage<TraceProcessorTrackPluginState>,
   ): Promise<SliceFlamegraphData | undefined> {
     const trackIds = [];
     for (const trackInfo of currentSelection.tracks) {
@@ -840,12 +841,13 @@
       ],
       nameColumnLabel: 'Slice Name',
     });
-    const store = ensureExists(this.store);
-    store.edit((draft) => {
-      draft.areaSelectionFlamegraphState = updateTreeExplorerState(
-        draft.areaSelectionFlamegraphState,
+    const current = storage.get();
+    storage.set({
+      ...current,
+      areaSelectionFlamegraphState: updateTreeExplorerState(
+        current.areaSelectionFlamegraphState,
         metrics,
-      );
+      ),
     });
     // The fetcher is created here, next to the metrics it serves, and moved
     // into the returned object: it dies with this generation, so its virtual
diff --git a/ui/src/plugins/dev.perfetto.TraceProcessorTrack/storage_schema_unittest.ts b/ui/src/plugins/dev.perfetto.TraceProcessorTrack/storage_schema_unittest.ts
new file mode 100644
index 0000000..1b6fb57
--- /dev/null
+++ b/ui/src/plugins/dev.perfetto.TraceProcessorTrack/storage_schema_unittest.ts
@@ -0,0 +1,66 @@
+// Copyright (C) 2026 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 {TRACE_PROCESSOR_TRACK_PLUGIN_STATE_SCHEMA} from './index';
+
+const TREE_STATE = {
+  selectedMetricId: 'self',
+  addedMetricIds: ['total'],
+  displayMode: 'tree',
+  filters: [{kind: 'SHOW_STACK', filter: 'foo'}],
+  view: {kind: 'TOP_DOWN'},
+};
+
+describe('TRACE_PROCESSOR_TRACK_PLUGIN_STATE_SCHEMA', () => {
+  test('accepts empty state', () => {
+    expect(TRACE_PROCESSOR_TRACK_PLUGIN_STATE_SCHEMA.parse({})).toEqual({});
+  });
+
+  test('accepts a populated state', () => {
+    const state = {areaSelectionFlamegraphState: TREE_STATE};
+    expect(TRACE_PROCESSOR_TRACK_PLUGIN_STATE_SCHEMA.parse(state)).toEqual(
+      state,
+    );
+  });
+
+  test('fills defaults in nested tree explorer state', () => {
+    const result = TRACE_PROCESSOR_TRACK_PLUGIN_STATE_SCHEMA.parse({
+      areaSelectionFlamegraphState: {
+        selectedMetricId: 'self',
+        filters: [],
+        view: {kind: 'BOTTOM_UP'},
+      },
+    });
+    expect(result.areaSelectionFlamegraphState).toEqual({
+      selectedMetricId: 'self',
+      addedMetricIds: [],
+      displayMode: 'flamegraph',
+      filters: [],
+      view: {kind: 'BOTTOM_UP'},
+    });
+  });
+
+  test('rejects an invalid tree explorer state', () => {
+    const result = TRACE_PROCESSOR_TRACK_PLUGIN_STATE_SCHEMA.safeParse({
+      areaSelectionFlamegraphState: {...TREE_STATE, view: {kind: 'NOT_A_VIEW'}},
+    });
+    expect(result.success).toBe(false);
+  });
+
+  test('rejects undefined (relies on defaultValue)', () => {
+    expect(
+      TRACE_PROCESSOR_TRACK_PLUGIN_STATE_SCHEMA.safeParse(undefined).success,
+    ).toBe(false);
+  });
+});
diff --git a/ui/src/plugins/dev.perfetto.TraceProcessorTrack/thread_slice_aggregator.ts b/ui/src/plugins/dev.perfetto.TraceProcessorTrack/thread_slice_aggregator.ts
index 4159399..7cfe7a4 100644
--- a/ui/src/plugins/dev.perfetto.TraceProcessorTrack/thread_slice_aggregator.ts
+++ b/ui/src/plugins/dev.perfetto.TraceProcessorTrack/thread_slice_aggregator.ts
@@ -300,7 +300,7 @@
               ),
             );
           } else {
-            const track = tracks[0];
+            const track = tracks[0]!;
             return m(
               Anchor,
               {
diff --git a/ui/src/plugins/dev.perfetto.TraceProcessorTrack/trace_processor_slice_track.ts b/ui/src/plugins/dev.perfetto.TraceProcessorTrack/trace_processor_slice_track.ts
index 6497107..5fe6d1c 100644
--- a/ui/src/plugins/dev.perfetto.TraceProcessorTrack/trace_processor_slice_track.ts
+++ b/ui/src/plugins/dev.perfetto.TraceProcessorTrack/trace_processor_slice_track.ts
@@ -129,7 +129,7 @@
       src: 'slice',
       filter: {
         col: 'track_id',
-        eq: trackIds[0],
+        eq: trackIds[0]!,
       },
     });
   } else {
diff --git a/ui/src/plugins/dev.perfetto.TrackEvent/index.ts b/ui/src/plugins/dev.perfetto.TrackEvent/index.ts
index 31f7d12..a6b6b96 100644
--- a/ui/src/plugins/dev.perfetto.TrackEvent/index.ts
+++ b/ui/src/plugins/dev.perfetto.TrackEvent/index.ts
@@ -33,7 +33,6 @@
 import {ThreadSliceDetailsPanel} from '../../components/details/thread_slice_details_tab';
 import {TREE_EXPLORER_STATE_SCHEMA} from '../../widgets/tree_explorer';
 import {CallstackDetailsSection} from '../dev.perfetto.TraceProcessorTrack/callstack_details_section';
-import type {Store} from '../../base/store';
 import {z} from 'zod';
 import {createPerfettoTable} from '../../trace_processor/sql_utils';
 import ThreadPlugin from '../dev.perfetto.Thread';
@@ -52,12 +51,10 @@
     });
 }
 
-const TRACK_EVENT_PLUGIN_STATE_SCHEMA = z.object({
+export const TRACK_EVENT_PLUGIN_STATE_SCHEMA = z.object({
   areaSelectionFlamegraphState: TREE_EXPLORER_STATE_SCHEMA.optional(),
 });
 
-type TrackEventPluginState = z.infer<typeof TRACK_EVENT_PLUGIN_STATE_SCHEMA>;
-
 export default class TrackEventPlugin implements PerfettoPlugin {
   static readonly id = 'dev.perfetto.TrackEvent';
   static readonly dependencies = [
@@ -68,18 +65,14 @@
   ];
 
   private parentTrackNodes = new Map<string, TrackNode>();
-  private store?: Store<TrackEventPluginState>;
-
-  private migrateTrackEventPluginState(init: unknown): TrackEventPluginState {
-    const result = TRACK_EVENT_PLUGIN_STATE_SCHEMA.safeParse(init);
-    return result.data ?? {};
-  }
 
   async onTraceLoad(ctx: Trace): Promise<void> {
     const numMachines = await getMachineCount(ctx.engine);
-    this.store = ctx.mountStore(TrackEventPlugin.id, (init) =>
-      this.migrateTrackEventPluginState(init),
-    );
+    const storage = ctx.registerStorage({
+      id: TrackEventPlugin.id,
+      schema: TRACK_EVENT_PLUGIN_STATE_SCHEMA,
+      defaultValue: {},
+    });
 
     await ctx.engine.query(`include perfetto module viz.summary.track_event;`);
 
@@ -231,13 +224,13 @@
           continue;
         }
         assertTrue(trackIds.length === 1);
-        const trackId = trackIds[0];
+        const trackId = trackIds[0]!;
         ctx.tracks.registerTrack({
           uri,
           description: description ?? undefined,
           tags: {
             kinds: [kind],
-            trackIds: [trackIds[0]],
+            trackIds: [trackIds[0]!],
             upid: upid ?? undefined,
             utid: utid ?? undefined,
             trackEvent: true,
@@ -271,7 +264,7 @@
           renderer: await createTraceProcessorStateTrack({
             trace: ctx,
             uri,
-            trackId: trackIds[0],
+            trackId: trackIds[0]!,
             trackName,
           }),
         });
@@ -343,17 +336,18 @@
         uri,
       });
       parent.addChildInOrder(node);
-      trackIdToTrackNode.set(trackIds[0], node);
+      trackIdToTrackNode.set(trackIds[0]!, node);
     }
 
-    const store = ensureExists(this.store);
     ctx.selection.registerAreaSelectionTab(
       new TrackEventCallstackFlamegraphTab(
         ctx,
-        () => store.state.areaSelectionFlamegraphState,
+        () => storage.get().areaSelectionFlamegraphState,
         (state) => {
-          store.edit((draft) => {
-            draft.areaSelectionFlamegraphState = state;
+          const current = storage.get();
+          storage.set({
+            ...current,
+            areaSelectionFlamegraphState: state,
           });
         },
       ),
diff --git a/ui/src/plugins/dev.perfetto.TrackEvent/storage_schema_unittest.ts b/ui/src/plugins/dev.perfetto.TrackEvent/storage_schema_unittest.ts
new file mode 100644
index 0000000..14519d0
--- /dev/null
+++ b/ui/src/plugins/dev.perfetto.TrackEvent/storage_schema_unittest.ts
@@ -0,0 +1,64 @@
+// Copyright (C) 2026 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 {TRACK_EVENT_PLUGIN_STATE_SCHEMA} from './index';
+
+const TREE_STATE = {
+  selectedMetricId: 'self',
+  addedMetricIds: ['total'],
+  displayMode: 'tree',
+  filters: [{kind: 'SHOW_STACK', filter: 'foo'}],
+  view: {kind: 'TOP_DOWN'},
+};
+
+describe('TRACK_EVENT_PLUGIN_STATE_SCHEMA', () => {
+  test('accepts empty state', () => {
+    expect(TRACK_EVENT_PLUGIN_STATE_SCHEMA.parse({})).toEqual({});
+  });
+
+  test('accepts a populated state', () => {
+    const state = {areaSelectionFlamegraphState: TREE_STATE};
+    expect(TRACK_EVENT_PLUGIN_STATE_SCHEMA.parse(state)).toEqual(state);
+  });
+
+  test('fills defaults in nested tree explorer state', () => {
+    const result = TRACK_EVENT_PLUGIN_STATE_SCHEMA.parse({
+      areaSelectionFlamegraphState: {
+        selectedMetricId: 'self',
+        filters: [],
+        view: {kind: 'BOTTOM_UP'},
+      },
+    });
+    expect(result.areaSelectionFlamegraphState).toEqual({
+      selectedMetricId: 'self',
+      addedMetricIds: [],
+      displayMode: 'flamegraph',
+      filters: [],
+      view: {kind: 'BOTTOM_UP'},
+    });
+  });
+
+  test('rejects an invalid tree explorer state', () => {
+    const result = TRACK_EVENT_PLUGIN_STATE_SCHEMA.safeParse({
+      areaSelectionFlamegraphState: {...TREE_STATE, view: {kind: 'NOT_A_VIEW'}},
+    });
+    expect(result.success).toBe(false);
+  });
+
+  test('rejects undefined (relies on defaultValue)', () => {
+    expect(TRACK_EVENT_PLUGIN_STATE_SCHEMA.safeParse(undefined).success).toBe(
+      false,
+    );
+  });
+});
diff --git a/ui/src/plugins/dev.perfetto.VideoFrames/video_frame_player.ts b/ui/src/plugins/dev.perfetto.VideoFrames/video_frame_player.ts
index 1e5ab99..7b2689c 100644
--- a/ui/src/plugins/dev.perfetto.VideoFrames/video_frame_player.ts
+++ b/ui/src/plugins/dev.perfetto.VideoFrames/video_frame_player.ts
@@ -195,7 +195,7 @@
   // skips re-decoding when the selection is already the seeked frame.
   private selectAndSeek(idx: number): void {
     void this.seekToIndex(idx);
-    this.trace.selection.selectTrackEvent(this.trackUri, this.frames[idx].id);
+    this.trace.selection.selectTrackEvent(this.trackUri, this.frames[idx]!.id);
   }
 
   togglePlay(): void {
@@ -244,7 +244,7 @@
     });
     decoder.configure(decoderConfig(setup));
     for (let i = 0; i < range.length; i++) {
-      decoder.decode(chunkFor(setup, range[i], datas[i], i === 0));
+      decoder.decode(chunkFor(setup, range[i]!, datas[i]!, i === 0));
     }
     await decoder.flush().catch(() => undefined);
     if (decoder.state !== 'closed') decoder.close();
@@ -357,7 +357,7 @@
       if (token !== this.token) return;
       // Drop seed frames decoded before fromIdx without painting (they
       // exist only to prime the decoder's reference list).
-      while (session.queue.length > 0 && session.queue[0].idx < fromIdx) {
+      while (session.queue.length > 0 && session.queue[0]!.idx < fromIdx) {
         session.queue.shift()!.frame.close();
       }
       let due: QueuedFrame | undefined;
@@ -367,7 +367,7 @@
           due = session.queue.shift();
           started = true;
           lastWallMs = performance.now();
-          playbackTs = this.frames[due!.idx].ts;
+          playbackTs = this.frames[due!.idx]!.ts;
         }
       } else {
         const nowMs = performance.now();
@@ -378,7 +378,7 @@
         // Drain all frames whose ts is now due; paint only the latest.
         while (
           session.queue.length > 0 &&
-          this.frames[session.queue[0].idx].ts <= playbackTs
+          this.frames[session.queue[0]!.idx]!.ts <= playbackTs
         ) {
           if (due !== undefined) due.frame.close();
           due = session.queue.shift();
@@ -393,7 +393,7 @@
           // re-seeking while playing, so the canvas doesn't flicker.
           this.trace.selection.selectTrackEvent(
             this.trackUri,
-            this.frames[due.idx].id,
+            this.frames[due.idx]!.id,
           );
           m.redraw();
         }
@@ -426,7 +426,7 @@
           return;
         }
         session.decoder.decode(
-          chunkFor(setup, batch[i], datas[i], base + i === k),
+          chunkFor(setup, batch[i]!, datas[i]!, base + i === k),
         );
       }
     }
@@ -452,7 +452,7 @@
   // frame to seed the reference list before any non-key frame.
   private nearestKey(idx: number): number {
     let k = idx;
-    while (k >= 0 && !this.frames[k].isKey) k--;
+    while (k >= 0 && !this.frames[k]!.isKey) k--;
     // -1 when no key frame precedes idx, e.g. a ring buffer whose start (and
     // the GOP's key frame) was overwritten. Such frames can't be decoded.
     return k;
@@ -462,8 +462,8 @@
     if (this.setup !== undefined) return this.setup;
     if (this.configId === undefined || this.codecString === undefined) return;
     const [config] = await this.fetchAuData([this.configId]);
-    if (config.length === 0) return;
-    this.setup = {codecString: this.codecString, config};
+    if (config!.length === 0) return;
+    this.setup = {codecString: this.codecString, config: config!};
     return this.setup;
   }
 
diff --git a/ui/src/plugins/dev.perfetto.WidgetsPage/demos/charts_demo.ts b/ui/src/plugins/dev.perfetto.WidgetsPage/demos/charts_demo.ts
index fc091a1..ad07ed7 100644
--- a/ui/src/plugins/dev.perfetto.WidgetsPage/demos/charts_demo.ts
+++ b/ui/src/plugins/dev.perfetto.WidgetsPage/demos/charts_demo.ts
@@ -2546,8 +2546,8 @@
         let max = -Infinity;
         const filteredValues: Array<readonly [number, number, number]> = [];
         for (const [xIdx, yIdx, val] of data.values) {
-          const xLabel = data.xLabels[xIdx];
-          const yLabel = data.yLabels[yIdx];
+          const xLabel = data.xLabels[xIdx]!;
+          const yLabel = data.yLabels[yIdx]!;
           const newX = xIndices.get(xLabel);
           const newY = yIndices.get(yLabel);
           if (newX !== undefined && newY !== undefined) {
@@ -2829,8 +2829,8 @@
         let max = -Infinity;
         const filteredValues: Array<readonly [number, number, number]> = [];
         for (const [xIdx, yIdx, val] of data.values) {
-          const xLabel = data.xLabels[xIdx];
-          const yLabel = data.yLabels[yIdx];
+          const xLabel = data.xLabels[xIdx]!;
+          const yLabel = data.yLabels[yIdx]!;
           const newX = xIndices.get(xLabel);
           const newY = yIndices.get(yLabel);
           if (newX !== undefined && newY !== undefined) {
diff --git a/ui/src/plugins/dev.perfetto.WidgetsPage/demos/datagrid_demo.ts b/ui/src/plugins/dev.perfetto.WidgetsPage/demos/datagrid_demo.ts
index f7a8082..1fa5e58 100644
--- a/ui/src/plugins/dev.perfetto.WidgetsPage/demos/datagrid_demo.ts
+++ b/ui/src/plugins/dev.perfetto.WidgetsPage/demos/datagrid_demo.ts
@@ -263,6 +263,7 @@
       initialOpts: {
         showExportButton: false,
         structuredQueryCompatMode: false,
+        enableQuickFilter: false,
         disablePivotControls: false,
         disableColumnControls: false,
         disableFilterControls: false,
diff --git a/ui/src/plugins/dev.perfetto.WidgetsPage/demos/fuzzy_demo.ts b/ui/src/plugins/dev.perfetto.WidgetsPage/demos/fuzzy_demo.ts
index 9474084..544dbd5 100644
--- a/ui/src/plugins/dev.perfetto.WidgetsPage/demos/fuzzy_demo.ts
+++ b/ui/src/plugins/dev.perfetto.WidgetsPage/demos/fuzzy_demo.ts
@@ -92,7 +92,7 @@
 
   function toCamelCase(words: string[]): string {
     return (
-      words[0].toLowerCase() +
+      words[0]!.toLowerCase() +
       words
         .slice(1)
         .map((w) => w.charAt(0).toUpperCase() + w.slice(1))
@@ -186,8 +186,8 @@
       );
       results = searchResults.map((res) => ({
         item: res.item,
-        nameSegments: res.segments[0],
-        categorySegments: res.segments[1],
+        nameSegments: res.segments[0]!,
+        categorySegments: res.segments[1]!,
         score: res.score,
       }));
     } else {
diff --git a/ui/src/plugins/dev.perfetto.WidgetsPage/demos/grid_demo.ts b/ui/src/plugins/dev.perfetto.WidgetsPage/demos/grid_demo.ts
index e88b9c8..b55db56 100644
--- a/ui/src/plugins/dev.perfetto.WidgetsPage/demos/grid_demo.ts
+++ b/ui/src/plugins/dev.perfetto.WidgetsPage/demos/grid_demo.ts
@@ -528,7 +528,7 @@
     loadedRows = [];
     for (let i = 0; i < limit && offset + i < totalRows; i++) {
       const idx = offset + i;
-      const langData = languages[idx % languages.length];
+      const langData = languages[idx % languages.length]!;
 
       const menuItems = contextMenus
         ? [
diff --git a/ui/src/plugins/dev.perfetto.WidgetsPage/demos/nodegraph_demo.ts b/ui/src/plugins/dev.perfetto.WidgetsPage/demos/nodegraph_demo.ts
index 0d98320..2ed221f 100644
--- a/ui/src/plugins/dev.perfetto.WidgetsPage/demos/nodegraph_demo.ts
+++ b/ui/src/plugins/dev.perfetto.WidgetsPage/demos/nodegraph_demo.ts
@@ -543,7 +543,7 @@
   const undo = () => {
     if (historyIndex > 0) {
       historyIndex--;
-      store = history[historyIndex];
+      store = history[historyIndex]!;
       m.redraw();
       console.log(`Undo to state ${historyIndex}`);
     }
@@ -552,7 +552,7 @@
   const redo = () => {
     if (historyIndex < history.length - 1) {
       historyIndex++;
-      store = history[historyIndex];
+      store = history[historyIndex]!;
       m.redraw();
       console.log(`Redo to state ${historyIndex}`);
     }
@@ -587,7 +587,7 @@
 
       // Remove any connections to/from this node
       for (let i = draft.connections.length - 1; i >= 0; i--) {
-        const c = draft.connections[i];
+        const c = draft.connections[i]!;
         if (c.fromNode === nodeId || c.toNode === nodeId) {
           draft.connections.splice(i, 1);
         }
@@ -641,7 +641,7 @@
       for (let i = 0; i < 100; i++) {
         const id = uuidv4();
         const factory =
-          nodeFactories[Math.floor(Math.random() * nodeFactories.length)];
+          nodeFactories[Math.floor(Math.random() * nodeFactories.length)]!;
         const x = Math.random() * 2000;
         const y = Math.random() * 2000;
         const newNode = factory(id, x, y);
@@ -665,7 +665,9 @@
         if (availableParents.length === 0) break;
 
         const parentId =
-          availableParents[Math.floor(Math.random() * availableParents.length)];
+          availableParents[
+            Math.floor(Math.random() * availableParents.length)
+          ]!;
         const parent = draft.nodes.get(parentId)!;
 
         // Find a child node that can dock (has canDockTop)
@@ -680,7 +682,7 @@
         const childId =
           availableChildren[
             Math.floor(Math.random() * availableChildren.length)
-          ];
+          ]!;
 
         // Stack the child under the parent
         parent.nextId = childId;
@@ -694,8 +696,8 @@
       const numConnections = 150;
       for (let i = 0; i < numConnections; i++) {
         // Pick random nodes
-        const fromNodeId = nodeIds[Math.floor(Math.random() * nodeIds.length)];
-        const toNodeId = nodeIds[Math.floor(Math.random() * nodeIds.length)];
+        const fromNodeId = nodeIds[Math.floor(Math.random() * nodeIds.length)]!;
+        const toNodeId = nodeIds[Math.floor(Math.random() * nodeIds.length)]!;
 
         if (fromNodeId === toNodeId) continue;
 
@@ -872,7 +874,7 @@
 
         const validInputs = inputs.filter((sql) => sql);
         if (validInputs.length === 0) return '';
-        if (validInputs.length === 1) return validInputs[0];
+        if (validInputs.length === 1) return validInputs[0]!;
         return validInputs.map((sql) => `(${sql})`).join(` ${unionType} `);
       }
 
@@ -1058,7 +1060,7 @@
             );
             if (bottomConnectionIdx > -1) {
               draft.connections[bottomConnectionIdx] = {
-                ...draft.connections[bottomConnectionIdx],
+                ...draft.connections[bottomConnectionIdx]!,
                 fromNode: id,
                 fromPort: 0,
               };
@@ -1330,7 +1332,7 @@
 
             // If a connection already exists between these nodes, remove it
             for (let i = draft.connections.length - 1; i >= 0; i--) {
-              const conn = draft.connections[i];
+              const conn = draft.connections[i]!;
               if (
                 (conn.fromNode === targetId && conn.fromPort === 0) ||
                 (conn.toNode === child?.id && conn.toPort === 0)
diff --git a/ui/src/plugins/dev.perfetto.WidgetsPage/demos/tabs_demo.ts b/ui/src/plugins/dev.perfetto.WidgetsPage/demos/tabs_demo.ts
index ea2afd1..d4ae55e 100644
--- a/ui/src/plugins/dev.perfetto.WidgetsPage/demos/tabs_demo.ts
+++ b/ui/src/plugins/dev.perfetto.WidgetsPage/demos/tabs_demo.ts
@@ -138,7 +138,7 @@
                   if (draggedIdx === -1) return;
                   const [dragged] = tabEntries.splice(draggedIdx, 1);
                   if (beforeKey === undefined) {
-                    tabEntries.push(dragged);
+                    tabEntries.push(dragged!);
                   } else {
                     const beforeIdx = tabEntries.findIndex(
                       (e) => e.key === beforeKey,
@@ -146,7 +146,7 @@
                     tabEntries.splice(
                       beforeIdx === -1 ? tabEntries.length : beforeIdx,
                       0,
-                      dragged,
+                      dragged!,
                     );
                   }
                 }
diff --git a/ui/src/plugins/org.chromium.ChromeCriticalUserInteractions/generic_slice_details_tab.ts b/ui/src/plugins/org.chromium.ChromeCriticalUserInteractions/generic_slice_details_tab.ts
index 5f211c4..fdbfead 100644
--- a/ui/src/plugins/org.chromium.ChromeCriticalUserInteractions/generic_slice_details_tab.ts
+++ b/ui/src/plugins/org.chromium.ChromeCriticalUserInteractions/generic_slice_details_tab.ts
@@ -64,7 +64,7 @@
     const detailNodes =
       columns !== undefined
         ? Object.keys(columns).map((key) => {
-            const argKey = columns[key].displayName ?? key;
+            const argKey = columns[key]!.displayName ?? key;
             return m(TreeNode, {
               left: argKey,
               right: sqlValueToReadableString(data[key]),
diff --git a/ui/src/plugins/org.chromium.ChromeScrollJank/event_latency_details_panel.ts b/ui/src/plugins/org.chromium.ChromeScrollJank/event_latency_details_panel.ts
index 31c5376..08f0519 100644
--- a/ui/src/plugins/org.chromium.ChromeScrollJank/event_latency_details_panel.ts
+++ b/ui/src/plugins/org.chromium.ChromeScrollJank/event_latency_details_panel.ts
@@ -402,7 +402,10 @@
 
       const rows = this.relevantThreadTracks.map((track, i) => {
         let description = '';
-        if (i == 0 || track.thread != this.relevantThreadTracks[i - 1].thread) {
+        if (
+          i == 0 ||
+          track.thread != this.relevantThreadTracks[i - 1]!.thread
+        ) {
           description = track.causeDescription;
         }
         return [
diff --git a/ui/src/plugins/org.chromium.ChromeScrollJank/scroll_delta_graph.ts b/ui/src/plugins/org.chromium.ChromeScrollJank/scroll_delta_graph.ts
index 7226475..b68e466 100644
--- a/ui/src/plugins/org.chromium.ChromeScrollJank/scroll_delta_graph.ts
+++ b/ui/src/plugins/org.chromium.ChromeScrollJank/scroll_delta_graph.ts
@@ -218,7 +218,7 @@
   // rendered in a new layer, with new tooltip/color/etc.
   const filteredPresentedDeltas = presentedDeltas.filter((item) => {
     for (let i = 0; i < predictorDeltas.length; i++) {
-      const predictorDelta: ScrollDeltaDetails = predictorDeltas[i];
+      const predictorDelta: ScrollDeltaDetails = predictorDeltas[i]!;
       if (
         predictorDelta.ts == item.ts &&
         predictorDelta.scrollUpdateId == item.scrollUpdateId
diff --git a/ui/src/plugins/org.chromium.ChromeScrollJank/scroll_details_panel.ts b/ui/src/plugins/org.chromium.ChromeScrollJank/scroll_details_panel.ts
index 10f95f3..f84c685 100644
--- a/ui/src/plugins/org.chromium.ChromeScrollJank/scroll_details_panel.ts
+++ b/ui/src/plugins/org.chromium.ChromeScrollJank/scroll_details_panel.ts
@@ -244,13 +244,13 @@
       );
 
       if (presentedDeltas.length > 0) {
-        this.metrics.startOffset = presentedDeltas[0].scrollOffset;
+        this.metrics.startOffset = presentedDeltas[0]!.scrollOffset;
         this.metrics.endOffset =
-          presentedDeltas[presentedDeltas.length - 1].scrollOffset;
+          presentedDeltas[presentedDeltas.length - 1]!.scrollOffset;
 
         let pixelsScrolled = 0;
         for (let i = 0; i < presentedDeltas.length; i++) {
-          pixelsScrolled += Math.abs(presentedDeltas[i].scrollDelta);
+          pixelsScrolled += Math.abs(presentedDeltas[i]!.scrollDelta);
         }
 
         if (pixelsScrolled != 0) {
diff --git a/ui/src/plugins/org.chromium.ChromeScrollJank/scroll_jank_cause_link_utils.ts b/ui/src/plugins/org.chromium.ChromeScrollJank/scroll_jank_cause_link_utils.ts
index 9f21352..6d5a2ad 100644
--- a/ui/src/plugins/org.chromium.ChromeScrollJank/scroll_jank_cause_link_utils.ts
+++ b/ui/src/plugins/org.chromium.ChromeScrollJank/scroll_jank_cause_link_utils.ts
@@ -163,11 +163,11 @@
       };
       utids.push(utid);
     } else {
-      threadsWithTrack[utid].trackIds.push(it.trackId);
+      threadsWithTrack[utid]!.trackIds.push(it.trackId);
     }
   }
 
-  return utids.map((each) => threadsWithTrack[each]);
+  return utids.map((each) => threadsWithTrack[each]!);
 }
 
 export function getCauseLink(
@@ -200,7 +200,7 @@
         icon: Icons.UpdateSelection,
         onclick: () => {
           trace.scrollTo({
-            track: {uri: trackUris[0], expandGroup: true},
+            track: {uri: trackUris[0]!, expandGroup: true},
           });
           if (exists(ts) && exists(dur)) {
             trace.scrollTo({
diff --git a/ui/src/plugins/org.chromium.ChromeScrollJank/scroll_jank_cause_map.ts b/ui/src/plugins/org.chromium.ChromeScrollJank/scroll_jank_cause_map.ts
index 65ba6f4..bbd130b 100644
--- a/ui/src/plugins/org.chromium.ChromeScrollJank/scroll_jank_cause_map.ts
+++ b/ui/src/plugins/org.chromium.ChromeScrollJank/scroll_jank_cause_map.ts
@@ -122,7 +122,7 @@
       const causeProcess = getScrollJankProcess(iter.causeProcess);
       const causeThread = getScrollJankThread(iter.causeThread);
 
-      this.causes[eventLatencyStage].jankCauses.push({
+      this.causes[eventLatencyStage]!.jankCauses.push({
         description: iter.causeDescription,
         process: causeProcess,
         thread: causeThread,
diff --git a/ui/src/plugins/org.chromium.ChromeScrollJank/utils.ts b/ui/src/plugins/org.chromium.ChromeScrollJank/utils.ts
index 2a12fc5..a16d191 100644
--- a/ui/src/plugins/org.chromium.ChromeScrollJank/utils.ts
+++ b/ui/src/plugins/org.chromium.ChromeScrollJank/utils.ts
@@ -152,7 +152,7 @@
   for (const it = queryResult.iter(spec); it.valid(); it.next()) {
     const row: Row = {};
     for (const key of Object.keys(spec)) {
-      row[key] = it[key];
+      row[key] = it[key]!;
     }
     results.push(row as InferRowType<R>);
   }
diff --git a/ui/src/plugins/org.chromium.MemorySnapshots/index.ts b/ui/src/plugins/org.chromium.MemorySnapshots/index.ts
index e091f93..4b12fa6 100644
--- a/ui/src/plugins/org.chromium.MemorySnapshots/index.ts
+++ b/ui/src/plugins/org.chromium.MemorySnapshots/index.ts
@@ -218,7 +218,7 @@
     }
     // Select first snapshot by default
     if (this.snapshots.length > 0) {
-      this.selectedSnapshotId = this.snapshots[0].id;
+      this.selectedSnapshotId = this.snapshots[0]!.id;
     }
   }
 
diff --git a/ui/src/plugins/org.chromium.V8/v8_sources_tab.ts b/ui/src/plugins/org.chromium.V8/v8_sources_tab.ts
index 2669380..5f041c9 100644
--- a/ui/src/plugins/org.chromium.V8/v8_sources_tab.ts
+++ b/ui/src/plugins/org.chromium.V8/v8_sources_tab.ts
@@ -337,6 +337,8 @@
           data: this.dataSource,
           schema: v8JsScriptUiSchema,
           fillHeight: true,
+          // The "Search scripts" box above already filters this grid.
+          enableQuickFilter: false,
           filters: this.filters,
           onFiltersChanged: (filters: readonly Filter[]) => {
             this.filters = filters;
diff --git a/ui/src/public/route_schema.ts b/ui/src/public/route_schema.ts
index fac02dc..e207504 100644
--- a/ui/src/public/route_schema.ts
+++ b/ui/src/public/route_schema.ts
@@ -59,6 +59,9 @@
     // Should we hide the sidebar?
     hideSidebar: z.boolean().optional().catch(undefined),
 
+    // Should we hide the status bar?
+    hideStatusbar: z.boolean().optional().catch(undefined),
+
     // A comma-separated list of plugins to enable for the current session.
     enablePlugins: z.string().optional().catch(undefined),
 
diff --git a/ui/src/public/trace.ts b/ui/src/public/trace.ts
index 12d48ef..bf50918 100644
--- a/ui/src/public/trace.ts
+++ b/ui/src/public/trace.ts
@@ -12,7 +12,7 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-import type {Migrate, Store} from '../base/store';
+import type {z} from 'zod';
 import type {TraceInfo} from './trace_info';
 import type {Engine} from '../trace_processor/engine';
 import type {App} from './app';
@@ -37,6 +37,29 @@
 }
 
 /**
+ * Describes a persistent storage container backed by the trace's permalink state.
+ */
+export interface StorageDescriptor<T> {
+  // A unique identifier for the storage within the trace's permalink state.
+  readonly id: string;
+  // The Zod schema used for validating the stored value upon restore.
+  readonly schema: z.ZodType<T>;
+  // The default value used when no state is present or if validation fails.
+  readonly defaultValue: T;
+}
+
+/**
+ * A persistent state container with get and set methods, backed by the trace's
+ * permalink state.
+ */
+export interface Storage<T> {
+  // Get the current value, validated by the schema or falling back to default.
+  get(): T;
+  // Update the stored value.
+  set(value: T): void;
+}
+
+/**
  * The main API endpoint to interact programmatically with the UI and alter its
  * state once a trace is loaded. There are N+1 instances of this interface,
  * one for each plugin and one for the core (which, however, gets to see the
@@ -67,8 +90,13 @@
   // selection.
   scrollTo(args: ScrollToArgs): void;
 
-  // Create a store mounted over the top of this plugin's persistent state.
-  mountStore<T>(id: string, migrate: Migrate<T>): Store<T>;
+  /**
+   * Register a persistent storage container backed by the trace's permalink state.
+   *
+   * When loading a permalink, the value will be restored from the permalink if
+   * valid according to the schema, or fall back to defaultValue.
+   */
+  registerStorage<T>(descriptor: StorageDescriptor<T>): Storage<T>;
 
   // Returns the blob of the current trace file.
   // If the trace is opened from a file or postmessage, the blob is returned
diff --git a/ui/src/public/workspace.ts b/ui/src/public/workspace.ts
index 3db409a..72f050b 100644
--- a/ui/src/public/workspace.ts
+++ b/ui/src/public/workspace.ts
@@ -476,8 +476,8 @@
 
   private collectFlatTracks(tracks: TrackNode[]): void {
     for (let i = 0; i < this.children.length; ++i) {
-      tracks.push(this.children[i]); // Push the current node before its children
-      this.children[i].collectFlatTracks(tracks); // Recurse to collect child tracks
+      tracks.push(this.children[i]!); // Push the current node before its children
+      this.children[i]!.collectFlatTracks(tracks); // Recurse to collect child tracks
     }
   }
 
diff --git a/ui/src/public/workspace_unittest.ts b/ui/src/public/workspace_unittest.ts
index d7bbc78..22d5662 100644
--- a/ui/src/public/workspace_unittest.ts
+++ b/ui/src/public/workspace_unittest.ts
@@ -370,9 +370,9 @@
   expect(cloned.removable).toBe(root.removable);
   expect(cloned.children).toHaveLength(2);
 
-  expect(cloned.children[0].name).toBe(childA.name);
-  expect(cloned.children[0].uri).toBe(childA.uri);
+  expect(cloned.children[0]!.name).toBe(childA.name);
+  expect(cloned.children[0]!.uri).toBe(childA.uri);
 
-  expect(cloned.children[1].name).toBe(childB.name);
-  expect(cloned.children[1].uri).toBe(childB.uri);
+  expect(cloned.children[1]!.name).toBe(childB.name);
+  expect(cloned.children[1]!.uri).toBe(childB.uri);
 });
diff --git a/ui/src/test/screenshot_diff_reporter.ts b/ui/src/test/screenshot_diff_reporter.ts
index 2878366..bd8e8b5 100644
--- a/ui/src/test/screenshot_diff_reporter.ts
+++ b/ui/src/test/screenshot_diff_reporter.ts
@@ -139,7 +139,7 @@
       if (m === null || a.path === undefined || !fs.existsSync(a.path)) {
         continue;
       }
-      const screenshotName = m[1];
+      const screenshotName = m[1]!;
       const role = m[2] as Role;
       let failure = byName.get(screenshotName);
       if (failure === undefined) {
@@ -152,9 +152,9 @@
         };
         byName.set(screenshotName, failure);
       }
-      const fileName = `${failure.id}-${role}.png`;
+      const fileName = `${failure!.id}-${role}.png`;
       fs.copyFileSync(a.path, path.join(this.outputFolder, fileName));
-      failure.images[role] = fileName;
+      failure!.images[role] = fileName;
     }
     // Only keep entries that have an actual image: that's what a failed
     // comparison (or a missing baseline) produces.
diff --git a/ui/src/trace_processor/dataset.ts b/ui/src/trace_processor/dataset.ts
index 8441c10..634c4fa 100644
--- a/ui/src/trace_processor/dataset.ts
+++ b/ui/src/trace_processor/dataset.ts
@@ -250,7 +250,7 @@
 
   implements<T extends DatasetSchema>(required: T): this is Dataset<T> {
     return Object.entries(required).every(([name, required]) => {
-      return name in this.schema && checkExtends(required, this.schema[name]);
+      return name in this.schema && checkExtends(required, this.schema[name]!);
     });
   }
 
@@ -312,7 +312,7 @@
         const newSch: SpecType = {};
         for (const [key, value] of Object.entries(unionSchema)) {
           if (key in dsSchema) {
-            const commonType = unionTypes(value, dsSchema[key]);
+            const commonType = unionTypes(value, dsSchema[key]!);
             if (commonType !== undefined) {
               newSch[key] = commonType;
             }
@@ -351,7 +351,7 @@
 
     for (const srcGroup of combinedSrcSets.values()) {
       if (srcGroup.length === 1) {
-        mergedDatasets.push(srcGroup[0]);
+        mergedDatasets.push(srcGroup[0]!);
       } else {
         // Combine schema across all members in the union
         const combinedSchema = srcGroup.reduce((acc, e) => {
@@ -394,7 +394,7 @@
         const mergedFilter = mergeFilters(inFilters);
         mergedDatasets.push(
           new SourceDataset({
-            src: srcGroup[0].src,
+            src: srcGroup[0]!.src,
             schema: combinedSchema,
             filter: mergedFilter,
             select:
@@ -413,7 +413,7 @@
     // If we merged everything into a single dataset, use its query directly
     // Pass the querySchema to enable column and join elimination
     if (mergedDatasets.length === 1) {
-      return mergedDatasets[0].query(querySchema);
+      return mergedDatasets[0]!.query(querySchema);
     }
 
     // Generate union query from merged datasets
@@ -484,7 +484,7 @@
 
   implements<T extends DatasetSchema>(required: T): this is Dataset<T> {
     return Object.entries(required).every(([name, required]) => {
-      return name in this.schema && checkExtends(required, this.schema[name]);
+      return name in this.schema && checkExtends(required, this.schema[name]!);
     });
   }
 }
@@ -498,7 +498,7 @@
 
 function mergeFilters(filters: InFilter[]): InFilter | undefined {
   if (filters.length === 0) return undefined;
-  const col = filters[0].col;
+  const col = filters[0]!.col;
   const values = new Set(filters.flatMap((filter) => filter.in));
   return {col, in: Array.from(values)};
 }
@@ -595,7 +595,7 @@
         const newSch: SpecType = {};
         for (const [key, value] of Object.entries(unionSchema)) {
           if (key in dsSchema) {
-            const commonType = unionTypes(value, dsSchema[key]);
+            const commonType = unionTypes(value, dsSchema[key]!);
             if (commonType !== undefined) {
               newSch[key] = commonType;
             }
@@ -625,7 +625,7 @@
     const groupQueries: string[] = [];
 
     for (let groupId = 0; groupId < this.sourceGroupArray.length; groupId++) {
-      const [src, group] = this.sourceGroupArray[groupId];
+      const [src, group] = this.sourceGroupArray[groupId]!;
       const partitionMap = this.partitionMaps.get(src)!;
       const partitionColumns = Array.from(partitionMap.columns.keys());
 
@@ -670,7 +670,7 @@
 
     // Single group - no need for UNION
     if (groupQueries.length === 1) {
-      return groupQueries[0];
+      return groupQueries[0]!;
     }
 
     // Small number of groups - use simple UNION ALL
@@ -701,7 +701,7 @@
 
   implements<T extends DatasetSchema>(schema: T): this is Dataset<T> {
     return Object.entries(schema).every(([name, required]) => {
-      return name in this.schema && checkExtends(required, this.schema[name]);
+      return name in this.schema && checkExtends(required, this.schema[name]!);
     });
   }
 
@@ -722,7 +722,7 @@
       return [];
     }
 
-    const [src, group] = this.sourceGroupArray[groupId];
+    const [src, group] = this.sourceGroupArray[groupId]!;
     const partitionMap = this.partitionMaps.get(src)!;
 
     const results: Dataset[] = [];
diff --git a/ui/src/trace_processor/dataset_unittest.ts b/ui/src/trace_processor/dataset_unittest.ts
index 9d03427..071b942 100644
--- a/ui/src/trace_processor/dataset_unittest.ts
+++ b/ui/src/trace_processor/dataset_unittest.ts
@@ -421,7 +421,7 @@
   const inMatch = query.match(/IN \(([\d, ]+)\)/);
   expect(inMatch).toBeTruthy();
   if (inMatch) {
-    const values = inMatch[1].split(',');
+    const values = inMatch[1]!.split(',');
     expect(values.length).toBe(800);
   }
 });
diff --git a/ui/src/trace_processor/perfetto_sql_type.ts b/ui/src/trace_processor/perfetto_sql_type.ts
index efaab5b..350125c 100644
--- a/ui/src/trace_processor/perfetto_sql_type.ts
+++ b/ui/src/trace_processor/perfetto_sql_type.ts
@@ -173,8 +173,8 @@
       return okResult({
         kind: 'joinid',
         source: {
-          table: match[1],
-          column: match[2],
+          table: match[1]!,
+          column: match[2]!,
         },
       });
     }
@@ -186,8 +186,8 @@
       return okResult({
         kind: 'id',
         source: {
-          table: match[1],
-          column: match[2],
+          table: match[1]!,
+          column: match[2]!,
         },
       });
     }
diff --git a/ui/src/trace_processor/proto_ring_buffer.ts b/ui/src/trace_processor/proto_ring_buffer.ts
index 230aa9b..0a23120 100644
--- a/ui/src/trace_processor/proto_ring_buffer.ts
+++ b/ui/src/trace_processor/proto_ring_buffer.ts
@@ -142,7 +142,7 @@
     let len = 0;
 
     if (this.mode === 'PROTO_PREAMBLE') {
-      const tag = data[pos++]; // Assume one-byte tag.
+      const tag = data[pos++]!; // Assume one-byte tag.
       if (tag >= 0x80 || (tag & 0x07) !== 2 /* len delimited */) {
         throw new Error(
           `RPC framing error, unexpected tag ${tag} @ offset ${pos - 1}`,
@@ -153,7 +153,7 @@
         if (pos >= dataEnd) {
           return undefined; // Not enough data to read varint.
         }
-        const val = data[pos++];
+        const val = data[pos++]!;
         len |= ((val & 0x7f) << shift) >>> 0;
         if (val < 0x80) break;
       }
@@ -162,7 +162,7 @@
         if (pos >= dataEnd) {
           return undefined; // Not enough data to read a uint32.
         }
-        const val = data[pos++] & 0xff;
+        const val = data[pos++]! & 0xff;
         len |= (val << (i * 8)) >>> 0;
       }
     } else {
diff --git a/ui/src/trace_processor/query_result.ts b/ui/src/trace_processor/query_result.ts
index 13c3a2a..3f35749 100644
--- a/ui/src/trace_processor/query_result.ts
+++ b/ui/src/trace_processor/query_result.ts
@@ -215,19 +215,19 @@
   let b = 0;
   let i = 0;
   for (; i < 4; ++i) {
-    b = buf[pos++];
+    b = buf[pos++]!;
     lo = (lo | ((b & 127) << (i * 7))) >>> 0;
     if (b < 128) {
       cursor.pos = pos;
       return lo;
     }
   }
-  b = buf[pos++];
+  b = buf[pos++]!;
   lo = (lo | ((b & 127) << 28)) >>> 0;
   hi = (hi | ((b & 127) >> 4)) >>> 0;
   if (b >= 128) {
     for (i = 0; i < 5; ++i) {
-      b = buf[pos++];
+      b = buf[pos++]!;
       hi = (hi | ((b & 127) << (i * 7 + 3))) >>> 0;
       if (b < 128) break;
     }
@@ -264,7 +264,7 @@
   let b = 0;
   let i = 0;
   for (; i < 4; ++i) {
-    b = buf[pos++];
+    b = buf[pos++]!;
     lo = (lo | ((b & 127) << (i * 7))) >>> 0;
     if (b < 128) {
       cursor.pos = pos;
@@ -273,12 +273,12 @@
       return;
     }
   }
-  b = buf[pos++];
+  b = buf[pos++]!;
   lo = (lo | ((b & 127) << 28)) >>> 0;
   hi = (hi | ((b & 127) >> 4)) >>> 0;
   if (b >= 128) {
     for (i = 0; i < 5; ++i) {
-      b = buf[pos++];
+      b = buf[pos++]!;
       hi = (hi | ((b & 127) << (i * 7 + 3))) >>> 0;
       if (b < 128) break;
     }
@@ -310,16 +310,16 @@
     // fast route (lo)
     for (; i < 4; ++i) {
       // 1st..4th
-      lo = (lo | ((buf[pos] & 127) << (i * 7))) >>> 0;
-      if (buf[pos++] < 128) {
+      lo = (lo | ((buf[pos]! & 127) << (i * 7))) >>> 0;
+      if (buf[pos++]! < 128) {
         cursor.pos = pos;
         return BigInt(lo);
       }
     }
     // 5th
-    lo = (lo | ((buf[pos] & 127) << 28)) >>> 0;
-    hi = (hi | ((buf[pos] & 127) >> 4)) >>> 0;
-    if (buf[pos++] < 128) {
+    lo = (lo | ((buf[pos]! & 127) << 28)) >>> 0;
+    hi = (hi | ((buf[pos]! & 127) >> 4)) >>> 0;
+    if (buf[pos++]! < 128) {
       cursor.pos = pos;
       return (BigInt(hi) << SHIFT_32BITS) | BigInt(lo);
     }
@@ -330,14 +330,14 @@
         throw Error('Index out of range');
       }
       // 1st..3rd
-      lo = (lo | ((buf[pos] & 127) << (i * 7))) >>> 0;
-      if (buf[pos++] < 128) {
+      lo = (lo | ((buf[pos]! & 127) << (i * 7))) >>> 0;
+      if (buf[pos++]! < 128) {
         cursor.pos = pos;
         return BigInt(lo);
       }
     }
     // 4th
-    lo = (lo | ((buf[pos++] & 127) << (i * 7))) >>> 0;
+    lo = (lo | ((buf[pos++]! & 127) << (i * 7))) >>> 0;
     cursor.pos = pos;
     return (BigInt(hi) << SHIFT_32BITS) | BigInt(lo);
   }
@@ -345,8 +345,8 @@
     // fast route (hi)
     for (; i < 5; ++i) {
       // 6th..10th
-      hi = (hi | ((buf[pos] & 127) << (i * 7 + 3))) >>> 0;
-      if (buf[pos++] < 128) {
+      hi = (hi | ((buf[pos]! & 127) << (i * 7 + 3))) >>> 0;
+      if (buf[pos++]! < 128) {
         cursor.pos = pos;
         const big = (BigInt(hi) << SHIFT_32BITS) | BigInt(lo);
         return BigInt.asIntN(64, big);
@@ -358,8 +358,8 @@
         throw Error('Index out of range');
       }
       // 6th..10th
-      hi = (hi | ((buf[pos] & 127) << (i * 7 + 3))) >>> 0;
-      if (buf[pos++] < 128) {
+      hi = (hi | ((buf[pos]! & 127) << (i * 7 + 3))) >>> 0;
+      if (buf[pos++]! < 128) {
         cursor.pos = pos;
         const big = (BigInt(hi) << SHIFT_32BITS) | BigInt(lo);
         return BigInt.asIntN(64, big);
@@ -517,8 +517,8 @@
   let maxType = 0;
   let col = 0;
   for (let i = start; i < end; i++) {
-    const t = bytes[i];
-    seen[col] |= 1 << t;
+    const t = bytes[i]!;
+    seen[col]! |= 1 << t;
     if (t > maxType) maxType = t;
     if (++col === numColumns) col = 0;
   }
@@ -859,7 +859,7 @@
     let row = 0;
     const batches = this.batches;
     for (let b = 0; b < batches.length; b++) {
-      const batch = batches[b];
+      const batch = batches[b]!;
       if (batch.numCells === 0) continue;
       const bytes = batch.batchBytes;
       const f64 = batch.float64Cells;
@@ -888,7 +888,7 @@
       for (let c = 0; c < numColumns; c++) {
         const expType = specValues[c];
         if (expType === undefined) continue;
-        if (trustMasks && isMaskCompatible(seen[c], expType)) continue;
+        if (trustMasks && isMaskCompatible(seen[c]!, expType)) continue;
         // Slow path: throws, naming the first offending row and column.
         throwOnIncompatibleCell(
           bytes,
@@ -897,7 +897,7 @@
           numColumns,
           c,
           expType,
-          colNames[c],
+          colNames[c]!,
           row, // Rows already decoded from earlier batches.
           this._errorInfo,
         );
@@ -934,14 +934,14 @@
               }
               break;
             case CellType.CELL_FLOAT64: {
-              const v = f64[fIdx++];
+              const v = f64[fIdx++]!;
               if (dests[c] !== undefined) {
                 (dests[c] as Array<number | null>)[row] = v;
               }
               break;
             }
             case CellType.CELL_STRING: {
-              const v = strs[sIdx++];
+              const v = strs[sIdx++]!;
               if (kind === Kind.Str) {
                 (dests[c] as Array<string | null>)[row] = v;
               }
@@ -963,7 +963,7 @@
               }
               break;
             case CellType.CELL_BLOB: {
-              const v = blobs[bIdx++];
+              const v = blobs[bIdx++]!;
               if (kind === Kind.Blob) {
                 (dests[c] as Array<SqlValue>)[row] = new Uint8Array(v);
               }
@@ -1365,7 +1365,7 @@
     // Read the current row.
     for (let i = 0; i < numColumns; i++) {
       const cellType = batchBytes[this.nextCellTypeOff++];
-      const colName = this.columnNames[i];
+      const colName = this.columnNames[i]!;
       const expType = colTypes[i];
 
       switch (cellType) {
@@ -1383,15 +1383,15 @@
           break;
 
         case CellType.CELL_FLOAT64:
-          rowData[colName] = this.float64Cells[this.nextFloat64Cell++];
+          rowData[colName] = this.float64Cells[this.nextFloat64Cell++]!;
           break;
 
         case CellType.CELL_STRING:
-          rowData[colName] = this.stringCells[this.nextStringCell++];
+          rowData[colName] = this.stringCells[this.nextStringCell++]!;
           break;
 
         case CellType.CELL_BLOB:
-          const blob = this.blobCells[this.nextBlobCell++];
+          const blob = this.blobCells[this.nextBlobCell++]!;
           rowData[colName] = blob;
           break;
 
@@ -1472,7 +1472,7 @@
       // If undefined, the caller doesn't want to read this column at all, so
       // it can be whatever.
       if (expType === undefined) continue;
-      if (trustMasks && isMaskCompatible(seen[c], expType)) continue;
+      if (trustMasks && isMaskCompatible(seen[c]!, expType)) continue;
       this.checkColumnCellTypes(c, expType, numColumns);
     }
     return true;
@@ -1493,7 +1493,7 @@
       numColumns,
       col,
       expType,
-      this.columnNames[col],
+      this.columnNames[col]!,
       0,
       this.resultObj.errorInfo,
     );
diff --git a/ui/src/trace_processor/query_result_benchmark_unittest.ts b/ui/src/trace_processor/query_result_benchmark_unittest.ts
index 0bee030..0171bea9 100644
--- a/ui/src/trace_processor/query_result_benchmark_unittest.ts
+++ b/ui/src/trace_processor/query_result_benchmark_unittest.ts
@@ -78,7 +78,7 @@
 function pushLenDelim(arr: number[], field: number, payload: number[]): void {
   pushTag(arr, field, 2);
   pushVarint(arr, payload.length);
-  for (let i = 0; i < payload.length; i++) arr.push(payload[i]);
+  for (let i = 0; i < payload.length; i++) arr.push(payload[i]!);
 }
 
 const textEncoder = new TextEncoder();
@@ -142,7 +142,7 @@
       pushInt(depth);
       pushInt(upid);
       cellTypes.push(CELL_STRING);
-      stringCells.push(NAMES[r % NAMES.length]);
+      stringCells.push(NAMES[r % NAMES.length]!);
     }
     const isLast = row + n >= numRows;
 
@@ -247,12 +247,12 @@
   let checksum = 0;
   for (let i = 0; i < count; i++) {
     checksum +=
-      (ids[i] +
+      (ids[i]! +
         Number(tss[i]) +
         Number(durs[i]) +
-        counts[i] +
-        depths[i] +
-        upids[i] +
+        counts[i]! +
+        depths[i]! +
+        upids[i]! +
         (names[i] ?? '').length) %
       65521;
   }
@@ -409,7 +409,7 @@
   const depths = cols.depth;
   let checksum = 0;
   for (let i = 0; i < count; i++) {
-    checksum += (tss[i] + durs[i] + counts[i] + depths[i]) % 65521;
+    checksum += (tss[i]! + durs[i]! + counts[i]! + depths[i]!) % 65521;
   }
   return checksum;
 }
@@ -514,7 +514,7 @@
   const scales = cols.__scale;
   let checksum = 0;
   for (let i = 0; i < count; i++) {
-    checksum += tss[i] + durs[i] + values[i] + scales[i];
+    checksum += tss[i]! + durs[i]! + values[i]! + scales[i]!;
   }
   return checksum;
 }
@@ -539,7 +539,7 @@
   const upids = cols.upid;
   let checksum = 0n;
   for (let i = 0; i < count; i++) {
-    checksum += (tss[i] + durs[i] + trackIds[i] + upids[i]) % 65521n;
+    checksum += (tss[i]! + durs[i]! + trackIds[i]! + upids[i]!) % 65521n;
   }
   return checksum;
 }
@@ -594,8 +594,8 @@
   samples.sort((a, b) => a - b);
   return {
     label,
-    min: samples[0],
-    median: samples[Math.floor(samples.length / 2)],
+    min: samples[0]!,
+    median: samples[Math.floor(samples.length / 2)]!,
     mean: samples.reduce((a, b) => a + b, 0) / samples.length,
     checksum,
   };
diff --git a/ui/src/trace_processor/sql_utils.ts b/ui/src/trace_processor/sql_utils.ts
index 0960e19..dd89762 100644
--- a/ui/src/trace_processor/sql_utils.ts
+++ b/ui/src/trace_processor/sql_utils.ts
@@ -183,7 +183,7 @@
 export function rowsToSelectStatement(
   rows: readonly Record<string, SqlValue>[],
 ) {
-  const firstRow = rows[0];
+  const firstRow = rows[0]!;
   const columnNames = Object.keys(firstRow);
   const queryRows: string[] = [];
   for (const row of rows) {
diff --git a/ui/src/widgets/combobox.ts b/ui/src/widgets/combobox.ts
index 2670b4e..e953664 100644
--- a/ui/src/widgets/combobox.ts
+++ b/ui/src/widgets/combobox.ts
@@ -107,7 +107,7 @@
       } else if (e.key === 'Enter') {
         e.preventDefault();
         if (this.isOpen) {
-          onChange(allItems[this.highlightIdx].value);
+          onChange(allItems[this.highlightIdx]!.value);
           this.isOpen = false;
           this.highlightIdx = 0;
         } else {
diff --git a/ui/src/widgets/drawer_panel.ts b/ui/src/widgets/drawer_panel.ts
index c4fe589..e2cf14e 100644
--- a/ui/src/widgets/drawer_panel.ts
+++ b/ui/src/widgets/drawer_panel.ts
@@ -165,7 +165,7 @@
 
     // Get active tab key (controlled or uncontrolled)
     const activeKey = isTabsMode
-      ? (activeTabKey ?? this.internalActiveTab ?? tabs[0].key)
+      ? (activeTabKey ?? this.internalActiveTab ?? tabs[0]!.key)
       : undefined;
 
     // Render tabs UI and drawer content based on mode
diff --git a/ui/src/widgets/flamegraph.ts b/ui/src/widgets/flamegraph.ts
index c8d92c3..b476bfb 100644
--- a/ui/src/widgets/flamegraph.ts
+++ b/ui/src/widgets/flamegraph.ts
@@ -339,7 +339,7 @@
                 this.tooltipPos = undefined;
                 return;
               }
-              const renderNode = this.renderNodes![newHoveredIdx];
+              const renderNode = this.renderNodes![newHoveredIdx]!;
               this.tooltipPos = {
                 x: offsetX,
                 y: renderNode.y,
@@ -482,7 +482,7 @@
       .trim();
 
     for (let i = 0; i < this.renderNodes.length; i++) {
-      const node = this.renderNodes[i];
+      const node = this.renderNodes[i]!;
       const {x, y, width: width, source, state} = node;
       if (y + NODE_HEIGHT <= yStart || y >= yEnd) {
         continue;
@@ -503,7 +503,7 @@
         name = '(merged)';
         colorScheme = getFlamegraphColorScheme(name, state === 'PARTIAL');
       } else {
-        name = nodes[source.queryIdx].name;
+        name = nodes[source.queryIdx]!.name;
         colorScheme = getFlamegraphColorScheme(name, state === 'PARTIAL');
       }
       const highlighted =
@@ -616,7 +616,7 @@
       parentCumulativeValue,
       properties,
       marker,
-    } = nodes[queryIdx];
+    } = nodes[queryIdx]!;
 
     const percent = displayPercentage(
       cumulativeValue,
@@ -674,10 +674,10 @@
         }
         return null;
       }),
-      this.renderNodeActionBar(source, name, nodes[queryIdx], nodeActions),
+      this.renderNodeActionBar(source, name, nodes[queryIdx]!, nodeActions),
     ];
     const {renderNodeTooltip} = this.attrs;
-    const node = nodes[queryIdx];
+    const node = nodes[queryIdx]!;
     return m(
       'div',
       renderNodeTooltip === undefined
@@ -1215,7 +1215,7 @@
 
   const zoomQueryWidth = zoomRegion.queryXEnd - zoomRegion.queryXStart;
   for (let i = 0; i < nodes.length; i++) {
-    const {id, parentId, depth, xStart: qXStart, xEnd: qXEnd} = nodes[i];
+    const {id, parentId, depth, xStart: qXStart, xEnd: qXEnd} = nodes[i]!;
     assertTrue(depth !== 0);
 
     const depthMatchingZoom = isDepthMatchingZoom(depth, zoomRegion);
@@ -1257,7 +1257,7 @@
       const mergedXKey = `${id}_${depth > 0 ? depth + 1 : depth - 1}`;
       const childMergedIdx = keyToChildMergedIdx.get(parentChildMergeKey);
       if (childMergedIdx !== undefined) {
-        const r = renderNodes[childMergedIdx];
+        const r = renderNodes[childMergedIdx]!;
         const mergedWidth = isDepthMatchingZoom(depth, zoomRegion)
           ? Math.min(qXEnd - r.source.queryXStart, zoomQueryWidth) / queryXPerPx
           : (qXEnd - r.source.queryXStart) / queryXPerPx;
diff --git a/ui/src/widgets/multiselect_input.ts b/ui/src/widgets/multiselect_input.ts
index 94b41c4..5838c9c 100644
--- a/ui/src/widgets/multiselect_input.ts
+++ b/ui/src/widgets/multiselect_input.ts
@@ -128,7 +128,7 @@
                 ev.preventDefault();
               } else if (ev.key === 'Enter') {
                 if (filteredOptions.length > 0) {
-                  const option = filteredOptions[this.selectedItemIndex];
+                  const option = filteredOptions[this.selectedItemIndex]!;
                   const alreadyAdded = selectedOptions.includes(option.key);
                   if (alreadyAdded) {
                     attrs.onOptionRemove(option.key);
@@ -160,7 +160,7 @@
                   selectedOptions.length > 0
                 ) {
                   attrs.onOptionRemove(
-                    selectedOptions[selectedOptions.length - 1],
+                    selectedOptions[selectedOptions.length - 1]!,
                   );
                   ev.preventDefault();
                 }
diff --git a/ui/src/widgets/nodegraph.ts b/ui/src/widgets/nodegraph.ts
index 7307392..ff79a7d 100644
--- a/ui/src/widgets/nodegraph.ts
+++ b/ui/src/widgets/nodegraph.ts
@@ -459,7 +459,7 @@
         const nodeId = nodeElement.dataset.node!;
         const [type, portIndexStr] = portId.split('-');
         if (type === 'input') {
-          const portIndex = parseInt(portIndexStr, 10);
+          const portIndex = parseInt(portIndexStr!, 10);
           canvasState.hoveredPort = {nodeId, portIndex, type: 'input'};
         } else {
           canvasState.hoveredPort = null;
@@ -633,7 +633,7 @@
         let currentY = node.y;
         chain.slice(1).forEach((chainNode) => {
           // For chained nodes, calculate their Y position
-          const previousNodeId = chain[chain.indexOf(chainNode) - 1].id;
+          const previousNodeId = chain[chain.indexOf(chainNode) - 1]!.id;
           currentY += getNodeDimensions(previousNodeId).height;
 
           if (nodeOverlapsRect(node.x, currentY, chainNode.id)) {
@@ -820,7 +820,7 @@
       return portType === 'input' ? 'left' : 'right';
     }
 
-    return ports[portIndex].direction;
+    return ports[portIndex]!.direction;
   }
 
   function renderConnections(
@@ -1612,7 +1612,7 @@
               (conn) => conn.toNode === id && conn.toPort === portIndex,
             );
             if (existingConnIdx !== -1) {
-              const existingConn = connections[existingConnIdx];
+              const existingConn = connections[existingConnIdx]!;
               const {onConnectionRemove} = vnode.attrs;
               if (onConnectionRemove !== undefined) {
                 onConnectionRemove(existingConnIdx);
diff --git a/ui/src/widgets/popup.ts b/ui/src/widgets/popup.ts
index b82f729..c138be3 100644
--- a/ui/src/widgets/popup.ts
+++ b/ui/src/widgets/popup.ts
@@ -368,7 +368,7 @@
           phase: 'beforeWrite',
           requires: ['computeStyles'],
           fn: ({state}) => {
-            state.styles.popper.width = `${state.rects.reference.width}px`;
+            state.styles.popper!.width = `${state.rects.reference.width}px`;
           },
           effect: ({state}) => {
             const trigger = state.elements.reference as HTMLElement;
diff --git a/ui/src/widgets/router.ts b/ui/src/widgets/router.ts
index 576991f..e8212e9 100644
--- a/ui/src/widgets/router.ts
+++ b/ui/src/widgets/router.ts
@@ -131,9 +131,9 @@
   if (pattern.length !== input.length) return null;
   const params: Record<string, string> = {};
   for (let i = 0; i < pattern.length; i++) {
-    const p = pattern[i];
+    const p = pattern[i]!;
     if (p.startsWith(':')) {
-      const value = safeDecode(input[i]);
+      const value = safeDecode(input[i]!);
       if (value === undefined) return null;
       params[p.slice(1)] = value;
     } else if (p !== input[i]) {
diff --git a/ui/src/widgets/router_jsdomtest.ts b/ui/src/widgets/router_jsdomtest.ts
index b4f26fc..832c99c 100644
--- a/ui/src/widgets/router_jsdomtest.ts
+++ b/ui/src/widgets/router_jsdomtest.ts
@@ -252,7 +252,7 @@
       const objects = container.querySelectorAll('.object');
       expect(objects.length, dumpDom()).toBe(1);
       expect(objects[0], dumpDom()).toBe(objectEl);
-      expect(objects[0].textContent, dumpDom()).toBe('2');
+      expect(objects[0]!.textContent, dumpDom()).toBe('2');
     });
 
     test('renders cached routes in declaration order', () => {
diff --git a/ui/src/widgets/settings_shell.ts b/ui/src/widgets/settings_shell.ts
index 0725cbd..0fc6386 100644
--- a/ui/src/widgets/settings_shell.ts
+++ b/ui/src/widgets/settings_shell.ts
@@ -65,7 +65,7 @@
       ([entry]) => {
         header.classList.toggle(
           'pf-settings-shell__header--stuck',
-          !entry.isIntersecting,
+          !entry!.isIntersecting,
         );
       },
       {threshold: [0]},
diff --git a/ui/src/widgets/tree_explorer.ts b/ui/src/widgets/tree_explorer.ts
index fdf7bce..9713830 100644
--- a/ui/src/widgets/tree_explorer.ts
+++ b/ui/src/widgets/tree_explorer.ts
@@ -260,7 +260,7 @@
   metrics: ReadonlyArray<TreeExplorerMetric>,
 ): TreeExplorerState {
   return {
-    selectedMetricId: metricId(metrics[0]),
+    selectedMetricId: metricId(metrics[0]!),
     addedMetricIds: [],
     displayMode: 'flamegraph',
     filters: [],
@@ -298,7 +298,7 @@
     view: state.view,
     addedMetricIds: state.addedMetricIds,
     displayMode: state.displayMode,
-    selectedMetricId: metricId(metrics[0]),
+    selectedMetricId: metricId(metrics[0]!),
   };
 }
 
@@ -357,7 +357,7 @@
       let pos = 0;
       while ((pos = lowerText.indexOf(searchStr, pos)) !== -1) {
         // Only split if at start or preceded by whitespace
-        if (pos === 0 || /\s/.test(text[pos - 1])) {
+        if (pos === 0 || /\s/.test(text[pos - 1]!)) {
           splitPositions.push(pos);
         }
         pos += searchStr.length;
@@ -376,7 +376,7 @@
   // Split text at those positions
   const result: string[] = [];
   for (let i = 0; i < splitPositions.length; i++) {
-    const start = splitPositions[i];
+    const start = splitPositions[i]!;
     const end = splitPositions[i + 1] ?? text.length;
     const part = text.substring(start, end).trim();
     if (part) {
diff --git a/ui/tsconfig.json b/ui/tsconfig.json
index 710e259..86a95c6 100644
--- a/ui/tsconfig.json
+++ b/ui/tsconfig.json
@@ -21,5 +21,6 @@
     },
     "esModuleInterop": true,
     "allowSyntheticDefaultImports": true,
+    "noUncheckedIndexedAccess": true,
   }
 }