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. + + + +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_ = ∈ + 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, } }